Commit Graph
1907 Commits
Author SHA1 Message Date
DottaandPaperclip 84fe89906d fix: complete native agent review handoffs (#13581)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Native execution uses durable runs, issue locks, wake requests, and
typed tool authority
> - A child can finish with a native agent review request while its
original assignee stays responsible for the work
> - The reviewer then needs a bounded execution path that can inspect
the child, record one decision, and finish safely
> - Before this change, assignee-only gates rejected the reviewer or
left the parent waiting after the child review ended
> - This pull request adds typed reviewer admission, scoped reviewer
tools, durable wake and recovery handling, and parent continuation
evidence
> - The benefit is that native review handoffs complete without changing
child ownership or granting broad mutation access

## Linked Issues or Issue Description

Refs: #13314
Refs: #13574

**What happened?**

A native child run could report `needs_review` for an agent reviewer.
The reviewer wake then failed assignee and execution-lock checks. The
child remained in review and the parent remained waiting.

**Expected behavior**

The named reviewer should receive one durable wake. The reviewer should
inspect the child and resolve the exact review card. The child assignee
should stay unchanged. The parent should receive the recorded review
outcome after the child reaches its terminal state.

**Steps to reproduce**

1. Run a native task with a different named agent reviewer.
2. Keep the child assigned to its original worker.
3. Let the worker finish with a native completion review request.
4. Start the durable reviewer wake.
5. Resolve the review and finish the reviewer run.
6. Observe the child and parent state.

**Paperclip version or commit**

Base: `e926b1301`. PR head: `b31ad9ab8`. Live reviewer verification
source: `eea171aae`.

**Deployment mode**

Built from source.

**Installation method**

Built from source (pnpm build).

**Agent adapter(s) involved**

Not adapter-specific (core bug).

**Access context**

Both.

**Database mode**

Embedded PostgreSQL in the isolated live test fixtures.

## What Changed

- Add server-validated native review assignment facts.
- Admit only the exact company, issue, source run, decision, revision,
addressee, and resolver policy.
- Give reviewer runs a narrow set of Paperclip read and resolve tools.
File and shell access follow the configured agent and environment
policy, so reviewers can run tests.
- Separate server-owned reviewer instructions from untrusted persisted
review data. Escape the data boundary; retain server-enforced
authorization.
- Keep the child assignee unchanged. Atomically claim the reviewer run,
wake request, and issue execution lock. A competing lock prevents
provider startup.
- Require the exact running reviewer session and current issue lock to
resolve its assigned card. Reject missing, unrelated, or terminal
reviewer runs.
- Add durable reviewer wake, lock, stale-card, and abandoned-run
recovery handling.
- Prevent duplicate native wake dispatches during deferred admission and
recovery.
- Carry accepted or rejected child review outcomes into parent task
context and continuation evidence.
- Add focused server, runner, and native protocol coverage.
- Preserve upstream continuation rules. Add child review decisions as
separate evidence, while keeping real human answers in their own field.
- Return actionable completion validation feedback to both providers.
Permit a corrected completion after rejection. Keep strict terminal
acknowledgment validation.
- Apply exclusive shared-workspace locks to sandbox environments. Local
and SSH folders can run concurrently, including when old settings
request serialization.
- Repair test timing, native event parsing, and the review artifact
assertion. Allow a valid reject, correct, and accept review sequence.
Check the accepted card against its reviewer run and decision. Keep
polling within the existing deadline when review acceptance precedes the
parent wake projection; report a specific missing-continuation error at
timeout.
- Apply the ACPX pending-call limit to reserved finish/block calls, with
capacity-release and cancellation tests.

## Verification

- `pnpm build`: passed on `eea171aae`.
- `pnpm -r typecheck`: passed on `eea171aae`.
- `pnpm test:e2e:runner:unit`: 359 tests passed in 30 files on
`b31ad9ab8`; runner E2E typecheck also passed.
- `pnpm check:token-gates`: passed.
- Focused DB review, reviewer authority, and prompt-boundary checks: 31
tests passed. They cover invalid reviewer runs, competing locks, atomic
admission, duplicate claims, and valid resolution.
- Heartbeat, workspace, and recovery checks: 30 tests passed.
- ACPX sidecar suite: 27 tests passed. Moving the capacity guard back
below reserved handling makes both new regression cases fail.
- Four focused live continuation checks passed on their first attempt at
`f15f55e0a`: answer updates scope (6/6 each on Codex and Claude) and
question tool guidance (12/12 each). These cases do not use the reviewer
prompt path changed afterward.
- Fresh Codex and Claude review-handoff checks passed all 29 native
checks each on their first attempt at `eea171aae`. Both runs received
the expected fixed prompt and completed cleanup. Only the six selected
live flows were tested; no full paid provider catalog run.
- The final commit only extracts the existing test-harness timeout
diagnostic into a shared helper and adds positive and negative coverage.
Removing the accepted-review guard makes two regression assertions fail;
restoring it passes all six timeout tests. Production runtime code,
prompts, deadlines, and grading criteria are unchanged by this final
commit.
- Deadline regressions: a valid continuation delayed 20 seconds succeeds
within its 30-second unit-test deadline; an absent wake returns a
specific candidate-failure diagnostic at that same deadline. Both
assertions failed before the fix. Production E2E deadlines remain
unchanged.
- Historical native failures remain recorded: Docker availability
failures; a valid reject/correct/accept sequence that the first-card
grader misread; and a test that rejected the gap between accepted child
review and parent wake projection. No failed result was regraded. The
latest tests use a protected reference to the pinned Docker image and
the unchanged artifact oracle and time limits.
- Full repository verification runs in GitHub CI. Local verification
uses the focused suites above, full build, and full typecheck. An
unchanged Codex shutdown timing test failed once in CI, passed in
isolation, and its full shard passed on the final commit without changes
to that test or its causal code path. The original failure is retained
in the verification record. Greptile reviewed `b31ad9ab8` at 5/5 with no
outstanding actionable findings. All review threads are resolved. All
current-head CI gates passed, including the isolated native runner
Docker build (55 successful checks; two skipped by the workflow).

## Risks

- Reviewer admission depends on exact persisted decision and interaction
bindings. A stale or changed card is rejected.
- Paperclip control-plane tools are limited to inspection and review
resolution. This is not a filesystem permission boundary; provider file
and shell access retain the configured policy.
- Deferred wake recovery changes dispatch receipt coalescing. A
scheduler regression could delay a continuation if the receipt state is
wrong.
- Parent review outcomes are evidence for the model. They do not grant
tool authority or change issue ownership.
- This change does not address legacy lease-hold handoff behavior.

> Roadmap review: native execution, review gates, and durable recovery
are existing roadmap capabilities. This PR completes a narrow
reliability path for those capabilities.

## Model Used

OpenAI `gpt-6-astra` with reasoning, tool use, and code execution.
OpenAI `gpt-5.6-luna` assisted with bounded implementation, review, and
journal work. Context window size is not exposed by this session. Live
test subjects use `gpt-5.6-sol` and `claude-sonnet-5`; they are not the
PR authors.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-09-17 15:52:19 -05:00
mouse-value-add fcdb3f2499 feat: add optional you.com search integration (#13555)
<!-- Simplified Technical English (ASD-STE100). -->

## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Agents that do research work need live information from the web
> - Paperclip reaches external systems through governed, catalog-based
MCP connections
> - The Apps catalog is data-driven: a researched provider with a hosted
remote MCP server becomes a connectable app with no runtime code change
> - You.com operates a hosted remote MCP server for web search, content
extraction, and research tools
> - The server supports OAuth 2.1 with dynamic client registration, an
API key in a bearer header, and a keyless free profile at a separate
endpoint
> - This pull request adds You.com to the self-serve MCP research ledger
and generates its catalog entry with three connection methods: browser
sign-in, API key, and the keyless free profile
> - The benefit is that an operator can give agents live web search
through the normal connection governance, and the free profile needs no
account at all

## Linked Issues or Issue Description

No public issue exists for this provider. The problem description
follows the new-adapter issue template.

**Agent or provider**

You.com — web search and research tools over a hosted remote MCP server.

**Why this adapter is useful**

Agents that do research, monitoring, or fact-finding tasks need current
web results. You.com exposes web search (`you-search`), live page
extraction (`you-contents`), citation-backed research (`you-research`),
and finance research (`you-finance`) as MCP tools. Any Paperclip company
can connect it in a few clicks. The free profile offers `you-search`
without an account, so a new company can try agent web search at zero
cost and zero setup.

**How the agent is invoked**

Hosted remote MCP server (Streamable HTTP) at `https://api.you.com/mcp`.
Three supported access paths, verified against the live server on
2026-09-16:

- OAuth 2.1 browser sign-in. The server returns a `WWW-Authenticate`
challenge with RFC 9728 protected-resource metadata and advertises a
dynamic client registration endpoint, so Paperclip's automatic DCR path
applies.
- API key. Sent as an `Authorization: Bearer` header per the provider's
official server manifest and docs. Keys come from you.com/platform and
unlock higher rate limits plus the full tool set.
- Keyless free profile at `https://api.you.com/mcp?profile=free`.
Provides a reduced, read-only tool set.

Official docs: https://you.com/docs/build-with-agents/mcp-server

**Are you willing to implement it?**

Yes. Implemented in this pull request.

**Additional context**

Research evidence collected 2026-09-16, from live protocol probes and
official provider sources only:

- Unauthenticated `POST https://api.you.com/mcp` returns HTTP 401 with
`WWW-Authenticate: Bearer
resource_metadata="https://api.you.com/mcp/.well-known/oauth-protected-resource"
scope="Tools offline_access"`.
- RFC 9728 metadata lists one authorization server with scopes `Tools`
and `offline_access`.
- The authorization-server metadata (RFC 8414) publishes authorization,
token, and revocation endpoints, and advertises a
`registration_endpoint`, so DCR is available. No registration was
performed during research, per the runbook's non-registering preflight
rule.
- The keyless free profile answers `initialize` (server `You.com`,
version `4.0.1`), lists the tools `you-search` and `you-discover`, and
executed both tools successfully during the probe.
- The API-key placement matches the provider's official `server.json` in
the youdotcom-oss/mcp repository: header `Authorization`, value `Bearer
<key>`.

## What Changed

- Added You.com (slug `youcom`, wave 4, risk tier S2) to the self-serve
MCP research ledger in
`packages/shared/src/self-serve-mcp-research.json`, and refreshed the
ledger verification date.
- Added the You.com category (`ai`) and API-key header spec to
`scripts/ingest-app-definitions.mjs`.
- Added a You.com case to `specialMethodsFor` that emits three methods:
browser sign-in (`mcp-oauth`, DCR), API key (`mcp-api-key`, bearer
header), and keyless free profile (`mcp-free`, no auth).
- Regenerated `packages/shared/src/app-definitions/youcom.json` and the
generated registry via the ingestion script (`--definitions-only` mode;
no unrelated provider churn).
- Added the official You.com wordmark artwork (light and dark theme
variants, taken from the provider's docs site) under
`ui/public/brands/apps/`, with a manifest entry.
- Updated `packages/shared/src/app-definitions.test.ts`: ledger counts
(47 providers, 44 candidates), store count (48), verification date, and
assertions for the three You.com methods and their endpoints.

## Verification

- `node scripts/ingest-app-definitions.mjs --definitions-only` — passed.
Generated the new definition and registry import only; no other provider
JSON changed.
- `node scripts/check-app-brand-assets.mjs` — passed (71 identities).
- `node --test scripts/app-brand-validation.test.mjs` — passed.
- `pnpm exec vitest run packages/shared/src/app-definitions.test.ts
ui/src/lib/app-brand-assets.test.ts
ui/src/pages/apps/AppLogo.brand-assets.test.tsx` — passed (39 tests).
- `pnpm exec vitest run packages/shared/src/app-definitions.test.ts
server/src/__tests__/tool-access-service.test.ts
server/src/__tests__/generic-mcp-connection.test.ts
server/src/__tests__/tool-connection-removal.test.ts
ui/src/pages/apps/AppsConnect.test.tsx
ui/src/pages/apps/Browse.test.tsx` — passed (181 tests). Two server
suites that require embedded Postgres skipped on this machine by their
own environment gate; the gate is unrelated to this change.
- `pnpm --filter @paperclipai/shared typecheck` — passed.
- `pnpm --filter @paperclipai/ui typecheck` — passed.
- `pnpm --filter @paperclipai/plugin-sdk ensure-build-deps` — passed;
builds `@paperclipai/shared` with the new definition.
- `pnpm test:run` (full Vitest suite) — 7,930 passed, 18 failed, 4,592
skipped. Every failure is environmental on this container: the
embedded-Postgres suites refuse to start because the machine runs as
root, the native runtime suites need the Rust runner binary that this
container cannot build, and one media suite needs a native HEIC binary.
No failure touches the app-catalog, connection, branding, or
shared-package surface; those suites pass locally. CI is the
authoritative gate for the full suite.
- `pnpm --filter @paperclipai/server typecheck` — not completed: the
script's `prepare:runner-vendor` prelude builds the Rust runner, which
cannot build on this container. A direct `tsc --noEmit` reports only
pre-existing errors from the missing vendored runner types; no error
touches this change. No server code is changed.
- Live You.com proof on 2026-09-16 (keyless free profile, real network
calls): preflight 401 challenge with RFC 9728/8414 metadata and DCR
endpoint ✓, `initialize` ✓, `tools/list` ✓, `you-search` call returned
results ✓, `you-discover` call returned results ✓.
- Live proof NOT run: an authenticated OAuth connect and an API-key call
against the full server. This environment has no You.com account or API
key. Per the runbook, this proof stays outstanding and must not be
assumed from the keyless probe. Both paths match the reviewed
`mcp_remote` patterns (DCR and bearer header) used by existing
providers.
- Browser e2e suites not run: opt-in per `AGENTS.md`, and this change
adds catalog data only, with no UI code.

## Risks

- Low risk. The change is catalog data plus generated output. It adds no
runtime code and touches no existing provider.
- The free-profile method is a fixed keyless endpoint. If You.com
changes or removes `?profile=free`, that method breaks and the entry
needs a ledger update. The OAuth and API-key methods do not depend on
it.
- The authenticated tool catalog is discovered live at connect time, so
provider-side tool changes appear through the normal catalog refresh and
quarantine flow, not through this definition.
- Rollback is a single revert; no migration and no state are involved.

## Model Used

- Provider: Zhipu AI, via OpenRouter
- Model: GLM-5.3 (`z-ai/glm-5.3`)
- Context window: 200K tokens
- Capabilities used: tool use (shell, file edits, live HTTP probes),
long-context repository reading
- The change was produced with AI assistance and reviewed by a human
before submission.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` /
`Closes: #` / `Refs: #` OR (b) described the issue in-PR following the
relevant issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [ ] All Paperclip CI gates are green
- [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge
2026-09-17 10:01:49 -07:00
5d9b20ccf0 fix(ui): keep task composer available while pause state loads (#13562)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Task messages enter through the shared task composer.
> - The task page waits for a separate tree-control query to find active
pause holds.
> - The old loading guard disables the composer until that request
settles. A slow or stalled request blocks messages on both desktop and
mobile.
> - This PR allows sends while that query is pending. The server still
rejects paused board messages before saving a comment or waking an
agent.
> - Query failures and known pause holds still block the composer.
> - Regression tests cover pending sends, successful responses, query
failures, and late root or inherited pauses.

## Linked Issues or Issue Description

Fixes: #13561

Related: #13569 adds pending/error coverage for the same fix. This PR
now covers those cases and the late-pause transitions.

The report overstates two details: `isPending` clears after a successful
response, and the shared loading guard also affects mobile. The
reproduction holds the request pending. It does not prove why the
reporter's request remained unresolved.

## What Changed

- Preserve the original two-line fix that removes the pending-state
composer block.
- Add eight page regression cases using a real QueryClient and a
controlled API promise. Cover desktop and mobile, submission before the
query completes, successful resolution, rejected resolution, and late
root/inherited pause responses.
- Repair an existing server CI failure in a separate commit. Reuse the
shared unique-violation helper so Drizzle-wrapped duplicate inserts
become retryable document conflicts. Add a deterministic regression and
preserve unrelated database errors.
- Repair an existing Inbox test race in a separate commit. Wait for
workspace metadata, which resolves independently of the task list.

## Verification

- Red: restore the pre-fix `IssueDetail.tsx` and run the new `composer
tree control` cases. Both desktop and mobile pending-send cases fail
with `Checking task status…`. The other six cases pass.
- Green: restore the original PR fix. All 343 tests in IssueDetail,
TaskChatThread, and TaskChatComposer pass.
- The server comment/reopen and artifact-review suites pass (179 tests).
They include POST and PATCH pause checks that return 409 before any
comment, task mutation, or wakeup.
- The document error regression fails before the shared-helper fix and
passes after it. The document, artifact-review, and database-error
suites pass (31 tests). The handler matches only the issue-document key
constraint; revision and other constraint errors retain their original
identity.
- The Inbox suite passes (27 tests).
- `pnpm check:token-gates` passes.
- `pnpm -r typecheck` and `pnpm build` pass locally. The full CI matrix
passes on `5af1ed0b43269247aaba406cf4fd4d7fe1a22e75`: 54 successful
checks and two opt-in Storybook skips, including all general/serialized
tests, runner checks, release checks, and eight browser shards.
- One server shard initially hit an unrelated `EADDRINUSE` on test port
52000. Its single rerun passed without code changes.
- Greptile completed successfully on that exact commit with 5/5 and no
outstanding findings or review threads.
- The serial local `pnpm test:run` was started, then stopped after the
complete parallel CI matrix passed. It is not claimed as a completed
local full-suite run. The focused local suites above did finish
successfully.

For a manual reproduction, delay the task's `/tree-control-state`
response, open the task, and enter a message. Send should remain
available during the delay. Resolve the response with an active pause
hold and confirm that the pause takeover replaces the composer. Reject
the request and confirm that the error blocks sends.

## Risks

A user can attempt a send before the pause response arrives. The server
remains authoritative and returns 409 for a paused task before saving or
waking work. The known pause takeover and query-error block remain.
There are no schema, API, or styling changes.

The document change restores the existing conflict/retry behavior for
wrapped database errors. It does not retry unrelated database failures.
The Inbox change affects test synchronization only.

## Model Used

- Original fix: Anthropic Claude Sonnet 4.6 (`claude-sonnet-4-6`), 200k
context, tool use and code editing, as reported by the author.
- Review, regression tests, and CI repairs: OpenAI GPT-6 (`gpt-6-astra`)
through Codex, with reasoning, tool use, and code execution. The session
does not expose its context-window size.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: austinpilz <austinpilz@users.noreply.github.com>
Co-authored-by: Dotta <bippadotta@protonmail.com>
2026-09-17 08:40:40 -05:00
Devin FoleyandPaperclip fae6980310 revert(apps): restore Google connector visibility (#13552)
## Thinking Path

> - Paperclip helps people manage AI agents for work.
> - The Connectors catalog lists services that agents can use.
> - PR #13551 temporarily hid Google connectors.
> - We now want to restore their catalog visibility.
> - This PR reverts that change and restores the previous catalog
behavior.

## Linked Issues or Issue Description

Refs: #13551

Revert the temporary removal of Google connectors from the UI.

## What Changed

- Restore Gmail and eight Google Workspace entries to the catalog.
- Restore the matching branding flags and original catalog and service
tests.
- Remove the temporary-hiding documentation note.

This is an exact revert of commit
`cf1e873ab24277d55ffd3ab06074f77014dc4015`.

## Verification

- Passed: 507 catalog, UI, and connection service tests.
- Passed: `pnpm check:token-gates` and `node
scripts/check-app-brand-assets.mjs`.
- Passed: `pnpm --filter @paperclipai/ui... build` and `pnpm --filter
@paperclipai/ui... typecheck`.
- Full local build and typecheck stop at the Rust runner because `cargo`
is not installed.
- Full local Vitest was not repeated because the unchanged base has
confirmed macOS skill-cache permission failures. The full CI suites
passed.
- Passed: all GitHub CI gates; Greptile 5/5 on commit
`4e3dddef0ebfef1f99001e7735822ed4cba852ab`, with no review threads.
- Reviewer check: open Connectors and confirm that Gmail and Google
Workspace entries appear again.

## Risks

Low risk. This restores the previous catalog visibility and setup entry
points. Connector implementations and saved connection data are
retained.

## Model Used

OpenAI GPT-6 through Codex, with reasoning, tool use, and code
execution. The exact deployment ID and context window size are not
exposed in this session.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-09-16 15:35:16 -07:00
Devin FoleyandPaperclip cf1e873ab2 fix(apps): temporarily hide Google connectors (#13551)
## Thinking Path

> - Paperclip helps people manage AI agents for work.
> - The Connectors catalog lists services that agents can use.
> - We need to temporarily remove Google connectors from the UI.
> - The catalog already separates visibility from retained definitions.
> - This PR uses that setting so Google can return with a small change.

## Linked Issues or Issue Description

**What existing behavior does this improve?**
The Connectors catalog and its setup entry points.

**Current behavior**
The catalog shows Gmail and eight Google Workspace connectors.

**Proposed behavior**
Temporarily hide those nine entries. Keep their definitions and existing
connections.

**Reason and benefit**
Make the temporary UI removal easy to reverse.

**Breaking changes**
Fresh catalog setup no longer offers Google. Saved connections keep the
existing management and reconnect paths.

## What Changed

- Add the nine Google connector slugs to the existing hidden list.
- Match the branding manifest visibility flags.
- Update existing catalog and service tests. Keep backend Google
connection coverage and document how to restore visibility.

## Verification

- Passed: 507 targeted tests covering catalog definitions, URL matching,
setup routing, connector UI, branding, and the connection service.
- Passed: `pnpm --filter @paperclipai/ui... build` and `pnpm --filter
@paperclipai/ui... typecheck`.
- Passed: `pnpm check:token-gates` and `node
scripts/check-app-brand-assets.mjs`.
- Full local build and typecheck stop at the Rust runner because `cargo`
is not installed.
- Stopped the full local Vitest run after skill-cache permission
failures. Three failures in `company-skills-service.test.ts` also
reproduce on the unchanged base branch. The final connector service
suite passes all 319 tests.
- Greptile: 5/5 on the current commit, with no open review threads. CI
is retrying one unrelated preview-server readiness timeout. That test
file passes all seven tests locally.
- Reviewer check: open Connectors in a company with no Google
connections. Gmail and Google Workspace entries should be absent.
Existing saved connections remain manageable.

## Risks

Low risk. This uses the existing catalog visibility mechanism. No
connector implementation, credential, or database schema is removed.
Restoring visibility requires updating both the hidden list and branding
manifest.

## Model Used

OpenAI GPT-6 through Codex, with reasoning, tool use, and code
execution. The exact deployment ID and context window size are not
exposed in this session.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [ ] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-09-16 15:04:46 -07:00
Devin FoleyandPaperclip 6fe8e30625 feat(apps): add Railway connection and governed deployment tools (#13415)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Apps gives agents governed access to external resources.
> - Operators need to inspect Railway services, read logs, deploy code,
and run container commands.
> - Railway offers hosted MCP with OAuth, but broad remote actions hide
their internal operations.
> - This PR adds a branded connection and fixed direct operations
through the existing gateway.
> - Separate SSH keys enable container commands under the same grants
and policies.
> - Operators can require approval for an action and inspect the
resulting audit record.

## Linked Issues or Issue Description

**Subsystem affected**

Apps catalog, connection setup, gateway execution, and connection
documentation.

**Problem or motivation**

Agents need Railway access through Paperclip. Operators need to grant
and revoke that access, inspect available actions, and govern deployment
and container operations without giving agents provider credentials.

**Proposed solution**

Reuse hosted MCP OAuth, vault storage, catalog discovery, grants, and
the gateway. Probe the actual credential before enabling fixed GraphQL
operations. Use a dedicated grant-owned SSH key for bounded container
commands.

**Alternatives considered**

A catalog entry alone cannot execute the missing operations. The hosted
general agent has opaque internal effects. An unrestricted CLI runtime
can bypass action policy and inherit ambient credentials.

**Roadmap alignment**

This extends the existing MCP Tool Gateway & Apps path and the Connected
Apps direction in ROADMAP.md. It does not add a plugin or parallel
connection service.

Related PRs #311, #939, and #7861 concern hosting Paperclip on Railway.
They do not add this outbound Apps connection. The separate shared
agent-picker fix is #13414 and is not included here.

## What Changed

- Add the generated Railway catalog entry, official marks, provenance,
and OAuth setup guidance.
- Add fixed service/deployment status, bounded logs, and
redeploy/restart/rollback tools. Block source deployment until the
provider can atomically bind the approved repository and commit.
- Verify API access with an explicit workspace before exposing direct
tools.
- Add grant-owned SSH key setup and a bounded runner with host
verification, target checks, isolated state, and cleanup.
- Block the opaque hosted railway-agent and accept-deploy actions.
Preserve normal Allowed defaults and Ask-first policies for other
actions.
- Quarantine new or changed Railway schemas after initial discovery,
including reconnect.
- Add provider, lifecycle, gateway, SSH, UI, and browser fixtures.
Document setup, limitations, and the release checklist.

## Verification

- Security follow-up: removed the unsafe source-deployment mutation.
Direct calls and old active catalog entries are denied before any
upstream request, including normalized aliases. Refresh marks retired
entries disabled. All 386 focused Railway, catalog and gateway tests
passed, and server TypeScript checking passed. Full [GitHub
CI](https://github.com/paperclipai/paperclip/actions/runs/35139421144)
passed on d86530ab9, including typecheck, build, all tests, runner
checks, and browser tests. Superagent passed and confirmed the P2 fix.
Greptile reviewed the same commit at 5/5 with no findings.

- CI follow-up: fixed the missing Railway SSH operation in the OpenAPI
document, including its request schema, operator-only authentication,
and error responses. The failure reproduced locally before the fix; all
403 selected API, Railway, catalog, and artwork tests passed after it.
Synced current master and resolved the catalog/artwork conflicts.

- After rebase: 440 focused provider, lifecycle, gateway, catalog, and
container-panel tests passed. AppDetail and AppsConnect passed another
196 tests.
- Full typecheck, build, token gates, and the gallery browser check
passed after rebase.
- During implementation, full build and the gallery browser check
passed. Shared generic-MCP fixtures covered OAuth callback/state/issuer
binding and failure paths.
- Local live consent and tools/list succeeded. There were 44 active
hosted actions and two blocked actions. A workspace-bound API probe and
direct project/service/environment reads succeeded. The inspected
project had no deployed services. No provider mutation ran.
- Full GitHub CI passed on commit 303340f19, including all
server/workspace test groups, typecheck, build, runtime verification,
release dry run, and browser tests. The original local full-run attempt
was incomplete; the complete automated suite is now verified in CI.

Manual review: connect Railway, review the actual actions, install for
an agent, and run a resource read through the gateway. Choose Ask first
before testing a deployment mutation. Configure a dedicated key only
when container access is needed.

**Release qualification is still open.** Live agent gateway reads/logs,
rejected and approved deployment calls, refresh/revoke, public HTTPS
consent, and SSH enrollment/commands/cleanup need an authorized
disposable service. The passing API diagnostic does not replace those
tests. See doc/connections/RAILWAY.md and RAILWAY-REVIEW.md.

## Risks

Overall risk is medium. New runtime behavior is gated to Railway
connections, but the PR changes shared catalog, credential lifecycle,
and gateway code. A regression in those paths can affect other Apps
connections. The highest-impact operations are Railway deployments and
container commands.

- Provider consent can authorize an entire workspace. Catalog labels are
not local resource allowlists. Direct tools check target membership, and
provider permissions still apply.
- Shell commands have broad internal authority. Action policy cannot
approve each internal shell step. Timeouts close the local connection
but cannot guarantee remote child-process termination.
- Log and command output may contain application secrets that pattern
redaction cannot recognize.
- Source deployment is unavailable until the provider supports atomic
repository/commit binding. Existing deployments can still be redeployed,
restarted or rolled back.
- No database migration is required. Rollback can remove promotion and
direct dispatch while preserving connection data and the generic MCP
path.
- Live Railway qualification must still pass before release acceptance.

## Model Used

OpenAI Codex, based on GPT-6, with code execution and browser testing.
An independent read-only security agent reviewed the local
implementation. The exact serving model ID and context window were not
exposed in this session.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-09-16 13:54:44 -07:00
DottaandPaperclip d0b67bfe71 feat: queue approvals and answers during active runs (#13539)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Users guide running agents through messages, questions, and approval
cards.
> - Messages already wait in a queue when an agent is running.
> - Card responses did not appear in that queue. Some question answers
also steered a later run without a user click.
> - A fast approval could invalidate the agent's review handoff and
cause it to stop its own run.
> - This pull request gives card responses the same queue controls and
preserves the exact response during delivery.
> - Users can wait for completion or explicitly send the response with
Interrupt or Steer.

## Linked Issues or Issue Description

Refs #13517, which is merged. This PR targets master and adds queued
interaction responses on top of the onboarding changes. Related
continuation work: #10519 and #12866.

**What happened?**

Accepting a proposal while its source run was active left a saved
response outside the message queue. The agent could then lose its review
path, reassign the task, and cancel itself. Answers to older questions
could also steer another active turn without a click.

**Expected behavior**

Save the response immediately. Queue its continuation behind the active
run. Deliver it after completion, or when the user explicitly chooses
Interrupt or Steer. Preserve approval revisions and answer choices.

**Steps to reproduce**

1. Let an agent publish a confirmation card while its run is still
active.
2. Accept the card before the agent finishes its review handoff.
3. Inspect the message queue and the task's next run.

**Paperclip version or commit**

Reproduced on da8a3876c with the onboarding changes from #13517.

**Deployment mode**

Local development from source. The fix covers legacy adapters and native
Runner turns.

## What Changed

- Project resolved cards into the existing queue as immutable responses.
Keep answers and exact approval revisions.
- Require an explicit click to steer a response into a compatible native
turn. Use Interrupt when a fresh session is required.
- Preserve typed response context through interruption, cleanup waits,
and normal queue promotion. Keep the direct answer channel for a
provider blocked on its original question request.
- Accept the source run's review handoff after its card resolves. Reject
stale agent reassignment that would orphan a queued response.
- Add deterministic regression tests and an `accept-while-running` case
to the first-task suite. Require recorded timestamp overlap before that
case can pass.
- Keep the first-task skill name out of user-facing messages.

## Verification

- Red-green: the original route failed the queue regression; the changed
route passes it.
- Focused server/UI tests: 139 passed, including 64 queue-route tests.
- Runner harness unit tests: 314 passed.
- Server, UI, and Runner E2E typechecks passed. UI token gates passed.
- Full repository typecheck and build passed. Server typecheck passed
again after review fixes.
- Review regressions: 165 queue/reopen route tests, 53 wake admission
tests, and 18 run identity tests passed. Approval acknowledgement
recovery and both message/approval arrival orders are covered.
- Full local test run: 12,401 passed; three new admission regressions
ran against a cached pre-fix module. A fresh run of that entire suite
passed (53 tests). The complete CI suite passed on the final commit.
- Previous-head CI at `c28e2ef12`: 32 checks passed and 2 optional
Storybook checks skipped. Every server/workspace/browser shard, Runner
verification, build, typecheck/release registry, canary, policy, and
security check passed. Greptile: 5/5, no unresolved threads. Earlier
interrupted CI workers were replaced by this fresh complete run.
- After integrating the updated parent: 314 harness tests, 119
queue/admission tests, 44 onboarding/question-delivery tests, and 13
native recovery tests passed locally. Full repository typecheck and
build passed.
- Clarified the skill wording preference: routine replies describe the
action without announcing the internal skill; direct questions and
permission/security/execution disclosures remain truthful.
- The paid `accept-while-running` scenario is registered for all four
local first-task profiles. It has not been run against a model in this
change.

- Rebased onto the merged parent at `11921075a`; the resulting tree
exactly matches the locally verified integration tree. Final-head CI on
`b53054807` passed: 54 successful checks, 2 optional Storybook checks
skipped, no failed checks. Every new server/browser shard, aggregate
verify/e2e gate, Runner, typecheck, build, canary, and security check
passed on the first attempt. Greptile reviewed this exact head at 5/5
with no unresolved threads.

## Risks

- Responses now wait instead of implicitly steering another active turn.
A provider blocked on the original question still receives its answer
directly.
- Approval receipts cannot be edited, discarded, or reordered as
comments. This preserves the recorded decision.
- Interruption must still prove that the prior execution stopped. The
tests cover cleanup waits and duplicate delivery.
- The new paid overlap case can be unexercised if the model finishes
before the click lands. It cannot pass without evidence of overlap.
- No database migration is required. This repairs the existing approvals
and execution controls; it does not implement the roadmap's work-stream
queues.

## Model Used

OpenAI GPT-6 through Codex. The exact deployed model ID and
context-window size were not exposed in this session. Capabilities used:
agentic reasoning, repository inspection, code editing, terminal
commands, and test execution.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-09-16 14:44:36 -05:00
DottaandPaperclip 9fd2e50310 feat: create company skills from runner tasks (#13538)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - The Runner gives agents tools to change company resources.
> - Users need agents to save reusable skills during a task.
> - A saved skill needs a visible result that users can inspect and
edit.
> - This pull request adds `create_skill` and a task feed card linked to
Skill Studio.
> - Users can open the saved skill from the task and edit the same
resource.

## Linked Issues or Issue Description

**Subsystem affected**

Runner tools, company skill storage, task feed, and Skill Studio.

**Problem or motivation**

The Runner has no dedicated tool to create a company skill. A user
cannot follow a creation result from the task feed to the saved skill.

**Proposed solution**

Add a company-scoped `create_skill` tool. Save the skill with the
existing company policy. Add one creation card to the task. Open a named
sidebar tab from that card. Let the user open the same skill in Skill
Studio.

**Alternatives considered**

An agent can write a local file, but that file is not a company skill. A
second document copy in the task would become stale after a Studio edit.
The sidebar therefore reads the saved skill directly.

**Roadmap alignment**

This extends the shipped Skills Manager, Skill Studio, and Skills Store
milestone. The maintainer requested and approved this scope. Search
found no duplicate `create_skill` PR or issue. Related UI validation
work: #8715. This PR does not change that validation display.

## What Changed

- Add the real Runner tool, its contract, and its mock implementation.
- Validate the complete SKILL.md and derive company, task, agent, and
run identity from authentication.
- Apply the existing company skill policy. Do not assign the skill to an
agent.
- Make keyed retries return one skill and one creation event. Reject
conflicting retries.
- Make concurrent file creation safe. Never replace an existing
published skill during creation.
- Add a creation card, a named sidebar tab, and an Open in Skill Studio
action.
- Show saved Studio edits when the user returns to the task.
- Add storage, policy, mode, retry, UI, and Product E2E tests. Document
the tool.
- Fix deleted-name reuse, onboarding panel persistence, immediate feed
refresh, and mock validation parity from review.
- Serialize Studio file edits and renames with skill deletion and
recreation. Reject stale editor requests before they can change a
replacement skill.
- Generate the standalone mock parser and validator from the production
contract. Use portable UUIDs so the browser scenario bundle builds.

## Verification

- All latest-head PR checks pass on `145dd76a5`, including all server
shards, browser E2E, Runner verification, build, typecheck, and release
dry run. Greptile: 5/5 with no open findings. An interrupted CI runner
was retried successfully.
- `pnpm -r typecheck`: passed.
- `pnpm build`: passed.
- `pnpm check:token-gates`: passed.
- Review regressions: 73 storage tests, 6 real API tests, 63 UI tests,
and 61 semantic runtime tests passed. Parser synchronization passed.
- CI exposed existing fire-and-forget Sentry test races. Reproduced the
resumption race locally, then synchronized the related sweep and
finalizer assertions on the actual report; all 27 tests across the three
affected files pass.
- Runner scenario browser build and strict content-security-policy
check: passed.
- Runner suite: 2,012 tests passed; 10 skipped.
- `pnpm test:run`: the general-server batch had 12,416 passes and two
failures. The old tool-count assertion was fixed; all 16 authority tests
then passed. The chat webhook test had a socket error; it passed four
isolated reruns.
- Both workspace test groups passed. The isolated route suites
completed. Two socket failures in the initial route batches passed on
individual reruns; all remaining 61 files passed.
- Product E2E `create-skill-studio`: passed with local Codex and local
ACPX Claude.
- Manual browser test: submit a task, observe the real tool call and
creation card, open the sidebar, edit in Studio, save, and return. The
task reached Done. The saved second revision and sidebar tab survived a
server restart.
- The new companion headless Runner Eval passed. Companion coverage PR:
https://github.com/paperclipai/paperclip-evals/pull/23. Daytona was not
run because no immutable runner image was configured.

## Risks

- Database writes and local file writes cannot share one transaction.
Recovery accepts only an exact file-for-file retry after a database
rollback. Conflicting files remain untouched.
- The sidebar displays the current skill. The feed card remains the
historical creation receipt.
- No database migration, dependency, or workflow change is included.
- Remote Daytona behavior still needs a run with a configured immutable
image.

## Model Used

OpenAI GPT-6 (`gpt-6-astra`) handled design, integration, review, and
browser verification. OpenAI `gpt-5.6-luna` assisted with bounded
implementation and eval work. Both used code execution and tool access.
The host did not expose the context window size.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-09-16 13:01:58 -05:00
DottaandPaperclip 669bd0e7a9 fix(ui): show progress and verify subscriptions during onboarding (#13499)
Automatically verify detected Claude and Codex subscriptions during initial onboarding. Show connection progress, support retries, and ignore stale results after navigation. Prefer the personal default subscription while preserving the later create-agent chooser.

Allow Enter to advance from the agent name field. Add regression tests and production-component Storybook coverage.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-09-15 17:39:25 -05:00
DottaandPaperclip 9cfa7fd2d1 fix(ui): share compact live and saved activity across runners (#13421)
## Thinking Path

> - Paperclip helps people manage AI agents and inspect their work.
> - Task threads show live activity and saved transcripts from several
runners.
> - Legacy runs used a separate activity renderer that expanded tool
cards as commands arrived.
> - A compact live row makes ongoing work easier to follow.
> - This PR shares the native runner activity group across live and
saved legacy turns.
> - Both paths now use the same labels, icon gutter, animation, and
history controls.

## Linked Issues or Issue Description

Related: Refs #13255, which introduced rolling native-runner activity
groups.

**What happened?**

During a legacy CLI run, each new command added an expanded tool card
under an activity heading. The original legacy parity story rendered a
completed turn, so it did not exercise this live path.

**Expected behavior**

Show one current activity line per commentary group. Roll that line
forward when a new activity starts. Keep tool icons aligned on the left,
use friendly labels, and show history only when expanded.

**Steps to reproduce**

1. Start a task with the Codex local adapter using the CLI engine.
2. Ask it to read two files in separate tool calls and run a test
command.
3. Watch the activity feed while the run is active, then expand its
history.

**Paperclip version or commit**

The live behavior was reproduced on
bdee5ebb21b2d09280e49c88bc329435da1b07c8. This update includes both live
and saved rendering fixes.

**Deployment mode**

Built from source with the local test-drive command and a real Codex CLI
agent.

## What Changed

- Use `TaskChatRunnerActivityGroup` for both saved legacy phases and
`TaskChatLiveTail`.
- Align the legacy Working spinner with the shared activity icon gutter.
- Cover streamed reasoning updates, successive commands, image labels,
hidden details, and explicit history expansion in tests.
- Feed raw legacy transcript events through the real adapter and live
renderer in Storybook. Add live, expanded, narrow, light, and completed
stories with the final reply preserved.

## Verification

- Passed 195 targeted tests covering the live tail, status pill, shared
activity group, native turn, and full task thread.
- Passed UI typechecking, token gates, UI build, and Storybook build
before submission.
- Observed a real Codex CLI run while it read separate files and ran
tests. The current activity stayed at one 32-pixel row without an
accumulated tool list; the spinner and activity icon centers aligned.
- Compared native and legacy Storybooks: identical rolling animation,
fixed height, persistent expansion, truncated long labels, and correct
light and completed states.
- Full repository `pnpm -r typecheck` and `pnpm build` passed after
replaying the branch on current master, including the Rust runner. The
full `pnpm test:run` suite is still running.

## Risks

- Legacy activity now starts collapsed. Users can expand each group and
each row to inspect the same transcript details.
- Live runtime request cards must retain their timeline positions.
Existing task-thread and native-runner regression tests cover this
boundary.
- No API, database, or transcript format changes.

## Model Used

- OpenAI GPT-6 through Codex for the live-path fix, tests, and browser
verification. Capabilities used: reasoning, tool use, local code
execution, and image inspection. The exact deployment ID and
context-window size are not exposed in this session.
- The original saved-turn change recorded OpenAI Codex with GPT-5.6; its
exact variant and context size were not recorded.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [ ] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-09-15 16:40:32 -05:00
DottaandPaperclip d49f168381 fix: publish sandbox files on legacy and native runners (#13493)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Agents must publish generated files so users can inspect their
results after a sandbox stops.
> - Legacy sandbox bridges blocked attachment listing and could not
carry multipart binary uploads through the queue transport.
> - The native runner has a separate verified file registration path
that needs the same durable result.
> - This pull request repairs legacy binary transport, makes native
download receipts explicit, and reveals new outputs in the task
Artifacts tab.
> - Users can open generated files from either runner without a
transport flag change.

## Linked Issues or Issue Description

Refs #13355 for the existing native file publication path. Related
filename fixes: #2615 and #4788. Related sandbox persistence work:
#13376. This change repairs attachment delivery through the existing
API; it does not add workspace persistence.

**What happened?**

The upload helper first lists task attachments to avoid duplicates. Both
legacy bridge allowlists rejected that GET request with 403. A direct
multipart upload also failed: the queue bridge accepted only JSON,
excluded attachment uploads, and converted bytes to UTF-8 text. Enabling
HTTP/2 alone did not fix the missing listing route. These failures
occurred before attachment storage.

**Expected behavior**

Both runners can publish a workspace file, register its work product,
bind it to a response, and return a working download. The file stays
accessible after sandbox deletion. A new output opens the task Artifacts
tab. The agent receives accurate errors and decides how to retry or
report a failure.

**Steps to reproduce**

1. Run a legacy agent in Daytona with the duplex bridge disabled.
2. Invoke the bundled upload helper with Bash on a PNG or PDF.
3. Repeat with the duplex bridge enabled.
4. Register the same file through the native runner with generic API
tools disabled.
5. Retry registration, delete the sandbox, and compare the downloaded
bytes with the original file.

**Paperclip version or commit**

The failing baseline was `f2c5e54dc`. This branch is rebased onto
`6cfe4acff`.

**Deployment mode**

Source checkout with a local API and real isolated Daytona sandboxes.

## What Changed

- Allow authenticated attachment listing, upload, and content download
through both legacy bridge transports.
- Add optional base64 body encoding to queue envelopes. Preserve the
existing UTF-8 contract when the encoding field is absent. Decode binary
bodies before forwarding them.
- Preserve multipart headers. Bound raw bytes, encoded envelopes, and
in-flight reservations. Retain timeout and uncertain-write behavior.
- Preserve helper deduplication and return structured uncertain-write
failures. Document explicit Bash invocation in live skills.
- Add attachment IDs and content/download paths to native registration
receipts. Reuse verified local and remote file reads, attachment
storage, work-product registration, and response binding.
- Preserve Unicode upload filenames and provide a valid
Content-Disposition header.
- Open the task Artifacts tab when new stored outputs arrive, including
a closed desktop panel or mobile drawer. Deduplicate upload and
registration events by object ID. Preserve manual selection on
refetches, edits, and panel remounts.
- Remove task artifact filters, the company Artifacts footer link, and
the unassigned group heading and timestamp.

### Screenshot

![Generated images and a document in the task Artifacts
tab](https://pages.paperclip.ing/sandbox-file-delivery-2026-09-15/artifacts-tab.png)

This is the local display fixture. The image was generated separately
and published through the attachment and work-product APIs.

## Verification

- Post-rebase `pnpm -r typecheck` and `pnpm build` pass.
- The post-rebase local `pnpm test:run` passed 12,369 tests before one
existing conversation reset test timed out; all 33 tests in that suite
pass when rerun with isolated test configuration. The aggregate command
stopped before its remaining groups. GitHub runs the complete suite in
separate shards.
- All [GitHub verification
checks](https://github.com/paperclipai/paperclip/actions/runs/35017893350)
pass on `b66ac276dd3d5fc738a22ecea783400106a494d4`: 32 successful checks
and two configured skips. The native-session recovery assertion
initially raced its fire-and-forget Sentry report; all 13 tests pass
locally, and the same-commit CI rerun passes all 170 suites (3,079
tests).
- Live post-rebase Daytona: all three file-delivery tests pass. They
cover the real Bash helper with the queue bridge, the helper with
HTTP/2, and native `register_deliverable` with generic API tools
disabled.
- Daytona cases cover PNG/PDF bytes, spaced and Unicode names, duplicate
registration, response binding, authorization controls, and
byte-for-byte downloads after sandbox deletion.
- Local focused coverage includes transfer bounds, malformed encoding,
interrupted transfers, remote path containment, and native file
verification. The attachment route suite passes all 32 tests, including
an eight-case filename-header matrix for Unicode and special characters,
inline and forced downloads, and full and partial responses.
- Browser verification confirms image previews, persisted downloads,
automatic Artifacts selection, and preserved manual selection after
edits and reloads. Desktop/mobile component coverage passes. The latest
UI cleanup passes its 10 affected tests and token gates.
- Coverage limit: the Daytona tests call the real helper and native
registration path directly. They do not replay a complete model-led
image-generation task through the browser.

Live command (requires a configured Daytona credential):

```sh
PAPERCLIP_FILE_DELIVERY_DAYTONA=1 pnpm exec vitest run server/src/__tests__/file-delivery-bridges.test.ts
```

## Risks

- Binary queue bodies use more memory because base64 adds encoding
overhead. Transfer and process limits must remain aligned.
- An interrupted write can have an unknown result. The bridge reports
this state and preserves stable retry identities.
- New artifacts intentionally change the active task tab. Existing
history and repeated updates must not take focus again.
- Transport flag defaults, server authorization, frozen skill snapshots,
and completion policies remain unchanged. No schema migration is
required.

## Model Used

OpenAI Codex, based on GPT-6, with reasoning, repository tools, code
execution, and browser testing. The runtime does not expose a more
specific model ID or context-window size.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-09-15 15:46:57 -05:00
DottaandPaperclip f4cdc7b231 fix: recover transient workspace bootstrap scans (#13481)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - The control plane prepares task workspaces before it starts an
agent.
> - Workspace preparation reads Git state so it can preserve edits and
exclude private files.
> - A failed scan was treated as a non-Git folder and lost its actual
failure code.
> - The resulting generic setup failure could not recover, even when the
cause was temporary.
> - This pull request keeps the cause and uses the existing bounded
retry schedule before provider startup.
> - Tasks can recover without human intervention, while permanent
failures and exhausted retries stop with useful guidance.

## Linked Issues or Issue Description

**What happened?**

A Git scan error during managed repository preparation became
`Configured repository folder is not a Git checkout`, followed by
generic `setup_failed`. The agent never started. Generic recovery could
not distinguish a temporary timeout from a bad workspace configuration.

**Expected behavior**

Keep the closed scan error code. Retry temporary timeouts and queue
saturation under the existing shared budget. Preserve edits, exclusions,
ownership, and pause gates. Stop permanent failures and exhausted
retries with a specific explanation. Do not replay historical generic
setup failures.

**Steps to reproduce**

1. Configure a task project with a local Git source that must be copied
into its managed repositories.
2. Make the ignored-file scan exceed its timeout before the agent
starts.
3. Before this fix, the snapshot returns null and the run ends as
non-retryable `setup_failed`.
4. Use the disposable browser fixture in
`tests/e2e/workspace-bootstrap/README.md` to inject real timeouts and
test the full recovery path.

**Paperclip version or commit**

Reproduced against `4510bf7c9e2fcbeb043445850928b5dcb79908ca`.

**Deployment mode**

Built from source. The defect is in core workspace setup, not a specific
model provider.

Related work: Refs #13442 (managed repository preparation), Refs #11572
(bounded Git scheduler), Refs #12997 (separate adapter startup retry
work), Refs #13469 (separate terminal-workspace scan performance work).

## What Changed

- Return the non-Git fallback only for repository discovery. Propagate
failed scans of a confirmed repository.
- Replace full ignored status output with an ignored-only directory
listing. Preserve NUL-delimited paths and exclusions.
- Preserve typed, sanitized scan errors through workspace preparation
and persist pre-provider failure details.
- Retry only timeouts and queue saturation, using the existing durable
two-retry budget and issue gates. Prevent generic recovery from adding
another budget.
- Show workspace-specific failure copy and actionable exhausted-recovery
notices.
- Add red-green unit tests, real-database restart and retry-boundary
tests, and opt-in browser acceptance fixtures with real Git subprocess
timeouts.
- Document the recovery contract and browser verification procedure.

## Verification

- Red: injected scan failures returned null instead of rejecting; setup
lost the timeout code; task-thread and recovery notices had generic
copy.
- Green: 119 focused adapter/backend tests, 20 recovery-boundary tests,
and 136 task-thread tests.
- `pnpm -r typecheck` — passed.
- `pnpm build` — passed on the final production code.
- `pnpm check:token-gates` — passed.
- The initial local `pnpm test:run` overlapped source edits and was
interrupted after two late-added assertions saw pre-fix behavior; it is
not counted as a green full run. A fresh final-head run passed all 229
tests across the six affected adapter/backend/UI suites. The clean
latest-head CI full test matrix passed: all five general-server shards,
all five serialized-server shards, and all three general-workspace
shards.
- Latest-head CI also passed all three browser shards and their
aggregate gate, typecheck and release registry, build, runner
verification, canary dry run, policy, Docker context integrity, and
security gates. Greptile: 5/5, with the review thread resolved.
- Browser: created a task in a disposable instance. A real Git timeout
scheduled recovery, the next run completed through the run-scoped API
without manual Retry, and Done survived reload. The deterministic
process worker checked preserved source edits and excluded private
files; no model calls were made.
- `WORKSPACE_BOOTSTRAP_TEST_URL=<disposable-instance-url> pnpm exec
playwright test --config
tests/e2e/workspace-bootstrap/playwright.config.ts` — 2 passed (3.6
minutes). The persistent case made exactly three failed attempts, never
started the worker, showed the cause-specific notice, stayed stopped for
another scheduler tick, and retained Blocked after reload.
- Extra red-green coverage: 50 recovery tests passed after fixing an
exhausted-bootstrap classification that incorrectly implied unknown
provider actions. Missing or uncertain evidence still retains the safety
hold.
- Verified the documented Git executable override during repository
seeding.

## Risks

- A confirmed repository scan failure now fails closed instead of
falling back to directory sync. This prevents unfiltered copying but
makes previously hidden errors visible.
- Temporary host problems can create up to two additional setup
attempts, 30 seconds apart. Permanent scan errors do not auto-retry.
Generic recovery cannot reset this budget.
- The durable retry path still enforces ownership, pause, and work
eligibility. Integration tests cover restart, duplicate promotion,
pause, exhaustion, and non-retryable categories.
- No schema migration, new runtime setting, new retry budget, production
deployment, or historical task replay.

## Model Used

OpenAI Codex, GPT-5-based coding agent, with reasoning, repository
tools, shell execution, and browser testing. The exact deployment model
ID and context-window size are not exposed in this session.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-09-15 12:37:21 -05:00
Devin FoleyandPaperclip c0fda8fac5 fix(apps): restore action test picker scrolling and agent eligibility (#13414)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Apps action tests let operators use an agent's permissions.
> - The agent picker must scroll inside the test dialog.
> - Its body portal sits outside the dialog's scroll boundary and blocks
wheel input.
> - Admin permission bypasses also skip agent lifecycle checks.
> - This PR fixes scrolling and rejects agents that cannot receive
assignments.

## Linked Issues or Issue Description

**What happened?**

The Act as picker does not scroll with the mouse wheel inside an action
test dialog. Admins can also see terminated agents.

**Expected behavior**

The list scrolls normally. Terminated and pending-approval agents are
absent. Direct requests cannot test an action as one of those agents.

**Steps to reproduce**

1. Create enough agents to overflow the list. Terminate one agent.
2. Open a connected app's Permissions tab. Click Test on an action.
3. Open Act as and use the mouse wheel over the list.
4. Check whether the terminated agent appears as an admin.

**Paperclip version or commit**

Reproduced on master at f2c5e54dc. Rebased onto d351e08de.

**Deployment mode**

Local dev, built from source. This is a shared Apps bug and does not
require Railway credentials.

Related search result: #9918 added search to a separate secrets picker.
It does not cover this action test dialog. No duplicate action-test
picker PR was found.

## What Changed

- Keep the action tester's agent popover inside its dialog's scroll
boundary.
- Check company membership and the shared agent lifecycle policy before
assignment permission bypasses.
- Reject terminated and pending-approval agents in lists, previews, and
test calls.
- Reuse company-scoped rows during listing to avoid extra per-agent
queries.
- Add route tests for both admin modes and a browser wheel-scroll
regression.

## Verification

- 335 focused tool-access and TestPanel tests passed after rebase. After
the review cleanup, both admin regressions and writable-agent selection
passed again (3 tests).
- The browser regression failed before the fix because wheel input left
scrollTop at zero. It passed after the fix, including search and
selection. It executes no provider tools.
- Full typecheck, build, and token gates passed during implementation.
Token gates passed again after rebase.
- The full test run reported a failure in the GitHub installation
recovery chat test. That test passed in isolation. The full run was
stopped after the failure, so later groups were not completed.

Manual check: open an action's Test dialog, open Act as, scroll, search,
and select an agent. Terminated agents must be absent.

## Risks

The portal change affects only the picker inside the action test dialog.
The browser test covers scrolling and selection. Paused agents remain
eligible under existing assignment rules. There is no migration or
provider policy change.

## Model Used

OpenAI Codex, based on GPT-6, with code execution and browser testing.
The exact serving model ID and context window were not exposed in this
session.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [ ] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-09-14 21:18:12 -07:00
Nicky LeachandClaude Opus 5 b64469e403 feat(workspaces): add an operator default for isolated execution workspaces (#13444)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - The execution workspace subsystem decides if a task run uses the
shared project checkout or an isolated per-task git worktree
> - The mode comes from the project policy, then the task settings. A
project that stores no policy always falls back to the shared checkout
> - An operator who wants every project to use isolated workspaces must
therefore edit each project one at a time, and must repeat this for each
new project
> - There is no instance-level control, so a fleet operator cannot set
this default at all
> - This pull request adds a managed experimental flag that moves the
default for projects that store no policy of their own
> - The benefit is that an operator sets the workspace default one time,
and every current and future project follows it

## Linked Issues or Issue Description

No public issue exists. The description follows the feature request
template.

**Subsystem affected**

Execution workspaces. The files are
`server/src/services/execution-workspace-policy.ts` and the run dispatch
path in `server/src/services/heartbeat.ts`.

**Problem or motivation**

`resolveExecutionWorkspaceMode` reads only the project policy, the task
settings, and a legacy field. Its last statement returns
`shared_workspace`. A project that stores no policy always gets the
shared project checkout.

An operator has no way to change this default for many projects at the
same time. The operator must edit each project, and must edit each new
project again later. Tasks in one project therefore share one checkout,
and they run one at a time when the environment driver makes the
scheduler serialize them.

**Proposed solution**

Add the managed experimental flag `enableIsolatedWorkspacesByDefault`.
When the flag is on, a project that stores no policy of its own resolves
as if it selected isolated workspaces. A project that stores a policy
keeps that policy.

The new helper substitutes a project policy. It does not move the last
statement of `resolveExecutionWorkspaceMode`. Two behaviors make this
necessary:

- A task that has no project must keep its current behavior. An isolated
workspace needs a repository to cut a worktree from.
`isUnrunnableWorktreeCombo` blocks an isolated task that has no
`projectId` and no `projectWorkspaceId`. A moved fallback would resolve
isolated for project-less tasks, such as agent chat, and stop them
before dispatch.
- The mode and the strategy must agree.
`buildExecutionWorkspaceAdapterConfig` supplies the default
`git_worktree` strategy only when one layer asserts workspace control. A
moved fallback would leave isolated mode with a `project_primary`
strategy.

**Alternatives considered**

- Change the last statement of `resolveExecutionWorkspaceMode` to
`isolated_workspace`. This is one line, but it changes the default for
every deployment. It is also not gated, so it would apply where isolated
workspaces are off.
- Write the policy to each project row with a script. This does not
cover new projects, and it does not cover new instances.
- Add an instance defaults section to the managed-config document. This
needs a new document key, new validation, and new delivery code. A
boolean flag reuses the delivery machinery that exists today.

**Roadmap alignment**

`ROADMAP.md` does not list execution workspace defaults. This change
adds an operator control to an existing capability. It does not add a
new capability.

**Additional context**

The flag is `tier: "managed"`. A cloud operator can therefore deliver it
with the managed-config machinery that exists today. No new delivery
code is needed.

## What Changed

- Add `enableIsolatedWorkspacesByDefault` to the feature catalog with
`tier: "managed"`. Both defaults are off.
- Add the flag to the experimental settings schema, the type, and both
branches of `normalizeExperimentalSettings`.
- Add `applyDefaultIsolatedExecutionWorkspacePolicy` to
`execution-workspace-policy.ts`. It substitutes `{ enabled: true,
defaultMode: "isolated_workspace" }` only when the flag is on, the task
has a project, and the project stores no policy.
- Apply the helper in the run dispatch path in `heartbeat.ts`, after the
existing `gateProjectExecutionWorkspacePolicy` call. The `hasProject`
argument reads the resolved project row, not the raw `projectId` of the
task.
- Gate the new flag behind `enableIsolatedWorkspaces` at the call site.
The new flag does nothing on its own.
- Add a toggle card to the instance experimental settings page. The card
shows only when isolated workspaces are on.
- Add eight tests for the new helper.

## Verification

Commands:

```
pnpm --filter @paperclipai/shared typecheck
pnpm --filter @paperclipai/ui typecheck
cd server && ../node_modules/.bin/tsc --noEmit
```

The server typecheck script also builds a Rust binary. I ran `tsc`
directly because this machine has no `cargo`. The server package reports
no type errors.

Tests:

```
./node_modules/.bin/vitest run \
  server/src/__tests__/execution-workspace-policy.test.ts \
  server/src/__tests__/instance-settings-service.test.ts \
  server/src/__tests__/instance-settings-cloud-defaults.test.ts \
  server/src/__tests__/instance-settings-managed-overlay.test.ts \
  server/src/__tests__/instance-settings-routes.test.ts \
  server/src/__tests__/managed-config.test.ts \
  server/src/__tests__/heartbeat-workspace-busy.test.ts \
  server/src/__tests__/heartbeat-workspace-session.test.ts \
  server/src/__tests__/heartbeat-workspace-ready-comment.test.ts \
  server/src/__tests__/execution-workspaces-service.test.ts \
  server/src/__tests__/issue-runtime-workspace-binding.test.ts \
  server/src/__tests__/run-trust-preset.test.ts \
  packages/shared/src/feature-catalog.test.ts \
  packages/shared/src/settings-visibility.test.ts \
  packages/shared/src/validators/instance.test.ts \
  ui/src/pages/InstanceExperimentalSettings.test.tsx \
  ui/src/components/Sidebar.test.tsx
```

All of these files pass. The new tests cover each of these cases:

- The helper substitutes an isolated policy for a project that stores
none.
- The helper changes nothing while the flag is off.
- The helper changes nothing for a task that has no project.
- The helper keeps a stored policy, including a policy with `enabled:
false`.
- The resolver returns `isolated_workspace` for an unpolicied project.
- An explicit task setting still wins over the operator default.
- The substituted policy produces the `git_worktree` strategy.
- A project-less task does not become an unrunnable worktree.

To confirm the behavior by hand:

1. Turn on Isolated Workspaces, then turn on Use Isolated Workspaces By
Default.
2. Open a project that has no execution workspace policy.
3. Start a task in that project.
4. The run gets its own worktree. Tasks in that project no longer wait
for each other.

## Risks

Low to medium. The details:

- The flag defaults to off, and it is inert unless
`enableIsolatedWorkspaces` is also on. An instance that does not turn on
both flags sees no change.
- A project that stores a policy keeps it. This includes a policy with
`enabled: false`, which the helper reads as a decision to stay on the
shared checkout.
- When an operator turns the flag on, the workspace configuration
fingerprint changes for projects that store no policy. Their next run
creates a new workspace. This is correct, because the mode did change,
but the first run after the change does more setup work.
- A task that is in flight when the flag changes resumes with a
different workspace path than the path its session remembers. An
operator should let current runs finish before turning the flag on.
- Isolated workspaces use more disk, because each task gets its own
worktree.

## Model Used

Claude Opus 5 (`claude-opus-5`) in Claude Code, with extended thinking
and tool use. The model read the repository, made the change, and ran
the typechecks and tests above.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 20:59:56 -07:00
DottaandPaperclip f912ecaacf fix: carry AI connections through hiring and unblock task execution (#13438)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Agents hire other agents and assign tasks to them.
> - Managed AI connections must follow those hires across legacy and
native runners.
> - Missing accounts should pause task execution and let the user
connect from the task.
> - Subscription contention must wait without asking for new
credentials.
> - This pull request fixes these paths and the native tool and Daytona
staging failures found during live tests.
> - The result is a working hire, subtask, and connection setup flow on
local and remote runners.

## Linked Issues or Issue Description

**What happened?**

A managed Claude or Codex agent could hire a teammate without a usable
AI binding. Cross-provider hiring could fail before the user had a
chance to connect the new provider. First-time task setup did not show
the existing AI credential form inline. A busy subscription could
request a new connection. Native API replies could stop the parent after
a hire had already committed. Fresh Daytona sandboxes could fail to
extract read-only skill directories created on macOS.

**Expected behavior**

Compatible hires inherit the managed connection choice. A hire for
another provider uses the responsible user's default. If that account is
missing, the hire succeeds and the task asks for a connection.
Completing setup in the task resumes work automatically. Explicit child
auth settings and existing unmanaged login paths keep precedence.
Shared-account access checks remain in force.

**Steps to reproduce**

1. Connect a Claude or Codex parent with a managed AI account.
2. Ask it to hire one agent of each provider and create a self-assigned
subtask.
3. Assign work to both hires without connecting the second provider
first.
4. Connect the missing provider from its task card.
5. Check that all tasks finish and same-provider work uses the original
account.
6. Repeat with native runners and fresh Daytona sandboxes. The opt-in
browser suite in `tests/hiring-ai-connections/README.md` performs these
steps.

**Paperclip version or commit**

The live failures were reproduced from `f2c5e54dc`. The branch is
rebased onto `5282cabde`.

**Deployment mode**

Isolated local development instance. Legacy CLI and native runners.
Local execution and ephemeral Daytona sandboxes.

Related work: Refs #13247 for managed AI connections. Refs #13268 for
legacy credential-reference inheritance, which this branch preserves.
Refs #13432 for a concurrent managed-inheritance fix. This PR also
covers cross-provider task setup, subscription waits, native API
replies, and Daytona extraction. It permits missing responsible-user
defaults at hire time; restricted shared selections still fail.

## What Changed

- Apply managed connection defaults to both agent creation routes.
Preserve explicit auth choices and legacy credential-reference
inheritance.
- Allow hires before their responsible user connects the provider. Keep
approval gates, company boundaries, and shared-account access checks.
- Reuse the production AI credential form inside the pending task card.
Resume the task after setup.
- Retry subscription lease contention without consuming the
provider-failure allowance or creating a connection request.
- Require task execution-lock ownership when scheduling, promoting, and
dispatching subscription retries. Recheck ownership under the issue row
lock.
- Rename the HTTP operation identity at the native tool boundary so it
cannot override the runner's operation identity.
- Delay directory permission restoration during Daytona extraction.
Preserve the final read-only modes.
- Add database-backed regressions, real browser acceptance tests, and
Storybook states. Document setup and run-log behavior.

## Verification

- Six real browser scenarios passed: both parent providers on legacy
local and legacy Daytona; native Codex locally; native Claude on
Daytona. Each scenario hires both providers, completes a self-subtask
and assigned work, and connects the missing provider inline with
automatic continuation.
- Successful runs verify the account, responsible user, runner mode, and
Daytona lease. All 18 test sandboxes were deleted.
- Live authentication used API keys. Subscription inheritance, lease
contention, and retry have integration coverage. Fresh subscription
OAuth sign-in was not automated.
- Red/green tests reproduced missing bindings, missing inline forms,
subscription contention, native API reply failure, and GNU tar
permission failure.
- Seven Storybook browser checks passed. They cover both providers,
method selection, narrow layout, completion, cancellation, and invalid
credentials.
- Full local suite coverage completed before rebase. Initial timing and
fixture startup failures passed unchanged on isolated reruns. The first
full command did not exit cleanly; the remaining workspace and
serialized groups were completed separately.
- After rebase, 107 hiring/auth/retry tests and 59 native API,
task-card, and Daytona tests passed. The full workspace typecheck,
production build, and token gates passed again. Storybook build passed
before rebase.

- Review fixes: 169 hiring/retry/dispatch tests, 37 adjacent tests, and
four explicit cancellation-race cases passed. Eight cross-provider cases
cover stale auth keys on both creation routes and both runner types.
Server typecheck and build passed.

- Final CI on `ee4890837a8a4913e07453392b9a75969580dae1`: 32 checks
passed. Two optional Storybook jobs were skipped. The full server,
workspace, browser, native runner, build, typecheck, and release checks
passed.
- Three unchanged tests initially failed on a busy port, a chat row-lock
race, and preview-server readiness. Each affected job passed after one
CI rerun. Isolated local checks also passed: 41 credential tests, the
chat-concurrency case, and 25 preview-runtime tests.
- Greptile reviewed the final commit at 5/5. Both review threads are
resolved. GitHub reports no merge conflicts.

## Risks

- A missing personal account now defers authentication to the first
task. Explicit incompatible bindings and restricted shared accounts
still fail at hire time.
- An inherited personal default uses the responsible user's existing
authorization to install access for the new agent. It never copies
credentials or another user's identity.
- Subscription contention retries after a delay and rechecks task
eligibility. It does not consume the provider-failure budget.
- Native hiring uses the existing managed API-tools opt-in. Remote
native runners require a matching Linux binary and provider pack, as
documented in the acceptance README.
- No schema changes. Live tests make paid provider calls and remain
opt-in.

## Model Used

OpenAI GPT-6 (`gpt-6-astra`) in Codex, with reasoning, repository
inspection, code execution, browser automation, and API tools. The
context-window size is not exposed in this session.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-09-14 16:15:48 -05:00
DottaandPaperclip 5282cabde8 fix(ui): make every agent reachable from Chats (#13420)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Experimental Agent Chat gives each person a persistent conversation
with each agent.
> - The sidebar only showed starred or previously visited agents.
> - A person could not start a conversation with an agent absent from
that list.
> - This pull request adds a searchable agent picker and a default
sidebar entry.
> - People can now reach every company agent while keeping their
frequent conversations close.

## Linked Issues or Issue Description

Refs #13283, which introduced the existing task-backed agent chat
surface. This change adds discovery to that surface after maintainer
review of the Storybook design.

**What happened?**

With Agent Chat enabled, a person with no starred or recent agents had
no agent shortcut. The sidebar also lacked a direct way to start a chat
with another agent.

**Expected behavior**

Show the first-created company agent by default. Let the person search
all company agents and open a persistent conversation.

**Steps to reproduce**

1. Enable Agent Chat in a company with agents.
2. Use an account with no starred agents or recent chats.
3. Look for a chat entry in the sidebar, or try to chat with an agent
absent from its shortcuts.

**Paperclip version or commit**

The existing behavior is present on master at 728f7185f.

## What Changed

- Add a compact picker that searches every company agent by name or
role. Include loading, retry, empty, and no-match states.
- Keep the first-created agent in Chats alongside stars and up to four
other recent conversations.
- Align the compose button with stars. Show it on hover or keyboard
focus, and keep it visible on touch devices.
- Use the existing company-aware chat route. Close the mobile sidebar on
selection and reset the picker when the company or user changes.
- Connect the approved Storybook scenarios to the production sidebar and
picker. Update product and design-guide documentation.

## Verification

- Ten focused tests pass for ordering, duplicate names, role search,
keyboard selection, search reset, retry states, full-roster navigation,
mobile dismissal, and company/user changes.
- The agent-chat sidebar end-to-end test passes against an isolated
PostgreSQL container. It verifies the first-use default, picker
navigation, lazy creation, stars, draft preservation, and reopening
existing history. The old four-row and See all link expectations now
match the approved behavior.
- Browser review of the production components in Storybook: open the
sidebar picker, search for an agent absent from the shortcuts, select
with Enter, and send a message through the existing composer.
- `pnpm build`, `pnpm -r typecheck`, `pnpm check:token-gates`, and `pnpm
build-storybook` pass on the rebased branch. The full local test run
reached 12,020 passing server tests, then stopped because an unrelated
environment-custom-images suite could not allocate PostgreSQL shared
memory on this Mac. All corresponding CI test shards pass on isolated
hosts.
- All CI checks pass on commit
`c324568324a6a8b65adfc6447ef19bcc710c61df`. Greptile reviewed that
commit at 5/5 with no open findings.
- Reviewer path: enable Agent Chat, open the Chats compose button,
search by name or role, and select an agent. Existing conversation
history must remain available.

## Risks

- Sidebar ordering changes: the earliest-created agent remains visible
even without a visit or star.
- The hover control remains available to keyboard and touch users.
- This change uses the existing feature gate, APIs, membership
preferences, and persistent conversation behavior. It adds no migration
or server contract.
- Storybook uses fixture responses. Its first-use landing page is a
review fixture and is not added as a product route.

## Model Used

OpenAI GPT-6 Astra (`gpt-6-astra`) through Codex, with reasoning, code
execution, and browser tools. The session does not expose its context
window size.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-09-14 13:19:13 -05:00
DottaandPaperclip 78ce96a48b fix(runner): restore native Claude context and read permissions (#13422)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - The native runner supplies each agent with instructions, assigned
skills, and tools.
> - Native Claude lost its skill snapshot before provider launch. It
also changed exact model IDs to aliases.
> - The read permission mode denied ordinary Paperclip reads because
this runner has no interactive approval handler.
> - This pull request restores the missing context and permits only
assigned tools that Paperclip defines as reads.
> - Other requests that need approval stop with a clear action for the
operator. They do not retry automatically.
> - Agents can complete read tasks. Users can see why a restricted task
stopped.

## Linked Issues or Issue Description

**What happened?**

Native Claude could not find assigned skills. The ACP layer could
replace an exact model ID with an alias and then fail identity
verification. The default `approve-reads` mode denied Paperclip read
tools. A denied write showed a generic transport failure.

The tool descriptions also called live operations “mock” operations. The
completion prompt said to call a completion tool once, although the
protocol can reject a claim and require a corrected call.

**Expected behavior**

Load assigned skills before launch. Keep the selected model ID. Allow
assigned Paperclip reads. Stop an operation that needs approval with
clear instructions when no approval handler exists.

**Steps to reproduce**

1. Configure a native Paperclip Runner agent with ACPX Claude and an
exact model ID.
2. Assign a skill and ask the agent to use it.
3. Select the read permission mode and ask the agent to read task
context and list documents.
4. Ask the agent to write a document. Check the task state and recovery
message.

**Paperclip version or commit**

Reproduced from `d351e08deee1b49d3467a950d1a3f01131943441`.

**Deployment mode**

Local native runner with real Claude, Rust runnerd, the Paperclip
server, and embedded PostgreSQL.

Related: #13196 fixed remote skill staging in the legacy `claude_local`
adapter. The native runner uses a separate path, which this pull request
fixes.

## What Changed

- Carry the runtime context through Rust and the ACPX sidecar. Load
assigned Claude skills after the provider lifetime lease is held.
Refresh the files on each open.
- Write the exact requested model ID into the isolated Claude settings.
- Grant exact MCP permissions for the intersection of assigned tools and
Paperclip's read catalog. Provider hints cannot grant access. Existing
task-control permissions stay in place.
- Stop requests that need an unavailable approval handler. Preserve the
typed error through the server. Show “Approval required” on the task and
require operator action without automatic retry.
- Label the setting “Allow Paperclip reads.” Remove “mock” from live
tool descriptions and regenerate the contracts.
- Change one completion-prompt sentence to require one accepted result.
Add regression tests and update the runner documentation.

## Verification

- Red/green regression tests cover read admission, unavailable approval
handling, server recovery, and the task error message.
- A real Claude read trial failed before the fix and completed after it:
[red
trace](https://www.braintrust.dev/app/Paperclip/object?object_type=project_logs&object_id=fda74078-b00d-495a-90d3-ea1be019d71b&id=95e6a326e24437f1),
[green
trace](https://www.braintrust.dev/app/Paperclip/object?object_type=project_logs&object_id=fda74078-b00d-495a-90d3-ea1be019d71b&id=85a1f347db5604d1).
- Full browser tests used real Claude and the production tool authority.
Reads completed. A write stopped with “Approval required.” No document
was created and no automatic retry was scheduled. All nine checks
passed: [events and
screenshots](https://www.braintrust.dev/app/Paperclip/object?object_type=project_logs&object_id=fda74078-b00d-495a-90d3-ea1be019d71b&id=1c4ff10be0d779cc).
- A separate full browser test assigned a skill, invoked it, and
completed with a marker absent from the task prompt: [skill
evidence](https://www.braintrust.dev/app/Paperclip/object?object_type=project_logs&object_id=fda74078-b00d-495a-90d3-ea1be019d71b&id=ba5fbcb29a60be52).
- Post-rebase checks passed: 128 targeted runner tests, 46 Rust tests,
27 sidecar/protocol contract tests, `pnpm -r typecheck`, and `pnpm
build`. The server/UI red-green checks and `pnpm check:token-gates` also
passed. The full suite passed in CI, including all general and
serialized test shards, all three browser shards, and runner
`check:all`. The duplicate unsharded local full-suite run was stopped
after CI passed.

Braintrust links require project access. The traces contain
provider/runner events and app outcomes. They do not contain raw model
HTTP requests.

## Risks

- `approve-reads` now allows assigned Paperclip reads. Other operations
that need approval stop the turn. Users must review the operation and
change permissions before retrying.
- The Claude settings depend on the pinned ACP and SDK behavior.
Automated tests and real Claude trials cover this boundary.
- The native Codex path is unchanged. The ACPX Codex fallback shares the
clearer approval failure handling.
- Local execution was tested end to end. Remote execution was not run.
This change has no database migration.

## Model Used

OpenAI GPT-6 through Codex. The agent used reasoning, code execution,
and browser tools. The exact deployment ID and context-window size were
not exposed in the session. Live acceptance tests used
`claude-sonnet-5`.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-09-14 10:56:24 -05:00
DottaandPaperclip 728f7185f6 feat: add native in-app announcements with persistent dismissal (#13403)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Self-hosted boards need a way to show occasional product
announcements.
> - An app release should not be required to publish or withdraw a card.
> - Native card controls keep publishing consistent; the hero can use a
static image or isolated HTML/CSS animation.
> - This pull request renders a validated JSON feed with native
components.
> - It stores dismissals per account on each instance, so a closed card
stays closed across companies and browsers.
> - Named staging feeds let authors test content before production
publication.

## Linked Issues or Issue Description

**Subsystem affected**

Board application shell, announcement delivery, and user preferences.

**Problem or motivation**

Operators need a small, optional announcement card. Users need reliable
dismissal state. Authors need to test remote content without changing
the production feed.

**Proposed solution**

Add one non-modal AnnouncementWell. Fetch validated JSON and
content-addressed media through the instance server. Keep card controls
native, with optional sandboxed HTML/CSS animation in the hero. Use
stable announcement IDs for dismissal, an explicit empty manifest and
quiet 404 handling. Provide a staged publishing helper and isolated
test-drive guide.

**Alternatives considered**

Hosting the entire card as a page would move navigation and dismissal
into remote content. This change limits HTML to a scriptless, isolated
visual hero and keeps controls native. Browser-only storage would lose
dismissals across browsers, so the instance stores account preferences.

**Roadmap alignment**

ROADMAP.md has no overlapping announcement feature. A GitHub title
search found no related announcement pull requests. This work implements
a maintainer-requested feature.

## What Changed

- Add shared feed types, strict validation of every object, supported
routes, expiration and version checks.
- Add a board-only current-feed API, constrained media proxy, and
idempotent dismissal API. Store the first dismissal and its company
audit entry in one transaction.
- Cache upstream data for one hour. Use conditional requests, request
deduplication, response limits, public destination checks, and a
three-second deadline. Treat a remote 404 as an empty feed with a
fifteen-minute retry cooldown.
- Keep announcement visibility stable when focus moves to browser chrome
or another app pane; only tab visibility starts a return check.
- Add a responsive native announcement card. Respect onboarding, dialogs
and toast placement. Sync pending dismissals across tabs and retry after
reconnect or return.
- Add idempotent migrations for dismissals and validated publication
IDs, design-guide examples, static and animated Storybook examples, and
focused tests. The publication registry supports offline retries without
accepting caller-invented IDs.
- Add HTML/CSS animated heroes with static posters, automatic playback,
reduced-motion handling, strict DOMPurify validation, an empty iframe
sandbox and CSP that blocks scripts/network resources.
- Add validated staging publication, content-addressed assets, an empty
production manifest, preview fixtures, and authoring/operator
documentation.

## Verification

- The preceding implementation passed 98 targeted
shared/server/publisher/route/OpenAPI/UI tests and 127 tests including
the master rebase. The playback-control removal passes all 21
announcement UI tests, covering the rendered sandbox, fallback, reduced
motion, dismissal and slow/stale state lookups. The preceding
shared/server tests cover HTML validation and response sandbox headers.
- The playback-control removal passes UI typecheck, production UI build,
Storybook build and token gates locally. Browser verification confirms
the animated card has only its dismiss button and two links, with no
page errors. The full canonical CI matrix passed on current head
`00e416431edb610861599d50490270bbd0f3c6b6`: 32 successful checks and two
optional Storybook deployment checks skipped. This run needed no
retries. Greptile reviewed this same head at 5/5 with no outstanding
findings.
- The local canonical general-server run passed 12,063 tests before
reporting embedded-PostgreSQL startup failures in an unrelated fixture.
All 31 tests in that fixture passed across isolated retries. The UI
group passed 6,219 tests and other workspace groups passed 3,201; two
CLI database-startup failures also passed individually. Serialized
server suites were verified by the full CI matrix rather than repeating
them locally. No source changes were needed for these environment
failures.
- The real S3/CloudFront staging manifest and both media asset headers
were verified. Production remains empty/unpublished. The guide
distinguishes the preview host's disabled edge cache from production
cache requirements.
- In the isolated test-drive, the animation visibly moves without
playback controls. A 390×844 browser viewport keeps the card above
navigation. Reduced motion makes no animation request. Both themes
render correctly and browser page errors are empty. Browser fault
injection verified that scripts cannot execute and CSS cannot make
network requests; a missing animation leaves its poster and controls.
- Refresh leaves the animated card visible. Closing it persists after
reload and the API returns null. Earlier live checks verified dismissal
across browsers, company-relative CTA navigation, modal
deferral/restoration, and new-ID eligibility after restarting the same
database.
- The deployed empty feed and a real remote 404 return HTTP 200 with
null from the board API, with a usable dashboard and no announcement
popup or browser warnings.
- Authoring documentation covers staging, animated HTML constraints,
test-drive, withdrawal, ID reuse and cache-refresh steps.

## Risks

- Animation supports self-contained visual HTML/CSS and inline SVG,
without JavaScript or external resources. A static image is required.
Older builds that do not recognize the optional animation field quietly
hide that unsupported feed.
- The default feed makes an outbound request from an instance when a
board is used. Operators can disable it. Requests contain no account
IDs, company data, cookies or interaction events.
- Feed publication and withdrawal can take about 65 minutes to reach
returning users because of CDN and instance caches. Expiration also
removes visible cards locally.
- Dismissals follow an account within one instance. No-login instances
share the existing local-board identity. Separate installations do not
share state.
- Both tables are additive. A unique key prevents duplicate dismissals;
the transaction prevents duplicate first-dismissal audit entries. The
publication registry retains only validated IDs. AGENTS.md and the
implementation spec document the required exception to company scope for
these instance-level records.
- Publication was limited to separate public staging prefixes on the
existing preview host. Production remains empty/unpublished. No AWS
policies or infrastructure were changed.

## Model Used

OpenAI GPT-6 through Codex. The exact runtime model ID and
context-window size are not exposed in this session. Capabilities used:
reasoning, code editing, shell execution, tests, browser interaction,
and tool use.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-09-14 10:19:54 -05:00
DottaandPaperclip f1d57863d2 fix: make connection checks and task handoffs reliable (#13404)
Preserve connection-probe outcomes through cleanup, reduce unrelated startup work, and report selected Claude authentication accurately. Make artifact download actions match their labels.

Route delegated feedback through its active child, retain accepted messages across completion, and avoid redundant worker runs for proven closing notes. Preserve explicit follow-ups, human input, company boundaries, source provenance, and mixed issue references.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-09-14 10:06:06 -05:00
Michael Nguyen 2d47a8058d fix(apps): update connector artwork and theme fallback (#13361)
> Awaiting author review. Do not merge until the author explicitly
approves.

## Thinking Path

> - Paperclip helps people manage AI agents for work.
> - Connector screens need recognizable app artwork.
> - Several bundled marks have inconsistent artwork or dark-theme
behavior.
> - The shared logo component should retain the existing frame.
> - This change replaces selected artwork and fixes local theme
fallback.
> - Users see consistent connector icons across shared component
callers.

## Linked Issues or Issue Description

**Current behavior**

Some connector marks use outdated artwork or unsuitable theme variants.
A remote dark logo can override a canonical local mark that works in
both themes.

**Proposed behavior**

Use the selected bundled artwork with the existing gray rounded frame.
Use local light artwork in both themes unless a distinct local dark
variant exists.

**Subsystem affected**

Connector artwork, the shared AppLogo resolver, and its validation.

**Breaking changes**

No connector capability, permission, credential, or catalog activation
changes. No duplicate PR was found in the earlier search.

## What Changed

- Update 46 artwork files and only the app definitions whose logo paths
need to change.
- Keep a compact public manifest of identities, paths, visibility, and
aliases.
- Prefer local artwork in both themes and preserve the existing frame
and padding.
- Add locally runnable artwork safety checks and a light/dark Storybook
gallery; leave PR workflows unchanged.
- Document artwork conventions. Source research is kept outside the
public manifest.

## Verification

- Artwork check: 69 identities pass.
- Node artwork validation tests: 13 pass (rechecked September 14).
- Focused resolver, component, and catalog tests: 40 pass (rechecked
September 14).
- Maintainer decision: dedicated icon-validation CI is not required; the
workflow remains unchanged. Greptile acknowledged 5/5 with no remaining
code concerns on September 14.
- UI typecheck, token gates, and Storybook build pass.
- Earlier full build and repository typecheck passed. The broad local
test run was stopped after workspace-runtime dependency fixture failures
outside this change. Current GitHub CI remains the full-suite gate.
- Visual approval remains outstanding. Review the canonical icon
registry in both themes at 24–48px.

## Risks

The SVG checker rejects common active features; it is not a general
sanitizer for arbitrary uploads. Optical balance still requires human
review. Remote fallback for unknown brands retains existing behavior.
This change does not add an asset importer or new connector
capabilities.

## Model Used

OpenAI Codex, assisted by GPT-5 and GPT-6 with code execution and
browser tooling. Exact hosted model IDs and context window sizes were
not exposed.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [ ] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [ ] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge


## Artwork comparison

Before and after for every affected identity. Images follow your GitHub
light/dark theme and are pinned to the base and PR commits. This
compares artwork; the existing gray rounded product frame and padding
are unchanged.

| Connector | Before | After |
|---|:---:|:---:|
| AgentMail | <picture><source media="(prefers-color-scheme: dark)"
srcset="https://raw.githubusercontent.com/paperclipai/paperclip/c9e3bb7ca40160b2ff80958ec1a8c0254638ad42/ui/public/brands/apps/agentmail-dark.svg"><img
src="https://raw.githubusercontent.com/paperclipai/paperclip/c9e3bb7ca40160b2ff80958ec1a8c0254638ad42/ui/public/brands/apps/agentmail.svg"
alt="AgentMail" width="48" height="48"></picture> | <picture><source
media="(prefers-color-scheme: dark)"
srcset="https://raw.githubusercontent.com/paperclipai/paperclip/ea053c60d9d2c5c3470275e2f4dfde5f8fe5db53/ui/public/brands/apps/agentmail.svg"><img
src="https://raw.githubusercontent.com/paperclipai/paperclip/ea053c60d9d2c5c3470275e2f4dfde5f8fe5db53/ui/public/brands/apps/agentmail.svg"
alt="AgentMail" width="48" height="48"></picture> |
| Airtable | <picture><source media="(prefers-color-scheme: dark)"
srcset="https://raw.githubusercontent.com/paperclipai/paperclip/c9e3bb7ca40160b2ff80958ec1a8c0254638ad42/ui/public/brands/apps/airtable.svg"><img
src="https://raw.githubusercontent.com/paperclipai/paperclip/c9e3bb7ca40160b2ff80958ec1a8c0254638ad42/ui/public/brands/apps/airtable.svg"
alt="Airtable" width="48" height="48"></picture> | <picture><source
media="(prefers-color-scheme: dark)"
srcset="https://raw.githubusercontent.com/paperclipai/paperclip/ea053c60d9d2c5c3470275e2f4dfde5f8fe5db53/ui/public/brands/apps/airtable.svg"><img
src="https://raw.githubusercontent.com/paperclipai/paperclip/ea053c60d9d2c5c3470275e2f4dfde5f8fe5db53/ui/public/brands/apps/airtable.svg"
alt="Airtable" width="48" height="48"></picture> |
| Asana | <picture><source media="(prefers-color-scheme: dark)"
srcset="https://raw.githubusercontent.com/paperclipai/paperclip/c9e3bb7ca40160b2ff80958ec1a8c0254638ad42/ui/public/brands/apps/asana.svg"><img
src="https://raw.githubusercontent.com/paperclipai/paperclip/c9e3bb7ca40160b2ff80958ec1a8c0254638ad42/ui/public/brands/apps/asana.svg"
alt="Asana" width="48" height="48"></picture> | <picture><source
media="(prefers-color-scheme: dark)"
srcset="https://raw.githubusercontent.com/paperclipai/paperclip/ea053c60d9d2c5c3470275e2f4dfde5f8fe5db53/ui/public/brands/apps/asana.svg"><img
src="https://raw.githubusercontent.com/paperclipai/paperclip/ea053c60d9d2c5c3470275e2f4dfde5f8fe5db53/ui/public/brands/apps/asana.svg"
alt="Asana" width="48" height="48"></picture> |
| ClickHouse | <picture><source media="(prefers-color-scheme: dark)"
srcset="https://raw.githubusercontent.com/paperclipai/paperclip/c9e3bb7ca40160b2ff80958ec1a8c0254638ad42/ui/public/brands/apps/clickhouse.svg"><img
src="https://raw.githubusercontent.com/paperclipai/paperclip/c9e3bb7ca40160b2ff80958ec1a8c0254638ad42/ui/public/brands/apps/clickhouse.svg"
alt="ClickHouse" width="48" height="48"></picture> | <picture><source
media="(prefers-color-scheme: dark)"
srcset="https://raw.githubusercontent.com/paperclipai/paperclip/ea053c60d9d2c5c3470275e2f4dfde5f8fe5db53/ui/public/brands/apps/clickhouse-dark.svg"><img
src="https://raw.githubusercontent.com/paperclipai/paperclip/ea053c60d9d2c5c3470275e2f4dfde5f8fe5db53/ui/public/brands/apps/clickhouse.svg"
alt="ClickHouse" width="48" height="48"></picture> |
| Cloudflare | <picture><source media="(prefers-color-scheme: dark)"
srcset="https://raw.githubusercontent.com/paperclipai/paperclip/c9e3bb7ca40160b2ff80958ec1a8c0254638ad42/ui/public/brands/apps/cloudflare.svg"><img
src="https://raw.githubusercontent.com/paperclipai/paperclip/c9e3bb7ca40160b2ff80958ec1a8c0254638ad42/ui/public/brands/apps/cloudflare.svg"
alt="Cloudflare" width="48" height="48"></picture> | <picture><source
media="(prefers-color-scheme: dark)"
srcset="https://raw.githubusercontent.com/paperclipai/paperclip/ea053c60d9d2c5c3470275e2f4dfde5f8fe5db53/ui/public/brands/apps/cloudflare.svg"><img
src="https://raw.githubusercontent.com/paperclipai/paperclip/ea053c60d9d2c5c3470275e2f4dfde5f8fe5db53/ui/public/brands/apps/cloudflare.svg"
alt="Cloudflare" width="48" height="48"></picture> |
| Cloudinary | <picture><source media="(prefers-color-scheme: dark)"
srcset="https://raw.githubusercontent.com/paperclipai/paperclip/c9e3bb7ca40160b2ff80958ec1a8c0254638ad42/ui/public/brands/apps/cloudinary-dark.svg"><img
src="https://raw.githubusercontent.com/paperclipai/paperclip/c9e3bb7ca40160b2ff80958ec1a8c0254638ad42/ui/public/brands/apps/cloudinary.svg"
alt="Cloudinary" width="48" height="48"></picture> | <picture><source
media="(prefers-color-scheme: dark)"
srcset="https://raw.githubusercontent.com/paperclipai/paperclip/ea053c60d9d2c5c3470275e2f4dfde5f8fe5db53/ui/public/brands/apps/cloudinary-dark.svg"><img
src="https://raw.githubusercontent.com/paperclipai/paperclip/ea053c60d9d2c5c3470275e2f4dfde5f8fe5db53/ui/public/brands/apps/cloudinary.svg"
alt="Cloudinary" width="48" height="48"></picture> |
| Discord | <picture><source media="(prefers-color-scheme: dark)"
srcset="https://raw.githubusercontent.com/paperclipai/paperclip/c9e3bb7ca40160b2ff80958ec1a8c0254638ad42/ui/public/brands/apps/discord.svg"><img
src="https://raw.githubusercontent.com/paperclipai/paperclip/c9e3bb7ca40160b2ff80958ec1a8c0254638ad42/ui/public/brands/apps/discord.svg"
alt="Discord" width="48" height="48"></picture> | <picture><source
media="(prefers-color-scheme: dark)"
srcset="https://raw.githubusercontent.com/paperclipai/paperclip/ea053c60d9d2c5c3470275e2f4dfde5f8fe5db53/ui/public/brands/apps/discord-dark.svg"><img
src="https://raw.githubusercontent.com/paperclipai/paperclip/ea053c60d9d2c5c3470275e2f4dfde5f8fe5db53/ui/public/brands/apps/discord.svg"
alt="Discord" width="48" height="48"></picture> |
| GitHub | <picture><source media="(prefers-color-scheme: dark)"
srcset="https://raw.githubusercontent.com/paperclipai/paperclip/c9e3bb7ca40160b2ff80958ec1a8c0254638ad42/ui/public/brands/apps/github-dark.svg"><img
src="https://raw.githubusercontent.com/paperclipai/paperclip/c9e3bb7ca40160b2ff80958ec1a8c0254638ad42/ui/public/brands/apps/github.svg"
alt="GitHub" width="48" height="48"></picture> | <picture><source
media="(prefers-color-scheme: dark)"
srcset="https://raw.githubusercontent.com/paperclipai/paperclip/ea053c60d9d2c5c3470275e2f4dfde5f8fe5db53/ui/public/brands/apps/github-dark.svg"><img
src="https://raw.githubusercontent.com/paperclipai/paperclip/ea053c60d9d2c5c3470275e2f4dfde5f8fe5db53/ui/public/brands/apps/github.svg"
alt="GitHub" width="48" height="48"></picture> |
| Gmail | <picture><source media="(prefers-color-scheme: dark)"
srcset="https://raw.githubusercontent.com/paperclipai/paperclip/c9e3bb7ca40160b2ff80958ec1a8c0254638ad42/ui/public/brands/apps/gmail.svg"><img
src="https://raw.githubusercontent.com/paperclipai/paperclip/c9e3bb7ca40160b2ff80958ec1a8c0254638ad42/ui/public/brands/apps/gmail.svg"
alt="Gmail" width="48" height="48"></picture> | <picture><source
media="(prefers-color-scheme: dark)"
srcset="https://raw.githubusercontent.com/paperclipai/paperclip/ea053c60d9d2c5c3470275e2f4dfde5f8fe5db53/ui/public/brands/apps/gmail.svg"><img
src="https://raw.githubusercontent.com/paperclipai/paperclip/ea053c60d9d2c5c3470275e2f4dfde5f8fe5db53/ui/public/brands/apps/gmail.svg"
alt="Gmail" width="48" height="48"></picture> |
| Google Calendar | <picture><source media="(prefers-color-scheme:
dark)"
srcset="https://raw.githubusercontent.com/paperclipai/paperclip/c9e3bb7ca40160b2ff80958ec1a8c0254638ad42/ui/public/brands/apps/google-calendar.svg"><img
src="https://raw.githubusercontent.com/paperclipai/paperclip/c9e3bb7ca40160b2ff80958ec1a8c0254638ad42/ui/public/brands/apps/google-calendar.svg"
alt="Google Calendar" width="48" height="48"></picture> |
<picture><source media="(prefers-color-scheme: dark)"
srcset="https://raw.githubusercontent.com/paperclipai/paperclip/ea053c60d9d2c5c3470275e2f4dfde5f8fe5db53/ui/public/brands/apps/google-calendar.svg"><img
src="https://raw.githubusercontent.com/paperclipai/paperclip/ea053c60d9d2c5c3470275e2f4dfde5f8fe5db53/ui/public/brands/apps/google-calendar.svg"
alt="Google Calendar" width="48" height="48"></picture> |
| Google Chat | <picture><source media="(prefers-color-scheme: dark)"
srcset="https://raw.githubusercontent.com/paperclipai/paperclip/c9e3bb7ca40160b2ff80958ec1a8c0254638ad42/ui/public/brands/apps/google-chat.svg"><img
src="https://raw.githubusercontent.com/paperclipai/paperclip/c9e3bb7ca40160b2ff80958ec1a8c0254638ad42/ui/public/brands/apps/google-chat.svg"
alt="Google Chat" width="48" height="48"></picture> | <picture><source
media="(prefers-color-scheme: dark)"
srcset="https://raw.githubusercontent.com/paperclipai/paperclip/ea053c60d9d2c5c3470275e2f4dfde5f8fe5db53/ui/public/brands/apps/google-chat.svg"><img
src="https://raw.githubusercontent.com/paperclipai/paperclip/ea053c60d9d2c5c3470275e2f4dfde5f8fe5db53/ui/public/brands/apps/google-chat.svg"
alt="Google Chat" width="48" height="48"></picture> |
| Google Docs | <picture><source media="(prefers-color-scheme: dark)"
srcset="https://raw.githubusercontent.com/paperclipai/paperclip/c9e3bb7ca40160b2ff80958ec1a8c0254638ad42/ui/public/brands/apps/google-docs.svg"><img
src="https://raw.githubusercontent.com/paperclipai/paperclip/c9e3bb7ca40160b2ff80958ec1a8c0254638ad42/ui/public/brands/apps/google-docs.svg"
alt="Google Docs" width="48" height="48"></picture> | <picture><source
media="(prefers-color-scheme: dark)"
srcset="https://raw.githubusercontent.com/paperclipai/paperclip/ea053c60d9d2c5c3470275e2f4dfde5f8fe5db53/ui/public/brands/apps/google-docs.svg"><img
src="https://raw.githubusercontent.com/paperclipai/paperclip/ea053c60d9d2c5c3470275e2f4dfde5f8fe5db53/ui/public/brands/apps/google-docs.svg"
alt="Google Docs" width="48" height="48"></picture> |
| Google Drive | <picture><source media="(prefers-color-scheme: dark)"
srcset="https://raw.githubusercontent.com/paperclipai/paperclip/c9e3bb7ca40160b2ff80958ec1a8c0254638ad42/ui/public/brands/apps/google-drive.svg"><img
src="https://raw.githubusercontent.com/paperclipai/paperclip/c9e3bb7ca40160b2ff80958ec1a8c0254638ad42/ui/public/brands/apps/google-drive.svg"
alt="Google Drive" width="48" height="48"></picture> | <picture><source
media="(prefers-color-scheme: dark)"
srcset="https://raw.githubusercontent.com/paperclipai/paperclip/ea053c60d9d2c5c3470275e2f4dfde5f8fe5db53/ui/public/brands/apps/google-drive.svg"><img
src="https://raw.githubusercontent.com/paperclipai/paperclip/ea053c60d9d2c5c3470275e2f4dfde5f8fe5db53/ui/public/brands/apps/google-drive.svg"
alt="Google Drive" width="48" height="48"></picture> |
| Google People | <picture><source media="(prefers-color-scheme: dark)"
srcset="https://raw.githubusercontent.com/paperclipai/paperclip/c9e3bb7ca40160b2ff80958ec1a8c0254638ad42/ui/public/brands/apps/google-people.svg"><img
src="https://raw.githubusercontent.com/paperclipai/paperclip/c9e3bb7ca40160b2ff80958ec1a8c0254638ad42/ui/public/brands/apps/google-people.svg"
alt="Google People" width="48" height="48"></picture> | <picture><source
media="(prefers-color-scheme: dark)"
srcset="https://raw.githubusercontent.com/paperclipai/paperclip/ea053c60d9d2c5c3470275e2f4dfde5f8fe5db53/ui/public/brands/apps/google-people.svg"><img
src="https://raw.githubusercontent.com/paperclipai/paperclip/ea053c60d9d2c5c3470275e2f4dfde5f8fe5db53/ui/public/brands/apps/google-people.svg"
alt="Google People" width="48" height="48"></picture> |
| Google Sheets | <picture><source media="(prefers-color-scheme: dark)"
srcset="https://raw.githubusercontent.com/paperclipai/paperclip/c9e3bb7ca40160b2ff80958ec1a8c0254638ad42/ui/public/brands/apps/google-sheets.svg"><img
src="https://raw.githubusercontent.com/paperclipai/paperclip/c9e3bb7ca40160b2ff80958ec1a8c0254638ad42/ui/public/brands/apps/google-sheets.svg"
alt="Google Sheets" width="48" height="48"></picture> | <picture><source
media="(prefers-color-scheme: dark)"
srcset="https://raw.githubusercontent.com/paperclipai/paperclip/ea053c60d9d2c5c3470275e2f4dfde5f8fe5db53/ui/public/brands/apps/google-sheets.svg"><img
src="https://raw.githubusercontent.com/paperclipai/paperclip/ea053c60d9d2c5c3470275e2f4dfde5f8fe5db53/ui/public/brands/apps/google-sheets.svg"
alt="Google Sheets" width="48" height="48"></picture> |
| Google Slides | <picture><source media="(prefers-color-scheme: dark)"
srcset="https://raw.githubusercontent.com/paperclipai/paperclip/c9e3bb7ca40160b2ff80958ec1a8c0254638ad42/ui/public/brands/apps/google-slides.svg"><img
src="https://raw.githubusercontent.com/paperclipai/paperclip/c9e3bb7ca40160b2ff80958ec1a8c0254638ad42/ui/public/brands/apps/google-slides.svg"
alt="Google Slides" width="48" height="48"></picture> | <picture><source
media="(prefers-color-scheme: dark)"
srcset="https://raw.githubusercontent.com/paperclipai/paperclip/ea053c60d9d2c5c3470275e2f4dfde5f8fe5db53/ui/public/brands/apps/google-slides.svg"><img
src="https://raw.githubusercontent.com/paperclipai/paperclip/ea053c60d9d2c5c3470275e2f4dfde5f8fe5db53/ui/public/brands/apps/google-slides.svg"
alt="Google Slides" width="48" height="48"></picture> |
| Google Workspace Search | <picture><source
media="(prefers-color-scheme: dark)"
srcset="https://raw.githubusercontent.com/paperclipai/paperclip/c9e3bb7ca40160b2ff80958ec1a8c0254638ad42/ui/public/brands/apps/google-workspace-search.svg"><img
src="https://raw.githubusercontent.com/paperclipai/paperclip/c9e3bb7ca40160b2ff80958ec1a8c0254638ad42/ui/public/brands/apps/google-workspace-search.svg"
alt="Google Workspace Search" width="48" height="48"></picture> |
<picture><source media="(prefers-color-scheme: dark)"
srcset="https://raw.githubusercontent.com/paperclipai/paperclip/ea053c60d9d2c5c3470275e2f4dfde5f8fe5db53/ui/public/brands/apps/google-workspace-search.svg"><img
src="https://raw.githubusercontent.com/paperclipai/paperclip/ea053c60d9d2c5c3470275e2f4dfde5f8fe5db53/ui/public/brands/apps/google-workspace-search.svg"
alt="Google Workspace Search" width="48" height="48"></picture> |
| Hugging Face | <picture><source media="(prefers-color-scheme: dark)"
srcset="https://raw.githubusercontent.com/paperclipai/paperclip/c9e3bb7ca40160b2ff80958ec1a8c0254638ad42/ui/public/brands/apps/hugging-face.svg"><img
src="https://raw.githubusercontent.com/paperclipai/paperclip/c9e3bb7ca40160b2ff80958ec1a8c0254638ad42/ui/public/brands/apps/hugging-face.svg"
alt="Hugging Face" width="48" height="48"></picture> | <picture><source
media="(prefers-color-scheme: dark)"
srcset="https://raw.githubusercontent.com/paperclipai/paperclip/ea053c60d9d2c5c3470275e2f4dfde5f8fe5db53/ui/public/brands/apps/hugging-face.svg"><img
src="https://raw.githubusercontent.com/paperclipai/paperclip/ea053c60d9d2c5c3470275e2f4dfde5f8fe5db53/ui/public/brands/apps/hugging-face.svg"
alt="Hugging Face" width="48" height="48"></picture> |
| Jam.dev (library only) | New library entry | <picture><source
media="(prefers-color-scheme: dark)"
srcset="https://raw.githubusercontent.com/paperclipai/paperclip/ea053c60d9d2c5c3470275e2f4dfde5f8fe5db53/ui/public/brands/apps/jam-dev-dark.svg"><img
src="https://raw.githubusercontent.com/paperclipai/paperclip/ea053c60d9d2c5c3470275e2f4dfde5f8fe5db53/ui/public/brands/apps/jam-dev.svg"
alt="Jam.dev" width="48" height="48"></picture> |
| Jira | <picture><source media="(prefers-color-scheme: dark)"
srcset="https://raw.githubusercontent.com/paperclipai/paperclip/c9e3bb7ca40160b2ff80958ec1a8c0254638ad42/ui/public/brands/apps/jira-dark.svg"><img
src="https://raw.githubusercontent.com/paperclipai/paperclip/c9e3bb7ca40160b2ff80958ec1a8c0254638ad42/ui/public/brands/apps/jira.svg"
alt="Jira" width="48" height="48"></picture> | <picture><source
media="(prefers-color-scheme: dark)"
srcset="https://raw.githubusercontent.com/paperclipai/paperclip/ea053c60d9d2c5c3470275e2f4dfde5f8fe5db53/ui/public/brands/apps/jira.svg"><img
src="https://raw.githubusercontent.com/paperclipai/paperclip/ea053c60d9d2c5c3470275e2f4dfde5f8fe5db53/ui/public/brands/apps/jira.svg"
alt="Jira" width="48" height="48"></picture> |
| Linear | <picture><source media="(prefers-color-scheme: dark)"
srcset="https://raw.githubusercontent.com/paperclipai/paperclip/c9e3bb7ca40160b2ff80958ec1a8c0254638ad42/ui/public/brands/apps/linear.svg"><img
src="https://raw.githubusercontent.com/paperclipai/paperclip/c9e3bb7ca40160b2ff80958ec1a8c0254638ad42/ui/public/brands/apps/linear.svg"
alt="Linear" width="48" height="48"></picture> | <picture><source
media="(prefers-color-scheme: dark)"
srcset="https://raw.githubusercontent.com/paperclipai/paperclip/ea053c60d9d2c5c3470275e2f4dfde5f8fe5db53/ui/public/brands/apps/linear-dark.svg"><img
src="https://raw.githubusercontent.com/paperclipai/paperclip/ea053c60d9d2c5c3470275e2f4dfde5f8fe5db53/ui/public/brands/apps/linear.svg"
alt="Linear" width="48" height="48"></picture> |
| Manufact | <picture><source media="(prefers-color-scheme: dark)"
srcset="https://raw.githubusercontent.com/paperclipai/paperclip/c9e3bb7ca40160b2ff80958ec1a8c0254638ad42/ui/public/brands/apps/manufact.svg"><img
src="https://raw.githubusercontent.com/paperclipai/paperclip/c9e3bb7ca40160b2ff80958ec1a8c0254638ad42/ui/public/brands/apps/manufact.svg"
alt="Manufact" width="48" height="48"></picture> | <picture><source
media="(prefers-color-scheme: dark)"
srcset="https://raw.githubusercontent.com/paperclipai/paperclip/ea053c60d9d2c5c3470275e2f4dfde5f8fe5db53/ui/public/brands/apps/manufact-dark.svg"><img
src="https://raw.githubusercontent.com/paperclipai/paperclip/ea053c60d9d2c5c3470275e2f4dfde5f8fe5db53/ui/public/brands/apps/manufact.svg"
alt="Manufact" width="48" height="48"></picture> |
| Microsoft Teams | <picture><source media="(prefers-color-scheme:
dark)"
srcset="https://raw.githubusercontent.com/paperclipai/paperclip/c9e3bb7ca40160b2ff80958ec1a8c0254638ad42/ui/public/brands/apps/microsoft-teams.svg"><img
src="https://raw.githubusercontent.com/paperclipai/paperclip/c9e3bb7ca40160b2ff80958ec1a8c0254638ad42/ui/public/brands/apps/microsoft-teams.svg"
alt="Microsoft Teams" width="48" height="48"></picture> |
<picture><source media="(prefers-color-scheme: dark)"
srcset="https://raw.githubusercontent.com/paperclipai/paperclip/ea053c60d9d2c5c3470275e2f4dfde5f8fe5db53/ui/public/brands/apps/microsoft-teams.svg"><img
src="https://raw.githubusercontent.com/paperclipai/paperclip/ea053c60d9d2c5c3470275e2f4dfde5f8fe5db53/ui/public/brands/apps/microsoft-teams.svg"
alt="Microsoft Teams" width="48" height="48"></picture> |
| Miro | <picture><source media="(prefers-color-scheme: dark)"
srcset="https://raw.githubusercontent.com/paperclipai/paperclip/c9e3bb7ca40160b2ff80958ec1a8c0254638ad42/ui/public/brands/apps/miro-dark.svg"><img
src="https://raw.githubusercontent.com/paperclipai/paperclip/c9e3bb7ca40160b2ff80958ec1a8c0254638ad42/ui/public/brands/apps/miro.svg"
alt="Miro" width="48" height="48"></picture> | <picture><source
media="(prefers-color-scheme: dark)"
srcset="https://raw.githubusercontent.com/paperclipai/paperclip/ea053c60d9d2c5c3470275e2f4dfde5f8fe5db53/ui/public/brands/apps/miro.svg"><img
src="https://raw.githubusercontent.com/paperclipai/paperclip/ea053c60d9d2c5c3470275e2f4dfde5f8fe5db53/ui/public/brands/apps/miro.svg"
alt="Miro" width="48" height="48"></picture> |
| Mixpanel | <picture><source media="(prefers-color-scheme: dark)"
srcset="https://raw.githubusercontent.com/paperclipai/paperclip/c9e3bb7ca40160b2ff80958ec1a8c0254638ad42/ui/public/brands/apps/mixpanel.svg"><img
src="https://raw.githubusercontent.com/paperclipai/paperclip/c9e3bb7ca40160b2ff80958ec1a8c0254638ad42/ui/public/brands/apps/mixpanel.svg"
alt="Mixpanel" width="48" height="48"></picture> | <picture><source
media="(prefers-color-scheme: dark)"
srcset="https://raw.githubusercontent.com/paperclipai/paperclip/ea053c60d9d2c5c3470275e2f4dfde5f8fe5db53/ui/public/brands/apps/mixpanel-dark.svg"><img
src="https://raw.githubusercontent.com/paperclipai/paperclip/ea053c60d9d2c5c3470275e2f4dfde5f8fe5db53/ui/public/brands/apps/mixpanel.svg"
alt="Mixpanel" width="48" height="48"></picture> |
| Netlify | <picture><source media="(prefers-color-scheme: dark)"
srcset="https://raw.githubusercontent.com/paperclipai/paperclip/c9e3bb7ca40160b2ff80958ec1a8c0254638ad42/ui/public/brands/apps/netlify.svg"><img
src="https://raw.githubusercontent.com/paperclipai/paperclip/c9e3bb7ca40160b2ff80958ec1a8c0254638ad42/ui/public/brands/apps/netlify.svg"
alt="Netlify" width="48" height="48"></picture> | <picture><source
media="(prefers-color-scheme: dark)"
srcset="https://raw.githubusercontent.com/paperclipai/paperclip/ea053c60d9d2c5c3470275e2f4dfde5f8fe5db53/ui/public/brands/apps/netlify-dark.svg"><img
src="https://raw.githubusercontent.com/paperclipai/paperclip/ea053c60d9d2c5c3470275e2f4dfde5f8fe5db53/ui/public/brands/apps/netlify.svg"
alt="Netlify" width="48" height="48"></picture> |
| Notion | <picture><source media="(prefers-color-scheme: dark)"
srcset="https://raw.githubusercontent.com/paperclipai/paperclip/c9e3bb7ca40160b2ff80958ec1a8c0254638ad42/ui/public/brands/apps/notion-dark.svg"><img
src="https://raw.githubusercontent.com/paperclipai/paperclip/c9e3bb7ca40160b2ff80958ec1a8c0254638ad42/ui/public/brands/apps/notion.svg"
alt="Notion" width="48" height="48"></picture> | <picture><source
media="(prefers-color-scheme: dark)"
srcset="https://raw.githubusercontent.com/paperclipai/paperclip/ea053c60d9d2c5c3470275e2f4dfde5f8fe5db53/ui/public/brands/apps/notion.svg"><img
src="https://raw.githubusercontent.com/paperclipai/paperclip/ea053c60d9d2c5c3470275e2f4dfde5f8fe5db53/ui/public/brands/apps/notion.svg"
alt="Notion" width="48" height="48"></picture> |
| PagerDuty | <picture><source media="(prefers-color-scheme: dark)"
srcset="https://raw.githubusercontent.com/paperclipai/paperclip/c9e3bb7ca40160b2ff80958ec1a8c0254638ad42/ui/public/brands/apps/pagerduty.svg"><img
src="https://raw.githubusercontent.com/paperclipai/paperclip/c9e3bb7ca40160b2ff80958ec1a8c0254638ad42/ui/public/brands/apps/pagerduty.svg"
alt="PagerDuty" width="48" height="48"></picture> | <picture><source
media="(prefers-color-scheme: dark)"
srcset="https://raw.githubusercontent.com/paperclipai/paperclip/ea053c60d9d2c5c3470275e2f4dfde5f8fe5db53/ui/public/brands/apps/pagerduty.svg"><img
src="https://raw.githubusercontent.com/paperclipai/paperclip/ea053c60d9d2c5c3470275e2f4dfde5f8fe5db53/ui/public/brands/apps/pagerduty.svg"
alt="PagerDuty" width="48" height="48"></picture> |
| PostHog | <picture><source media="(prefers-color-scheme: dark)"
srcset="https://raw.githubusercontent.com/paperclipai/paperclip/c9e3bb7ca40160b2ff80958ec1a8c0254638ad42/ui/public/brands/apps/posthog-dark.svg"><img
src="https://raw.githubusercontent.com/paperclipai/paperclip/c9e3bb7ca40160b2ff80958ec1a8c0254638ad42/ui/public/brands/apps/posthog.svg"
alt="PostHog" width="48" height="48"></picture> | <picture><source
media="(prefers-color-scheme: dark)"
srcset="https://raw.githubusercontent.com/paperclipai/paperclip/ea053c60d9d2c5c3470275e2f4dfde5f8fe5db53/ui/public/brands/apps/posthog-dark.svg"><img
src="https://raw.githubusercontent.com/paperclipai/paperclip/ea053c60d9d2c5c3470275e2f4dfde5f8fe5db53/ui/public/brands/apps/posthog.svg"
alt="PostHog" width="48" height="48"></picture> |
| Postman | <picture><source media="(prefers-color-scheme: dark)"
srcset="https://raw.githubusercontent.com/paperclipai/paperclip/c9e3bb7ca40160b2ff80958ec1a8c0254638ad42/ui/public/brands/apps/postman.svg"><img
src="https://raw.githubusercontent.com/paperclipai/paperclip/c9e3bb7ca40160b2ff80958ec1a8c0254638ad42/ui/public/brands/apps/postman.svg"
alt="Postman" width="48" height="48"></picture> | <picture><source
media="(prefers-color-scheme: dark)"
srcset="https://raw.githubusercontent.com/paperclipai/paperclip/ea053c60d9d2c5c3470275e2f4dfde5f8fe5db53/ui/public/brands/apps/postman.svg"><img
src="https://raw.githubusercontent.com/paperclipai/paperclip/ea053c60d9d2c5c3470275e2f4dfde5f8fe5db53/ui/public/brands/apps/postman.svg"
alt="Postman" width="48" height="48"></picture> |
| Shopify | <picture><source media="(prefers-color-scheme: dark)"
srcset="https://raw.githubusercontent.com/paperclipai/paperclip/c9e3bb7ca40160b2ff80958ec1a8c0254638ad42/ui/public/brands/apps/shopify.svg"><img
src="https://raw.githubusercontent.com/paperclipai/paperclip/c9e3bb7ca40160b2ff80958ec1a8c0254638ad42/ui/public/brands/apps/shopify.svg"
alt="Shopify" width="48" height="48"></picture> | <picture><source
media="(prefers-color-scheme: dark)"
srcset="https://raw.githubusercontent.com/paperclipai/paperclip/ea053c60d9d2c5c3470275e2f4dfde5f8fe5db53/ui/public/brands/apps/shopify.svg"><img
src="https://raw.githubusercontent.com/paperclipai/paperclip/ea053c60d9d2c5c3470275e2f4dfde5f8fe5db53/ui/public/brands/apps/shopify.svg"
alt="Shopify" width="48" height="48"></picture> |
| Slack | <picture><source media="(prefers-color-scheme: dark)"
srcset="https://raw.githubusercontent.com/paperclipai/paperclip/c9e3bb7ca40160b2ff80958ec1a8c0254638ad42/ui/public/brands/apps/slack.png"><img
src="https://raw.githubusercontent.com/paperclipai/paperclip/c9e3bb7ca40160b2ff80958ec1a8c0254638ad42/ui/public/brands/apps/slack.png"
alt="Slack" width="48" height="48"></picture> | <picture><source
media="(prefers-color-scheme: dark)"
srcset="https://raw.githubusercontent.com/paperclipai/paperclip/ea053c60d9d2c5c3470275e2f4dfde5f8fe5db53/ui/public/brands/apps/slack.svg"><img
src="https://raw.githubusercontent.com/paperclipai/paperclip/ea053c60d9d2c5c3470275e2f4dfde5f8fe5db53/ui/public/brands/apps/slack.svg"
alt="Slack" width="48" height="48"></picture> |
| Stripe | <picture><source media="(prefers-color-scheme: dark)"
srcset="https://raw.githubusercontent.com/paperclipai/paperclip/c9e3bb7ca40160b2ff80958ec1a8c0254638ad42/ui/public/brands/apps/stripe.svg"><img
src="https://raw.githubusercontent.com/paperclipai/paperclip/c9e3bb7ca40160b2ff80958ec1a8c0254638ad42/ui/public/brands/apps/stripe.svg"
alt="Stripe" width="48" height="48"></picture> | <picture><source
media="(prefers-color-scheme: dark)"
srcset="https://raw.githubusercontent.com/paperclipai/paperclip/ea053c60d9d2c5c3470275e2f4dfde5f8fe5db53/ui/public/brands/apps/stripe.svg"><img
src="https://raw.githubusercontent.com/paperclipai/paperclip/ea053c60d9d2c5c3470275e2f4dfde5f8fe5db53/ui/public/brands/apps/stripe.svg"
alt="Stripe" width="48" height="48"></picture> |
| Supabase | <picture><source media="(prefers-color-scheme: dark)"
srcset="https://raw.githubusercontent.com/paperclipai/paperclip/c9e3bb7ca40160b2ff80958ec1a8c0254638ad42/ui/public/brands/apps/supabase.svg"><img
src="https://raw.githubusercontent.com/paperclipai/paperclip/c9e3bb7ca40160b2ff80958ec1a8c0254638ad42/ui/public/brands/apps/supabase.svg"
alt="Supabase" width="48" height="48"></picture> | <picture><source
media="(prefers-color-scheme: dark)"
srcset="https://raw.githubusercontent.com/paperclipai/paperclip/ea053c60d9d2c5c3470275e2f4dfde5f8fe5db53/ui/public/brands/apps/supabase.svg"><img
src="https://raw.githubusercontent.com/paperclipai/paperclip/ea053c60d9d2c5c3470275e2f4dfde5f8fe5db53/ui/public/brands/apps/supabase.svg"
alt="Supabase" width="48" height="48"></picture> |
| Telegram | <picture><source media="(prefers-color-scheme: dark)"
srcset="https://raw.githubusercontent.com/paperclipai/paperclip/c9e3bb7ca40160b2ff80958ec1a8c0254638ad42/ui/public/brands/apps/telegram.svg"><img
src="https://raw.githubusercontent.com/paperclipai/paperclip/c9e3bb7ca40160b2ff80958ec1a8c0254638ad42/ui/public/brands/apps/telegram.svg"
alt="Telegram" width="48" height="48"></picture> | <picture><source
media="(prefers-color-scheme: dark)"
srcset="https://raw.githubusercontent.com/paperclipai/paperclip/ea053c60d9d2c5c3470275e2f4dfde5f8fe5db53/ui/public/brands/apps/telegram.svg"><img
src="https://raw.githubusercontent.com/paperclipai/paperclip/ea053c60d9d2c5c3470275e2f4dfde5f8fe5db53/ui/public/brands/apps/telegram.svg"
alt="Telegram" width="48" height="48"></picture> |
| Todoist | <picture><source media="(prefers-color-scheme: dark)"
srcset="https://raw.githubusercontent.com/paperclipai/paperclip/c9e3bb7ca40160b2ff80958ec1a8c0254638ad42/ui/public/brands/apps/todoist.svg"><img
src="https://raw.githubusercontent.com/paperclipai/paperclip/c9e3bb7ca40160b2ff80958ec1a8c0254638ad42/ui/public/brands/apps/todoist.svg"
alt="Todoist" width="48" height="48"></picture> | <picture><source
media="(prefers-color-scheme: dark)"
srcset="https://raw.githubusercontent.com/paperclipai/paperclip/ea053c60d9d2c5c3470275e2f4dfde5f8fe5db53/ui/public/brands/apps/todoist.svg"><img
src="https://raw.githubusercontent.com/paperclipai/paperclip/ea053c60d9d2c5c3470275e2f4dfde5f8fe5db53/ui/public/brands/apps/todoist.svg"
alt="Todoist" width="48" height="48"></picture> |
| Wix | <picture><source media="(prefers-color-scheme: dark)"
srcset="https://raw.githubusercontent.com/paperclipai/paperclip/c9e3bb7ca40160b2ff80958ec1a8c0254638ad42/ui/public/brands/apps/wix.svg"><img
src="https://raw.githubusercontent.com/paperclipai/paperclip/c9e3bb7ca40160b2ff80958ec1a8c0254638ad42/ui/public/brands/apps/wix.svg"
alt="Wix" width="48" height="48"></picture> | <picture><source
media="(prefers-color-scheme: dark)"
srcset="https://raw.githubusercontent.com/paperclipai/paperclip/ea053c60d9d2c5c3470275e2f4dfde5f8fe5db53/ui/public/brands/apps/wix-dark.svg"><img
src="https://raw.githubusercontent.com/paperclipai/paperclip/ea053c60d9d2c5c3470275e2f4dfde5f8fe5db53/ui/public/brands/apps/wix.svg"
alt="Wix" width="48" height="48"></picture> |
| Zapier | <picture><source media="(prefers-color-scheme: dark)"
srcset="https://raw.githubusercontent.com/paperclipai/paperclip/c9e3bb7ca40160b2ff80958ec1a8c0254638ad42/ui/public/brands/apps/zapier.svg"><img
src="https://raw.githubusercontent.com/paperclipai/paperclip/c9e3bb7ca40160b2ff80958ec1a8c0254638ad42/ui/public/brands/apps/zapier.svg"
alt="Zapier" width="48" height="48"></picture> | <picture><source
media="(prefers-color-scheme: dark)"
srcset="https://raw.githubusercontent.com/paperclipai/paperclip/ea053c60d9d2c5c3470275e2f4dfde5f8fe5db53/ui/public/brands/apps/zapier.svg"><img
src="https://raw.githubusercontent.com/paperclipai/paperclip/ea053c60d9d2c5c3470275e2f4dfde5f8fe5db53/ui/public/brands/apps/zapier.svg"
alt="Zapier" width="48" height="48"></picture> |
2026-09-14 05:05:27 -10:00
DottaandPaperclip 3052686b1e fix(ui): hide task chat attribution badge (#13251)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - The task chat shows messages from agents and users.
> - An agent message can contain an internal on-behalf-of user value.
> - The new task view showed this value as a badge next to the agent
name.
> - This badge added unwanted identity text to the task chat.
> - This pull request removes the badge from the new task view.
> - The benefit is a simpler agent identity row in the task chat.

## Linked Issues or Issue Description

**What happened?**

The new task view shows a `for <user>` badge next to an agent name when
a message has an on-behalf-of user value.

**Expected behavior**

The task chat shows the agent name without the on-behalf-of badge.

**Steps to reproduce**

1. Open the new task view.
2. Show an agent message that has an on-behalf-of user value.
3. See the attribution badge next to the agent name.

**Paperclip version or commit**

The issue occurs on `master` at commit `d0b7ba419`.

**Deployment mode**

Local dev and all other modes that use the web UI.

## What Changed

- Removed the attribution chip from the task chat agent identity.
- Added a regression test that supplies an on-behalf-of value and
confirms that the badge is absent.

## Verification

- `pnpm --filter @paperclipai/ui exec vitest run
src/components/task-chat/TaskChatBubble.test.tsx` passed with 21 tests.
- `pnpm check:token-gates` passed.
- `pnpm --filter @paperclipai/ui typecheck` passed.

## Risks

- Low risk. The change only removes one badge from the new task chat
view.
- The message data remains unchanged.

> This is a small UI fix. It does not add roadmap scope.

## Model Used

- OpenAI Codex, GPT-5.4, with reasoning and tool use. The provider did
not expose the context window size.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g.
`docs/no-internal-issue-references`, `fix/sandbox-secret-resolution`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [ ] All Paperclip CI gates are green
- [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-09-14 09:58:44 -05:00
DottaandPaperclip ef84f363b7 fix(ui): remove execution workspace access card (#13406)
## Thinking Path

> - Paperclip helps people manage AI agents and their work.
> - Execution workspace pages show the tools and state for one isolated
workspace.
> - The workspace access card repeats runtime state that the page
already shows.
> - The card also adds open and repair actions that are not needed on
this page.
> - This pull request removes the complete workspace access card from
execution workspace detail pages.
> - The benefit is a smaller page that keeps attention on workspace
controls and work results.

## Linked Issues or Issue Description

**What existing behavior does this improve?**

The execution workspace detail page shows a workspace access status
card.

**Current behavior**

The page can show Ready, preparation, degraded, failed, or Workspace is
not running states. The card can also show Open workspace and repair
actions.

**Proposed behavior**

The page does not show the workspace access status card or its page-only
actions.

**Reason and benefit**

The card adds status and controls that are not needed on this page. Its
removal makes the isolated workspace page simpler.

**Breaking changes**

The workspace access card and its actions are no longer available from
the execution workspace detail page. Workspace runtime controls remain
available.

## What Changed

- Removed the workspace access status card from execution workspace
detail pages.
- Removed the page-only login handoff and repair mutations that served
the card.
- Added a regression test for the removed card and text.

## Verification

- `pnpm exec vitest run ui/src/pages/ExecutionWorkspaceDetail.test.tsx`
passes with 8 tests.
- `pnpm typecheck` passes.
- `pnpm check:token-gates` passes.
- `pnpm build` passes.
- `pnpm test:run` found unrelated failures in
`server/src/__tests__/workspace-runtime.test.ts` during the local broad
run. The focused changed-area tests pass.
- The complete GitHub Actions matrix passes on the latest run, including
build, typecheck, server tests, runner verification, and e2e tests.

## Risks

- Low risk. The change removes one UI card and the page-only code that
supported it.
- Users must use the remaining workspace runtime controls instead of
this card.

> This change is focused UI cleanup. It does not add a roadmap feature.

## Model Used

- OpenAI Codex based on GPT-5, with reasoning, tool use, and code
execution. The exact context window is not exposed in this environment.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-09-14 09:47:10 -05:00
DottaandPaperclip d351e08dee fix(ui): stop Recent Tasks storage feedback across tabs (#13402)
Version recent-task snapshots separately from activity, reject stale cache updates, and publish only on query or membership changes. Migrate history into an isolated storage namespace while preserving restart retries.

Add regression coverage for conflicting caches, migration, comments, unchanged writes, and storage implementations on Node 24 and Node 26.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-09-14 08:05:06 -05:00
DottaandPaperclip c9e3bb7ca4 fix: preserve queued work after native Stop and honor steering support (#13354)
## Thinking Path

> - Paperclip lets people manage AI agents and their tasks.
> - The runner owns execution, while the task keeps user instructions
and status.
> - Stop must stop the current response without losing instructions that
the user already sent.
> - The queue stored its original reason inside saved context. Recovery
checked the outer deferred reason and left the message waiting.
> - Claude also exposed Steer through a shared method even though its
driver did not support it. A rejected request could remove its own error
row.
> - This pull request keeps queued work until execution has stopped,
uses the driver's real capability, and preserves completion event order.
> - Users can continue work without repairing task state or repeating
messages.

## Linked Issues or Issue Description

Refs #13338. Related recovery work: #13353.

**What happened?**

A message sent during a native run stayed queued after Stop. Claude
exposed an unsupported Steer action. A steering failure could hide the
queued row and its error. A terminal event could also precede the final
provider result, and subtree Stop omitted the board actor.

**Expected behavior**

Stop ends the current execution. Once Paperclip proves that execution
has stopped, it delivers the saved instruction once through normal
admission. Pause and recovery holds still prevent dispatch. Unsupported
controls stay disabled, and a rejected action leaves an actionable error
visible. Final results precede terminal events.

**Steps to reproduce**

1. Start a Claude or Codex task that writes a file and then waits.
2. Send a follow-up instruction while it runs.
3. Press Stop. Check that the queued instruction runs once and preserves
the file.
4. Check Claude's Steer control and simulate a server rejection on the
only queued message.

## What Changed

- Recover saved native comments after acknowledged Stop using their
original wake reason.
- Require durable remote termination receipts or verified local process
termination before dispatch.
- Preserve actor identity, queued-message deduplication, Pause, and
recovery gates.
- Derive steering support from the driver descriptor and reject
unsupported calls.
- Keep the queue mounted until a steering request succeeds so its error
remains visible.
- Emit provider results before terminal events and pass the board actor
into subtree Stop.
- Document Stop and steering behavior.

## Verification

- Final-head continuation suite: 104 passed, after failing regressions
for saved wake reasons, cleanup proof, and deduplication of every queued
message. Steering UI: 121 passed. Driver capability: 26 passed. Runner
backend/transport: 205 passed; Rust library: 285 passed.
- Real Claude and Codex browser journeys both preserved the saved file,
delivered the queued instruction once after Stop, and reached Done with
exactly two total runs. The process Stop browser fixture also passed.
- Local full repository typecheck and build passed on `afaa35139`;
server typecheck and the affected 104-test suite passed after the final
queue changes. Token gates passed. Final-head CI verifies the complete
integrated source.
- Local aggregate evidence has explicit limits: the general-server
invocation overlapped the queue fixes and finished with 11,989 passed, 2
failed, and 80 skipped; both failures are covered by the final 104-test
pass. The UI and CLI then passed all 6,184 and 485 tests; the complete
145-file serialized rerun passed all 2470 tests. The shared-package lock
fixture passed unchanged on rerun, but the package phase subsequently
stopped at an embedded-Postgres bootstrap resource failure. No single
pristine green local full aggregate is claimed.
- Greptile reviewed `fa66e2bd5` at [5/5 with no unresolved
findings](https://github.com/paperclipai/paperclip/pull/13354#issuecomment-5650334242).
[Final-head CI completed
successfully](https://github.com/paperclipai/paperclip/actions/runs/34733781888/attempts/2):
33 successful checks, 2 conditional skips, including all server,
package, UI, browser, runner, typecheck, and build gates. The first
attempt hit a preview-readiness/port-collision fixture; its unchanged
local control passed 25 tests with 3 skips, and one supported unchanged
CI retry passed the affected shard and aggregate gates.

## Risks

- Queue recovery must never overlap an old execution. Unknown cleanup
state remains blocked.
- Driver descriptors are now authoritative for steering; a wrong
descriptor disables the action instead of attempting it.
- No schema migration or historical status reconciliation is included.

## Model Used

OpenAI GPT-6 through Codex, with reasoning, code execution, browser
testing, and tool use. The exact hosted model ID and context-window size
are not exposed in this task.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` OR (b) described the issue in-PR following the relevant issue
template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-09-12 22:29:54 -05:00
DottaandPaperclip 6809314a3f fix: recover sandbox workspace setup and retries (#13353)
## Thinking Path

> - Paperclip manages AI agents and their tasks.
> - Sandbox tasks need a workspace and a provider session before work
can start.
> - A selected Git subfolder is a valid workspace, but it is not a
repository fetch source.
> - A resumed sandbox must keep one resource identity when the provider
fills in its region.
> - Workspace reuse does not prove that a provider session has started.
> - A recorded continuation must not leave an old failure blocking Retry
for a newer attempt.
> - This pull request fixes those setup and recovery boundaries while
preserving ownership checks.

## Linked Issues or Issue Description

**What happened?**

A Daytona task failed before provider startup when its project folder
was inside a parent Git repository. After the folder was repaired, Retry
resumed the same sandbox and verified its workspace sentinel, but
workspace preparation reported that the lease was no longer active. A
later attempt could fail because the resumed workspace had no provider
checkpoint. The old run also kept a recovery projection after the server
recorded its explicit successor, hiding Retry for the new failure.

**Expected behavior**

Sync the selected folder without importing parent files or history. Keep
the existing sandbox identity stable. Allow a new provider session only
with proof that its exact session has never started. Let the current
failed attempt retain Retry once the old recovery has a recorded
successor.

**Steps to reproduce**

1. Select a subfolder of a Git repository as a project workspace and
start a Daytona task.
2. Leave the target region unset. Release its reusable sandbox after
setup fails, then resume and realize the workspace.
3. Retry a provider setup that failed before any session directory or
checkpoint was created.
4. Record an explicit successor for a native failure, fail that
successor during setup, and inspect Retry in the task thread.

**Paperclip version or commit**

Reproduced against `8d1f0c20a` with new failing regressions before each
production fix.

**Deployment mode**

Local controller with a Daytona environment. Automated tests use
deterministic provider fixtures and real filesystem operations.

Related: #13338, #13163, #13264, #13349. The open work-folder stack in
#13264 includes a broader fresh-session authority change. This patch
addresses the independently reproduced startup failure with existing
durable bootstrap proof and atomic directory creation. It does not
include the work-folder migration or credential changes from that stack.

## What Changed

- Classify only the selected Git repository root as a fetch source. Sync
subfolders as directories and preserve their enclosing Git ignore rules
on upload and restore. Recognize the shared scheduler’s completed
non-repository result so ordinary folders still sync; timeout,
cancellation, and output-limit failures remain closed.
- Remove the placement target from Daytona account cache identity. Keep
API endpoint, credential digest, company, environment, driver, and
sandbox ID boundaries.
- Preserve closed-lease admission until a sentinel-verified resume
reopens that same resource.
- Show the already-recorded explicit successor of a resolved recovery.
Keep the old failure evidence and unresolved holds. No historical status
writes occur.
- Permit a resumed workspace to create a new session directory only with
matching durable identity, zero connections and events, untouched
bootstrap commands, no backup, and an absent remote session. Claim the
directory atomically. Existing, partial, or ambiguous state still blocks
startup.

## Verification

- Final head `c43c7403f`: [CI completed
successfully](https://github.com/paperclipai/paperclip/actions/runs/34733846820/attempts/2),
with 32 successful checks and 2 conditional skips. This includes every
server, UI, package, serialized-route, browser, native-runner,
typecheck, and build gate. Greptile reviewed the same head at [5/5 with
no unresolved
findings](https://github.com/paperclipai/paperclip/pull/13353#issuecomment-5650270168).
- New regressions failed before each of the four production fixes.
Git/archive/restore suites: 148 passed. The scheduler-wrapped non-Git
regression also failed before its fix; 135 affected Git/sync/Codex tests
then passed.
- Daytona plugin: 230 passed, 6 opt-in live tests skipped. Native
executor, projection, and TaskChatThread: 494 passed, including
existing/partial state, wrong identity, prior connections or turns,
backups, unavailable proof, and unresolved recovery controls.
- Local full-repository typecheck, build, and token gates passed on the
final head. Local CLI: 485 passed. Complete single-worker package rerun:
3,224 passed, 19 skipped.
- Local verification is an aggregate with recorded retries, not one
pristine green invocation: the general-server run began on `e721a920a`
and finished with 12,002 passed, 3 failed, 70 skipped. Its real Codex
scheduler failure is fixed above; the socket and workspace-runtime
timeout failures passed unchanged in focused reruns. Both Inbox failures
passed unchanged in the full 27-test Inbox file; database/shared-package
failures passed in the single-worker package rerun. The supplemental
local serialized-route rerun remains in progress; all five corresponding
final-head CI lanes passed.
- The first final-head CI attempt hit a Daytona fixture-readiness race
and a signoff-browser heartbeat receipt timeout. One supported unchanged
failed-job rerun passed both and the aggregate gates. Live combined
user-journey verification is tracked in the related follow-up; this PR's
provider tests use deterministic fixtures and real filesystem checks.

## Risks

- A selected subfolder uses directory sync and does not carry parent Git
history. Its ignored files stay local.
- The target region remains a creation setting and part of workspace
reuse policy; it does not split the account identity of an existing
sandbox.
- Incomplete or conflicting provider state still fails closed. This
change does not erase a session, infer completed work, bypass a user
decision, or replay uncertain actions.
- A later remote setup failure can leave a claimed partial session
directory. It remains blocked rather than being overwritten.

## Model Used

OpenAI GPT-6 through Codex, with reasoning, repository tools, and code
execution. The exact hosted model ID and context-window size are not
exposed in this task.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` /
`Closes: #` / `Refs: #` OR (b) described the issue in-PR following the
relevant issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-09-12 22:19:42 -05:00
DottaandPaperclip 8d1f0c20af fix: let responsible users choose either AI subscription or API key (#13351)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - AI Connections select the account used for each run.
> - A responsible-user binding must follow the person whose work the
agent performs.
> - The saved sign-in method currently blocks users with another method
for the same provider.
> - This pull request resolves a personal default by company, user, and
provider.
> - Each user can use a subscription or API key with the same bot and
model.

## Linked Issues or Issue Description

Refs #13247, #13248, #13346, #13347.

**What happened?**
A bot configured with a Claude subscription rejects another responsible
user’s Claude API key. Inline repair also limits that person to the
original sign-in method.

**Expected behavior**
The same bot uses each responsible user’s default Claude account,
whether it is a subscription or API key. Explicit shared account
selections remain fixed.

**Steps to reproduce**
1. User A connects a Claude subscription and creates a bot using the
responsible user’s connection.
2. User C connects a personal Claude API key.
3. User C runs the same bot. Before this fix, credential resolution
fails.

## What Changed

- Add a personal provider-default table. Preserve legacy per-method
preferences and backfill the most recently updated preference, including
unavailable defaults. Repeated migration does not replace a selection. A
database trigger propagates old-server default updates without treating
new accounts as replacement defaults.
- Resolve responsible-user bindings by provider. Retain the method as a
wire compatibility hint for old servers. Explicit selections still
require the exact method and grant.
- Use the selected account’s method for credential isolation, refresh
locking, and run attribution.
- Update onboarding, agent setup, the picker, and inline task repair.
Keep existing authentication components and harness/model settings.
- Add mixed-method runtime, migration, repair, and Storybook coverage.
Include upstream’s duplicate Anthropic option fix through the base
branch.

## Verification

- Focused resolver, migration, connection-intent, onboarding, agent
setup, model, and connector UI suites: 331 tests passed.
- Onboarding and new-agent regression suites passed during the initial
focused run.
- UI typecheck, token gates, and Storybook build passed.
- Live browser checks passed for Claude and Codex API-default execution,
switching both back to subscriptions, and both existing shared-account
bots. Bot configuration remained unchanged.
- One Daytona startup command stalled before Claude launched. The test
run was cancelled, its sandbox stopped, and the same account/task passed
on retry. Startup cancellation remains a separate environment finding;
this PR does not change that command transport.
- Browser review: all eight assertions passed in the new mixed-method
story, including shared selection, return to responsible-user selection,
and unchanged harness/model.
- Repository build and typecheck passed after refreshing upstream
dependencies. Final resolver and historical rollback verification: 38
tests passed. All latest-head CI gates passed, including
server/workspace/serialized suites, browser E2E, build, typecheck, and
runner verification. The extra serial local full-suite run was stopped
after equivalent CI passed; focused local checks completed.

## Risks

- Users with both historical method defaults get their most recently
updated preference as the initial provider default. They can change it
explicitly in Connections.
- A revoked or unavailable default blocks. Connecting an additional
account does not silently replace it.
- Existing legacy authentication is unchanged. Managed responsible-user
bindings intentionally stop pinning a method.
- Live staging: the same Claude and Codex bots completed real API-key
runs after changing only the personal default, then completed
subscription runs after restoring the original defaults. Read-only
database verification confirms unchanged bot configuration and actual
method attribution. Distinct-user concurrency is covered by automated
real-database tests with synthetic credentials, not two live human
logins.

## Model Used

OpenAI GPT-6 (Codex), with reasoning, repository tools, code execution,
and browser interaction. The runtime does not expose a more specific
model ID or context-window size.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-09-12 20:27:26 -05:00
DottaandPaperclip 422287eecd fix: preserve runner recovery, warm sessions, and task outcomes (#13338)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - The native runner connects task messages, provider execution, and
task outcomes.
> - First-time user tests exposed gaps in recovery, completion
permissions, message delivery, and Stop behavior.
> - These gaps left usable output hidden, completed work waiting for
bookkeeping, or safe work unable to continue.
> - This pull request fixes the shared lifecycle and receipt paths while
preserving process ownership and action checks.
> - Users can continue work with accurate task state and durable
messages.

## Linked Issues or Issue Description

**What happened?**

A stopped local Codex execution could remain blocked even after its
processes had stopped and its complete transcript proved that no
external action needed replay. Claude under Conservative permissions
could fail to call task completion tools. Recovery could reuse an
assistant item ID and overwrite prior output. A delivered comment could
remain marked uncertain after navigation. Stop could look like Pause or
a new recovery incident. Workspace contention could look like
cancellation. A direct reply reopening Done could enter a clarification
loop.

**Expected behavior**

Recover automatically only with verified termination and complete action
receipts. Preserve answers and messages. Keep task completion available
under Conservative permissions without broad tool access. Show crashes
as Blocked, actual human decisions as In Review, and ordinary workspace
contention as waiting. Stop the current response and allow a new
direction.

**Steps to reproduce**

1. Create ordinary response tasks with local Codex and Claude Code, then
send follow-up messages through the task composer.
2. Interrupt a disposable local Codex runner during text-only work.
Verify automatic continuation and retained output.
3. Stop a response, send a new request, answer a clarification, and
reopen completed work with another message.
4. Navigate or reload while a comment submission is pending. Confirm the
exact persisted request receipt settles it without removing newer draft
text.
5. Run two tasks in a shared Daytona workspace. Confirm waiting does not
appear as failure.

**Paperclip version or commit**

Initial acceptance baseline: `c9021c6721f91e2c74bd9fee9d3fd41c999d17b7`.
Current integration base: `6cef9743c`. Both operator-interruption and
workspace-waiting guards are preserved; native restart and legacy
permission rules remain documented.

**Deployment mode**

An isolated source-built test-drive instance, with real local Codex and
Claude Code providers and disposable Daytona environments.

Related work: #13314, #13316, #13327, #13344, #13239, #13254, #13163.
This PR addresses additional failures from ordinary task journeys,
including controller restart handoff and repeated warm sandbox setup.
Historical task status reconciliation is excluded.

## What Changed

- Persist runner ownership immediately at spawn and resume an explicitly
adopted runner even when the controller crashed before the first driver
checkpoint. Detach the controller safely across graceful restarts,
including session startup. Prevent an old finalizer from suspending or
signaling an adopted runner. Checkpoint idle warm sessions before
shutdown. Preserve the same run and queued follow-up messages.
- Scope saved legacy queue successor checks to the queue owner while
preserving ordinary task locks, operator identity, assignment gates, and
exactly-once delivery.
- Preserve managed Codex credential files when an old session is
detached for restart; normal owned cleanup still copies refreshed auth
back and removes the scoped copy.
- Reuse the bound warm shared sandbox and fully verify an existing
staged provider pack before using it. This avoids repeated uploads when
the pack is already valid.
- Add a narrow local Codex replacement path with stopped-process proof,
a closed transcript inventory, exact completion receipts, and
fresh-session lineage. Preserve no-replay holds when evidence is
incomplete. Recovery may clear only the same run's recorded Blocked
status version; manual re-blocking and dependency changes invalidate
that receipt, while queued comments do not. Later blocks stop scheduled,
queued, and final dispatch; queued/final checks re-read dependencies
even when the task status stays In Progress.
- Permit only task delivery and human-input tools through the isolated
Claude runner's exact task bridge.
- Scope assistant item identity to the provider turn and ignore only
authority-free Codex skill-change notifications during startup.
- Reconcile composer submissions by client request ID across response
loss, navigation, and reload. Retain text typed during delivery.
- Keep acknowledged run-only Stop neutral and show workspace contention
as waiting. Project exhausted native failures as Blocked.
- Restore the guarded task-page retry action for failed legacy runs,
including the server-supported explicit new-attempt path for stopped
conversation adapters. Preserve native/process recovery holds and avoid
promising Retry while a decision or execution gate hides it.
- Refresh delivered artifacts and handle direct user replies that reopen
completed work without a clarification loop.
- Check the embedded PostgreSQL PID, data directory, and actual port
before connecting or migrating.
- Document accepted behavior and add focused regressions at lifecycle,
route, transcript, and UI boundaries.

## Verification

- Final head `fece606ac2` passes the complete GitHub CI matrix: **34
green checks, two expected Storybook skips, no failures or pending
checks**, including `ci / verify`, `ci / e2e`, full runner verification,
typecheck, build, every server/workspace shard, and all browser shards.
[CI
run](https://github.com/paperclipai/paperclip/actions/runs/34727183287).
Greptile is **5/5 with no open findings**. The final two commits only
refine test fixtures; both affected suites pass 24/24 locally and in CI,
with server typecheck green.
- Complete local Vitest coverage uses the canonical groups/shards: all
635 general server suites, all 145 serialized suites, and all workspace
packages. The aggregate began on `0a8001c18` while the final queue fix
arrived: 23,903 passed, five failed, 87 skipped. The five
port/socket/timing failures passed unchanged in follow-ups (60 tests in
the exposure/file suites and 412 tests covering the serialized failures
and unrun tails). The final queue/operator-identity suites separately
passed 52/52. This is aggregate coverage plus explicit reruns, not a
pristine single-command final-head run.
- After integration with current master,
queue/operator-identity/continuation suites passed 162/162 and affected
UI suites passed 140/140. ACP Stop/continuation and legacy
task/Inbox/message browser suites passed 9/9, including both task
recovery Retry and thread Try again, automatic saved-message delivery,
exactly one new run, Done, and retained output after reload. The default
process Stop/Pause/Resume browser case passed (the native-provider case
is opt-in and skipped by default). The complete Board attachment/receipt
browser suite passed 11/11 on a disposable instance, covering both
composers, exact receipts after lost responses, no replay, bound
attachments, and newer drafts after reload.
- Blocking-intent regressions cover pre-existing Blocked, a mismatched
run/cause, an explicit manual re-block, changed dependencies, a queued
comment after failure, and a block arriving between scheduling and
provider dispatch. The negative cases reproduced before the fix. All 478
affected executor/recovery/dispatch tests passed; both database suites
ran separately after availability-probe skips in the first combined
command. The final late-dependency check passed all 143 affected
recovery/dispatch tests (zero skips) after two new negative cases
reproduced the bug.
- Focused runtime regressions cover awaited runner ownership
publication, authenticated adoption before the first checkpoint,
old-finalizer detachment, idle and busy warm-session shutdown, rejected
checkpoint propagation, provider-pack verification, and managed-Codex
credential preservation. Four managed credential detachment cases
reproduced the bug before the fix; normal owned cleanup still succeeds
exactly once.
- Live local Claude: SIGKILL 2.6 seconds into startup recovered the same
run automatically in 53 seconds, then a normal follow-up completed in 24
seconds. SIGTERM 2.5 seconds into startup preserved the same run (54
seconds) and its queued follow-up (21 seconds). Answers remained visible
and the task reached Done.
- Live Claude Daytona: a warm follow-up retained its sandbox and fell
from 121 seconds to 44 seconds. A separate cold turn took 127 seconds;
after controller shutdown and checkpointing, its follow-up completed in
33 seconds with the same sandbox, workspace, native session, and runner.
Both answers remained visible and the task was Done.
- Other live journeys covered task completion and follow-up with local
and Daytona Codex, local Codex crash recovery, Stop then new direction,
clarification response, live artifact refresh, and shared-workspace
waiting.
- Validation limits: the opt-in native composer Stop/Pause→subtree
Resume fixture exposes terminal/result ordering and subtree-cancellation
attribution bugs that can leave a child task blocked; that new finding
is assigned to a separate follow-up and is not claimed fixed here.
Default CI skips this optional native-provider fixture. Managed-Codex
credential handoff and the queue-agent integration use automated
regression evidence. Cold custom provider-pack uploads still add startup
latency.

## Risks

- Automatic replacement remains deliberately narrow: local Codex,
verified stopped identities, unchanged retained state, and a complete
text/completion-only turn. Unknown actions, partial history, or changed
ownership remain blocked.
- Claude completion permission handling changes an upstream package
patch. The exact isolated task bridge must remain pinned; unrelated
tools keep their existing permissions.
- New task failure projection changes user-visible status. No historical
status backfill or database migration is included.
- This is a broad lifecycle fix across server and UI. Live proof covers
graceful local Claude restart during startup and idle Claude Daytona
session recovery across controller shutdown. Live abrupt SIGKILL during
local Claude startup also recovered the same run. Unknown ownership or
missing action evidence still blocks reuse. Cold custom provider-pack
uploads still add startup latency; this change avoids unnecessary repeat
uploads.

## Model Used

OpenAI GPT-6 (Codex), with reasoning, code execution, browser
automation, and tool use. The exact hosted model ID and context window
are not exposed in this task.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-09-12 19:41:15 -05:00
DottaandPaperclip 13bae6fa21 fix: reject unsupported REST tool connections without stdio validation (#13346)
## Thinking Path

> - Paperclip manages AI agents and their connections.
> - Connection checks must use the configured transport.
> - The tool service treated every remaining transport as local stdio.
> - Anthropic's old REST method therefore failed with a templateId
error. A REST connection with a valid stdio template could incorrectly
pass.
> - Anthropic now has a supported AI-account flow. This pull request
removes its obsolete REST setup option and limits stdio checks to stdio
connections.
> - Users can connect an AI account, and existing unsupported
connections receive an accurate error.

## Linked Issues or Issue Description

Related: #13248 added the supported AI-account flow. Searches for
related REST health and templateId bugs found no duplicate fix.

**What happened?**

The Anthropic REST API-key connection showed `Local stdio MCP
connections must use an approved templateId`. Health checks and catalog
discovery both fell through to the local stdio path. A REST connection
with an approved template could report success and expose the template's
catalog without a REST integration.

**Expected behavior**

Only local stdio connections use command templates. Unsupported
transports return an accurate HTTP 422 error. New Anthropic accounts use
the supported runtime authentication flow.

**Steps to reproduce**

1. Check out the test-only commit `924e6e85a` in a separate worktree and
install dependencies.
2. Run `pnpm exec vitest run packages/shared/src/app-definitions.test.ts
server/src/__tests__/tool-access-service.test.ts -t 'unsupported
REST|obsolete Anthropic'`.
3. The tests exercise saved Anthropic REST configuration and an
unsupported REST connection containing an approved stdio template. They
cover health checks and catalog discovery separately.
4. Run the same tests on the fix commit. They pass. The full affected
files also pass.

**Paperclip version or commit**

Reproduced against master `6cef9743c`.

**Deployment mode**

Server transport handling. Reproduced with an isolated embedded
PostgreSQL test database. No provider account or live credentials are
required.

## What Changed

- Restrict stdio health checks and tool discovery to `local_stdio`.
- Return and audit `tool_connection_transport_unsupported` with HTTP 422
for unsupported tool transports.
- Remove Anthropic's obsolete REST method from the generated catalog and
its durable ingestion source. Keep its subscription and API-key AI
methods.
- Cover the reported error, false-success case, rejected obsolete setup,
connection removal, and the UI's AI-account submission path.
- Replace impossible reconnect forms for removed methods with supported
setup, while preserving connection removal.
- Preserve AI-versus-tool intent isolation for legacy requests and
reject new unsupported Anthropic tool requests.
- Document recovery for existing unsupported connections.

## Verification

- Clean-worktree red/green: the same command failed all six regression
cases at `924e6e85a` and passed all six at `4d3de9de0`. The failing run
includes the reported templateId error.
- Green: all 555 tests across the six affected test files passed.
- Recovery UI red/green: three added cases failed before the recovery
fix and passed afterward; all 200 tests across setup, detail, and
advanced controls passed.
- After the recovery UI update, UI typecheck/build and token gates
passed again.
- `pnpm -r typecheck` — passed.
- `pnpm build` — passed.
- `pnpm check:token-gates` — passed.
- Catalog regeneration — passed with the documented
`PAPERCLIP_CONTENT_TEMPLATES` override for the local capture corpus.
- Full CI on `69fb31fd4` — passed all general and serialized test
shards, browser shards, typecheck, build, runner verification, and
canary dry run:
https://github.com/paperclipai/paperclip/actions/runs/34726975425.
- The local serial `pnpm test:run` was stopped after the fixture
correction superseded that run; full-suite verification above comes from
CI. All 555 affected tests passed locally, including all 17
connection-intent tests after the correction.
- Greptile — 5/5, successful check on final commit `69fb31fd4`, no
unresolved findings.
- No live Anthropic validation was performed. The UI regression uses a
fake key and a mocked AI-account response.

## Risks

Existing obsolete REST connections remain in needs-attention state.
Users must add an account through the supported flow and remove the old
connection. Credentials and grants are not transferred automatically.
Removal remains covered. The specialized AgentMail and Composio paths
keep their existing behavior. There are no schema or permission changes.

## Model Used

OpenAI GPT-6 through Codex. The exact serving model ID and
context-window capacity are not exposed in this session. Used reasoning,
code editing, shell tools, and test execution.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-09-12 19:26:58 -05:00
DottaandPaperclip e704e1c9ae fix: keep AI subscription locks safe through transaction pooling (#13347)
## Thinking Path

> - Paperclip manages AI agents and their credentials.
> - AI Connections must preserve account ownership from login through
execution.
> - A subscription environment check can pass and leave a session
advisory lock on a pooled database backend.
> - The next execution then reports that the subscription is busy.
> - Onboarding can also lose its completion callback when the connection
list refreshes before the login poll.
> - This change keeps each credential lease in one transaction and keeps
the login controller mounted until completion.

## Linked Issues or Issue Description

Refs: #13247, #13248, #13344.

**What happened?**

A real hosted subscription login saved successfully and passed its
environment check. The first task then failed with an AI connection busy
error. A connection-list update could also leave onboarding on
Connecting.

**Expected behavior**

A completed environment check releases its credential lease. A saved
login completes onboarding without another sign-in.

**Steps to reproduce**

1. Run Paperclip with a transaction-pooling PostgreSQL proxy.
2. Connect a Claude subscription through onboarding and reuse it for an
agent.
3. Start a task after its environment check succeeds.
4. For the UI race, refresh the managed connection list before the login
completion poll.

## What Changed

- Hold the grant lock inside one transaction. Roll back on cleanup or
failed acquisition.
- Disable the lease transaction's idle timeout so long provider
executions retain the lock.
- Keep the onboarding login controller mounted while its authorization
URL is active; restore saved-account retry if later agent creation
fails.
- Add lock-lifetime and Claude/Codex completion-order regressions.
- Document the pooling requirement.

## Verification

- 104 focused connection and onboarding tests passed.
- Workspace typecheck, production build, Storybook build, and token
gates passed.
- All 34 latest-head checks are terminal: 32 passed and two Storybook
workflows skipped by their normal filters. CI covers all
server/workspace/serialized test shards, browser tests, typecheck,
build, runner verification, and canary packaging. The additional local
full-suite run is still in progress.
- Real browser sign-ins saved Claude and OpenAI subscriptions on both
new and existing staging stacks. On the patched new stack, both
providers completed tasks and immediate repeat executions with the same
saved accounts. Read-only database inspection confirmed live
transaction-scoped locks and no remaining locks after completion. On the
final deployed head, both shared accounts on the existing stack also
completed actual tasks. Both personal accounts passed a fresh
environment check followed immediately by execution after a deployment
restart.

## Risks

- Each active subscription reserves one database connection and holds an
otherwise idle transaction until cleanup. This is required to pin the
backend through a transaction pool.
- Old session locks from earlier versions may need operator cleanup
after active runs drain. This change does not bypass existing locks.
- No database migration, credential routing, or legacy authentication
change.

## Model Used

OpenAI GPT-6 in Codex, with code execution and browser tools. The exact
deployment model ID and context-window size are not exposed to this
task.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-09-12 19:05:18 -05:00
DottaandPaperclip 6cef9743c0 fix: deliver saved user messages after recovery stops (#13327)
Deliver saved user messages after legacy recovery stops. Validate undelivered comments and queue ownership under the task lock, preserve the operator identity checks from #13315, and prevent duplicate successors.

Add a recovery notice with Retry and inline errors, plus service, route, component, and browser coverage.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-09-12 18:08:04 -05:00
DottaandPaperclip b2acc674be fix: enable isolated subscription login on authenticated self-hosted instances (#13344)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - AI Connections store reusable provider credentials with company and
owner boundaries.
> - Self-hosted instances can require board authentication while running
agents on the local server.
> - The login UI treated those instances as unsupported and displayed
instructions without a command.
> - Removing that restriction must not expose the server operator's
existing CLI account.
> - This pull request enables owner-scoped login attempts and reuses the
existing login UI.
> - Users can connect Codex and Claude subscriptions on an authenticated
self-hosted instance.

## Linked Issues or Issue Description

**What happened?**

On an authenticated self-hosted instance, OpenAI subscription setup
displayed terminal instructions with no command and a disabled Connect
button. Claude also could not complete the local connection flow.

**Expected behavior**

An authorized board user can prepare an isolated sign-in attempt, sign
in on the server, and save the verified account as a Connection. This
must not import another user's or the operator's ambient credentials.

**Steps to reproduce**

Run Paperclip in authenticated mode with a local environment. Open
Connections, choose OpenAI or Anthropic, and select Subscription. The
previous UI never enabled local login preparation.

Related: #13247, #13248, and #10751. This fix preserves the restriction
on remote access to the operator's ambient Claude login.

## What Changed

- Allow company-authorized users to create, check, cancel, and complete
their own isolated local login attempts.
- Keep ambient Claude credential import restricted to the local
operator.
- Support isolated Claude credential files without falling back to the
host account or mutating process-wide environment variables.
- Use Codex device authorization so sign-in does not depend on a browser
callback to the remote server's localhost.
- Gate server-host login on authenticated public deployments unless a
trusted runtime host is configured. Publish the capability through
health so setup shows supported alternatives.
- Read isolated Claude credential files through bounded,
descriptor-bound opens with ownership, permission, and symlink checks.
Try the alternate filename after malformed JSON.
- Reuse shared login instructions and lifecycle hooks in onboarding,
agent setup, and Connections. Show health-query failures explicitly.
- Document authenticated self-hosted behavior and add authorization,
isolation, lifecycle, and UI regression tests.

## Verification

- Passed 71 focused tests across connection routes, credential
isolation, legacy compatibility, the shared login hook, and agent setup.
- Passed 89 onboarding regression tests.
- Passed `pnpm -r typecheck`, `pnpm build`, Storybook build, and `pnpm
check:token-gates`.
- Completed real Codex device authorization and Claude browser
authorization on an authenticated Linux self-hosted instance. Both
accounts were detected automatically and saved as Connected. Both
completed attempt directories were removed.
- These live checks cover login, credential validation, and connection
creation. They do not establish a new model execution or long-running
refresh result.
- Review follow-up: 68 focused checks passed after rerunning one route
socket error; the full route/health rerun passed all 49 tests. The
70-test onboarding suite also passed. Final workspace typecheck,
production build, and Storybook build passed again.
- The broad local run exposed an instance-name assumption in two new
assertions. The fixture now uses an explicit non-default instance, and
all 32 connection tests passed with a different inherited instance name.
The superseded broad run was stopped; this is not a claim that the full
local suite completed. Full CI results will be recorded before merge.

## Risks

- The server must have the provider CLI installed. Users still run the
displayed command on the server that hosts Paperclip.
- Authorization checks must keep login attempts scoped to the company,
owner, provider, and reconnect target. Regression tests cover cross-user
and cross-company access.
- Existing local-trusted Claude behavior stays available. Authenticated
remote users cannot use its ambient import path.
- No database migration, dependency change, agent binding change, or
provider routing change is included.

## Model Used

OpenAI GPT-6 through Codex, with reasoning, code execution, and browser
tools. The runtime does not expose a more specific model version or
context-window size.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [ ] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-09-12 23:06:55 +00:00
8b84ae5b35 fix(ui): improve mobile entity picker sheets (#13343)
Co-Authored-By: Paperclip CodexRunner <codexrunner@paperclip.local>
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-09-12 22:42:37 +00:00
DottaandPaperclip df984cbc2c fix: dispatch queued legacy messages with operator identity and task permissions (#13315)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Task conversations save messages that arrive during an active turn.
> - Legacy adapters deliver these messages in a later turn.
> - A run can stop before the saved queue is delivered.
> - The Interrupt button previously required an active run, so it could
not release this queue.
> - This pull request lets a board operator send the saved queue after
the run stops and retries queues missed during finalization.
> - Manual dispatch must use the clicking operator and must not require
permission to create agents.
> - The task can continue without a duplicate message or a second
execution owner.

## Linked Issues or Issue Description

**What happened?**

A legacy task retained a queued message after its run stopped. Interrupt
was disabled because the queue had no active target. Finalization and
deferred message admission can also leave a queue without a successor.

**Expected behavior**

Interrupt sends the saved messages when no runner is active. Messages
that arrive during normal completion are delivered automatically. An
uncertain previous execution still requires proof that its process or
sandbox stopped.

**Steps to reproduce**

1. Queue a user message during a legacy conversation turn.
2. Let the turn stop or simulate a server restart before queue
promotion.
3. Open the task with a deferred queue and no active run.
4. Try Interrupt. Before this change, the button is disabled.

**Paperclip version or commit**

Reproduced against `8f40b4ad4`.

**Deployment mode**

Legacy conversation adapter. The same persisted queue state is covered
with an isolated PostgreSQL fixture.

Related public work: #13275 adds active legacy interruption. #13291
addresses automatic sandbox conversation recovery. This change handles
explicit saved-queue delivery and late queue promotion.

## What Changed

- Accept a null Interrupt target while retaining queue identity,
revision, company, and assignee checks.
- Save the operator's request on the existing queue. Reuse normal
admission after verified stop, including older messages, different
authors, and queues whose original wake came from the system.
- Strip interruption authority from caller-supplied wake payloads. Only
the board queue route can persist that authority.
- Retry durable interruption requests after restart and deferred queues
after legacy cleanup.
- Let an explicit Interrupt retry cleanup for its stopped run, including
old ephemeral leases that recorded success without a provider stop
receipt. Preserve retained resources, other lease owners, and the
automatic retry limit.
- Preserve the server's waiting explanation when normalizing and
combining queue entries.
- Revalidate the consumed board queue receipt at dispatch so a different
message author does not cause setup failure.
- Use the Interrupt user's execution identity for the new run. Preserve
original message authors. Validate the receipt independently at startup
and inherit the resulting identity on retry.
- Persist authenticated board authority for ordinary manual wakes too.
Adopting someone else's queued messages cannot switch a manual run to
that author's permissions. Strip caller-supplied authority markers and
retain private conversation ownership checks.
- Keep the clicking user when a manual wake is merged into an older
deferred receipt. Update its requester and payload in the same
transaction.
- Use the same current-queue/revision API on task details and pipeline
conversations; show Interrupt after a legacy target stops.
- Keep manual wakes out of active runs, including unscoped agent wakes.
They receive their own execution identity; a matching receipt requester
is not sufficient because an exact retry can retain a different
originating identity.
- Authorize both existing-agent wake endpoints with `agent:wake`,
available to active non-viewer company members. Keep `agents:create` for
hiring. Validate the stored task and current assignee before an exact
task retry.
- Reject viewer Interrupt requests before saving intent or stopping
execution. Keep external chat retry authorization and per-action
agent/user permission checks.
- Preserve edits and discards until dispatch. Prevent another queue
promotion when the same agent already has a successor. Keep independent
reviewer recovery available.
- Suppress cancelled/failed run toasts for intentional operator
interruption. Keep ordinary runtime error notices.
- Add UI, route, admission, restart, successor ownership, and toast
regression tests. Document the behavior.
- Reuse the existing socket reservation helper for both
credential-quorum test cases after CI exposed an ambient-port collision.
This changes test preparation only; production credential staging is
still called exactly once.

## Verification

- Failing regression tests reproduced the message-author identity bug
and an operator's `agents:create` rejection before the fixes.
- All 316 focused tests pass across eight route, queue, identity,
authorization, continuation, and responsible-user suites, including the
44-test rerun of queue admission and actual startup after the final
manual-wake restriction. Regressions reproduce cross-user merging both
with and without a task, and same-requester receipt ambiguity. The
cross-company existence guard also passes both tests.
- Startup integration tests reach adapter execution under the clicking
operator and retain that identity through follow-up. Coverage includes
mixed authors, adopted queues, system-origin queues, restarts, forged or
stale receipts, viewers, suspended memberships, changed assignees,
private conversations, and caller-supplied authority markers.
- The earlier queue/cleanup/UI regression suite passed 402 tests. The
final review corrections pass another 180 tests across queue
admission/persistence, real heartbeat startup, UI API, conversation
rendering, and pipeline suites. Regression tests reproduced both review
findings before correction. The final head has a 5/5 review with no
unresolved threads. Full CI passes on `c2002979c`, including every
general and serialized server shard, all browser shards, Paperclip
Runner verification, typecheck, build, canary dry run, and the aggregate
gates.
- Full `pnpm -r typecheck`, `pnpm build`, and UI token gates pass after
the final application changes. CI identified an outdated task-page API
mock after the shared helper extraction; the fixture now exercises the
real helper, and all 131 task-page/API tests pass. The final application
build passes with the additional manual-wake restriction.
- CI exposed a pre-existing port collision in the Codex
credential-quorum fixture. It reproduced locally; both listener cases
now use the existing bounded reservation helper. All 41 credential tests
pass on rerun. One intervening local run hit a separate ambient bind
collision in the two-occupied-port case.
- The full local `pnpm test:run` attempt was stopped after host
contention caused focused-suite timeouts. The affected focused tests
passed on rerun. An expiring trace fixture and a missing
private-conversation state were corrected. The successful full CI run is
the complete-suite verification.
- Hosted Interrupt previously cleared the original queue and produced
exactly one successor with neutral interruption feedback. It exposed the
dispatch authorization defect. Retry on that earlier build was rejected
for missing `agents:create` before creating another run.
- Deployed the final application build (`38257f391`) to the scoped
hosted instance and verified readiness. The latest PR commit changes
only the credential test fixture; application code matches that
deployment. A live Retry by the same operator without `agents:create`
created one successor attributed to that operator, passing the former
dispatch permission gate. Startup then stopped at
`configuration_incomplete` because that operator has not configured
their required personal Claude Code OAuth secret; the post-deployment
run page confirms the operator identity and no provider work started,
and the My secrets UI still shows the token as not set. Provider
execution remains unverified pending that credential. No permission
grants or credentials were changed.

## Risks

Queue admission and finalization can race. The task lock, durable queue
receipt, current comment IDs, and successor guard prevent duplicate
dispatch. Process and lease stop checks, task pauses, approvals,
ownership, and budgets remain in force. The API change only allows null
on legacy Interrupt; native steering still requires an active run. No
schema migration is required. Active non-viewer board members can now
invoke existing agents without agent-creation permission. Agent
self-invocation rules, raw provider-trace admin access, task retry
scope, external chat authorization, and action-specific user/agent
permissions remain enforced.

## Model Used

OpenAI GPT-6 through Codex. The session does not expose an exact backend
model ID or context-window size. Used reasoning, repository search, code
execution, tests, and browser tools.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` OR (b) described the issue in-PR following the relevant issue
template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-09-12 17:11:30 -05:00
DottaandPaperclip 8d6232e7b0 feat: reuse provider sign-in across AI connection workflows (#13248)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Users connect provider accounts during onboarding and agent setup.
> - They should reuse and manage those accounts through the existing
Connectors interface.
> - A second login wizard would diverge from the established provider
workflows.
> - This pull request composes the existing sign-in components into
Connections and agent configuration.
> - Users can select accounts without changing their agent's harness or
model.

## Linked Issues or Issue Description

**Problem or motivation**
AI credentials are configured separately from Connections. Agents cannot
consistently reuse a responsible user's account or a permitted shared
account.

**Proposed solution**
Manage AI accounts with the existing Connections grants and permissions.
Keep model and harness selection independent from credential selection.
Preserve legacy authentication until validated adoption.

**Alternatives considered**
A separate credential registry would duplicate ownership and access
policy. Automatic fallback would risk using the wrong account.

**Roadmap alignment**
This extends the shipped Apps, multi-user, secrets, and agent-runtime
capabilities. The maintainer requested the feature and reviewed the UI.
Related groundwork: #11899 (connection permissions), #10910 (connection
wizard), #11692 (Claude subscription profiles), and #11854 (Codex
account rotation).

## What Changed

- Add compact AI-account management to the existing Connectors pages.
- Reuse AgentProviderConnection, AdapterLoginPanel, AdapterLoginChrome,
and authentication controllers.
- Add the shared connection picker to agent setup/settings and task
requests.
- Preserve onboarding's sequence and reuse existing accounts.
- Add local-login recovery, retry, cancellation, and React StrictMode
handling.
- Add interactive Storybook scenarios, design-guide examples, and app
acceptance checks.

This is part 2 of the AI Connections change. The runtime foundation in
#13247 is merged. This PR now targets master.

## Verification

- Updated against master `47ded8bf9`, including the landed runtime
foundation and upstream task-search changes.
- Full workspace typecheck, production build, Storybook build, and token
gates passed on the integrated branch. Final local-login changes passed
59 focused tests; new-agent and inbox regression suites passed 63 tests.
- Browser checks verified automatic local Claude account detection,
resumable Codex login commands, retry, focus restoration, and
desktop/phone layouts. Commands create their isolated directory before
invoking the CLI.
- All CI test, browser, build, packaging, and runner jobs passed on
final head `dd17d3211931dd70aaa6ea619d83a7f9966dd18e`. The fresh
Greptile review is 5/5, the security scan passed, and there are no
unresolved review threads. The final CI aggregate gates passed.
- Local general-server coverage passed 11,804 tests; three
port-collision failures passed in an isolated 25-test rerun. All 6,111
UI tests passed. CLI coverage passed 484 tests; its remaining doctor
test requires port 3199, which is occupied by an unrelated report server
on this Mac. The complete CLI suite passed in CI.
- Live browser testing verified Codex API-key reconnect inside a task
card on desktop and phone. Real provider runs resumed and completed with
unchanged connection/grant identity and agent routing.
- Tested opening, cancelling, reopening, and completing connection
creation. A regression confirms Connect another account cannot submit
the new-agent form or copy provider keys into agent settings.
- Added shared inline repair, automatic local sign-in checks, and
responsive connection dialogs. Standalone Daytona installation ignores
workspace configuration and suppresses dependency scripts. Its
standalone build also passed with CI's exact pnpm 9.15.4.
- Destructive live tests are excluded by default. Explicit opt-in, local
deployment checks, and matching disposable fixture identities are
required before any mutation.

## Risks

- Local Codex/Grok creation requires the connection-specific terminal
login command.
- Browser sign-in uses the existing supported-environment controllers.
- This update verifies live local Claude detection and Codex API-key
task repair. New subscription authorization/refresh and
independent-human/native-runner isolation were not reverified in this
update.
- No agent automatically adopts managed Connections.

## Model Used

OpenAI GPT-6 through Codex, with reasoning, repository tools, code
execution, and browser testing. The exact runtime model identifier and
context-window size are not exposed in this session.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-09-12 16:51:26 -05:00
DottaandPaperclip 47ded8bf97 feat: manage AI runtime credentials through Connections (#13247)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Agent runs need credentials for a specific provider and sign-in
method.
> - Connections already owns accounts, grants, and access permissions.
> - AI authentication should use those same boundaries.
> - This pull request adds the storage, API, adoption, and runtime
foundation.
> - Legacy agents keep their authentication until they explicitly adopt
a managed connection.

## Linked Issues or Issue Description

**Problem or motivation**
AI credentials are configured separately from Connections. Agents cannot
consistently reuse a responsible user's account or a permitted shared
account.

**Proposed solution**
Manage AI accounts with the existing Connections grants and permissions.
Keep model and harness selection independent from credential selection.
Preserve legacy authentication until validated adoption.

**Alternatives considered**
A separate credential registry would duplicate ownership and access
policy. Automatic fallback would risk using the wrong account.

**Roadmap alignment**
This extends the shipped Apps, multi-user, secrets, and agent-runtime
capabilities. The maintainer requested the feature and reviewed the UI.
Related groundwork: #11899 (connection permissions), #10910 (connection
wizard), #11692 (Claude subscription profiles), and #11854 (Codex
account rotation).

## What Changed

- Add AI-purpose/runtime-auth contracts and an additive, idempotent
migration.
- Add Claude, OpenAI, OpenRouter, and Grok provider capabilities and
catalog entries.
- Store credentials on grants. Resolve responsible-user defaults or
explicit permitted grants.
- Isolate managed credentials and provider sessions across accounts.
Block missing credentials without ambient fallback.
- Keep imported legacy secrets unchanged during reconnect. Use
independent local Codex/Grok sign-in attempts for rotating credentials.
- Add authorization, migration, concurrent refresh, retry, cancellation,
and legacy-compatibility tests.

This is part 1 of a two-PR stack. The app UI follows in #13248. Merge
the foundation first.

## Verification

- Updated against master `04e364236`, preserving upstream provider login
and connector workflows.
- Full workspace typecheck, production build, Storybook build, and token
gates passed on the integrated branch. Final local-login changes passed
59 focused tests; new-agent and inbox regression suites passed 63 tests.
- Browser checks verified automatic local Claude account detection,
resumable Codex login commands, retry, focus restoration, and
desktop/phone layouts. Commands create their isolated directory before
invoking the CLI.
- All current-head CI checks passed on `2a996560a`, including all
server/workspace tests, browser shards, runner verification, typecheck,
build, and canary dry run. Greptile reviewed that commit at 5/5 with no
unresolved threads. Earlier local full-suite attempts hit the Mac
PostgreSQL shared-memory limit; the complete suites passed in CI.
- Renumbered the additive AI migration to `0276` after upstream
migrations and regenerated its snapshot. Existing legacy agents retain
their configuration.
- Added local login status checks, owner-scoped retry, managed OpenCode
remote homes, credential-aware model discovery, and task
connection-repair delivery.

## Risks

- Managed credential failures intentionally block execution. They do not
restore legacy fallback.
- Preview-era copied Codex/Grok subscriptions require independent
reconnect.
- The integrated branch has live provider acceptance coverage. This
update verifies local Claude detection and Codex API-key task repair; it
does not add a new subscription authorization/refresh or Daytona stress
pass.
- Runtime-auth connections must stay excluded from tool and channel
handling.

## Model Used

OpenAI GPT-6 through Codex, with reasoning, repository tools, code
execution, and browser testing. The exact runtime model identifier and
context-window size are not exposed in this session.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-09-12 16:30:10 -05:00
DottaandPaperclip 1652a5c7f2 fix: improve task search relevance with a PostgreSQL rubric (#13335)
Unify full and quick task search around PostgreSQL term coverage, explicit relevance bands, and conservative typo recovery. Preserve matching evidence and navigation, and add a judged corpus, regression tests, and documented performance measurements.

Validation: local typecheck, build, focused PostgreSQL tests, and task-list tests pass. All final-head CI gates pass and Greptile is 5/5.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-09-12 16:22:58 -05:00
Devin Foley 6b45db0c35 fix(deps): force one @codemirror/state resolution via pnpm overrides (#13324)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - The web UI embeds CodeMirror editors, and CodeMirror validates
extensions with `instanceof`
> - Different CodeMirror packages pin different transitive minors of
`@codemirror/state` (6.7.1 / 6.7.2) and `@codemirror/view` (6.43.9 /
6.43.11), so the bundle ships two module instances
> - The second instance makes valid extensions fail the `instanceof`
check and crashes the editor
> - This pull request adds a shared caret override to `pnpm.overrides`,
the same mechanism the existing `react` and `rollup` overrides use, so
every consumer resolves one copy of each package
> - The lockfile is not edited by hand; the lockfile automation
regenerates it from the manifests
> - The benefit is that the editor stops crashing with "Unrecognized
extension value in extension set"

## Linked Issues or Issue Description

**What happened?**

The production UI throws `Error: Unrecognized extension value in
extension set ([object Object]). This sometimes happens because multiple
instances of @codemirror/state are loaded, breaking instanceof checks.`
Observed 43 times in one week.

**Expected behavior**

The editor loads its extension set without errors. One instance of
`@codemirror/state` and `@codemirror/view` serves every CodeMirror
package.

**Steps to reproduce**

1. Run `grep "'@codemirror/state@" pnpm-lock.yaml` on master: two
versions resolve (6.7.1 and 6.7.2).
2. Build `ui/` and search the output for `Unrecognized extension value`,
a string unique to `@codemirror/state`: two chunks each carry a full
copy, one with a 6.7.1-only code pattern and one without it.
3. Open a view that composes extensions from packages on different
copies: the extension set rejects the foreign-instance extension.

**Paperclip version or commit**

master (0e14c61da)

## What Changed

- `package.json` (`pnpm.overrides`): added `"@codemirror/state":
"^6.7.2"` and `"@codemirror/view": "^6.43.11"`. A shared range forces
every consumer onto one resolution of each package.
- `pnpm-workspace.yaml`: the mirror overrides block gets the same two
entries, kept in sync with `package.json`.
- `ui/src/lib/codemirror-single-instance.test.ts`: regression pin that
fails when the lockfile resolves more than one version of either
package.
- No lockfile change in this PR. The `policy` job regenerates
`pnpm-lock.yaml` from the manifests for downstream jobs; CI owns
lockfile updates.

## Verification

- With the override, `pnpm install` resolves a single
`@codemirror/state@6.7.2` and a single `@codemirror/view@6.43.11`.
- Built `ui/` before and after. Before: two chunks each carried a full
copy of `@codemirror/state` (four total occurrences of its unique error
string; one chunk fingerprints as 6.7.1, the other as 6.7.2). After: one
chunk carries one copy (two occurrences, no 6.7.1 fingerprint).
- `pnpm vitest run src/components/IssuesList.test.tsx` in `ui/` — 46/46
pass.
- New test `ui/src/lib/codemirror-single-instance.test.ts` pins the
invariant: the lockfile must resolve exactly one version of
`@codemirror/state` and `@codemirror/view`. The PR CI policy job
regenerates the lockfile from the manifests, so the test evaluates this
PR's real resolution — verified locally against a lockfile regenerated
the same way (`pnpm install --resolution-only`): 2/2 pass, and the same
test fails against the current master lockfile with its two resolved
copies.

## Risks

- Low risk. The override stays inside the caret ranges every consumer
already declares, so no package receives a version outside its stated
compatibility. Rollback is removing the two override lines.
- A future CodeMirror consumer that needs a major bump of these packages
must update the override; the override comment states why it exists.

## Model Used

Claude (Anthropic) — claude-fable-5 (Claude Fable 5), Claude Code
harness, extended thinking with tool use.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [ ] All Paperclip CI gates are green
- [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge
2026-09-12 13:24:47 -07:00
DottaandPaperclip 4d317274ce feat(channels): add experimental iMessage Photon (#13299)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Channels connect external conversations to company tasks and agent
execution.
> - Slack, Discord, and AgentMail already provide durable delivery and
access controls.
> - People also need to reach an agent from Apple Messages and send
photos.
> - Photon provides shared Pro DMs, dedicated numbers, and authenticated
event recovery.
> - This pull request connects Photon to the existing channel services.
> - People can message an agent while Paperclip retains task ownership
and approval authority.

## Linked Issues or Issue Description

**Subsystem affected**

Cross-cutting: channel services, shared contracts, database constraints,
Apps, and agent Channels UI.

**Problem or motivation**

Paperclip has no iMessage channel. A person cannot use Apple Messages to
start a task, send a photo, or answer an agent's pending question.

**Proposed solution**

Add experimental **iMessage Photon** with Pro-compatible shared DMs or a
dedicated Photon Cloud number per agent channel. Reuse channel
admission, identity links, task generations, publication, and
interaction continuation. Keep groups disabled for shared allocation.
Dedicated lines support groups that an operator explicitly enables.
Require a fresh linked message and a published agent response before
setup completes.

**Alternatives considered**

Shared allocation has no owned phone number, so it reserves one project
and allows DMs only. Dedicated allocation reserves one stable number.
Local Mac access needs a separate deployment model. The upstream Photon
Chat SDK adapter does not persist the poll mappings and send receipts
required here. This change uses the lower-level SDK without adding
another agent runtime.

**Roadmap alignment**

This extends Connected Apps and agent communication through the existing
channel subsystem. It does not add a parallel tool connection or agent
loop. GitHub searches for Photon and iMessage found no matching provider
implementation.

**Additional context**

This ships behind the existing experimental channel gate. Dedicated-line
release qualification remains incomplete. Real Photon Pro DMs passed
task/reply, native poll, text answers, confirmation rejection, media,
restart, pause, reconnect, revocation, and removal tests. An
operator-supplied iPhone camera HEIC also passed the full round trip.
Dedicated groups remain unqualified. See [the verification
record](doc/connections/IMESSAGE-PHOTON-VERIFICATION.md) and [the
implementation plan](doc/plans/2026-09-11-imessage-photon.md).

## What Changed

- Add the provider catalog entry, shared setup contracts, and a forward
migration. A global partial index reserves the dedicated number or
shared project until its endpoint is archived.
- Add Cloud project inspection, vaulted project credentials,
selected-line token renewal, and a leased receiver. Persist checkpoint
updates under the receiver lease. Shared project replay accepts sparse
increasing sequences only after a complete recovery barrier.
- Connect DMs and enabled groups to existing task generations, sender
authorization, ordered delivery, and publication services. Keep each
iMessage conversation on its task after completion; only explicit `/new`
or `/close` releases the binding. Publish committed inbound comments
live and label their human bubbles “Sent from iMessage” in both
task-chat renderers.
- Persist immutable text/file send identities, upload receipts, poll
IDs, option IDs, per-person drafts, and canonical interaction
continuation proofs.
- Add source-bound file recovery, bounded HEIC/HEIF conversion, JPEG
previews, and related Live Photo companion video retention.
- Add the three-step setup flow and channel management surfaces with
official branding. Preserve the experimental gate and existing
pause/disconnect behavior.
- Add interactive production-component Storybooks for setup, access,
recovery, and ongoing conversations. Add provider, integration, catalog,
and browser regression coverage. Document setup, recovery, supported
boundaries, and qualification gaps.

## Verification

- Live Photon Pro, SDK 2.1.0: linked iPhone messages create a task and
receive native Codex replies in Apple Messages. Unlinked senders cannot
start work.
- Three real follow-ups each reopened the same completed task. Incoming
bubbles appeared on its open page without reload and showed “Sent from
iMessage.” The third follow-up ran after restarting the server on
`4d7222110`; the agent correctly repeated its previous reply from before
the restart.
- Native polls after restart, sequential text drafts, required-field
correction, explicit submission, approval rejection with a required
reason, and native continuation passed against Photon.
- PNG, text documents, synthetic HEIC, and a real iPhone camera HEIC
passed in both directions. The camera photo produced a 3024×4032 JPEG
preview. The native agent described it and returned the received HEIC
byte-for-byte.
- Pause/resume, reconnect, identity revocation, removal, `/status`,
`/new`, `/close`, and stale answers after close passed live. Messages
suppressed by pause did not become work on resume. Removal stopped
intake and removed credential bindings.
- All 304 focused tests passed on `4d7222110`. These cover Photon
unit/integration behavior, both task-chat renderers, live comment
hydration, completed-task continuity after restart, enabled groups,
duplicate delivery, and explicit reset/close. The selected Teams
completion-boundary regression also passed. Full workspace
typecheck/build and token gates passed for the conversation fix; the
final UI changes passed their affected typecheck/build and tests.
- All 26 new Photon Storybook Playwright cases passed in light and dark
themes, including the complete shared-DM setup journey and 390px mobile
follow-ups. UI typecheck and the Storybook build passed. These stories
use simulated Photon responses and do not replace the live evidence
above.
- The full chat-adapters browser suite previously passed all 39 cases.
Migration checks passed, and migration 0275 applied to the isolated live
instance with the earlier Photon migration already applied.
- The local full Vitest run was previously interrupted by the host's
embedded-Postgres shared-memory limit; it is not a full-suite pass. All
30 applicable CI checks passed on preceding head `7a5419cac`, with two
skipped checks and Greptile 5/5. Head `24f8e1aae` adds an explicit
required-story discovery guard to the 26 passing Storybook cases.
Greptile rates this final head 5/5 with no unresolved review threads.
All 30 applicable CI checks passed, with two optional checks skipped.
- A repeated live send key suppressed the duplicate but returned gRPC 6
/ SDK `internalError` without an original receipt. Paperclip keeps
unknown delivery unresolved. This provider behavior is covered by a
regression test.
- See [the verification
record](doc/connections/IMESSAGE-PHOTON-VERIFICATION.md) for package
versions, redacted live evidence, deterministic coverage, and remaining
qualification gaps.

## Risks

- Dedicated group qualification remains unrun; groups are disabled for
the approved Pro scope. Real iPhone camera HEIC passed transport,
preview generation, agent inspection, and return. Keep the channel
experimental; the dedicated-line release matrix remains incomplete.
- Shared recovery and attachment aliases were verified against the live
gateway. Duplicate writes currently return an error without the original
receipt; unresolved sends require operator resolution. The
implementation fails visibly on invalid replay ordering, a reset cursor,
or changed identity.
- The HEIF converter passed on macOS arm64 and in Linux CI. Windows HEIF
binaries have not been executed in this work. Linux musl has no packaged
converter. Unsupported conversion retains the original and reports the
missing preview.
- The migration adds a global reservation across companies for Photon
numbers and shared projects. Paused and revoked endpoints keep that
reservation until removal.
- Integration touches shared channel services. Existing provider browser
coverage passes; broad repository verification is recorded above.
- `pnpm-lock.yaml` is intentionally excluded under repository policy.
The repository bot owns lockfile updates. The additional Superagent
supply-chain scan is neutral/inconclusive because these new dependencies
are not yet in the committed lockfile. Its security scan passed; all
required CI checks pass.

## Model Used

OpenAI Codex, GPT-6 family, with reasoning, repository inspection, code
execution, browser testing, and tool use. The exact served model
identifier and context-window size are not exposed in this session. No
sub-agents were used.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-09-12 15:23:50 -05:00
DottaandPaperclip ab15aff390 feat: add experimental persistent agent chat (#13284)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Conversations must use the same tasks, controls, and execution
history.
> - Users need an ongoing chat with an agent without managing task
properties.
> - Agents should clarify and plan work, then hand execution to assigned
project tasks.
> - This pull request combines the reviewed Agent Chat stack for one
squash merge.
> - The benefit is persistent conversation with normal task governance
and shared UI.

## Linked Issues or Issue Description

**Subsystem affected**

Task lifecycle, agent runtime tools, shared task UI, and browser/paid
runner tests.

**Problem or motivation**

Users need one persistent conversation with each agent. A separate chat
store or renderer would duplicate task behavior and bypass existing
controls.

**Proposed solution**

Use a task-backed chat per company, user, and agent. Reuse the task
composer and transcript. Clarify and plan in chat, then create assigned
project tasks with the relevant plan. Keep Agent Chat behind its own
disabled-by-default experimental setting.

**Roadmap alignment**

This implements the task-backed direction in [CEO
Chat](https://github.com/paperclipai/paperclip/blob/master/ROADMAP.md#-ceo-chat).
Related proposals: #2504 and #9693. Related request: #7981. The
maintainer requested one squash merge of the complete stack.

Consolidates the reviewed runtime
[#13281](https://github.com/paperclipai/paperclip/pull/13281), backend
[#13282](https://github.com/paperclipai/paperclip/pull/13282), and UI
[#13283](https://github.com/paperclipai/paperclip/pull/13283) layers
with this PR's E2E coverage. All four layers passed CI and received
Greptile 5/5 before consolidation. This PR targets master and includes
the complete feature.

## What Changed

- Add personal canonical chat tasks with ordinary company visibility,
immutable identity, idempotent first sends, and an idle waiting state.
- Process `/new` in queue order. Preserve history, release a chat pause,
and fence old provider context and delayed writes.
- Keep chat lifecycle rules across recovery, finalization, assignment,
task lists, and rollups.
- Support research and plan revision in chat. Hand plans to ordinary
assigned project tasks before execution starts. Reject new chat
subtasks.
- Add repository-aware project creation and discovery tools, including
multiple repository IDs and GitHub URLs, authorization, idempotency, and
durable project-created cards.
- Reuse task UI components for chat, with starred/recent agent
navigation and a separate `enableAgentChat` experimental flag.
- Add deterministic browser tests and 24 paid chat cells across four
Codex/Claude profiles, with validated reports and screenshots.
- Integrate current master recovery, controller lease, queued-message,
and task UI changes. Gate chat interruption and deferred promotion on
ownership/feature policy. Guarantee lease renewal and active controls
are stopped even if teardown fails.
- Preserve master's migration 0273 and generate chat migration 0274 with
idempotent replay for development databases.

## Verification

- Prior exact heads of all four PRs passed Linux CI, including build,
typecheck, general/serialized tests, and browser E2E. Each had Greptile
5/5 and no unresolved findings.
- Integrated local verification passed: full repository typecheck and
production build, Storybook build, token gates, 340 focused UI tests,
all 20 deterministic chat browser tests, two migration replay tests, 88
focused chat/queue/native/controller tests, and provider/session
regressions including real lease expiry. These include the three
lifecycle regressions for the final admission/teardown fixes; server
typecheck also passes. Current head
`1268eda16cc2af892055917e7292f068820be135` has Greptile 5/5 with no
unresolved findings and passing security scans. All final-head CI gates
passed: build, full Runner verification, typecheck/release registry,
canary, all general/serialized test shards, and all browser E2E shards
([CI
run](https://github.com/paperclipai/paperclip/actions/runs/34696739927)).
Local PostgreSQL startup contention required serialized retries; skipped
fixtures do not count as passing coverage.
- The earlier paid campaign passed all 24 chat cells and retained 32
screenshots:
[report](https://d1p6rlowie26tp.cloudfront.net/runner-e2e/campaigns/gha-34648511170-1/index.html?report=agent-chat#suite-agent-chat).
It tested `abacbdfd2f660709ec37312cdb758284c8399d04`; it is prior
evidence, not a paid run of this integrated head.
- Manual check: enable Agent Chat in Experimental settings, open an
agent, clarify and revise a plan, then hand off to an assigned project
task. Stop a reply, send `/new`, and verify fresh context with retained
history. Disable the setting and verify agent shortcuts/new chat turns
are blocked.

## Risks

- Queue/session integration can affect retries and delayed writes. Tests
cover ownership, cancellation, reset boundaries, idle recovery, and
ordinary task behavior.
- Migration 0274 adds conversation fields and constraints. Replay is
idempotent and preserves existing development chat history.
- This combines the previously reviewed stack at the maintainer's
request. Agent Chat remains off by default and is separate from
Conference Room.

## Model Used

OpenAI Codex, GPT-6 Astra (`gpt-6-astra`), with reasoning, code
execution, browser tools, and parallel review. The exact context-window
size is not exposed in this session. Codex and Claude also ran as test
subjects in the linked paid campaign.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-09-12 08:56:04 -05:00
DottaandPaperclip 586b5ec828 fix(ui): improve mobile task spacing (#13304)
## Thinking Path

> - Paperclip helps people manage AI agents and their work.
> - The task detail view is the main place for task conversation.
> - The mobile view used too much horizontal space for gutters and
controls.
> - The status control and identifier also reduced the title width.
> - This pull request gives the title its own mobile row and reduces
mobile padding.
> - The benefit is a clearer task view with more space for useful
content.

## Linked Issues or Issue Description

**What existing behavior does this improve?**

The mobile task detail header, conversation list, and message composer.

**Current behavior**

The title shares one row with status and identifier controls. The
conversation and composer also use larger mobile gutters than needed.

**Proposed behavior**

The title uses the full mobile width. Status and metadata use the next
row. The conversation and composer use smaller mobile gutters.

**Reason and benefit**

Long titles have more readable line lengths. The reduced padding gives
task content more room on small screens.

**Breaking changes**

None.

## What Changed

- Put the task title on a full-width mobile row.
- Move the mobile status and metadata below the title.
- Reduce the mobile conversation and composer padding.
- Update the composer dock class test.

## Verification

- `pnpm --filter @paperclipai/ui typecheck`
- `pnpm exec vitest run ui/src/components/TaskChatThread.test.tsx
ui/src/components/task-chat/TaskChatComposer.test.tsx
ui/src/pages/IssueDetail.test.tsx --reporter=dot`
- `pnpm --filter @paperclipai/ui build`
- `pnpm check:token-gates`
- `git diff --check`

## Risks

- Low risk. The layout changes apply only at the mobile breakpoint.
- Desktop spacing stays unchanged.

> For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and
discuss it in `#dev` before opening the PR. Feature PRs that overlap
with planned core work may need to be redirected — check the roadmap
first. See `CONTRIBUTING.md`.

## Model Used

- OpenAI Codex, GPT-5.6, with reasoning and tool use.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [ ] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-09-12 08:27:14 -05:00
DottaandPaperclip 8f40b4ad4b fix(connections): repair and simplify Google Workspace setup (#13289)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - App connections give agents controlled access to external services.
> - Managed Google Workspace methods depend on profiles enabled for each
Paperclip instance.
> - The catalog used those profiles, but connection creation used static
availability and rejected enabled connections.
> - Switching capabilities also reset personal ownership to company-wide
ownership.
> - This PR uses the same availability rules for catalog and setup, and
preserves supported ownership choices.
> - Paperclip is the default Google authentication method. A small link
opens custom OAuth settings when needed.
> - Local and cloud instances can start the selected Workspace
connection without broadening its audience.

## Linked Issues or Issue Description

**What happened?**

A fresh enrolled instance showed managed Google Workspace apps as
available. The issue was first found with Gmail. Selecting Continue to
sign in returned HTTP 422 with “This app does not have an available
connection method.” Changing from Read & create drafts to Read only also
reset Just me to company-wide ownership.

**Expected behavior**

Start Google authorization for an enabled profile. Keep personal
ownership when the selected method supports it. Reject profiles that the
instance cannot use.

**Steps to reproduce**

1. Start a fresh source test-drive and enroll the instance with
Paperclip Cloud.
2. Open Apps and select Gmail.
3. Select Just me and choose the agents that can use the connection.
4. Continue to setup and select Read only.
5. Go back to inspect ownership, then continue to sign in.

**Paperclip version or commit**

Reproduced on master commit 250deab910.
The fix is rebased onto current master.

**Deployment mode**

Local source test-drive. Regression tests also cover authenticated cloud
mode, HTTPS callbacks, and instance credentials supplied through
environment variables.

Related PRs: #13098 preserves task context through enrollment and OAuth.
#12619 introduced the managed Google Workspace rollout. This PR fixes
availability validation and ownership changes in that setup flow.

## What Changed

- Share instance-specific managed-method filtering between catalog
discovery and connection creation.
- Keep stored managed methods recognizable during callback, refresh, and
revoke.
- Preserve credential ownership when switching to another method that
supports it.
- Replace the Google authentication radio cards with a small Use your
own Google OAuth app link. Reveal custom fields only when selected, with
a Use Paperclip instead link to return. Associate the toggle with its
labeled field region for screen readers.
- Test all 16 managed Google Workspace profiles in local and
authenticated cloud modes, including cloud environment credentials and
unavailable profiles.
- Test ownership across all nine Workspace app cards, including
capability changes, authentication changes, and enrollment return.
- Document the shared availability and ownership behavior.

## Verification

- All 135 setup tests pass after the UI change. The focused connector
and service suites also passed before this presentation-only change.
- The expanded Workspace matrix includes 32 local/cloud callback cases,
16 cloud environment-identity cases, 32 unavailable-profile cases, and
18 UI ownership cases.
- `pnpm -r typecheck`, `pnpm build`, and `pnpm check:token-gates` pass.
UI typecheck and token gates also pass on final commit `2071002d6`.
- Browser tests cover Gmail, Calendar, Chat, Docs, Drive, People,
Sheets, Slides, and Workspace Search in an isolated source test-drive.
- Each app reaches Google sign-in with its expected read-only scopes.
Personal ownership persists after capability or authentication changes.
Chat also resumes its saved setup with read-only access intact.
- Browser verification of the new layout: custom fields start hidden,
the small link reveals them, and keyboard activation of Use Paperclip
instead hides them. Personal ownership and read-only selection persist.
- Google consent was not granted. Live provider reads and a deployed
cloud instance remain unverified.
- The local repository-wide suite was stopped at the maintainer's
request. Full CI verification passed for final commit `2071002d6`: 31
successful checks, two optional Storybook checks skipped. This includes
repository tests, browser E2E, typecheck, build, and canary dry run.
Greptile reviewed that commit at 5/5 with no outstanding findings.

## Risks

- The shared availability helper affects all managed connectors. It
filters methods by the instance's advertised profiles and does not
mutate the static catalog.
- Stored connections can resolve their managed method after availability
changes. The broker still enforces current access during authorization
and refresh.
- No database migration or provider scope change is included.

## Model Used

OpenAI Codex (GPT-6), with reasoning, code editing, shell tools, and
browser automation. The session does not expose an exact runtime model
ID or context-window size.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-09-12 07:57:48 -05:00
DottaandPaperclip eb9f954bae fix(ui): stabilize steered chat activity presentation (#13246)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - The task chat shows live agent work and user steering.
> - Steered messages showed a second timestamp that did not match normal
chat messages.
> - Folded live work also changed height as new commands arrived.
> - Status carets and dots did not use the same vertical alignment.
> - This pull request gives these states one stable presentation.
> - The benefit is a task chat that is easier to read while an agent
works.

## Linked Issues or Issue Description

**What happened?**

Steered chat messages showed a separate queued or steered timestamp.
Folded live activity could grow and shrink. Some carets and status dots
did not align vertically.

**Expected behavior**

Steered messages use the normal timestamp. Folded live activity shows
one latest line until the user opens it. Carets and dots use the same
vertical center.

**Steps to reproduce**

1. Open a task chat with a running agent.
2. Steer the chat and inspect the message timestamp.
3. Keep live activity folded while new commands arrive.
4. Compare the caret with the status dot in the Reconnecting state.

**Paperclip version or commit**

Current `master` before this change.

**Deployment mode**

Local development mode.

## What Changed

- Use the normal timestamp for steered chat messages.
- Keep folded live activity to one line and replace it with the latest
activity.
- Keep the full activity timeline available after explicit expansion.
- Vertically align carets and status dots, including Reconnecting.
- Add focused component tests and Storybook review states.

## Verification

- `pnpm --filter @paperclipai/ui exec vitest run
src/components/task-chat/TaskChatRunnerTurn.test.tsx
src/components/task-chat/TaskChatStatusPill.test.tsx
src/components/task-chat/task-chat-adapter.test.ts` (63 tests passed)
- `pnpm --filter @paperclipai/ui typecheck`
- `pnpm check:token-gates`
- `pnpm --filter @paperclipai/ui build-storybook`

## Risks

- Low risk. The change is limited to task chat presentation and its
tests.
- A live activity item can replace the folded text. The expanded
timeline keeps the full history.

> This fix does not overlap with planned work in `ROADMAP.md`.

## Model Used

- OpenAI Codex. The runtime did not expose the exact model ID or context
window. The agent used reasoning, tool use, and code execution.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [ ] All Paperclip CI gates are green
- [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-09-11 21:26:44 -05:00
DottaandPaperclip 30aa3740ba fix(ui): make feed cards fully clickable (#13294)
## Thinking Path

> - Paperclip helps people manage AI agents and their work.
> - The activity feed shows cards for recent work.
> - A feed card showed a linked entity, but only some card content
behaved as one clear click target.
> - Users expect the image, title, and blank card space to open the
entity.
> - This pull request makes the full visible card use the entity link.
> - It also adds a regression test for the full-card click target.
> - The benefit is a larger and consistent navigation target.

## Linked Issues or Issue Description

**What happened?**

Clicks on some feed card content or blank card space did not reliably
open the linked entity.

**Expected behavior**

A click anywhere in a linked feed card opens its entity quick view.

**Steps to reproduce**

1. Open the activity feed.
2. Find a card that links to an entity.
3. Click its image, title, or blank space.
4. Observe that only part of the card acts as the link before this
change.

**Paperclip version or commit**

Current `master` before this pull request.

## What Changed

- Made each linked feed card anchor use the full available width.
- Made the visible card width account for its existing page margins.
- Added a component test that clicks the card and confirms link
navigation.

## Verification

- `pnpm --filter @paperclipai/ui exec vitest run
src/components/FeedCard.test.tsx`
- `pnpm check:token-gates`
- `pnpm --filter @paperclipai/ui typecheck`

## Risks

- Low risk. The change only expands the existing link click target.
- The width calculation can affect feed card layout. The regression test
checks the expected width classes.

> This bug fix does not add a roadmap feature.

## Model Used

- OpenAI GPT-5.6, Codex agent, with reasoning and code execution tools.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [ ] All Paperclip CI gates are green
- [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-09-12 01:58:25 +00:00
Michael Nguyen fe38085174 fix(ui): hide profile feedback flag on Cloud (#13292)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - The sidebar provides account controls and a feedback link.
> - Cloud now has Plain chat through the snippet support in #13168.
> - The feedback flag creates a second feedback route on Cloud.
> - This PR uses the existing Cloud metadata to hide the flag.
> - Self-hosted users keep the existing feedback link.

## Linked Issues or Issue Description

Refs #13168 and #10850. Related: #12778 proposes a separate native
feedback relay; this PR only hides the existing flag on Cloud.

**What happened?**
Cloud users see both Plain chat and the profile feedback flag, which
opens the external feedback form.

**Expected behavior**
Cloud users use Plain chat. Self-hosted users keep the profile feedback
flag.

**Steps to reproduce**
Open a Cloud instance with Plain enabled and expand the sidebar. Both
feedback controls are visible.

## What Changed

- Use `useCloudInstance()` in both account-menu variants.
- Render the feedback flag only when the sidebar is expanded and the
instance is not Cloud.
- Extend existing tests for Cloud and authenticated self-hosted
behavior.

## Verification

- Account-menu tests: 6 passed (`cd ui && pnpm exec vitest run
src/components/SidebarAccountMenu.test.tsx`).
- `pnpm check:token-gates`: passed.
- `pnpm --filter @paperclipai/ui typecheck`: passed.
- Full typecheck: failed in unchanged `plugin-workspace-diff` code
(`editStateKey` required by `UseFileDiffInstanceProps`).
- UI build: blocked by four missing exports in the installed
`assistant-cloud` dependency, including `createRunReport`.
- Repository build: failed on the same unchanged workspace-diff plugin
types.
- Full test suite: started, then stopped after broader validation hit
dependency failures. Only the six targeted account-menu tests are
claimed as passed.
- Fresh installation used `--no-frozen-lockfile --lockfile=false`
because the base lockfile and server manifest differ. No dependency or
lockfile changes are included.
- After deployment, check that Cloud has no profile feedback flag and
self-hosted still links to `https://paperclip.ing/feedback`.

## Risks

Low risk. The hook reads the existing health query cache and adds no
request. CloudAccessGate loads health before the main UI mounts. The
flag is hidden on all Cloud instances, so operators must keep Plain
configured. No backend, settings, or Plain integration changes.

## Model Used

OpenAI GPT-6 Codex, with code inspection and command execution. The
exact model ID and context-window size are not exposed in this session.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [ ] All Paperclip CI gates are green
- [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge
2026-09-11 17:03:38 -07:00
9b7bd41833 feat(ui): refine dashboard cards, charts, and recent lists (#13269)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Operators use the dashboard and Live runs page to inspect current
and recent runs.
> - Large transcript cards take space and make it hard to compare run
states.
> - A compact card must show the agent, linked task, and time, with
access to run details.
> - This pull request applies the supplied card design to both views.
> - Operators can scan more runs and open a run or task for details.

## Linked Issues or Issue Description

**What existing behavior does this improve?**

The agent run cards on the dashboard and Live runs page, plus dashboard
charts and recent lists.

**Subsystem affected**

`ui/` — React board UI.

**Current behavior**

Both views show large cards with embedded transcripts. Queued and
running cards share a live treatment. The dashboard chart grid leaves an
empty column, recent lists use different row sizes, and some activity
labels expose raw event names.

**Proposed behavior**

Both views use the same compact grid. Each card shows the existing
initials avatar, the agent name, one linked task row, and a
right-aligned timestamp. There is no status chip next to the agent name.
The timestamp uses small Inter text and the same muted gray as dashboard
metric descriptions. Recovery details remain in the task view. Run
status remains in the header tooltip and accessible label, and run
transcripts remain in the run detail view. The shared in-progress task
icon is now an animated circular spinner across the app.

**Reason and benefit**

Operators can scan task states without scrolling through embedded
output. The in-progress spinner keeps the shared task icon sizes,
circular shape, and stroke width. It honors reduced-motion preferences.

**Breaking changes**

The dashboard and Live runs page no longer show transcripts inside
cards. Open the agent header to inspect a run. There are no API or
database changes.

**Additional context**

Related public work found during the duplicate search:

- Refs #4317 — related run-state display concerns. This change does not
change server state reconciliation.
- Refs #11394 — related live-run cache updates. This change retains the
existing data flow.
- Refs #2118 — related navigation from agent cards. The card header here
opens the specific run.

## What Changed

- Apply compact cards to the dashboard and Live runs page, with status
icons and theme tokens.
- Use 16 × 16px status icons in the shared cards, including the
missing-task clock.
- Keep the existing circular initials avatar. Remove the status chip
beside the agent name while preserving the run label for tooltips and
accessibility.
- Replace the shared in-progress task glyph with an animated open
circle. Use the same 10-unit radius and 2-unit stroke as the other task
glyphs, with a reduced-motion guard across all task status surfaces.
This is the requested workflow-status indicator across the app,
including between runs; live indicators separately report active
execution.
- Use the same Tailwind blue tokens as nav dots and Live labels for the
progress icon: blue-400 in dark mode and blue-600 in light mode.
Covered-blocked icons follow the same blue token.
- Match the Tasks by Status chart's In Progress bar and legend to the
spinner's theme-aware color token.
- Distribute the three visible dashboard charts across equal-width
desktop columns, preserving existing gaps, card padding, and page
margins. Retain four columns when the optional priority chart is
enabled.
- Use the done task icon's `--status-task-icon-done` token for green
bars in Run Activity, Tasks by Status, and Success Rate, including their
legends.
- Use the blocked task icon's `--status-task-icon-blocked` token for red
bars and legends in Run Activity, Tasks by Status, Success Rate, and
priority charts.
- Align Recent Tasks live counts to the sidebar's right edge. Reveal the
ellipsis over a fading row surface on hover, keyboard focus, and while
its menu is open, without moving the label or count.
- Keep the ellipsis backdrop synchronized with the row background during
fade-out, using the actual sidebar surface in both themes to prevent a
darker flash.
- On coarse-pointer devices, reserve space for the always-visible
ellipsis and disable its fade so the live count remains readable beside
it.
- Order desktop dashboard Recent Tasks as status icon, task title, agent
avatar/name, 11px monospace task ID, then timestamp. In narrow cards,
keep the ID right-aligned beside the truncated title and place the agent
and timestamp on the second line.
- Give both dashboard lists the same 48px desktop rows, 24px leading
slots, 80px desktop task ID columns, and 64px right-aligned timestamp
columns. Use an 8px icon-to-content gap matching the task detail
heading. Narrow layouts use matching 76px rows with intrinsic-width IDs
on the title line; activity timestamps stay below.
- Order dashboard Recent Activity as actor avatar, actor name, verb,
task title, 11px monospace task ID, then timestamp. Use direct verbs
such as “Board read …” instead of “issue read marked”. Truncate titles
to preserve IDs and timestamps; keep full names and titles in tooltips.
- Use 12px task status icons in the top breadcrumb and Properties status
row. Keep the main task title icon at 20px.
- Reduce monospace task IDs to the 11px micro type token in breadcrumbs
and shared run cards, aligning them to the adjacent task titles' text
baseline while keeping status icons centered.
- Show the task title and identifier in one bordered row. Keep
missing-task links usable and show lookup failures.
- Remove the recovery chip and place the timestamp below the task row.
- Keep the link to all runs available when the dashboard has four or
fewer runs.
- Avoid transcript polling for compact cards.
- Fix bundled Inter font URLs and update the design guide and Storybook
fixtures.
- Cover run navigation, task status, failed lookups, shared icon sizes
and stroke, and reduced-motion-safe animation in tests.

## Verification

- Latest review fixes: targeted SidebarRecentTasks, SidebarNavItem,
StatusGlyph, StatusIcon, ActiveAgentsPanel, activity-format,
ui-font-assets, and Dashboard suites — 65 tests pass, including
read/unread verbs and reduced-motion-safe task animation.
- `pnpm --filter @paperclipai/ui typecheck` — passes.
- `pnpm check:token-gates` — all gates pass.
- `git diff --check` — passes.
- Related component suites passed during development: run cards, status
glyphs, breadcrumbs, issue properties, charts, sidebar navigation,
recent-task actions, and settings sidebar.
- Full repository `pnpm -r typecheck` and `pnpm build` pass on the final
commit using the temporary Rust toolchain. Storybook build passed
earlier in preparation.
- All CI gates pass on `c85e949b12b471d425d216caa609aee41dc58bde`: all
general/workspace and serialized server test shards, all three browser
shards, build/runner verification, typecheck/release registry, canary
dry run, policy, and security checks. The duplicate local `pnpm
test:run` was stopped after CI completed the same test suites; it is not
claimed as a completed local pass. The two Storybook jobs are skipped by
the configured draft-PR workflow.
- Greptile reviewed the final commit at 5/5 with no actionable findings
and zero unresolved review threads.
- Browser measurements at 1654px, 860px, and 390px confirm matching 48px
desktop and 76px narrow rows (plus 1px dividers), right-aligned IDs on
the title line, 64px timestamp slots, and no horizontal overflow. Narrow
Recent Tasks rows retain readable agent names below the title. Activity
reads as actor, verb, title, ID, time. Additional reference details can
expand an activity row.
- Verified three equal-width desktop charts with 16px gaps and aligned
outer edges. Chart blues, greens, and reds resolve to the matching
task-icon tokens.
- Verified real queued, running, succeeded, failed, cancelled, and
timed-out runs in the dev dashboard. Checked compact cards, task/run
links, timestamps, light/dark themes, and narrow layout.
- To inspect: open Dashboard, then Live runs. Both pages use the same
small cards. Open an agent header for run output, or the task row for
task details.
- Verified the updated spinner on the real dashboard cards, Recent
tasks, and task list. Checked actual SVG circle radius, rendered size,
and stroke width. Confirmed the spinner, nav dots, and Live labels
resolve to the identical blue-400 color in the dark-mode preview; light
mode uses their shared blue-600 token.
- Verified 12px computed width and height in the task breadcrumb and
Properties pane, the restored 20px main task icon, and 11px task IDs
with baseline alignment in the breadcrumb and shared dashboard/Live runs
cards.
- Verified the chart bar and legend resolve to the spinner color; Recent
Tasks counts align with Dashboard's count. Checked the fading ellipsis
overlay with keyboard focus and its open-menu state, then dismissed the
menu.

## Risks

- Operators must open run details to read output that was previously
embedded.
- Run outcomes are available in the header tooltip and run details
instead of a visible status chip. An in-progress task icon reflects task
status, independently of an individual run's outcome.
- Long names and task titles truncate within the compact layout. Full
labels remain available through links and tooltips.
- Font loading changes affect all UI text that uses the bundled Inter
font. The files remain served from the existing public fonts directory.
- No schema, API, adapter, or execution-policy changes.

## Model Used

OpenAI Codex, GPT-6 Astra (`gpt-6-astra`), with extended reasoning,
repository tools, code execution, and browser verification. The session
does not expose the context-window size.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Scott Tong <scott@scotts-mbp-m5-max.local>
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-09-11 17:02:40 -07:00
DottaandPaperclip f12b647ae8 fix: reliably interrupt and resume legacy message queues (#13275)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - A task can collect more messages while its agent works.
> - Legacy runners must stop the active process before they can receive
those messages.
> - The old Interrupt action cancelled the run but could leave the queue
idle and hidden.
> - Codex could also classify a cancelled run as successful or start a
fresh process after cancellation.
> - This pull request joins cancellation, preserves the provider
session, and dispatches the current queue after cleanup.
> - The benefit is reliable interruption with the saved message order,
edits, and deletions.

## Linked Issues or Issue Description

**What happened?**

Interrupt could strand a legacy message queue. The UI could hide pending
messages after the run stopped. A Codex signal exit could race the
cancellation write. A stale session warning could also trigger a fresh
process after an interrupted resume.

**Expected behavior**

Interrupt stops the active turn and sends the remaining messages once,
in their saved order. Deleted messages stay deleted. An interrupted
Codex turn keeps its session and does not restart itself.

**Steps to reproduce**

1. Assign a task to a legacy Codex agent that runs a long command.
2. Queue three messages. Edit one, discard another, and move the last
message first.
3. Click Interrupt in the queue.
4. Repeat the interruption while the resumed session runs another
command.

Related work: Refs #13160, which moves native queue steering into the
wake-queue module. This change fixes legacy interruption and keeps
native steering unchanged.

## What Changed

- Add a revision-checked, company-scoped endpoint for legacy queue
interruption.
- Promote only the requested queue after the provider stops and releases
its lease. Retry its persisted interrupt intent from the scheduler after
a promotion error or server restart.
- Keep pending legacy queues visible after a run stops. Use server state
for the interrupt result.
- Serialize owned process cancellation before classifying the adapter
result. Preserve late session and log metadata. Acknowledge cancellation
only when an actual process or process group was owned; scheduler
placeholders retain their normal release policy.
- Send Ctrl-C to legacy Codex. Prevent missing-session fallback once the
session has started.
- Add cancellation race, multi-actor queue order, durable retry, resume
fallback, and stale request regression tests. Document the behavior.

## Verification

- Real browser tests passed with legacy Codex CLI and ACP engines, using
Codex 0.153.4 and gpt-5.6-sol.
- All three automated ACP browser scenarios passed locally: immediate
Interrupt delivery, no replay of an unfinished write, and pause
requiring Resume. Updated the old test expectation that required a
separate “go” after Interrupt.
- Browser tests covered queued edits, deletion, reordering, deleting the
final message, and repeated interruption.
- Two consecutive CLI interrupts kept one provider session. Both stopped
processes exited. The final message arrived once.
- `pnpm -r typecheck` passed.
- `pnpm check:token-gates` passed.
- All 346 post-review scheduling, recovery, queue-route,
archived-company, worktree-suppression, and stale-queue regression tests
passed.
- All 318 process-recovery and durable-chat tests passed after the final
cancellation guard.
- Codex adapter, queue UI, issue-page, and OpenAPI contract tests
passed.
- `pnpm build` passed.
- Full local suite coverage completed with
`PAPERCLIP_IN_WORKTREE=false`, using the stable runner and its CI
shards: 618 general server suites, all 145 serialized server suites, and
all workspace groups. Every failing suite passed a targeted rerun after
the fixes, rebuilding the native test fixture, correcting macOS
temporary-path setup, or retrying setup/timing failures. Existing skips
remain.
- The original monolithic run reported failures before the final fixes;
its failed suites were rerun rather than rerunning all 618 suites again.
The final process-recovery/durable-chat regression run passed all 318
tests.
- All CI checks passed for `e30eaf787f23a5511a3cb3cdb5abbccab9ed001d`:
[run 34654820774, attempt
2](https://github.com/paperclipai/paperclip/actions/runs/34654820774/attempts/2),
including typecheck, build, all test shards, E2E, and canary. The
signoff and Cursor sandbox tests each hit a timeout in the initial
attempt; both suites passed locally, and both failed shards passed their
single CI rerun. All three corrected ACP browser scenarios passed in CI.
- Greptile reviewed `e30eaf787f23a5511a3cb3cdb5abbccab9ed001d`: 5/5, no
open review threads.

## Risks

Cancellation order affects local adapters. The tests cover signal exits,
graceful exits, adapter exceptions, termination errors, and cancellation
write errors. Embedded adapters keep their cancellation controls.
Ordinary run cancellation and task pause keep their distinct queue
policies. No database migration is required.

## Model Used

OpenAI Codex, GPT-6, with reasoning, tool use, browser testing, and code
execution. The exact serving model ID and context-window size are not
exposed in this session. The live test runner used OpenAI gpt-5.6-sol.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-09-11 18:26:59 -05:00
DottaandPaperclip 9031516a7e fix: recover legacy Daytona startup failures from task and inbox (#13272)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Legacy conversation adapters can run in Daytona sandboxes.
> - A server restart during provisioning can occur before the invocation
event exists.
> - Recovery then lacks the old adapter identity and leaves a hold that
ordinary user retries cannot clear.
> - A remote launch can also fail when its host relay looks for Node in
the sandbox PATH.
> - This pull request records the adapter at claim time and restores
explicit user continuation after verified cleanup.
> - Users can recover from the task or inbox while the failed run and
uncertain action history remain intact.

## Linked Issues or Issue Description

Refs #13237, #13239, #13254. Those changes cover recorded conversation
runs, native user continuation, and explicit remote Stop. This change
covers legacy failure before `adapter.invoke` and exact task/inbox
Retry.

Refs #9771 for overlapping generated-command quoting. This change also
supplies the absolute host Node executable. Refs #13163 and #13264 for
the separate native restart and retained-workspace work.

**What happened?**
A legacy Daytona run interrupted during provisioning became
`process_lost` without an invocation event. Recovery preserved an
execution hold, and Retry or a new task reply could not resume it.
Cleanup could also run before the Daytona plugin was ready. On a macOS
host, a subsequent ACP relay launch failed with `env: node: No such file
or directory` because the remote launch environment did not contain the
host Node path.

**Expected behavior**
An interrupted conversation can continue after its previous execution
stops. Explicit Retry and new user replies should start a fresh turn
with the task history. Cleanup failures must remain visible and
recoverable. The host relay must use the host Node executable.

**Steps to reproduce**
1. Use a legacy Claude adapter with a Daytona environment.
2. Interrupt the server after it acquires the sandbox lease and before
it records `adapter.invoke`.
3. Restart and inspect the task hold.
4. Retry from the task or inbox, or send a new task reply.
5. Confirm the old sandbox has stopped and one new response arrives.

**Paperclip version or commit**
Reproduced from master at `3bafac12f796fbea02e609e1074a9639f872e9c4`.
The branch is rebased on `51b0e01ea`, including #13261 and #13270.

**Deployment mode**
Built from source on macOS with a real Daytona sandbox and the legacy
Claude ACP adapter.

## What Changed

- Count new browser specs with the scheduler's median duration in the
shard-balance check. This fixes a false policy failure after new specs
arrive from both branches. The balance threshold is unchanged.

- Persist server-owned adapter identity in the queued-to-running claim
before provisioning starts.
- Wait for provider plugin startup before restart cleanup. Keep failed
cleanup leases as active ownership blockers.
- Admit exact board retries and new user comments after verified
termination. Retain the old run, task history, approvals, and unknown
action outcomes.
- Adopt repeated Retry requests. Permit one scoped cleanup attempt per
explicit user Retry after the automatic limit, with an activity record.
A later user Retry can recover after a transient provider failure;
automatic attempts remain capped.
- Resume replies deferred during cleanup, including historical legacy
startup failures.
- Launch the host ACP relay through the absolute host Node executable.
- Add a task-level Retry button and return actionable blockers when
retry admission is refused.
- Add database regressions and three browser recovery journeys. Exclude
installed third-party dependency skills from the shipped-skill audit.

## Verification

- Current head: `d23c84181`, rebased on `51b0e01ea`. Conflict resolution
retains the saved-message recovery, local stop receipts, and wait
reasons from #13270 alongside exact legacy Retry support.
- Real Daytona: interrupted the server after lease acquisition and
before adapter invocation. Restart cleanup confirmed provider
termination. Task Retry cleared a seeded historical hold and a real
Claude agent returned `Recovery verified.` in the task. Removed the
disposable sandbox and environment after testing.
- All three browser recovery journeys passed again after the final
rebase. Task Retry, Inbox Retry, and a new reply each produced one fresh
successor, completed the task, preserved the failed run, and retained
the answer after reload.
- All 29 e2e/server shard-partition tests passed. The balance check now
uses the scheduler's median fallback for unmeasured specs, with the same
balance threshold.
- Server typecheck passed after rebuilding the generated runner
dependencies. The combined recovery/route run passed 136 of 137 tests.
Its remaining route test timed out during the first cold module import
at its explicit 10-second limit; an isolated rerun reproduced that
timeout and passed the other 51 route cases. The complete CI suite
passed on this head. The same route file passed all 52 cases in CI,
including the first cold import in 7.5 seconds.
- Before the final rebase, recursive typecheck, full build, UI token
gates, 132 targeted server tests, and the complete [CI
workflow](https://github.com/paperclipai/paperclip/actions/runs/34650004085)
passed. The subsequent CI failure was the shard-balance accounting
mismatch fixed here.
- Greptile reviewed `d23c84181` at 5/5 with no outstanding actionable
findings. The complete [current CI
workflow](https://github.com/paperclipai/paperclip/actions/runs/34653327949)
passed on attempt 2. All test, typecheck, build, and canary jobs passed
on the first attempt. Docker setup timed out fetching BuildKit from
Docker Hub; retrying that job and its dependent aggregate succeeded.

## Risks

- Recovery admission changes executable authority. Company, task, agent,
user, approvals, process ownership, and provider termination checks
remain required.
- Explicit continuation starts a fresh conversation with history. It
does not certify unknown external action outcomes or rerun
non-conversation adapters automatically.
- Changing task status alone does not clear an execution hold. The task
now offers an explicit Retry action.
- Historical adapter claims and invocation events take precedence over
current agent settings. Known process or webhook runs retain their hold.
Pre-upgrade rows with no adapter evidence may receive only a new
explicit user turn after termination proof; they do not become eligible
for automatic replay.
- No schema migration or sandbox-image change is required. This branch
has not been deployed to production.

## Model Used

OpenAI GPT-6 through Codex, with repository inspection, code execution,
browser automation, and test execution. The exact deployment model ID
and context window are not exposed in this session.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [ ] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-09-11 18:08:14 -05:00
DottaandPaperclip f2e2d38972 feat(ui): summarize completed runner activity groups (#13274)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Task chat shows tool activity between agent updates.
> - Finished groups currently keep the last raw command on screen.
> - Failure totals add visual weight to normal retries.
> - This pull request summarizes finished groups with short action
phrases.
> - Users can expand each group to inspect the original activity and
output.
> - The benefit is a quieter history that still explains the work.

## Linked Issues or Issue Description

**What existing behavior does this improve?**

Runner activity in live task chat and saved history.

**Current behavior**

A finished group shows its last command or tool target. A separate
failure count remains visible after retries.

**Proposed behavior**

Show short phrases such as “Ran commands” or “Read files, ran commands”
when a commentary group finishes. Remove failure counts in both active
and finished groups. Keep original output in expandable history.

**Reason and benefit**

The activity summary describes the work without filling the conversation
with shell arguments or treating each retry as an alarm. Unsuccessful
reads and edits use “Checked files” and “Worked on files” to avoid
claiming success.

**Additional context**

Refs: #13255. This builds on the merged rolling activity groups. Related
open PR #13246 covers steering and status presentation; this change
concerns completed summaries and failure counts. The design was reviewed
in desktop and mobile Storybook previews.

## What Changed

- Add a deterministic summary shared by builtin and provider-native
activity.
- Combine repeated categories and retries, preserve category order, and
bound long summaries.
- Summarize each inactive commentary group while the next group can
still be running.
- Keep expansion, individual output disclosures, and active rolling
rows.
- Use the production component in eight review stories, including
animated desktop and mobile transitions.
- Cover retries, unsuccessful edits, unknown tools, reasoning-only
groups, saved history, and resuming work.

## Verification

- Focused summary, group, and runner-turn tests pass: 62 tests.
- Token gates pass.
- The approved Storybook previews passed browser checks for desktop,
mobile, keyboard expansion, live-to-completed transitions, and original
retry output.
- `pnpm -r typecheck`, `pnpm build`, and the production Storybook build
pass.
- The complete UI suite passes: 582 files and 6,005 tests. The full
repository test run is in progress after repairing missing symlinks in
the local PostgreSQL dependency. A native workspace suite that hit the
setup failure now passes all six tests.
- Greptile is 5/5 on the current commit, with no review threads.
Security checks pass. All individual CI jobs pass except server shard
4/5, where one plugin-worker output timing assertion failed. The
complete plugin-worker suite passes locally (83 tests). The workflow
finished. One retry of the failed shard and aggregate check was
dispatched and is queued. Squash auto-merge is enabled and remains gated
on required checks.
- Rechecked the production stories in the browser: mobile history stays
on one line, and expansion survives completion while the next group
remains active.
- Review in Storybook under Tasks → Completed activity preview. Use Next
to finish one group while the next group remains active. Open a
completed summary to inspect its history.

## Risks

- Summaries classify observed activity; “Ran commands” does not mean
exit code zero.
- Unknown tools use a generic description. Full names and outputs remain
in history.
- No API, database, or runner protocol contracts change.

> Reviewed ROADMAP.md. This is a focused improvement to the existing
task-chat presentation.

## Model Used

OpenAI GPT-6 through Codex, with reasoning, tool use, code execution,
and browser testing. The runtime does not expose a more specific model
version or context-window size.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [ ] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-09-11 22:48:25 +00:00
DottaandPaperclip 51b0e01ead fix: resume saved user messages after execution recovery (#13270)
Preserve verified native process-stop evidence and retry saved user messages through normal continuation admission after recovery cleanup. Show the current wait reason and serialize delivery so a saved message starts one fresh turn.

Validated with 410 focused tests, typecheck, build, token gates, all PR CI checks, and Greptile 5/5.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-09-11 17:12:55 -05:00
DottaandPaperclip 2083bf6f9a feat(connections): add AgentMail inboxes and email tasks (#13256)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Connections give agents controlled access to external services.
> - Experimental channels already map conversations to tasks and durable
work queues.
> - Email needs inbox ownership, recipient envelopes, delivery records,
and explicit sends.
> - This pull request adds AgentMail to that infrastructure and keeps
the provider key in the server vault.
> - Agents can receive and send email from local or sandbox execution
while the board follows each conversation in its task.

## Linked Issues or Issue Description

**Problem or motivation**

Agents need dedicated email addresses. Incoming email should become
assigned work. Internal task comments and progress must never become
outgoing email by accident.

**Proposed solution**

Add experimental AgentMail connections, an inbox assignment wizard,
durable email intake and publication, task email cards, and
authenticated API, CLI, and native runtime actions. Agents use Paperclip
credentials to request sends. Paperclip owns the provider key and
enforces access and task authority.

**Alternatives considered**

A general mailbox MCP connector does not provide durable task binding or
publication boundaries. A separate mailbox application duplicates task
collaboration. The board instead directs the agent through the normal
task conversation.

**Roadmap alignment**

This extends the existing experimental connections and task
infrastructure. Product scope and interaction design were reviewed with
the maintainer. Related connection authority work: #11831 and #11818.
The duplicate search found no competing task-based AgentMail
integration.

## What Changed

- Add AgentMail catalog data, shared contracts, company-scoped email
records, and an additive migration.
- Add vaulted setup, inbox assignment, access grants, trust guidance,
and provider-side allowlist guidance.
- Support WebSocket and signed-webhook intake through a shared durable
pipeline, deduplication, catch-up, and task wakeups.
- Queue explicit new conversations and replies with immutable send
intents, idempotency, delivery state, and uncertain-send resolution.
- Show inbound and outbound email cards in normal task conversations.
Keep internal messages internal.
- Add task-scoped CLI actions and the sandbox callback routes required
for Daytona execution.
- Provide a dedicated AgentMail skill automatically only to agents with
active authorized inbox assignments. Keep email instructions out of the
universal Paperclip skill.
- Advertise connector-owned `agentmail_inboxes`,
`agentmail_read_thread`, `agentmail_send`, and `agentmail_delivery`
tools only in eligible native sessions. Recheck live authority on
execution.
- Isolate Codex CLI connector skills by agent and skill revision.
Deliver the assigned skill in the run prompt for adapters that use
shared skill directories, including resumed turns. Keep automatic skills
out of manual persistent sync. Show them as read-only and document the
pattern in the connector playbook.
- Fix AgentMail health checks that entered local-stdio validation and
optional missing Codex credential cleanup in sandboxes.
- Add API, pipeline, authorization, sandbox, browser, and Storybook
coverage.

## Verification

- Live AgentMail testing covered WebSocket intake, signed webhooks,
restart catch-up, and a full receive → task → Daytona Codex CLI →
explicit reply → Delivered round trip. The reply was verified in the
other inbox. The normal task composer also initiated an outgoing email
child task.
- The connector-skill change was verified in the browser: AgentMail
appears once as an automatic, read-only skill with its assigned address.
Disabling experimental chat connections removes it; re-enabling restores
it. A regression test covers assignment data arriving after library
data.
- Connector regression coverage passed 178 runtime utility, email
integration, skill-route, and heartbeat tests. All 17 Codex execution
tests passed, including per-agent skill isolation, model identity,
revision changes, removal, and prompt delivery without shared skill
files.
- After rebasing onto master, all 44 focused email, heartbeat, and
native-authority tests passed. All 313 native-session executor tests
passed. The UI regression suite passed all 3 tests. These test sets
overlap earlier focused runs.
- Full workspace typecheck and build passed after the rebase. Token
gates passed. Earlier focused Playwright task/setup coverage and the
Storybook build also passed.
- Native connector tool execution uses deterministic integration tests.
Live Daytona qualification used the Codex CLI adapter; the new
shared-home prompt fallback has deterministic coverage.
- The full repository suite is run by CI. The earlier unsharded local
full-suite attempt was stopped after the equivalent CI suites passed and
is not reported as a completed local run. Greptile reviewed
`7e57dc267a8446d3c906e3cc5b8abc94fb8860eb` at 5/5 with no unresolved
threads. All server, workspace, serialized server, and browser suites
passed in CI. The build job hit a five-second timeout in a runner
transport test; both variants and the full 80-test file passed locally
with unchanged timeouts. The build passed on retry on the same commit
without code or timeout changes. All required CI gates, including the
final `ci / verify` and `ci / e2e` summaries, are green on
`7e57dc267a8446d3c906e3cc5b8abc94fb8860eb`.

## Risks

- Email from external senders can start normal agent work. Setup
recommends a low-trust agent and AgentMail sender controls. Sender
addresses never grant board membership.
- Provider timeouts can leave uncertain sends. Retries retain their
idempotency key; expired windows require reconciliation or operator
resolution.
- Connector skills and native tools are assignment-dependent and require
current access. Revocation denies retained calls; assignment changes
select a new runtime context.
- Activation remains behind the experimental-channel setting. The native
runner path has deterministic coverage; live Daytona qualification used
the Codex CLI adapter.
- Schema changes are additive. Inbox ownership is unique across
companies. Disconnect preserves provider inboxes and task history.

## Model Used

OpenAI GPT-6 (Codex). Used reasoning, repository tools, code execution,
and browser testing. The exact deployment model ID and context-window
size were not exposed in this session.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-09-11 16:56:38 -05:00