mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-06 21:05:21 +02:00
98298cb7ff816369efbba976e6cbf64e7c5c3a4c
1511
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
98298cb7ff |
build(deps-dev): bump tsx from 4.23.1 to 4.23.12 (#11722)
Bumps [tsx](https://github.com/privatenumber/tsx) from 4.23.1 to 4.23.12. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/privatenumber/tsx/releases">tsx's releases</a>.</em></p> <blockquote> <h2>v4.23.12</h2> <h2><a href="https://github.com/privatenumber/tsx/compare/v4.23.11...v4.23.12">4.23.12</a> (2026-08-10)</h2> <h3>Bug Fixes</h3> <ul> <li>shim <code>import.meta</code> when tokens are split by comments or newlines (<a href="https://redirect.github.com/privatenumber/tsx/issues/829">#829</a>) (<a href="https://github.com/privatenumber/tsx/commit/ed9d33046a135de13a35fdfce12368b79d1b1518">ed9d330</a>), closes <a href="https://redirect.github.com/privatenumber/tsx/issues/828">#828</a></li> </ul> <hr /> <p>This release is also available on:</p> <ul> <li><a href="https://www.npmjs.com/package/tsx/v/4.23.12"><code>npm package (@latest dist-tag)</code></a></li> </ul> <h2>v4.23.11</h2> <h2><a href="https://github.com/privatenumber/tsx/compare/v4.23.10...v4.23.11">4.23.11</a> (2026-08-07)</h2> <h3>Bug Fixes</h3> <ul> <li>preserve async ESM require fallback (<a href="https://github.com/privatenumber/tsx/commit/55cbecef8ebe839c7110e8c141a1c3bc4da326cd">55cbece</a>)</li> </ul> <hr /> <p>This release is also available on:</p> <ul> <li><a href="https://www.npmjs.com/package/tsx/v/4.23.11"><code>npm package (@latest dist-tag)</code></a></li> </ul> <h2>v4.23.10</h2> <h2><a href="https://github.com/privatenumber/tsx/compare/v4.23.9...v4.23.10">4.23.10</a> (2026-08-07)</h2> <h3>Bug Fixes</h3> <ul> <li>support nyc coverage discovery (<a href="https://redirect.github.com/privatenumber/tsx/issues/710">#710</a>) (<a href="https://github.com/privatenumber/tsx/commit/ec1bcd5f711e5159b67cb0aea211f06cf2cfce8a">ec1bcd5</a>)</li> </ul> <hr /> <p>This release is also available on:</p> <ul> <li><a href="https://www.npmjs.com/package/tsx/v/4.23.10"><code>npm package (@latest dist-tag)</code></a></li> </ul> <h2>v4.23.9</h2> <h2><a href="https://github.com/privatenumber/tsx/compare/v4.23.8...v4.23.9">4.23.9</a> (2026-08-06)</h2> <h3>Bug Fixes</h3> <ul> <li>map Node test locations (<a href="https://github.com/privatenumber/tsx/commit/2f55884195a8c745fbe64a0288de69bc062ed876">2f55884</a>)</li> <li>support data URLs in tsImport (<a href="https://github.com/privatenumber/tsx/commit/b94f46f6b6a7e6dc575624b0ecc7124318723056">b94f46f</a>)</li> </ul> <hr /> <p>This release is also available on:</p> <ul> <li><a href="https://www.npmjs.com/package/tsx/v/4.23.9"><code>npm package (@latest dist-tag)</code></a></li> </ul> <h2>v4.23.8</h2> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/privatenumber/tsx/commit/ed9d33046a135de13a35fdfce12368b79d1b1518"><code>ed9d330</code></a> fix: shim <code>import.meta</code> when tokens are split by comments or newlines (<a href="https://redirect.github.com/privatenumber/tsx/issues/829">#829</a>)</li> <li><a href="https://github.com/privatenumber/tsx/commit/651f5bec70d9a116d1fe1706000b7ca011a516fc"><code>651f5be</code></a> test: cover CommonJS TypeScript import.meta paths</li> <li><a href="https://github.com/privatenumber/tsx/commit/bd3bc6448e957c1172eb91a0584ec7fec2d6a7ad"><code>bd3bc64</code></a> test: cover CommonJS loader source fallback</li> <li><a href="https://github.com/privatenumber/tsx/commit/55cbecef8ebe839c7110e8c141a1c3bc4da326cd"><code>55cbece</code></a> fix: preserve async ESM require fallback</li> <li><a href="https://github.com/privatenumber/tsx/commit/6c5ba85f7a1e57f06bcb760718d6ba3b978e5a05"><code>6c5ba85</code></a> docs: document CommonJS default interop</li> <li><a href="https://github.com/privatenumber/tsx/commit/ec1bcd5f711e5159b67cb0aea211f06cf2cfce8a"><code>ec1bcd5</code></a> fix: support nyc coverage discovery (<a href="https://redirect.github.com/privatenumber/tsx/issues/710">#710</a>)</li> <li><a href="https://github.com/privatenumber/tsx/commit/b6e5b48a7b0fa4639e67119c8b02150ec8c6cef7"><code>b6e5b48</code></a> docs: clarify CommonJS default imports</li> <li><a href="https://github.com/privatenumber/tsx/commit/2f55884195a8c745fbe64a0288de69bc062ed876"><code>2f55884</code></a> fix: map Node test locations</li> <li><a href="https://github.com/privatenumber/tsx/commit/de935d588b6c0959ac8af71e2cf40d1a61e659e7"><code>de935d5</code></a> docs: document Node source-map stack formatting</li> <li><a href="https://github.com/privatenumber/tsx/commit/b94f46f6b6a7e6dc575624b0ecc7124318723056"><code>b94f46f</code></a> fix: support data URLs in tsImport</li> <li>Additional commits viewable in <a href="https://github.com/privatenumber/tsx/compare/v4.23.1...v4.23.12">compare view</a></li> </ul> </details> <br /> [](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) </details> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> |
||
|
|
ec8d7dd21f |
build(deps): bump ws from 8.21.1 to 8.21.3 (#11729)
Bumps [ws](https://github.com/websockets/ws) from 8.21.1 to 8.21.3. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/websockets/ws/releases">ws's releases</a>.</em></p> <blockquote> <h2>8.21.3</h2> <h1>Bug fixes</h1> <ul> <li>The server now correctly rejects permessage-deflate offers if the incoming <code>client_max_window_bits</code> parameter value is smaller than its configured <code>clientMaxWindowBits</code> (e97a20ea).</li> </ul> <h2>8.21.2</h2> <h1>Bug fixes</h1> <ul> <li>Fixed a test for <a href="https://github.com/nodejs/citgm">CITGM</a> (2eb3be0b).</li> </ul> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/websockets/ws/commit/c791e707eab3c13dd9a261d2479c3cc4a49a6fed"><code>c791e70</code></a> [dist] 8.21.3</li> <li><a href="https://github.com/websockets/ws/commit/e97a20eaa6f2ad7969419eed732a506453251eb9"><code>e97a20e</code></a> [fix] Reject offers with <code>client_max_window_bits</code> below config</li> <li><a href="https://github.com/websockets/ws/commit/787ebf22ce3d091fb6f931d20b4c7e914ba7cf85"><code>787ebf2</code></a> [dist] 8.21.2</li> <li><a href="https://github.com/websockets/ws/commit/b4d62ebad40c3b925c84ff305a47975406015422"><code>b4d62eb</code></a> Revert "[ci] Trust Coveralls Homebrew tap"</li> <li><a href="https://github.com/websockets/ws/commit/e4bb883723a0c18452eea10a74139901ae33c61d"><code>e4bb883</code></a> [security] Use GitHub PVR as main reporting channel</li> <li><a href="https://github.com/websockets/ws/commit/2eb3be0bff2453e2654b1315c5872e8d5d424a50"><code>2eb3be0</code></a> [test] Skip test on Node.js versions where it does not apply</li> <li>See full diff in <a href="https://github.com/websockets/ws/compare/8.21.1...8.21.3">compare view</a></li> </ul> </details> <br /> [](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) </details> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> |
||
|
|
e0d46d1375 |
test(workspaces): fix runtime provision metadata assertion (#11707)
## Thinking Path > - Paperclip manages agent work in isolated execution workspaces. > - Workspace operations record operation metadata and command-result metadata separately. > - Runtime provisioning records its provision kind in the operation metadata. > - One merged regression test checked that value in the command-result metadata. > - The production behavior was correct, but the test failed. > - This pull request checks the provision kind in the operation metadata. > - The benefit is that the regression test now matches the recorder contract. ## Linked Issues or Issue Description Related pull request: #11706 **What happened?** The runtime provisioning regression test expected `provisionKind` in `result.metadata`. The recorder stores this value in the operation's top-level `metadata`. The command-result metadata is `null` for this case. **Expected behavior** The test must check `metadata.provisionKind`. It must continue to check `result.status`. **Steps to reproduce** 1. Check out commit `e1df4c6068fea684a1e9714ebd64bce95f3db19a`. 2. Run the focused runtime provisioning test. 3. Observe that the assertion checks the wrong metadata object. **Paperclip version or commit** `e1df4c6068fea684a1e9714ebd64bce95f3db19a` **Deployment mode** Local development. ## What Changed - Move the `provisionKind` assertion from `result.metadata` to the operation's top-level `metadata`. - Keep the `result.status` assertion unchanged. ## Verification - `pnpm --filter @paperclipai/server exec vitest run src/__tests__/workspace-runtime.test.ts -t "keeps an explicit command matching the built-in seed command as runtime provisioning"` - Result: 1 test passed and 125 tests skipped. ## Risks - Low risk. This pull request changes one test assertion and does not change production code. > 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, high-reasoning mode, with repository, shell, Git, GitHub, and code execution tools. The runtime does not expose a context-window value. ## 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> |
||
|
|
e1df4c6068 |
fix(workspaces): keep deferred seed databases reliable (#11706)
## Thinking Path > - Paperclip manages agent work in isolated execution workspaces. > - A workspace depends on a valid database seed before it can run. > - Deferred seed failures were hidden behind a successful provision status. > - The seed restore also had two possible owners for the embedded PostgreSQL process. > - That allowed the target database to stop while the restore was still running. > - This pull request makes seed failures visible and gives the seed process sole lifecycle ownership. > - The benefit is that workspace provisioning reports the real result and does not stop its own target database. ## Linked Issues or Issue Description Related: #11684 **What happened?** Initial worktree provisioning could report success before its deferred database seed completed. The seed restore could also reuse a target embedded PostgreSQL process with another shutdown owner. This could stop the target database during the restore. **Expected behavior** Workspace status must show a failed deferred seed as a failure. The seed restore must own the target embedded PostgreSQL process until restore, migration, and validation finish. **Steps to reproduce** 1. Provision a worktree with deferred database seeding. 2. Make the seed manifest end in a failed state while the command exits with code 0. 3. Observe that the provision status remains successful on `master`. 4. Start a seed restore against an already-running target embedded PostgreSQL process. 5. Observe that another lifecycle owner can stop the target during restore. **Paperclip version or commit** `51a843e135` **Deployment mode** Local dev with execution workspaces and embedded PostgreSQL. ## What Changed - Add a first-class `workspace_seed` operation for deferred database seeds. - Require terminal, verified seed evidence before the seed operation succeeds. - Surface the seed phase and failure metadata in workspace status and UI state. - Give the seed process exclusive lifecycle ownership of the target embedded PostgreSQL process. - Suppress imported embedded-Postgres exit hooks without removing existing host listeners. - Record a credential-safe shutdown diagnostic in failed seed manifests. ## Verification - The original deferred-seed commit passed 4 server tests, 24 workspace-status UI tests, shared/server/UI typechecks, and the UI token gate. - The original PostgreSQL-lifecycle commit passed 3 lifecycle tests, 3 ownership/diagnostic tests, 1 real embedded-Postgres seed integration, and the affected package typechecks. - No local tests were rerun after the clean cherry-pick because the operator requested the shortest landing path. - Review the automatic PR checks for the clean `origin/master` replay. ## Risks - A live target database now causes an early error instead of being reused. The error includes recovery guidance. - Workspace consumers must handle the new `workspace_seed` operation type. Shared types and UI state handling are updated in this pull request. > 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, high-reasoning mode, with repository, shell, and GitHub tool use. The runtime does not expose a more specific deployment suffix or context-window value. ## 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> |
||
|
|
f27c0ee3f9 |
build(deps): bump open from 11.0.0 to 11.0.1 (#11517)
Bumps [open](https://github.com/sindresorhus/open) from 11.0.0 to 11.0.1. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/sindresorhus/open/releases">open's releases</a>.</em></p> <blockquote> <h2>v11.0.1</h2> <ul> <li>Fix WSL failure when the working directory is unreachable from Windows 6ac3fe4</li> </ul> <hr /> <p><a href="https://github.com/sindresorhus/open/compare/v11.0.0...v11.0.1">https://github.com/sindresorhus/open/compare/v11.0.0...v11.0.1</a></p> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/sindresorhus/open/commit/f38acc807a8760968310759a203cf14ca4d54727"><code>f38acc8</code></a> 11.0.1</li> <li><a href="https://github.com/sindresorhus/open/commit/6ac3fe443994a3a2a61ee6785b9169faf96115c3"><code>6ac3fe4</code></a> Fix WSL failure when the working directory is unreachable from Windows</li> <li><a href="https://github.com/sindresorhus/open/commit/a30acc78bef1c1e5448bd88d19180e8ad6899ab9"><code>a30acc7</code></a> Meta tweaks</li> <li>See full diff in <a href="https://github.com/sindresorhus/open/compare/v11.0.0...v11.0.1">compare view</a></li> </ul> </details> <br /> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> |
||
|
|
a2bf936f9a |
feat(workspaces): sign the workspace login handoff and gate readiness (#11671)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Managed worktree services run isolated Paperclip instances with cloned databases. > - A reachable service was reported as ready even when its database, runtime identity, or login path was not usable. > - The first candidate added verified database seeding and managed repair in #11665. > - This pull request consolidates that candidate with signed login handoff and a complete readiness contract. > - Post-QA fixes close five defects in repair identity, repair responses, UI retry, seed journal handling, and seed-source trust. > - The benefit is a workspace that either opens safely or reports one accurate recovery action. ## Linked Issues or Issue Description No public GitHub issue exists for this work, so the problem is described here. **What happened** Managed workspace URLs could return HTTP 200 and report ready while login failed. QA also found cases where repair used the wrong instance identity, returned a generic error, left the UI stuck, rejected a safe journal lag, or trusted a mutable workspace manifest. **Expected behavior** Opening a ready workspace signs the board user in to the correct isolated instance. Provisioning and repair use a registered source and report a structured recovery state. **Actual behavior** Entry depended on a password copied into the clone. Several failure paths could publish stale readiness, hide the repair precondition, or trust state that the workspace could modify. **Additional context** This pull request includes the commits first published in #11665. That pull request keeps the original base head for review history. This consolidated pull request is the merge candidate. Related open readiness work includes #11575 and #11621. ## What Changed - Adds a short-lived, signed, single-use login ticket. It binds the user, workspace, instance, and runtime origin. - Exchanges the ticket through Better Auth. It creates the session and cookie through the supported adapter path. - Adds protected workspace readiness fields for the database, clone data, login handoff, seed phase, and runtime identity. - Fails readiness closed when the guest has no company or execution-workspace binding. - Binds ticket issuance to the exact cloned user and active company membership selected for the handoff. - Verifies every current active board identity through the exact-user handoff before publication or reuse. - Gates managed runtime publication on the readiness contract and the recorded worktree instance identity. - Refreshes runtime work products from the live runtime row after a port change. - Adds one workspace access card with ready, degraded, repairing, and failed states. - Uses the runtime response identity for repair. It returns structured repair precondition errors. - Lets a valid source journal lag converge during provisioning. - Binds seed and repair manifests to a source registered outside the agent-writable worktree. - Clears recovered UI errors so a successful retry can open the workspace. - Makes runtime tests register canonical sources and avoid ports owned by live host listeners. - Keeps Vitest on source suites when compiled `dist` trees exist. - Isolates CLI and adapter tests from ambient AWS and runtime API environment variables. - Preserves a 404 response for cross-company workspace ID lookups before runtime authorization. - Makes concurrent single-flight coverage independent of path-canonicalization scheduling order. ## Verification The following checks passed on the integrated head: ```sh pnpm -r typecheck pnpm build pnpm check:token-gates pnpm --filter @paperclipai/db check:migrations ``` - The server source lane passed 420 files and 4,953 tests. Five tests were skipped. - The CLI lane passed 57 files and 385 tests. - The database lane passed 26 files and 97 tests. - The shared package passed 58 files and 506 tests. - The adapter utility lane passed 640 tests. Four tests were skipped. - The Claude adapter passed 220 tests. One test was skipped. - The Codex adapter passed 323 tests. - The OpenClaw adapter passed 13 tests. - The OpenCode adapter passed 42 tests. - The plugin SDK passed 45 tests. - The workspace runtime suite passed 124 tests. - The caller-scoped readiness and handoff suite passed 52 tests. - The workspace provisioning shell suite passed 7 tests. - The runtime exposure suite passed 17 tests while live host mappings occupied fixed test ports. - `git diff --check` passed and the worktree is clean. The serialized route lane will run in GitHub CI with its normal shards. No deployment or active-workspace migration was performed. ## Risks - This is a medium-risk authentication and runtime-readiness change. - The login ticket uses exact origin, workspace, instance, and user binding. It has a short expiry and a one-time nonce. - Runtime publication is stricter. A real readiness, identity, per-user handoff, or control-plane database disagreement now blocks publication. - This pull request supersedes #11665 as the merge candidate. Close #11665 after this pull request merges. - No new database migration is included. The lockfile and workflow files are unchanged. - Deployment and active-workspace migration are intentionally outside this pull request. > 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 Claude Opus 5 (`claude-opus-5[1m]`), 1M context, extended thinking, tool use, and code execution produced the main candidate. OpenAI GPT-5 (`gpt-5`) through Codex, with agentic reasoning, tool use, and code execution, integrated the post-QA fixes and hardened the test gates. The Codex context-window size was 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 - [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> |
||
|
|
6aaef2998f |
build(deps): bump better-auth from 1.6.25 to 1.6.28 (#11516)
Bumps [better-auth](https://github.com/better-auth/better-auth/tree/HEAD/packages/better-auth) from 1.6.25 to 1.6.28. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/better-auth/better-auth/releases">better-auth's releases</a>.</em></p> <blockquote> <h2>v1.6.28</h2> <h2><code>better-auth</code></h2> <h3>Bug Fixes</h3> <ul> <li>Prevented duplicate session requests during React Suspense retries while preserving revalidation for interrupted refreshes (<a href="https://redirect.github.com/better-auth/better-auth/pull/10769">#10769</a>)</li> <li>Restored client plugin declaration compatibility for downstream TypeScript consumers (<a href="https://redirect.github.com/better-auth/better-auth/pull/10794">#10794</a>)</li> </ul> <p>For detailed changes, see the <a href="https://github.com/better-auth/better-auth/blob/86faaee69b6c2afe237fff8a00602ecc8eccc367/packages/better-auth/CHANGELOG.md"><code>CHANGELOG</code></a>.</p> <h2><code>@better-auth/electron</code></h2> <h3>Bug Fixes</h3> <ul> <li>Restored client plugin declaration compatibility for downstream TypeScript consumers (<a href="https://redirect.github.com/better-auth/better-auth/pull/10794">#10794</a>)</li> </ul> <p>For detailed changes, see the <a href="https://github.com/better-auth/better-auth/blob/86faaee69b6c2afe237fff8a00602ecc8eccc367/packages/electron/CHANGELOG.md"><code>CHANGELOG</code></a>.</p> <h2><code>@better-auth/expo</code></h2> <h3>Bug Fixes</h3> <ul> <li>Restored client plugin declaration compatibility for downstream TypeScript consumers (<a href="https://redirect.github.com/better-auth/better-auth/pull/10794">#10794</a>)</li> </ul> <p>For detailed changes, see the <a href="https://github.com/better-auth/better-auth/blob/86faaee69b6c2afe237fff8a00602ecc8eccc367/packages/expo/CHANGELOG.md"><code>CHANGELOG</code></a>.</p> <h2>Contributors</h2> <p>Thanks to everyone who contributed to this release:</p> <p><a href="https://github.com/bytaesu"><code>@bytaesu</code></a></p> <p><strong>Full changelog:</strong> <a href="https://github.com/better-auth/better-auth/compare/v1.6.27...v1.6.28"><code>v1.6.27...v1.6.28</code></a></p> <h2>v1.6.27</h2> <h2><code>better-auth</code></h2> <h3>Bug Fixes</h3> <ul> <li>Fixed duplicate session requests being made across Suspense retries (<a href="https://redirect.github.com/better-auth/better-auth/pull/10676">#10676</a>)</li> </ul> <p>For detailed changes, see <a href="https://github.com/better-auth/better-auth/blob/be47e9418b4a25a4ecd51ba781d2296373b65a03/packages/better-auth/CHANGELOG.md"><code>CHANGELOG</code></a></p> <h2><code>@better-auth/scim</code></h2> <h3>Bug Fixes</h3> <ul> <li>Fixed auth endpoint types to align with <code>better-call</code> (<a href="https://redirect.github.com/better-auth/better-auth/pull/10657">#10657</a>)</li> </ul> <p>For detailed changes, see <a href="https://github.com/better-auth/better-auth/blob/be47e9418b4a25a4ecd51ba781d2296373b65a03/packages/scim/CHANGELOG.md"><code>CHANGELOG</code></a></p> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/better-auth/better-auth/blob/main/packages/better-auth/CHANGELOG.md">better-auth's changelog</a>.</em></p> <blockquote> <h2>1.6.28</h2> <h3>Patch Changes</h3> <ul> <li> <p><a href="https://redirect.github.com/better-auth/better-auth/pull/10769">#10769</a> <a href="https://github.com/better-auth/better-auth/commit/773de54b18c0e920a3542bdecaf8b42fffc0dc4b"><code>773de54</code></a> Thanks <a href="https://github.com/bytaesu"><code>@bytaesu</code></a>! - Prevent duplicate session requests during transient remounts while ensuring incomplete refreshes are revalidated.</p> </li> <li> <p><a href="https://redirect.github.com/better-auth/better-auth/pull/10794">#10794</a> <a href="https://github.com/better-auth/better-auth/commit/2ad2928f967afa9f9858caecd01466ecb8686982"><code>2ad2928</code></a> Thanks <a href="https://github.com/bytaesu"><code>@bytaesu</code></a>! - Restore client plugin declaration compatibility for downstream TypeScript consumers.</p> </li> <li> <p>Updated dependencies []:</p> <ul> <li><code>@better-auth/core</code><a href="https://github.com/1"><code>@1</code></a>.6.28</li> <li><code>@better-auth/drizzle-adapter</code><a href="https://github.com/1"><code>@1</code></a>.6.28</li> <li><code>@better-auth/kysely-adapter</code><a href="https://github.com/1"><code>@1</code></a>.6.28</li> <li><code>@better-auth/memory-adapter</code><a href="https://github.com/1"><code>@1</code></a>.6.28</li> <li><code>@better-auth/mongo-adapter</code><a href="https://github.com/1"><code>@1</code></a>.6.28</li> <li><code>@better-auth/prisma-adapter</code><a href="https://github.com/1"><code>@1</code></a>.6.28</li> <li><code>@better-auth/telemetry</code><a href="https://github.com/1"><code>@1</code></a>.6.28</li> </ul> </li> </ul> <h2>1.6.27</h2> <h3>Patch Changes</h3> <ul> <li> <p><a href="https://redirect.github.com/better-auth/better-auth/pull/10657">#10657</a> <a href="https://github.com/better-auth/better-auth/commit/2ae491eac3ece50839a0eb2d4f868c4deedac67b"><code>2ae491e</code></a> Thanks <a href="https://github.com/bytaesu"><code>@bytaesu</code></a>! - Aligned endpoint and middleware context types with runtime route parameters, and preserved response headers when resolving sessions from endpoint contexts.</p> </li> <li> <p><a href="https://redirect.github.com/better-auth/better-auth/pull/10676">#10676</a> <a href="https://github.com/better-auth/better-auth/commit/90b509344794b8064700371cbc04b985d0519839"><code>90b5093</code></a> Thanks <a href="https://github.com/bytaesu"><code>@bytaesu</code></a>! - Deduplicate in-flight session requests when React retries a suspended component.</p> </li> <li> <p>Updated dependencies [<a href="https://github.com/better-auth/better-auth/commit/2ae491eac3ece50839a0eb2d4f868c4deedac67b"><code>2ae491e</code></a>]:</p> <ul> <li><code>@better-auth/core</code><a href="https://github.com/1"><code>@1</code></a>.6.27</li> <li><code>@better-auth/drizzle-adapter</code><a href="https://github.com/1"><code>@1</code></a>.6.27</li> <li><code>@better-auth/kysely-adapter</code><a href="https://github.com/1"><code>@1</code></a>.6.27</li> <li><code>@better-auth/memory-adapter</code><a href="https://github.com/1"><code>@1</code></a>.6.27</li> <li><code>@better-auth/mongo-adapter</code><a href="https://github.com/1"><code>@1</code></a>.6.27</li> <li><code>@better-auth/prisma-adapter</code><a href="https://github.com/1"><code>@1</code></a>.6.27</li> <li><code>@better-auth/telemetry</code><a href="https://github.com/1"><code>@1</code></a>.6.27</li> </ul> </li> </ul> <h2>1.6.26</h2> <h3>Patch Changes</h3> <ul> <li> <p><a href="https://redirect.github.com/better-auth/better-auth/pull/10619">#10619</a> <a href="https://github.com/better-auth/better-auth/commit/9ede8059b56e1415c1e8cfdd93ff72691b848bbf"><code>9ede805</code></a> Thanks <a href="https://github.com/jeroenvandermerwe"><code>@jeroenvandermerwe</code></a>! - Ensure database rate-limit cleanup completes when no background task handler is configured.</p> </li> <li> <p><a href="https://redirect.github.com/better-auth/better-auth/pull/10608">#10608</a> <a href="https://github.com/better-auth/better-auth/commit/5a811f1b4314b8bcf6f21c0b72de5cb67d552d97"><code>5a811f1</code></a> Thanks <a href="https://github.com/bytaesu"><code>@bytaesu</code></a>! - Pass the email verification type to custom OTP generators after email sign-up.</p> </li> <li> <p><a href="https://redirect.github.com/better-auth/better-auth/pull/10605">#10605</a> <a href="https://github.com/better-auth/better-auth/commit/d8327f1fea92243b6fea1b0ab183e2a989792c0c"><code>d8327f1</code></a> Thanks <a href="https://github.com/XXMOHAMED012"><code>@XXMOHAMED012</code></a>! - The email OTP verification check no longer reveals whether an email is registered before the OTP itself is verified.</p> </li> <li> <p><a href="https://redirect.github.com/better-auth/better-auth/pull/10513">#10513</a> <a href="https://github.com/better-auth/better-auth/commit/e2c73fbec87f5e19f6a2b5ac371bc5bba9bd49ff"><code>e2c73fb</code></a> Thanks <a href="https://github.com/mrosberghaus"><code>@mrosberghaus</code></a>! - Fix <code>jwtClient()</code> collapsing <code>createAuthClient</code> type inference when combined with other client plugins such as <code>inferAdditionalFields</code>. Additional user fields (for example on <code>updateUser</code>) are preserved again.</p> </li> <li> <p><a href="https://redirect.github.com/better-auth/better-auth/pull/10635">#10635</a> <a href="https://github.com/better-auth/better-auth/commit/af50c45553a62cfb6cdcdede86828731ca00c22c"><code>af50c45</code></a> Thanks <a href="https://github.com/krish-vachhani"><code>@krish-vachhani</code></a>! - Fix <code>oneTapClient()</code> collapsing <code>createAuthClient</code> type inference when combined with other client plugins. The <code>oneTap</code> action is available on the client again.</p> </li> <li> <p><a href="https://redirect.github.com/better-auth/better-auth/pull/10633">#10633</a> <a href="https://github.com/better-auth/better-auth/commit/701cd43babac52784d855291a6adc0cf3fba7970"><code>701cd43</code></a> Thanks <a href="https://github.com/gustavovalverde"><code>@gustavovalverde</code></a>! - Minting or reading a JWKS signing key inside an active database transaction now uses the transaction-scoped adapter instead of the root connection. On a single-connection SQLite database with native transactions enabled, this no longer deadlocks, and on Postgres and MySQL the key commits with the surrounding transaction instead of independently of it.</p> </li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/better-auth/better-auth/commit/86faaee69b6c2afe237fff8a00602ecc8eccc367"><code>86faaee</code></a> chore: release v1.6.28 (<a href="https://github.com/better-auth/better-auth/tree/HEAD/packages/better-auth/issues/10796">#10796</a>)</li> <li><a href="https://github.com/better-auth/better-auth/commit/773de54b18c0e920a3542bdecaf8b42fffc0dc4b"><code>773de54</code></a> fix(client): deduplicate settled session requests during Suspense retries (<a href="https://github.com/better-auth/better-auth/tree/HEAD/packages/better-auth/issues/1">#1</a>...</li> <li><a href="https://github.com/better-auth/better-auth/commit/c92a1ca27bb3f430811f007e6b7769ac31c9749a"><code>c92a1ca</code></a> chore: upgrade <code>next</code> to 16.3 (<a href="https://github.com/better-auth/better-auth/tree/HEAD/packages/better-auth/issues/10787">#10787</a>)</li> <li><a href="https://github.com/better-auth/better-auth/commit/be47e9418b4a25a4ecd51ba781d2296373b65a03"><code>be47e94</code></a> chore: release v1.6.27 (<a href="https://github.com/better-auth/better-auth/tree/HEAD/packages/better-auth/issues/10686">#10686</a>)</li> <li><a href="https://github.com/better-auth/better-auth/commit/2ae491eac3ece50839a0eb2d4f868c4deedac67b"><code>2ae491e</code></a> fix(types): align auth endpoints with <code>better-call</code> (<a href="https://github.com/better-auth/better-auth/tree/HEAD/packages/better-auth/issues/10657">#10657</a>)</li> <li><a href="https://github.com/better-auth/better-auth/commit/90b509344794b8064700371cbc04b985d0519839"><code>90b5093</code></a> fix(client): deduplicate session requests across suspense retries (<a href="https://github.com/better-auth/better-auth/tree/HEAD/packages/better-auth/issues/10676">#10676</a>)</li> <li><a href="https://github.com/better-auth/better-auth/commit/a16b30e8437927c08350194000178073b06af8cf"><code>a16b30e</code></a> chore: release v1.6.26 (<a href="https://github.com/better-auth/better-auth/tree/HEAD/packages/better-auth/issues/10521">#10521</a>)</li> <li><a href="https://github.com/better-auth/better-auth/commit/9ede8059b56e1415c1e8cfdd93ff72691b848bbf"><code>9ede805</code></a> fix(rate-limit): await database cleanup by default (<a href="https://github.com/better-auth/better-auth/tree/HEAD/packages/better-auth/issues/10619">#10619</a>)</li> <li><a href="https://github.com/better-auth/better-auth/commit/af50c45553a62cfb6cdcdede86828731ca00c22c"><code>af50c45</code></a> fix(one-tap): preserve client plugin inference with oneTapClient (<a href="https://github.com/better-auth/better-auth/tree/HEAD/packages/better-auth/issues/10635">#10635</a>)</li> <li><a href="https://github.com/better-auth/better-auth/commit/222facff556e6c570bbd6b7fd5923757b5a55711"><code>222facf</code></a> fix(jwt): resolve the transaction-scoped adapter when signing (<a href="https://github.com/better-auth/better-auth/tree/HEAD/packages/better-auth/issues/10623">#10623</a>)</li> <li>Additional commits viewable in <a href="https://github.com/better-auth/better-auth/commits/v1.6.28/packages/better-auth">compare view</a></li> </ul> </details> <br /> [](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) </details> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> |
||
|
|
3dd2d21e4d |
build(deps-dev): bump @storybook/react-vite from 10.5.0 to 10.5.8 (#11514)
Bumps [@storybook/react-vite](https://github.com/storybookjs/storybook/tree/HEAD/code/frameworks/react-vite) from 10.5.0 to 10.5.8. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/storybookjs/storybook/releases">@storybook/react-vite's releases</a>.</em></p> <blockquote> <h2>v10.5.8</h2> <h2>10.5.8</h2> <ul> <li>React: Fix RDT tsconfig selection for Vite project references - <a href="https://redirect.github.com/storybookjs/storybook/pull/35743">#35743</a>, thanks <a href="https://github.com/ndelangen"><code>@ndelangen</code></a>!</li> <li>Tanstack React: Remove <code>@cloudflare/vite-plugin</code> from the inherited Vite config - <a href="https://redirect.github.com/storybookjs/storybook/pull/35706">#35706</a>, thanks <a href="https://github.com/FrancoKaddour"><code>@FrancoKaddour</code></a>!</li> <li>Tanstack: Wait for router to load before rendering - <a href="https://redirect.github.com/storybookjs/storybook/pull/35784">#35784</a>, thanks <a href="https://github.com/huang-julien"><code>@huang-julien</code></a>!</li> <li>Test: Fix Illegal invocation when reading prototype.focus - <a href="https://redirect.github.com/storybookjs/storybook/pull/35528">#35528</a>, thanks <a href="https://github.com/FrancoKaddour"><code>@FrancoKaddour</code></a>!</li> </ul> <h2>v10.5.7</h2> <h2>10.5.7</h2> <ul> <li>Angular: Serve ancestor node_modules for addon-vitest in browser mode - <a href="https://redirect.github.com/storybookjs/storybook/pull/35600">#35600</a>, thanks <a href="https://github.com/brandonroberts"><code>@brandonroberts</code></a>!</li> <li>Refactor: Update getVersionedPackages method to handle non-Storybook packages correctly - <a href="https://redirect.github.com/storybookjs/storybook/pull/35769">#35769</a>, thanks <a href="https://github.com/valentinpalkovic"><code>@valentinpalkovic</code></a>!</li> </ul> <h2>v10.5.6</h2> <h2>10.5.6</h2> <ul> <li>Dependencies: Pin `@testing-library/jest-dom` to `6.9.1` - <a href="https://redirect.github.com/storybookjs/storybook/pull/35614">#35614</a>, thanks <a href="https://github.com/ndelangen"><code>@ndelangen</code></a>!</li> <li>ESLint Plugin: Add plugin meta and document oxlint usage - <a href="https://redirect.github.com/storybookjs/storybook/pull/35655">#35655</a>, thanks <a href="https://github.com/yannbf"><code>@yannbf</code></a>!</li> <li>Vue: Skip docgen for module ids carrying a query - <a href="https://redirect.github.com/storybookjs/storybook/pull/35598">#35598</a>, thanks <a href="https://github.com/seanogdev"><code>@seanogdev</code></a>!</li> </ul> <h2>v10.5.5</h2> <h2>10.5.5</h2> <ul> <li>CLI: Update AI setup instructions to msw-storybook-addon v3 - <a href="https://redirect.github.com/storybookjs/storybook/pull/35512">#35512</a>, thanks <a href="https://github.com/yannbf"><code>@yannbf</code></a>!</li> <li>Core: Upgrade `ws` to fix security advisories - <a href="https://redirect.github.com/storybookjs/storybook/pull/35584">#35584</a>, thanks <a href="https://github.com/ndelangen"><code>@ndelangen</code></a>!</li> <li>ReactNative: Telemetry framework detection fix - <a href="https://redirect.github.com/storybookjs/storybook/pull/35560">#35560</a>, thanks <a href="https://github.com/ndelangen"><code>@ndelangen</code></a>!</li> <li>SyntaxHighlighter: Fix PrismJS dark mode mismatch - <a href="https://redirect.github.com/storybookjs/storybook/pull/35541">#35541</a>, thanks <a href="https://github.com/hxy-asdw"><code>@hxy-asdw</code></a>!</li> <li>TanStack: Preserve explicit route ids on pathful clones - <a href="https://redirect.github.com/storybookjs/storybook/pull/35499">#35499</a>, thanks <a href="https://github.com/unpunnyfuns"><code>@unpunnyfuns</code></a>!</li> <li>TanStack: Resolve mock redirects through Vite's resolver - <a href="https://redirect.github.com/storybookjs/storybook/pull/35501">#35501</a>, thanks <a href="https://github.com/unpunnyfuns"><code>@unpunnyfuns</code></a>!</li> <li>TanStack: Respect routeOverrides component overrides in stories - <a href="https://redirect.github.com/storybookjs/storybook/pull/35497">#35497</a>, thanks <a href="https://github.com/unpunnyfuns"><code>@unpunnyfuns</code></a>!</li> </ul> <h2>v10.5.4</h2> <h2>10.5.4</h2> <ul> <li>ReactNative: Telemetry framework detection fix - <a href="https://redirect.github.com/storybookjs/storybook/pull/35560">#35560</a>, thanks <a href="https://github.com/ndelangen"><code>@ndelangen</code></a>!</li> <li>SyntaxHighlighter: Fix PrismJS dark mode mismatch - <a href="https://redirect.github.com/storybookjs/storybook/pull/35541">#35541</a>, thanks <a href="https://github.com/hxy-asdw"><code>@hxy-asdw</code></a>!</li> </ul> <h2>v10.5.3</h2> <h2>10.5.3</h2> <ul> <li>Dependencies: Upgrade TypeScript to 6.0.3 - <a href="https://redirect.github.com/storybookjs/storybook/pull/34971">#34971</a>, thanks <a href="https://github.com/valentinpalkovic"><code>@valentinpalkovic</code></a>!</li> </ul> <h2>v10.5.2</h2> <h2>10.5.2</h2> <ul> <li>Angular-Vite: Drop <code>@angular/platform-browser-dynamic</code> peer dependency - <a href="https://redirect.github.com/storybookjs/storybook/pull/35457">#35457</a>, thanks <a href="https://github.com/valentinpalkovic"><code>@valentinpalkovic</code></a>!</li> <li>Angular-Vite: Widen TypeScript peer dependency range to support TypeScript 6 - <a href="https://redirect.github.com/storybookjs/storybook/pull/35455">#35455</a>, thanks <a href="https://github.com/valentinpalkovic"><code>@valentinpalkovic</code></a>!</li> <li>Core: Include chromatic packages in ecosystem identifier - <a href="https://redirect.github.com/storybookjs/storybook/pull/35170">#35170</a>, thanks <a href="https://github.com/yannbf"><code>@yannbf</code></a>!</li> <li>TanStack: Fix createServerFn validator mock - <a href="https://redirect.github.com/storybookjs/storybook/pull/35185">#35185</a>, thanks <a href="https://github.com/sjh9714"><code>@sjh9714</code></a>!</li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md">@storybook/react-vite's changelog</a>.</em></p> <blockquote> <h2>10.5.8</h2> <ul> <li>React: Fix RDT tsconfig selection for Vite project references - <a href="https://redirect.github.com/storybookjs/storybook/pull/35743">#35743</a>, thanks <a href="https://github.com/ndelangen"><code>@ndelangen</code></a>!</li> <li>Tanstack React: Remove <code>@cloudflare/vite-plugin</code> from the inherited Vite config - <a href="https://redirect.github.com/storybookjs/storybook/pull/35706">#35706</a>, thanks <a href="https://github.com/FrancoKaddour"><code>@FrancoKaddour</code></a>!</li> <li>Tanstack: Wait for router to load before rendering - <a href="https://redirect.github.com/storybookjs/storybook/pull/35784">#35784</a>, thanks <a href="https://github.com/huang-julien"><code>@huang-julien</code></a>!</li> <li>Test: Fix Illegal invocation when reading prototype.focus - <a href="https://redirect.github.com/storybookjs/storybook/pull/35528">#35528</a>, thanks <a href="https://github.com/FrancoKaddour"><code>@FrancoKaddour</code></a>!</li> </ul> <h2>10.5.7</h2> <ul> <li>Angular: Serve ancestor node_modules for addon-vitest in browser mode - <a href="https://redirect.github.com/storybookjs/storybook/pull/35600">#35600</a>, thanks <a href="https://github.com/brandonroberts"><code>@brandonroberts</code></a>!</li> <li>Refactor: Update getVersionedPackages method to handle non-Storybook packages correctly - <a href="https://redirect.github.com/storybookjs/storybook/pull/35769">#35769</a>, thanks <a href="https://github.com/valentinpalkovic"><code>@valentinpalkovic</code></a>!</li> </ul> <h2>10.5.6</h2> <ul> <li>Dependencies: Pin <code>@testing-library/jest-dom</code> to <code>6.9.1</code> - <a href="https://redirect.github.com/storybookjs/storybook/pull/35614">#35614</a>, thanks <a href="https://github.com/ndelangen"><code>@ndelangen</code></a>!</li> <li>ESLint Plugin: Add plugin meta and document oxlint usage - <a href="https://redirect.github.com/storybookjs/storybook/pull/35655">#35655</a>, thanks <a href="https://github.com/yannbf"><code>@yannbf</code></a>!</li> <li>Vue: Skip docgen for module ids carrying a query - <a href="https://redirect.github.com/storybookjs/storybook/pull/35598">#35598</a>, thanks <a href="https://github.com/seanogdev"><code>@seanogdev</code></a>!</li> </ul> <h2>10.5.5</h2> <ul> <li>CLI: Update AI setup instructions to msw-storybook-addon v3 - <a href="https://redirect.github.com/storybookjs/storybook/pull/35512">#35512</a>, thanks <a href="https://github.com/yannbf"><code>@yannbf</code></a>!</li> <li>Core: Upgrade <code>ws</code> to fix security advisories - <a href="https://redirect.github.com/storybookjs/storybook/pull/35584">#35584</a>, thanks <a href="https://github.com/ndelangen"><code>@ndelangen</code></a>!</li> <li>ReactNative: Telemetry framework detection fix - <a href="https://redirect.github.com/storybookjs/storybook/pull/35560">#35560</a>, thanks <a href="https://github.com/ndelangen"><code>@ndelangen</code></a>!</li> <li>SyntaxHighlighter: Fix PrismJS dark mode mismatch - <a href="https://redirect.github.com/storybookjs/storybook/pull/35541">#35541</a>, thanks <a href="https://github.com/hxy-asdw"><code>@hxy-asdw</code></a>!</li> <li>TanStack: Preserve explicit route ids on pathful clones - <a href="https://redirect.github.com/storybookjs/storybook/pull/35499">#35499</a>, thanks <a href="https://github.com/unpunnyfuns"><code>@unpunnyfuns</code></a>!</li> <li>TanStack: Resolve mock redirects through Vite's resolver - <a href="https://redirect.github.com/storybookjs/storybook/pull/35501">#35501</a>, thanks <a href="https://github.com/unpunnyfuns"><code>@unpunnyfuns</code></a>!</li> <li>TanStack: Respect routeOverrides component overrides in stories - <a href="https://redirect.github.com/storybookjs/storybook/pull/35497">#35497</a>, thanks <a href="https://github.com/unpunnyfuns"><code>@unpunnyfuns</code></a>!</li> </ul> <h2>10.5.4</h2> <ul> <li>ReactNative: Telemetry framework detection fix - <a href="https://redirect.github.com/storybookjs/storybook/pull/35560">#35560</a>, thanks <a href="https://github.com/ndelangen"><code>@ndelangen</code></a>!</li> <li>SyntaxHighlighter: Fix PrismJS dark mode mismatch - <a href="https://redirect.github.com/storybookjs/storybook/pull/35541">#35541</a>, thanks <a href="https://github.com/hxy-asdw"><code>@hxy-asdw</code></a>!</li> </ul> <h2>10.5.3</h2> <ul> <li>Dependencies: Upgrade TypeScript to 6.0.3 - <a href="https://redirect.github.com/storybookjs/storybook/pull/34971">#34971</a>, thanks <a href="https://github.com/valentinpalkovic"><code>@valentinpalkovic</code></a>!</li> </ul> <h2>10.5.2</h2> <ul> <li>TanStack: Fix createServerFn validator mock - <a href="https://redirect.github.com/storybookjs/storybook/pull/35185">#35185</a>, thanks <a href="https://github.com/sjh9714"><code>@sjh9714</code></a>!</li> <li>TanStack: Support pathless layout routes (id-only) in story routing - <a href="https://redirect.github.com/storybookjs/storybook/pull/35465">#35465</a>, thanks <a href="https://github.com/unpunnyfuns"><code>@unpunnyfuns</code></a>!</li> <li>Tanstack-react: Add missing Hydrate export - <a href="https://redirect.github.com/storybookjs/storybook/pull/35111">#35111</a>, thanks <a href="https://github.com/arun-357"><code>@arun-357</code></a>!</li> <li>Tanstack-react: Keep JSX-only component references during dead-code elimination - <a href="https://redirect.github.com/storybookjs/storybook/pull/35206">#35206</a>, thanks <a href="https://github.com/yatishgoel"><code>@yatishgoel</code></a>!</li> <li>Vitest: Fix coverage toggle crash on Vite 6 by clearing closed Vitest instance on restart - <a href="https://redirect.github.com/storybookjs/storybook/pull/35461">#35461</a>, thanks <a href="https://github.com/yannbf"><code>@yannbf</code></a>!</li> </ul> <h2>10.5.1</h2> <ul> <li>Angular-Vite: Drop <code>@angular/platform-browser-dynamic</code> peer dependency - <a href="https://redirect.github.com/storybookjs/storybook/pull/35457">#35457</a>, thanks <a href="https://github.com/valentinpalkovic"><code>@valentinpalkovic</code></a>!</li> <li>Angular-Vite: Widen TypeScript peer dependency range to support TypeScript 6 - <a href="https://redirect.github.com/storybookjs/storybook/pull/35455">#35455</a>, thanks <a href="https://github.com/valentinpalkovic"><code>@valentinpalkovic</code></a>!</li> <li>Core: Include chromatic packages in ecosystem identifier - <a href="https://redirect.github.com/storybookjs/storybook/pull/35170">#35170</a>, thanks <a href="https://github.com/yannbf"><code>@yannbf</code></a>!</li> </ul> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/storybookjs/storybook/commit/6ef7d1ae816ebd5fb8bf84b8dec7d4a92410d73c"><code>6ef7d1a</code></a> Bump version from "10.5.7" to "10.5.8" [skip ci]</li> <li><a href="https://github.com/storybookjs/storybook/commit/647e982151f1bb4e15163b0d2a31c5a1022efda3"><code>647e982</code></a> Merge pull request <a href="https://github.com/storybookjs/storybook/tree/HEAD/code/frameworks/react-vite/issues/35743">#35743</a> from storybookjs/norbert/revive-34415-file-aware-ts...</li> <li><a href="https://github.com/storybookjs/storybook/commit/7c6fb3a5ecf4495d73de6d70f802251934e079bd"><code>7c6fb3a</code></a> Bump version from "10.5.6" to "10.5.7" [skip ci]</li> <li><a href="https://github.com/storybookjs/storybook/commit/43f2316559b30948d9ef724e5cb3140ddeca8867"><code>43f2316</code></a> Merge pull request <a href="https://github.com/storybookjs/storybook/tree/HEAD/code/frameworks/react-vite/issues/35490">#35490</a> from storybookjs/valentin/remove-tsconfig-baseurl</li> <li><a href="https://github.com/storybookjs/storybook/commit/3126f0a14a351e971679f61cd0bd5609d086ed57"><code>3126f0a</code></a> Bump version from "10.5.5" to "10.5.6" [skip ci]</li> <li><a href="https://github.com/storybookjs/storybook/commit/05a52b7a888c6b85c3f8aa6765ed9a0a69a79e4c"><code>05a52b7</code></a> Bump version from "10.5.4" to "10.5.5" [skip ci]</li> <li><a href="https://github.com/storybookjs/storybook/commit/3327dc44697304275e28ceaa2cd34d9bede4e333"><code>3327dc4</code></a> Bump version from "10.5.3" to "10.5.4" [skip ci]</li> <li><a href="https://github.com/storybookjs/storybook/commit/9ac273930a49ad33b6a331f1f36dc472f5c36054"><code>9ac2739</code></a> Bump version from "10.5.2" to "10.5.3" [skip ci]</li> <li><a href="https://github.com/storybookjs/storybook/commit/b4b00f27662caf7328330b5ab47e9b903218f43a"><code>b4b00f2</code></a> Merge pull request <a href="https://github.com/storybookjs/storybook/tree/HEAD/code/frameworks/react-vite/issues/34971">#34971</a> from storybookjs/valentin/upgrade-typescript-6</li> <li><a href="https://github.com/storybookjs/storybook/commit/518f711cb367d8df184be22f1fab9a218b2743df"><code>518f711</code></a> Bump version from "10.5.1" to "10.5.2" [skip ci]</li> <li>Additional commits viewable in <a href="https://github.com/storybookjs/storybook/commits/v10.5.8/code/frameworks/react-vite">compare view</a></li> </ul> </details> <br /> --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Priya Raman <priya@paperclip.ing> Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
1b4de0b65c |
fix(workspaces): recover degraded runtime databases (#11651)
## Thinking Path
> - Paperclip is the open source app people use to manage AI agents for
work
> - Managed workspaces run local web services and embedded PostgreSQL
databases
> - A listening process could return an unhealthy response and still be
reused
> - Embedded PostgreSQL failures had no bounded restart owner
> - Cleanup inferred ownership from a branch slug instead of exact
persisted instance data
> - This pull request validates runtime health, supervises database
recovery, and uses exact cleanup ownership
> - The benefit is reliable replacement of degraded services without
deleting active instances
## Linked Issues or Issue Description
**What happened?**
Workspace reconciliation could reuse a degraded Paperclip process after
any successful HTTP response. Embedded PostgreSQL could stop without
bounded recovery. Cleanup could infer database ownership from a branch
slug and select the wrong instance.
**Expected behavior**
Paperclip must require a semantic healthy response from the assigned
loopback listener. It must replace degraded processes. It must supervise
embedded PostgreSQL with bounded restarts. Cleanup must use exact
persisted worktree and instance-root ownership.
**Steps to reproduce**
1. Start a managed workspace runtime.
2. Make its health endpoint return HTTP 200 with an unhealthy status, or
stop its embedded PostgreSQL process.
3. Reconcile the workspace or run instance cleanup.
4. Observe that the old implementation can reuse the degraded runtime or
infer ownership from its branch slug.
**Paperclip version or commit**
Current `master` before this pull request.
**Deployment mode**
Local dev with managed workspace services.
## What Changed
- Require `{ "status": "ok" }` from the assigned loopback health
endpoint before runtime reuse or adoption.
- Refresh persisted runtime health and replace degraded managed
processes.
- Add bounded embedded PostgreSQL restart supervision with coordinated
shutdown and hot-restart support.
- Stop the unhealthy web process when PostgreSQL recovery is exhausted
so reconciliation can replace it.
- Require exact persisted instance-root ownership before cleanup can
reclaim an embedded database.
- Add focused regression tests for degraded HTTP responses, ownership
mismatches, bounded recovery, active instance preservation, and
confirmed orphan reclamation.
## Verification
- `pnpm --filter @paperclipai/server typecheck`
- `pnpm --filter @paperclipai/server test --
src/embedded-postgres-supervisor.test.ts
src/services/workspace-instance-cleanup.test.ts
src/services/workspace-runtime.test.ts
src/services/execution-workspaces-service.test.ts`
- `pnpm -r typecheck`
- `pnpm build`
- `git diff --check`
- The full local stable test runner also found host-owned listeners on
ports 42000 and 52000. Those listeners conflict with the exposure test
fixture. The focused changed suites pass, and CI runs on a clean host.
## Risks
- A custom process that returns HTTP 2xx without the Paperclip health
contract is now degraded by design.
- Restart exhaustion terminates the managed web process. The runtime
reconciler then starts a clean process.
- Cleanup now fails closed when persisted ownership is missing. This can
retain an ambiguous orphan for manual review.
> 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 GPT-5 Codex. The exact serving revision and context-window size
are not exposed. The model used agentic reasoning, repository tools,
code execution, 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)
- [ ] 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>
|
||
|
|
120ae5428f |
feat(server): add a one-click relink action for detached custom-image templates (#11641)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Paperclip environments can use captured custom images for agent runs > - A configuration fingerprint change can detach a valid custom-image template > - Operators need a safe way to confirm that the image still matches the boot source > - This pull request adds a guarded relink action with drift classification and audit logging > - The benefit is a deliberate relink without a new sandbox boot or provider snapshot ## Linked Issues or Issue Description **Subsystem affected** Cross-cutting environment, server, and UI behavior. **Problem or motivation** A custom-image template detaches when the environment configuration fingerprint changes. The runtime then uses the base image, even when the boot source did not change. The only prior remedy required a full re-capture. **Proposed solution** Add an operator-triggered relink action. Classify configuration drift from a server-owned boot-relevant snapshot. Relink knob-only drift without confirmation. Require explicit confirmation for boot-source or unclassified drift. Guard the route for instance administrators and record a safe activity event. **Alternatives considered** Keep requiring a full re-capture. This adds a sandbox boot and provider snapshot for cases where the image remains correct. **Roadmap alignment** The roadmap has no matching custom-image relink item. This change addresses an environment operation gap. **Additional context** The relink response exposes raw drift values only in the transient 409 response to the instance administrator. The service never persists or logs fingerprints or configuration values. Reserved identity-path segments fail closed. ## What Changed - Add `relinkActiveTemplate` with drift classification and conditional fingerprint update. - Persist a server-owned boot-relevant configuration snapshot during capture. - Add the guarded relink route with strict request validation and activity logging. - Add the relink action and confirmation flow to the environment page. - Add service, route, UI, and OpenAPI coverage. ## Verification - Run the focused service suite: `pnpm vitest run server/src/services/environment-custom-images-service.test.ts`. - Run the focused route suite: `pnpm vitest run server/src/routes/environment-custom-image-routes.test.ts`. - Run the focused UI suite: `pnpm vitest run ui/src/pages/CompanyEnvironments.test.tsx`. - Run server and UI TypeScript checks. - Confirm the OpenAPI snapshot matches the new route. - Confirm all required GitHub checks pass on commit `e46fdcfe94a719be854adf8849d30714e5b70b93`. - Confirm Greptile reports 5/5 with no unresolved review threads. ## Risks The relink action can keep an image after configuration drift. The service requires explicit confirmation for boot-source or unclassified drift. Reserved path segments produce a safe unresolved marker and never enter stored values. ## Model Used OpenAI GPT-5 Codex. The model used repository inspection, GitHub operations, and PR preparation with tool use and code execution. The runtime did not expose a context-window value or a separate reasoning-mode value. ## 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> |
||
|
|
fe803bedf1 |
feat(server): add a configurable cooldown to the terminal workspace reaper (#11642)
## Thinking Path > - Paperclip is an open source app that manages AI agents for work. > - The server manages execution workspaces and their worktrees. > - The terminal workspace reaper removes a workspace when its issue tree reaches a terminal state. > - Immediate removal prevents a person from reopening recently completed work. > - This pull request adds a configurable cooldown before the reaper archives the workspace. > - The cooldown keeps recent work available and keeps immediate cleanup available with value `0`. ## Linked Issues or Issue Description Refs: #7790 **Problem** The reaper archives an execution workspace and deletes its worktree as soon as the issue tree becomes terminal. A person cannot reopen recent work without extra effort. **Expected behavior** The reaper should keep a recently completed workspace during a configurable cooldown window. It should archive older work and support immediate cleanup when the value is `0`. **Proposed solution** Read the cooldown from `PAPERCLIP_WORKSPACE_REAPER_COOLDOWN_DAYS`. Use a seven-day default. Use the latest terminal timestamp in the source issue tree as the cooldown anchor. ## What Changed - Add `PAPERCLIP_WORKSPACE_REAPER_COOLDOWN_DAYS` with a seven-day default. - Treat `0` as no cooldown and use the default for negative or non-numeric values. - Use the latest `completedAt` or `cancelledAt` value in the source issue tree. - Use `updatedAt` when a terminal timestamp is null. - Skip candidates inside the cooldown and report them in `skippedCooldown`. - Recheck the cutoff during the guarded archive operation. - Document the environment variable and add focused tests. ## Verification - Run `npx vitest run server/src/__tests__/execution-workspaces-service.test.ts`. - Confirm that the test run passes 66 tests. - Confirm that the tests cover a recent tree, an old tree, value `0`, and a null terminal timestamp. - Confirm that the changed files pass `tsc --noEmit`. ## Risks The default changes terminal workspace cleanup from immediate removal to a seven-day delay. A value of `0` preserves immediate cleanup. The guarded archive check limits race risk during concurrent lifecycle changes. > 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. ## Model Used OpenAI Codex, GPT-5, tool use and code execution. This model assisted with the implementation review and PR preparation. ## 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> Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> |
||
|
|
0e9b03832d |
fix(server): skip host provisionCommand for sandbox-driver environments (#11626)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - The run orchestrator prepares an execution environment before an agent starts > - A sandbox driver creates a remote folder before the adapter uploads repository content > - The orchestrator ran the host `provisionCommand` in that empty folder > - The command failed with exit 127 before the adapter could run its `stage.sync` step > - This pull request skips host provisioning for sandbox drivers and keeps the existing local and SSH behavior > - The benefit is that sandbox runs reach the adapter sync step without an empty-folder setup failure ## Linked Issues or Issue Description **What happened?** A sandbox environment ran the host `provisionCommand` before the adapter uploaded repository content. The command ran in an empty remote folder and failed with exit 127. **Expected behavior** The orchestrator should skip host provisioning for a sandbox driver. The adapter should upload the provisioned tree during its `stage.sync` step. **Steps to reproduce** 1. Configure an environment with the `sandbox` driver and a host `provisionCommand`. 2. Start a run that uses this environment. 3. Observe that the command runs in the empty sandbox folder and the run fails with `setup_failed`. **Paperclip version or commit** Reproduced on the current `master` commit before this change. **Deployment mode** Built from source with a sandbox environment. **Installation method** Built from source with pnpm. **Agent adapter(s) involved** Not adapter-specific (core bug). The sandbox adapter syncs the tree after environment setup. **Database mode** Not database-related. **Additional context** Related context: [#11091](https://github.com/paperclipai/paperclip/pull/11091) changes provision behavior for reused workspaces. This pull request covers the separate sandbox ordering failure. ## What Changed - Skip the orchestrator provision step when `environment.driver` is `sandbox`. - Keep the existing skip for `local` and the provision step for `ssh`. - Log one info message when a sandbox skip drops a present command. - Keep the existing `plugin` path because it has no `stage.sync` step and runs against the host filesystem. - Add tests for sandbox, local, SSH, plugin, logging, and provision failures. ## Verification - Run `./node_modules/.bin/vitest run server/src/__tests__/environment-run-orchestrator.test.ts`. - Confirm that the test run passes all 10 tests. - Confirm that CI checks pass on this pull request. ## Risks - Low risk. The change affects only the provision gate for sandbox drivers. - SSH and local behavior stays unchanged. - The plugin driver stays on its current path. - The new log line makes a sandbox skip visible to operators. ## Model Used OpenAI, GPT-5, exact runtime model `gpt-5`, with tool use and code review support. The implementation author used this model to inspect code, edit source and tests, and run the targeted test suite. ## 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 (no exact duplicate found; related PR #11091 reviewed) - [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 (no documentation change applies to this internal gate correction) - [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> |
||
|
|
6b8e42168e |
Add governed secret alias confirmation cards (#11486)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Agents need scoped secret bindings to use external services safely. > - Agents could not request an existing secret under a new config name without an internal secret identifier. > - Existing binding proposals were only visible in Settings and did not create an issue-thread approval path. > - A confirmation card could record acceptance without proving that the binding was created. > - This pull request extends the existing secret proposal system with safe source references and governed issue-thread confirmation cards. > - The benefit is a one-click flow that creates the binding or shows a clear failure without exposing secret material. ## Linked Issues or Issue Description Related prerequisite: #11482. **Subsystem affected** Cross-cutting: server REST APIs, shared interaction contracts, database proposal schema, and issue-thread UI. **Problem or motivation** An agent can need an existing bound secret under a second config name. The agent cannot safely discover the internal secret identifier. The existing proposal is also easy for the operator to miss because it only appears in Settings. A generic confirmation can record acceptance without executing the binding. **Proposed solution** Let an agent create a binding proposal from one of its existing config paths. Mint a server-owned, human-only confirmation card on the checked-out issue. Recheck the operator's target-agent permission under the proposal row lock. Execute the existing proposal transaction after card acceptance. Store an `executed` or `failed` result on the card. Render the complete lifecycle in the issue thread and attention resolver. **Alternatives considered** A new alias subsystem would duplicate proposal quotas, expiry, authorization, and binding synchronization. A text-only issue comment would not provide a governed action or an execution result. An agent-supplied card payload would permit metadata smuggling. This change uses the existing proposal transaction and a server-owned payload instead. **Roadmap alignment** This change extends the completed "Secrets Manager with per-agent access" roadmap item. It preserves scoped bindings and audited resolution. The required GitHub search found no other open duplicate issue or pull request. ## What Changed - Added safe source-config-path binding proposals and preserved user-secret ownership checks. - Added a proposal-to-interaction link and an idempotent database migration. - Minted human-only `request_confirmation` cards with server-owned `secretProposal` metadata. - Rejected agent-supplied governed metadata and agent addressees. - Rechecked `agent_config:update` authority under the proposal lock before execution. - Recorded `executed` or `failed` results and posted a failure comment when no binding was created. - Settled failed accepted proposals atomically and mirrored rejection, withdrawal, and expiry in both directions. - Emitted `secret.binding.created` for new agent binding writes. - Added a dedicated issue-thread card for pending, executed, failed, rejected, withdrawn, and expired states. - Showed only the source label, target agent, config path, skeptical justification, expiry, and safe failure code. - Replaced resolved attention-query entries immediately with the stitched server result. - Added focused server, database, UI, and state-transition tests. - Added Storybook fixtures for every review state and documented the API and agent behavior. ## Verification - `pnpm exec vitest run ui/src/components/IssueThreadInteractionCard.test.tsx ui/src/components/AttentionInteractionResolver.test.ts` — 58 passed. - `pnpm --filter @paperclipai/ui typecheck` - `pnpm check:token-gates` - `pnpm build-storybook` - `pnpm --filter @paperclipai/shared typecheck` - `pnpm --filter @paperclipai/db typecheck` - `pnpm --filter @paperclipai/server typecheck` - `pnpm --filter @paperclipai/db check:migrations` - `NODE_ENV=test pnpm exec vitest run server/src/__tests__/issue-thread-interaction-routes.test.ts server/src/__tests__/secret-proposals-routes.test.ts server/src/__tests__/secrets-routes.test.ts server/src/__tests__/agents-service-secret-bindings.test.ts` — 142 passed. - `NODE_ENV=test pnpm --filter @paperclipai/db exec vitest run src/company-secret-proposals-migration.test.ts --silent` — 1 passed. - `pnpm -r typecheck` - `pnpm test:run` — server 4,175 passed, UI 4,109 passed; the CLI AWS-doctor case passes 8/8 with runtime-injected static AWS credential variables unset. - `pnpm build` - `git diff --check origin/master...HEAD` ## Risks - Migration `0221` adds one nullable foreign key and one index. It uses idempotent guards. - The accept route performs a governed write after it records card acceptance. A failed write is visible and settles the proposal as rejected. - Concurrent proposal and card resolution must use proposal-before-interaction lock order. A race test covers direct approval against card rejection. - The new audit event increases activity rows for newly added agent bindings. It does not include secret values or fingerprints. - The card includes only safe proposal metadata. It does not include secret value, fingerprint, version, or internal secret identifiers. - The UI uses the stitched resolution result. Focused tests cover immediate cache replacement and every terminal state. > This work extends an existing completed roadmap capability. The GitHub duplicate search returned no other open related work. ## Model Used - OpenAI Codex with model ID `gpt-5`. The runtime did not expose its context-window size. Reasoning, repository tools, code execution, database integration tests, UI rendering, and GitHub tools were enabled. ## 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> |
||
|
|
1c366a9059 |
fix(server): reject invalid agent credentials instead of downgrading to the local user actor (#11589)
<!-- Write all pull request text in Simplified Technical English (ASD-STE100): short sentences, one instruction per sentence, simple approved vocabulary, and the active voice. --> ## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - The server authenticates each agent request in `actorMiddleware` before it attributes chat comments > - When an agent bearer token failed verification, the middleware called `next()` with no error and the request continued without an agent actor > - The request then fell back to the local user actor, so the server stored agent replies as user comments > - The task chat UI renders user comments in blue bubbles, so agent messages appeared as blue user bubbles > - This pull request rejects invalid agent credentials with 401 instead of a silent downgrade > - The benefit is that agent messages keep agent attribution, and broken credentials fail loudly with a clear retry message ## Linked Issues or Issue Description **What happened?** A user cancelled an onboarding question card. The agent posted a follow-up reply. The reply appeared in a blue bubble, which the UI reserves for human messages. The agent run held an expired local agent JWT. The auth middleware could not verify the token, called `next()` without an actor, and the request fell back to the local user identity. The server stored the agent comment as a user comment. **Expected behavior** Agent messages always render as agent bubbles. A request with invalid agent credentials must fail with 401 so the adapter can refresh credentials and retry. It must not post content under a human identity. **Steps to reproduce** 1. Start a local Paperclip instance. 2. Give an agent run an expired or malformed agent JWT. 3. Let the agent post an issue comment through the API bridge. 4. Before this change: the comment is stored with the local user identity and renders as a blue bubble. After this change: the request fails with 401 and a message that tells the caller to obtain fresh credentials. ## What Changed - `server/src/middleware/auth.ts`: a bearer token that fails verification now produces a 401 `unauthorized` error instead of a silent fall-through to the anonymous/local-user actor. - The 401 message states the cause: expired token, unverifiable token, empty bearer token, missing agent record, agent record in another company, terminated agent, or agent pending approval. - The API-key path now also rejects an agent record whose company does not match the key. - `packages/adapter-utils/src/execution-target.ts`: the bridge proxy now writes a `comment id: <id>` marker to the run log for each posted issue comment, so misattributed comments can be traced to a run. - `ui/src/components/task-chat/task-chat-adapter.test.ts`: a regression test asserts that a recovered `local-board` comment with a derived agent author renders as an agent bubble, not a user bubble. - `server/src/__tests__/agent-auth-middleware.test.ts` and `packages/adapter-utils/src/execution-target-sandbox.test.ts`: new tests cover each rejection path and the log marker. ## Verification - Run `pnpm vitest run src/__tests__/agent-auth-middleware.test.ts` in `server/` — 14 tests pass. - Run `pnpm vitest run execution-target-sandbox` at the repo root — 44 tests pass. - Run `pnpm vitest run src/components/task-chat/task-chat-adapter.test.ts` in `ui/` — 4 tests pass. - Manual check: post an issue comment with an expired agent JWT; the API returns 401 with a retry message and no comment is stored. ## Risks - Behavioral shift: requests that previously continued as anonymous or local-user actors after a failed agent-token verification now receive 401. Any caller that relied on the silent downgrade must refresh its credentials. This is the intended fix, and the adapters already handle 401 with a credential refresh. - No schema or migration changes. Low risk otherwise. > 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 - Claude (Anthropic), model ID `claude-fable-5`, via Claude Code with extended thinking and tool use (agent harness with shell, file, and git 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 - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [ ] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> Co-authored-by: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
8087661bb8 |
fix: bound workspace Git scans (#11572)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Workspaces let users and agents inspect files that belong to an issue > - Changed-file views use full-tree Git status scans > - Many issue views could start those scans at the same time and make the server unresponsive > - Route-level limits did not protect the process or coalesce work for one repository > - This pull request adds one bounded scheduler for every expensive workspace Git scan > - It also starts browser scans only when the file panel is open and visible > - The benefit is bounded child-process use and responsive health checks during request storms ## Linked Issues or Issue Description **What happened?** Many changed-file requests could start full `git status --porcelain=v1 -z --untracked-files=all` scans at the same time. One production incident produced about 270 direct Git child processes. The Node process stayed alive but stopped answering health requests in time. **Expected behavior** Paperclip must bound expensive Git work across all companies, actors, issues, repositories, and browser tabs. Duplicate requests for one worktree must share work. Excess requests must fail fast with a retryable response. Hidden or closed file panels must not start scans. **Steps to reproduce** 1. Open changed-file views for many issue and actor keys. 2. Send requests for two large workspace roots at the same time. 3. Observe that route-level limiter keys allow many full Git scans to run together. 4. Observe delayed health responses and accumulated Git children. **Paperclip version or commit** Reproduced on master before commit `43ab441f0f`. **Deployment mode** Self-hosted server with local workspace repositories. ## What Changed - Add a process-wide scheduler with configurable concurrency, queue capacity, timeout, and cache TTL. - Add fair admission, a bounded queue, canonical worktree keys, single-flight joins, and bounded result caching. - Add subprocess timeouts, TERM-to-KILL escalation, bounded output, waiter cancellation, and slot cleanup. - Route full-tree status work from file resources, workspace runtime, execution workspaces, and adapter overlay sync through the scheduler. - Return stable retryable `503` and `504` error codes for saturation and timeout. - Add structured logs with safe workspace hashes, durations, queue state, cache use, joins, and terminal outcomes. - Gate UI queries on panel and document visibility. Cancel queries on close, hide, unmount, and workspace change. - Disable focus and reconnect bursts. Keep one explicit refresh action and a retryable unavailable state. - Document the 10-second default freshness tradeoff and all configuration variables. - Add unit, route, UI, adapter, and deterministic 500-request load coverage. ## Verification - `pnpm -r typecheck` - `pnpm build` - `pnpm check:token-gates` - `pnpm --filter @paperclipai/server exec vitest run src/services/workspace-git-operation-scheduler.test.ts src/__tests__/file-resources-git-scan-load.test.ts --reporter=dot` — 16 tests passed. - `pnpm --filter @paperclipai/ui exec vitest run src/components/WorkspaceFileBrowser.test.tsx src/lib/page-visibility.test.ts --reporter=dot` — 38 tests passed. - `pnpm --filter @paperclipai/adapter-utils exec vitest run src/git-workspace-sync.test.ts --reporter=dot` — 16 tests passed. - Existing file-resource, workspace-runtime, and execution-workspace regression selections passed. - Two cleanup safety regressions prove failed scans preserve the worktree before archive and at the final deletion fence. - Before: the incident produced about 270 Git children and health requests timed out. - After: 500 concurrent requests across 500 issue keys, 73 actors, and two roots started two underlying scans. Peak scan concurrency was 2. All 500 requests succeeded. Health p99 was 4.94 ms. The harness found zero unreaped children. - The full local Vitest run passed 4,267 tests. Ten existing fixed-port HTTPS exposure tests could not run because this host already owns Tailnet listeners on ports 42000 and 52000. Clean GitHub CI is the final full-suite result. - Latest-head GitHub CI passed all required test, typecheck, build, canary, e2e, policy, and security gates. - Greptile completed at 5/5 with zero unresolved comments, recommendations, or follow-ups. ## Risks - Changed-file results can be up to 10 seconds old by default. Explicit refresh remains available. - A full queue returns a retryable `503` instead of waiting without a bound. - A scan that exceeds the default 8-second deadline returns a retryable `504` and terminates its process group. - Operators can tune all limits with documented environment variables. Safe defaults protect local and shared servers. > 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 family. The runtime does not expose the exact deployment ID or context-window size. High reasoning, tool use, and code execution were enabled. ## 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> |
||
|
|
962e98b1be |
feat(server): operator declaration for platform edge TLS termination on the Claude login guard (#11579)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - The Claude local adapter supports a setup-token subscription login, and its confidential routes pass a fail-closed transport guard > - The guard accepts direct socket TLS, a local_trusted loopback peer, or an allowlisted proxy peer that forwards https — and deliberately never reads the global `TRUST_PROXY` > - On a managed platform the edge terminates TLS, the app socket is always plain HTTP, and the edge-proxy peer addresses are not stable or documented, so none of the three cases can hold > - Every login on such a deployment shows the clear-text transport warning although the user's connection is HTTPS, and the agent-scoped confidential routes fail closed entirely > - This pull request adds a dedicated operator declaration that the platform edge terminates TLS, as a fourth guard case > - The benefit is a correct transport decision on managed platforms with the default posture unchanged everywhere else ## Linked Issues or Issue Description No public GitHub issue covers this. The problem is described in-PR following the enhancement template. Related public PRs: [#11347](https://github.com/paperclipai/paperclip/pull/11347) added the new-agent login flow and the non-blocking transport advisory, and [#11286](https://github.com/paperclipai/paperclip/pull/11286) added the setup-token login and the guard with its `CLAUDE_LOGIN_TRUSTED_PROXIES` allowlist. **Subsystem affected** server/ — the confidential transport guard for the Claude setup-token login (`services/setup-token-session.ts`, `routes/agents.ts`, `app.ts`). **Current behavior** The guard allows a confidential response on direct socket TLS, on a `local_trusted` loopback peer, or when the immediate peer is on the dedicated `CLAUDE_LOGIN_TRUSTED_PROXIES` allowlist and forwards `https`. Behind a managed platform's TLS-terminating edge (Railway, Render, Fly, and similar), the app socket is plain HTTP and the edge-proxy peer addresses are not operator-visible or stable, so the allowlist cannot express them — IPv6 entries match by exact string only. The result: the login panel shows "This connection is not encrypted" for a connection that is HTTPS to the user, and the agent-scoped confidential routes return the fixed no-secret error. **Proposed behavior** `CLAUDE_LOGIN_EDGE_TLS_TERMINATED=true` is an explicit, single-purpose operator declaration that every client request reaches the server through the platform's TLS-terminating edge. Under the declaration the guard treats a request as confidential unless the edge itself labels the client hop as plain `http` in `X-Forwarded-Proto`. The declaration is never derived from the global `TRUST_PROXY` setting, which the guard still never reads. Without the declaration, nothing changes. **Reason and benefit** The guard's spoofing concern does not apply to this deployment shape: a client cannot pick its transport, because the platform admits HTTPS only, and the header the guard consults is set by the platform edge, not the client. A blanket warning that is always wrong teaches users to ignore it. The declaration keeps the strict default for every deployment that does not opt in, and it keeps the allowlist as the precise tool for operators who do know their proxy addresses. ## What Changed - `ConfidentialTransportConfig` gains optional `edgeTlsTerminated` (default false), documented as the operator declaration for platform edge TLS termination. - `evaluateConfidentialTransport` adds the declaration as a guard case: allowed unless the forwarded protocol's first hop is explicitly `http` (reason `edge_labeled_plain_http` then; `operator_edge_tls_termination` when allowed). - `assessConfidentialStartup` reports `edge_tls_termination_declared`, so the startup log shows why forwarded requests pass. - `app.ts` parses `CLAUDE_LOGIN_EDGE_TLS_TERMINATED` (truthy: `1/true/yes/on`) and passes it to the agent routes; the routes build the guard config from it. - The SR-7 operator-requirement comment on the setup-token routes documents the new variable next to the allowlist. - Tests: five new guard unit cases and a route case asserting the prompt and code responses carry no `transportAdvisory` under the declaration. ## Verification ```sh cd server npx tsc --noEmit # clean npx vitest run src/services/setup-token-session.test.ts \ src/routes/setup-token-route.test.ts \ src/__tests__/openapi-routes.test.ts # 3 files, 89 passed ``` The new "keeps failing closed when the declaration is absent" case pins the unchanged default posture. ## Risks The declaration is an operator statement the server cannot verify; an operator who sets it on a deployment whose edge does not terminate TLS re-labels plain-HTTP requests as confidential. This is the same trust class as `CLAUDE_LOGIN_TRUSTED_PROXIES` (a wrong allowlist entry has the same effect) and is opt-in, off by default, and scoped to the login routes only. The guard still fails closed when the edge explicitly labels a request `http`. No schema change, no API shape change — `transportAdvisory` was already nullable. ## Model Used Claude Fable 5 (`claude-fable-5`), extended thinking, with tool use and code execution — investigation, implementation, and tests. ## 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 |
||
|
|
43ab441f0f |
Exempt plugin-managed issues from successful-run-handoff recovery (#9047)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Plugins can extend Paperclip with their own multi-step workflow/graph engines that own an issue's lifecycle across many agent handoffs > - When such a plugin-managed issue legitimately stays `in_progress` for a while (e.g. an anchor issue parked at a fan-out step, waiting on child issues it spawned), Paperclip's generic recovery mechanisms have no way to know that's intentional > - The first commit on this branch fixed one such mechanism (`decideSuccessfulRunHandoff`) to skip plugin-owned issues, and was deployed to a real instance to verify the fix > - Watching that same instance afterward, the identical symptom (repeated "give a disposition" nags, the agent repeating "completed", the plugin's own enforcement correctly reverting the status) recurred on the same class of issue — meaning a second, independent code path had the exact same gap > - Traced it to `reconcileStrandedAssignedIssues` in `service.ts`: it detects a stale successful-run-handoff corrective run via `isExhaustedSuccessfulRunHandoff` and, once "exhausted" (default max attempts is 1, so effectively immediate), escalates via `escalateStrandedAssignedIssue` — with no check on who owns the issue's lifecycle at all > - Rather than duplicate the `originKind` check inline a second time (which is exactly how it got missed the first time), extracted it into a shared, exported, unit-tested helper (`isPluginManagedIssueLifecycle`) that both recovery paths now call > - The benefit is the same as the first commit, but closing the second loop this pull request's earlier version left open: generic plugin-owned issues (any workflow/graph-engine plugin, not just one specific plugin) stop burning real agent-run cost in a loop that can never actually resolve, across both recovery mechanisms that can trigger it ## Linked Issues or Issue Description No existing public issue covers this — describing it directly, following the bug report fields: **What happened?** An issue owned by a workflow-engine-style plugin (`originKind` starting with `"plugin:"`) was correctly held at `in_progress` by the plugin while it waited on spawned child issues to finish. The assigned agent's heartbeat succeeded and posted a well-formed completion comment, but `issue.status` stayed `in_progress` (the plugin's own enforcement reverted it, correctly, since the underlying work wasn't done). - **Path 1 (fixed in the first commit):** `decideSuccessfulRunHandoff()` saw `status === "in_progress"` after a successful run and enqueued a "missing disposition" corrective wake. The agent responded again, the plugin reverted the status again, and the recovery re-triggered again. - **Path 2 (fixed in the second commit, found after deploying and verifying the first fix on a live instance):** separately, `reconcileStrandedAssignedIssues` periodically re-scans `in_progress` issues, sees the corrective run from Path 1 (or any prior successful-run-handoff wake) as "exhausted" evidence, and escalates the issue via `escalateStrandedAssignedIssue` regardless of plugin ownership — producing the same nag-revert-nag cycle through a completely different call path that the first commit's fix did not touch. **Expected behavior** Neither recovery mechanism should nag an agent for a disposition, or escalate for one, on an issue whose lifecycle is already owned and managed by a plugin — that plugin's own enforcement/recovery path is the correct owner of "what happens next," not these generic core mechanisms. **Steps to reproduce** 1. Install a plugin that creates/owns issues via the plugin host bridge (`ctx.issues.create`/`ctx.issues.update`) with an `originKind` of `"plugin:<pluginKey>"`. 2. Have the plugin's own graph/workflow logic hold an issue at `in_progress` while some multi-step process it owns is still pending (e.g. spawned child issues not yet complete). 3. Let an agent run a successful heartbeat on that issue that produces visible progress (a comment) but does not change `issue.status` away from `in_progress` in a way that sticks (the plugin's own logic reverts any change back to `in_progress` on the next event). 4. Observe `decideSuccessfulRunHandoff` enqueue a corrective handoff wake (Path 1), and/or `reconcileStrandedAssignedIssues` treat that wake's run as exhausted and escalate (Path 2). Either one repeats indefinitely on its own. **Paperclip version or commit** `eb2cb916be3271e3e7ab5f643ad3ca3eb7c34d01` (current `master` at time of the first commit; rebased onto `ad961227f` for the second) **Deployment mode** Self-hosted server ## What Changed - **First commit:** Added `originKind: issues.originKind` to the issue query in `heartbeat.ts` that feeds `decideSuccessfulRunHandoff`, and a skip condition there for `originKind` starting with `"plugin:"`. - **Second commit:** - Extracted the plugin-ownership check out of `decideSuccessfulRunHandoff` into a new exported helper, `isPluginManagedIssueLifecycle(issue)`, in `successful-run-handoff.ts`. - Added the same check to `reconcileStrandedAssignedIssues` in `service.ts`, immediately before it would otherwise escalate an issue based on `isExhaustedSuccessfulRunHandoff` evidence — skipping plugin-managed issues there too. - Added unit tests for the new helper directly (plugin-prefixed origin kinds → `true`; non-plugin/missing origin kinds → `false`), alongside the existing `decideSuccessfulRunHandoff` tests (updated to import and rely on the shared helper, behavior unchanged). ## Verification - `npx vitest run server/src/services/recovery/successful-run-handoff.test.ts` — 20/20 passed (18 pre-existing/from the first commit + 2 new for the extracted helper). - `npx vitest run server/src/__tests__/heartbeat-comment-wake-batching.test.ts server/src/__tests__/heartbeat-process-recovery.test.ts server/src/services/recovery/successful-run-handoff.test.ts` — full suite still passes with the refactor. - `pnpm --filter @paperclipai/server exec tsc --noEmit` — no new errors introduced by either commit (confirmed against a pre-existing baseline of unrelated `@paperclipai/plugin-sdk` module-resolution errors from the workspace, present identically with the changes stashed out). - Manually verified Path 1 against a real plugin-managed issue stuck in that loop: after deploying the first commit and restarting the server, the same agent posted the same completion comment again, and the corrective-handoff recovery did not re-trigger. - Path 2 was found live on the same instance after that first deploy (the loop recurred through the second, independent mechanism) — root-caused via direct inspection of `heartbeat_runs`/`agent_wakeup_requests`/issue comment history, then fixed in the second commit. Not yet re-verified live on the instance (pending redeploy of this updated branch). ## Risks - Low risk. Both changes are additive skip conditions — they only cause a recovery decision to return early for a specific, narrow case (`originKind` starting with `"plugin:"`) that previously fell through to escalation/enqueue. No existing skip conditions are changed or reordered in a way that affects non-plugin issues. - Behavioral shift: plugin-managed issues that are genuinely stuck (not just correctly mid-flight) will no longer get either of these corrective nags. This is intentional — the plugin owning the issue is expected to have its own recovery path — but it does mean these mechanisms are no longer a safety net for buggy plugins that leave issues stranded. Plugin authors should ensure their own enforcement handles stranded states. - The refactor (extracting `isPluginManagedIssueLifecycle`) is a pure code-motion change for the first commit's check — no behavior change there, only a new call site added in `service.ts`. - No migration required (query-shape and control-flow changes only, no schema change). ## Model Used Claude (Anthropic), model `claude-sonnet-5`, used within a coding-agent harness (Claude Code) with tool use (file edit, test execution, git operations, live production-instance debugging via SSH/SQL) and extended reasoning across two sessions: the first implemented and deployed the initial fix, the second discovered the second recovery path was still looping on a live instance, root-caused it, and implemented/tested this follow-up commit. ## 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 - [ ] 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: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
8774909361 |
fix(heartbeat): reuse sessions across execution handoffs (#9917)
## Thinking Path > - Paperclip uses durable task sessions so local adapters can resume work across sequential heartbeat runs. > - `execution_review_requested` and `execution_changes_requested` are issue-local execution-policy handoffs, not new task assignments. > - The existing `agent_task_sessions` lookup, adapter session codec, workspace resolution, and effective config freshness checks already decide whether reuse is safe. > - Treating those two handoff wake reasons as unconditional fresh-session boundaries discards a valid saved task session before adapter resume can be attempted. > - This makes Dev → CodeReview → Dev loops repeatedly cold-start even when task, issue, agent, adapter, workspace, and config identity are unchanged. > - The fix is to let normal review/change-request handoffs reach the durable task-session path while preserving explicit fresh-session and unsafe-boundary resets. ## Linked Issues or Issue Description Fixes #8246. cc @cryppadotta — this is the narrow handoff-session policy change discussed there: normal `execution_review_requested` / `execution_changes_requested` wakes no longer force a fresh task session by wake reason alone, while assignment, approval, review-participant recovery, timer wakes, explicit `forceFreshSession`, and config/workspace/model/session freshness still keep their safety boundaries. ## What Changed - Removed normal `execution_review_requested` and `execution_changes_requested` from the unconditional task-session reset policy. - Kept fresh-session boundaries for: - `issue_assigned` - `execution_approval_requested` - `execution_review_participant_recovery` - `heartbeat_timer` - explicit `forceFreshSession` - existing config/model/workspace/session freshness reset paths - Updated heartbeat session-policy tests so execution handoffs are resume-eligible by wake reason alone. - Preserved PF-4 timer-wake behavior and its explicit reset reason. ## Verification - `npx pnpm@9.15.4 exec vitest run server/src/__tests__/heartbeat-workspace-session.test.ts server/src/__tests__/heartbeat-timer-wake-session-reset-pf4.test.ts server/src/__tests__/codex-local-execute.test.ts server/src/__tests__/issue-comment-reopen-routes.test.ts --reporter=verbose` — 220 tests passed. - `npx pnpm@9.15.4 --filter @paperclipai/server typecheck` — passed. - `git diff --check` — passed. - `coderabbit review --agent -t committed --base origin/master` — 0 findings. ## Risks - Moderate behavior change in session-boundary policy: normal review/change-request handoffs may now reuse a saved per-task session when the existing identity/freshness checks pass. - Safety boundaries remain in place for new assignments, approval gates, review-participant recovery, timer/discovery wakes, explicit fresh-session requests, and config/model/workspace/session drift. - If a saved session is stale or incompatible, existing freshness/resume fallback behavior still handles reset/fresh execution. > For core feature work, check 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 GPT-5.5. Tool use and local verification were enabled. ## 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 - [x] My branch name describes the change and contains no internal Paperclip ticket ID - [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 — N/A, server policy/test-only change - [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: santastabber <184111696+santastabber@users.noreply.github.com> |
||
|
|
b90da4d115 |
fix: keep task sessions across issue comments (#10111)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Local session adapters persist task sessions so later wakes can resume the same conversation > - Session reuse correctly resets when effective execution configuration changes > - The workspace fingerprint currently includes the issue row's `updatedAt` timestamp > - Adding a comment advances that timestamp even though workspace configuration is unchanged > - The next same-issue wake therefore discards a valid task session and starts cold > - This pull request excludes that volatile timestamp while retaining actual workspace settings in the fingerprint > - The benefit is reliable same-task continuation without weakening configuration-freshness safety ## Linked Issues or Issue Description No public issue exists. The inline report below follows the bug report template. ### Pre-submission checklist - [x] I searched existing open and closed issues and found no duplicate. - [x] I reproduced the bug on the latest release and current `master`. - [x] I confirmed the error originates in Paperclip core fingerprinting, not an adapter, provider, or local configuration. ### What happened? On Paperclip 2026.720.0 and current `master`, a comment on an issue changes `issues.updated_at`. Heartbeat session fingerprinting includes that value under `workspaceConfig.issueConfigRevisionAt`, so the next wake for the same issue reports a workspace-config change and refuses the saved task session. ### Expected behavior Comment-only and other non-configuration issue updates should be delivered as wake deltas without invalidating the task session. Changes to the execution mode, issue workspace settings, project policy, environment, instructions, model, secrets, or other effective run configuration must still reset it. ### Steps to reproduce 1. Complete a local session-adapter run for an issue and retain its task session. 2. Add a comment to the issue without changing execution configuration. 3. Wake the same agent for the same issue. 4. Observe `changedCategories: ["workspaceConfig"]` and a fresh session. ### Paperclip version or commit Reproduced on Paperclip 2026.720.0 and current `master`. ### Deployment mode Self-hosted server. ### Installation method npm global install; also reproduced from the current source tree. ### Agent adapter(s) involved Codex exposed the symptom. The bug is in core fingerprint construction and is not adapter-specific. ### Database mode External Postgres. The bug is not database-specific. ### Access context Board comments trigger the timestamp change; the subsequent agent wake exposes the reset. ### Node.js version Node.js 22. ### Operating system Ubuntu 24.04. ### Relevant logs or output The next run records `changedCategories: ["workspaceConfig"]` and starts a fresh session after a comment-only mutation. ### Relevant config No unusual configuration is required. ### Additional context The regression test exercises the fingerprint directly on current `master`. ### Privacy checklist - [x] I reviewed the report for PII, credentials, private paths, company names, and instance-local identifiers. ## What Changed - Copy and sanitize the session workspace-fingerprint input before hashing. - Exclude only `issueConfigRevisionAt`, which reflects general issue mutation rather than workspace configuration. - Add regression coverage proving comment timestamps preserve the session while real workspace mode/settings changes still reset it. ## Verification - `pnpm exec vitest run server/src/__tests__/heartbeat-workspace-session.test.ts` - 120 tests passed. - `pnpm --filter @paperclipai/server typecheck` - passed. - `git diff --check` - passed. ## Risks Low risk. A general issue update no longer rotates the adapter session solely because its row timestamp changed. The fingerprint still includes issue workspace settings, issue adapter overrides, project workspace policy, environment, instructions, runtime skills, secrets, model profile, adapter configuration, and agent runtime configuration, so actual execution-config drift continues to reset. > 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`, context-window size not exposed, reasoning and tool use enabled. ## 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: Uliana Savostenko <ulia@MacBook-Air.local> |
||
|
|
7a4767017e |
fix(issues): base comment-wake decisions on post-insert issue state (#10068)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work; issues get commented on by both humans and agents, and the assignee is woken to act on new comments. > - #10050 added human-attributed issue comments for chat gateway plugins, with the host waking the issue's assignee the same way a board user's comment does. > - Greptile's review on #10050 flagged that the wakeup guard in `plugin-host-services.ts` decides whether to wake the assignee using the issue snapshot fetched *before* the comment was inserted. > - If another request closes, cancels, unassigns, or reassigns the issue in the window between that fetch and the wakeup call, the guard still acts on the stale snapshot — it can wake an agent for a now-terminal issue, or wake the old assignee instead of the new one. > - The PR discussion noted the HTTP add-comment route (`routes/issues.ts`) has the identical pattern outside its reopen/auto-approval branches, and deferred a fix to a follow-up covering both call sites — this PR is that follow-up. > - The fix re-fetches the issue immediately before the wake decision in both places, so the decision reflects the latest committed state instead of a pre-insert snapshot. ## Linked Issues or Issue Description Refs #10050 **Problem or motivation** Both the plugin-comment wakeup guard (`plugin-host-services.ts`) and the HTTP add-comment route's wakeup guard (`routes/issues.ts`, outside its reopen/auto-approval branches) decide whether to wake the issue's assignee using the issue state fetched before the comment was inserted. A concurrent close/unassign/reassign landing in that window is invisible to the guard, so it can enqueue a wakeup for a stale assignee or an issue that is no longer open. **Proposed solution** Re-fetch the issue immediately before the wake decision in both call sites, and base the assignee/status checks on that fresh read instead of the earlier snapshot. This shrinks the race window to essentially nothing (the fetch happens right before the fire-and-forget wakeup call), and any residual window is already covered by the heartbeat/checkout machinery re-validating issue status and assignee ownership when a woken run actually starts. **Alternatives considered** Wrap the whole comment-insert + wake-decision sequence in a single serializable transaction with row locking (rejected for this change — much larger blast radius across two already-complex handlers for a wakeup that is explicitly best-effort; the woken run's own re-validation already makes a stale wake degrade to a no-op rather than incorrect work). Leaving the plugin path fixed but not the HTTP route (rejected — that was the exact gap the original PR discussion flagged as needing a follow-up covering both call sites). **Roadmap alignment** Bug fix / hardening follow-up to #10050; no change to planned core roadmap items. ## What Changed - `server/src/services/plugin-host-services.ts`: `issues.createComment`'s assignee-wakeup guard now re-fetches the issue after the comment is inserted and bases the assignee/status checks on that fresh read, instead of the snapshot fetched before the insert. - `server/src/routes/issues.ts`: the `POST /issues/:id/comments` route's wakeup guard (outside the reopen/auto-approval branches, which already use post-mutation state) now does the same re-fetch before deciding whether — and whom — to wake. - Adds regression coverage for both: - `server/src/__tests__/plugin-orchestration-apis.test.ts`: a new embedded-Postgres test holds a row lock on the issue to deterministically force the race (comment-insert's internal update blocks until a concurrent transaction commits a cancellation), then asserts no wakeup is enqueued. - `server/src/__tests__/issue-comment-reopen-routes.test.ts`: two new mocked-service tests assert the route skips the wakeup when the fresh re-fetch shows the issue cancelled, and wakes the freshly reassigned agent (not the pre-insert snapshot's assignee) when the fresh re-fetch shows a different assignee. ## Verification - `pnpm --filter @paperclipai/server typecheck` — clean. - `pnpm --filter @paperclipai/server exec vitest run src/__tests__/plugin-orchestration-apis.test.ts` — 13/13 (1 new). - `pnpm --filter @paperclipai/server exec vitest run src/__tests__/issue-comment-reopen-routes.test.ts` — 74/74 (2 new). - `pnpm --filter @paperclipai/plugin-sdk exec vitest run tests/host-client-factory.test.ts` — 14/14. - Broader sweep of 38 `routes/issues.ts`-adjacent test files (447 tests) — all passing, confirming the added re-fetch doesn't change behavior for any existing reopen/auto-approval/interrupt/scheduled-retry/dependency-wake scenario. ## Risks Low risk. Both changes are additive guards around an existing best-effort, fire-and-forget wakeup (failures already logged, not thrown) — no change to the comment-write path itself, response shape, or status codes. The HTTP route's fix only touches the plain (non-reopen, non-auto-approval) wake-decision path; the reopen and auto-approval branches already used post-mutation state for the reasons documented inline and are unchanged. Adds one extra `SELECT` per comment on each call site, negligible relative to the existing query volume in both handlers. ## Model Used Claude Sonnet 5 (`claude-sonnet-5`), extended thinking, tool use enabled, via Claude Code. ## 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 searched the GitHub PR list (open and recently closed) for similar PRs; found no duplicate — this is a direct follow-up to the review discussion on #10050 - [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 - [x] My branch name describes the change and contains no internal ticket id - [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: anicca <annica@Michaels-Mac-Studio.local> Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
7ef75f5636 |
fix(opencode-local): retry models preflight during transient contention (#9225)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Local CLI adapters are responsible for starting agent runtimes and validating that their configured models are usable before a run starts. > - The OpenCode local adapter checks `opencode models` during model discovery and preflight validation. > - On hosts with a shared Ollama daemon, that lightweight metadata call can transiently queue behind an active generation and time out or return a short failure. > - Treating that transient contention as a hard adapter failure prevents otherwise valid local OpenCode runs from starting. > - This pull request adds a small bounded retry/backoff around OpenCode model discovery while keeping the existing per-attempt timeout and surfacing a final failure when retries are exhausted. > - The benefit is fewer false adapter failures during local Ollama contention without changing shared Ollama configuration or hiding genuinely stuck model discovery. ## Linked Issues or Issue Description No public GitHub issue exists for this adapter reliability bug. Bug description: - What happened: `opencode models` can transiently time out or fail while a shared local Ollama daemon is busy serving another OpenCode generation, causing the adapter preflight to fail before the actual run starts. - Expected behavior: transient model-list contention should be retried briefly before declaring the adapter unavailable. - Steps to reproduce: run an OpenCode local adapter using an Ollama-backed model while another `opencode run` is actively generating against the same daemon, then trigger model discovery/preflight during that contention window. - Paperclip version/commit: observed on the current Paperclip master-line OpenCode local adapter before this change. - Deployment mode: local trusted / local CLI adapter execution with a shared local Ollama daemon. Related search: - Searched public GitHub issues for `opencode models preflight retry`; no matching issue found. - Searched public GitHub PRs for `opencode models preflight retry`; no matching PR found. The only search hit was unrelated OpenClaw gateway authentication work (#6121). ## What Changed - Added bounded retry/backoff to OpenCode model discovery: three total attempts with 2s and 4s waits between failures. - Preserved the existing 20s per-attempt `opencode models` timeout. - Retry covers timeout and non-zero process exits, while spawn-level failures still surface immediately. - Added unit coverage for transient fail -> timeout -> success behavior and exhausted retry behavior. - Updated existing OpenCode environment diagnostic tests with explicit timeouts for the intentional retry/backoff path. ## Verification - `pnpm --filter @paperclipai/adapter-opencode-local exec vitest run src/server/models.test.ts src/server/execute.test.ts` -> 2 files passed, 13 tests passed. - `pnpm --filter @paperclipai/adapter-opencode-local typecheck` -> passed. - `pnpm vitest run server/src/__tests__/opencode-local-adapter-environment.test.ts` -> 1 file passed, 3 tests passed. - Branch diff against current `upstream/master` is limited to `packages/adapters/opencode-local/src/server/models.ts`, `packages/adapters/opencode-local/src/server/models.test.ts`, and `server/src/__tests__/opencode-local-adapter-environment.test.ts`. ## Risks Low risk. This only changes OpenCode model discovery behavior and keeps the preflight bounded. A genuinely unavailable `opencode models` call still fails after three attempts, and command spawn failures are not masked. ## Model Used OpenAI Codex, GPT-5.5 coding agent, tool-enabled repository editing and shell verification in a local Paperclip workspace. ## 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: Test <test@paperclip.ing> |
||
|
|
14fd8aee36 |
fix(server): flag truncated issue descriptions (#4771)
## Thinking Path > - Paperclip orchestrates AI agents for zero-human companies. > - The issue list API is one of the surfaces API consumers use to synchronize issue metadata. > - The list endpoint intentionally returns a bounded `description` preview so large descriptions do not bloat list responses. > - Before this change, that preview looked like a complete field value because the response did not say whether it had been shortened. > - That made round-trip clients vulnerable to accidentally PATCHing a preview back over the full description. > - This pull request keeps the existing preview behavior but adds an explicit `descriptionTruncated` flag. > - The benefit is backwards-compatible visibility into truncated issue descriptions, so clients can avoid data-loss workflows. ## Linked Issues or Issue Description Fixes #4758. Related PR: #4792 also targets #4758, but it includes unrelated logger changes and currently has separate review/security concerns. This PR keeps the fix scoped to the issue-list description truncation API behavior. ## What Changed - Added `descriptionTruncated` to the issue list projection when `description` exceeds the existing 1200-character preview limit. - Exposed `descriptionTruncated?: boolean` on the shared `Issue` type. - Added service tests for truncated descriptions, exact-limit descriptions, null descriptions, and multibyte-safe preview truncation. ## Verification June 18, 2026 refresh after rebasing onto current `origin/master`: - `pnpm install --frozen-lockfile` - `pnpm exec vitest run server/src/__tests__/issues-service.test.ts` - `pnpm --filter @paperclipai/server typecheck` - `pnpm typecheck` - `git diff --check origin/master...HEAD` - GitHub PR checks are green on head `12e828e6`. Earlier pre-review verification also included `pnpm test`. ## Risks - Low risk. This is an additive API response field; existing clients can ignore it. - The list endpoint still returns the same bounded `description` preview. Clients that need full text should continue fetching the issue detail, but can now detect when that is necessary. - No database migration or UI behavior change. > 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 based on GPT-5, via Codex desktop on April 29, June 15, and June 18, 2026. Used tool-assisted repository inspection, code editing, local test execution, GitHub CLI workflows, and PR review follow-up. Exact context window size is not surfaced by the tool. ## 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 run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots (N/A: no UI change) - [x] I have updated relevant documentation to reflect my changes (N/A: additive API field covered by tests) - [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: Sami Rusani <sr@samirusani> |
||
|
|
c1c46f1e4e |
feat: Claude login on the new-agent page before agent creation (#11347)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - The Claude local adapter supports subscription login through a sandbox > - The new-agent page must show login before the user creates an agent > - Test results must not expose raw sandbox diagnostics or secret values > - This pull request adds the login UI to both Test lanes and closes the diagnostic boundary > - The branch also adds durable cleanup recovery for failed sandbox teardown > - Reusable sandboxes must retain both their recorded teardown configuration and a valid lifecycle path until destruction succeeds > - The benefit is a usable login flow with fixed public checks, redacted server logs, and recoverable sandbox cleanup ## Linked Issues or Issue Description Related public work: [#9488](https://github.com/paperclipai/paperclip/pull/9488) adds first-class recognition for `CLAUDE_CODE_OAUTH_TOKEN` in headless and remote runs. Related public issue: [#2681](https://github.com/paperclipai/paperclip/issues/2681) requests Claude Code subscription support. This pull request adds the login transport and new-agent UI flow that those changes do not provide. **Subsystem affected:** Claude local adapter, server login probes, sandbox provider setup, cleanup recovery, and the new-agent UI. **Problem or motivation:** The Test lanes did not show the sandbox login panel in all supported cases. Test results also exposed raw probe diagnostics, and JSON escapes could end secret redaction early. **Proposed solution:** Surface the login capability through the bundled provider manifest. Prepare the same probe runtime in the ACP lane. Send diagnostics only to redacted server logs. Keep Test checks on fixed public messages. Normalize login URL hints to allowlisted HTTPS Claude and Anthropic hosts. Consume JSON escapes during redaction. Preserve failed sandbox cleanup state across retries and restarts, and prevent deletion from severing the lifecycle context of a live reusable sandbox. **Alternatives considered:** Keep raw diagnostics in Test checks or trust login URL text from the sandbox. Both choices increase information exposure. Keep separate probe behavior in the ACP lane. That choice would leave the two Test lanes inconsistent. ## What Changed - Surface the sandbox login panel on both Test lanes. - Reconcile the bundled Daytona plugin manifest so `supportsSetupTokenLogin` reaches the UI capability gate. - Prepare the ACP Test lane with the same probe runtime as the CLI Test lane. - Add the `claude_acp_login_probe_unavailable` warning when the ACP probe cannot run. - Send raw sandbox diagnostics only to redacted server logs. - Keep Test checks on fixed public messages in the ACP, managed-config, and CLI paths. - Normalize login URL hints to allowlisted HTTPS Claude and Anthropic hosts. - Redact JSON and escaped-JSON secret values, including escaped quotes and backslashes. - Preserve orphan cleanup records across provider failures, restarts, and unavailable plugins. - Atomically block environment deletion while a live reusable sandbox lease still depends on it. - Verify pending cleanup destroys plugin sandboxes with the provider configuration recorded on the lease, even after the current environment configuration changes. ## Verification - Head under review: `506b7fa2d83c36bfa5fd722ee9d95b0c7431c241`. - Focused environment route/service/runtime coverage passes: 196 tests across 3 files. - `pnpm -r typecheck` passes. - `pnpm build` passes. - The full Vitest run completed with 4,754 passing and 28 failing tests. All 23 source-test failures reproduce unchanged on parent head `58cfe61a33191ce03d965d65085d26064b4888ba`; the other 5 are duplicate executions from stale `server/dist` output. The failures are unrelated macOS path/listener and scheduler-fixture failures, so there is no new bad commit for bisect to localize. - All required CI checks pass for the current head, including build, typecheck/release registry, all server and workspace shards, serialized server suites, canary, and e2e. - A fresh Greptile review for `506b7fa2d83c36bfa5fd722ee9d95b0c7431c241` reports 5/5, “safe to merge,” with no blocking failure remaining. ## Risks - A probe or redaction change could hide useful server diagnostics. - An allowlist change could reject a valid Claude login URL. - Cleanup recovery changes could affect provider teardown ordering. - An environment with a live reusable sandbox can no longer be deleted until the owning issue or execution workspace completes teardown. - The implementation keeps public Test messages fixed and sends detail to redacted server logs. ## Model Used OpenAI GPT-5 via Codex — exact model ID: GPT-5; tool use and code execution enabled; extended reasoning enabled. The implementation author used AI-assisted development. ## 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 documented the result - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation or confirmed no separate documentation change is needed - [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> |
||
|
|
3061ce6901 |
feat(sandbox): stream session output by capability, drop three operator flags (#11557)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Sandboxed agents use provider capabilities to select safe execution paths > - Session output still depends on three operator flags that duplicate capability data > - Duplicate flags can drift from the verified sandbox capability snapshot > - This pull request makes the capability snapshot the only streaming decision and removes the obsolete flags > - The benefit is default streaming with a poll fallback when a capability or stream fails ## Linked Issues or Issue Description **What existing behavior does this improve?** ACP sandbox session-output streaming and sandbox execution configuration. **Subsystem affected** Cross-cutting (multiple of the above): server/, packages/shared/, packages/adapter-utils/, and packages/plugins/. **Current behavior** Session-output streaming requires operator flags in the server and Daytona plugin configuration. Saved configurations can retain a removed key. **Proposed behavior** The verified capability snapshot selects streaming. The Daytona plugin uses persistent sessions by default, keeps bypass commands one-shot, and falls back from the log stream to polling. Removed configuration keys become inert. **Reason and benefit** One capability source prevents configuration drift. The fallback keeps output available when capability resolution or log streaming fails. **Breaking changes** The three operator flags no longer control session-output streaming. Existing saved keys load but have no effect. ## What Changed - Remove `useSessions` and `useLogStream` from the Daytona plugin configuration and manifest. - Remove `streamAgentSessionOutput` from server configuration, shared types, and execution-target plumbing. - Select streaming from `persistentProcessSessions` and `independentControlCommands`. - Keep poll fallback on capability resolution failure and stream failure. - Strip removed keys from strict fake-sandbox and catchall plugin configuration. - Update the sandbox capability documentation and focused tests. ## Verification - `tsc --noEmit` passed in `packages/shared`, `packages/adapter-utils`, `server`, and the Daytona plugin. - Daytona `plugin.test.ts` passed 139 tests. - Server capability, configuration, route, and runtime suites passed 160 tests. - `packages/adapter-utils` `execution-target-sandbox.test.ts` passed 44 tests. - The capability matrix covers stream, poll, and resolution-failure paths. - Removed-key tests cover strict fake-sandbox and catchall plugin schemas. ## Risks - A capability snapshot that lacks either required session capability uses polling. - A log stream failure uses polling and can increase request count. - Existing removed configuration keys no longer change behavior. - The isolated-worktree Daytona Vitest run has a pre-existing missing `packages/adapters/droid-local` reference. CI and standard checkouts use the committed configuration. ## Model Used OpenAI Codex, GPT-5, tool use and code review assistance. The exact runtime context window is managed by the Codex platform. ## 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> |
||
|
|
e71ce9a9d3 |
feat: sandbox provider capability contract with fail-closed effective resolution (#11463)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Paperclip runs work through adapters and sandbox providers > - Providers need a clear contract so the server can use only verified capabilities > - A declared capability must not grant a method that the live worker did not verify > - This pull request adds manifest declarations and fail-closed effective capability resolution > - The benefit is safe provider reuse across execution targets and run lifecycles ## Linked Issues or Issue Description **Subsystem affected** Cross-cutting (multiple of the above) **Problem or motivation** Sandbox providers expose different runtime methods. The server needs one safe capability contract that accounts for provider declarations, worker verification, and narrowing configuration. **Proposed solution** Add strict manifest validation for five sandbox capabilities. Resolve effective capabilities as the subset of verified, declared, and narrowed values. Store the result as a frozen execution-target snapshot. **Alternatives considered** Trusting the manifest alone could grant methods that the worker does not support. Trusting only a fixed built-in list would reject valid third-party providers. The intersection rule keeps the verified runtime ceiling and supports both provider types. **Roadmap alignment** This change supports the ACP run lifecycle track and the sandbox provider contract work in the current roadmap. **Additional context** The legacy `supportsReusableLeases` field remains supported. The nested capability validator rejects unknown keys. Missing or unavailable verification resolves all capabilities to `false`. ## What Changed - Add strict `sandboxCapabilities` manifest validation with legacy reusable-lease compatibility. - Carry declarations through the ready-driver projection. - Add fail-closed effective resolution from verified, declared, and narrowed capabilities. - Add narrowing for provider configuration, Kubernetes Job leases, and Daytona sessions. - Add a frozen read-only capability snapshot to execution targets. - Add focused tests and keep existing characterization baselines covered. - Add and update sandbox provider capability documentation. ## Verification - `npx vitest run packages/shared/src/validators/plugin.test.ts` - `npx vitest run server/src/__tests__/plugin-environment-driver-sandbox-capabilities.test.ts` - `npx vitest run server/src/__tests__/sandbox-capability-contract.test.ts` - `npx vitest run server/src/__tests__/environment-execution-target-capabilities.test.ts` - `npx vitest run packages/adapter-utils/src/acpx-engine/startup-characterization.test.ts packages/adapter-utils/src/acpx-engine/turn-characterization.test.ts packages/adapter-utils/src/acpx-engine/settlement-characterization.test.ts packages/adapter-utils/src/acpx-engine/composed-run-characterization.test.ts` - Package typechecks for shared, server, and adapter-utils pass. - Stage-2 security review suites pass with 28 tests. ## Risks The resolver fails closed when verification is absent or unavailable. Providers that rely on undeclared capabilities may see narrower behavior until they expose verified worker methods. The change does not alter the existing native-sync guard. ## Model Used OpenAI Codex, GPT-5, exact runtime model ID `gpt-5`, tool use and code execution. The implementation author used this model to assist with the change. ## 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> |
||
|
|
1a17cbf232 |
fix(runtime-exposure): mediate leased app/HMR port pairs centrally (#11526)
<!-- Simplified Technical English (ASD-STE100). --> > **Stacked pull request.** This targets #11525, which targets #11524. Merge those first. Review only the last commit, `fix(runtime-exposure): mediate leased app/HMR port pairs centrally`. ## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Paperclip starts managed runtime services for execution workspaces, and #11524 and #11525 make those services reachable over Tailscale HTTPS on a loopback port pair > - An HTTPS lane is only safe if one execution workspace holds its port pair exclusively for the whole life of the lane > - A managed start reused a pair that a stopped but still leased workspace owned. Paperclip reported that workspace stopped and its exposure removed, while the host listeners and the Serve mappings for those ports were live and belonged to an unrelated workspace > - The cause is that ownership was decided in more than one place, and no single place saw persisted reservations, live listeners, and Serve mappings together > - This pull request adds one mediator that owns the decision, and makes every mismatch fail closed while naming the conflicting workspace > - The benefit is that a later start cannot collide with, adopt, or interfere with another issue's service, and cannot produce security evidence attributed to the wrong workspace ## Linked Issues or Issue Description No public GitHub issue exists. The change follows the bug report template. **What happened** A managed HTTPS start reused the loopback port pair of a stopped but still exclusively leased execution workspace. The ports were then held by an unrelated workspace. Paperclip continued to report the first workspace's runtime as stopped and its exposure as removed, while the host listeners and the `tailscale serve` mappings for those exact ports were live and owned by the other workspace. **Expected behavior** An active execution-workspace lease reserves its app and HMR pair until the lease is explicitly released or torn down. A start that finds the pair held by a different workspace fails closed and names the conflict. Paperclip never adopts a process or a Serve mapping across execution-workspace ids. **Root cause** Three separate readers each had an incomplete view: - `deprovisionExposure` replaces the exposure status with a fresh `removed` status whose `listeners` array is empty. A later reader asking "which ports did this row own?" gets no answer, so a stopped row's pair looked free even while the row was leased. - Startup reconciliation adopted a persisted service by `row.port` alone, then terminated the local service when its health check failed. Under the `project_primary` strategy, where workspaces share a working directory, the containment check cannot separate two workspaces, so the sweep could adopt and then kill an unrelated workspace's live service. - Allocation checked live port availability but never checked which pairs active leases still reserve. **Impact** Two workspaces can collide on one lane. A start can adopt or interfere with another issue's service, and evidence about an exposure can be attributed to the wrong workspace. ## What Changed - Add `server/src/services/runtime-exposure/port-reservation.ts`, one mediator that decides allocation and ownership from persisted reservations plus live listener and Serve ownership together. - Reserve a pair for as long as its execution workspace holds an active lease, until the lease is explicitly released or torn down. - Re-derive a row's pair from the `port` column and `deriveViteHmrPort` instead of the status `listeners` array, so a `removed` status no longer hides which ports a leased row still reserves. - Refuse to adopt a process or a Serve mapping across execution-workspace ids. A mismatch fails closed and names the conflicting workspace and issue. - Treat an unattributable holder as a conflict. A Serve mapping that is present but cannot be attributed means the host has something there that could not be named, so it fails closed instead of falling through to "allowed". - Make reconciliation surface a stopped or removed row whose reserved ports are live or mapped by another workspace, instead of reporting success. - Leave manual and unknown Serve mappings alone on release and teardown. ## Verification - `npx vitest run --root server src/services/runtime-exposure/ src/__tests__/workspace-runtime-exposure-reservation.test.ts src/services/workspace-runtime-exposure-backfill.test.ts` — 8 files, **112 tests pass**. - `npx tsc --noEmit -p server/tsconfig.json` — **0 errors** with `@paperclipai/plugin-sdk` built. - `pnpm --filter @paperclipai/db typecheck` — migration numbering and safety checks pass. - `pnpm --filter @paperclipai/tailscale-https-broker test` — 87 tests pass. The five required regressions are covered by `workspace-runtime-exposure-reservation.test.ts` and `port-reservation.test.ts`: 1. Reuse of a stopped-but-leased pair is denied. 2. Cross-execution-workspace process adoption is denied. 3. A Serve mapping ownership mismatch is visible and fails closed. 4. Concurrent allocators return unique pairs. 5. Release and teardown make the pair reusable without harming manual or unknown mappings. Note for reviewers: `server/src/services/workspace-runtime-exposure.test.ts` fails on a development host that already runs an HTTPS canary holding ports 42000, 42001, 52000, and 52001, because that fixture stubs port availability and then allocates into the occupied range. It is unaffected by this change and is expected to pass in CI, where no such listener exists. Please read the CI result rather than a local run on an exposing host. ## Risks - The mediator is now the single decision point for allocation and adoption, so a defect in it affects every managed start. This is deliberate: the incident happened because the decision was spread across three readers, and concentrating it is the fix. - Behavior becomes stricter. A start that previously reused a pair now fails closed with a named conflict. This is the intended change, and it can surface pre-existing collisions that used to pass silently. - The remediation path does not stop an unrelated service that already holds a pair. It reports the conflict instead, so it cannot disturb another issue's running lane. - No migration runs in this pull request. > For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and discuss it in `#dev` before opening the PR. ## Model Used Claude Opus 5 (`claude-opus-5`), 1M context window, extended thinking, with 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 |
||
|
|
4c349fe6b7 |
feat(runtime): managed Tailscale HTTPS lifecycle, durable runtime leases, and bounded control recovery (#11525)
<!-- Simplified Technical English (ASD-STE100). --> > **Stacked pull request.** This targets #11524. Merge #11524 first. Review only the second commit, `feat(runtime): managed Tailscale HTTPS lifecycle...`. ## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Paperclip starts and supervises managed runtime services, so an agent's branch can be previewed while the agent works > - The previous pull request added the host broker, the shared contract, and the database columns, but no code used them > - A managed runtime can only be exposed over HTTPS if it holds a stable loopback port pair for the whole life of the service. The current control path cannot promise this: two controls can race the same execution workspace, a stranded control can stay `running` forever, and a start can adopt a port it does not own > - This pull request adds the HTTPS lifecycle and the control-path hardening that the lifecycle depends on > - The benefit is that a managed preview becomes reachable from another device, and a managed control now always reaches a terminal state ## Linked Issues or Issue Description No public GitHub issue exists. The change follows the feature request template. **Subsystem affected** Managed workspace runtime services, workspace operations, the execution workspace routes, and the workspace runtime UI. **Problem or motivation** A managed runtime service is reachable only on loopback, so a preview cannot be opened from a phone or a second computer. Exposing it safely needs an exclusively held port pair. Three existing gaps block that. Overlapping controls can race the same workspace. A control whose owner dies stays `running` and blocks the lane forever. Port allocation does not confirm that the process holding a port is the process Paperclip spawned. **Proposed solution** Add the exposure lifecycle on top of the broker from #11524: reserve before spawn, expose after readiness, validate the public URL, and remove on stop. In the same change, make managed controls mutually exclusive per workspace, give each control a durable issue-owned lease and a terminal state, and verify port ownership before use. **Alternatives considered** - Add HTTPS exposure without the control hardening. This was rejected because a raced or stranded control makes exposure point at the wrong process. - Guard the lane with an in-memory lock only. This was rejected because the lock does not survive a server restart, so the lane can be lost or double-claimed. - Trust the requested bind address. This was rejected because a checkout that predates managed HTTPS overwrites `PAPERCLIP_BIND` from its own `--bind` argument, and then binds the wildcard address. **Roadmap alignment** This completes the managed workspace runtime capability that already exists. It adds no new product surface beyond the HTTPS link. **Additional context** This is the second of three pull requests. The third adds central mediation of leased port pairs. ## What Changed Exposure lifecycle: - Add the server-side broker client and the exposure lifecycle manager. The manager reserves the mapping before spawn, exposes after backend readiness, validates the public URL, and removes the mapping on stop. - Default managed worktree runtimes to `tailscale_https`, read exposure intent from legacy `expose` blocks, and backfill runtimes that are still HTTP-only. - Verify listener ownership for the app port and its Vite HMR companion before the broker is asked to expose anything. An unrelated listener on either port fails the start closed. - Force the loopback bind through argv instead of environment hints. Leave a non-Paperclip service's `--bind` argument alone. - Probe loopback for readiness instead of the public URL, and give Vite HMR its own loopback-bound server in middleware mode. - Preserve operator-declared Serve mappings across the managed lifecycle, so cleanup never removes a mapping that Paperclip did not create. - Name which listener predicate denied an expose, so an operator can act on the message. Control-path hardening: - Make `start`, `stop`, `restart`, and job `run` mutually exclusive per execution workspace. An overlap gets `409 workspace_runtime_control_in_progress`, and authorization is still checked first. - Take a durable exclusivity lease on the execution workspace, owned by the controlling issue. A different issue gets `409 workspace_runtime_lease_conflict` before any operation is recorded. Board and operator actions bypass the lease. - Give every control a terminal state. Each control stamps its owning process and pid, heartbeats while it runs, and has a wall-clock ceiling. Recovery of a stranded control uses a compare-and-swap on `updated_at`, so a live owner is never stolen. - Bound readiness probes, verify allocated port ownership on POSIX and Windows, harden sibling port allocation, and reconcile desired runtimes on server startup. - Surface exposure state and bounded runtime errors in the workspace runtime UI. - Record the new behavior in `doc/DEVELOPING.md`. ## Verification Focused checks, all run on this branch: - `npx tsc --noEmit -p server/tsconfig.json` — 139 errors, exactly the count on `master`. All 139 come from the unbuilt `@paperclipai/plugin-sdk` package. - `pnpm --filter @paperclipai/ui typecheck` — clean. - Server suites, 177 tests pass across 9 files: `workspace-runtime.test.ts`, `workspace-runtime-leases.test.ts`, `workspace-runtime-control-recovery.test.ts`, `execution-workspace-runtime-control-conflict.test.ts`, `execution-workspace-runtime-lease-route.test.ts`, `workspace-operations-reconciliation.test.ts`, `workspace-runtime-start-terminality.test.ts`, `app-hmr-port.test.ts`, and `workspace-runtime-ready-comment.test.ts`. - Exposure unit suites, 77 tests pass: `src/services/runtime-exposure/` and `workspace-runtime-exposure-backfill.test.ts`. - UI: `WorkspaceRuntimeControls.test.tsx` and `WorkspaceServiceControlBar.test.tsx` — 34 tests pass. **One suite is red on the development host and is expected to be green in CI.** `server/src/services/workspace-runtime-exposure.test.ts` has 10 failures on the machine used to write this branch. The cause is host contamination, not the code. That machine already runs an HTTPS canary that holds ports 42000, 42001, 52000, and 52001 on a tailnet address. The suite allocates from the same range, so the new listener-ownership check correctly reports: ``` listener_ownership_mismatch — port 42000 is bound to 100.123.243.20, 127.0.0.1, fd7a:115c:a1e0:0:0:0:dd3a:f314 ... instead of loopback only ``` A CI runner has no listener on those ports, so the check sees loopback only and the suite passes. Please confirm this from the CI result on this pull request rather than from a local run on a host that already exposes a managed runtime. This is a real weakness of the current test fixture, and the third pull request in the series removes it by allocating the pair through a central mediator instead of a stubbed availability check. `workspace-runtime-https-live-exercise.test.ts` needs a live `tailscale` host and was not run locally. ## Risks - This is the behavior-bearing pull request of the three, so it carries the most risk. - Two new `409` responses appear on managed control routes. A caller that assumed a control always starts must handle a conflict. Board and operator actions are deliberately exempt, so an agent lease cannot lock an operator out. - Managed worktree runtimes now default to `tailscale_https`. If the host has no working broker, the start fails closed and reports the exposure failure instead of silently serving plain HTTP. This is intended, and it is the reason the failure message names the denying predicate. - Startup reconciliation touches persisted runtime rows. It is scoped to desired state and does not resurrect a service that never came up. - The lease has a 30-minute time to live and explicit release paths, so a crashed owner cannot hold a lane forever. - No migration runs in this pull request. The tables and columns land in #11524. > For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and discuss it in `#dev` before opening the PR. ## Model Used Claude Opus 5 (`claude-opus-5`), 1M context window, extended thinking, with 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, with the one host-contaminated suite explained above - [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 |
||
|
|
f4802b1bbc |
feat(runtime-exposure): least-privilege Tailscale HTTPS broker, shared contract, and persisted exposure state (#11524)
<!-- Simplified Technical English (ASD-STE100). --> ## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Paperclip starts and supervises managed runtime services for a project's execution workspaces, so an agent's branch can be previewed while it works > - Those services only listen on plain loopback HTTP. A person on another device, or on a phone, cannot open the preview > - A Tailscale HTTPS mapping solves this, but `tailscale serve` needs host privileges that the Paperclip server process must not hold > - This pull request adds the foundation only: a separate least-privilege host broker, the shared exposure contract, and the database columns that hold exposure state > - Nothing calls the broker yet, so there is no behavior change. The benefit is that the privileged surface is small, reviewable, and isolated before any lifecycle code depends on it ## Linked Issues or Issue Description No public GitHub issue exists. The change follows the feature request template. **Subsystem affected** Managed workspace runtime services, the shared type and validator package, and the database schema. **Problem or motivation** A managed runtime service binds to loopback only. There is no supported way to reach that preview from another device. Adding HTTPS directly to the server would mean the server process runs `tailscale serve`, which needs privileges far wider than the task requires. A compromised or buggy server could then map any port to the tailnet. **Proposed solution** Split the privileged work into a separate broker process with a narrow protocol, and define one shared contract that the server, the UI, the runtime, and the broker all read. Land this foundation first, with no caller, so the privileged code can be reviewed on its own. **Alternatives considered** - Call `tailscale serve` from the server process. This was rejected because it gives the server unrestricted mapping authority. - Use `sudo` for single `tailscale` commands. This was rejected because the argument list is the only guard, and it is easy to widen by accident. - Use a generic reverse proxy. This was rejected because it does not remove the need for a privileged Tailscale mapping step. **Roadmap alignment** This supports the existing managed workspace runtime capability. It adds no new product surface on its own. **Additional context** The broker is the security boundary of the feature, so it is deliberately the first slice. Three later pull requests build on it: the server exposure lifecycle, the runtime lease and recovery integration, and the leased-port mediator. ## What Changed - Add the `@paperclipai/tailscale-https-broker` workspace package. The broker listens on a unix socket, authorizes each peer with `SO_PEERCRED`, and answers a small request protocol. - Restrict what the broker will map. It accepts only same-number HTTPS-to-loopback pairs inside the Paperclip port range, refuses protected ports, and confirms that the loopback port belongs to a Paperclip-owned listener. - Parse every request with a strict JSON reader that rejects duplicate keys, prototype keys, and unknown fields. - Write an append-only audit record for each broker decision. - Add the shared exposure contract in `@paperclipai/shared`: the `RuntimeExposureConfig`, `RuntimeExposureState`, and `RuntimeExposureStatus` types, their zod validators, the app and HMR port rules, and the loopback-bind helpers. - Persist exposure state on `workspace_runtime_services` with the new `exposure` column, plus the server-private `exposure_handle` and `backend_url` columns that are never serialized to API clients. - Add the `execution_workspace_runtime_leases` table that the later lease slice uses. - Extend the runtime read-model test fixture for the three new columns. ## Verification Focused checks, all run on this branch: - `pnpm --filter @paperclipai/tailscale-https-broker test` — 12 files, 82 tests pass. This covers peer credentials, port policy, protected ports, the serve config writer, the strict JSON reader, argv parsing, and the socket server. - `pnpm --filter @paperclipai/tailscale-https-broker typecheck` — clean. - `npx vitest run --root packages/shared src/runtime-exposure src/validators/runtime-exposure.test.ts` — 3 files, 40 tests pass. - `pnpm --filter @paperclipai/db typecheck` — runs `check:migrations` first. Migration numbering and migration safety both pass. - `pnpm --filter @paperclipai/shared typecheck` — clean. - `pnpm --filter @paperclipai/ui typecheck` — clean. - `npx vitest run --root server src/services/workspace-runtime-read-model.test.ts` — 3 tests pass. - `npx tsc --noEmit -p server/tsconfig.json` — 139 errors, which is exactly the count on `master` before this branch. All 139 come from the unbuilt `@paperclipai/plugin-sdk` package. To confirm the exposure state is inert, start a managed runtime service as usual. The new columns stay null and the service behaves as it does today. ## Risks - Migration risk is low. Both migrations only add a table and three nullable columns. No column is backfilled and no existing column changes. The migration safety check passes. - Behavior risk is low. No code path calls the broker in this pull request, and the shared exposure fields are optional. - The broker is privileged, so it is the real risk surface. It is mitigated by peer-credential authorization, a fixed port range, a protected-port deny list, same-number pair enforcement, listener-ownership checks, strict JSON parsing, and an audit trail. Reviewers should read `packages/tailscale-https-broker/src/authorization.ts` and `src/port-policy.ts` closely. - The broker requires a `tailscale` version floor, which its README records. An older host CLI makes the broker refuse to start rather than map incorrectly. - `pnpm-lock.yaml` changes because a new workspace package is added. The diff is the new importer block, plus one duplicate `tinyexec` entry that pnpm removed. > For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and discuss it in `#dev` before opening the PR. ## Model Used Claude Opus 5 (`claude-opus-5`), 1M context window, extended thinking, with 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 |
||
|
|
10d0555189 |
fix(interactions): authorize resolvers consistently (#11376)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Issue interactions give agents and people a structured decision record. > - Resolver routes used different authorization rules. > - Some routes blocked valid agents, including task watchdogs with normal issue access. > - The API did not show who could resolve a pending interaction. > - This pull request gives every interaction kind one resolver policy evaluator. > - The benefit is a clear decision path with consistent governance and company isolation. ## Linked Issues or Issue Description Fixes: #8087 Refs: #7403 Related PR: #11082 proposes board-only confirmation rules. This change keeps human-only review as an explicit policy. **What happened?** Agents could create issue interactions. Some resolver routes still required board access. This left valid agent confirmations pending. Task watchdogs could see the same problem without board identity. **Expected behavior** Every interaction kind must use one resolver policy contract. The contract must support `anyone`, `not_creator`, and `human_only`. It must also apply all normal governance controls. **Steps to reproduce** 1. Create a `request_confirmation` interaction as an agent. 2. Resolve it with another authorized agent. 3. Observe the board-only denial. **Paperclip version or commit** The problem exists on `master` before this change. **Deployment mode** Local development with `pnpm dev`. ## What Changed - Add canonical policies for `anyone`, `not_creator`, and `human_only`. - Use one server evaluator for every interaction kind. - Apply named addressees, company limits, review rules, and task watchdog scope. - Charge cross-issue resolutions to the existing per-run action limit. - Return the effective resolver audience in attention and interaction data. - Show the audience, governance choices, and denial reasons in the board UI. - Add telemetry, API documents, product documents, and regression fixtures. - Add migration provenance for safe legacy behavior. - Make migration `0218` safe for complete replays and partial prior runs. ## Product Rules - An interaction records a response. It does not grant authority for the next action. - `anyone` lets any authorized issue participant respond. - `not_creator` requires a responder other than the interaction creator. - `human_only` requires an authorized person. - A named addressee, company policy, or governed action can narrow the audience. - These controls cannot widen the audience. - A task watchdog uses the same rules as an ordinary agent. - A task watchdog does not receive board authority. - An agent resolution on another issue uses the shared cross-issue action limit. - Legacy pending interactions keep their earlier restrictions. - The UI shows the effective audience and a permanent denial reason. ## Verification - `pnpm --filter @paperclipai/db check:migrations` - `pnpm --filter @paperclipai/db typecheck` - `pnpm exec vitest run packages/db/src/issue-thread-interaction-resolver-policy-migration.test.ts` - The focused PostgreSQL test applies migration `0218` twice. - The test also completes a partial prior run and preserves existing provenance. - The latest GitHub head has 29 successful checks. - The opt-in Storybook visual check skipped as expected. - Greptile reports 5/5 with no open comments. ## Risks - New interaction writes use `anyone` by default. - Callers must select `not_creator` or `human_only` when they need stricter review. - Legacy pending interactions keep the old creator and human restrictions. - Migration `0218` fills only missing provenance fields during recovery. - Cross-issue resolutions can reach the existing action limit. - The shared evaluator affects every interaction kind. - Route, service, database, shared contract, and UI tests cover these rules. > This work matches the Agent Reviews and Approvals direction in `ROADMAP.md`. It does not duplicate a planned item. ## Model Used OpenAI Codex, GPT-5. The runtime does not expose the exact deployment ID or context window. The agent used reasoning, repository tools, shell 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 linked public issues or described the issue with the required labels - [x] I have not referenced internal Paperclip issues or links - [x] My branch name describes the change and contains no internal ticket id - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation - [x] I have considered and documented the risks - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open comments - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
9e9f744f58 |
Show blocker links in the task chat (#11456)
<!-- Write all pull request text in Simplified Technical English (ASD-STE100): short sentences, one instruction per sentence, simple approved vocabulary, and the active voice. --> ## Thinking Path > - Paperclip helps operators supervise agent work through tasks and task threads. > - The redesigned task thread shows the current work and its state. > - A blocked task did not show the dependency that prevented progress. > - Operators had to leave the thread to find the direct and final blockers. > - This pull request adds compact blocker links at the top and bottom of the task thread. > - The benefit is that operators can identify and open the relevant tasks without adding a large notice to the thread. ## Linked Issues or Issue Description **What existing behavior does this improve?** The redesigned task thread did not show which task directly blocked the current task or which task ultimately blocked its dependency chain. **Subsystem affected** `server/`, `packages/shared/`, and `ui/` task-blocker presentation. **Current behavior** A blocked task can open in the redesigned thread without a visible dependency link at the top or bottom of the conversation. **Proposed behavior** Show one compact amber row for the direct blocker. Show a second row for the selected final blocker when one exists. Render the rows at both ends of the thread. **Reason and benefit** Operators can see the reason for the blocked state and open the relevant task from the conversation. The compact rows preserve thread density. **Breaking changes** None. The new blocker-attention fields are optional. Existing clients remain compatible. ## What Changed - Added a compact task-chat component for direct and selected final blocker links. - Added the blocker rows to the top and bottom of populated and empty task threads. - Added link-ready blocker-attention details so an intermediate selected task stays on its correct direct chain. - Included blocker-link changes in the thread content key so pinned threads follow a newly added bottom row. - Added component, scrolling, server contract, and Storybook coverage for the new states. ## Verification - `pnpm exec vitest run ui/src/components/TaskChatThread.test.tsx server/src/__tests__/issue-blocker-attention.test.ts` (38 tests passed) - `pnpm --filter @paperclipai/shared typecheck` - `pnpm --filter @paperclipai/server typecheck` - `pnpm --filter @paperclipai/ui typecheck` - `pnpm check:token-gates` ## Risks - Low risk. The rows only render while the task status is `blocked` and an unresolved blocker is available. - Long titles are truncated to keep each blocker on one line. The full task label remains available in the link title. - Older server payloads keep the original leaf-selection behavior because the new sampled details are optional. > 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 with GPT-5. The run used tool-enabled reasoning and code execution. The context-window size was not exposed to the run. ## 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> |
||
|
|
cd501499a2 |
test: add ACPX run lifecycle characterization baselines (#11461)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - The adapter runtime starts, turns, settles, and composes ACPX runs > - Recent lifecycle corrections changed several order and cleanup rules > - Those rules need regression coverage before the planned engine refactor > - This pull request adds characterization suites for the corrected behavior > - The benefit is a clear test baseline for the next refactor ## Linked Issues or Issue Description **What existing behavior does this improve?** The ACPX adapter runtime and server heartbeat lifecycle need stable regression coverage for their current corrected behavior. **Subsystem affected** Cross-cutting (multiple of the above): `packages/adapter-utils` and `server` test suites. **Current behavior** The runtime has corrected rules for startup, turns, settlement, composed results, and heartbeat terminalization. The repository lacks a single characterization baseline for these rules. **Proposed behavior** Keep the current lifecycle rules pinned by five test suites. Let the later engine refactor change behavior only when it updates these tests with a clear reason. **Reason and benefit** The suites expose order, cleanup, transport, timeout, retry, result, and lease-release changes during the refactor. They also record one known latent defect as current behavior. **Breaking changes** None. This pull request adds tests only. ## What Changed - Add startup characterization coverage for commands, launch values, session fingerprints, sync order, bridge overlap, and cleanup paths. - Add turn characterization coverage for inputs, events, transports, timeout and cancel behavior, retry rules, errors, and usage. - Add settlement characterization coverage for teardown, adapter sync-back, workspace restore order, native sync, and error policy. - Add composed-run characterization coverage for result forms, finalization sets, and host-lane warm save and warm hit behavior. - Add server coverage that checks run terminalization before environment lease release. ## Verification - Run `npx vitest run packages/adapter-utils/src/acpx-engine/startup-characterization.test.ts packages/adapter-utils/src/acpx-engine/turn-characterization.test.ts packages/adapter-utils/src/acpx-engine/settlement-characterization.test.ts packages/adapter-utils/src/acpx-engine/composed-run-characterization.test.ts packages/adapter-utils/src/acpx-engine/execute.test.ts`. - Run `npx vitest run server/src/__tests__/heartbeat-run-terminalize-before-release.test.ts`. - The adapter-utils run passes 178 tests, and the server run passes 4 tests. - Check `pnpm --filter @paperclipai/adapter-utils typecheck`. - Check `pnpm --filter @paperclipai/server typecheck`. ## Risks Low risk. The change adds test files and does not change production code. One known cold ensure-session cleanup defect remains pinned as current behavior. ## Model Used OpenAI Codex, GPT-5, with 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 - [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> |
||
|
|
e52b8a343f |
fix: ACP run lifecycle corrections — failure settlement, workspace sync-back, lease cleanup (#11454)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Agent adapters run ACP sessions and manage runtime, workspace, and lease resources. > - Several failure paths left runtime bridges, staged workspaces, or environment leases active after an error. > - These leaks reduce run reliability and can leave later runs without clean resources. > - This pull request closes the failure paths, applies one teardown policy, and adds regression tests. > - The benefit is consistent failure settlement and safer reuse of agent workspaces and leases. ## Linked Issues or Issue Description **What happened?** ACP runs could leave runtime bridges, staged workspaces, or environment leases active after failures. Claude and Gemini ACP runs did not restore the sandbox workspace on teardown. Lease release stopped when one lease returned an error. **Expected behavior** Each ACP failure must return an error result and settle its resources. Teardown must run each step, release leases independently, and restore the host workspace when the sandbox ends. Pending cleanup leases must receive bounded retry attempts. **Steps to reproduce** 1. Run an ACP session that fails after runtime creation or during turn preparation. 2. Run an ACP session that fails during a warm hit or staged runtime handoff. 3. Run lease cleanup with more than one lease when the first release returns an error. 4. Inspect the result phase, teardown calls, workspace state, and lease metadata. 5. Run the regression suites listed in the Verification section. ## What Changed - Settle every ACP failure after runtime creation with an error result and one sandbox.startup span closure. - Close the ACP runtime and remove warm entries after every pre-turn failure. - Run all teardown steps, record teardown errors, release staging leases in finally, and prevent duplicate teardown. - Dispose staged runtimes after seam failures and remove borrowed staged entries with identity guards. - Add fail-open workspace sync-back teardown for Claude and Gemini ACP adapters. - Isolate lease release errors and add bounded retry sweeps for stranded pending_cleanup leases. - Atomically claim pending_cleanup retries and clamp attempt readers to keep the five-attempt bound. - Default absent provider reusableLeases values to false and align the fake provider with its runtime declaration. - Add regression tests for engine, adapter, server, and shared environment behavior. ## Verification - [x] `npx vitest run packages/adapter-utils/src/acpx-engine/execute.test.ts` — 124 tests passed. - [x] `npx vitest run packages/adapters/codex-local/src/server/acp.test.ts packages/adapters/claude-local/src/server/acp.test.ts packages/adapters/gemini-local/src/server/acp.test.ts` — 61 tests passed. - [x] `npx vitest run server/src/__tests__/environment-runtime.test.ts server/src/__tests__/heartbeat-pending-cleanup-sweep.test.ts server/src/__tests__/reusable-leases-default.test.ts server/src/__tests__/environment-routes.test.ts packages/shared/src/environment-support.test.ts` — passed. - [x] All listed suites ran from the repository root. - [x] GitHub CI completed successfully for `cfc349c9f232711433897915112a1c52c0e462ca`. - [x] Greptile completed with a 5/5 confidence score and no blocking finding. ## Risks The engine changes affect failure settlement and teardown order across ACP runs. The server changes add retry state to existing lease metadata without a schema migration. The adapter changes restore workspaces after sandbox execution. Regression tests cover the changed paths. GitHub CI and Greptile passed for the current head. > For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and discuss it in `#dev` before opening the PR. This change fixes runtime reliability and does not duplicate a roadmap feature. ## Model Used OpenAI GPT-5 Codex. The model used tool-based repository inspection, GitHub operations, and code review support. The runtime does not expose a context-window value. ## 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 (for example, `docs/...` or `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> |
||
|
|
bc9f70f54c |
fix(plugin-daytona): bound the sandbox liveness calls with a per-call timeout (#11408)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Sandbox provider plugins run agent work in remote execution environments > - The Daytona sandbox liveness read can stay pending when the connection stops responding > - A pending read blocks the plugin until a broad host-to-worker limit expires > - This pull request adds bounded deadlines to Daytona liveness calls and clears stale handles > - The benefit is a fast and clear error when a Daytona connection stops responding ## Linked Issues or Issue Description Refs #11341 **What happened?** The Daytona sandbox liveness read had no per-call timeout. A silent connection failure left the read pending until the broad host-to-worker RPC limit expired. **Expected behavior** The plugin should stop a liveness call within a defined limit and report a clear timeout error. **Steps to reproduce** 1. Create a Daytona sandbox handle. 2. Make the cached handle freshness read never resolve. 3. Run the next sandbox operation. 4. Observe that the operation waits for the outer RPC limit without a liveness timeout. **Paperclip version or commit** `master` before this change. **Deployment mode** Any deployment mode that uses the Daytona sandbox provider. ## What Changed - Add `withLivenessTimeout` with timer cleanup and `SandboxLivenessTimeoutError`. - Bound `refreshData` with configurable `livenessTimeoutMs`, which defaults to 30000 milliseconds. - Bound sandbox start and recovery calls with the SDK timeout plus a 5000 millisecond margin. - Reject `livenessTimeoutMs` values above 86400000 milliseconds and document the setting. - Evict a cached handle after a failed freshness refresh so the next operation fetches a new handle. - Add a test for a never-resolving freshness refresh and the cached-handle eviction. ## Verification - Run the Daytona plugin test suite with its package Vitest configuration. - Confirm that 150 of 150 tests pass. - Confirm that the new test reports a bounded timeout and a fresh handle on the next operation. - Confirm that GitHub Actions reports green status checks after the pull request starts. ## Risks This change adds an early timeout only to Daytona liveness calls. A value of 0 or less disables the extra bound. The default leaves normal SDK calls within their expected time limit. The main risk is a timeout value that is too short for a slow but healthy connection. ## Model Used OpenAI Codex, GPT-5. The model used tool calls and code execution. The model supplied the PR handoff and did not author the code in this pull request. ## 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> |
||
|
|
fdb9a4880d |
fix(security): route paperclipai CLI guidance through safe npx form (CWE-78) (#11400)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Paperclip provides CLI commands and guidance for operators and agents > - The `pnpm paperclipai` script can pass argument values through a shell > - Shell re-parsing can execute command substitutions inside quoted values > - This pull request routes guidance through inert-argv `npx paperclipai` commands and adds regression coverage > - The benefit is safer operator guidance across documentation and runtime hints ## Linked Issues or Issue Description This pull request fixes a command-injection-class defect in Paperclip CLI guidance. **What happened?** The `pnpm paperclipai <sub> --flag "$VALUE"` form can re-parse argument values through a shell. A command substitution inside a quoted value can execute on the host. **Expected behavior** Paperclip guidance must pass CLI values as inert argument values. Host-derived values must not appear in copyable commands. **Steps to reproduce** 1. Run a Paperclip guidance command that uses the `pnpm paperclipai` script. 2. Provide a quoted value that contains a command substitution. 3. Observe that the shell can evaluate the substitution before the CLI starts. 4. Compare the result with the `npx paperclipai` form. **Paperclip version or commit** `5670984b75d109950c968542a0111ebb6967f4da` **Deployment mode** All deployment modes that show or use the affected CLI guidance. **Installation method** Built from source and installed CLI guidance. **Agent adapter(s) involved** Not adapter-specific (core bug). **Database mode** Not database-related. **Access context** Both. **Additional context** The earlier merged PR [#11343](https://github.com/paperclipai/paperclip/pull/11343) used the unsafe `pnpm exec paperclipai` form. This fresh PR replaces that guidance with the safe `npx paperclipai` form. ## What Changed - Standardize documentation and runtime hints on `npx paperclipai`. - Remove the broken `pnpm exec paperclipai` guidance. - Use a static `<host>` placeholder in private-hostname guidance. - Add regression tests for unsafe forms, continued lines, static hosts, and offline guidance. ## Verification - `git diff --check origin/master...origin/fix/paperclipai-cli-npx-safe-invocation` passes. - The branch adds `server/src/__tests__/cli-invocation-safety.test.ts` and updates private-hostname tests. - CI must run the new tests, typecheck, lint, and build checks. - Local Vitest execution was not available because this worktree has no installed Vitest binary. ## Risks - The change affects operator and agent documentation text. - The runtime hints now show `<host>` instead of a request-derived host value. - No database schema or migration changes exist. - CI will detect any missed unsafe invocation or type error. ## Model Used OpenAI GPT-5, exact model ID `gpt-5`, with tool use and code-review assistance. The model used repository inspection, Git operations, and PR preparation. ## 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] CI ran the test suites and they pass; local test execution was unavailable in this worktree - [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 addressed all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
ea3a5ea7d2 |
fix(recovery): skip successful-run handoff for recovery-action-driven runs (#9010)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - The recovery subsystem repairs issues stranded without a valid disposition: `decideSuccessfulRunHandoff` queues one corrective wake per successful-but-dispositionless run, and `source_scoped_recovery_action` wakes a recovery owner for stranded issues > - `decideSuccessfulRunHandoff` already refuses to treat corrective handoff runs, issue-monitor runs, and comment-driven wakes as handoff *sources* — but not runs woken by `source_scoped_recovery_action` > - Because the handoff idempotency key includes `sourceRunId`, every succeeding recovery run is a brand-new source: recovery run → handoff wake → corrective run → new recovery action → recovery run → … with `DEFAULT_MAX_SUCCESSFUL_RUN_HANDOFF_ATTEMPTS` never binding (it is per-source-run) and the source-scoped recovery action created with `maxAttempts: null` > - The cycle is unbounded, each leg is a ~15s no-op "succeeded" run, and the designed handoff-exhausted escalation (blocked + exhausted notice) never engages > - This PR adds recovery-action-driven runs to the existing skip list, so recovery runs own their own follow-up path and the stranded-issue escalation remains the exit when the disposition is still missing > - The benefit is that missing-disposition recovery converges (one handoff, then escalation) instead of ping-ponging wake volume unboundedly ## Linked Issues or Issue Description Refs #6523 — same wake-loop family (repeated `source_scoped_recovery_action` wakes); this PR fixes the variant where the loop partner is the successful-run handoff. **Observed behavior:** in a 16-agent deployment, one agent produced 223 runs in 2 hours, every run `succeeded` with ~15s duration, with `contextSnapshot.wakeReason` alternating exactly between `source_scoped_recovery_action` (109) and `finish_successful_run_handoff` (108). The source issue never reached the exhausted escalation. ## What Changed - `server/src/services/recovery/successful-run-handoff.ts`: new `isRecoveryActionDrivenRun` predicate (matches `contextSnapshot.wakeReason === "source_scoped_recovery_action"` or a present `contextSnapshot.recoveryActionId`), consulted in `decideSuccessfulRunHandoff` alongside the existing corrective-handoff / issue-monitor / comment-driven skip guards. - `server/src/services/recovery/successful-run-handoff.test.ts`: cases asserting recovery-driven runs are skipped via both markers. ## Verification - `pnpm -F @paperclipai/server exec vitest run src/services/recovery/successful-run-handoff.test.ts` → 17 passed (16 existing unchanged + 1 new). - Production validation (same logic deployed as a dist patch on 2026.626.0): the alternating recovery/handoff wake pattern stopped after restart; ordinary successful-run handoffs (first corrective wake per genuine source run) continue to queue. ## Risks Low-to-moderate, scoped to one decision function. The behavioral shift: a recovery-action run that succeeds without fixing the disposition no longer gets a corrective handoff wake — instead the stranded-issue detector escalates (blocked + recovery owner + exhausted notice), which per the existing `escalateStrandedAssignedIssue` code is the designed terminal path. Runs not woken by a recovery action are unaffected (covered by the existing 16 tests, all green). ## Model Used Claude Fable 5 (`claude-fable-5`), extended thinking, agentic tool use via Claude Code. Human-reviewed 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 - [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 |
||
|
|
edb8083538 |
fix(server): serialize interaction review verdicts
Lock the issue before accepting or rejecting review confirmations, reauthorize against the current policy, and cover concurrent policy tightening. Co-Authored-By: Codex <noreply@openai.com> |
||
|
|
3526b82e2b |
test(server): expect transactional review transition
Align the watchdog in-review assertion with the atomic update contract. Co-Authored-By: Codex <noreply@openai.com> |
||
|
|
277c13529a |
fix(server): persist review requester atomically
Commit both bound and unbound in-review transition activity in the same transaction as the issue update. Co-Authored-By: Codex <noreply@openai.com> |
||
|
|
3a87b143a2 |
test(server): support locked review policy updates
Keep terminal-update route harnesses aligned with the transactional issue service contract. Co-Authored-By: Codex <noreply@openai.com> |
||
|
|
991f40bb2e |
fix(server): serialize review policy verdict authorization
Recheck terminal verdict and policy mutations under a row lock, and scope interaction verdict enforcement to the review confirmation itself. Co-Authored-By: Codex <noreply@openai.com> |
||
|
|
373b675f94 |
fix(server): prevent review policy verdict downgrade bypass
Authorize verdicts and policy changes against the stored restrictive review policy, remove downgrade guidance, and cover both restrictive policies with route regressions. Co-Authored-By: Paperclip <noreply@paperclip.ing> |
||
|
|
37fde84abd |
fix(server): enforce review policy on interaction verdicts
Co-Authored-By: Paperclip <noreply@paperclip.ing> |
||
|
|
8ee1fb21a6 |
feat(ui): badge the review policy when it constrains approval (#10938)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Agents move their work into review, and a reviewer must then give a verdict on it > - By default anyone with write access can give that verdict, including the agent that did the work > - The server can constrain that default per issue with a `reviewPolicy` column, but no screen showed the value > - A reviewer could therefore press Approve on a review that the server refuses, and get a 403 > - This pull request shows the policy as a badge on the two surfaces where a person gives a verdict > - It also makes an agent verdict read as a verdict in the activity timeline > - The benefit is that a reviewer sees who can approve before they try ## Linked Issues or Issue Description No public GitHub issue exists for this change. The description below follows `.github/ISSUE_TEMPLATE/enhancement.yml`. **What existing behavior does this improve?** The issue review flow. A reviewer cannot see the approval constraint on an issue before they give a verdict. **Subsystem affected** Web UI (`ui/`), with one supporting change in the server attention service. **Current behavior** The server stores an optional approval constraint for each issue in a `reviewPolicy` column. The column has three meaningful states: the default (`NULL` or `anyone`), `not_creator`, and `human_only`. The server enforces the constraint when it receives a verdict. No screen shows the value. Two problems follow: 1. A reviewer presses Approve on a review that the server refuses. The server answers 403, and the reason is not visible on the card. 2. An agent that accepts or rejects a review renders in the activity timeline as the raw action id, for example "issue thread interaction accepted". A person who reads the timeline cannot tell that a verdict was given. **Proposed behavior** Show the constraint as a read-only badge on the two surfaces where a person gives a verdict. Show no pixels for the default state, because the default is what every issue already does. Make an agent verdict read as a verdict in the timeline. Only agents set the column today, so this change adds no control to set it. **Reason and benefit** A reviewer sees the constraint before they act. This prevents the 403, and it removes the need to explain the 403 afterwards. The timeline also becomes complete, because it now shows agent verdicts and human verdicts in the same way. **Breaking changes** None. The change adds a badge and changes copy. It adds no column, no endpoint, and no request. **Additional context** The server-side column and the verdict enforcement landed earlier in #10931. This pull request is the user interface for that column. The default state stays unchanged on screen, so the badge appears on a small number of issues. ## What Changed - **A read-only "Approvals" row** in the issue Execution properties. The row renders *only* for a constrained policy: "Anyone else" (`not_creator`) or "Human only" (`human_only`). A `NULL` or `anyone` column adds no row, so the panel is untouched on the overwhelming majority of issues. - **The same badge on the stalled-review card** in `/decisions`, above the three review verbs. A reviewer now sees the constraint before they press Approve. The condition is the same, so the default card is unchanged. - **Agent verdicts read as verdicts in the activity timeline.** An agent that accepted or rejected a review request previously rendered the raw action id ("issue thread interaction accepted"). It now reads "approved the request". A stalled-review decision names the verb that the actor chose. - **A cleared policy reports as "anyone", not "none",** in the field-change receipt. The `reviewPolicy` column is nullable by default, so an absent value is a real setting rather than a missing one. - **All copy comes from `ui/src/lib/review-policy.ts`.** Its badge lookup returns `null` for the default. This makes "no pixels for the default" one enforced decision instead of a condition repeated at each call site. It also keeps the badge, the activity line, and the receipt reading alike. - **The server attention service carries the policy** on the review attention subject, so the stalled-review card can read it. ## Verification Automated tests: - `ui/src/lib/review-policy.test.ts` — the default returns no badge, however the column spells it (`null`, `undefined`, `"anyone"`). An unrecognised policy from the wire shows nothing rather than leaking an enum value. - `ui/src/components/AttentionQueueRow.test.tsx` — no badge on the default card, and the verbs still render. Suppression of the badge must not suppress the card. - `ui/src/components/IssueProperties.test.tsx` — no Approvals row on the default. The constrained row contains no `button`, so nothing there can PATCH. - `server/src/__tests__/attention-service.test.ts` — the review attention subject carries the policy, and subjects built from narrower selects do not claim one. Run them with: ```sh pnpm vitest run ui/src/lib/review-policy.test.ts \ ui/src/components/AttentionQueueRow.test.tsx \ ui/src/components/IssueProperties.test.tsx \ server/src/__tests__/attention-service.test.ts ``` Manual steps: 1. Open an issue that has no `reviewPolicy`. Confirm that the Execution properties panel shows no Approvals row. 2. Set the column to `not_creator`. Reload the issue. Confirm that the Approvals row reads "Anyone else", and that the row has no control. 3. Move that issue into review. Open `/decisions`. Confirm that the stalled review card shows the same badge above the review verbs. 4. Let an agent approve the review. Confirm that the activity timeline reads "approved the request" and not "issue thread interaction accepted". Screenshots were captured at 1440x900 and 390x844, in light mode and dark mode, with the three policy states side by side. The leftmost column in each capture is the default. It carries no badge and no extra row. ## Risks Low risk. - The change is additive on screen. Every new surface is behind a constrained policy, so the default path renders exactly as before. - The badge is read-only. It has no control and sends no request, and a test asserts that the row contains no `button`. - An unknown policy value from the wire renders nothing. It does not render the raw enum. - No migration, no schema change, and no endpoint change. ## Model Used Claude Opus 5 (Anthropic), model id `claude-opus-5[1m]`, 1M context window, with extended thinking and tool use enabled. Used through Claude Code for the implementation, the tests, and this description. ## 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: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
69027cbaae |
fix(workspaces): reopen archived git worktree for managed_checkout projects (#11395)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Execution workspaces give agent tasks isolated Git worktrees > - Archived isolated workspaces must reopen against a live project checkout > - A managed_checkout project has no project workspace directory in its row > - The reopen path used the removed archived worktree as the Git working directory > - This pull request resolves the live managed checkout and reports a clear error when it is unavailable > - The benefit is reliable workspace reopen behavior after archive cleanup ## Linked Issues or Issue Description Related public pull request: [#6164](https://github.com/paperclipai/paperclip/pull/6164) clears archive state during un-archive. This pull request fixes the separate reopen failure that occurs after archive cleanup. **What happened?** An archived isolated `git_worktree` workspace under a `managed_checkout` project failed to reopen after cleanup. The route attempted to run Git in the removed archived worktree and returned a generic service error. **Expected behavior** The reopen path should use the live managed checkout as the Git base directory and should return a clear error when that directory is unavailable. **Steps to reproduce** 1. Create a project with `managed_checkout` source control. 2. Create and archive an isolated `git_worktree` execution workspace. 3. Let archive cleanup remove the worktree. 4. Reopen the workspace for an issue. **Paperclip version or commit** `cab0c31dc61310106caef42ca244e9f7b0f19460` **Deployment mode** Local dev with the default embedded database. **Agent adapter(s) involved** Not adapter-specific. This issue affects core workspace handling. ## What Changed - Resolve the live managed checkout when a managed project reopens an archived Git worktree. - Keep local-folder projects on their project workspace directory. - Validate the Git base directory before `git rev-parse` and return a scrubbed error. - Add nine regression tests for workspace reopen behavior. ## Verification - `server` TypeScript check passes with `tsc --noEmit`. - `server/src/__tests__/execution-workspace-reopen.test.ts` passes with 9 tests. - GitHub Actions must pass all required PR checks. ## Risks Low risk. The change affects only archived isolated workspace reopen behavior. It reuses the existing managed checkout and Git authentication helpers. It adds no new credential path, endpoint, or telemetry. ## Model Used OpenAI GPT-5 assisted with review and GitHub operations. The implementation author supplied the code and test results. ## 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> |
||
|
|
a53cc8819b |
fix(claude-local): pipe print prompt via stdin (#9500)
Fixes #2444. Refs #4947. The `claude_local` adapter launched Claude Code as `claude --print - --output-format stream-json --verbose`. Paperclip writes the rendered task prompt to Claude's stdin, but current Claude Code releases can treat the stale `-` positional marker as the prompt itself, so Claude received the literal string `"-"` instead of the issue body. The customer's task ran against no content at all. The fix keeps `--print` mode and stdin delivery, and removes the stale `-`. Adds regression coverage on both sides of the delivery path: a `claude_local` assertion that `--print` is present, `"-"` is absent and the prompt still reaches stdin, and an adapter-utils case proving the sandbox run-log command wrapper preserves stdin while streaming logs. Authored by @elJayAdvisor, whose commit is included unchanged with their authorship. The branch had gone stale and was showing CONFLICTING; the conflict was in `execution-target-sandbox.test.ts`, where their new test was added at the same point as master's `creates the process session directories only in the launch exec` case and git interleaved the two into one hunk. Resolved by taking master's file and re-inserting their test whole, after checking every helper it needs still exists there. Verified: the bug was still live on master at `execute.ts:838`; the regression test genuinely catches it — restoring the stale `-` fails `expect(captured.argv).not.toContain("-")`; `@paperclipai/adapter-claude-local` and `@paperclipai/adapter-utils` typecheck clean; 67 pass across the two test files. All CI gates green; Greptile 5/5. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
5ca7b4c1fe |
fix(security): standardize paperclipai CLI guidance on safe npx path (#11343)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Paperclip provides CLI guidance to agents and operators through documentation and runtime messages. > - Content-bearing `pnpm paperclipai` examples send arguments through a shell. > - Shell evaluation can execute command substitutions in untrusted argument content. > - Runtime hostname guidance can also place request-derived content inside a shell command. > - This pull request uses `npx paperclipai` for content-bearing guidance and uses a static hostname placeholder. > - The benefit is safer copy-paste guidance for agents and operators. ## Linked Issues or Issue Description **Issue type** Incorrect information **Where is the issue?** CLI guidance in `doc/CLI.md`, `skills/paperclip/SKILL.md`, documentation, and runtime-generated hints. **What's wrong?** Content-bearing `pnpm paperclipai` commands can pass argument text through `/bin/sh`. Shell command substitution in an argument can execute before the CLI receives the value. **Suggested fix** Use `npx paperclipai` for content-bearing commands. Use a static `<host>` placeholder when runtime guidance displays the allowed-hostname command. ## What Changed - Replace content-bearing `pnpm paperclipai` examples with `npx paperclipai` across the documentation and agent-facing guidance. - Update runtime-generated CLI hints to use a static `<host>` placeholder. - Add safety notes to `doc/CLI.md` and `skills/paperclip/SKILL.md`. - Add scans and regression tests for unsafe invocation and hostile hostname headers. - Keep fixed lifecycle commands and `pnpm --filter @paperclipai/*` build commands unchanged. ## Verification - Run `tsc --noEmit` for the changed server files. - Run `cli-invocation-safety.test.ts`. - Run `private-hostname-guard.test.ts`. - Confirm that hostile hostname headers do not enter shown shell commands. - Confirm that the three commits contain the required Paperclip co-author trailer. ## Risks - This change updates documentation and diagnostic text across many surfaces. - Fixed lifecycle and setup commands remain unchanged. - The tests fail if content-bearing `pnpm paperclipai` guidance returns. - The change does not alter the CLI argument parser. ## Model Used OpenAI Codex, GPT-5, tool use, code execution, and repository review assistance. ## 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> |
||
|
|
05d58cd884 |
fix(tool-gateway): keep unsigned ask-first requests out of the review queue without cancelling them (#11338)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - The tool gateway creates approval requests and the review queue reads them > - The gateway creates a request row before it adds the signature > - A review-queue read can see the row during that short unsigned state > - The old read path cancels the unsigned row, so approval returns `409 action_not_pending` > - This pull request hides unsigned in-flight rows and keeps them pending until signing finishes > - The benefit is that approval succeeds while invalid signed requests remain cancelled ## Linked Issues or Issue Description **What happened?** A review-queue read cancelled a pending tool action request when the request had no signature yet. The next approval call returned `409 action_not_pending`. **Expected behavior** The review queue must hide an unsigned in-flight request and keep its state as `pending`. A request with an invalid signature must remain cancelled. **Steps to reproduce** 1. Create a require-approval tool action request. 2. Read the review queue while the request signature is still null. 3. Approve the request after the creator adds the signature. 4. Observe that the old code cancels the request and the approval call fails. **Paperclip version or commit** Commit `720aa0a494bbaa1711bc7a3d795f810765915bfe`. **Deployment mode** Local dev with the embedded PGlite database. **Installation method** Built from source with pnpm. **Agent adapter(s) involved** Not adapter-specific. This is a core tool access service bug. **Database mode** Embedded PGlite. **Access context** Board and agent tool approval flow. ## What Changed - Keep a pending request with a null signature out of `listActionRequests` results. - Cancel a request when its non-null signature fails verification. - Add a permanent regression test for the unsigned request transition. - Update the contract test for unsigned and invalid-signature requests. ## Verification - Run the tool access service, tool gateway service, tool gateway, and tool access policy service tests. - Confirm 227 tests pass. - Run the `@mcp-runnable` Playwright end-to-end suite in CI. - Run the US-9 loop 30 times in CI. ## Risks The change alters review-queue filtering for unsigned requests. A null signature now means that signing remains in progress. Invalid signed requests keep the existing cancellation behavior. The change has no database migration. ## Model Used OpenAI Codex, GPT-5, with tool use and code execution. The model reviewed the handoff, repository rules, and pull request state. The implementation author supplied the code and tests. ## 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] 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> |
||
|
|
0819cac4c6 |
feat(secrets): add agent-readable /secrets/catalog endpoint (#9530)
## Thinking Path
> - Paperclip is the open source app people use to manage AI agents for
work
> - Agents can be configured with env bindings that reference company
secrets — they specify which secret by UUID in `adapterConfig.env`
> - But there is no API endpoint agents can call to look up a secret
UUID by name — `GET /companies/:companyId/secrets` is board-only, and
the internal `secrets.resolve` handler only accepts UUIDs
> - So when an agent needs to wire a new secret (e.g. an API key for a
new skill), it has no way to discover the UUID from a known name like
`HOMEBOX_API_KEY` — the user must find it by inspecting browser network
traffic
> - The fix is a read-only catalog endpoint that agents can call to get
the `id`/`name`/`key`/`status` mapping — no values, no provider config —
just enough to resolve a name to a UUID
> - This PR adds `GET /companies/:companyId/secrets/catalog`, guarded by
`assertBoardOrAgent` + `assertCompanyAccess`, so agents can discover the
UUID they need without board-level access and without any secret value
being exposed
## Linked Issues or Issue Description
No pre-existing public issue. Describing inline per the feature request
template:
**Subsystem affected:** `server/` — REST API & orchestration services
**Problem or motivation:**
Agents that configure env bindings must reference secrets by UUID
(`secretId`). There is no agent-accessible API to resolve a secret name
to its UUID. `GET /companies/:companyId/secrets` requires board access;
the internal `secrets.resolve` handler rejects anything that is not
already a UUID. Agents and their operators are forced to find UUIDs by
inspecting browser network requests, which is friction that should not
exist.
**Proposed solution:**
Add a read-only catalog endpoint — `GET
/companies/:companyId/secrets/catalog` — that agents can call. It
returns only non-sensitive metadata (`id`, `name`, `key`, `status`) for
each active company secret, stripped of values, provider configuration,
and version history. Board callers get the same response. The existing
full-detail list endpoint (`GET /companies/:companyId/secrets`) remains
board-only and is unchanged.
**Alternatives considered:**
- Allow agents to call the existing `/secrets` list — rejected because
it returns full rows including provider metadata; narrowing the response
is safer.
- Add a name-to-UUID lookup by query param — simpler but less useful; a
full catalog means the agent can do the resolution locally without a
second round-trip.
**Roadmap alignment:** Does not duplicate anything in `ROADMAP.md`.
## What Changed
- `server/src/routes/secrets.ts` — new `GET
/companies/:companyId/secrets/catalog` route registered before the
board-only `GET /companies/:companyId/secrets` route. Uses
`assertBoardOrAgent` + `assertCompanyAccess`. Calls `svc.list()` then
projects each row to `{ id, name, key, status }` before responding.
- `server/src/__tests__/secrets-routes.test.ts` — adds `list` to the
shared mock service object (it was missing); adds a `describe` block
with four test cases: board caller receives stripped metadata, agent
caller in the same company receives stripped metadata, unauthenticated
request gets 401, agent from a different company gets 403.
## Verification
**Automated:**
```bash
pnpm --filter @paperclipai/server test --run secrets-routes
```
All four new test cases (board access, agent access, unauthed rejection,
cross-company rejection) should pass.
**Manual:**
1. Start the Paperclip server locally.
2. Create a company and a secret via the UI.
3. Call the endpoint as a board user:
```bash
curl http://localhost:3100/api/companies/<companyId>/secrets/catalog \
-H "Authorization: Bearer <board-session-token>"
```
Expect a JSON array with `id`, `name`, `key`, `status` fields — no
`provider`, no `referenceCount`, no version data.
4. Call the same endpoint with an agent API key:
```bash
curl http://localhost:3100/api/companies/<companyId>/secrets/catalog \
-H "Authorization: Bearer <agent-api-key>"
```
Expect the same response.
5. Call with an agent API key scoped to a *different* company — expect
403.
## Risks
Low risk. This is a purely additive, read-only endpoint. No existing
behavior changes. The only new capability is that agents can discover
the UUIDs of secrets in their own company — metadata they already need
to do their job. Secret values are never returned. Authorization reuses
the existing `assertBoardOrAgent` and `assertCompanyAccess` guards
already used throughout the codebase.
## Model Used
Claude Sonnet 4.6 (`claude-sonnet-4-6`) — Anthropic, extended context,
tool use enabled. The entire change (route, tests, PR description) was
produced by the model operating as a Paperclip CEO agent assigned to the
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
- [ ] All Paperclip CI gates are green
- [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [ ] I will address all Greptile and reviewer comments before
requesting merge
---------
Co-authored-by: Austin Pilz <austinpilz@users.noreply.github.com>
Co-authored-by: root <root@paperclip.pilz.dev>
Co-authored-by: Internet Historian <agent@paperclip.internal>
Co-authored-by: Andrew Aymeloglu <aaymeloglu@gmail.com>
|
||
|
|
eabecc6f77 |
feat(annotations): include issue document annotations in agent review context (#11332)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Reviewers annotate plans and issue documents with inline comments, and assigned agents act on that feedback > - The server already builds a bounded review context from open plan annotations and includes it in agent wake payloads > - Non-plan issue documents did not get the same treatment: their open annotation threads never reached the agent, and the properties pane did not surface their annotations > - This pull request extends the review-context path and the properties-pane UI to issue documents, at parity with plans > - The benefit is that agent feedback on any issue document reaches the assigned agent, not only feedback on the plan ## Linked Issues or Issue Description **What existing behavior does this improve?** The review-context pipeline that delivers inline annotation feedback to assigned agents, and the properties pane that surfaces those annotations to reviewers. **Subsystem affected** The server review-context path (`server/src/services/plan-review-context.ts`, wake payload assembly in `server/src/services/heartbeat.ts`, `server/src/routes/issues.ts`), shared wake-payload types (`packages/shared`, `packages/adapter-utils`), and the issue properties pane (`ui/src/components/issue-properties/`). **Current behavior** A reviewer can annotate any issue document, not only the plan. The agent wake payload includes open annotation threads for the plan document only. Feedback left on other issue documents is invisible to the assigned agent. In the properties pane, the Artifacts tab also gives no way to see or open a document's annotations. **Proposed behavior** Add `buildDocumentReviewContext` beside the existing plan builder. It collects open annotation threads for all non-plan issue documents, applies the same thread, comment, and character budgets across documents, and reports truncation. Include the result as a new `documentReviewContext` field in agent wake payloads and in the issue wake-context route. Keep the plan context on its legacy builder and field so plan-only wakes stay byte-for-byte compatible. Render the new context in the adapter wake-payload text, and surface annotation counts and the annotation panel for documents in the properties pane's Plans and Artifacts tabs. **Reason and benefit** The floating annotation popover and persistent highlight UI landed earlier; this change completes the loop so agent feedback on any issue document reaches the assigned agent, not only feedback on the plan. **Breaking changes** None. The wake payload gains a new optional `documentReviewContext` field; the existing plan context field and its legacy builder are unchanged, so plan-only wakes stay byte-for-byte compatible. ## What Changed - Add `buildDocumentReviewContext` in `server/src/services/plan-review-context.ts`: bounded review context (shared thread/comment/character budgets, per-document legacy limits) over all non-plan issue documents - Include `documentReviewContext` in agent wake payloads (`server/src/services/heartbeat.ts`) and in the issue wake-context response (`server/src/routes/issues.ts`) - Add shared `DocumentReviewContext` / `DocumentReviewContextDocument` types in `packages/shared` - Normalize and render the new context in adapter wake-payload text (`packages/adapter-utils/src/server-utils.ts`), with tests - Show a `DocumentAnnotationsCountChip` and the annotation panel for documents in the properties pane Plans and Artifacts tabs, with tests - Extend server document-annotations service tests to cover the new context builder ## Verification - Run `npx vitest run packages/adapter-utils/src/server-utils.test.ts server/src/__tests__/document-annotations-service.test.ts` from the repo root — 104 tests pass - Run `TZ=UTC npx vitest run ui/src/components/issue-properties/IssuePropertiesDocumentAnnotations.test.tsx ui/src/components/IssueProperties.test.tsx ui/src/components/IssueDocumentAnnotations.test.tsx ui/src/components/DocumentAnnotationPopover.test.tsx` from the repo root — 75 tests pass (one pre-existing monitor-row case asserts UTC timestamps, so use `TZ=UTC` locally; CI runs in UTC) - `pnpm run typecheck` in `server/` passes - Manual: annotate a non-plan issue document, then wake the assigned agent with a comment — the wake payload lists the open document annotation threads; the Artifacts tab shows the annotation count chip and opens the panel ## Risks - The wake payload gains a new optional `documentReviewContext` field; consumers that ignore unknown fields are unaffected, and the plan context field is unchanged - The context is new input to agent wakes; shared budgets (same limits as the plan context) bound token cost across all documents - Low UI risk: the properties-pane changes reuse the existing annotation components > 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 - Claude (Anthropic), model ID `claude-fable-5` (Claude Fable 5), with extended thinking and agentic tool use (Claude Code harness) ## 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> |
||
|
|
403fcefb97 |
build(deps-dev): bump vite from 6.4.1 to 6.4.3 (#11317)
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 6.4.1 to 6.4.3. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/vitejs/vite/releases">vite's releases</a>.</em></p> <blockquote> <h2>v6.4.3</h2> <p>Please refer to <a href="https://github.com/vitejs/vite/blob/v6.4.3/packages/vite/CHANGELOG.md">CHANGELOG.md</a> for details.</p> <h2>v6.4.2</h2> <p>Please refer to <a href="https://github.com/vitejs/vite/blob/v6.4.2/packages/vite/CHANGELOG.md">CHANGELOG.md</a> for details.</p> </blockquote> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/vitejs/vite/blob/v6.4.3/packages/vite/CHANGELOG.md">vite's changelog</a>.</em></p> <blockquote> <h2><!-- raw HTML omitted -->6.4.3 (2026-06-01)<!-- raw HTML omitted --></h2> <ul> <li>fix: backport <a href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/22572">#22572</a>, reject windows alternate paths (<a href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/22576">#22576</a>) (<a href="https://github.com/vitejs/vite/commit/96b0c10162e9c55485d922db2cfc6b8227cbc176">96b0c10</a>), closes <a href="https://redirect.github.com/vitejs/vite/issues/22572">#22572</a> <a href="https://redirect.github.com/vitejs/vite/issues/22576">#22576</a></li> <li>fix(deps): backport <a href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/22571">#22571</a>, reject UNC paths for launch-editor-middleware (<a href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/22575">#22575</a>) (<a href="https://github.com/vitejs/vite/commit/8fed5cf540c0d475266787f52072f258478cd42f">8fed5cf</a>), closes <a href="https://redirect.github.com/vitejs/vite/issues/22571">#22571</a> <a href="https://redirect.github.com/vitejs/vite/issues/22575">#22575</a></li> </ul> <h2><!-- raw HTML omitted -->6.4.2 (2026-04-06)<!-- raw HTML omitted --></h2> <ul> <li>fix: apply server.fs check to env transport (<a href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/22159">#22159</a>) (<a href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/22163">#22163</a>) (<a href="https://github.com/vitejs/vite/commit/fe28e47e9463e4c9619f94bfa06d2f8f1411b44b">fe28e47</a>), closes <a href="https://redirect.github.com/vitejs/vite/issues/22159">#22159</a> <a href="https://redirect.github.com/vitejs/vite/issues/22163">#22163</a></li> <li>fix: avoid path traversal with optimize deps sourcemap handler (<a href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/22161">#22161</a>) (<a href="https://github.com/vitejs/vite/commit/ca4da5d1fb45c9cfdce606aa30825095791b164b">ca4da5d</a>), closes <a href="https://redirect.github.com/vitejs/vite/issues/22161">#22161</a></li> </ul> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/vitejs/vite/commit/6c2c881f15495738ff03bc1d67cc052c07e0cac4"><code>6c2c881</code></a> release: v6.4.3</li> <li><a href="https://github.com/vitejs/vite/commit/96b0c10162e9c55485d922db2cfc6b8227cbc176"><code>96b0c10</code></a> fix: backport <a href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/22572">#22572</a>, reject windows alternate paths (<a href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/22576">#22576</a>)</li> <li><a href="https://github.com/vitejs/vite/commit/8fed5cf540c0d475266787f52072f258478cd42f"><code>8fed5cf</code></a> fix(deps): backport <a href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/22571">#22571</a>, reject UNC paths for launch-editor-middleware (<a href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/2">#2</a>...</li> <li><a href="https://github.com/vitejs/vite/commit/6b3fad02abd550bd7b79934ff92c58dbd7f33045"><code>6b3fad0</code></a> release: v6.4.2</li> <li><a href="https://github.com/vitejs/vite/commit/ca4da5d1fb45c9cfdce606aa30825095791b164b"><code>ca4da5d</code></a> fix: avoid path traversal with optimize deps sourcemap handler (<a href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/22161">#22161</a>)</li> <li><a href="https://github.com/vitejs/vite/commit/fe28e47e9463e4c9619f94bfa06d2f8f1411b44b"><code>fe28e47</code></a> fix: apply server.fs check to env transport (<a href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/22159">#22159</a>) (<a href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/22163">#22163</a>)</li> <li><a href="https://github.com/vitejs/vite/commit/5487f4f641f70c47ea05fd101a4319897df048b3"><code>5487f4f</code></a> release: v6.4.1</li> <li><a href="https://github.com/vitejs/vite/commit/1114b5d7ea03e26572708715343bec69db4536e8"><code>1114b5d</code></a> fix(dev): trim trailing slash before <code>server.fs.deny</code> check (<a href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/20968">#20968</a>) (<a href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/20969">#20969</a>)</li> <li><a href="https://github.com/vitejs/vite/commit/f12697c0f64b9a37196b9ab218a0911829d5b103"><code>f12697c</code></a> release: v6.4.0</li> <li><a href="https://github.com/vitejs/vite/commit/ca6455ee9eb6111a9caa9810506a1b9ac96a520a"><code>ca6455e</code></a> feat: allow passing down resolved config to vite's createServer (<a href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/20932">#20932</a>)</li> <li>Additional commits viewable in <a href="https://github.com/vitejs/vite/commits/v6.4.3/packages/vite">compare view</a></li> </ul> </details> <br /> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> |