mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-06 20:34:57 +02:00
codex/native-completion-master-final-candidate
1997
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
b8a6bf950a |
Clarify native completion tools and qualify independently on production defaults
Co-Authored-By: Paperclip <noreply@paperclip.ing> |
||
|
|
1815474597 |
fix: report pending execution phase at Stop timeout (#14990)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - The server owns each adapter execution and waits for it to settle after Stop. > - A Stop timeout reports that termination remains unverified. > - Existing phase timings arrive only after their work completes, so a stalled await has no timing. > - This pull request samples the pending phase when the Stop timer expires. > - Operators can identify the pending operation without treating diagnostics as stop proof. ## Linked Issues or Issue Description **What existing behavior does this improve?** The opt-in Sentry context for an unconfirmed adapter Stop timeout. **Current behavior** The timeout includes execution identity but no pending phase. A session close, instruction collection, workspace restore, or diagnostic write can remain pending without producing its completion timing. **Proposed behavior** Add a closed-list phase and elapsed milliseconds from the exact live execution control. Sample them when the timeout fires. Report `unknown` and a null age when the control or attribution is unavailable. **Reason and benefit** The next timeout can identify which operation is still pending. It does not require task text, paths, provider output, or additional database writes. **Breaking changes** No API or execution behavior change. The existing opt-in error context gains two fields. Related public work: #14639 added Stop identity diagnostics; #14866 and #14945 cover instruction cleanup and teardown outcomes. This change adds pending attribution to those paths. The native Stop work in #14802 remains separate. ## What Changed - Add a bounded tracker per execution control. Token scopes support nested and overlapping awaits. A late release cannot clear a newer scope. - Track adapter execution, ACP cancellation and settlement, diagnostic writes, and host cleanup. Keep a coarse host scope until the executor finishes. - Sample only the matching current control and settlement promise at timeout. Freeze the sanitized result. Use a monotonic clock and cap elapsed time at one day. - Test stalled operations, repeated Stop calls, stale and wrong-run controls, callback failures, scope bounds, and the real Sentry SDK context. ## Verification - `pnpm -r typecheck` passed. - `pnpm build` passed. - Six focused suites passed: 79 tests. They cover pending scopes, Stop control ownership, real ACP settlement stalls, and Sentry context isolation. - The real Sentry SDK contract ran with the audited optional peer `@sentry/node@10.71.0` installed outside the workspace. Valid phase and elapsed values were exported; arbitrary labels and nonfinite elapsed values were rejected. - An independent agent reviewed the production diff and ran the focused tests without blockers. - `git diff --check` and a redacted Gitleaks scan passed. The local full `pnpm test:run` was stopped during its large serial server batch to avoid duplicating the sharded CI suite. No complete local broad-suite pass is claimed. - All CI gates passed on `c223237b58aa8d479d1c66d7d399de30270bac4f`: 54 successful checks and two expected Storybook skips. This includes the full sharded test suite, typecheck, build, real Sentry SDK isolation, browser tests, canary dry run, and the security scan after the PR became ready for review. - Greptile scored the same commit 5/5 with no actionable findings or unresolved review threads. ## Risks This is diagnostic instrumentation. Cancellation, deadlines, teardown order, termination proof, and file recovery proof remain unchanged. Unsupported or uninstrumented work uses a coarse phase. Tracker overflow fails closed to `unknown`. The tracker emits no new run-log or Telemetry event. The existing Sentry opt-in gate remains in place. ## Model Used OpenAI Codex, GPT-6. The agent used code inspection, local command execution, automated tests, and an independent agent review. The runtime did not expose a more specific model identifier or context-window size. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
4abff286c2 |
fix: retain resolved ACP execution timeout metadata (#14986)
## Thinking Path > - Paperclip manages agent work through adapters and heartbeat runs. > - ACP adapters resolve a timeout for the selected execution target. > - An untouched sandbox timeout uses a four-hour default. > - Heartbeat finalization rebuilt the metadata from the stored zero. > - This made a timed-out sandbox run report an effective timeout of zero. > - This change retains the adapter's resolved policy for accurate run diagnostics. ## Linked Issues or Issue Description **What happened?** ACP sandbox runs with `timeoutSec: 0` use the four-hour default. Their terminal metadata reports `effectiveTimeoutSec: 0` and `timeoutSource: config` because heartbeat finalization only reads the stored agent configuration. **Expected behavior** The result must report the policy the adapter used: `14400` and `sandbox_default`. Explicit limits, fractional limits, explicit unlimited overrides, and local defaults must keep their resolved values. **Steps to reproduce** Run an ACP adapter on a sandbox target with `timeoutSec: 0`. Compare the start log's four-hour policy with the terminal result's effective timeout. The new tests exercise the adapter result and the heartbeat metadata merge without waiting four hours. **Paperclip version or commit** Reproduced from `6eaf218924f0a89faf1c02eb0d6877a6c5c8a2cb`. **Deployment mode** Self-hosted server with an ACP sandbox execution target. Searched open timeout and metadata issues and PRs. Related #14804 exposes timeout configuration in forms; #14496 proposes a default policy; #14833 addresses CLI session retention. This PR changes only ACP result metadata. ## What Changed - Retain the resolved timeout in the ACP result after settlement. - Use validated adapter resolution when merging terminal timeout metadata. Preserve config fallbacks for older adapters and the HTTP millisecond policy. - Test sandbox defaults, explicit and fractional limits, explicit unlimited overrides, local defaults, malformed metadata, and unchanged cancellation fields. - Document the result fields and their meaning. ## Verification - `pnpm -r typecheck` passed. - `pnpm build` passed. - Stop metadata tests: 23 passed. - Reporter and diagnostic suites: 84 passed; two real-Sentry-SDK tests skipped because the optional SDK is not installed. - ACP engine suite: all 206 tests passed with a deterministic local `gemini --version` shim. Ambient host CLI probes made the existing Gemini session-resume fixture intermittent (one assertion failure in each of two broad runs); an isolated 15-case rerun and the clean-base 206-test suite also passed. No assertion or timeout was changed. - `pnpm test:run` is in progress. This PR does not claim a complete local suite pass. - Independent review found no blocking issues. The tests cover real adapter emission and the real metadata merge separately. ## Risks Low runtime risk: this changes result diagnostics. It does not change timeout values, cancellation acknowledgement, cleanup, checkpoint safety, retries, or provider operations. It does not fix the cause of a quiet or long-running tool. Older stored results are not rewritten. The new source values apply only when an adapter returns a valid resolution. ## Model Used OpenAI GPT-6 with reasoning, repository inspection, code editing, and test execution. The deployment-specific model ID and context-window size are not exposed in this session. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [ ] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [ ] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
862a5758ba |
fix(agents): reduce hiring templates to role descriptions (#14985)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - New agents receive role instructions from onboarding, the hiring skill, or a team package. > - These sources repeat harness procedures and impose generic work policies. > - They can crowd out the task and the harness instructions. > - This pull request reduces those sources to short role descriptions. > - It preserves configuration, skills, authentication, reporting lines, and approval controls. > - The benefit is less repeated instruction text with explicit coverage for the default hiring path. ## Linked Issues or Issue Description Refs #3307. The CEO template can impose a fixed delegation route instead of letting the agent choose how to fulfill the request. This change removes that route. It does not implement autonomous goal selection. Related work: #14920 preserves stock Codex base instructions. #14948 reduces the generic manual and shared runtime prompts. #14961 improves native completion-tool descriptions. This PR is separate from those changes. ## What Changed - Select only the short CEO `AGENTS.md` for new default CEO bundles. Keep the three former companion files as compatibility assets. - Reduce the first-agent chief-of-staff prompt and coder, QA, UX, and security role examples. - Reduce seven bundled team role bodies. Preserve their role, reporting, and skill metadata. Regenerate the catalog. - Make hiring examples optional. Replace the long generic role manual with short role drafting guidance. Preserve explicit requester instructions. - Add configuration and import coverage for native and legacy managed bundles, custom instructions, first-agent rendering, and catalog contents. - Add an explicit-only hiring eval that starts from the production CEO default and checks one coder hire, independently computed JSON output, saved instructions, and worker reuse. - Include the full prompt comparison and a separate three-request drafting simulation. Neither is a live provider comparison. Prompt differences: [before and after](doc/plans/2026-10-02-hiring-template-prompt-diff.md). The CEO default falls from 1,897 to 20 words. The coder example falls from 652 to 18 words. Word counts describe instruction size, not outcome quality or billing. ## Verification - PASS: 99 focused server tests and eight shipped-catalog tests. - PASS: catalog generation and validation for four shipped teams. - PASS: hiring skill validation. - PASS: `pnpm -r typecheck`. - PASS: `pnpm build`. - INCOMPLETE: the full local `pnpm test:run` was stopped before rebase. Its original log is retained. This is not a completed full-suite pass. The full current-head GitHub CI workflow passed: https://github.com/paperclipai/paperclip/actions/runs/37073372419. - PASS: `pnpm test:e2e:runner:typecheck` and `pnpm test:e2e:runner:unit` (63 files / 843 tests). - PASS: discovery for the two new hiring cells, 50 existing everyday cells, and the full 438-cell catalog. - PASS after rebase: 99 server tests, 11 catalog tests, 62 selected E2E support tests, and the E2E typecheck. - PASS: all current-head PR checks at `57dcee147ed0b2d2e3cc657cd9e50fb16bf9ec25`: 51 successful check runs, two intentional Storybook skips, and successful Snyk status. Fresh Greptile is 5/5 with zero unresolved threads. - PENDING follow-up: matched live hiring runs on frozen integration refs. No live outcome-quality or non-regression result is claimed from the configuration checks or this merge. The new suite has two local native cells: Codex and ACPX Claude. It expects five provider turns per cell. It compares source-derived bundles, so the historical long templates remain admissible. Missing successful source-read receipts make a pair uncomparable. They do not establish a behavior regression or equivalence. ## Risks - New default roles have fewer prescribed procedures. Live checks must determine whether a removed instruction was needed for an outcome. - Existing custom and saved bundles keep their contents. The retained companion assets avoid a source-file compatibility break. - Specialized Summarizer, Reflection Coach, and Wiki Maintainer prompts remain unchanged. Their product contracts need separate review. - The generic non-CEO fallback reduction is in #14948. This PR alone does not provide its eight-word fallback. - Configuration tests and drafting simulations do not establish live outcome quality. QA, UX, security, and chief-of-staff hiring behavior remain outside the new two-cell comparison. > 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-6, with reasoning, code editing, shell tools, and delegated verification. The runtime does not expose the exact deployment model ID or context-window size. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge Co-Authored-By: Paperclip <noreply@paperclip.ing> |
||
|
|
22cea6b2e6 |
fix: bound sandbox bridge waits and flag silent runs sooner (#14979)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Sandbox agents exchange input and output through bridge control commands. > - A provider can stop responding to a command even when it receives a timeout. > - These small commands can inherit a four-hour agent lifetime and block input or teardown. > - The board also calls a silent run healthy for the first hour. > - This pull request bounds bridge control waits and surfaces silence sooner. ## Linked Issues or Issue Description **What happened?** A sandbox run can remain active when a bridge control command never returns. The shared helper passes a timeout to the provider but does not enforce it on the host. It also accepts the agent's hours-long timeout. Output silence remains `ok` for an hour and becomes `critical` only after four hours. **Expected behavior** Bound short bridge operations even if the provider never settles. Report failed input delivery through the existing shutdown path. Warn after five silent minutes and escalate after fifteen. Keep normal agent command limits and require verified termination before releasing execution ownership. **Steps to reproduce** 1. Use a sandbox runner whose bridge read or input-upload promise never settles. 2. Set its configured timeout to four hours. 3. Observe that the old queue client never returns or rejects. 4. Inspect a running task with 35 minutes of output silence. The old summary still reports `ok`. **Paperclip version or commit** Base commit `d6d88b9de2`. **Deployment mode** Self-hosted server with sandbox execution. **Agent adapter(s) involved** Shared command-managed sandbox bridge, including Codex ACP sessions. The informational silence thresholds apply to active runs across adapters. Related: #14889 recovers stalled Daytona output streams; #14485 retries explicit gateway failures during input delivery. This change bounds short control operations whose provider promises never settle. It does not add tool replay or automatic cancellation for output silence. #6297 proposes configurable per-agent silence thresholds; this patch only changes the existing defaults. ## What Changed - Enforce at most 30 seconds per bridge control shell command on the host and provider, including callback startup and shutdown, process-session launch, and payload setup. Preserve shorter configured deadlines and launch environments. - Keep the long-lived agent command outside this deadline. Use a fixed timeout diagnostic without command payloads. - Surface suspicious output silence after five minutes and critical silence after fifteen minutes. - Decouple the shared-workspace holder cutoff from warning thresholds and preserve its existing one-hour value. - Add regressions for hung reads, a late upload response, failed input delivery, exact warning boundaries, and fresh output clearing warnings. - Update the adapter guide and execution contract. ## Verification - The three new queue-client regressions fail on the unchanged base and pass with this patch. - Final callback bridge and sandbox session suites: 214 passed. These cover hung reads, writes, startup, shutdown, process-session launch, payload setup, and the separate long-running agent limit. - Stdin ordering and shutdown suite: 56 passed after the lifecycle change. - Daytona and watchdog coverage passed in the earlier focused runs. Across the focused suites, 602 distinct tests pass. - `pnpm -r typecheck` and `pnpm build`: passed. Server and adapter typecheck/build also passed after their respective follow-up changes. - `pnpm test:run`: attempted and stopped after known local failures. Four chat/email cases used an external ancestor skill path, three skill-cache cases failed on macOS, and one wakeup case timed out. The wakeup case passes alone (1 passed, 27 skipped). This run spanned the workspace-cutoff follow-up and also failed its new holder case; a fresh final-head workspace suite passes all 19 tests. The interrupted run is not a full local-suite pass or final-head verification. - A filesystem queue-drain test failed once during the lifecycle rerun and passed on the complete two-suite rerun. It uses the filesystem client, outside the changed command-runner path. - Complete CI on `ff2212c235`: 53 successful checks and two expected skips, including the full test suite and canary packaging dry run. No failed or pending checks. - Greptile reviewed `ff2212c235` at 5/5. All review findings are addressed, no threads remain unresolved, and the branch has no merge conflicts with `master`. - `git diff --check` and a scan of added text for secrets and private identifiers passed. ## Risks - A bridge control operation that needs more than 30 seconds now fails, even if the caller selected a longer run lifetime. Agent commands retain their own limits. - Timing out a provider promise does not cancel the remote operation or prove it stopped. Existing execution settlement still owns termination verification. No uncertain tool action is replayed. - Quiet healthy runs display warnings sooner. Existing snooze, continue, and false-positive dismissal controls still apply. Silence alone does not cancel a run, create review work, or change assignments. - No schema or API shape change. ## Model Used OpenAI GPT-6 through Codex, with tool use and code execution. The exact serving model ID and context window are not exposed in this session. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run change-specific 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> |
||
|
|
5b8b2b38ca |
feat(apps): add Neon connection (#14980)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Agents reach external services through the Apps catalog. Each catalog entry is a reviewed `AppDefinition` that wires a provider's hosted MCP server into Paperclip's shared vault, grants, policies, gateway, and audit trail. > - Neon is a widely used serverless Postgres provider with an official hosted MCP server, but it is not in the catalog. Teams that run their databases on Neon must use the generic "connect your own MCP server" path, which has no branding, no guidance, and no project or read-only controls. > - The connector playbook requires a catalog entry for a provider like this: the hosted server supports dynamic client registration and bearer API keys, and the common definition fields can express every option Paperclip can serialize. > - This pull request adds the Neon definition, its official artwork, the research and permission-review ledger rows, documentation, and deterministic tests, without any provider-specific runtime code. > - The benefit is a one-click, governed Neon connection with optional project pinning and read-only mode, and a documented path to live qualification. ## Linked Issues or Issue Description **Problem or motivation** Neon is a common Postgres host for the applications agents work on, but Paperclip's Apps catalog has no Neon entry. Operators who want agents to inspect schemas, run SQL, or manage branches must paste the MCP URL into the generic remote-MCP flow, which gives no branding, no provider guidance, no project boundary, and no read-only switch. **Proposed solution** Add a catalog-only Neon connection built from the connector playbook: browser sign-in through Neon's dynamic client registration with the reviewed `read` and `write` scopes, or a customer API key sent as an Authorization bearer header. Both methods expose Neon's documented `projectId` pin and `readonly` switch as optional Advanced fields. Every discovered tool stays governed by the normal per-action policies. **Alternatives considered** A plugin was not needed because no custom UI, tables, workers, or webhooks are involved. A separate read-only method was not added because the playbook treats read-only switches as advanced fields rather than methods. Neon's repeatable `category` query filter was left out because tenant fields serialize lists as one comma-joined value, so it cannot be sent correctly without new runtime code; per-action policies cover catalog narrowing instead. **Roadmap alignment** This extends the existing self-serve remote-MCP connection catalog and does not overlap planned core work. ## What Changed - Added the `neon` provider to `scripts/ingest-app-definitions.mjs` (category, API-key placement, methods, tenant fields, guidance, warnings) and regenerated `packages/shared/src/app-definitions/neon.json` plus the generated registry. - Added the Neon row to the self-serve MCP research ledger with `dcr_or_api_key` auth and risk tier S4. - Added permission reviews for `neon/mcp-oauth` (explicit scopes `read`, `write`, taken from Neon's live authorization-server metadata) and `neon/mcp-api-key` (provider key), with evidence links. - Added Neon's official tile icon (`ui/public/brands/apps/neon.png`, copied byte-for-byte from the icon linked by neon.com) and the brand manifest entry. - Added prosumer gallery copy for the Neon card. - Added `doc/connections/NEON.md` (service involvement, endpoints, administrator setup, capabilities and policy, manifest, brand provenance, validation hook) and linked it from the connections README and the permission audit. - Tests: Neon definition shape, store visibility and artwork, URL recognition, reviewed scopes with scope-widening rejection, URL projection of the project pin and read-only flag, invalid project ID rejection, the connect form's API-key gating, and the pinned catalog counts. ## Verification - `pnpm exec vitest run packages/shared/src/app-definitions.test.ts packages/shared/src/app-definitions-url.test.ts` — 34 passed. - `pnpm exec vitest run server/src/__tests__/tool-access-service.test.ts` — 367 passed. - `pnpm exec vitest run ui/src/pages/apps/AppsConnect.test.tsx ui/src/pages/apps/Browse.test.tsx ui/src/lib/app-brand-assets.test.ts ui/src/pages/apps/AppLogo.brand-assets.test.tsx` — all passed. - `node scripts/check-app-brand-assets.mjs` and `node --test scripts/app-brand-validation.test.mjs` — passed. - `pnpm --filter @paperclipai/shared typecheck`, `pnpm --filter @paperclipai/server typecheck`, `pnpm --filter @paperclipai/ui typecheck`, `pnpm check:token-gates` — clean. - Manual: in a local instance, open Apps → Browse, confirm the Neon card and icon, open `/apps/connect?source=neon`, confirm both methods, the Advanced project pin and read-only toggle, and that Connect enables after an API key is entered. The operator completed a live connection against a Neon account on this build. - Live metadata probed on 2026-10-02: both `.well-known` documents at `mcp.neon.tech` return the recorded endpoints and scopes; an unauthenticated `initialize` returns 401 with `resource_metadata`. ## Risks - Low risk to existing providers: the change is additive catalog data plus tests. The generated registry only gains one import. - Neon's hosted server grants broad project and database management. The definition carries two warnings, recommends a development project, and keeps every write under the normal action policies; the read-only switch is enforced by Neon's server, not locally. - The permission-review ledger records live proof for both methods as not run; the full lifecycle checklist in `doc/connections/NEON.md` still needs a documented pass before the entry is considered fully qualified. > 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 Fable 5.1 (`claude-fable-5-1`) in Claude Code, with extended thinking and tool use (shell, file editing, browser verification). ## 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> |
||
|
|
d6d88b9de2 |
fix: preserve run outcomes when agent file cleanup is deferred (#14945)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - The heartbeat service records each agent turn and releases its working files. > - A turn can save its work and finish before instruction-copy cleanup runs. > - A cleanup exception can replace that completed result with an adapter failure. > - This also loses result accounting and can prevent environment lease release. > - This pull request records a cleanup warning and keeps the original run outcome. > - The existing recovery sweep retries cleanup from the durable working-copy record. ## Linked Issues or Issue Description Related cleanup and lock work: #14866 and #14869. Related, distinct work: #14695 retains warm-process files; #12021 handles provider-process SIGTERM after a terminal result. **What happened?** An agent saved its plan, posted a comment, and requested approval. The provider completed its turn. Instruction-copy cleanup then timed out on a directory lock. Its exception escaped a `finally` block and replaced the provider result, so the completed turn showed `Run failed`. **Expected behavior** Keep the provider outcome, usage, cost, saved work, and pending approval. Record a cleanup warning and let the existing recovery sweep retry. A real provider failure must keep its original error. A failed file save must keep its failed-save receipt. **Steps to reproduce** 1. Complete a legacy adapter turn that saves work and requests approval. 2. Make instruction-copy release throw a directory-lock timeout. 3. Read the run result. Before this change, the cleanup error replaces the provider outcome. The new heartbeat tests reproduce the failure without a live provider or external service. **Paperclip version or commit** The regression reproduces on `c83df091b1a5207375eaf23466bb5c62e4e1518e`. This branch is rebased onto `cf8ad63c80`. **Deployment mode** Server-managed agent execution with persistent instruction working copies. ## What Changed - Catch instruction-copy release failures in both heartbeat teardown paths. Stop repeating a failed cleanup attempt within the same run. - Write a sanitized `instruction_cleanup` warning. A warning-write failure also preserves the run result. - Test successful, failed, and throwing providers; both teardown paths; warning-write failure; accounting; approval state; and execution-control release. - Extend the held-lock test to prove a fresh recovery worker removes the deferred copy and preserves its failed-save receipt. - Document deferred cleanup and the run-log event. ## Verification - Red proof: all five new heartbeat regression cases fail with the original release calls. - At head `20bea4f431c916d2f5db1970213aab85f5daa34c`, all 417 tests passed across heartbeat process recovery, agent directory working copies, and directory merge locks. - Full local `pnpm -r typecheck`, `pnpm build`, and `git diff --check` passed. - [GitHub CI](https://github.com/paperclipai/paperclip/actions/runs/37031119795) passed at this head. All 53 reported checks passed; the two Storybook checks were correctly skipped. This includes general and serialized tests, browser shards, runner verification, build, typecheck, and the canary dry run. - Greptile reviewed this head with 5/5, no code comments, and no unresolved review threads. The branch has no merge conflicts. - The local `pnpm test:run` attempt was stopped after it reported eight failures in unchanged suites. Four Slack/AgentMail cases selected an unrelated ancestor skills directory and failed with `ENOENT`; the two Slack cases passed with a temporary local skill-root link, which was then removed. Three company-skill cases reproduced macOS `EACCES` errors when renaming read-only cache directories. One gateway case passed when rerun alone. No full local-suite pass is claimed; the complete CI test jobs passed. ## Risks - Cleanup errors now leave recovery work pending. The durable working-copy record remains available for the existing retry sweep. - This change preserves provider failures and failed-save receipts. It does not claim that unsaved file edits were saved. - Native instruction reservation errors retain their existing behavior because they guard process ownership. - No schema, lockfile, workflow, API, or UI changes. ## Model Used OpenAI Codex, based on GPT-6, with reasoning, repository tools, and code execution. The exact backend model ID and context-window size are not exposed by this session. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
92ad158ce1 |
fix(claude-local): order Claude models the way the Claude app does (#14917)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Each agent runs on an adapter, and the operator picks the agent's model from a list the adapter advertises. > - The `claude_local` adapter advertises a static list and merges in the models the Anthropic API returns. Neither list has a deliberate order. > - The model dropdown then sorts every list by id. For Claude this shows "Fable 5", "Fable 5.1", "Haiku 4.5", "Mythos 5", "Opus 4.6" ... which is not the order of capability, release, or version (#14877). > - This pull request gives the adapter one defined order, the one the Claude app uses: the newest release of each family first, by decreasing capability, then older releases grouped by family. The server applies it to discovered models, and the dropdown keeps the adapter's order instead of re-sorting. > - The benefit is that a user who knows the Claude app finds the right model at once, and older models sit at the end of the list. ## Linked Issues or Issue Description Fixes #14877. Related: #14147 touches the same adapter's model list (the `ANTHROPIC_MODEL` default label) and does not change ordering. #14878 is the Codex counterpart and depends on the dropdown change in this PR. ## What Changed - `packages/adapters/claude-local/src/server/model-order.ts` (new): `sortClaudeModels()` and `parseClaudeModelId()`. The parser reads the current scheme (`claude-opus-4-8`), the legacy scheme (`claude-3-7-sonnet-20250219`), dated snapshots, `-latest` aliases, the `[1m]` suffix, and Bedrock ids (`us.anthropic.…-v1`, `…-v2:0`). The sort puts the newest release of each family first (Fable, Mythos, Opus, Sonnet, Haiku), then older releases grouped by family with versions descending. An alias sorts before its dated snapshots, and dated snapshots of one release sort newest first. Ids that are not Claude models keep their incoming order at the end. - `packages/adapters/claude-local/src/server/models.ts`: apply the order to the static fallback, to the merged API list, and to the Bedrock list. Reorder `BEDROCK_MODELS` to match. - `packages/adapters/claude-local/src/index.ts`: reorder the advertised `models` list to the same order. - `ui/src/components/AgentConfigForm.tsx`: `ModelDropdown` gets a `preserveOrder` prop. With it the dropdown shows the list as the adapter ordered it; without it the list is sorted by id as before. `ui/src/lib/model-utils.ts` adds `adapterCuratesModelOrder()`, true for the built-in adapters whose list arrives in a deliberate order (`claude_local`, `codex_local`, `paperclip_runner`, `gemini_local`, `grok_local`, `kimi_local`, `openclaw_gateway`, and `opencode_local` / `pi_local`, which the server sorts when discovered and which lead with the default model when it falls back to the declared list). Cursor is not in the set because its list comes from `agent models` discovery, and adapters not named there, including externally installed ones, keep the alphabetical fallback. The three dropdown call sites (`AgentConfigForm`, `ConfigureBuiltInAgentModal`, `NewAgentSetup`) pass it; `NewAgentSetup` decides by the resolved brand type, because a `paperclip_runner` agent fetches the Claude or Codex list for its brand. Grouped lists (`opencode_local`, `pi_local`) are unchanged. - Tests: `model-order.test.ts` (adapter, including the snapshot-date tie-breaker), `ModelDropdown.test.tsx` (ui: preserved order with the prop, alphabetical without it, provider groups unchanged), `model-utils.test.ts` (which adapters opt in), and two updated expectations plus one new order assertion in `server/src/__tests__/adapter-models.test.ts`. Mythos is not in the Claude app's list. This PR ranks it directly after Fable, in the top capability tier. The rank table in `model-order.ts` is one line to change if you prefer a different slot. ## Verification Run from the repository root: ```sh pnpm exec vitest run packages/adapters/claude-local server/src/__tests__/adapter-models.test.ts ui/src/lib/model-utils.test.ts ui/src/components/ModelDropdown.test.tsx ui/src/components/AgentConfigForm.render.test.tsx ui/src/components/ConfigureBuiltInAgentModal.test.tsx ui/src/pages/NewAgent.test.tsx pnpm --filter @paperclipai/adapter-claude-local typecheck pnpm --filter @paperclipai/ui typecheck pnpm --filter @paperclipai/server typecheck pnpm check:module-boundaries && pnpm check:token-gates && pnpm check:tokens ``` Red on `master`, green here: - `ModelDropdown.test.tsx` fails against the unmodified dropdown because the ids come back sorted alphabetically even with `preserveOrder`. - `adapter-models.test.ts` fails against the unmodified adapter because the first model is `claude-opus-4-8`, not `claude-fable-5-1`. Manual check: open an agent that uses `claude_local`, open the model dropdown. With no `ANTHROPIC_API_KEY` the list reads Fable 5.1, Mythos 5, Opus 5.5, Sonnet 5, Haiku 4.5, Fable 5, Opus 5, Opus 4.8, Opus 4.7, Opus 4.6, Sonnet 4.6, Sonnet 4.5. With a key, the discovered models slot into the same order. ## Risks - The other built-in adapters in the set (Gemini with `Auto` first, Grok, Kimi, OpenClaw, the runner's Codex list, and the OpenCode and Pi lists in the built-in-agent modal) are now shown as their adapter delivers them instead of alphabetized. Cursor's discovered list and every adapter outside the set, including externally installed ones, keep the alphabetical order they had, so no option moves between refreshes. Grouped lists are unchanged. - The first entry of the Claude list changes from Opus 4.8 to Fable 5.1. Nothing reads the first entry as a default: `DEFAULT_CLAUDE_LOCAL_MODEL` is `claude-opus-5` and is resolved separately. - No API, schema, or migration change. ## Model Used Anthropic Claude Fable 5.1 (`claude-fable-5-1`) through Claude Code, extended thinking on, with tool use for reading the repository, running vitest and tsc, and editing files. The account holder reviewed the change and owns the 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 - [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: abderbj <115119179+abderbj@users.noreply.github.com> |
||
|
|
2ec82c5774 |
fix(runner): preserve task context when tool connections change (#14963)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Agents use tools through company-scoped connections and provider sessions. > - Resolving a tool connection currently forces a fresh session even when the provider can load new tools into the existing conversation. > - A fresh provider conversation can receive too little history to continue the task. > - This pull request adds explicit tool-refresh capabilities and uses them in both runner paths. > - Fresh attempts receive bounded task history with source IDs and retrieval instructions. > - The benefit is that agents can continue the same task after a connection changes. ## Linked Issues or Issue Description **What happened?** A resolved tool connection forced a fresh provider conversation. The new conversation could lose the original goal and prior answers. Claude also rejected resume when only the MCP server set changed. **Expected behavior** Resume the provider conversation when its harness can refresh tools. When a fresh session is required, supply enough bounded history to continue the task. Preserve company, agent, task, workspace, model, instruction, and skill checks. **Steps to reproduce** 1. Start a conversation and agree on a task and its constraints. 2. Request and connect a tool needed for the task. 3. Continue the conversation after the connection resolves. 4. Check that the agent remembers the task and can use the new tool. **Paperclip version or commit** The bug was reproduced on master at `c46e41e81`. This branch is rebased on current master. **Deployment mode** Self-hosted server. Both legacy adapters and the native runner are affected. Related public work: Refs #13282 for task-backed conversations. Refs #13057 for the broader session-compaction proposal. Refs #14659 for another report about local CLI session continuity. This change fixes tool-connection continuation. Provider authentication repairs keep their existing recovery behavior. ## What Changed - Expose tool-refresh support in native harness descriptors and legacy adapter metadata. - Request tool refresh after connection resolution. Keep provider authentication repair as a fresh-session wake. - Reload current tools and credentials while retaining supported Claude, Codex, Grok, and other provider conversations. - Allow MCP-only changes during qualified native recovery. Keep all other compatibility checks. - Refresh managed-provider and ACPX tool bindings when attaching a new run. - Add a fresh-session handoff for both runner paths. Bound database reads, excerpts, and the final packet to 24,000 bytes. - Include the original request, recent messages, decisions, plans, prior answers, and source IDs. Mark omitted content. Apply reset boundaries, wake cutoffs, quarantine, and secret redaction. - Add regression tests and document the capabilities and handoff behavior. ## Verification - `pnpm -r typecheck` and `pnpm build` passed. Rust formatting passed. - Final review fixes passed 314 server tests, 333 adapter utility tests, 139 native-session runtime tests, and 12 managed-provider Rust tests. They verify historical quarantine, raised budgets across attachment, no history reads on successful resume, and handoff delivery on fresh retry. - Broader branch verification also passed 1,401 adapter utility tests, 1,047 runner TypeScript tests, 43 Grok adapter tests, and 311 Rust core tests. - Live Claude CLI and Grok ACP probes preserved the provider session ID, recalled a prior task constraint, and called a newly added read-only MCP tool. - GitHub CI passed on `b21486d18084a7aa4cafbe8e012f7cad6585d9cc`: 55 successful checks and 4 skipped checks. This includes all test shards, all eight browser shards, runner checks, and the Grok clean public npm install canary. [CI run](https://github.com/paperclipai/paperclip/actions/runs/37057514976). - A full local test attempt encountered a separate Git snapshot timeout. All affected local suites passed after the final edits, and the full CI test gates passed. - Review the capability matrix in `packages/paperclip-runner/README.md`. Repeat the four reproduction steps with a supported provider and with an unsupported harness. ## Risks - Provider tool refresh can fail. Existing recovery falls back to a fresh conversation where policy permits it. - A new transport can replace an old process while preserving the provider conversation. Tests cover current credentials and unchanged identity. - Long history can omit older context. Explicit markers and source IDs let the agent retrieve needed context within task scope. - Unknown and unqualified harnesses use the fresh-session path. No database migration is required. ## Model Used OpenAI Codex, GPT-6, with reasoning, tool use, code execution, and live provider testing. The exact model ID and context-window size are not exposed in this session. Claude and Grok also ran as test subjects. ## 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> |
||
|
|
144083fd48 |
fix(interactions): wait for workspace readiness before enabling approval (#14893)
## Thinking Path > - Paperclip lets people manage AI agents and review their work. > - Task confirmations must use the work produced by their source run. > - The server blocks approval while that run still needs to sync its workspace. > - The card currently enables approval before that check can pass, so an ordinary click produces an error. > - This PR exposes the existing readiness check and shows “Preparing approval…” with acceptance disabled. > - The card refreshes itself and enables approval when the source workspace settles. ## Linked Issues or Issue Description **What happened?** A confirmation appears while its source run is still preparing or syncing its workspace. Its enabled approval button returns a conflict asking the user to retry after syncing. **Steps to reproduce** 1. Run an agent in an isolated workspace. 2. Have it create a confirmation before workspace finalization completes. 3. Click the approval button while the source workspace is still active. **Expected behavior** The card explains that approval is preparing. Acceptance becomes available automatically when the same server check permits it. Reject and revise remain available. Related work: #10770 handles this conflict after a click with retries. #9520 proposes changing the workspace acceptance barrier. This PR preserves that barrier and exposes readiness before the click, including in compact task chat. It preserves the terminal-finalize behavior from #10099. ## What Changed - Add an optional, read-only `acceptanceBlocker` to interaction responses. Readiness uses the existing source-run workspace predicate, with one check per pending source run. - Disable acceptance and show a shared preparation notice in classic and compact confirmation cards, including checkbox and secret-binding confirmations. - Refresh preparing cards every two seconds in task detail, attention, pipelines, and Skill Studio. Restore each surface's previous polling cadence when preparation clears. - Preserve live tool reviews, questions, rejection, revision, and the server acceptance barrier. No automatic acceptance occurs. - Document the preparation state and cover readiness, terminal sync outcomes, unrelated runs, historical cards, and automatic refresh. ## Verification - Focused service, card, query-refresh, and helper tests: 217 passed across five files. - `pnpm -r typecheck`: passed. - `pnpm build`: passed. - `pnpm build-storybook`: passed. - `pnpm check:token-gates`: passed. - `pnpm test:run`: incomplete locally. Stopped after about 17 minutes once it reproduced seven existing environment failures: two Slack tests and two email tests lack ancestor-directory skill fixtures; three company-skills tests fail on macOS runtime-cache staging permissions. These are outside this change. The full CI test matrix passed. - CI: all 53 checks passed; two optional Storybook jobs were skipped. The branch has no conflicts with `master`. - Greptile: 5/5 on commit `8a6f216d8d`, with no review threads. - Reviewed added lines and new files for credentials, private URLs, internal task references, user paths, and run artifacts. None found. ## Risks - No database migration or change to acceptance authorization. Readiness is advisory; the server still enforces its existing gate at acceptance. - An open preparing card adds a read every two seconds. This cadence stops after readiness clears; historical cards add no workspace checks. - Failed or stale finalization retains the existing server behavior. This PR does not change recovery policy. ## Model Used OpenAI GPT-6 through Codex. The exact serving model ID and context-window size are not exposed in this session. Used reasoning, repository inspection, tool execution, and automated tests. No sub-agents. ## 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 (217 focused tests; full local-suite limitations are recorded 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 - [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> |
||
|
|
0a2385eb31 |
build(deps): bump dompurify from 3.4.14 to 3.4.16 (#14783)
Bumps [dompurify](https://github.com/cure53/DOMPurify) from 3.4.14 to 3.4.16. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/cure53/DOMPurify/releases">dompurify's releases</a>.</em></p> <blockquote> <h2>DOMPurify 3.4.16</h2> <ul> <li>Fixed a problem with <code>IN_PLACE</code> node removal when working with hooks, thanks <a href="https://github.com/manus-pi"><code>@manus-pi</code></a></li> <li>Fixed a problem with <code>IN_PLACE</code> sanitization and raw-text roots, thanks <a href="https://github.com/h-t-m"><code>@h-t-m</code></a></li> <li>Fixed a problem with ESM default exports landing in CommonJS declarations, thanks <a href="https://github.com/ssi02014"><code>@ssi02014</code></a></li> <li>Migrated from <code>rollup</code> to <code>rolldown</code> because performance, thanks <a href="https://github.com/ssi02014"><code>@ssi02014</code></a></li> <li>Bumped several dependencies where possible</li> </ul> <h2>DOMPurify 3.4.15</h2> <ul> <li>Added better clobbering hardening when XML content is involved, thanks <a href="https://github.com/gnyselcuk"><code>@gnyselcuk</code></a></li> <li>Added several smaller hardening and edge-case improvements, thanks <a href="https://github.com/leechristensen"><code>@leechristensen</code></a></li> <li>Bumped several dependencies where possible</li> </ul> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/cure53/DOMPurify/commit/b9b9d80f7e401771c2ccaef5f45def7eec8f27d7"><code>b9b9d80</code></a> release: 3.4.16 (<a href="https://redirect.github.com/cure53/DOMPurify/issues/1636">#1636</a>)</li> <li><a href="https://github.com/cure53/DOMPurify/commit/1d7460c4f8a27be825c11b1c9d346d79db32c1e5"><code>1d7460c</code></a> release: 3.4.15 (<a href="https://redirect.github.com/cure53/DOMPurify/issues/1609">#1609</a>)</li> <li>See full diff in <a href="https://github.com/cure53/DOMPurify/compare/3.4.14...3.4.16">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) You can disable automated security fix PRs for this repo from the [Security Alerts page](https://github.com/paperclipai/paperclip/network/alerts). </details> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> |
||
|
|
d034ba7491 |
fix(interactions): derive question storage from canonical forms (#14946)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Agents request human input through durable issue interactions. > - A question form has a canonical presentation and a compatibility storage format. > - The creation API required agents to write both formats. > - Tool guidance told agents to split text and choice questions across those formats. > - This pull request accepts one complete canonical form and derives storage fields on the server. > - The benefit is a complete question card with stable answer and retry behavior. ## Linked Issues or Issue Description Related work: Refs #13630 and #14430. PR #13630 addresses the display of historical partial forms. This change fixes creation and keeps the check that rejects conflicting new forms. **What happened?** A question save supplied three compatibility questions and one canonical text question. The API correctly rejected the incomplete canonical form. The Runner's tool description encouraged this split. Sending only a complete canonical form also failed because the API required compatibility questions. **Expected behavior** An agent sends one complete `payload.questionSet` with every text and choice question. Paperclip derives `payload.questions` for storage and answer compatibility. Existing legacy requests remain valid. Explicitly conflicting dual forms remain invalid. **Steps to reproduce** 1. Call `paperclip_request_human_input` with `interactionKind: "questions"`. 2. Send `payload: { version: 1, questionSet: ... }` with a required text question and a required choice question. 3. The old API rejects the missing compatibility questions. With this change, it stores both questions and preserves the canonical form. 4. Retry with the same idempotency key. Confirm that only one interaction exists. 5. Submit both answers. Confirm that the normal resolver and continuation rules apply. **Paperclip version or commit** The branch is based on `cf8ad63c8`. The problem affects the native Runner and the interaction creation API. **Deployment mode** Server deployment with the native Paperclip Runner. Integration tests use the real interaction service and an embedded test database. ## What Changed - Add one shared canonical-to-storage projection. Reuse it for native harness question requests. - Accept canonical-only question creation at the shared validator and server boundary. - Export the input type and update the plugin SDK and its RPC contract. - Advertise a typed, complete question form in the live and scenario tool schemas. - Enforce canonical text and custom-answer constraints before ordinary or native resolution. Preserve harmless display whitespace. - Run regex matching in isolated workers with a deadline and resource limits. Both answer paths await the result before persistence. Saved native delivery uses the validated answer without taking another worker slot. - Update agent guidance and generated Runner contracts. - Test mixed forms, option-ID collisions, retries, answers, legacy requests, and conflicting forms. ## Verification - Interaction service, HTTP route, native bridge, and Runner authority suites: 221 tests passed after correcting an obsolete tool-description assertion. - Shared validator, plugin SDK, CLI, and UI compatibility suites: 67 tests passed. - Runner core tool-contract suite: 20 tests passed. AJV validates live and scenario schemas. - Final review regressions: 172 shared, service, native bridge, and authority tests passed. These cover text length, pattern, numeric limits, whitespace, custom option IDs, and historical pending cards. - Runner session suites: 67 tests passed. Published example tests: 4 tests passed. - Server typecheck and the shared/server builds passed after the compatibility fixes. - Final delivery verification: 35 response-delivery tests passed. The native delivery regression proves saved answers do not enter pattern workers; server typecheck and build passed. - Pattern security and answer-flow verification: 205 tests passed after repairing the child fixture loader. These cover pathological matching, event-loop responsiveness, worker concurrency, slot cleanup, HTTP routes, native delivery, and the full helper in a child process. - `pnpm -r typecheck` passed on the bounded-worker revision. - `pnpm build` passed on the bounded-worker revision. - All 55 GitHub checks passed on `fe457af`; four optional jobs were skipped. An unchanged Cursor adapter test timed out once in CI, passed locally, and passed on one failed-job rerun. - Reviewers can send the canonical-only mixed form above and verify that the saved interaction contains both canonical and compatibility questions. ## Risks - The creation API accepts a new input shape. Stored rows and answer contracts keep the existing shape. - The shared projection must preserve synthetic free-text option IDs. Collision and native round-trip tests cover this behavior. - Historical partial rows remain readable. New conflicting dual forms, including written-answer mismatches, remain rejected. - Existing pending cards retain the written-answer paths offered by their stored options. Canonical text constraints still apply. - Ordinary answers now enforce declared canonical constraints before persistence. Invalid answers leave the card pending. - Regex validation has a one-second deadline and a four-worker capacity limit. A complex pattern or capacity error leaves the card pending with a validation error. - No database migration or change to company authorization is required. ## Model Used - OpenAI GPT-6 through Codex. The session exposes the GPT-6 model family; its exact runtime model identifier and context window size are not exposed. Used reasoning, tool use, and code execution. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [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> |
||
|
|
8fd3cf74ea |
build(deps): bump @grpc/grpc-js from 1.14.4 to 1.14.5 (#14786)
Bumps [@grpc/grpc-js](https://github.com/grpc/grpc-node) from 1.14.4 to 1.14.5. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/grpc/grpc-node/releases">@grpc/grpc-js's releases</a>.</em></p> <blockquote> <h2><code>@grpc/grpc-js</code> 1.14.5</h2> <ul> <li>Fix a bug that caused clients to automatically transmit excessive error details to clients by default (<a href="https://github.com/grpc/grpc-node/security/advisories/GHSA-f596-whhp-79r4">advisory GHSA-f596-whhp-79r4</a>)</li> <li>Fix a bug that caused <code>getAuthContext</code> to return unverified certificates as though they were verified in some configurations (<a href="https://github.com/grpc/grpc-node/security/advisories/GHSA-m9gg-hp2v-232j">advisory GHSA-m9gg-hp2v-232j</a>)</li> <li>Fix a bug that could cause stale call data to accumulate if a channel failed to connect for a long period of time (<a href="https://redirect.github.com/grpc/grpc-node/issues/3078">#3078</a>)</li> <li>Fix a bug that could cause call status to be reported with expected fields missing (<a href="https://redirect.github.com/grpc/grpc-node/issues/3079">#3079</a>)</li> <li>Avoid redundant end() calls on completed HTTP/2 streams (<a href="https://redirect.github.com/grpc/grpc-node/issues/3082">#3082</a> contributed by <a href="https://github.com/olavloite"><code>@olavloite</code></a>)</li> <li>Unify call numbers and avoid disabled trace allocations (<a href="https://redirect.github.com/grpc/grpc-node/issues/3084">#3084</a> contributed by <a href="https://github.com/olavloite"><code>@olavloite</code></a>)</li> </ul> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/grpc/grpc-node/commit/56567d9604b4e45cdca0d2e3c2a60ac227ee659d"><code>56567d9</code></a> Merge pull request <a href="https://redirect.github.com/grpc/grpc-node/issues/3086">#3086</a> from murgatroid99/grpc-js_1.14.5</li> <li><a href="https://github.com/grpc/grpc-node/commit/748ae86f7bb8af4a8d917d6fcf01c7a4c070f0a4"><code>748ae86</code></a> Merge pull request <a href="https://redirect.github.com/grpc/grpc-node/issues/3088">#3088</a> from murgatroid99/grpc-js_perf_improvement_backport</li> <li><a href="https://github.com/grpc/grpc-node/commit/526702d8ed335a99960878aea19cf6748f6d2314"><code>526702d</code></a> test(grpc-js): fix type errors in client stream lifecycle tests</li> <li><a href="https://github.com/grpc/grpc-node/commit/26a8d3d7d919098ded374b1c246d113161d69eb1"><code>26a8d3d</code></a> fix(grpc-js): avoid redundant end() calls on completed HTTP/2 streams</li> <li><a href="https://github.com/grpc/grpc-node/commit/152eebdcd5bbb1548b7779d14e0f5046784c21c1"><code>152eebd</code></a> chore(grpc-js): unify call numbers and avoid disabled trace allocations</li> <li><a href="https://github.com/grpc/grpc-node/commit/c5ae75026d7f07d24ab1bbd76cb84d78ab3a4a8d"><code>c5ae750</code></a> grpc-js(-xds): Increment version numbers (1.14.x)</li> <li><a href="https://github.com/grpc/grpc-node/commit/735a09a4f967400667fbbeda54584437e1bcf721"><code>735a09a</code></a> Merge commit from fork</li> <li><a href="https://github.com/grpc/grpc-node/commit/af9b1401fbf72d7cbe8b569c8df45cb4d4905e24"><code>af9b140</code></a> Merge commit from fork</li> <li><a href="https://github.com/grpc/grpc-node/commit/45ac33e74312ccd34cd7015147b36ef21b12b6c3"><code>45ac33e</code></a> Merge commit from fork</li> <li><a href="https://github.com/grpc/grpc-node/commit/9df49e3ca3ea20f8626f62339d703d7284ed13e9"><code>9df49e3</code></a> Merge pull request <a href="https://redirect.github.com/grpc/grpc-node/issues/3081">#3081</a> from murgatroid99/grpc-js-xds_weighted_target_fix_ba...</li> <li>Additional commits viewable in <a href="https://github.com/grpc/grpc-node/compare/@grpc/grpc-js@1.14.4...@grpc/grpc-js@1.14.5">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> |
||
|
|
9786f6df56 |
fix(runner): preserve credential content in document saves (#14937)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - The Runner sends authorized tool calls to the control plane. > - Agents use these calls to save plans and instruction files. > - The Runner used diagnostic secret detection to reject execution arguments. > - Ordinary credential-related prose could reject a document save before persistence. > - This pull request forwards the original arguments and leaves credential policy to the provider harness. > - The benefit is reliable saves with useful diagnostic records. ## Linked Issues or Issue Description Related foundation: Refs #12415 and #14430. No duplicate save-policy fix was found. **What happened?** A `write_document` call failed before the server saved its plan. The Runner reported `semantic tool input contains credential material; refusing to execute altered arguments`. The detector also masked ordinary phrases such as `secret manager` and `credential handling` in diagnostics. Both TypeScript dispatchers had equivalent execution gates. One dispatcher also rewrote structured approval and question payloads before execution. **Expected behavior** Paperclip forwards authorized arguments unchanged. The provider harness decides credential-content policy. Log and audit redaction does not reject or rewrite save input. **Steps to reproduce** 1. Send an authorized `write_document` call with a plan that discusses credential handling. 2. Include an intentional credential value in the body to exercise harness-owned policy. 3. The old Runner rejects the call. With this change, the document service stores the exact body. 4. Diagnostic records still mask explicit credential values. Qualified credential fields, short bearer values, opaque diagnostic pairs, and valid encoded JSON token headers have regression coverage. **Paperclip version or commit** Reproduced at `c46e41e81c03cd3c8b64cf993615b604d7fe8c62`. The branch is based on current `master`. **Deployment mode** Server deployment with the native Paperclip Runner. Local regression tests use the real document service and an embedded test database. ## What Changed - Remove credential-content vetoes from Rust admission and both TypeScript semantic dispatchers. - Preserve original structured approval and question arguments during execution. - Keep transport bounds, schema checks, authorization, idempotency, and audit masking. - Require explicit credential syntax or recognized formats for diagnostic masking. Preserve ordinary prose, metadata, and dotted identifiers. - Test exact document persistence, replay, nested argument identities, and masked audit copies. - Remove obsolete retry guidance and document harness-owned credential policy. ## Verification - `cargo test --manifest-path packages/paperclip-runner/runner/Cargo.toml --locked -p paperclip-runner-core --lib --test acpx_event_payload --test acpx_provider_state --test acpx_provider_turns`: 355 tests passed. - Focused server and adapter tests: 189 tests passed after rebase. These include the real document save and the complete tool-gateway suite. - Semantic dispatcher and conformance tests: 34 tests passed. - Diagnostic redaction and MCP tests: 46 tests passed, including all six review examples. - `pnpm -r typecheck` and `pnpm build` passed on the repaired branch. - The broad local root suite was interrupted after database fixture setup failures. The focused database suites passed. CI runs the complete configured test lanes. ## Risks - Authorized tool arguments can intentionally contain credentials. The harness must enforce its content policy. - Diagnostic detection is narrower. Explicit assignments, credential fields, and recognized credential formats remain masked. - The change does not add a database migration or change company authorization. ## Model Used - OpenAI GPT-6 through Codex. The session exposes the GPT-6 model family; its exact runtime model identifier and context window size are not exposed. Used reasoning, tool use, and code execution. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [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> |
||
|
|
839cac1343 |
fix: request supported offline access for generic MCP OAuth (#14950)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Agents use external MCP tools through the governed gateway. > - Remote MCP connections can use OAuth access tokens that expire. > - Some providers issue refresh tokens only after an offline-access request and consent. > - Resource scopes hid that identity-provider capability in the generic connection flow. > - This pull request requests supported offline access and tests expiry through a local MCP server. > - The benefit is continued tool access without another sign-in when the provider permits refresh. ## Linked Issues or Issue Description Related PR: #13447 addresses the same OAuth symptom together with managed Codex configuration. This PR focuses on generic MCP OAuth. It also covers consent, explicit scope overrides, legacy reconnects, exact scope persistence, and real HTTP expiry tests. **What happened?** A generic MCP resource can advertise only its tool scopes. Its OAuth server can separately advertise `offline_access`. Paperclip selected the resource scopes and omitted the offline-access request. A provider could then issue an access token without a refresh token. Tool access stopped after the access token expired. **Expected behavior** Paperclip adds advertised offline access to the selected tool scopes when the OAuth server does not exclude refresh tokens. It requests consent and stores the scopes sent in the authorization request. Existing connections can discover this capability when the user reconnects. Providers without this capability keep their existing scope behavior. **Steps to reproduce** 1. Run `node scripts/mcp-fixtures/servers/oauth-refresh-fixture.mjs` from the repository root. 2. Add its MCP URL as a generic connection on a local Paperclip instance. 3. Approve the test consent page and call `read_status`. 4. Let the two-minute access token expire and call the tool again. 5. Before this fix, the connection needs another sign-in. With this fix, the call refreshes the token and succeeds. **Paperclip version or commit** The integration regression reproduced the missing-refresh-token failure on the parent of this PR's fix. The same test passes with the fix. **Deployment mode** Local development. Automated tests use a loopback HTTP MCP/OAuth server and a disposable PostgreSQL database. ## What Changed - Track offline-access capability separately from MCP tool scopes. - Add supported offline access and consent for generic connections. - Preserve the actual requested scopes through callback completion and reconnect. - Discover the capability for older connections with cached OAuth endpoints. - Add a reusable MCP/OAuth fixture with PKCE, token expiry, resource binding, and refresh-token rotation. - Test shared and personal gateway calls through two refresh rotations. Cover scope selection, unsupported refresh, and legacy reconnects. - Document the behavior and local test commands. ## Verification - The two real HTTP expiry tests failed before the fix with `oauth_refresh_missing` after the first token expired. - Tests passed on the current head: 76 generic MCP regressions, all 365 tool-access service tests, and 4 fixture controls. - Full workspace `pnpm -r typecheck` and `pnpm build` passed. Server TypeScript checks also passed after the review fixes. - All remote checks passed on `d22909bb34e9d54478c0002077c498ffe105932d`. Greptile gave 5/5 with both previous findings resolved. The complete local `pnpm test:run` is still running. - Run `node --test scripts/mcp-fixtures/servers/oauth-refresh-fixture.test.mjs` for the standalone provider controls. - Run `pnpm exec vitest run server/src/__tests__/generic-mcp-connection.test.ts` for the Paperclip integration tests. ## Risks - Users can see a consent prompt when a generic provider supports offline access. - The provider can still decline to issue a refresh token. Access works until expiry, then the user must reconnect. - A provider that advertises offline access but rejects the scope produces an OAuth error. This PR does not add an automatic retry without that scope. - Existing grants without refresh tokens need another sign-in. The fix does not change them in place. - Curated Apps keep their reviewed scope and authorization-parameter allowlists. No database migration is required. - This simulation verifies the suspected failure. The reported internal MCP server has not been tested. ## Model Used - OpenAI Codex, based on GPT-6, with reasoning, tool use, and code execution. The runtime did not expose a more specific model ID or context-window size. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
7a52dcdc74 |
fix: repair MCP validation and cancelled execution recovery (#14951)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - The tool gateway gives agents access to connected services. Recovery controls what happens when a run stops. > - Generated tool names can exceed the provider limit after the MCP client adds its prefix. > - The same invalid definition can fail each automatic retry. A cancelled run can also hold saved messages without showing its cause. > - This pull request bounds tool names, stops configuration retries, and retains cancellation evidence. > - It shows the stopped run and admits saved input only after the existing safety checks pass. > - The benefit is a clear recovery path that preserves operator Stop and prevents duplicate message delivery. ## Linked Issues or Issue Description **What happened?** A long connected MCP tool name makes the provider reject the entire request. Automatic recovery repeats the invalid request. Separately, unexpected legacy cancellations can leave saved input behind a recovery hold. The notice does not identify the stopped run or its cause. **Expected behavior** Complete MCP names fit the provider limit. Tool-definition errors require configuration repair. Cancelled runs retain their source and reason. The recovery notice shows the cause and saved-message count. Verified unexpected cancellations can start a fresh turn through the existing admission checks. **Steps to reproduce** 1. Assign an App gallery connection with a long application key and tool name to a Claude agent. 2. Start a run. The provider rejects a name over 128 characters, including its MCP prefix. 3. For cancellation recovery, stop a legacy provider turn without an operator Stop request and send a user message while the recovery hold is active. 4. Inspect the recovery notice and the deferred message queue. **Paperclip version or commit** Rebased onto master at `cf8ad63c806685bfd7c48e3ed4a919d61a7c55f1`. **Deployment mode** Hosted or self-hosted server with legacy Claude or Codex execution. Related public work: - Refs #14017. That PR caps name segments. This PR preserves existing short names and uses stable hash aliases for long complete names. It also covers classification and recovery. - Refs #4510. That PR adds a cancellation-source column. This PR records bounded evidence in the existing run result, without a migration. - Refs #12552 and #4506. Those PRs suppress recovery after operator cancellation. This PR preserves operator intent and uses the existing continuation gates. ## What Changed - Bound gateway names with the full provider prefix in the 128-character budget. Retain the original upstream tool name for dispatch and permissions. - Classify invalid tool definitions as configuration failures before diagnostic redaction. Stop automatic retries and continuation attempts for that error code. - Persist cancellation source, expectedness, initiator, reason, and time. Preserve recorded Stop intent when adapter results arrive. Report unexpected started cancellations with closed diagnostic labels. - Show the run cause, saved-message count, and Inspect run link. Offer Continue for eligible unexpected cancellations. Require verified provider stop, empty tool inventory, ownership, and the existing pause, budget, approval, and dependency gates. Use the existing queue for single delivery. - Add regression coverage and update the execution, MCP gateway, and run-log documentation. ## Verification - `pnpm -r typecheck` and `pnpm build` passed. - `pnpm check:token-gates` passed. - Ran `pnpm test:run` and completed its workspace and serialized groups. Initial resource and timing failures passed on isolated reruns. All 149 serialized route suites passed. - Reran the changed server, adapter, and UI suites after the rebase. Coverage includes long-name upstream dispatch, configuration retry suppression, cancellation evidence retention, privacy labels, oversized run projection, and concurrent saved-message delivery. - `pnpm test:e2e tests/e2e/legacy-failure-continuation.spec.ts` passed all six browser scenarios. The recovery notice shows the run cause and inspection link, and each recovery entry point reaches one new response. - Added database-backed checks for active, removed, paused, unavailable, and disabled chat connections. The final continuation and recovery-notice suites passed 167 tests. Externally bound chats hide board Continue and show a usable next action. - All 55 GitHub checks passed on `42afbf1371dcaeb72646e3d8f65c19ff7cddf8de`. Two unrelated Storybook jobs were skipped by their normal conditions. Greptile reviewed that commit at 5/5 with no findings and no open review threads. ## Risks - Long tool names change to aliases. Existing short names stay compatible. The original connection and upstream name remain the dispatch authority. - Invalid tool definitions no longer get automatic retries. An operator must repair the configuration before a new attempt. - Continuation changes apply only to positively identified unexpected legacy cancellations with complete empty tool inventory. Operator Stop, unknown historical cancellations, outstanding tools, and unverified provider termination keep their holds. - No database migration. The added projection fields are optional. Cancellation reason and initiator IDs remain local run evidence; Sentry receives only closed source and initiator-type labels and expectedness. ## Model Used - OpenAI GPT-6 through Codex, with reasoning, repository editing, shell execution, and GitHub tool use. The runtime does not expose the exact model variant or context-window size. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
7d59de6113 |
feat(connections): probe provider usage limits on demand (#14936)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Connections store the AI accounts used by legacy and native runners. > - Subscription accounts can reach session, weekly, model, or paid usage limits. > - Operators need to read these limits for a specific stored account before making a routing decision. > - This pull request adds an on-demand usage probe to the connection service and account detail. > - The result preserves provider limits, reset times, paid usage, and unknown values for later consumers. ## Linked Issues or Issue Description **Subsystem affected** Shared contracts, the connection service and API, and the account detail UI. **Problem or motivation** Managed AI accounts lack a common operation to read their current usage limits. A local harness probe can read a different login from the account selected for an agent. **Proposed solution** Add `aiConnectionService.probeUsage()` and a board-only connection usage endpoint. Probe the selected credential grant on request. Support Codex, Claude, and Grok subscriptions, plus OpenRouter API key limits. **Alternatives considered** Harness-specific automatic polling would couple the read to execution and can read ambient credentials. This change uses the managed connection credential and leaves scheduling and admission decisions to later work. **Roadmap alignment** This extends the existing Personal & Shared AI Accounts capability. It adds no routing or quota enforcement. Related: Refs #14459 for managed OpenAI quota reads; Refs #14781 and Refs #13379 for downstream pacing and budget work. This operation reads one requested account across all three subscription providers. ## What Changed - Add typed usage snapshots and a probe capability flag to managed AI connections. - Normalize Codex, Claude, Grok, and OpenRouter responses. Keep model scopes, provider admission, reset periods, and paid allowances separate. Preserve unknown values. - Enforce company membership, credential audience, grant identity, and connection lifecycle before reading the stored secret. - Add a board-only `GET /api/companies/:companyId/ai-connections/:connectionId/usage` endpoint with `no-store` responses. - Add manual **Check usage** and **Refresh** actions to account details. Show compact usage bars, resets, admission and overage status; remove repeated descriptions and account-default copy. Clear previous results during a new request or error. - Add Storybook previews using the production account components for all four providers, initial checks, loading, and permission errors. - Add provider, authorization, runner selection, API, and UI coverage. Document provider sources and live qualification. ## Verification - Initial provider, authorization, selection, API, and UI validation passed (96 focused tests): `pnpm exec vitest run server/src/services/ai-connection-usage.test.ts server/src/__tests__/ai-connections.test.ts ui/src/components/ai-connections/AiConnectionUsagePanel.test.tsx server/src/__tests__/openapi-routes.test.ts`. - `pnpm -r typecheck` passes for the initial implementation. After simplifying the UI, 9 usage-panel and date-helper tests, UI typecheck, token gates, and Storybook build pass. The initial feature module boundary check also passed. - Real Codex, Claude, and Grok credentials were saved to encrypted disposable connections. The actual usage HTTP route returned 200 with `status: ok`. Legacy and native runner selection checks passed. The tests started no model turn and exchanged no refresh token. The disposable databases and vaults were removed. - Live Claude responses added structured scoped limits. Live Grok responses omitted included-plan usage. Tests now cover both shapes and preserve the Grok omission as unknown. - The full workspace build passes. A full local test run hit a heartbeat feedback timeout. That case passes in isolation. The duplicate local run was stopped after all remote checks passed. The Slack ordering and OpenCode transport CI flakes also pass in isolation and on the CI rerun. - Current head: `ff3d479029a1c4248190323e221b2803cfb0d79d`. All 54 active checks pass. Two Storybook checks are intentionally skipped by the workflow. Greptile is 5/5 with no unresolved review findings; the branch is mergeable. ## Risks - Subscription usage endpoints can change. Credentials can lack usage-read permission. The probe returns explicit errors without fresh limits in these cases. - A successful probe can contain partial data. Missing utilization or admission remains unknown. An enabled paid-usage switch does not prove a funded balance. - This change adds no migration. It does not change runner admission or automatic provider selection. Provider requests use fixed endpoints, disabled redirects, bounded response sizes, and a 15-second deadline. ## Model Used OpenAI Codex, GPT-6, with reasoning, file editing, shell execution, and HTTP tools. The session does not expose the exact runtime model variant or context window size. Real provider credentials were used only for the authorized live checks. ## 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> |
||
|
|
cf8ad63c80 |
build(deps-dev): bump tsx from 4.23.12 to 4.23.15 (#12965)
Bumps [tsx](https://github.com/privatenumber/tsx) from 4.23.12 to 4.23.15. <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.15</h2> <h2><a href="https://github.com/privatenumber/tsx/compare/v4.23.14...v4.23.15">4.23.15</a> (2026-09-20)</h2> <h3>Bug Fixes</h3> <ul> <li>exclude bare builtins from namespace inheritance (<a href="https://github.com/privatenumber/tsx/commit/38e158857e50bca311be7c232a5057e5a2e5347a">38e1588</a>)</li> <li>expose require.cache and require.extensions to tsImport CommonJS modules (<a href="https://github.com/privatenumber/tsx/commit/2da34075afaed43e2b7fd0aca5fbebaaf337ff3a">2da3407</a>)</li> <li>make namespaced register() overloads portable for declaration emit (<a href="https://github.com/privatenumber/tsx/commit/562c434a5c8695e74327bbeb51cfeb9b86fc7e15">562c434</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.15"><code>npm package (@latest dist-tag)</code></a></li> </ul> <h2>v4.23.14</h2> <h2><a href="https://github.com/privatenumber/tsx/compare/v4.23.13...v4.23.14">4.23.14</a> (2026-09-20)</h2> <h3>Bug Fixes</h3> <ul> <li>restore the CJS bridge namespace for Node 24 require(esm) under tsImport() (<a href="https://redirect.github.com/privatenumber/tsx/issues/802">#802</a>) (<a href="https://github.com/privatenumber/tsx/commit/6e5236b065738d3687a06396d064774cfede390f">6e5236b</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.14"><code>npm package (@latest dist-tag)</code></a></li> </ul> <h2>v4.23.13</h2> <h2><a href="https://github.com/privatenumber/tsx/compare/v4.23.12...v4.23.13">4.23.13</a> (2026-08-30)</h2> <h3>Bug Fixes</h3> <ul> <li><strong>cache:</strong> bound shared transform cache memory (<a href="https://redirect.github.com/privatenumber/tsx/issues/835">#835</a>) (<a href="https://github.com/privatenumber/tsx/commit/28e1f12d04cd2afe1db17f8555b14fe5fb567c6e">28e1f12</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.13"><code>npm package (@latest dist-tag)</code></a></li> </ul> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/privatenumber/tsx/commit/ca66105a17a2a4c6503fe3a12b5b9ec408286011"><code>ca66105</code></a> test: fix drive-less file URLs in ESM resolver fixtures</li> <li><a href="https://github.com/privatenumber/tsx/commit/2da34075afaed43e2b7fd0aca5fbebaaf337ff3a"><code>2da3407</code></a> fix: expose require.cache and require.extensions to tsImport CommonJS modules</li> <li><a href="https://github.com/privatenumber/tsx/commit/38e158857e50bca311be7c232a5057e5a2e5347a"><code>38e1588</code></a> fix: exclude bare builtins from namespace inheritance</li> <li><a href="https://github.com/privatenumber/tsx/commit/562c434a5c8695e74327bbeb51cfeb9b86fc7e15"><code>562c434</code></a> fix: make namespaced register() overloads portable for declaration emit</li> <li><a href="https://github.com/privatenumber/tsx/commit/edfb1f05a3f40b879a41a03a0801c2abd3a3ecf9"><code>edfb1f0</code></a> build: upgrade pkgroll and externalize CJS loader reference</li> <li><a href="https://github.com/privatenumber/tsx/commit/70e78284837c859f09b96cd10cd71d007aa4b795"><code>70e7828</code></a> test: upgrade tinyspy for disposable API</li> <li><a href="https://github.com/privatenumber/tsx/commit/9ed2022dfa9ea1be9511fe6abcde8110c25055a7"><code>9ed2022</code></a> ci: avoid duplicate release notifications</li> <li><a href="https://github.com/privatenumber/tsx/commit/872e77ffc5e96ca5c4727e74c0694debcb26219b"><code>872e77f</code></a> refactor: use disposables for cleanup</li> <li><a href="https://github.com/privatenumber/tsx/commit/6e5236b065738d3687a06396d064774cfede390f"><code>6e5236b</code></a> fix: restore the CJS bridge namespace for Node 24 require(esm) under tsImport...</li> <li><a href="https://github.com/privatenumber/tsx/commit/28e1f12d04cd2afe1db17f8555b14fe5fb567c6e"><code>28e1f12</code></a> fix(cache): bound shared transform cache memory (<a href="https://redirect.github.com/privatenumber/tsx/issues/835">#835</a>)</li> <li>See full diff in <a href="https://github.com/privatenumber/tsx/compare/v4.23.12...v4.23.15">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> |
||
|
|
6c1a75da49 |
feat(connections): make AgentMail a default connection with inline setup (#14772)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Connections give agents access to external services. > - AgentMail needs both a saved key and an inbox assigned to the agent. > - Chat requests offered a setup link instead of an inline card and could treat a saved key as complete. > - Inbox setup also hid address conflicts behind a generic server error and a separate review step. > - This pull request makes AgentMail a default connection, adds the inline card, reduces setup to two steps, and shows conflicts beside the address. > - Shared native dropdown styles also give every caret a consistent inset. ## Linked Issues or Issue Description **What happened?** AgentMail requests in chat did not show a usable inline connection card. Manual setup required extra screens, ignored saved account keys, and could trap new-address setup in a locked inbox dropdown. Agent selectors omitted the avatar from the selected value. A taken address could produce an HTTP 403 from AgentMail and appear as an internal server error. Native dropdown arrows also touched the right edge of their fields. **Expected behavior** Make AgentMail available as a default connection. Ask for the API key inline, with a direct link to its provider page. Default human access to the company and agent access to the requesting agent. Resume the agent only after an assigned inbox is active. Manual setup should ask for an agent and email address, then finish. Address checks should run as the user types. Taken addresses should show clickable alternatives. A domain dropdown beside the name should prefer a verified custom domain. Setup should suggest authorized saved AgentMail keys and show agent avatars in the picker and selected value. **Steps to reproduce** 1. Ask an agent to connect AgentMail when it has no assigned inbox. 2. Check that an inline API-key card appears and links to the provider's API-key page. 3. Open AgentMail setup, choose an agent, and request an address that is already taken. 4. Correct the inline error, refresh, and finish setup with the same request ID. 5. Inspect native dropdown carets in light, dark, disabled, and right-to-left states. Uses the bounded provider-error parser merged in #14768. Related work: #13256 introduced AgentMail; #14725 expanded connection search. ## What Changed - Stop recurring email queries for tasks that have no email thread. Share the query between the thread provider and activity view. Keep email-task updates and invalidation-based discovery. - Make AgentMail available without the experimental chat setting. Keep the catalog, setup and management routes, agent Channels tab, task email feed, receiving worker, and agent tools available by default. Other experimental chat providers stay gated. - Make the email address and copy icon a single clickable action with the shared Copied! confirmation. Add View inbox linking directly to the matching AgentMail console inbox, with the address encoded as one URL path segment. - Reorganize inbox Settings around the copyable email address, usage instructions, and receiving status. Move reconnect credentials into a disclosure and separate the Disconnect action. Add production Settings stories for active, paused, unassigned-address, revoked, webhook, long-address, mobile, and reconnect states. Show repair controls when the inbox has an error. Keep usage instructions tied to an active inbox with an address. - Add AgentMail channel intents and an inline key field with the direct API-key URL. - Keep setup and retry state tied to the interaction. Require an active inbox for completion. Preserve company and agent access checks. - Reduce manual setup to agent selection and email selection. Put the domain dropdown beside the address and default to a verified custom domain. Preserve explicit choices across reloads. Keep receiving settings under Advanced options. - Check the initial address and edits after a 350 ms pause. Abort superseded requests and ignore stale responses. Show clickable suggestions and retain known creation conflicts across reloads. - Add a company-scoped, manager-only address check using the saved credential. Search the visible inbox list instead of fetching an uncreated inbox: live AgentMail retains negative lookups that can break subsequent access-key creation. Unlisted addresses remain unknown; creation is authoritative. - Suggest labeled saved AgentMail keys in both manual setup and the inline card. Filter by company, provider, active credential, and current-user grants on the server. Prefer an account key and preserve the selected key or an explicit new-key choice across refresh. Use verified scope metadata and bounded concurrent checks for legacy keys. Never return secret values. - Catch an inbox-only key before the email step. Allow its existing inbox only after an explicit choice. Recover old locked drafts at the key picker. Save the replacement key before retiring an empty draft, then use a new setup URL so refresh preserves the switched account; stop if cleanup fails. Preserve already allocated addresses and their original accounts. - Use the shared AgentSelect in email setup. Show the canonical agent avatar in each option and the selected value, including other consumers of the shared component. Add regression coverage for legacy and current Lucide agent-mention icon formats. - Start each catalog Add connection with a fresh setup identity. Honor Finish setup's exact draft/account/address instead of resuming an unrelated browser draft. Return Cancel and Done to Connectors and Email settings to the inbox. Group the task/thread explanation in a How it Works card. - Route AgentMail catalog removal through the email inbox control API, including unfinished drafts. Refresh both the catalog and inbox views. - Render each inbox management tab separately. Access uses the saved account grants and agent controls; Conversations and Activity use the shared persisted email feed. Activity lifecycle actions use the email API. Reconnect returns to inbox Settings. Conversation failures show a retry instead of a false empty state. Email delivery recovery stays in the task. - Map documented provider address conflicts to a field error. Preserve actionable messages for other failures. - Preserve non-secret draft fields across refresh, scoped to the requested agent. Never save API keys in browser storage. Resume partial inbox creation with the original agent, address, and request ID. - Show an already-created address with explicit retry and new-address recovery instead of locked inputs. Preserve the original inbox and resumable draft when choosing another address. Distinguish runtime-key 404 errors and log safe provider status/operation/code. - Apply final agent access once within email setup authorization for a new account whose original installs are unchanged. Preserve later permission edits and reused account installs. Support in-place retry of progress loading. - Let a failed inline setup change keys after retiring an empty draft. Persist its replacement setup identity without storing secrets. Recover a server-saved account when refresh interrupts the save response, while preserving intentional account changes. - Render the production setup in Storybook and add error, recovery, and mobile states. - Inset native select carets in shared CSS. Preserve custom icons, listboxes, keyboard behavior, and forced-color controls. - Add browser regression coverage and an AgentMail Product E2E case with persisted-state and rendered-card evidence. ## Verification - Full `pnpm -r typecheck`, `pnpm build`, `pnpm check:token-gates`, and `git diff --check` passed after the default-availability change. - All 485 focused tests passed. These cover setup, management, catalog and route gates, connection intents, email authorization, Cursor execution, and the OpenAPI contract. All 39 email integration tests run with the experimental chat setting off. - The shared polling change passed four behavioral tests, UI typecheck and build, and token gates. - `tests/e2e/agentmail.spec.ts` passed with the actual server setting off. This full-stack browser test uses simulated provider responses. It covers catalog entry, saved keys, editable address and domain controls, creation, conflicts, retry, all management tabs, clipboard feedback, the provider link, and task email rendering. - In the live local browser, Add connection reached the editable email step with the saved account key. The verified custom domain was selected by default. Both domain choices worked. The existing inbox Settings page remained available. Both active inboxes completed new mail checks with the setting off. No new provider inbox or email message was created for this pass. - Earlier live provider acceptance covered creation on a verified custom domain, Finish connecting on the reported draft, successful mail checks after refresh, and catalog removal of disposable draft and active connections. Clicking the email address copied the exact address and showed Copied!. View inbox opened the same inbox in AgentMail’s console. No email messages were sent. - Production setup and Settings Storybook builds and interactions passed. Settings states include active, paused, unassigned, revoked, webhook, long-address, mobile, and reconnect. Receiving and revoked-access stories had zero accessibility violations. - Full local `pnpm test:run` on an earlier revision completed with 14,709 passing, 87 skipped, and four transient failures. All four failed cases passed in focused reruns without product changes. That serial full local command was not repeated after each follow-up. The latest-head full CI suite is the final test gate. - CI found an obsolete browser assertion that hid every channel when the flag was off. Updated it to keep AgentMail and the Channels surface visible while preserving the GitHub chat route gates. All 11 provider browser tests passed locally after scoping the Channels selector to the agent sidebar. Two initial local attempts stopped at temporary Postgres initialization. The passing run used a separate disposable database on the existing local Postgres server; it was removed after the test. - Updated the remaining sidebar and aggregator discovery assertions for default AgentMail availability. Ordinary task fixtures now return no email thread. All 128 sidebar/task-page tests and all 42 aggregator tests passed locally. - Latest head `b42bb4cd5cc9f2d01a99ab8026832d5a956ea85f`: full CI passed, with 54 successful checks including Snyk and two intentional Storybook skips. The CI run is https://github.com/paperclipai/paperclip/actions/runs/37020833647. A fresh Greptile review scored 5/5 with no unresolved threads. Live model evaluations and inbound/outbound email delivery were not run. ## Risks - AgentMail no longer needs experimental opt-in. Setup still requires a human to connect an account and assign an inbox. Inline setup creates an inbox after a human submits a new or saved key. Company access, agent access, inbox assignment, and completion checks remain enforced. - AgentMail read APIs cannot prove global address availability. The visible-list check is bounded to 100 entries and cannot see inboxes outside the key’s scope. The UI reports this limitation, suggests alternatives without claiming they are free, and keeps final creation conflicts inline. Lookup outages show an error without preventing the authoritative creation attempt. - Native select CSS affects the whole app. Custom-icon selects and multi-row lists are excluded. Forced-color mode keeps the browser caret. - Saved-key discovery uses stored verified scope metadata and checks authorized legacy credentials concurrently within a shared three-second deadline. Provider outages mark legacy choices unavailable; users can still enter another key. Final use rechecks authorization and provider access. - No database migration or transport default change. Live connection remains the default. ## Model Used OpenAI Codex, GPT-6, with reasoning, tool use, and code execution. The exact served model ID and context-window size are not exposed in this session. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass (focused suites; full-suite limitation documented 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 - [x] All Paperclip CI gates are green (latest head `b42bb4cd5cc9f2d01a99ab8026832d5a956ea85f`) - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups (latest head `b42bb4cd5cc9f2d01a99ab8026832d5a956ea85f`) - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
e00d10d5d5 |
fix(connections): repair stale AI defaults from agent settings (#14916)
## Thinking Path > - Paperclip manages AI agents and controls the credentials used for their work. > - Managed AI connections resolve each responsible user's provider default. > - Agent settings created another account but kept the old default selected. > - A rejected provider test left the old account marked as connected. > - Claude ACP reported a typed login failure as a generic terminal-access error. > - This pull request repairs the selected account or selects the new login explicitly. > - Agents can save and run with the repaired credential, and failed logins request sign-in. ## Linked Issues or Issue Description - Fixes #14831. - Refs #13867. Environment failures remain separate from credential-health failures. ## What Changed - Add an agent-settings action to reconnect an unavailable personal default in place. Keep its connection, grant, default, and agent access. - State that a new account becomes the user's provider default. Select its returned grant before changing the agent binding. Keep the actual sign-in method. - Show default-update errors and allow retry without another provider login. - Show the agent-access choice. Connection managers start with company-wide access for their own tasks. Other members start with access for the current agent. - Use the server's connection-manager permission in the shared list response. This includes members with a custom management grant. - Mark credentials as needing attention after an explicit login rejection in Test or Save. This includes API-key 401 and 403 responses. Network, quota, and server failures keep the credential health unchanged. - Reuse the credential-generation check so an old failure cannot invalidate a newer reconnect. - Route Claude's typed provider `access` failure to the existing login-recovery flow. Replace its generic terminal-access fallback with a sign-in message. - Add regression tests and update the AI Connections documentation. ## Verification - Red: the UI tests failed on the missing reconnect action, unused returned grant, missing access choice, and lost default-update error. The server tests failed because rejected credentials stayed connected. The real ACP fixture returned `acpx_turn_failed` for typed login failures. - Green: 156 tests passed across the AI connection, hiring, agent field, and New Agent suites. All 37 environment-route tests passed. The Claude ACP authentication fixtures also passed. - `pnpm check:token-gates` passed. - `pnpm -r typecheck` passed. - `pnpm build` passed. - The full local `pnpm test:run` passed 707 files and 14,503 tests, then exited with an agent-conversation timeout and embedded PostgreSQL startup failures in unchanged suites. The isolated conversation and migration tests passed on rerun. Later local test groups did not run after this failure. - [All CI gates passed](https://github.com/paperclipai/paperclip/actions/runs/37012669356) on commit `38513dfe2`. This includes the full test matrix, browser tests, typecheck, build, Runner checks, and canary dry run. - Greptile reviewed commit `38513dfe2` and returned 5/5 with no open findings. - The regression tests use a real embedded database and a real ACP fixture process. Live provider sign-in requires a valid account and was not run. ## Risks - Connecting a new account from agent settings changes the user's provider default. The dialog states this before sign-in. - The displayed access choice can allow all company agents to use the account for its owner's tasks. Reconnect keeps the existing access. Server permissions still control installs. - Claude's typed `access` category maps to the provider's `auth_required` signal. Tool and workspace request failures retain their existing classification. - No database migration or provider credential format changes are required. ## Model Used - OpenAI GPT-6 through Codex. The exact served model identifier and context window are not exposed in this session. Capabilities used: reasoning, repository tools, code editing, and command 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> |
||
|
|
c46e41e81c |
fix(heartbeat): validate native MCP gateway ownership (#14914)
## Thinking Path > - Paperclip lets people manage agents and govern their tool access. > - Native runs receive an immutable MCP tool assignment for one agent. > - The gateway must enforce that owner when it authenticates a run token. > - Older gateway rows stored the owner only in metadata. > - This change validates the gateway and profile, binds new rows, and repairs valid older rows on reuse. > - It also delivers each native assignment once. > - Other agents cannot use the assignment, and explicit shared gateways keep their configured scope. ## Linked Issues or Issue Description Builds on #14012 by @busla (Jón Levy). That PR adds agent binding and seven regressions. This PR carries that fix onto current master and adds legacy authentication, profile validation, and duplicate-delivery coverage. Related: #14864 improves discovery memory use. **What happened?** Native gateway creation stored an owner in metadata but left `agentId` null. Authentication could therefore accept another agent's run token. Managed discovery could also deliver historical native assignments again. **Expected behavior** A native assignment accepts only its owner's run token. The gateway and profile must refer to the same immutable assignment. The current assignment enters the run configuration once. **Steps to reproduce** 1. Run the database fixtures in `heartbeat-runtime-mcp-servers.test.ts` on the baseline. 2. Create a native assignment and inspect its stored gateway owner. 3. Authenticate with another agent's run token, then inspect legacy reuse and managed delivery. 4. The baseline fails six ownership and delivery cases. The fix passes all twelve cases. **Paperclip version or commit** The red baseline is `f2e0f1963`. This PR is based on `cad26c6bf`, which includes the merged discovery fix. **Deployment mode** Native Paperclip Runner execution and managed Codex MCP delivery. Reproduction uses isolated database and HTTP fixtures. ## What Changed - Store the agent owner and agent context on new native gateways. - Validate profile and gateway assignment metadata before reuse or token creation. - Bind valid legacy rows with a company-scoped, null-owner update and validate the result. - Reject mismatched run tokens before legacy repair. - Identify native assignments by gateway metadata, the reserved profile key, or profile source. Reject missing or malformed provenance, including JSON null. - Exclude historical native assignments from managed gateway delivery. Keep their rows for existing runs. - Add twelve database and HTTP regressions and document the runtime contract. ## Verification - Red baseline: six regressions fail and four controls pass before the initial fix. Two additional regressions reproduce metadata-loss admission and a JSON-null TypeError before the review fix. - All twelve ownership regressions pass on the final code, including owner admission, cross-agent rejection, metadata loss, JSON-null HTTP 401, and explicit shared-gateway admission. Policy, listing-memory, and discovery HTTP coverage also passes. - Full workspace typecheck and build pass locally. Server typecheck and compilation pass again after the review fix. The final ownership and grant patches pass 42 combined database and HTTP regressions. - [Full CI](https://github.com/paperclipai/paperclip/actions/runs/37011383657) passes for `626a08ae66361cf586105877e24d806b1a7a9c20`: all 54 checks succeed; two optional Storybook checks skip. This includes full typecheck, build, all test shards, all eight E2E shards, runner verification, and the canary dry run. - Greptile scores that exact head 5/5. No review threads remain unresolved. ## Risks Invalid historical native gateway or profile metadata now rejects authentication. Valid unbound rows are repaired only when their owner reuses the assignment. Conflicting owners are never overwritten. Historical rows are retained for existing runs. Explicit shared gateways use ordinary profiles and keep their configured scopes. The reserved native profile namespace remains agent-owned even when gateway metadata is cleared. No schema or dependency changes are included. ## Model Used Original fix and seven regressions in #14012: Anthropic Claude Opus 5.5, `claude-opus-5-5`, 1M context, as reported by @busla. Extensions and verification: OpenAI Codex (GPT-6), with reasoning, repository inspection, code execution, and tests. This session does not expose the exact serving model identifier or context window. ## 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> |
||
|
|
483dbc8890 |
fix(tool-access): enforce stored grant restrictions (#14915)
## Thinking Path > - Paperclip governs the tools that agents can discover and call. > - Stored grants can limit access to a tool, connection, or application. > - The grant matcher must enforce every restriction in that scope. > - A nonmatching allow list fell through to a policy selector matcher that ignores allow. > - This change requires an explicit allow match and validates additional selectors. > - Malformed and unknown restrictions deny access. > - Discovery and execution now enforce the same stored grant limits. ## Linked Issues or Issue Description Related: #14864 adds the shared database and HTTP discovery fixture used here. Searched existing public PRs for tool grant scope fixes. No duplicate scope-validation fix was found. **What happened?** A stored grant with a nonmatching `scope.allow` could authorize a tool. Empty or malformed allow lists, unknown selectors, and combined mismatching selectors could also authorize access. The fallback policy matcher does not validate stored grant JSON. **Expected behavior** An explicit allow list must match the requested tool, connection, or application. Every additional selector must also match. Unknown or malformed restrictions must deny access. Existing null and empty-object scopes keep their broad grant behavior. **Steps to reproduce** 1. Run `tool-grant-scope.test.ts` on the baseline. 2. Create a deny profile and a grant that names another tool. 3. Attempt discovery or a call for the tool outside the grant. 4. The baseline authorizes access. The fix denies it. **Paperclip version or commit** The red baseline is `f2e0f1963`. This PR is based on `cad26c6bf`, which includes the merged discovery fix. **Deployment mode** The company-scoped MCP gateway. Reproduction uses isolated database fixtures and a deterministic HTTP provider. ## What Changed - Require an explicit allow entry to match the gateway or upstream tool name, connection, or application. - Apply all additional selectors after the allow match. - Reject unknown selectors, invalid value types, empty restrictions, and non-object scopes. - Preserve null and empty-object scope compatibility. - Add sixteen regressions, including discovery, successful execution, and revocation through the HTTP gateway. - Document stored grant scope behavior. ## Verification - Red baseline: seven restricted-scope cases and three malformed-root cases fail. HTTP discovery also exposes tools outside the grant. - All 16 grant regressions and 35 adjacent policy tests pass locally. The HTTP test excludes an ungranted tool from discovery, returns 403 for its call, and verifies that no provider call occurs. It also checks successful execution and later revocation. - Server typecheck passes. The final ownership and grant patches also pass 42 combined database and HTTP regressions. - [Full CI](https://github.com/paperclipai/paperclip/actions/runs/37011177989) passes for `803fa9440111742672c94c4471e5b98f15dd3b97`: all 54 checks succeed; two optional Storybook checks skip. This includes full typecheck, build, all test shards, all eight E2E shards, runner verification, and the canary dry run. - Greptile scores that exact head 5/5. No review threads remain unresolved. ## Risks Stored scopes with unknown keys or malformed restrictions now deny access. Operators must correct those grants before they can authorize tools. Null and empty-object scopes keep their previous broad behavior. There are no schema, dependency, or API changes. ## Model Used OpenAI Codex (GPT-6), with reasoning, repository inspection, code execution, database regressions, and HTTP tests. This session does not expose the exact serving model identifier or context window. ## 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> |
||
|
|
cad26c6bfb |
fix(tool-gateway): bound MCP discovery memory and concurrency (#14864)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Agents discover governed tools through the MCP gateway. > - A listing repeated policy and full run-row reads for each catalog tool. > - Parallel listings multiplied those allocations during run startup. > - One 900-tool baseline listing used 11,489 queries and about 1.7 GiB of extra heap in a fixture. > - This pull request shares reads within a listing and bounds whole listings across the process. > - The benefit is lower discovery memory use while execution still checks current policy. ## Linked Issues or Issue Description Refs #13115. Its on-demand target change affects the same listing loop. **What happened?** MCP discovery repeated roughly 13 reads per tool. Full run snapshots and repeated connection configurations caused large allocations. Per-listing bounds alone did not limit concurrent listings across gateways. **Expected behavior** Discovery reads shared inputs once per listing. The process bounds active and queued listings. Catalog payload size and policy evaluation still grow with the catalog. Tool execution checks current access rules. **Steps to reproduce** Create a company with a remote MCP connection, 900 catalog tools, large schemas, and a large run snapshot. Send concurrent tools/list requests using a run-bound gateway token. Run the committed benchmark for a deterministic reproduction. **Paperclip version or commit** Baseline: |
||
|
|
4a999089ef |
Retry transient failures in dashboard reads (#14873)
## Thinking Path > - Paperclip shows company activity in the dashboard. > - The dashboard reads company, task, approval, and cost data. > - A pooled database connection can close during one of these reads. > - The driver must reject ambiguous statements because writes may have committed. > - These four dashboard queries are known to be read-only. > - This change retries only the failed read and preserves completed work. ## Linked Issues or Issue Description Refs #14773, which correctly removed automatic replay of ambiguous database statements. Searched existing database and dashboard PRs. Related #8780 changes pool recycling and logging; #13925 adds dashboard consistency coverage. Neither provides these per-query retries. **What happened?** A dashboard request returns a server error when its company lookup, task count, approval count, or monthly spend query loses its database connection. Drizzle wraps the driver's connection error in `cause`. **Expected behavior** A transient connection failure gets a bounded retry of the specific read. Completed reads and budget processing are not replayed. Persistent outages and non-connection errors still fail the request. **Steps to reproduce** Inject a typed `CONNECTION_CLOSED` error into one of these reads. Then allow the next query to succeed. Before this change, the dashboard request fails immediately. ## What Changed - Apply independent retries to the company lookup, task counts, pending approval count, and monthly spend query. Each callback rebuilds its own query with the same company scope. - Extract the existing authentication retry helper as `retryIdempotentDatabaseOperation`. Preserve authentication behavior and its existing exports. - Retain the existing limit of three total attempts with 50 ms and 100 ms pauses. Match typed connection codes through the error cause chain. - Test later-read failures, unchanged query parameters, retry exhaustion, missing companies, and errors that must not retry. Document the boundary. ## Verification - Final focused dashboard, authentication, and real database wire suites: 38 tests passed. Six initial recovery regressions failed before the implementation. - `pnpm -r typecheck`: passed on the final source. - Independent review: no actionable findings. The reviewer separately passed all 38 focused tests and checked the code allowlist, attempt bounds, pauses, and final error identity. - `pnpm test:run`: the general-server group completed with 14,738 tests passed, 13 failed, and 87 skipped. All 13 failures match the previously reproduced clean-base macOS skill-cache failures. The two test files and their implementations are unchanged from that baseline. The runner exited after this group, so the remaining local workspace and serialized groups did not run. All corresponding Linux CI groups passed on this commit. - `pnpm build`: passed on the final source. - Full CI: 53 successful checks and 2 skips on `6a113529c0`. Greptile: 5/5 on that commit, with no review threads or remaining findings. - Merge compatibility with master `f2e0f19630`, including #14866: no conflicts. The five reviewed files are unchanged in the resulting merge tree. ## Risks A persistent outage adds at most two retries per covered query. Each connection attempt retains the configured driver timeout. The change does not repair the underlying network or database failure. Agent counts, run-activity queries, and the budget workflow stay outside these retry boundaries. General database statements and disconnected transactions are not replayed. There is no schema or authorization change. ## Model Used OpenAI GPT-6 through Codex, with reasoning, repository inspection, code editing, and test execution. The runtime does not expose a more specific serving model identifier or context-window size. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass (38 focused tests; the full local run has the baseline limitation documented 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 - [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> |
||
|
|
427e048405 |
fix(company-skills): approve managed-checkout project dirs for local skill import (#10329)
## Thinking Path
> - Paperclip is the open source app people use to manage AI agents for
work
> - Company skills can be imported into a company from a local folder;
`companySkillService.importFromSource` guards this with
`assertLocalImportSourceAllowed`, which only permits import sources
inside an approved set of roots (managed skills root + registered
project-workspace cwds), realpath-resolved and `${root}${sep}`-anchored
to prevent path traversal/escape
> - A project can exist as a `managed_checkout` (server-managed clone)
with **no registered `project_workspaces` row** — its `primaryWorkspace`
is `null` and `workspaces` is `[]`, so its only real on-disk location is
the server-derived `codebase.managedFolder`
> - Because `configuredRoots` was built solely from the managed skills
root and `workspaces[].cwd`, a `managed_checkout` project's
`managedFolder` was never an approved root, so importing a skill from
that project's own folder was rejected with
`skill_workspace_boundary_denied`
> - This PR adds each project's server-derived `codebase.managedFolder`
to `configuredRoots` so in-place skill imports from managed-checkout
projects are allowed
> - The benefit is that managed-checkout projects can re-import their
own skills in place, without weakening the traversal/escape protections
(the new roots are server-derived and matched exactly like the existing
ones)
## Linked Issues or Issue Description
No public GitHub issue. Describing in-PR (bug):
**What's wrong:** `assertLocalImportSourceAllowed` denies a legitimate
local skill import (`skill_workspace_boundary_denied`) for any project
that is a `managed_checkout` with no registered workspace row.
**Repro:** Create/import a company skill from a `managed_checkout`
project's own folder (`codebase.managedFolder/.agents/skills/<skill>`).
The import is rejected even though the source is inside the project's
server-managed checkout.
**Expected:** The import from a managed-checkout project's own
`managedFolder` subtree should be allowed, while paths outside that
subtree remain denied.
Related context (already merged): #9564 introduced the open-by-default
skill policy / this import boundary. This PR does not change that
boundary's matching logic — it only adds a missing, server-derived
approved root.
## What Changed
- `server/src/services/company-skills.ts`: add
`...projectRows.map((project) => project.codebase.managedFolder)` to
`configuredRoots` in `assertLocalImportSourceAllowed`. `managedFolder`
is server-derived (`resolveManagedProjectWorkspaceDir(companyId,
projectId)` → instance root + sanitized ids); it is
`fs.realpath`-resolved and `${root}${sep}`-prefix matched exactly like
every existing root. `managedFolder` is used rather than
`effectiveLocalFolder` because the latter can fall through to a
user-registered `localFolder`, which is already covered by the
registered workspace cwds.
- `server/src/__tests__/company-skill-import-boundary.test.ts`: add a
regression test — a managed-checkout project's `managedFolder/<skill>`
import is **allowed**, and a **prefix-adjacent sibling** (`managedFolder
+ "-evil"`) stays **denied**.
## Verification
- `cd server && ./node_modules/.bin/vitest run
src/__tests__/company-skill-import-boundary.test.ts` → **2/2 pass**
(embedded-Postgres suite). Covers both the new allow case and the
prefix-adjacent deny case, alongside the existing out-of-tree /
symlink-escape / non-file-scheme rejections.
## Risks
Low risk. The change only **adds** approved roots; it does not alter the
realpath + `${root}${sep}`-anchored matching that closes
traversal/prefix-adjacency escapes. The added roots are fully
server-derived from the instance root + sanitized company/project ids
(same trust class as the existing `resolveManagedSkillsRoot`) — no value
derived from the import `source` argument reaches them. Sanitization
(`[^a-zA-Z0-9._-]+ → -`) prevents separator/level injection, and the
only user-influenced segment (repo name) is normalized via `new
URL(...)`. The regression test's prefix-adjacent (`-evil`) case asserts
the escape class stays closed.
## Model Used
Claude Opus 4.8 (`claude-opus-4-8`), extended thinking + tool use (code
execution, git). Implementation and security review were produced with
Claude; this integration/PR was prepared with `claude-opus-4-8`.
## 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 (N/A —
internal boundary fix, no user-facing docs)
- [x] I have considered and documented any risks above
- [ ] All Paperclip CI gates are green (CI in progress)
- [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
(pending review)
- [x] I will address all Greptile and reviewer comments before
requesting merge
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: brandonburr <brandonburr@gmail.com>
|
||
|
|
2a36e915ef |
build(deps): bump @vercel/connect from 0.6.1 to 2.3.3 (#13390)
Bumps [@vercel/connect](https://github.com/vercel/vercel/tree/HEAD/packages/connect) from 0.6.1 to 2.3.3. <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/vercel/vercel/blob/main/packages/connect/CHANGELOG.md">@vercel/connect's changelog</a>.</em></p> <blockquote> <h1><code>@vercel/connect</code></h1> <h2>2.0.2</h2> <h3>Patch Changes</h3> <ul> <li>c028593: Update the Core SDK documentation to show how to start an authorization request.</li> </ul> <h2>2.0.1</h2> <h3>Patch Changes</h3> <ul> <li>2ecb357: <code>connectGitHubCredentials</code> now resolves the GitHub App slug from the connector's metadata and exposes it as <code>appSlug</code> on the returned credentials, so eve's <code>githubChannel</code> can derive its invocation token (<code>botName</code>) without extra configuration.</li> </ul> <h2>2.0.0</h2> <h3>Major Changes</h3> <ul> <li>42938f9: Make Eve connector provisioning opt-in with <code>autoProvision: true</code>. When enabled, try token and authorization requests before provisioning, then provision and retry once only when the connector is missing or not linked to the project.</li> </ul> <h2>1.1.0</h2> <h3>Minor Changes</h3> <ul> <li>b9fab7c: Add Sendblue credential helpers for Eve-native channels and the Chat SDK adapter, including Connect trigger-forwarded webhook verification for Chat SDK users.</li> </ul> <h2>1.0.0</h2> <h3>Major Changes</h3> <ul> <li>9b55136: Default omitted scopes to <code>['*']</code> in token and authorization requests.</li> </ul> <h3>Minor Changes</h3> <ul> <li>4199902: Send Vercel API requests to the region from <code>VERCEL_REGION</code>, with a <code>region</code> option to override it.</li> </ul> <h2>0.9.0</h2> <h3>Minor Changes</h3> <ul> <li>46a5aaa: Add Linq helpers for Eve and Chat SDK applications. <code>connectLinqCredentials</code> resolves an app-scoped Linq API key, and <code>connectLinqAdapter</code> adds trusted Connect OIDC verification for trigger-forwarded Linq webhooks while retaining the provider signing secret within Connect.</li> </ul> <h2>0.8.1</h2> <h3>Patch Changes</h3> <ul> <li><code>@vercel/oidc</code><a href="https://github.com/3"><code>@3</code></a>.8.5</li> </ul> <h2>0.8.0</h2> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li>See full diff in <a href="https://github.com/vercel/vercel/commits/@now/next@2.3.3/packages/connect">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> |
||
|
|
f2e0f19630 |
Defer agent directory cleanup until stop proof is available (#14866)
## Thinking Path > - Paperclip manages agents and their persistent files. > - Each run owns a temporary agent directory and a save receipt. > - Cleanup needs independent proof that the owning process stopped. > - A cleanup call without that proof currently waits for the directory lock anyway. > - A second lock failure can prevent environment release after the run already reported a failed save. > - This change skips cleanup that has no authority and retries unavailable remote copies after exact destruction proof. > - The save failure stays visible. Existing lock owners remain protected. ## Linked Issues or Issue Description Related work: Refs #14787 (lock diagnostics), #14695 (warm instruction ownership), #9667 (stale lock proposal), and #9872 (control-plane ownership proposal). I checked open PRs and issues. This change leaves the shared filesystem lock protocol in place and does not duplicate the warm-retention work in #14695. **What happened?** Heartbeat cleanup records an explicit unavailable instruction-save warning, then calls directory release before releasing the environment lease. Release can wait for a lock even though the copy has no process-stop proof and cannot be removed. That secondary timeout prevents the following lease-release step. If destruction proof arrives later, the unavailable copy is excluded from both recovery queries. **Expected behavior** Skip a release that cannot remove anything. Preserve the failed-save receipt and candidate fields. Once exact remote destruction is recorded, recover remote cleanup without running a provider command. Unavailable local copies retain their potentially uncollected edits even if local stop proof arrives later. A blocked cleanup must not prevent cleanup for other agents. **Steps to reproduce** 1. Prepare an agent directory, report its save unavailable, and leave process-stop proof absent. 2. Hold the shared directory lock and call release. Before this change, release waits and fails although removal is not authorized. 3. Record destruction of the copy's exact remote lease. Before this change, neither recovery sweep selects the unavailable copy. **Paperclip version or commit** Reproduced against `efc2e6810e9bc0dc8cb412b0e7647c0db9821caa`. **Deployment mode** Local and remote execution with persistent agent directories. Tests use an isolated embedded PostgreSQL database and fixture transports. ## What Changed - Re-read receipts and skip release before lock acquisition when stop proof is absent, the copy is superseded, or cleanup is complete. Keep the same checks inside the lock. - Recover unavailable remote copies only after exact destruction proof. Preserve their unavailable state, errors, candidate hash, and candidate bytes. Keep unavailable local copies and their uncollected edits unchanged. - Store destruction-only cleanup authority with the stop proof. Later cleanup honors it after a lost database response or restart, including when a transport remains cached. - Defer failed or unproven cleanup with bounded batches and a retry delay. Keep failed cleanup visible in logs and its receipt. - Serialize preparation of an existing run with cleanup. Fresh run preparation keeps its existing admission path. - Cover held locks, receipt scope, delayed proof, batch fairness, lost update responses, cached transports, and concurrent same-run preparation with database regressions. ## Verification - Focused directory, legacy instruction-copy, shared lock, and bounded diagnostic suites: 169 tests passed across four files. - `pnpm -r typecheck`: passed on the final source. - `pnpm build`: passed on the final source. - Completed all selected local `pnpm test:run` groups: 733 general server suites, 149 serialized suites, and 14 workspace projects. There are 13 known macOS `EACCES` failures in the unchanged runtime skill cache tests. Their exact signatures match earlier clean-base results, and the cache source and test blobs match both that base and this PR base (existing fix: #14290). One CLI import test timed out under concurrent load; its full file passed separately (17 tests). Broad coverage began before the review corrections; the final source has the focused 169-test run, typecheck, and build. This is a local verification limit, not a passing full local suite. - `git diff --check` and local Gitleaks plus private-identifier/PII diff scans passed. - Independent review of the final source found no remaining actionable issue. Its 17 targeted tests cover crash recovery, cached transports, same-run preparation, real local edit preservation, proof scope, and batch fairness. The main focused run also covers contained scheduling failures. - Final commit `35a24085f7`: Greptile 5/5 with no recommendations and zero unresolved review threads. - Final commit `35a24085f7`: all 53 checks passed, including Canary Dry Run and the security scan; two visual checks were intentionally skipped. The workspace shard passed on retry after GitHub reported that its first runner lost communication. An earlier Canary runner shut down after the release dry run passed. Neither interruption recorded an application assertion failure; the exact final-head checks are now green. ## Risks - This repairs cleanup ordering and recovery eligibility. It does not repair an ambiguous legacy lock owner or restore unsaved files. Actual collection still fails visibly when its lock cannot be acquired. - An unavailable remote copy is recovered only after exact destruction proof. A stopped but retained environment stays protected; recovery does not execute a command that could restart it. - Unavailable local copies with later stop proof still retain potentially uncollected edits. A general local recollection or reclamation policy remains outside this change. - Existing-run preparation now waits for the same lock as cleanup. The fresh-run path is unchanged. - The cleanup mode is stored in the existing private receipt JSON. No schema migration or public API change is required. - No deployment, task replay, or runtime lock deletion was performed. ## Model Used OpenAI GPT-6 (Codex), with reasoning, repository tools, and test execution. The runtime does not expose a more specific model suffix or context-window size. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` 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 references) - [x] My branch name describes the change and contains no internal Paperclip ticket id - [ ] 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> |
||
|
|
4039d4f06b |
fix(auth): allow scoped low-trust work and owner-chat instruction edits (#14870)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Low-trust agents must work within their assigned scope. > - Task creation currently rejects these agents before checking assignment permission or scope. > - Persistent instruction saves also reject direct requests from authorized chat owners. > - This PR checks the requested action and its recorded authority instead of denying all such work. > - Agents can organize permitted work and follow their owner's instruction-edit requests while outside work stays restricted. ## Linked Issues or Issue Description **What happened?** Low-trust agents cannot create self-assigned tasks or subtasks, even within their allowed scope. An authorized user also cannot ask an agent in their own Agent Chat to update its managed `AGENTS.md`. Agent-folder collection can hide the permission rejection behind a generic save failure. **Expected behavior** Allow task creation when assignment permissions and project or root-task scope permit it. Allow instruction self-edits during authenticated owner-chat execution, subject to the user's current edit permission. Outside tasks, subtasks, connector messages, and peer agents do not inherit that instruction authority. Explain the actual denial when a save fails. **Steps to reproduce** 1. Configure an active agent with `low_trust_review` and a project or root-task boundary. 2. Ask it to create an in-scope task assigned to itself, or a subtask of its own task. 3. As a user with permission to configure that agent, ask it in your Agent Chat to update its managed `AGENTS.md`. 4. Observe blanket permission denials rather than action-specific checks. **Paperclip version or commit** Rebased onto master at `8ec4b84e1`. This is a core authorization change, independent of adapter choice. **Deployment mode** Authenticated server. Regression coverage uses the server services, HTTP routes, native tool authority, and embedded PostgreSQL. Related work: #14775 adds human-directed task execution. #13599 concerns instruction-path configuration; this PR leaves that configuration restricted. #11988 proposes separate active-review instruction protection. #10693 reports unclear authorization denials on a different API surface. ## What Changed - Apply task-assignment checks to both HTTP creation routes and native task creation, including unassigned work. Preserve low-trust policy and source attribution on the created task and its initial plan. - Allow self-assigned decomposition within the permitted project or root-task tree. Resolve workspace-derived project scope before authorization, and reauthorize existing tasks before duplicate detection returns them. Keep cross-project and peer-assignment checks. - Derive instruction self-edit authority from the accepted run identity and authenticated owner-message wake. Recheck current permissions at save time. Bind retries to the same request and chat session. - Reject inherited instruction authority from outside tasks, subtasks, plugins, connectors, stale sessions, cancelled runs, and peer edits. - Surface permission errors in instruction and agent-folder save receipts. Tell chat agents to explain the rejected action and the specific restriction. - Update the low-trust policy and implementation documentation. ## Verification - All 297 tests in 11 focused server suites pass after the rebase. These cover owner-chat saves, private copies, warm agent directories, reset and retry boundaries, permission revocation, task creation routes, and native tool authority. - After review fixes, all 126 tests in the four affected authorization/chat suites pass. Workspace scope regressions and 146 existing creation/ownership/workspace-route tests also pass. - The final duplicate-task and CI fixes pass all 39 tests across chat-project tools, duplicate creation, environment-selection guards, and assignee-invokability routes. The duplicate-task test reproduced an unauthorized response before the fix and verifies denial plus permitted reuse afterward. - `pnpm --filter @paperclipai/server typecheck` passes after rebasing; `pnpm --filter @paperclipai/server exec tsc --noEmit` also passes after the review fixes. - `git diff --check origin/master...HEAD` passes. - Final head `7e73270b86748792649e4ae6fbc6879f73b42b73`: all 54 checks passed, with two expected skips and no pending or failed checks. This includes builds, typechecking, the full test matrix, end-to-end tests, runner verification, the canary dry run, and security scans. - Greptile is 5/5 on that exact head, with no unresolved review threads. This change has not been deployed to staging. ## Risks This changes authorization behavior. The instruction exception must not become an inherited task permission. The check uses server-owned execution records, requires the agent's own chat and instructions, and keeps normal protected-change and responsible-user checks. Saves fail closed when current provenance or permission is missing. Owner chat grants a turn-scoped capability; the server does not classify the message intent or require approval of the exact new file bytes. Prompt injection within an authorized owner-chat turn remains a model-level risk. This is the requested owner-chat trust boundary, without a new per-edit confirmation flow. No database migration or broad trust-preset change is required. ## Model Used OpenAI Codex, based on GPT-6, with reasoning, code editing, shell tools, and test execution. The exact runtime model ID and context-window size are not exposed in this session. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
793a98cd8c |
chore(deps): bump open from 11.0.1 to 11.0.4 (#13473)
Bumps [open](https://github.com/sindresorhus/open) from 11.0.1 to 11.0.4. <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.4</h2> <ul> <li>Fix <code>browser</code>/<code>browserPrivate</code> not detecting Safari or Brave as the default browser 6ae6196</li> </ul> <hr /> <p><a href="https://github.com/sindresorhus/open/compare/v11.0.3...v11.0.4">https://github.com/sindresorhus/open/compare/v11.0.3...v11.0.4</a></p> <h2>v11.0.3</h2> <ul> <li>Fix Windows launches being killed when the parent process exits 734b821</li> </ul> <hr /> <p><a href="https://github.com/sindresorhus/open/compare/v11.0.2...v11.0.3">https://github.com/sindresorhus/open/compare/v11.0.2...v11.0.3</a></p> <h2>v11.0.2</h2> <ul> <li>Update dependencies 6f006ad</li> </ul> <hr /> <p><a href="https://github.com/sindresorhus/open/compare/v11.0.1...v11.0.2">https://github.com/sindresorhus/open/compare/v11.0.1...v11.0.2</a></p> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/sindresorhus/open/commit/41511103abd932225b605b8e7f9e565cc180b1b6"><code>4151110</code></a> 11.0.4</li> <li><a href="https://github.com/sindresorhus/open/commit/6ae6196fa199cbc5eb4af007efd52e675c53b590"><code>6ae6196</code></a> Fix <code>browser</code>/<code>browserPrivate</code> not detecting Safari or Brave as the default b...</li> <li><a href="https://github.com/sindresorhus/open/commit/81deafb72a29ea16b2c3bdd30cdaf294aaa11d77"><code>81deafb</code></a> 11.0.3</li> <li><a href="https://github.com/sindresorhus/open/commit/734b821c36ee959dc11e380c3202770969347274"><code>734b821</code></a> Fix Windows launches being killed when the parent process exits</li> <li><a href="https://github.com/sindresorhus/open/commit/ccf1fd644de3dfc9448438e185037eceb2d5d3d7"><code>ccf1fd6</code></a> 11.0.2</li> <li><a href="https://github.com/sindresorhus/open/commit/52d2d62d6f02f023720f4ca5a2f73bf050ae3ee7"><code>52d2d62</code></a> Use <code>hasOwn</code> (<a href="https://redirect.github.com/sindresorhus/open/issues/372">#372</a>)</li> <li><a href="https://github.com/sindresorhus/open/commit/6f006ad1a80950ff0dd9eb7e3252634153e3ef12"><code>6f006ad</code></a> Update dependencies</li> <li>See full diff in <a href="https://github.com/sindresorhus/open/compare/v11.0.1...v11.0.4">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> |
||
|
|
8ec4b84e1c |
fix(chat): resume messages after failed runs without duplicate delivery (#14857)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - A user can send a new message after a native run fails. > - The server checks that the old execution has stopped before it starts a fresh turn. > - A failed run can retain a result accepted before checkpoint or cleanup failed. > - The continuation gate treated that saved result as active recovery and held the new message forever. > - This pull request removes that false liveness signal while retaining controller, process, environment, and authorization checks. > - Live staging then exposed a second defect: chat admission created a successor without consuming the original deferred receipt, so completion delivered the message again. > - Consume that exact receipt atomically with admission, while preserving separate turns for later chat messages. ## Linked Issues or Issue Description **What happened?** A new user message stayed in the queue with `controller_settling` after the previous run had reached `terminal_failure`. The old coordinator had no lease owner but still had a `resultId`. Its remote environment had a verified stop receipt. **Expected behavior** Start one fresh turn after execution has stopped and normal admission checks pass. Preserve the failed run and its accepted result as history. **Steps to reproduce** 1. Accept a native result, then fail checkpoint or cleanup and exhaust recovery. 2. Retain the result ID on the terminal failure record and stop the execution environment. 3. Send a new user message. Before this fix, it waits forever for the finished controller. **Paperclip version or commit** Reproduced in a database-backed regression test on `26900655b`. **Deployment mode** Server with a native runner and remote sandbox. Local process stop checks also apply. Related: https://github.com/paperclipai/paperclip/pull/14775. Searched existing PRs for retained-result continuation fixes; no duplicate found. ## What Changed - Remove the retained-result veto for terminal failures. - Keep controller ownership, successor, process, environment cleanup, pending decision, and ordinary admission checks. - Add regressions for retained results, active execution, missing stop evidence, and delayed remote cleanup. - Atomically consume the resumed receipt in agent chat, even though chat does not coalesce other queued messages. - Reproduce completion-time duplicate promotion, race cleanup against periodic recovery, and prove a subsequent chat message keeps its own turn. - Document that a saved result does not make a terminal failure active. - Keep exhausted workspace export on its separate repair path, tested through the production finalizer. ## Verification - Red: retained-result admission failed with `controller_settling` before the original fix. The new chat-specific regression then reproduced duplicate promotion when the first reply finished. - Green: 406 tests across native continuation, workspace-export recovery, and the wake-queue module passed on `cbc531cc0`. - The chat regressions exercise real Postgres transactions, simultaneous recovery callbacks, successful completion, the production queue-drain use case, and repeated drain attempts. A distinct follow-up remains a separate turn. - `pnpm -r typecheck` and `pnpm build` passed on `cbc531cc0`. - The earlier full local test run encountered a timeout and follow-on failure in unchanged AI connection-adoption tests; all 50 tests passed on isolated rerun. That local run was stopped after the full CI test matrix passed on the earlier head. - All 54 CI checks passed on `cbc531cc0` (2 skipped), including the full test matrix and browser shards. One unchanged interaction-route test returned HTTP 500 on its first CI attempt; its full 84-test file passed locally, and the failed shard passed on one targeted rerun. - Greptile reviewed `cbc531cc0`: 5/5, no unresolved findings. - Live staging first verified that the original saved message resumes and receives a successful response; that test exposed the duplicate now covered above. - Deployed exact commit `cbc531cc0410e1ef6e8811c6c5c014c3528351ed` to the affected staging workspace; deployment verification, health, authentication, and startup recovery passed. - Submitted a fresh message through the browser. The agent replied in 39 seconds; server records show exactly one successful run, native phase `committed`, no error, and an empty queue. A later check more than a minute after completion found no duplicate run. ## Risks The change affects admission after native execution failure and consumption of a resumed deferred receipt. A fresh turn must never overlap the prior execution, and consuming one chat receipt must not absorb later messages. Tests retain the controller, process, and remote-stop guards. This change does not migrate data, apply an old result, or reset the old retry budget. ## Model Used OpenAI Codex (GPT-6). The exact runtime model identifier and context window are not exposed in this session. Used reasoning, repository inspection, code execution, database-backed tests, and browser inspection. ## 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> |
||
|
|
8f7baf2f72 |
chore(deps): bump @aws-sdk/client-s3 from 3.1122.0 to 3.1141.0 (#13475)
Bumps [@aws-sdk/client-s3](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/clients/client-s3) from 3.1122.0 to 3.1141.0. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/aws/aws-sdk-js-v3/releases">@aws-sdk/client-s3's releases</a>.</em></p> <blockquote> <h2>v3.1141.0</h2> <h4>3.1141.0(2026-09-25)</h4> <h5>Chores</h5> <ul> <li><strong>codegen:</strong> smithy-aws-typescript-codegen 0.54.0 (<a href="https://redirect.github.com/aws/aws-sdk-js-v3/pull/8314">#8314</a>) (<a href="https://github.com/aws/aws-sdk-js-v3/commit/ad80ce3ebaf394679aabc6e26b2dcd023ce8e010">ad80ce3e</a>)</li> </ul> <h5>New Features</h5> <ul> <li><strong>client-connect:</strong> Agent Privacy During Hold is a new privacy capability for Amazon Connect Voice that prevents agent audio from being captured in call recordings or Contact Lens conversational analytics during hold. When enabled, agents are automatically muted on entering hold and unmuted on resuming the contact (<a href="https://github.com/aws/aws-sdk-js-v3/commit/03527f9ea153365c1e3654ac6d3f3e064d06b5d0">03527f9e</a>)</li> <li><strong>client-qconnect:</strong> Release shapes for the proactive agentic recommendations and the multi-knowledge base search features. Increases the maximum length of QuickResponseContent. (<a href="https://github.com/aws/aws-sdk-js-v3/commit/e008332b0b70c55d22dfca8a9c2317b67d06a5f3">e008332b</a>)</li> <li><strong>client-bedrock-agent:</strong> Adds support for calling VPC configuration API's in Bedrock. These configurations allow the use of On Prem connectors in Bedrock Managed Knowledge bases (<a href="https://github.com/aws/aws-sdk-js-v3/commit/18524dc69cf36ebbb8bc7bc33e0bce6311dcdb23">18524dc6</a>)</li> <li><strong>client-mediaconnect:</strong> This release adds support for RTMP push router outputs in AWS Elemental MediaConnect. (<a href="https://github.com/aws/aws-sdk-js-v3/commit/5bd8d80bbca2c1c2545521b03d741b46fccd09b4">5bd8d80b</a>)</li> <li><strong>client-securityagent:</strong> This release adds the ListActorMessages operation, which returns the multi-factor authentication messages received at an actor's server-generated email address (<a href="https://github.com/aws/aws-sdk-js-v3/commit/10e53d506db74c48b09b94d9b9387b84dd40ed58">10e53d50</a>)</li> <li><strong>client-arc-region-switch:</strong> Adds a service quota checker to Region switch to verify quota parity between your primary and standby Region, and automatically submit quota limit increases. Adds an optional EC2 Auto Scaling and ECS setting that waits for instances or tasks in the scaled-up Region to be healthy in target groups. (<a href="https://github.com/aws/aws-sdk-js-v3/commit/cca33e380a8985e23a0e3fbb420577aab4b60ac7">cca33e38</a>)</li> <li><strong>client-bedrock-agentcore-control:</strong> Amazon Bedrock AgentCore Payments now supports credential rotation for payment connectors, letting you rotate API and wallet secrets for Quick Create payment auths from the console. This release also adds Type and Creation type columns to the payment managers views. (<a href="https://github.com/aws/aws-sdk-js-v3/commit/adca591f07c448603de2876faaf7914cad441436">adca591f</a>)</li> <li><strong>client-neptune-graph:</strong> Add GraphIdentifier filter for ListImportTasks (<a href="https://github.com/aws/aws-sdk-js-v3/commit/9b9aea9b553ba84f006f95da5d8ffd5381cc8a17">9b9aea9b</a>)</li> <li><strong>client-rekognition:</strong> This release adds support for Feedback and Metadata in the GetFaceLivenessSessionResults response. Feedback returns codes explaining why a Face Liveness check produced its result. Metadata includes the client SDK type. (<a href="https://github.com/aws/aws-sdk-js-v3/commit/0831c361bb69d44357ff57360db39afdbb149337">0831c361</a>)</li> <li><strong>client-glue:</strong> add support for table level federation (<a href="https://github.com/aws/aws-sdk-js-v3/commit/a44458b77853cbb25a9fcb362b0a275d7dc1c69b">a44458b7</a>)</li> <li><strong>client-wellarchitected:</strong> This change releases the Well-Architected Agent, a generative AI service that analyzes a customer's AWS environment and delivers personalized, prioritized recommendations across cost, security, performance, and resilience. (<a href="https://github.com/aws/aws-sdk-js-v3/commit/d0656586067f70b8d50000300f04512dd089df96">d0656586</a>)</li> </ul> <hr /> <p>For list of updated packages, view <strong>updated-packages.md</strong> in <strong>assets-3.1141.0.zip</strong></p> <h2>v3.1140.0</h2> <h4>3.1140.0(2026-09-24)</h4> <h5>Documentation Changes</h5> <ul> <li><strong>client-route53resolver:</strong> Documentation updates for Route 53 Resolver. Clarifies which Outpost Resolver operations apply to first-generation AWS Outposts and that Resolver is managed automatically on second-generation Outposts. Adds Local Network Interface subnet compatibility notes for Resolver endpoints. (<a href="https://github.com/aws/aws-sdk-js-v3/commit/b4432abaaaf19bf4ac5d4d2b09bcc83e4d5440a0">b4432aba</a>)</li> <li><strong>client-iot:</strong> Fixed ListV2LoggingLevels and DeleteV2LoggingLevel documentation to include all supported target-types (<a href="https://github.com/aws/aws-sdk-js-v3/commit/4dcf76d527e0c1fe76d64cb8ea444ce62d64135b">4dcf76d5</a>)</li> </ul> <h5>New Features</h5> <ul> <li><strong>clients:</strong> update client endpoints as of 2026-09-24 (<a href="https://github.com/aws/aws-sdk-js-v3/commit/29a8566cb4c6eeb0cc554f4ae9bf985160556523">29a8566c</a>)</li> <li><strong>client-eventbridgev2:</strong> Introducing Amazon EventBridge enhanced Custom event bus, a new shareable event bus for organizational-scale event-driven applications feature ordered delivery, deduplication, open event formats, and cross-account bus sharing. (<a href="https://github.com/aws/aws-sdk-js-v3/commit/69fbe6a22fd7810332b0b0356803a0eee3f563cf">69fbe6a2</a>)</li> <li><strong>client-datazone:</strong> Amazon DataZone now supports the TOOLING blueprint category on CreateEnvironmentBlueprint, UpdateEnvironmentBlueprint, GetEnvironmentBlueprint, and ListEnvironmentBlueprints, for custom tooling blueprints. CreateConnection now accepts roleArn in iamProperties. (<a href="https://github.com/aws/aws-sdk-js-v3/commit/591cd6f5a7b714427cbe87b36b13357d560d48ea">591cd6f5</a>)</li> <li><strong>client-elasticache:</strong> Added tagging support for ElastiCache Global DataStore. (<a href="https://github.com/aws/aws-sdk-js-v3/commit/0fa9da5946312f09942dad6f711885855f0d0b8e">0fa9da59</a>)</li> <li><strong>client-marketplace-discovery:</strong> AWS Marketplace Discovery API now supports localized responses and SigV4a request signing. It returns new fulfillment details, including AMI architecture, EBS volume and security group information, SaaS quick-launch status, and SageMaker input and output MIME types. (<a href="https://github.com/aws/aws-sdk-js-v3/commit/510673e376bbc578d318308136ecb5a841416bc3">510673e3</a>)</li> <li><strong>client-redshift-data:</strong> Updates to the ListDatabases and WorkgroupName validation (<a href="https://github.com/aws/aws-sdk-js-v3/commit/218c24e106efe1ad64658984123af6634fc7278d">218c24e1</a>)</li> <li><strong>client-securityagent:</strong> Added support for Confluence export, enabling customers to publish security findings to Confluence pages. (<a href="https://github.com/aws/aws-sdk-js-v3/commit/81408527778af52f0c604a4eaca440f445082f78">81408527</a>)</li> <li><strong>client-cloudwatch:</strong> This release adds Create, Get, Update, and DeleteResourceMetricsConfiguration to enable detailed metric collection for an AWS resource, and adds UpdateOTelEnrichment plus include and exclude filters on StartOTelEnrichment so you can choose which metric namespaces CloudWatch enriches. (<a href="https://github.com/aws/aws-sdk-js-v3/commit/765cc1ce8f95a4f62d83dc07b81a927d74e09b52">765cc1ce</a>)</li> <li><strong>client-eventbridge:</strong> Adds a ManagedBy field to the DescribeEventBus and ListEventBuses responses, identifying the AWS service that created an event bus on your behalf. (<a href="https://github.com/aws/aws-sdk-js-v3/commit/28a639b27585c85376a4b5db528c31efb80e874d">28a639b2</a>)</li> </ul> <h5>Tests</h5> <ul> <li><strong>undici-http-handler:</strong> update bidi stream e2e test to nova-2-sonic model (<a href="https://redirect.github.com/aws/aws-sdk-js-v3/pull/8313">#8313</a>) (<a href="https://github.com/aws/aws-sdk-js-v3/commit/d9a37d9d318f2ef7f5bcf6286bf3c7b475e4175b">d9a37d9d</a>)</li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/aws/aws-sdk-js-v3/blob/main/clients/client-s3/CHANGELOG.md">@aws-sdk/client-s3's changelog</a>.</em></p> <blockquote> <h1><a href="https://github.com/aws/aws-sdk-js-v3/compare/v3.1140.0...v3.1141.0">3.1141.0</a> (2026-09-25)</h1> <p><strong>Note:</strong> Version bump only for package <code>@aws-sdk/client-s3</code></p> <h1><a href="https://github.com/aws/aws-sdk-js-v3/compare/v3.1139.0...v3.1140.0">3.1140.0</a> (2026-09-24)</h1> <p><strong>Note:</strong> Version bump only for package <code>@aws-sdk/client-s3</code></p> <h1><a href="https://github.com/aws/aws-sdk-js-v3/compare/v3.1138.0...v3.1139.0">3.1139.0</a> (2026-09-23)</h1> <p><strong>Note:</strong> Version bump only for package <code>@aws-sdk/client-s3</code></p> <h1><a href="https://github.com/aws/aws-sdk-js-v3/compare/v3.1137.0...v3.1138.0">3.1138.0</a> (2026-09-22)</h1> <p><strong>Note:</strong> Version bump only for package <code>@aws-sdk/client-s3</code></p> <h1><a href="https://github.com/aws/aws-sdk-js-v3/compare/v3.1136.0...v3.1137.0">3.1137.0</a> (2026-09-21)</h1> <p><strong>Note:</strong> Version bump only for package <code>@aws-sdk/client-s3</code></p> <h1><a href="https://github.com/aws/aws-sdk-js-v3/compare/v3.1135.0...v3.1136.0">3.1136.0</a> (2026-09-18)</h1> <p><strong>Note:</strong> Version bump only for package <code>@aws-sdk/client-s3</code></p> <h1><a href="https://github.com/aws/aws-sdk-js-v3/compare/v3.1134.0...v3.1135.0">3.1135.0</a> (2026-09-17)</h1> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/aws/aws-sdk-js-v3/commit/5bc8d9a96936723ac90d721e0c5a2bff7ee8520d"><code>5bc8d9a</code></a> Publish v3.1141.0</li> <li><a href="https://github.com/aws/aws-sdk-js-v3/commit/6050a3813c26795562b5ada8b0d9ea498eb9f8a1"><code>6050a38</code></a> Publish v3.1140.0</li> <li><a href="https://github.com/aws/aws-sdk-js-v3/commit/03d54a858f80012bbc60046a77242223e8dfd9d9"><code>03d54a8</code></a> Publish v3.1139.0</li> <li><a href="https://github.com/aws/aws-sdk-js-v3/commit/c68e50e4a6e0469a20c2894fe8a29c140553ebb8"><code>c68e50e</code></a> Publish v3.1138.0</li> <li><a href="https://github.com/aws/aws-sdk-js-v3/commit/9a104768684e8f22d4373fcc5d910711e62676d6"><code>9a10476</code></a> chore(codegen): sync for MetricsRecorder support and core error/retry fixes (...</li> <li><a href="https://github.com/aws/aws-sdk-js-v3/commit/6b432472f9bdf5437319b9186f706e3af5c9a748"><code>6b43247</code></a> Publish v3.1137.0</li> <li><a href="https://github.com/aws/aws-sdk-js-v3/commit/d6b94db8f4a00cc452dbe0aacb247e8ece3897ea"><code>d6b94db</code></a> Publish v3.1136.0</li> <li><a href="https://github.com/aws/aws-sdk-js-v3/commit/2d5f18d08aa373d95692d83cb3d60a6a79248fae"><code>2d5f18d</code></a> Publish v3.1135.0</li> <li><a href="https://github.com/aws/aws-sdk-js-v3/commit/0d6310bf6979ddbf737a7e15cfd8d0e7cec07063"><code>0d6310b</code></a> Publish v3.1134.0</li> <li><a href="https://github.com/aws/aws-sdk-js-v3/commit/615a1ca4661ec0e4cb34b8da89fe60c2419b94d0"><code>615a1ca</code></a> Publish v3.1133.0</li> <li>Additional commits viewable in <a href="https://github.com/aws/aws-sdk-js-v3/commits/v3.1141.0/clients/client-s3">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> |
||
|
|
efc2e6810e |
fix: show each task once in dashboard agent cards (#14847)
## Thinking Path > - Paperclip helps people manage AI agents and their tasks. > - The dashboard shows recent agent activity in compact cards. > - Those cards use run records, so two runs for one task can create duplicate task cards. > - An operator needs to see each task once when scanning the dashboard. > - This pull request selects one run per linked task before it applies the card limit. > - The live runs page still shows each run for run inspection. ## Linked Issues or Issue Description **What happened?** The dashboard showed the same task in two agent cards when that task had both an active run and a completed run. **Expected behavior** The dashboard should show a linked task at most once. It should keep the active run card when one is present. **Steps to reproduce** 1. Start an agent run for a task that already has a completed run. 2. Open the company dashboard. 3. Observe two cards linked to the same task. **Paperclip version or commit** Reproduced on the pre-change master at `8b4aa0692`. **Deployment mode** Local dev, built from source. The bug is in the core dashboard UI and does not depend on an agent adapter or database mode. ## What Changed - Select distinct linked tasks from capped active and recent run samples before applying the dashboard card limit. - Keep separate cards for runs without a linked task. - Preserve the dashboard's count of additional distinct cards behind the live-runs link. - Add UI and embedded Postgres regression tests for duplicate runs and document the dashboard rule. - Give the existing multi-request cross-tenant authorization test enough time on loaded CI runners. ## Verification - `pnpm --filter @paperclipai/ui exec vitest run src/components/ActiveAgentsPanel.test.tsx` - `pnpm --filter @paperclipai/ui exec vitest run src/api/heartbeats.test.ts` - `pnpm exec vitest run server/src/__tests__/dashboard-service.test.ts server/src/__tests__/agent-live-run-routes.test.ts` - `pnpm exec vitest run server/src/__tests__/agent-cross-tenant-authz-routes.test.ts` - `pnpm --filter @paperclipai/ui typecheck` - `pnpm --filter @paperclipai/server typecheck` - `pnpm --filter @paperclipai/ui build` - `pnpm -r typecheck` - `pnpm build` - `pnpm check:token-gates` - Review the dashboard with an active and a completed run on the same task. Confirm that it shows one card. Open Live agent runs to inspect both run records. ## Risks - A very high volume of recent runs for one task can fill the capped sample and leave older tasks off the dashboard. The Live runs page remains available for full run inspection. - The dashboard may fetch up to 50 distinct run representatives to preserve its overflow count. The default run API response and persisted data are unchanged. > For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and discuss it in `#dev` before opening the PR. Feature PRs that overlap with planned core work may need to be redirected — check the roadmap first. See `CONTRIBUTING.md`. ## Model Used - OpenAI Codex, GPT-6. The runtime does not expose the exact model ID or context window size to this task. The model used reasoning, tool calls, 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> |
||
|
|
6f2ce27ca7 |
fix(workspaces): prepare checkouts without a local seed config (#14810)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Task preparation can create an isolated Git worktree and run its setup script. > - The Paperclip repository setup script also prepares a seeded development instance. > - A server configured through environment variables can have no local seed config. > - This stops ordinary task preparation before the agent starts. > - This pull request prepares checkout dependencies when no seed source exists, while preserving errors for invalid sources and existing development instances. > - Tasks can start without creating or claiming a seeded development runtime. ## Linked Issues or Issue Description **What happened?** A task with the Paperclip repository fails during setup when the host has no repository-local or default instance config. The automatic worktree provisioner requires a seed source even when the task only needs the checkout. **Expected behavior** A plain checkout should prepare its dependencies without a local development database. A missing custom source, invalid source path, or existing development instance with a missing source should still fail. Starting a seeded runtime must still require a valid source. **Steps to reproduce** 1. Run an environment-configured Paperclip server without a local instance config. 2. Add the Paperclip repository to a project. 3. Start a task that uses an isolated Git worktree without a custom provision command. 4. Observe the setup error before agent execution. **Paperclip version or commit** Reproduced against `0d3e7bf6ac` with a real script subprocess and workspace realization regression. **Deployment mode** Environment-configured server with external PostgreSQL. **Additional context** Searched open and closed GitHub PRs and issues. Related work: Refs #14795 (seed-source diagnostics) and Refs #11733 (source validation). This change keeps source validation and seed-readiness checks in place. ## What Changed - Permit dependency setup when the default seed config is absent (including the Docker image config path) and the worktree has no development-instance state. - Keep missing custom configs, invalid paths, and lost sources for existing instances as errors. - Create no config, environment file, or seed manifest for a plain checkout. - Keep dependency install failures visible and allow normal instance setup once a source becomes available. - Cover the setup script, seed-runtime refusal, and automatic server worktree realization. - Document the difference between checkout preparation and seeded-runtime readiness. ## Verification - Regression tests failed before the fix for absent-source checkout preparation and dependency setup. - `bash -n scripts/provision-worktree.sh` - `node --test scripts/__tests__/provision-worktree-self-heal.test.mjs` — 34 passed; 1 existing flock-dependent test skipped on macOS. - Server regression — 2 passed, covering an unset config and the Docker image default path. - `pnpm build` — passed. - `pnpm -r typecheck` — passed. - All CI checks passed, including the full test shards, build, typecheck, browser tests, and canary dry run. - The first local `pnpm test:run` encountered two chat-test failures because skill discovery selected an unrelated parent directory. Both tests pass at the PR commit in a clean temporary checkout. The full local run was not completed; the redundant clean run was stopped after the complete CI suite passed. - `git diff --check` and added-line secrets/PII scan passed. - Greptile: 5/5, no comments. The branch has no merge conflicts. - No live tenant deployment or task retry was performed. ## Risks - A new checkout with no implicit seed config now completes dependency setup. It has no seeded development instance. A runtime request still fails until a valid source exists. - Existing instances and custom source paths retain their failure behavior. The script does not synthesize a source from environment credentials or copy a live database. - No schema, API, or task-setting changes. Revert the commit to restore the previous setup behavior. ## Model Used OpenAI Codex (GPT-6), with tool-assisted analysis, code edits, and local tests. The runtime did not expose a verified model variant or context-window size. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
6395cae072 |
fix(runner): ship provider pack in the standard Docker image (#14854)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Remote OpenCode and ACPX runs need a provider pack from the application build. > - Cloud now builds its application image from the standard production image. > - The provider pack was added only to the legacy cloud image target. > - The standard image therefore cannot supply the pack to downstream Cloud images. > - This pull request adds the pack to the production image and lets the cloud target inherit it. > - Remote runs can then use the pack that matches the application source commit. ## Linked Issues or Issue Description Refs #13827. Refs #14024. The standard production image does not include the remote provider pack. Downstream Cloud images inherit that omission. Remote OpenCode and ACPX runs fail with `runner_remote_provider_artifact_incompatible` and ask for `PAPERCLIP_RUNNER_REMOTE_PROVIDER_PACK_PATH`. ## What Changed - Build and copy the provider pack into the standard production image. - Set the pack path and check that an unprivileged user can read its artifacts and execute Node. - Let the legacy cloud target inherit the pack from production. - Add regression checks for production packaging and cloud inheritance. - Document stamped image behavior and the default pack path. ## Verification - The 12 focused Docker stamp and provider-pack reuse tests pass on commit `4a11f8d52aead55f85527c8e82c6d7f2644ce0da`. - The new packaging regression failed against the old Dockerfile and passed with the fix. - On the current commit, `pnpm build` and `pnpm -r typecheck` pass. All seven standard-image contract tests also pass. - The current-head CI build, typecheck, test, browser, and native Runner checks passed. The local full suite hit one chat-channel assertion failure; that exact test passed in isolation. The remaining local run was stopped after CI completed to avoid duplicating its full suite. An earlier run on the pre-rebase base had a heartbeat comment batching timeout; the external chat wait integration suite passed all 142 tests in isolation. - [The stamped preview image build passed](https://github.com/paperclipai/paperclip/actions/runs/36885002850/job/110446106393), including the production-stage provider pack build, copy, and unprivileged artifact readability/executable check. Publication, compatibility validation, and deployment of this exact commit to a staging QA instance passed. - Reproduced the exact missing-pack error on an existing staging image with Paperclip Runner, ACPX, and Claude in a remote Daytona computer. The legacy Claude adapter succeeds with the same account and computer. After deploying this commit, the same native task succeeded: it computed `5050` with a real remote shell command, wrote a proof file, read it back in a separate call, uploaded the file as a deliverable, and completed the task. The uploaded file contents and Done state persisted after a page reload. The run trace confirms Paperclip Runner, ACPX, and Claude. The first run took 2m 59s, including approximately 97s of remote artifact preparation. A second native run read the unchanged file from the prior run and completed successfully. Its startup took about 120s; this verifies repeated execution and file persistence, not fast provider-pack reuse. ## Risks - Stamped standard images now include the provider pack and its build cost. A pack build failure now fails the production image build. - Unstamped local builds still skip pack generation. Setting the path alone does not create a pack. - No database, provider authentication, or runner verification rules change. ## Model Used OpenAI Codex, GPT-6. The exact serving model identifier and context window are not exposed in this session. Capabilities used: repository inspection, code editing, shell verification, and browser testing. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [ ] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
4ac374103f |
fix(connections): repair Asana MCP and add shared-app sign-in (#14756)
## Thinking Path
> - Paperclip is the open source app people use to manage AI agents for
work.
> - Connections let agents use provider tools through the permission
gateway.
> - Asana provides an official remote MCP server, but its v2 server
requires a registered MCP OAuth app.
> - Setup can discover retired v1 endpoints and send a callback that
differs from the displayed URL.
> - This pull request repairs custom app setup and adds sign-in through
Paperclip's shared app.
> - Users can choose their own app without enrolling with Paperclip
Cloud.
> - Agents can use Asana tools after the user connects their account and
sets action permissions.
## Linked Issues or Issue Description
Related: #14739 supplies the personal credential repair used by resumed
Asana setup. No duplicate Asana authentication PR was found.
**What happened?**
Asana setup failed even with a user-created app. Root discovery metadata
still points at v1. MCP v2 uses the Asana OAuth issuer and requires an
MCP app with a client secret. Local setup also displayed a localhost
callback while an Origin header could make authorization use a numeric
loopback callback.
**Expected behavior**
Sign in with Paperclip's app when its broker profile is available. Keep
custom MCP app setup available without Cloud enrollment. Use the correct
issuer, callback, client credentials, and resource throughout setup.
**Steps to reproduce**
1. Open Asana in the connection catalog.
2. Supply an Asana MCP app's client ID and secret.
3. Start OAuth on a local instance opened with a numeric loopback
address, or resume a draft that cached v1 metadata.
4. Observe the wrong discovery endpoint or callback mismatch.
**Paperclip version or commit**
Reproduced from
|
||
|
|
8b4aa06920 |
build(deps): bump multer from 2.2.0 to 2.4.0 (#14493)
Bumps [multer](https://github.com/expressjs/multer) from 2.2.0 to 2.4.0. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/expressjs/multer/releases">multer's releases</a>.</em></p> <blockquote> <h2>v2.4.0</h2> <h2>Highlights</h2> <p><strong>multer finally supports Google Cloud Functions and Firebase 🎉</strong></p> <p>These platforms read the request body before your code runs, so multer's classic <code>req.pipe(busboy)</code> received nothing: empty <code>req.body</code>, empty <code>req.files</code>, and nearly a decade of duplicated issues.</p> <p>The new <code>streamHandler</code> option closes that gap: you decide how the body reaches the parser, so the pre-read <code>rawBody</code> just works (see image).</p> <pre lang="js"><code>const multer = require('multer') <p>const upload = multer({<br /> storage: multer.memoryStorage(),<br /> streamHandler: (req, busboy) => {<br /> // Cloud Functions / Firebase expose the pre-read body here<br /> if (req.rawBody) busboy.end(req.rawBody)<br /> else req.pipe(busboy)<br /> }<br /> })</p> <p>app.post('/upload', upload.single('file'), (req, res) => {<br /> res.json({ name: req.file.originalname, size: req.file.size })<br /> })<br /> </code></pre></p> <p>This landed thanks to community PRs going back to 2017; their authors are credited as co-authors in the release.</p> <h2>Important: Security</h2> <ul> <li>Fix <a href="https://www.cve.org/CVERecord?id=CVE-2026-88932">CVE-2026-88932</a> (<a href="https://github.com/expressjs/multer/security/advisories/GHSA-3pph-fpjx-jg34">GHSA-3pph-fpjx-jg34</a>)</li> </ul> <h2>What's Changed</h2> <ul> <li>docs: remove README translations by <a href="https://github.com/UlisesGascon"><code>@UlisesGascon</code></a> in <a href="https://redirect.github.com/expressjs/multer/pull/1463">expressjs/multer#1463</a></li> <li>ci: add macOS to the test matrix by <a href="https://github.com/kilisamemarisaaa"><code>@kilisamemarisaaa</code></a> in <a href="https://redirect.github.com/expressjs/multer/pull/1464">expressjs/multer#1464</a></li> <li>feat. improve wording for LIMIT_UNEXPECTED_FILE error code by <a href="https://github.com/flashbag"><code>@flashbag</code></a> in <a href="https://redirect.github.com/expressjs/multer/pull/426">expressjs/multer#426</a></li> <li>feat: add filename to file errors by <a href="https://github.com/UjjwalKumar239"><code>@UjjwalKumar239</code></a> in <a href="https://redirect.github.com/expressjs/multer/pull/1416">expressjs/multer#1416</a></li> <li>refactor: remove concat-stream dependency by <a href="https://github.com/Phillip9587"><code>@Phillip9587</code></a> in <a href="https://redirect.github.com/expressjs/multer/pull/1356">expressjs/multer#1356</a></li> <li>fix: reject non-integer fileSize limits by <a href="https://github.com/abhu85"><code>@abhu85</code></a> in <a href="https://redirect.github.com/expressjs/multer/pull/1395">expressjs/multer#1395</a></li> <li>fix: allow exactly limits.parts parts by <a href="https://github.com/deepakganesh78"><code>@deepakganesh78</code></a> in <a href="https://redirect.github.com/expressjs/multer/pull/1446">expressjs/multer#1446</a></li> <li>fix: do not consume maxCount for files skipped by fileFilter by <a href="https://github.com/Sagargupta16"><code>@Sagargupta16</code></a> in <a href="https://redirect.github.com/expressjs/multer/pull/1426">expressjs/multer#1426</a></li> <li>fix: validate all limits at construction time by <a href="https://github.com/ShubhamOulkar"><code>@ShubhamOulkar</code></a> in <a href="https://redirect.github.com/expressjs/multer/pull/1335">expressjs/multer#1335</a></li> <li>test: cover storage engine _removeFile invocation semantics by <a href="https://github.com/kilisamemarisaaa"><code>@kilisamemarisaaa</code></a> in <a href="https://redirect.github.com/expressjs/multer/pull/1460">expressjs/multer#1460</a></li> <li>feat: accept a function for limits by <a href="https://github.com/hossein-zare"><code>@hossein-zare</code></a> in <a href="https://redirect.github.com/expressjs/multer/pull/1133">expressjs/multer#1133</a></li> <li>fix: add flush option to disk storage to fsync files before completion by <a href="https://github.com/kilisamemarisaaa"><code>@kilisamemarisaaa</code></a> in <a href="https://redirect.github.com/expressjs/multer/pull/1458">expressjs/multer#1458</a></li> <li>feat: expose busboy defCharset, highWaterMark and fileHwm options by <a href="https://github.com/UlisesGascon"><code>@UlisesGascon</code></a> in <a href="https://redirect.github.com/expressjs/multer/pull/1465">expressjs/multer#1465</a></li> <li>docs: describe the file stream contract for storage engines by <a href="https://github.com/UlisesGascon"><code>@UlisesGascon</code></a> in <a href="https://redirect.github.com/expressjs/multer/pull/1468">expressjs/multer#1468</a></li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/expressjs/multer/blob/main/CHANGELOG.md">multer's changelog</a>.</em></p> <blockquote> <h2>2.4.0</h2> <ul> <li>Fix <a href="https://www.cve.org/CVERecord?id=CVE-2026-88932">CVE-2026-88932</a> (<a href="https://github.com/expressjs/multer/security/advisories/GHSA-3pph-fpjx-jg34">GHSA-3pph-fpjx-jg34</a>)</li> <li>Add <code>filename</code> to <code>LIMIT_FILE_SIZE</code> and <code>LIMIT_UNEXPECTED_FILE</code> errors (<a href="https://redirect.github.com/expressjs/multer/pull/1416">#1416</a>)</li> <li>Accept a function for <code>limits</code>, called with the request, to set limits per request (<a href="https://redirect.github.com/expressjs/multer/pull/1133">#1133</a>)</li> <li>Add opt-in <code>flush</code> option to <code>DiskStorage</code> to fsync files before the callback runs (<a href="https://redirect.github.com/expressjs/multer/pull/1458">#1458</a>)</li> <li>Expose busboy's <code>defCharset</code>, <code>highWaterMark</code> and <code>fileHwm</code> options (<a href="https://redirect.github.com/expressjs/multer/pull/1465">#1465</a>)</li> <li>Add <code>streamHandler</code> option to feed busboy from pre-consumed bodies (Google Cloud Functions, Firebase) (<a href="https://redirect.github.com/expressjs/multer/pull/1466">#1466</a>)</li> <li>Allow <code>multer.diskStorage()</code> to be called without options (<a href="https://redirect.github.com/expressjs/multer/pull/1471">#1471</a>)</li> <li>Decode WHATWG-escaped characters (<code>%0A</code>, <code>%0D</code>, <code>%22</code>) in field names, matching <code>file.originalname</code> since 2.3.0: <code>req.body</code> keys, <code>file.fieldname</code> and <code>err.field</code> now carry the real name. If you matched the escaped spelling as a workaround, use the real name now (<a href="https://redirect.github.com/expressjs/multer/pull/1473">#1473</a>)</li> <li>Report the decoded filename in <code>err.filename</code> on <code>LIMIT_FILE_SIZE</code> errors, matching <code>file.originalname</code> (<a href="https://redirect.github.com/expressjs/multer/pull/1478">#1478</a>)</li> <li>Reject non-integer or negative <code>limits</code> values at construction time; a float limit silently disabled the check (<a href="https://redirect.github.com/expressjs/multer/pull/1395">#1395</a>, <a href="https://redirect.github.com/expressjs/multer/pull/1335">#1335</a>)</li> <li>Accept requests with exactly <code>limits.parts</code> parts; <code>LIMIT_PART_COUNT</code> now fires only when the limit is exceeded. If you set <code>parts</code> one higher to work around this, you can drop the extra one (<a href="https://redirect.github.com/expressjs/multer/pull/1446">#1446</a>)</li> <li>Files skipped by <code>fileFilter</code> no longer count towards <code>maxCount</code> (<a href="https://redirect.github.com/expressjs/multer/pull/1426">#1426</a>)</li> <li>Change the <code>LIMIT_UNEXPECTED_FILE</code> message to "Unexpected file field" (<a href="https://redirect.github.com/expressjs/multer/pull/426">#426</a>)</li> <li>Remove the <code>concat-stream</code> dependency (<a href="https://redirect.github.com/expressjs/multer/pull/1356">#1356</a>)</li> <li>Docs: add JSDoc to the public API and document the storage engine stream contract (<a href="https://redirect.github.com/expressjs/multer/pull/1467">#1467</a>, <a href="https://redirect.github.com/expressjs/multer/pull/1468">#1468</a>)</li> <li>Docs: add FormData upload examples (<a href="https://redirect.github.com/expressjs/multer/pull/896">#896</a>)</li> <li>Docs: remove the translated READMEs (<a href="https://redirect.github.com/expressjs/multer/pull/1463">#1463</a>)</li> <li>Internal: run the test suite on macOS (<a href="https://redirect.github.com/expressjs/multer/pull/1464">#1464</a>)</li> </ul> <h2>2.3.0</h2> <ul> <li>Fix <a href="https://www.cve.org/CVERecord?id=CVE-2026-77078">CVE-2026-77078</a> (<a href="https://github.com/expressjs/multer/security/advisories/GHSA-wc9g-mqfw-jrwm">GHSA-wc9g-mqfw-jrwm</a>)</li> <li>Fix <a href="https://www.cve.org/CVERecord?id=CVE-2026-77037">CVE-2026-77037</a> (<a href="https://github.com/expressjs/multer/security/advisories/GHSA-qfvm-cv95-jqjf">GHSA-qfvm-cv95-jqjf</a>)</li> <li>Fix <a href="https://www.cve.org/CVERecord?id=CVE-2026-77063">CVE-2026-77063</a> (<a href="https://github.com/expressjs/multer/security/advisories/GHSA-qvfw-j98x-7q72">GHSA-qvfw-j98x-7q72</a>)</li> <li>Fix <a href="https://www.cve.org/CVERecord?id=CVE-2026-82333">CVE-2026-82333</a> (<a href="https://github.com/expressjs/multer/security/advisories/GHSA-535w-7cp7-47q4">GHSA-535w-7cp7-47q4</a>)</li> <li>Add <code>MulterError</code> codes <code>INVALID_FIELD_NAME</code> and <code>STREAM_DESTROYED</code></li> <li>Add opt-in <code>limits.fieldArrayIndexLimit</code> to bound numeric array indexes in field names (<a href="https://redirect.github.com/expressjs/multer/pull/1438">#1438</a>)</li> <li>Accept files whose size is exactly <code>limits.fileSize</code> (<a href="https://redirect.github.com/expressjs/multer/pull/1407">#1407</a>)</li> <li>Preserve the caller's async context (<code>AsyncLocalStorage</code>) when calling <code>next()</code> (<a href="https://redirect.github.com/expressjs/multer/pull/1124">#1124</a>)</li> <li>Decode WHATWG-escaped characters (<code>%0A</code>, <code>%0D</code>, <code>%22</code>) in <code>file.originalname</code> (<a href="https://redirect.github.com/expressjs/multer/pull/1421">#1421</a>)</li> <li>Do not crash when <code>fileFilter</code> invokes its callback more than once (<a href="https://redirect.github.com/expressjs/multer/pull/1427">#1427</a>)</li> <li>Use a fallback message for <code>MulterError</code> codes without a mapping (<a href="https://redirect.github.com/expressjs/multer/pull/1448">#1448</a>)</li> <li>Docs: clarify <code>preservePath</code> and <code>parts</code>, use <code>crypto.randomBytes</code> in the <code>DiskStorage</code> example (<a href="https://redirect.github.com/expressjs/multer/pull/1414">#1414</a>, <a href="https://redirect.github.com/expressjs/multer/pull/1430">#1430</a>, <a href="https://redirect.github.com/expressjs/multer/pull/1436">#1436</a>)</li> <li>Docs: add Indonesian, Japanese and Tamil translations and refresh all translations from the current README (<a href="https://redirect.github.com/expressjs/multer/pull/1431">#1431</a>, <a href="https://redirect.github.com/expressjs/multer/pull/1354">#1354</a>, <a href="https://redirect.github.com/expressjs/multer/pull/1462">#1462</a>)</li> <li>Internal: run the test suite on Windows (<a href="https://redirect.github.com/expressjs/multer/pull/1334">#1334</a>)</li> </ul> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/expressjs/multer/commit/35979e5afbb814bdb4b750ce028b125eb84c53af"><code>35979e5</code></a> 2.4.0 (<a href="https://redirect.github.com/expressjs/multer/issues/1469">#1469</a>)</li> <li><a href="https://github.com/expressjs/multer/commit/b888532fe2e10ceb13da44286448cb2bb4ce9720"><code>b888532</code></a> chore(deps): bump github/codeql-action/upload-sarif to 4.37.9 (<a href="https://redirect.github.com/expressjs/multer/issues/1474">#1474</a>)</li> <li><a href="https://github.com/expressjs/multer/commit/e6bcd7db69315714fb9a38b1cd1e0f582cbce65a"><code>e6bcd7d</code></a> chore(deps): bump github/codeql-action/analyze from 4.37.4 to 4.37.9 (<a href="https://redirect.github.com/expressjs/multer/issues/1475">#1475</a>)</li> <li><a href="https://github.com/expressjs/multer/commit/00dec43b394c5bfaf4efb6d0fe8467bad05525ed"><code>00dec43</code></a> chore(deps): bump github/codeql-action/init from 4.37.4 to 4.37.9 (<a href="https://redirect.github.com/expressjs/multer/issues/1476">#1476</a>)</li> <li><a href="https://github.com/expressjs/multer/commit/8d5c3b72e430e7edaa2749e96dcb75bf18d84733"><code>8d5c3b7</code></a> feat: allow diskStorage without options (<a href="https://redirect.github.com/expressjs/multer/issues/1471">#1471</a>)</li> <li><a href="https://github.com/expressjs/multer/commit/02f6e8265b6bf6b6921a819db3b84276efa03ed2"><code>02f6e82</code></a> fix: report the decoded filename on LIMIT_FILE_SIZE (<a href="https://redirect.github.com/expressjs/multer/issues/1478">#1478</a>)</li> <li><a href="https://github.com/expressjs/multer/commit/bc3f72d5edaa19b993771348e3fb47b366316a88"><code>bc3f72d</code></a> fix: decode escaped field names, not just filenames (<a href="https://redirect.github.com/expressjs/multer/issues/1473">#1473</a>)</li> <li><a href="https://github.com/expressjs/multer/commit/2661325ba8ca2a72b7fb554b63d2df51da9290c4"><code>2661325</code></a> docs: add JSDoc to the public API (<a href="https://redirect.github.com/expressjs/multer/issues/1467">#1467</a>)</li> <li><a href="https://github.com/expressjs/multer/commit/53337f9713619ef3381ee6b4e541f926dbaac305"><code>53337f9</code></a> fix: remove late-completing uploads aborted before the engine names them</li> <li><a href="https://github.com/expressjs/multer/commit/7f2c9ab5f35c0478a7b3bb0f5e1af9b536780132"><code>7f2c9ab</code></a> feat: add streamHandler option to feed busboy from pre-consumed bodies (<a href="https://redirect.github.com/expressjs/multer/issues/1466">#1466</a>)</li> <li>Additional commits viewable in <a href="https://github.com/expressjs/multer/compare/v2.2.0...v2.4.0">compare view</a></li> </ul> </details> <details> <summary>Maintainer changes</summary> <p>This version was pushed to npm by <a href="https://www.npmjs.com/~GitHub%20Actions">GitHub Actions</a>, a new releaser for multer since your current version.</p> </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 <noreply@paperclip.ing> |
||
|
|
0829d94af2 |
fix(auth): derive low-trust human direction from existing execution records (#14775)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Low-trust review contains work that may include hostile input. > - Its default intake boundary currently blocks direct human chat and tasks outside that boundary. > - Human direction should authorize the assigned work while preserving containment. > - Existing conversations and execution requests already identify direct human instructions. > - This pull request derives exact-task authority from those records and the current assignee. > - The agent can perform that work without gaining access to unrelated tasks or privileged tools. ## Linked Issues or Issue Description **What happened?** A low-trust agent with a project boundary rejects its owner's direct Agent Chat before provider execution. Human-assigned tasks outside that project fail the same check. **Expected behavior** An authorized human can talk to the agent or assign it a task. The exact task runs with its existing sandbox, credential, and tool restrictions. **Steps to reproduce** 1. Enable Agent Chat and isolated workspaces. Configure a sandbox agent with low-trust review scoped to an intake project. 2. Send the agent a direct board chat message, or assign it a projectless task. 3. Observe `low_trust_boundary_mismatch` before execution. Related: #14766 adds private task directories for repo-free low-trust execution. It is now merged into master and included in the branch base, so CI and staging verify the combined behavior. ## What Changed - Derive owner-chat access from existing conversation identity. - Derive exact-task access from the existing human requester and server-owned request origin, including coalesced requests. Plugin and external sender attribution do not authorize work. - Follow existing `retryOfRunId` database links for automatic continuations, checking company, agent, and task throughout; cancelled ancestors cannot grant authority. - Require a live run and current assignment. Preserve sandbox, credential, privileged-tool, responsible-user, and quarantined-output checks. - Retain board backlog assignments in existing request records without starting execution. Reassignment cancels old human requests in the common service transaction, including plugin writes; late settlement cannot revive them. - Add real database and HTTP coverage for request provenance, retry ancestry, cancelled runs, concurrent reassignment, spoofing, and containment. Document the rule. - Preserve legacy board assignment requests through their existing source, reason, and human requester. - Use the existing wrapped-error helper for concurrent chat-question idempotency; a deterministic race test reproduces the CI failure before the fix and passes after it. - No new schema, migrations, or user-identity fields. Existing requester columns hold attribution. ## Verification - Passed the focused database, policy-retention, HTTP, and reassignment tests locally. The HTTP test creates a task through the real board route and checks the resulting persisted wakeup before exercising agent reads, comments, mutations, and review handoff. - Database tests hold a reassignment transaction open to verify coherent authorization before and after commit, with a two-connection pool. They cover retries, coalesced requests, cancelled ancestry, invalid cross-company/agent/task links, cycles, and forged attribution. - Full local `pnpm -r typecheck` and `pnpm build` passed on the final commit (`d107c26df`). [Latest-head CI](https://github.com/paperclipai/paperclip/actions/runs/36815589542) passed: 54 successful checks, two expected skips, including all eight browser-test shards. Greptile is 5/5 on this exact commit with no unresolved threads. Local tests were targeted; the full test suite ran through CI’s test matrix. - The revised HTTP suite passed all 13 tests; database authorization tests passed all 11, including legacy compatibility and late watchdog settlement; the backlog route contract passed all 3 tests. Another 102 tests covering durable chat admission, wake queues, and Cursor execution passed. - All 90 interaction-service tests passed with both create calls deliberately held until their optimistic reads complete, forcing duplicate-key recovery. That forced race failed before switching to the shared wrapped-error helper. - Previous staging proof covered owner chat and projectless task persistence. The simplified revision has not been redeployed; that earlier proof is not claimed for the new implementation. ## Risks - This is an authorization change: only the live run's exact task qualifies, and normal responsible-user restrictions still apply. - Existing request and retry records are authoritative. Merely naming a responsible/originating user or an external connector sender does not qualify. - Reassignment invalidates existing human request records transactionally. A cancelled run or request cannot regain authority when the task is assigned back. - Ordinary task exceptions require server-owned origin or the legacy board assignment source/reason/actor combination. Existing owner chats use conversation identity. ## Model Used OpenAI GPT-6 in Codex, with reasoning, repository tools, code execution, and browser testing. The runtime does not expose a more specific model ID or context-window size. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
467125fafb |
feat(connections): one-screen connector setup with stated defaults (#14811)
## Thinking Path
> - Paperclip is the open source app people use to manage AI agents for
work
> - Agents use Connections (the Apps catalog) to act in services like
Notion, GitHub, Google Workspace and Railway
> - Each connector asked the user to answer setup questions before it
went to the provider. Most of the questions already had the correct
answer selected
> - ROADMAP.md lists "simpler setup" for Apps and Connections as ongoing
work. This change continues that work
> - This pull request removes the questions that Paperclip can answer
itself. It states the defaults in one line and moves the choices behind
"Change" and onto the Permissions tab
> - The benefit is that most connectors take one click in Paperclip and
then the provider's own consent screen
## Linked Issues or Issue Description
No public issue exists. This is the description, from the enhancement
template.
**What existing behavior does this improve?**
The setup flow for tool connectors in the Apps catalog.
**Subsystem affected**
Apps and Connections: `ui/src/features/connections`,
`ui/src/pages/apps`, the `packages/shared` app definitions, and the
OAuth routes in `server/src/routes/tool-access.ts`.
**Current behavior**
Every connector opened with an Access step. The step asked who can use
the connection and which agents get it, and both answers were already
selected. 18 connectors also asked "How do you want to connect?" when
Paperclip could rank the methods. The Google apps and Postman also asked
"What should Paperclip be able to do?" before sign-in. The four gateway
connectors (Zapier, Arcade, Composio, Executor) used a separate two-step
wizard. Asana was pinned to a customer-owned OAuth app, so the user had
to register an app in Asana's developer console. The "Set all" control
on the Permissions tab changed only one action. After the user approved
access, Railway's consent page showed "you can close this window" and
did not return to Paperclip.
**Proposed behavior**
One screen per connector, with one primary button. The screen states the
defaults in one sentence, for example "Connects for everyone in your
organization, available to all agents". A "Change" link opens one
Advanced panel. When the provider's metadata allows dynamic client
registration, Paperclip registers a client itself. Connecting lands on
the Permissions tab. On that tab, "Set all" changes every action in the
group.
**Reason and benefit**
The user makes fewer decisions before the connection exists. Most
choices are easier to make after the connection, on the Permissions tab,
where a change has an immediate effect.
**Breaking changes**
None. No schema or API change. Existing connections keep their settings.
## What Changed
- **No Access step.** `ConnectionSetupFlow` no longer has the Access
step. The flow shows the resolved default above the primary button and
on the completion screen. The access controls moved into one Advanced
panel. The panel opens automatically only when a setting in it is
required.
- **A default method for every app.** The flow always picks the ranked
default method. Alternate methods are in the Advanced panel. The Google
and Postman capability choice is not asked before sign-in. The
write-capable method is the default.
- **Gateway connectors.** `RemoteMcpProductionSetup` (Zapier, Arcade,
Composio, Executor) no longer has its own Access step. Its commit path
and the main commit path use one helper, `askFirstCatalogEntryIdsFor`,
for server-suggested defaults.
- **Dynamic registration from live metadata.**
`canRegisterOAuthClientDynamically` now allows registration when the
provider advertises a registration endpoint, even if the catalog entry
lists only customer-owned clients. The Asana and Linear definitions and
catalog text match live probes. Asana issues clients for loopback
callbacks only, so a hosted deployment still needs an Asana app.
- **Connection setup states.** New
`packages/shared/src/connection-setup-state.ts` sorts each method into
`instant`, `authorize`, `paste` or `register`. The gallery card verb
("Connect" or "Add key") comes from this resolver and the instance's
ownership availability.
- **Generic MCP.** The generic path no longer asks "Does it need a key?"
first. A credential challenge from the server shows the key field.
- **Permissions tab.** Each action row shows its risk level. Each group
has a "Set all" control. The control sends one change for the whole
group. Before, each row's save started from the same render, so the
saves overwrote each other. The Zapier/Arcade/Composio/Executor setup
screen had the same defect.
- **OAuth callback interstitial.** A cross-site browser navigation to
`/api/tools/oauth/callback` gets a small same-origin "Finishing your
connection…" page. That page repeats the request, and the repeat does
the code exchange. Railway's consent page replaces itself after about
two seconds, and the code exchange plus tool discovery takes longer than
that. The interstitial uses only a meta refresh, because the OAuth code
is single-use. Requests without `Sec-Fetch-Site: cross-site` take the
old path.
- **Linear registers through its MCP server.** Linear pins the console
endpoints at `linear.app`. Pinned endpoints now replace discovery only
when the method cannot register, or when the connection has an
operator-entered client. So a Linear connection now finds the
registration endpoint at `mcp.linear.app`.
- **Own-OAuth-app recovery stays on the one-click screen.** When the
method also accepts a customer-owned client, the client fields are in
the Advanced panel. The panel opens after a failed sign-in. "Try again"
resumes the draft with the operator's client.
- **E2E specs** follow the one-screen flow. The Access-step clicks are
removed, the specs open **Change** before they pick agents, and they
expect GitHub's **Add key** verb.
- **Default permissions do not change.** New connections still allow
every action. The user can set actions to Ask first or Off on the
Permissions tab.
## Verification
- `cd ui && npx vitest run src/pages/apps src/features/connections
--no-file-parallelism`
- `cd packages/shared && npx vitest run src/app-definitions.test.ts
src/connection-setup-state.test.ts`
- `cd server && npx vitest run src/__tests__/tool-access-service.test.ts
src/__tests__/remote-mcp-connectors.test.ts`
- `pnpm check:token-gates`
- New tests:
- `PermissionsPanel.group.test.tsx` checks that "Set all" sends one
change for the whole group. It fails on the old code.
- `action-permissions.test.ts` checks the group update.
- `connection-setup-state.test.ts` checks the four setup states.
- A server test checks that a cross-site callback gets the interstitial
and does not use the OAuth state, and that the same-origin repeat
completes the connection.
- Manual check on a hosted staging deployment. GitHub, Google Drive,
Composio, Notion, PostHog and Railway each connected from one screen and
returned to the Permissions tab. On Railway, "Set all" changed all 65
write actions, and the change remained after a reload.
- Visual changes: snapshot baselines are intentionally not updated. See
the `doc/design/DECISION-SHEET.md` entry "Per-change snapshot
verification demoted to dormant (Jul 13 2026)".
## Risks
- **Fewer confirmation clicks.** Organization-wide access is the
default, and the user does not confirm it on a separate step. This was
already the preselected answer. The flow shows the default before the
user clicks and again after the connection.
- **Google write scope.** Google apps now request the write-capable
scope by default. A narrower scope needs a new sign-in.
- **Dynamic registration from live metadata.** A provider can advertise
registration and then reject a redirect URI. Asana rejects hosted
callbacks, for example. In that case registration fails, and the
customer-owned client path remains available for recovery.
- **Callback interstitial.** The OAuth callback adds one same-origin
step for cross-site browser navigations. Browsers without `Sec-Fetch-*`
headers use the old direct path.
- Chat and bot connectors (Discord, Telegram, Microsoft Teams, iMessage)
do not 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
- Claude Opus 5.5 (Anthropic), model ID `claude-opus-5-5`, used through
Claude Code with tool use (shell, file editing, browser automation) and
extended thinking. It wrote the code, the tests and this description. A
human product owner directed the work and tested it by hand.
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: scotttong <squadbot000@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
|
||
|
|
4b9a6000f7 |
Add bounded evidence for directory lock timeouts (#14787)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Agent files use directory locks during collection and cleanup. > - A lock timeout can fail finalization after the model turn completes. > - The timeout currently identifies no owner state or waiting operation. > - This pull request adds bounded evidence to the existing run failure report. > - Operators can distinguish a known local holder from a possible old lock without changing lock safety. ## Linked Issues or Issue Description **What happened?** A directory lock timeout does not distinguish active local work from an owner record left by an earlier process. The stored execution stage can also precede the cleanup operation that failed. **Expected behavior** The failure report should identify the waiting operation and expose bounded ownership clues. It must preserve the timeout and keep unknown ownership protected. **Steps to reproduce** Hold a directory merge lock while a second caller reaches its acquisition deadline. The regression tests exercise a live holder and an older owner record with a live PID. Related: #9667 proposes stale-lock recovery under a single-server assumption. This change only adds evidence and does not adopt that assumption. #14575 and #14665 add other run failure diagnostics. ## What Changed - Record lock owner state, capped age and wait duration, same-process and process-age comparisons, and whether this module holds the lock. - Label agent-directory release, collection, checkpoint, and warm handoff timeouts with a fixed operation code. - Validate each field before the existing event-local Sentry report accepts it. Exclude owner records, PIDs, paths, and absolute timestamps. - Limit the extra diagnostic owner read to 100 ms with best-effort abort; malformed JSON is `invalid` and unreadable owner records remain `unknown`. - Document the diagnostic limits and verify that contenders never reclaim protected locks. ## Verification - Focused lock, diagnostic, real Sentry SDK, and database-backed agent-directory tests: 126 passed, including stalled-read and malformed/missing/unreadable-owner regression coverage. - Final revision `0691613dcc`: all 54 reported checks successful, with two intentionally skipped Storybook checks. Greptile: 5/5, zero unresolved review threads; no merge conflicts. - `pnpm -r typecheck`: passed. - `pnpm build`: passed. - `pnpm test:run`: complete suite coverage ran with the existing repository shard flags: four general-server shards, four serialized shards, two general-workspaces-a shards, and general-workspaces-b. The full run is not green because of the base failures below. - The broad run found 13 failures in the unchanged macOS skill-cache tests. All 13 reproduce on the clean base revision. Open PR #14290 covers that existing failure. - Two unchanged CLI archive tests hit their five-second limits during the broad run; all 17 tests in that file pass on recheck. A CLI auth socket error also cleared on recheck (19 tests), and its full serialized shard passed on rerun. ## Risks This is a diagnostic change, not a stale-lock fix. Owner observations can race with release. Wall-clock shifts can affect the age comparison. A local-holder flag covers only this module instance. None of these fields authorizes reclamation or proves a file save. Lock acquisition, release, retries, task status, and recovery guards retain their current behavior. No schema change or deployment action is required. ## Model Used OpenAI Codex, based on GPT-6, with code execution and repository tools. The exact model build and context window were not exposed to this agent. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [ ] I have run tests locally and they pass (focused checks pass; existing base failures are documented 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 - [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> |
||
|
|
f7e36ba3e2 |
fix: isolate repository-free low-trust tasks in private directories (#14766)
## Thinking Path > - Paperclip manages work by agents within company boundaries. > - Email tasks can run under the low-trust review preset. > - These tasks must use an isolated workspace and a sandbox. > - The default workspace strategy assumed that the project had a Git repository. > - A project without a configured workspace failed before the agent could start. > - This change gives each such task a private directory and keeps the sandbox requirement. ## Linked Issues or Issue Description **What happened?** An inbound email assigned to a low-trust agent failed with `git_worktree_base_not_git_checkout` when its boundary project had no configured workspace. Setup had accepted the project and sandbox. **Expected behavior** The agent can process email without a repository. Its workspace stays isolated from other tasks and the shared agent home. **Steps to reproduce** 1. Select a low-trust agent with an active sandbox and a project boundary. 2. Leave the project without a configured workspace. 3. Receive an email through AgentMail. 4. Observe that startup fails before provider work starts. **Paperclip version or commit** Reproduced against `5edf55d73`. **Deployment mode** Hosted staging with sandbox execution. Related: #13256 added email tasks. #13636 fixed default isolation for projects without workspaces; the explicit isolation used by low-trust tasks still needed this path. ## What Changed - Select private task directories for low-trust sandbox tasks with no configured workspace or explicit workspace strategy. - Keep each directory scoped to its company and task. Retain files across turns and reassignment and reject symlink paths and mismatched workspace reuse. - Preserve Git validation for configured workspaces and explicit strategies, plus the existing authorization and remote gates for referenced projects. - Add a startup regression and directory isolation tests. Document the supported repository-free path. ## Verification - The startup regression failed before the fix with the same Git validation error. - 260 targeted email, workspace policy, heartbeat, referenced-project and directory tests pass. - Full `pnpm -r typecheck` and `pnpm build` pass on the latest commit. - All CI checks, including the complete sharded test suite and canary dry run, pass on `b4ccd9802b09b2e95499df72d48b4a3906b8c328`. - The final commit also passes the same server shard locally: 60 files, 1,024 passed / 6 skipped tests. The earlier all-groups local run was interrupted during follow-up edits; complete-suite verification comes from CI on the final commit. - Deployed the reviewed commit to staging and independently verified the full serving SHA. Two real Codex runs in Daytona succeeded and finalized the same private company/task workspace. The first wrote a 35-byte marker; the second read the existing file without modifying it and returned the independently verified SHA-256 `ce3bbeb44d07ca6822826d3a5945752a38d30b356d10829f3159a191e5aa92a6`. - Live runtime caveat: Codex reported a nested `bwrap` loopback permission error and used its configured escalated execution inside Daytona. The outer Daytona sandbox remained active for both runs. - The startup regression uses a real database, production trust checks, workspace persistence, sandbox lease acquisition and realization, and a fake provider. It checks reassignment and allows only an authorized referenced project. - The transfer regression runs production archive/sync-back/merge code against distinct filesystem roots: create output in one sandbox, restore it, then read and update it in a fresh sandbox. The provider I/O is emulated; live staging verification is separate. ## Risks - The new default applies only to low-trust sandbox tasks without workspace configuration. Standard agents and explicit Git strategies keep their existing behavior. - Task directories retain work across turns and consume instance storage. The change does not migrate or copy existing shared files. - No database migration or credential changes are required. ## Model Used OpenAI GPT-6 through Codex, with reasoning, repository inspection, code execution, and browser tools. The exact runtime model revision and context window are not exposed in this session. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [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> |
||
|
|
3bbb8d0f69 |
Add bounded AgentMail failure diagnostics (#14768)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - AgentMail connections create inboxes and handle email tasks. > - A failed provider request currently records only its HTTP status. > - The same 403 can mean a permission denial, a resource limit, or another provider restriction. > - This pull request records a fixed operation name and a documented, allowlisted error code. > - Operators can distinguish these failures without exposing provider payloads or changing retry behavior. ## Linked Issues or Issue Description **What happened?** An AgentMail inbox creation failure reports only `AgentMail request failed (403)`. The response body is deliberately excluded because it can contain private mail or credentials. That also discards the provider code needed to identify the cause. **Expected behavior** Keep the HTTP failure visible with a fixed operation name and a safe provider code. Never copy arbitrary error text, resource identifiers, suggested fixes, or URLs into diagnostics. **Steps to reproduce** 1. Make an inbox creation request through `agentmailApi` with a fake provider returning HTTP 403 and `code: "missing_permission"`. 2. Observe that the old error lacks the operation and provider code. 3. With this change, verify the error includes `operation=create_inbox, code=missing_permission`, preserves status 403, and excludes all other response fields. Related work: #13256 introduced the AgentMail connection. The provider documents stable codes in its [error reference](https://docs.agentmail.to/errors). ## What Changed - Add a fixed method/route-to-operation map and an allowlist of documented provider codes. - Read at most 8 KiB for diagnostics, with a one-second deadline. Cancel unread bodies and preserve the HTTP error if reading or parsing fails. - Keep the existing error prefix, status, retry delay, and failure handling. - Add regression coverage and document the diagnostic limits. ## Verification - `pnpm exec vitest run server/src/__tests__/agentmail-api.test.ts` — 44 tests passed. - `pnpm build` — passed. - `pnpm -r typecheck` — passed before the review correction. Final `pnpm --filter @paperclipai/server exec tsc --noEmit` also passed. - Full local `pnpm test:run` did not finish successfully; three company-skills-service failures were observed outside the changed module. The final-head CI server suites passed. The remaining workspaces-b CI retry covers an unrelated HTTP/2 port collision. - The diff passed a scan for configured secrets, private deployment references, and non-fixture email addresses. ## Risks - A failed request can now wait up to one extra second while reading its diagnostic code. - New, missing, malformed, or oversized provider codes report `unknown`. A future provider code needs an explicit allowlist update. - This is a diagnostics change. It does not establish or repair the cause of an existing provider denial. - No schema, credential policy, or retry behavior changes. ## Model Used OpenAI Codex, GPT-6, with reasoning, tool use, and code execution. The exact served model ID and context-window size are not exposed in this session. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [ ] All Paperclip CI gates are green - [x] Greptile is 5/5 at 20853e31abacf53a32f1a63467ee208a719bbf00; the locked-body finding is fixed and its thread resolved - [x] I will address all Greptile and reviewer comments before requesting merge Final verification (September 30): all final-head GitHub checks pass at `20853e31abacf53a32f1a63467ee208a719bbf00`, including the targeted workspaces-b rerun after the unrelated EADDRINUSE failure. Greptile scored 5/5 on this head and no review threads remain unresolved. The branch is mergeable. The local full-suite run did not yield a passing completion; CI completed successfully across all suites. This public PR remains open for maintainer merge. --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
e2908fff5c |
fix: enforce terminal outcomes during recovered sandbox cleanup (#14767)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Native runners can keep a reusable sandbox warm after successful turns. > - Failed turns must stop their sandbox before a later retry resumes it. > - Workspace recovery can release a lease outside the executor's normal teardown. > - Successful file copy-back can then retain a sandbox even when its run failed. > - This pull request checks the durable run outcome at the shared release boundary. > - Ordinary teardown and recovery now apply the same retention rule. ## Linked Issues or Issue Description **What happened?** A real Daytona verification on `5edf55d73` produced a failed native turn. The runner process exited, but workspace recovery retained the sandbox without stopping it. The recovery callback used successful workspace copy-back to select warm retention. It bypassed the terminal-state check in normal heartbeat teardown. **Expected behavior** Keep a sandbox running only after a successful run. Failed, cancelled, timed-out, and interrupted runs must convert requested warm retention to stop-and-retain. Preserve the existing ownership hold before release. **Steps to reproduce** 1. Persist a terminal failed native run whose workspace copy-back succeeds. 2. Release its environment lease from the recovery path with a stored `keep_running` disposition. 3. Observe that the provider receives `keep_running` on the base commit. 4. With this fix, the provider receives `stop_and_retain` and the lease status follows the durable run outcome. **Paperclip version or commit** Base: `5edf55d7350c7f08c9dd132c7e0f1421fa0bf2fb`. **Deployment mode** Native runner with a reusable Daytona sandbox. Related: #14747 retires unsuccessful warm runner sessions. This change closes the separate recovery lease-release path. Related search found no duplicate fix. ## What Changed - Read the durable run status at the shared lease-release boundary. - Apply the existing terminal-outcome retention rule before calling the environment runtime. - Use that same durable status for the lease-state mapping. - Add five database-backed regressions for four unsuccessful outcomes and successful warm retention. - Document the recovery rule. ## Verification - Before the fix: the four unsuccessful-outcome regressions fail; the successful case passes. - After the fix: 163 tests pass across the lease-release, native lifecycle, and explicit continuation suites. - Repository typecheck and build pass. - `pnpm test:run` encountered the existing local `native-session-resume.test.ts:1125` assertion failure; a focused rerun reproduced the same failure. This was also recorded before this follow-up with the unmodified base executor. The full command was stopped after that confirmation, so later local groups were not completed. - All 56 latest-head checks are successful or intentionally skipped (54 passed, 2 skipped), including the complete CI test groups and browser E2E suite. Greptile is 5/5 on `e7da3b3ad`, with no unresolved review comments. - Deployed exact PR head `e7da3b3adbf7a13642c0e56f5b0f0c4666adf358` to the staging workspace and independently verified the serving commit. A real failed native turn persisted `keep_running` and completed workspace finalization, reproducing the recovery-path conditions; Paperclip automatically issued stop-and-retain, and an independent Daytona read confirmed `stopped`. No manual stop was used. - Retried that failed run through the public API after correcting its temporary API-key credential. The same stopped sandbox resumed successfully. Three successful turns retained one live runner PID/start time and the same native, runner, and provider sessions. - Verified exact canonical note contents, deletion persistence, and an unchanged 8 MiB binary after every turn. Subsequent checkpoints copied/hashed only 58 and 87 bytes. After sandbox deletion, canonical files still matched. Temporary secrets were removed and agent/configuration policy restored. - Live acceptance used temporary API-key authentication. The separate managed-subscription authentication issue and browser Retry control were not tested by this campaign. ## Risks - Recovery callers can no longer use stale success status to retain a failed run's sandbox. - The existing native ownership hold still blocks release while ownership is unresolved. - Successful warm turns and explicit destroy dispositions keep their existing behavior. - No database migration, API contract, dependency, or UI change is included. ## Model Used OpenAI Codex, GPT-6, with reasoning, tool use, code execution, and test analysis. The exact served model ID and context-window size are not exposed in this session. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
33f2b3a159 |
fix: separate GitHub tools and code review bot connections (#14750)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - The Connectors catalog lets people give agents tools or connect agents to conversations. > - GitHub put these two uses behind one card and an extra choice. > - People should choose the connection they need from the catalog. > - This pull request keeps GitHub for tools and adds GitHub Code Review Bot as a separate card. > - Each card opens its setup directly. Both use the existing connection code. ## Linked Issues or Issue Description **What existing behavior does this improve?** GitHub connector discovery and setup. **Current behavior** With chat connectors enabled, GitHub opens a menu that asks whether to use tools or create a bot. Saved tools and bots share the same catalog entry. **Proposed behavior** GitHub opens tool account access. GitHub Code Review Bot opens agent selection. Saved bots and drafts appear under the bot card. Chat-disabled instances show only GitHub tools. **Reason and benefit** The catalog names the two uses and removes an extra setup choice. The bot keeps the existing GitHub provider, credentials, endpoint IDs, setup steps, and runtime. **Additional context** Related work: https://github.com/paperclipai/paperclip/pull/12843 and https://github.com/paperclipai/paperclip/pull/14594 established GitHub account identity. This change preserves that tool flow. No duplicate catalog split was found. ## What Changed - Split the generated app definitions into GitHub tools and GitHub Code Review Bot. Reuse the existing GitHub logo and channel method. - Open bot setup directly, including old resume and reconnect links. - Put existing bot endpoints and drafts under the bot card. Hide duplicate internal chat applications. - Keep pasted GitHub URLs mapped to the tool connection. - Add seven Storybook states for the catalog, saved connections, disabled chat, both setup paths, mobile, and light mode. - Fix narrow-screen bot rows so the label cannot overlap status and setup actions. - Update catalog, route, browser, and API tests, plus the GitHub connector guide. ## Verification - [Hosted Storybook](https://d1p6rlowie26tp.cloudfront.net/storybook/branches/codex~2Fgithub-review-connection/?path=/story/connections-github-and-code-review-bot--catalog): seven states built from this branch. The deployment passed its public-file verification. - All GitHub checks pass on `d13a2cd53561645bb2a15c6f8e75a61a936d6459`. Two optional Storybook jobs skip under their normal trigger rules; the manual Storybook deployment passes. The branch has no merge conflicts. - Greptile: 5/5 on the current head, with no review comments or unresolved threads. - `pnpm -r typecheck`, `pnpm build`, `pnpm check:token-gates`, and `pnpm build-storybook` passed. The final Storybook fixture also passed UI typecheck and the hosted build. - Targeted catalog, URL matching, routing, grouping, brand, and chat UI contract tests passed. - GitHub provider browser tests: 2 passed. These cover direct tool setup and the bot setup and management lifecycle with provider responses mocked. - Embedded-browser test on an isolated local instance: opened both cards, selected an agent, saved a bot draft, and resumed the same endpoint under the bot card after a reload. - Storybook Tool Setup and Bot Setup assertions pass in the published preview. Chat Disabled assertions pass locally. Inspected mobile and light mode, including the draft-row layout and official GitHub marks. - Local full-suite limitation: `pnpm test:run` was not clean. A cross-company route assertion failed in the aggregate run and passed in isolation; a workspace-runtime test reached its 30-second hook timeout. Some isolated database reruns skipped when the embedded-PostgreSQL availability probe failed. The local aggregate was stopped after CI completed. The corresponding full CI suites pass all 360 tool-access tests and all 162 workspace-runtime tests. - No live GitHub authorization or installation was performed. The isolated instance correctly stopped at the cloud enrollment or public HTTPS prerequisites. ## Risks - Low scope: catalog presentation and routing change. There is no database migration or provider credential change. - Existing GitHub bot URLs now open bot setup directly. The tool route remains `/apps/connect?source=github`. - The bot remains behind the existing chat-connectors feature flag. Existing endpoints retain `provider: github`. - Channel applications are represented by endpoint rows. Regression tests cover legacy bot applications, tools, active bots, and drafts together. ## Model Used OpenAI GPT-6 through Codex, with reasoning, code execution, and embedded-browser tools. The exact deployed model ID, context window size, and reasoning setting are not exposed to this session. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
018993140f |
feat: let agents name prompt-only tasks (#14761)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Users create tasks with a title and a description. > - A required title adds work when the prompt already explains the request. > - An agent can name the task once it reads that request. > - This pull request accepts prompt-only tasks and starts them with a short prompt slice. > - A scoped title tool lets the assigned agent replace that slice early without changing execution state. > - A live browser eval checks the real agent call, saved title, audit entry, and preservation of user titles. ## Linked Issues or Issue Description **Subsystem affected** Cross-cutting: task creation, shared contracts, database, server, runner tools, and board UI. **Problem or motivation** Users must currently write a title before they can submit a detailed task prompt. The agent has enough context to write a useful title itself. **Proposed solution** Make the title optional when a description is present. Save the first 120 characters of the normalized prompt as a provisional title. Ask the assigned agent to call `set_task_title` early. Use an atomic provisional-title guard to preserve titles supplied or edited by users. Keep explicit titles supported. Related: #14543 and #14556 concern empty-title submission. This change intentionally enables that submission when a prompt is present, instead of requiring a title. ## What Changed - Add the `titleNeedsGeneration` field with an idempotent migration. Keep existing titles unchanged. - Add `PUT /api/issues/:id/title` and the native and legacy `set_task_title` tool. Enforce company access, active-run ownership, shared, bounded retry receipts across native/HTTP calls, and transactional audit logging. Refresh external-object links after commit, with the same feature gate and plugin detectors as ordinary title edits. - Add early naming guidance in Standard, Ask, and Plan task context. Preserve the description, status, and assignment. - Allow prompt-only root and child task creation, plus draft restoration in the New Task dialog. Keep user titles supported. - Add an opt-in Product E2E suite for prompt-only Standard and Ask tasks, plus an explicit-title control. It checks actual provider calls within the first five tools, persisted state, audit attribution, and the reloaded UI. - Preserve a closed vocabulary of API key maintenance phrases in declared prose while rejecting opaque credential suffixes. Add one bounded naming retry after wording is rejected, without treating the rejected call as a saved title. - Repair the native cleanup receipt check exposed during full verification: accept matching input digests, retain legacy input checks, and reject conflicting receipts. ## Verification - Live Product E2E on `f43478473800e3a46b85c5ee79677efdb15108e7`: **3/3 passed** with native Codex `gpt-5.4-mini`, first attempts only, automatic retries disabled. Standard and Ask each saved “Rotate expired API key” on their first tool call, with matching persisted state and a single same-run audit entry. The explicit-title control retained its user title with zero title writes. All three verified the reloaded browser UI. - Campaign: `local-2026-09-30T21-30-11-021Z`. Earlier failed campaigns are retained separately; they exposed credential-prose handling and prompted the naming recovery fix. No failed result was regraded or deleted. - Reproduce with `pnpm test:e2e:runner -- --id task-titles.runner-codex-mini.local.prompt-title-standard --id task-titles.runner-codex-mini.local.prompt-title-ask --id task-titles.runner-codex-mini.local.preserve-explicit-title --max-automatic-retries 0` and an authorized provider key. - Full `pnpm -r typecheck` and `pnpm build` passed on the latest commit. The runner build used the configured external eval source tree. - Product E2E unit suite: **61 files, 818 tests passed**; E2E typecheck and UI token gates passed. - Title API/native regressions cover prompt-only and explicit child creation, user edits, ownership/company isolation, external reference refresh, cross-surface retry replay, and the 64-key limit without receipt eviction. All passed. Prompt-context coverage: **44 tests passed**. - Rust credential regressions: **35 tests passed**, including benign maintenance qualifiers and opaque credential rejection in every declared prose field. Catalog/report reconciliation: **28 tests passed**. Native recovery: **560 tests passed**. - Broad local `pnpm test:run`: **14,555 tests passed** in the general server group; two suites failed to initialize embedded PostgreSQL and the existing 40,000-file Git streaming stress test exceeded its 300-second macOS timeout. All three suites then passed in isolation (**5 tests passed**) without code or timeout changes. The original full local command exited nonzero and is not being represented as a clean full run. - Latest-head GitHub checks are green: **53 passed, 4 skipped, zero failed or pending**, including all test shards and the canary packaging dry run. Greptile reviewed the same commit at **5/5**, with zero unresolved review threads. ## Risks - The additive database field must reach the server and UI together. The migration uses `IF NOT EXISTS` and defaults existing tasks to a final title. - Title generation depends on the assigned agent running. Tasks without a run keep their provisional title. - Live qualification covers the native Codex path in Standard and Ask modes. API/legacy and Plan behavior have deterministic coverage. - The credential-prose exception validates the entire suffix against a closed maintenance vocabulary. Unknown suffixes, assignments, quoted values, credential prefixes, and diagnostics retain strict checks. ## Model Used OpenAI Codex, based on GPT-6, with reasoning, tool use, and code execution. The exact deployment ID and context window are not exposed in this session. The live eval uses the native Codex `gpt-5.4-mini` profile. ## 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> |
||
|
|
0ea6b10967 |
Record ACP activity and workspace restore failure evidence (#14665)
## Thinking Path Paperclip records terminal run failures for operators. A timeout's own log and cleanup output update the run's last-output timestamp, so that timestamp can make a long-silent provider look active. Snapshot runtime activity before finalization and include the saved workspace restore classification to make the next failure actionable without copying tool payloads. ## Linked Issues or Issue Description **What existing behavior does this improve?** Terminal run diagnostics in the existing opt-in Sentry integration. **Current behavior** Reports cannot distinguish runtime events from finalization logging and omit the already-persisted workspace restore code. A later successful run also does not establish that earlier workspace files were restored. **Proposed behavior** Record runtime-event age/count and pending-tool inventory at finalization, before status reads and cleanup. Forward only finite counts, a completeness boolean, and known restore codes through the existing reporter. **Reason and benefit** Operators can distinguish a silent turn with unfinished tools from recent runtime activity and see restore failures without retrieving private run output. Neither signal certifies productive work or successful recovery. **Breaking changes** None. Error grouping, execution deadlines, cancellation, recovery policy, and the Sentry opt-in remain unchanged. Related diagnostic work: #14573, #14575, #14639. ## What Changed - Snapshot ACP activity before success/failure finalization, including thrown relay failures. - Forward bounded numeric/boolean evidence and shared workspace restore codes; exclude commands, tool IDs, paths, and arbitrary result data. - Document limitations and test silence, empty streams, timeout, cleanup delay, incomplete tool inventory, and privacy. ## Verification - `pnpm -r typecheck` passed after the final implementation. - Changed suites: 252 tests passed; all 29 database reporter tests subsequently passed after restoring the embedded-Postgres package library symlinks. The migration test also passed (30 database cases total). - `pnpm build` passed during implementation. Final head `fe78dba6f592b1abccac7cdbf341bd2e0b0d30cb` passed all 53 CI checks, including complete test coverage, typecheck, build, and browser/runner gates; two unrelated checks intentionally skipped. - Full local test attempts initially hit missing embedded-Postgres library symlinks; the dependency setup was repaired and database tests passed. Duplicate local full-suite runs were stopped after full CI completed. This PR does not claim a completed full local suite. - Review regression: completed, failed, and cancelled tools are excluded from the pending count; focused activity/timeout tests and adapter-utils typecheck passed. - Reviewed the diff for secrets, customer data, and internal references. ## Risks Low risk, diagnostic-only. The existing tool inventory is incomplete for some runtime events, so the report carries its completeness flag. Event age is measured at finalization and does not prove useful work or identify the underlying provider failure. No schema changes or new capture gate. ## Model Used OpenAI GPT-6 via Codex, with repository inspection, code execution, and tests. Exact model build identifier is not exposed by this session. ## Checklist - [x] Thinking path and model are specified - [x] Checked ROADMAP.md; this is a maintenance correction, not planned feature work - [x] Searched for duplicate and related PRs - [x] Described the issue using the enhancement template - [x] No internal issue references, customer data, or private instance links - [x] Descriptive branch name - [x] Focused regression tests pass - [x] Added tests and updated documentation - [x] Risks documented - [x] Required validation and CI gates are green (full suite validated in CI; local scope documented above) - [x] Greptile is 5/5 with no unresolved findings - [x] I will address review comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
5edf55d735 |
fix: retire failed warm sessions before sandbox stop (#14747)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Native runner sessions can stay warm between turns in a reusable sandbox. > - Heartbeat stops that sandbox when a turn fails or is cancelled. > - The native executor treated every returned terminal result as a successful warm release. > - A failed session could therefore retain a transport for a stopped sandbox. > - This pull request retires unsuccessful sessions before heartbeat stops their sandbox. > - A retry can start without inheriting that stale transport. Successful turns stay warm. ## Linked Issues or Issue Description **What happened?** A structured failed or cancelled terminal result did not throw. The host kept its native session in the warm cache even though heartbeat stopped the reusable sandbox. Later session retirement could use the stopped provider transport and reject the retry. **Expected behavior** Retire the unsuccessful session and collect its managed files before returning to heartbeat. Keep successful sessions warm. **Steps to reproduce** 1. Run a native session with a warm lifecycle and a reusable sandbox. 2. Return a structured failed or cancelled result from the provider. 3. Stop the sandbox after the executor returns. 4. Retry with a changed native session identity. 5. Verify that the previous session was closed before step 3 and is not closed again during retry. **Paperclip version or commit** Developed from `b54b2dc35`, the current `origin/master` at implementation time. **Deployment mode** Native runner with a reusable Daytona sandbox. The same warm-session release path also serves local providers. Related work: #14735 added incremental managed-file checkpoints for warm turns. #14734 preserves tool outcomes during shutdown. This change fixes the host's handling of unsuccessful terminal results. ## What Changed - Retain a warm session only when its terminal run state is `succeeded`. - Use the existing failed-session retirement path for structured failures and cancellations. - Preserve the existing checkpoint-before-retirement path, including when provider shutdown fails. Collect stopped files after successful shutdown, including edits made during shutdown. - Retire the warm owner if the checkpoint or its receipt callback rejects, then propagate the initiating error. - Add ten regression cases for failure and cancellation, with and without managed files. They check cleanup order, cache removal, retry with a new session identity, and edits preserved when close rejects. - Document the lifecycle rule. ## Verification - The failed and cancelled managed-file regressions fail on unpatched master because the provider is not closed. - All 516 native executor tests pass, including ten new regressions. - `pnpm -r typecheck` and `pnpm build` pass. `pnpm test:run` finished its general-server group with 14,537 passed, 75 skipped, and one existing failure in `native-session-resume.test.ts` (`retainedNativeCleanupJournalMatches`, line 1125). A separate run using the unmodified `origin/master` executor fails the same assertion. The command stops before later local groups; all equivalent CI groups pass on this head. - All 56 PR checks are successful or intentionally skipped. Greptile reviewed this head at 5/5 with no remaining findings. - A real Daytona public-API probe forced a Codex authentication failure, waited for a confirmed sandbox stop, corrected the credential, and retried successfully in the same resumed sandbox. It verified the agent note in canonical storage and deleted the test sandbox. - Pumpkin staging on this exact commit: forced a structured authentication failure, confirmed sandbox stop, corrected the credential, and retried successfully in that same sandbox. Three successful turns kept the same live runner PID/start ticks, native session, runner instance, and provider session. Canonical downloads verified the note, all 8 MiB binary bytes, and deletion persistence. Subsequent checkpoints hashed/copied only 52 and 78 bytes. After sandbox deletion, canonical files still matched. Temporary secrets, agent configuration, and test policy were cleaned up or restored. - Unpatched live probes with both 5-second and 90-second retry delays also succeeded. The unit regressions prove incorrect retention; the original stopped-lease exception was not reproduced in those probes. The staging recovery campaign used the public retry API after an explicit reset of the disposable task’s already-deleted old sandbox/session. The UI did not expose a Retry control on the inspected task or run detail views. - Temporary API-key authentication was used for the campaign. This change does not repair the original managed-subscription authentication 401. ## Risks - Failed and cancelled turns now close their provider sooner. Successful warm-turn behavior is unchanged. - Cleanup uses the existing failed-session path. Its existing handling of cleanup errors is unchanged. - No database migration, API contract change, or dependency change is included. ## Model Used OpenAI Codex, GPT-6, with reasoning, tool use, code execution, and test analysis. The exact served model ID and context-window size are not exposed in this session. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass (516 relevant executor tests; the full local suite has the independently reproduced baseline failure documented 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 - [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> |
||
|
|
ad55d0a281 |
fix(connections): repair personal credentials and request write access (#14739)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Agents use Apps through a gateway that checks identity, company access, and action policies. > - Personal pasted credentials can point to company secrets. Setup can show success while the gateway rejects every call. > - Several OAuth methods also omit the scopes needed for their supported write actions. > - This pull request gives setup, health checks, and invocation the same credential rules. Owners repair existing connections by reconnecting. > - New connections request reviewed permissions for their supported actions. Read-only choices remain available under Advanced. > - Agents can use the connections people give them, while existing consent, identity boundaries, and action restrictions remain enforced. ## Linked Issues or Issue Description Refs #14009 and #14008. This addresses the personal-credential defect. The separate GitHub organization-identity selection defect is outside this change. Related work: #13942 fixed part of new personal-key setup. #14200 independently fixes legacy personal reconnect and protects managed-agent profile credentials during removal. This PR covers that ownership invariant across key and secret-URL setup, reconnect, health, discovery, and invocation, and keeps owner reconnect as the repair path. #14059 tracks requested versus provider-asserted OAuth scopes; it remains separate work. I searched open PRs and issues for Zapier, Airtable scopes, connector writes, and personal credential failures. **What happened?** A Zapier secret URL saved through personal setup can become a company secret referenced by a user grant. Health checks bypass the gateway's ownership check, so the connection appears healthy but calls fail with `grant_credential_invalid`. Custom-header paths can also receive a duplicate `credentials.` prefix. Omitted OAuth scopes make write access depend on provider defaults. **Expected behavior** Personal invocation credentials belong to the selected user. Setup, health, and actual calls enforce the same rule. New connections request documented permissions for supported read and write actions. Existing tokens gain no permissions without provider consent. **Steps to reproduce** 1. Connect Zapier or a generic secret URL with the personal identity. 2. Allow an agent to use the connection and complete setup. 3. Invoke a tool through a run-scoped gateway. The legacy layout fails ownership validation despite successful setup. **Paperclip version or commit** The implementation started from `44736c9c7c67b7b646ead9d51721db10f5b83835` and was rebased onto master at `94e8dec56`. **Deployment mode** Built from source. Regression tests use isolated PostgreSQL fixtures and controlled MCP transports. ## What Changed - Share credential writing, ownership validation, and canonical paths across initial setup, resume, reconnect, rotation, health, discovery, and gateway calls. Keep OAuth client-registration secrets separate from invocation credentials. - Existing personal connections with company-scoped credentials require owner reconnect with a fresh key or secret URL. Reconnect creates a correctly owned value and updates the existing grant and declarations. There is no automatic ownership backfill or new startup hook. - Preserve PostgreSQL timestamp precision when reconnect checks whether a grant changed. Previously, converting the timestamp to a JavaScript Date could reject reconnect with a false concurrent-change error. - Protect credentials used by other grants, connections, bindings, managed-agent profiles, routine triggers, or secret proposals from connection removal. - Review all 117 tool methods, including 84 OAuth methods. Record explicit scopes or documented provider-default exceptions with official evidence. Add Airtable's seven scopes, Hugging Face repository/job scopes, and other documented MCP permissions. - Prefer available write-capable methods. Put explicit read-only choices under Advanced. Explain pasted-key permissions and offer reconnect for missing OAuth consent. Preserve existing grants, policies, Google availability gates, and curated scope allowlists. - Reconnect generic secret URLs and custom headers using their stored credential fields. Refresh the catalog after setup, correct reconnect feedback and error guidance, and let Cancel exit invalid setup while Save & exit retains draft-saving behavior. - Apply ownership checks to the new GitHub repository/skill connection picker. Align the permission audit with the Google scope reductions merged on master. - Add run-scoped gateway, ownership, owner-reconnect, OAuth URL, insufficient-scope, UI, and catalog-wide regression coverage. Update the connector playbook and permission audit. ## Verification Latest commit `97bc0b86e0eae0ec892e4ac44beff1a66164b20e` passes all CI/status gates (55 completed check runs, no failures or pending checks) and has a completed Greptile review at **5/5 with no outstanding findings**. GitHub reports the PR as mergeable/CLEAN. - **Embedded browser:** used the actual server and built UI from this worktree, a fresh isolated database, and local HTTP MCP fixtures. Completed personal bearer-key, secret-URL, and custom-header setup; reproduced the legacy ownership failure; reconnected through the owner’s form; and completed writes afterward. Read-back was verified for bearer-key and secret-URL connections. Public organization-wide setup appeared immediately in Browse without reload. Zapier URL validation/Cancel and Google’s enrollment gate were also exercised. - **Persistence and invocation:** verified user ownership, canonical `credentials.authorization` / `remote.url` / `headers.X-Api-Key` declarations, and unchanged connection/grant identity. The old company secrets retain their ownership. Separate HTTP calls through an actual run-scoped gateway session completed a write and read-back. - **Backend coverage:** the final gateway suite passes all 82 cases, including catalog Zapier and generic inline reconnect. It checks company/user isolation, canonical declarations, same-endpoint URL validation, fresh credentials, retained restrictions, and real gateway read/write execution using fixture transport. A timestamp with PostgreSQL microseconds covers the former false reconnect conflict. - **Local checks:** 368 catalog, gateway, repository, and UI tests passed before the final extra Zapier case; 49 GitHub skill access tests also passed. All three Apps browser regressions pass, including reconnect through the actual form and catalog visibility without reload. Full `pnpm -r typecheck`, `pnpm build`, server typecheck after the final patch, and token gates passed. Full tool-access service runs hit varying 15-second Google fixture timeouts; both affected cases and the updated reconnect assertion pass in isolation (3 tests). The complete test matrix passes in CI on this head. - **Verification limits:** no live provider account was available for Zapier/Airtable/OAuth consent or account-bound write proof. Public metadata and local fixtures do not establish provider consent. The original development database clone failed on a pre-existing missing `tool_connections_transport_check` constraint; browser acceptance used a fresh isolated database created by the normal CLI onboarding flow. ## Risks - Existing broken personal connections stay unusable until their owner reconnects. Health, discovery, and invocation return an actionable ownership error; startup does not rewrite credential ownership. - Scope changes affect new authorization requests. Providers may still require resource selection, account roles, paid plans, or app verification. Existing consent and action restrictions remain unchanged. - Shared credentials are retained rather than reassigned or revoked. Provider-default exceptions and unavailable live checks are documented in `doc/connections/CONNECTOR-PERMISSION-AUDIT.md`. - No new endpoint, database table, lockfile change, or CI workflow change is included. ## Model Used OpenAI Codex, based on GPT-6, with reasoning, code editing, shell execution, web research, and browser tools. The exact deployment model ID and context window were not exposed in this session. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
cbd278dc03 |
fix(interactions): derive chat recipients and validate explicit users (#14742)
## Thinking Path > - Paperclip helps people manage AI agents and their work. > - Agents use saved questions to get human input and continue the same task. > - The standard question example recently told models to copy a user ID. > - A model can omit an identity prefix and create a question its intended recipient cannot answer. > - Agent Chat already knows the conversation owner, so the server can supply that identity. > - This pull request removes the blanket instruction and validates explicit recipients before saving. > - Ordinary questions stay simple, and explicit addressing remains available for decisions that need a particular person. ## Linked Issues or Issue Description Refs #14707, #14188. Related: #14238 handles legacy email recipients; this change prevents invalid recipients in new cards and retains exact ID matching. **What happened?** A model copied a Cloud user ID without its prefix into `addresseeUserId`. Creation succeeded. The intended user's answer then failed the exact recipient check. **Expected behavior** Ordinary chat questions use the saved conversation owner. A task may optionally name a specific recipient. The API rejects an unknown or unauthorized recipient before it creates a card. **Steps to reproduce** Create a chat question for a user whose ID is `paperclip-id:example`. Supply `example` as the addressee. Before this change, creation accepts the invalid recipient and the owner cannot answer. With this change, creation returns 422. Omitting the field saves the full owner ID and allows that owner to answer. ## What Changed - Remove `addresseeUserId` from standard question examples and remove the blanket requester-ID instruction. - Derive the recipient of ordinary chat questions from the persisted conversation owner. Reject conflicting explicit user IDs. - Keep explicit task recipients optional. Validate supplied user IDs with the existing board mutation policy, including company, viewer, and Cloud restrictions. - Preserve explicit agent routing, connector intents, confirmations, exact recipient checks, idempotent retries, and no-login local-board authority in local-trusted mode. - Update the blocker grader to accept an omitted recipient and verify the actual requester answered. - Add database and HTTP tests for prefixed identities, denied recipients, concurrent retries, saved answers, and response delivery. ## Verification - Database interaction service suite: 90 tests passed, including implicit local-board creation/answering and authenticated/Cloud denial. - Interaction HTTP route suite: 84 tests passed. - Affected interaction/native/connector/documentation suites: 231 tests passed across six files after valid-user fixtures were updated. - Resolver and interaction unit suites: 29 tests passed. - Product E2E unit/calibration suite: 793 tests passed; Product E2E typecheck and blocker catalog discovery passed. - Generated API-reference and capability contract checks passed. - `pnpm -r typecheck` and `pnpm build` passed. - Full local `pnpm test:run` did not finish green: its initial general-server pass had 14,416 passing assertions, one unrelated native-resume assertion failure on macOS, and three teardowns from an intermediate fixture cleanup fixed above. Separate broad local groups also encountered timeout/live-port failures under host load. Local UI (7,026), CLI (502), shared (817), and skills-catalog (20) tests passed; the complete final-head CI matrix is the broad verification gate. - After two CI cold-start readiness timeouts, a separate test-only commit gives the first exposure lifecycle fixture the existing normal 30-second readiness budget. Its real HTTP, ordering, and cleanup assertions remain intact; the targeted case and final Linux CI shard passed. Production deadlines are unchanged. - A separate OpenCode fixture failed twice on GitHub-hosted Ubuntu because its cached Node executable was group-writable; the same case passed on AWS runners. The fixture now qualifies its own Linux copy with mode `0500` and the actual copy digest. Host files and production security checks are unchanged. The focused macOS case passed; the new Linux-copy branch also passed on the final AWS-hosted Linux runner (1,125 passing Runner tests, 3 skipped). The final run was not on a GitHub-hosted runner. - Final-head [CI run 36762078176](https://github.com/paperclipai/paperclip/actions/runs/36762078176) passed for `116b968b24fa0a8c5724a7bf96e73a8dda5f0425`: 54 successful checks and two conditional Storybook skips, with no pending or failed checks. The 27 general/serialized test jobs reported 28,635 passing tests. Typecheck, build, Runner, browser E2E, and Canary gates passed. Greptile reviewed that exact head at 5/5; both review threads are resolved, with no open follow-ups. - No live provider replay is claimed by this PR. ## Risks - New explicitly addressed cards reject users who cannot mutate the issue, including viewers, inactive members, and invalid IDs. Callers that supplied invalid recipients must correct their request. - Existing addressed cards are not rewritten. Existing authorization checks remain strict. - Chat inference applies only to questions without an agent addressee. Connector intents and governed confirmations retain their own recipient paths. - No schema change or migration is required. ## Model Used OpenAI Codex, GPT-6 (exact serving variant and context window are not exposed in this environment). Used reasoning, tool use, code editing, and test execution. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
b54b2dc35c |
fix: preserve warm Codex turns with incremental managed file checkpoints (#14735)
## Thinking Path > - Paperclip manages AI agents and keeps their instructions and files durable. > - Native Codex runners can keep a process alive between compatible turns. > - Managed file collection stopped that process after each turn, which defeated warm reuse. > - Agent folders can contain large images and other files, so full copies on every turn are expensive. > - This change keeps one managed directory for the live session and saves only file changes after each turn. > - Ownership, authorization, instruction changes, and process retirement still control when reuse is safe. ## Linked Issues or Issue Description Related: #13710 introduced native warm session reuse. This fixes managed file collection that still forced those sessions to stop. No duplicate open PR or issue was found. **What happened?** With managed instructions and warm native Codex enabled, consecutive turns reused a Daytona sandbox but started a new runner process each time. The managed directory collector required process termination before saving files. **Expected behavior** Compatible turns keep the same process and managed `AGENT_HOME`. Each completed turn saves added, changed, and deleted files before the next turn starts. Unchanged large files do not transfer again. **Steps to reproduce** 1. Use a native Codex agent with managed instructions and a reusable Daytona environment. 2. Enable warm session reuse and run three turns on the same task. 3. Write a large binary on the first turn, edit a small note on each turn, and delete a file on the second turn. 4. Compare process identity across turns and read the canonical files through the public agent-files API. **Paperclip version or commit** Reproduced on `d30b03bd8c17604cdab1533eeeeb087aba30e8b1`. **Deployment mode** Local server with remote Daytona execution; cloud native runner uses the same path. ## What Changed - Retain the managed directory only for the verified owner of a live native Codex session. - Checkpoint each completed turn before releasing the session for reuse. Retry unstable captures, then stop and collect when a warm checkpoint cannot be validated. - Compare metadata and cached hashes, stream only changed file payloads, record deletions, and validate path, content, quota, and authorization before saving. - Rotate sessions when canonical files, loaded instructions, credentials, or launch policy change. Fence stale collection and cleanup callbacks from later owners. - Keep cleanup and recovery aware of the current session owner. Recheck canonical files under the writer lock at handoff, attach the successor collector before fallible bookkeeping, and emit one final save receipt on checkpoint fallback. Preserve storage warnings across unchanged checkpoints. - Add regression coverage and a three-turn Daytona test with independent public API file checks, an unchanged 8 MiB binary, deletion checks, and strict process identity checks. - Document checkpoint consistency, lifecycle behavior, and local run-log counters. - Replace a timing assumption in the Daytona teardown test with explicit transfer-arrival gates after CI exposed an unset release callback. ## Verification - Full local `pnpm -r typecheck` and `pnpm build` passed. Server checks were repeated after the final storage-warning fix. - Runner E2E typecheck and 749 runner E2E unit tests passed. - Focused file checkpoint, directory ownership, instruction collection, native session, and merge tests passed. After review fixes, the managed-directory and native-session suites passed 550 tests, including intervening canonical edits, same-run fresh restore, failed handoff collection, and one-call fallback collection. Server typecheck passed again. The Daytona plugin suite passed 218 tests. The quota-warning regression failed before the fix and passed afterward. - Three real Daytona campaigns passed before the final handoff review fixes. The latest kept PID 547 across all three turns. The first checkpoint copied 8,388,635 bytes; the next two copied 36 and 54 bytes. Public API reads verified the binary, note contents, and deletion after every turn. Test cleanup deleted the sandbox. - The final head was also deployed to an isolated cloud staging instance and passed three UI-triggered native Codex turns with managed instructions. All three retained the same process ID/start time, native session, provider session, runner instance, and Daytona sandbox. Checkpoints copied 8,388,643 bytes on turn 1, then only 52 and 78 bytes on turns 2 and 3; those warm captures also hashed only 52 and 78 bytes. Independent canonical API reads verified every byte of the unchanged 8 MiB binary and the exact note contents after every turn; the deleted file returned 404 after turns 2 and 3. After restoring the original lifecycle and agent-auth configuration, removing the temporary secret, pausing the test agent, and deleting both test sandboxes, independent canonical API reads still verified the entire binary, the final 78-byte three-line note, and the deletion. The native runner flag remained enabled and the final serving revision remained the PR head. - Two earlier staging attempts are preserved as failures and are excluded from the acceptance result: a saved ChatGPT login failed with a provider routing 401, and its subsequent stopped-sandbox retry failed before provider startup with a closed-lease admission error. The successful campaign used a fresh sandbox and a temporary encrypted API-key binding. The stopped-lease retry remains unexplained; this campaign does not establish recovery of that failed sandbox. - All [Paperclip CI gates](https://github.com/paperclipai/paperclip/actions/runs/36750397355) pass on `26ef2ef56a389259246809805c0b34a4747eb86b`, including full test partitions, build, typecheck, runner verification, E2E shards, and the Canary clean public-npm install. Greptile reviewed that exact head at 5/5 with no unresolved review threads or outstanding findings. - Full local repository coverage used the existing CI partitions, but the 40,000-file Git streaming stress test timed out and its local retry was interrupted by macOS thermal emergency sleep; this is not a green full local suite claim. The exact stress test passed on the final head in [CI server shard 2/12](https://github.com/paperclipai/paperclip/actions/runs/36750397355/job/110008294290), in 111.9 seconds. - Repeat the live test with configured credentials and a Linux runner artifact: `pnpm test:e2e:runner -- --id daytona-warm-continuity.runner-codex.daytona.warm-three-turn`. ## Risks - This is a file-level checkpoint, not an atomic snapshot of the whole folder. Background writes after a capture are saved by the next checkpoint or final stopped collection. - Metadata scans still visit all paths. Modified files transfer in full; unchanged files do not rehash or transfer. - Incorrect ownership or reuse could collect the wrong directory. Run ownership fences, current authorization, stable capture validation, and stopped collection fallbacks are covered by tests. - Warm reuse remains opt-in. No database migration or fleet default changes. ## Model Used OpenAI GPT-6 through Codex, with reasoning, code editing, tool use, and test execution. The exact serving model ID and context-window size are not exposed by this session. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
d432dc7fa3 |
Add GitHub-synced skill sources (#14713)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Company skills supply instructions and files to those agents. > - GitHub imports already exist, but users cannot manage repositories as skill sources. > - Repository refresh also needs caller-authorized access and complete local packages. > - This pull request adds Sources inside Skills and reuses GitHub connections from Apps. > - Installed snapshots let agents use skills without fetching GitHub during a run. > - Manual refresh preserves skill identity and leaves failed imports on their last good version. ## Linked Issues or Issue Description **Subsystem affected** Cross-cutting: skills UI, server, database, shared contracts, and runtime materialization. **Problem or motivation** Users keep skills in GitHub repositories. They need a clear way to select, import, and refresh those skills. Existing imports do not expose repository management or consistently preserve supporting files. **Proposed solution** Add company-scoped skill sources. Browse repositories from all accessible GitHub connections, or paste a public repository or branch URL. Select whole skill packages, inspect included files and reference warnings, and install complete, immutable snapshots. Refresh each source manually. **Alternatives considered** Project repository settings hide the workflow from Skills. A second GitHub connector would duplicate credentials and grants. Upstream editing and PR creation are separate work. **Roadmap alignment** This implements the Skills Manager direction in ROADMAP.md. The maintainer requested this scope and reviewed the component and full-app journey stories before implementation. Related reports: Refs #10285, Refs #10949, Refs #13464. Related work: #14356, #13656, #9268. ## What Changed - Add source and entry records, an idempotent migration, company-scoped APIs, and legacy GitHub import adoption. - Reuse current caller grants and credential refresh. Combine and deduplicate repository inventories across accessible connections. Pasted public URLs also prefer the active user’s authorized connections. Tokens stay in the Git child environment, never argv or disk. - Fetch a shallow Git snapshot at one immutable commit. Scan the full local tree, including hidden and nested folders. Read Git objects without checkout or archive transformations and enforce nested package boundaries. - Bound Git downloads to 128 MiB and three minutes. Cancel active process groups and remove incomplete downloads. Preserve cancellation and deadlines while progress drains; close stalled HTTP progress streams after 30 seconds. Reuse caller-scoped temporary snapshots for preview/import after reauthorization. - Index repository package boundaries once and cap expanded work at 1,000 packages, 10,000 files, and 100 MiB, including repeated copies of shared blobs. Bound path depth and the shared path index. Discovery keeps audited manifests without retaining all package bodies. - Resolve moving branches before fetching so unchanged discovery reuses caller-scoped snapshots. Limit active scans, scan frequency, and new downloads per caller and company; quotas apply before metadata reads and across connections, and cached scans do not consume the download quota. - Store complete versions with script content, binary bytes, and executable modes. Preserve these through copies, runtime caches, and runner packaging. - Stage downloads before publication. Use source leases, revision checks, and transactional activity records. Keep installed versions after failures, upstream deletion, deselection, and disconnect. - Add the approved import flow, Sources page, selection tree, provenance, read-only Studio behavior, and saved return from GitHub setup. - Add package manifests, commit-pinned file previews, and separate runtime requirements and reference warnings. Supporting files are included together; nested skills remain independently selectable. Preview requests reauthorize the caller and re-audit package content. - Show installed skills as compact links beneath each source. Repository titles open GitHub. Keep Refresh, Select skills, and Disconnect source in a three-dot menu. Source rows omit the branch, imported count, and refresh timestamp; action alignment and repository titles work at narrow widths. - Stream discovery metadata over an opt-in NDJSON response. Show measured Git download progress and real package/file counts, animate newly checked skills, support cancellation, and require a complete scan before selection. Keep the existing JSON API. - Retain component stories and add a separate full-app journey story group. Include fixed progress states and interactive scan, large-repository, interruption, and saving stories. - Update Skills documentation and product contracts. Suppress private GitHub skill references in telemetry. Privacy review requested for the telemetry changes. ## Verification - Local repository typecheck, full build, token gates, and Storybook build passed during this work. Focused transport, authorization, scanner, persistence, route, and UI tests pass. The final UI refinement passes all eight focused UI tests, UI typecheck/build, and token gates. The scanner resource and repeated-discovery fixes pass 132 focused scanner, transport, authorization, source-service, route, and rate-limit tests, plus server typecheck/build. Full-suite verification comes from CI; the older full local Vitest run was stopped after unrelated chat failures and a font-test failure, all of which passed in fresh focused runs. At commit `1098d5996`, all 54 active checks pass; two optional Storybook jobs are skipped. CI covers repository typecheck, build, the full test suites, browser shards, and the canary dry run. Greptile is 5/5 with no open findings; the security scan also passes. - Adversarial scanner tests verify repeated-blob byte accounting with and without declared sizes, package/file/path caps, one-time repository indexing, metadata-only discovery audits, and nested package boundaries. Additional tests cover branch movement, snapshot reuse, caller/company quotas, isolation across connections, active-lease cleanup, quota recovery, and rejection before any metadata API call. - Real Git tests verify hidden paths, exact binary bytes, executable modes, export-ignore preservation, symlink/submodule reporting, pinned commits, caller-scoped cache reuse, cancellation, cleanup, and credential isolation. Regression tests hold both download slots with permanently blocked progress callbacks, verify timeout/cancellation cleanup and retry, and exercise HTTP backpressure cancellation. Access tests cover automatic public-URL connection selection and revoked grants. Database tests verify company and grant audiences. - Live isolated browser test: the public `anthropics/skills` scan now completes and discovers all 20 skills without connecting an account. Imported canvas-design with all 83 files, opened it from Sources, and verified the installed binary-font preview/download control. Package previews also expose the complete file inventory before import. Cancelled an active Git download and retried successfully to all 20 discovered skills; the browser displayed measured download progress. The current audits reject four other packages; eligible selections remain importable. - Browser checks verify the simplified source rows at desktop and narrow widths, keyboard navigation into the actions menu, Refresh from the menu, selection, and fixture disconnect with installed skills retained. Storybook includes a menu-open checkpoint and a 320px layout. - Storybook includes receiving/preparing download checkpoints and a timed full-app import journey, plus cancellation, retry, large-repository, and saving states. Streaming tests cover split UTF-8 frames, incomplete streams, late responses, cross-company requests, HTTP errors, and JSON compatibility. - Earlier live acceptance on this PR imported `stitch-skill` with `DESIGN.md`, assigned it to an agent, disconnected its source, and ran a successful Studio test that read both installed files. An editable copy changed independently. Both Skills variants, mobile selection, and return from GitHub setup were exercised. - Private access, revoked credentials, OAuth success return, binary/script preservation, concurrent refresh, transaction rollback, version pins, and legacy adoption have automated coverage. A real private-repository OAuth grant was not created during this test. ## Risks - The migration groups recognizable legacy imports without provider calls. Their first successful refresh completes the local package snapshot. - Reference checks are advisory. They cover Markdown links and explicit relative resource paths, not arbitrary runtime dependency graphs. Preview text is capped at 64 KiB; imported bytes remain complete. - Git must be installed on the server. Shallow fetches still download the branch snapshot, including files outside selected packages. Downloads have size/time/concurrency limits. Temporary caches are bounded and caller-scoped. GitHub API quota still applies to repository metadata and the connection picker; content no longer uses per-file API requests. Failed scans retain installed content. - Sources depend on the current caller's GitHub access. A saved connection does not grant access to another person's token. - GitHub script support and immediate manual refresh are explicit maintainer-approved requirements. The operator trusts the selected repository and accepts upstream script and executable-mode changes on refresh. Static audits are not a sandbox or a guarantee of safe code; agents may later invoke installed helpers under their runtime permissions. Import and refresh do not execute scripts, hooks, package installation, or builds. Raw URL and skills.sh imports keep their prior script restrictions. - Source originals remain read-only. Refresh affects subsequent unpinned runs; explicit pins and active runs retain their versions. - The telemetry change removes source-managed GitHub identifiers from skill-reference events. It introduces no event or field. Please review the privacy boundary. ## Model Used OpenAI Codex, based on GPT-6, with reasoning, code execution, and browser tools. The exact serving model ID and context-window size are not exposed in this session. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |