paperclip/packages/adapters/acpx-local/src/server/execute.ts

1732 lines
63 KiB
TypeScript
Raw Normal View History

Add ACPX local adapter runtime (#4893) ## Thinking Path > - Paperclip orchestrates AI-agent companies through a control plane that can start, supervise, and recover agent runs. > - Local adapters are the bridge between Paperclip issues and concrete agent runtimes such as Claude, Codex, and other ACP-compatible tools. > - The roadmap calls out broader “bring your own agent” and claw-style agent support, and ACPX gives Paperclip one path to normalize multiple ACP agents behind a single adapter. > - The branch needed to become one reviewable PR against current `paperclipai/paperclip:master`, without carrying stale base conflicts or generated lockfile churn. > - This pull request adds an experimental built-in `acpx_local` adapter, integrates it through the server/CLI/UI adapter surfaces, and adds regression coverage for runtime execution, skill sync, stream parsing, diagnostics, and log redaction. > - The benefit is that Paperclip can run Claude/Codex/custom ACP agents through ACPX while keeping operator configuration, skills, logging, and transcript rendering inside the existing adapter model. ## What Changed - Added `@paperclipai/adapter-acpx-local` with server execution, config schema, ACPX session handling, CLI formatting, UI config helpers, and stdout parsing. - Registered `acpx_local` across CLI, server, shared constants, UI adapter metadata, adapter capabilities, and agent creation/editing surfaces. - Added ACPX runtime execution support with persistent sessions, local-agent JWT environment handling, skill snapshots, runtime skill materialization, and isolation/security regressions. - Added ACPX adapter diagnostics and marked the adapter experimental in the UI. - Added command/env secret redaction for resolved command metadata in adapter-utils, server event storage, and the Agent Detail invocation UI. - Added Storybook coverage for ACPX config, transcript rendering, and skill states, plus PR screenshots under `docs/pr-screenshots/pap-2944/`. - Rebased the branch onto current `public-gh/master`; `pnpm-lock.yaml` is intentionally not included and there are no migration/schema changes. ## Verification - `pnpm exec vitest run packages/adapters/acpx-local/src/server/execute.test.ts packages/adapters/acpx-local/src/server/test.test.ts packages/adapters/acpx-local/src/cli/format-event.test.ts packages/adapters/acpx-local/src/ui/parse-stdout.test.ts packages/adapter-utils/src/server-utils.test.ts server/src/__tests__/redaction.test.ts server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/acpx-local-skill-sync.test.ts server/src/__tests__/acpx-local-adapter-environment.test.ts server/src/__tests__/adapter-routes.test.ts server/src/__tests__/agent-skills-routes.test.ts ui/src/adapters/metadata.test.ts` — 12 files, 87 tests passed. - `pnpm --filter @paperclipai/adapter-acpx-local typecheck` — passed. - `pnpm --filter @paperclipai/server typecheck` — passed. - `pnpm --filter @paperclipai/ui typecheck` — passed. - Confirmed PR diff does not include `pnpm-lock.yaml`, database schema files, or migrations. Screenshots: ![ACPX Claude skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-light.png?raw=true) ![ACPX Claude skills dark](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-dark.png?raw=true) ![ACPX custom skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-custom-light.png?raw=true) ## Risks - Medium risk: this introduces a new built-in adapter package and touches runtime execution, adapter registration, agent config, skills, and transcript rendering. - ACPX and ACP agent behavior can vary by installed tool versions; the adapter is marked experimental to set operator expectations. - `pnpm-lock.yaml` is excluded per repository PR policy, so dependency lock refresh must be handled by the repo’s automation or maintainers. - No database migration risk: no schema or migration files changed. > 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 coding agent based on GPT-5, with repository tool use, shell execution, git operations, and local verification. Exact hosted context window was not exposed in this environment. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-30 19:57:05 -05:00
import fs from "node:fs/promises";
import os from "node:os";
import path from "node:path";
import { createHash, randomUUID } from "node:crypto";
import { fileURLToPath } from "node:url";
import type { AdapterExecutionContext, AdapterExecutionResult } from "@paperclipai/adapter-utils";
import { readAdapterExecutionTarget, adapterExecutionTargetSessionIdentity } from "@paperclipai/adapter-utils/execution-target";
import {
DEFAULT_PAPERCLIP_AGENT_PROMPT_TEMPLATE,
applyPaperclipWorkspaceEnv,
asNumber,
asString,
buildInvocationEnvForLogs,
buildPaperclipEnv,
ensureAbsoluteDirectory,
ensurePathInEnv,
joinPromptSections,
materializePaperclipSkillCopy,
parseObject,
readPaperclipRuntimeSkillEntries,
Add planning mode for issue work (#5353) ## Thinking Path > - Paperclip is a control plane for autonomous AI companies. > - Issues are the core unit of work, and issue comments are how board users and agents coordinate execution. > - Some issue conversations need to produce plans and approvals instead of immediate implementation work. > - The existing issue contract did not distinguish standard execution comments from planning-oriented issue work. > - This pull request adds an issue work-mode contract and board UI affordances for standard vs planning mode. > - The benefit is that planning-mode issues can be created, displayed, discussed, and carried through agent heartbeat context without losing the normal issue workflow. ## What Changed - Added `standard` / `planning` issue work-mode contracts across DB, shared validators/types, server issue flows, plugin protocol, and adapter heartbeat payloads. - Added an idempotent `0081_optimal_dormammu` migration for `issues.work_mode`, ordered after current `public-gh/master` migrations. - Updated heartbeat/context summaries and issue-thread interaction behavior so planning work mode is preserved when creating suggested follow-up issues. - Added UI support for planning-mode issue creation, issue rows, detail composer styling, and composer work-mode toggles. - Added focused server/shared/UI tests plus a Playwright visual verification spec for planning-mode surfaces. - Rebased the branch onto current `public-gh/master` and added durable planning-mode screenshots under `doc/assets/pap-3368/`. ## Verification - `pnpm --filter @paperclipai/db run check:migrations` - `pnpm exec vitest run --project @paperclipai/shared packages/shared/src/validators/issue.test.ts` - `pnpm exec vitest run --project @paperclipai/server server/src/__tests__/heartbeat-context-summary.test.ts server/src/__tests__/issue-thread-interactions-service.test.ts server/src/__tests__/issues-goal-context-routes.test.ts --pool=forks --poolOptions.forks.isolate=true` - `pnpm exec vitest run --project @paperclipai/ui ui/src/components/IssueChatThread.test.tsx ui/src/components/NewIssueDialog.test.tsx ui/src/components/IssueRow.test.tsx ui/src/pages/IssueDetail.test.tsx` - `pnpm exec vitest run --project @paperclipai/adapter-utils packages/adapter-utils/src/server-utils.test.ts` - `PAPERCLIP_E2E_SKIP_LLM=true npx playwright test --config tests/e2e/playwright.config.ts tests/e2e/planning-mode-visual-verification.spec.ts` ## Screenshots Desktop planning detail: ![Desktop planning detail](https://raw.githubusercontent.com/paperclipai/paperclip/PAP-3368-plan-a-planning-mode-for-issues/doc/assets/pap-3368/desktop-planning-detail.png) Desktop planning row: ![Desktop planning row](https://raw.githubusercontent.com/paperclipai/paperclip/PAP-3368-plan-a-planning-mode-for-issues/doc/assets/pap-3368/desktop-planning-row.png) Desktop staged standard toggle: ![Desktop staged standard toggle](https://raw.githubusercontent.com/paperclipai/paperclip/PAP-3368-plan-a-planning-mode-for-issues/doc/assets/pap-3368/desktop-standard-toggle.png) Mobile planning detail: ![Mobile planning detail](https://raw.githubusercontent.com/paperclipai/paperclip/PAP-3368-plan-a-planning-mode-for-issues/doc/assets/pap-3368/mobile-planning-detail.png) Mobile planning row: ![Mobile planning row](https://raw.githubusercontent.com/paperclipai/paperclip/PAP-3368-plan-a-planning-mode-for-issues/doc/assets/pap-3368/mobile-planning-row.png) ## Risks - Medium migration risk: this adds a non-null issue column. The migration uses `ADD COLUMN IF NOT EXISTS` so installations that applied an older branch-local migration number can still apply the final numbered migration safely. - Medium contract risk: issue payloads, plugin payloads, and adapter heartbeat payloads now include work mode; compatibility is handled by defaulting missing values to `standard`. - UI risk is moderate because composer controls changed; focused component tests and visual e2e coverage exercise standard vs planning display and toggle behavior. > For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and discuss it in `#dev` before opening the PR. Feature PRs that overlap with planned core work may need to be redirected — check the roadmap first. See `CONTRIBUTING.md`. ## Model Used - OpenAI Codex, GPT-5 coding agent in a local Paperclip worktree, with shell/tool use. Exact context-window size is not exposed in this runtime. ## 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 run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-05-06 07:01:28 -05:00
readPaperclipIssueWorkModeFromContext,
Add ACPX local adapter runtime (#4893) ## Thinking Path > - Paperclip orchestrates AI-agent companies through a control plane that can start, supervise, and recover agent runs. > - Local adapters are the bridge between Paperclip issues and concrete agent runtimes such as Claude, Codex, and other ACP-compatible tools. > - The roadmap calls out broader “bring your own agent” and claw-style agent support, and ACPX gives Paperclip one path to normalize multiple ACP agents behind a single adapter. > - The branch needed to become one reviewable PR against current `paperclipai/paperclip:master`, without carrying stale base conflicts or generated lockfile churn. > - This pull request adds an experimental built-in `acpx_local` adapter, integrates it through the server/CLI/UI adapter surfaces, and adds regression coverage for runtime execution, skill sync, stream parsing, diagnostics, and log redaction. > - The benefit is that Paperclip can run Claude/Codex/custom ACP agents through ACPX while keeping operator configuration, skills, logging, and transcript rendering inside the existing adapter model. ## What Changed - Added `@paperclipai/adapter-acpx-local` with server execution, config schema, ACPX session handling, CLI formatting, UI config helpers, and stdout parsing. - Registered `acpx_local` across CLI, server, shared constants, UI adapter metadata, adapter capabilities, and agent creation/editing surfaces. - Added ACPX runtime execution support with persistent sessions, local-agent JWT environment handling, skill snapshots, runtime skill materialization, and isolation/security regressions. - Added ACPX adapter diagnostics and marked the adapter experimental in the UI. - Added command/env secret redaction for resolved command metadata in adapter-utils, server event storage, and the Agent Detail invocation UI. - Added Storybook coverage for ACPX config, transcript rendering, and skill states, plus PR screenshots under `docs/pr-screenshots/pap-2944/`. - Rebased the branch onto current `public-gh/master`; `pnpm-lock.yaml` is intentionally not included and there are no migration/schema changes. ## Verification - `pnpm exec vitest run packages/adapters/acpx-local/src/server/execute.test.ts packages/adapters/acpx-local/src/server/test.test.ts packages/adapters/acpx-local/src/cli/format-event.test.ts packages/adapters/acpx-local/src/ui/parse-stdout.test.ts packages/adapter-utils/src/server-utils.test.ts server/src/__tests__/redaction.test.ts server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/acpx-local-skill-sync.test.ts server/src/__tests__/acpx-local-adapter-environment.test.ts server/src/__tests__/adapter-routes.test.ts server/src/__tests__/agent-skills-routes.test.ts ui/src/adapters/metadata.test.ts` — 12 files, 87 tests passed. - `pnpm --filter @paperclipai/adapter-acpx-local typecheck` — passed. - `pnpm --filter @paperclipai/server typecheck` — passed. - `pnpm --filter @paperclipai/ui typecheck` — passed. - Confirmed PR diff does not include `pnpm-lock.yaml`, database schema files, or migrations. Screenshots: ![ACPX Claude skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-light.png?raw=true) ![ACPX Claude skills dark](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-dark.png?raw=true) ![ACPX custom skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-custom-light.png?raw=true) ## Risks - Medium risk: this introduces a new built-in adapter package and touches runtime execution, adapter registration, agent config, skills, and transcript rendering. - ACPX and ACP agent behavior can vary by installed tool versions; the adapter is marked experimental to set operator expectations. - `pnpm-lock.yaml` is excluded per repository PR policy, so dependency lock refresh must be handled by the repo’s automation or maintainers. - No database migration risk: no schema or migration files changed. > 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 coding agent based on GPT-5, with repository tool use, shell execution, git operations, and local verification. Exact hosted context window was not exposed in this environment. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-30 19:57:05 -05:00
renderPaperclipWakePrompt,
renderTemplate,
[codex] Add LLM Wiki plugin host support (#5597) ## Thinking Path > - Paperclip orchestrates AI agents for zero-human companies. > - The plugin system needs host contracts and runtime support before large plugins can integrate cleanly. > - The source branch mixed the LLM Wiki package with supporting host/runtime work, managed plugin skills, root-level storage spaces, and a bookmarks reference plugin. > - [PAP-9173](/PAP/issues/PAP-9173) asked for the current branch to be split by file boundary: plugin package separately from everything else. > - [PAP-9188](/PAP/issues/PAP-9188) clarified that LLM Wiki may have plugin-local spaces, but Paperclip core should not reorganize top-level local storage into spaces. > - Follow-up review clarified that the bookmarks example should not ship in this PR either. > - This pull request contains the non-`packages/plugins/plugin-llm-wiki/` host/runtime work, keeps runtime state under the selected Paperclip instance root, and no longer includes the bookmarks example. ## What Changed - Added/updated plugin host contracts, SDK types, worker RPC plumbing, managed plugin skill support, and related server tests. - Removed the bookmarks example plugin package and its bundled-example/workspace references. - Removed the root-level local spaces CLI/migration surface and restored instance-root runtime defaults for config, db, logs, storage, secrets, workspaces, projects, and adapter homes. - Replaced shared root `space-paths` helpers with `home-paths` helpers for core runtime storage. - Tightened stranded recovery unique-conflict detection so concurrent recovery scans reuse the raced recovery issue when Postgres errors are wrapped. - Kept `packages/plugins/plugin-llm-wiki/` out of this PR diff; plugin-local spaces remain in the stacked plugin-only PR. ## Verification - `pnpm exec vitest run cli/src/__tests__/data-dir.test.ts cli/src/__tests__/home-paths.test.ts cli/src/__tests__/onboard.test.ts packages/shared/src/home-paths.test.ts packages/db/src/runtime-config.test.ts server/src/__tests__/agent-instructions-service.test.ts server/src/__tests__/claude-local-execute.test.ts server/src/__tests__/codex-local-execute.test.ts` - `pnpm exec vitest run packages/db/src/runtime-config.test.ts` - `pnpm exec vitest run server/src/__tests__/plugin-routes-authz.test.ts` - `pnpm --filter @paperclipai/server typecheck` - `pnpm exec vitest run server/src/__tests__/heartbeat-process-recovery.test.ts -t "reuses the raced stranded recovery issue"` skipped locally because embedded Postgres did not initialize on this macOS temp host; the code path was typechecked and is covered by Linux CI. - Boundary check: no core references remain for `PAPERCLIP_SPACE_ID`, `spaces migrate-default`, `@paperclipai/shared/space-paths`, `registerSpacesCommands`, or the removed bookmarks example. - Previous PR head `4f23e034` had green GitHub checks: `verify`, all four serialized server shards, `e2e`, `Canary Dry Run`, `policy`, Snyk, and `Greptile Review`. Current head `582f466d` is re-running checks after the bookmarks deletion. ## Risks - Plugin host changes touch shared runtime paths, so regressions would most likely appear in adapter startup, plugin loading, or local dev path defaults. - Removing the bookmarks example also removes one demonstration of plugin database namespaces plus local-folder persistence; remaining plugin examples still cover bundled example discovery and plugin host flows. - The plugin package itself is intentionally deferred to the stacked plugin-only PR, where LLM Wiki plugin-local spaces live. - Existing installs that tested the transient root-level spaces CLI should stop using it; this PR intentionally removes that unsupported migration surface before merge. > For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and discuss it in `#dev` before opening the PR. Feature PRs that overlap with planned core work may need to be redirected — check the roadmap first. See `CONTRIBUTING.md`. ## Model Used - OpenAI GPT-5 Codex via Codex CLI, tool use and local code execution enabled; context window not exposed. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass, except where noted above for host-specific embedded Postgres initialization - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge Stacked follow-up: PR #5592 contains only `packages/plugins/plugin-llm-wiki/` and targets this branch. --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-05-10 07:34:12 -05:00
resolvePaperclipInstanceRootForAdapter,
Add ACPX local adapter runtime (#4893) ## Thinking Path > - Paperclip orchestrates AI-agent companies through a control plane that can start, supervise, and recover agent runs. > - Local adapters are the bridge between Paperclip issues and concrete agent runtimes such as Claude, Codex, and other ACP-compatible tools. > - The roadmap calls out broader “bring your own agent” and claw-style agent support, and ACPX gives Paperclip one path to normalize multiple ACP agents behind a single adapter. > - The branch needed to become one reviewable PR against current `paperclipai/paperclip:master`, without carrying stale base conflicts or generated lockfile churn. > - This pull request adds an experimental built-in `acpx_local` adapter, integrates it through the server/CLI/UI adapter surfaces, and adds regression coverage for runtime execution, skill sync, stream parsing, diagnostics, and log redaction. > - The benefit is that Paperclip can run Claude/Codex/custom ACP agents through ACPX while keeping operator configuration, skills, logging, and transcript rendering inside the existing adapter model. ## What Changed - Added `@paperclipai/adapter-acpx-local` with server execution, config schema, ACPX session handling, CLI formatting, UI config helpers, and stdout parsing. - Registered `acpx_local` across CLI, server, shared constants, UI adapter metadata, adapter capabilities, and agent creation/editing surfaces. - Added ACPX runtime execution support with persistent sessions, local-agent JWT environment handling, skill snapshots, runtime skill materialization, and isolation/security regressions. - Added ACPX adapter diagnostics and marked the adapter experimental in the UI. - Added command/env secret redaction for resolved command metadata in adapter-utils, server event storage, and the Agent Detail invocation UI. - Added Storybook coverage for ACPX config, transcript rendering, and skill states, plus PR screenshots under `docs/pr-screenshots/pap-2944/`. - Rebased the branch onto current `public-gh/master`; `pnpm-lock.yaml` is intentionally not included and there are no migration/schema changes. ## Verification - `pnpm exec vitest run packages/adapters/acpx-local/src/server/execute.test.ts packages/adapters/acpx-local/src/server/test.test.ts packages/adapters/acpx-local/src/cli/format-event.test.ts packages/adapters/acpx-local/src/ui/parse-stdout.test.ts packages/adapter-utils/src/server-utils.test.ts server/src/__tests__/redaction.test.ts server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/acpx-local-skill-sync.test.ts server/src/__tests__/acpx-local-adapter-environment.test.ts server/src/__tests__/adapter-routes.test.ts server/src/__tests__/agent-skills-routes.test.ts ui/src/adapters/metadata.test.ts` — 12 files, 87 tests passed. - `pnpm --filter @paperclipai/adapter-acpx-local typecheck` — passed. - `pnpm --filter @paperclipai/server typecheck` — passed. - `pnpm --filter @paperclipai/ui typecheck` — passed. - Confirmed PR diff does not include `pnpm-lock.yaml`, database schema files, or migrations. Screenshots: ![ACPX Claude skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-light.png?raw=true) ![ACPX Claude skills dark](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-dark.png?raw=true) ![ACPX custom skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-custom-light.png?raw=true) ## Risks - Medium risk: this introduces a new built-in adapter package and touches runtime execution, adapter registration, agent config, skills, and transcript rendering. - ACPX and ACP agent behavior can vary by installed tool versions; the adapter is marked experimental to set operator expectations. - `pnpm-lock.yaml` is excluded per repository PR policy, so dependency lock refresh must be handled by the repo’s automation or maintainers. - No database migration risk: no schema or migration files changed. > 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 coding agent based on GPT-5, with repository tool use, shell execution, git operations, and local verification. Exact hosted context window was not exposed in this environment. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-30 19:57:05 -05:00
resolvePaperclipDesiredSkillNames,
Harden remote workspace sync and restore flows (#5444) ## Thinking Path > - Paperclip orchestrates AI agents for zero-human companies > - When an agent runs against a remote target, Paperclip syncs the workspace out to the remote at run start and restores changes back to the local workspace at run end > - The previous restore flow naïvely overwrote local files with whatever the remote returned, so files that the remote run never touched but had timestamp/mode drift could be needlessly rewritten — and a single static `refs/paperclip/ssh-sync/imported` ref made concurrent SSH workspace exports race on the same git ref > - This pull request adds a `workspace-restore-merge` module that diffs a pre-run snapshot against the post-run remote state and only writes back files the remote actually changed; SSH workspace exports now use a per-import unique ref so concurrent runs can't trample each other > - Every adapter's execute path threads the snapshot through `prepareAdapterExecutionTargetRuntime` so the merge has the baseline it needs > - The benefit is workspace restores no longer churn untouched files, and concurrent SSH runs no longer collide on the import ref ## What Changed - `packages/adapter-utils/src/workspace-restore-merge.{ts,test.ts}`: new module — directory snapshot (kind/mode/sha256/symlink target) plus snapshot-aware merge that writes only the files the remote changed - `packages/adapter-utils/src/ssh.ts`: SSH workspace export uses a per-import unique ref (`refs/paperclip/ssh-sync/imported/<uuid>`); restore goes through the new merge helper; `ssh-fixture.test.ts` covers the unique-ref + merge paths - `packages/adapter-utils/src/sandbox-managed-runtime.ts` + `remote-managed-runtime.ts`: thread the snapshot/merge through the sandbox and SSH paths - `packages/adapter-utils/src/server-utils.{ts,test.ts}` + `execution-target.ts`: helpers for capturing the pre-run snapshot; `prepareAdapterExecutionTargetRuntime` gains required `runId` and optional `workspaceRemoteDir`, and returns the realized `workspaceRemoteDir` - Each adapter's `execute.ts` (acpx, claude, codex, cursor, gemini, opencode, pi) takes the snapshot at run start and passes it through to the runtime restore - Remote execute test mocks updated to match the new `prepareWorkspaceForSshExecution` return shape and the per-run `${managedRemoteWorkspace}` cwd subdirectory ## Verification - `pnpm vitest run --no-coverage --project @paperclipai/adapter-utils --project @paperclipai/adapter-acpx-local --project @paperclipai/adapter-claude-local --project @paperclipai/adapter-codex-local --project @paperclipai/adapter-cursor-local --project @paperclipai/adapter-gemini-local --project @paperclipai/adapter-opencode-local --project @paperclipai/adapter-pi-local` — 196/196 passing - `pnpm typecheck` clean across the workspace ## Risks Medium. The restore path now writes a strict subset of what it previously did — files the remote did not touch are no longer rewritten. If any flow was relying on a touch-without-content-change being copied back (timestamp or permission propagation only), that behavior is now skipped. Snapshot capture adds an O(N-files-in-workspace) hash pass at run start; the cost is bounded by the existing exclude list. The `runId` parameter on `prepareAdapterExecutionTargetRuntime` is now required — every in-tree caller is updated; out-of-tree adapter authors need to pass it. ## Model Used Claude Opus 4.7 (1M context) ## 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 run tests locally and they pass - [x] I have added or updated tests where applicable — new module + every adapter execute path covered - [x] If this change affects the UI, I have included before/after screenshots — N/A (no UI) - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge
2026-05-07 14:44:45 -07:00
rewriteWorkspaceCwdEnvVarsForExecution,
Fix remote workspace environment shaping (#5118) > **Stacked PR (part 5 of 7).** Depends on: - PR #5114 - PR #5115 - PR #5116 - PR #5117 > Diff against `master` includes commits from earlier PRs in the stack — the new commit in this PR is the topmost one. ## Thinking Path > - Paperclip orchestrates AI agents for zero-human companies > - Agents run with a Paperclip-shaped environment (`PAPERCLIP_WORKSPACE_CWD`, > worktree path, `PAPERCLIP_WORKSPACES_JSON` hints) so the CLI can locate the > correct project tree > - SSH testing reproduced a real failure: a Codex SSH run wrote to > `/tmp/paperclip-env-matrix-...` (the *host* path) instead of the realized > remote workspace at `/home/<user>/paperclip-env-matrix-ssh-claude/...` > because the adapter injected `PAPERCLIP_WORKSPACE_CWD=/tmp/...` into the > remote env > - Code review on the initial codex-only fix asked to roll the same approach > into every other SSH-capable adapter (claude, acpx, cursor, opencode, gemini, > pi) via a shared helper rather than duplicating per-adapter > - This PR adds `shapePaperclipWorkspaceEnvForExecution` in adapter-utils that, > when the execution target is remote: replaces local cwd with the realized > execution cwd, nulls out worktree path (which has no remote meaning), and > rewrites/strips `cwd` entries in workspace hints based on what was actually > synced. Every adapter calls it before invoking the remote runner > - The benefit is that remote runs see the realized remote workspace, host-local > paths stop leaking into remote env, and the rule is unit-tested in one place ## What Changed - Added `shapePaperclipWorkspaceEnvForExecution` to `packages/adapter-utils/src/server-utils.ts` with full unit coverage (`server-utils.test.ts`) - Each of acpx-local, claude-local, codex-local, cursor-local, gemini-local, opencode-local, pi-local now calls the new shaper before issuing the remote command and feeds the shaped values into `applyPaperclipWorkspaceEnv` - Per-adapter `execute.remote.test.ts` files extended to cover the new shaping behaviour: localhost paths replaced with remote cwd, foreign-cwd hints stripped, worktree path nulled out for remote targets - `acpx-local/src/server/execute.test.ts` extended with shaping coverage ## Verification - `pnpm test -- server-utils execute.remote` - `pnpm --filter @paperclipai/adapter-acpx-local test` - Manual QA reproducing the original failure: 1. Provision an E2B sandbox environment for the Paperclip QA company 2. Assign an issue to a remote-targeted claude-local agent and confirm the run starts in the correct remote cwd (no `/Users/...` path leakage in the run logs) 3. Repeat for opencode-local and pi-local ## Risks - Behavioural shift: hints whose `cwd` doesn't match the workspace cwd are now stripped on remote targets. If any adapter relied on a leaked local hint cwd, it will see a missing `cwd` instead. Reviewed all current callers — none do. - Adds a small per-run cost (path resolve + string normalisation) on every remote execution. Negligible. - Worktree path is now nulled out on remote (it has no meaning there). Adapters that previously read the value defensively will continue to work. ## Model Used - OpenAI GPT-5.4 (reasoning effort: high) via Codex CLI - Provider: OpenAI - Used to author the code changes in this PR ## 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 run tests locally and they pass - [x] I have added or updated tests where applicable - [ ] If this change affects the UI, I have included before/after screenshots — N/A - [ ] I have updated relevant documentation to reflect my changes — N/A - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge
2026-05-03 13:17:52 -07:00
shapePaperclipWorkspaceEnvForExecution,
Add ACPX local adapter runtime (#4893) ## Thinking Path > - Paperclip orchestrates AI-agent companies through a control plane that can start, supervise, and recover agent runs. > - Local adapters are the bridge between Paperclip issues and concrete agent runtimes such as Claude, Codex, and other ACP-compatible tools. > - The roadmap calls out broader “bring your own agent” and claw-style agent support, and ACPX gives Paperclip one path to normalize multiple ACP agents behind a single adapter. > - The branch needed to become one reviewable PR against current `paperclipai/paperclip:master`, without carrying stale base conflicts or generated lockfile churn. > - This pull request adds an experimental built-in `acpx_local` adapter, integrates it through the server/CLI/UI adapter surfaces, and adds regression coverage for runtime execution, skill sync, stream parsing, diagnostics, and log redaction. > - The benefit is that Paperclip can run Claude/Codex/custom ACP agents through ACPX while keeping operator configuration, skills, logging, and transcript rendering inside the existing adapter model. ## What Changed - Added `@paperclipai/adapter-acpx-local` with server execution, config schema, ACPX session handling, CLI formatting, UI config helpers, and stdout parsing. - Registered `acpx_local` across CLI, server, shared constants, UI adapter metadata, adapter capabilities, and agent creation/editing surfaces. - Added ACPX runtime execution support with persistent sessions, local-agent JWT environment handling, skill snapshots, runtime skill materialization, and isolation/security regressions. - Added ACPX adapter diagnostics and marked the adapter experimental in the UI. - Added command/env secret redaction for resolved command metadata in adapter-utils, server event storage, and the Agent Detail invocation UI. - Added Storybook coverage for ACPX config, transcript rendering, and skill states, plus PR screenshots under `docs/pr-screenshots/pap-2944/`. - Rebased the branch onto current `public-gh/master`; `pnpm-lock.yaml` is intentionally not included and there are no migration/schema changes. ## Verification - `pnpm exec vitest run packages/adapters/acpx-local/src/server/execute.test.ts packages/adapters/acpx-local/src/server/test.test.ts packages/adapters/acpx-local/src/cli/format-event.test.ts packages/adapters/acpx-local/src/ui/parse-stdout.test.ts packages/adapter-utils/src/server-utils.test.ts server/src/__tests__/redaction.test.ts server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/acpx-local-skill-sync.test.ts server/src/__tests__/acpx-local-adapter-environment.test.ts server/src/__tests__/adapter-routes.test.ts server/src/__tests__/agent-skills-routes.test.ts ui/src/adapters/metadata.test.ts` — 12 files, 87 tests passed. - `pnpm --filter @paperclipai/adapter-acpx-local typecheck` — passed. - `pnpm --filter @paperclipai/server typecheck` — passed. - `pnpm --filter @paperclipai/ui typecheck` — passed. - Confirmed PR diff does not include `pnpm-lock.yaml`, database schema files, or migrations. Screenshots: ![ACPX Claude skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-light.png?raw=true) ![ACPX Claude skills dark](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-dark.png?raw=true) ![ACPX custom skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-custom-light.png?raw=true) ## Risks - Medium risk: this introduces a new built-in adapter package and touches runtime execution, adapter registration, agent config, skills, and transcript rendering. - ACPX and ACP agent behavior can vary by installed tool versions; the adapter is marked experimental to set operator expectations. - `pnpm-lock.yaml` is excluded per repository PR policy, so dependency lock refresh must be handled by the repo’s automation or maintainers. - No database migration risk: no schema or migration files changed. > 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 coding agent based on GPT-5, with repository tool use, shell execution, git operations, and local verification. Exact hosted context window was not exposed in this environment. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-30 19:57:05 -05:00
stringifyPaperclipWakePayload,
type PaperclipSkillEntry,
} from "@paperclipai/adapter-utils/server-utils";
import { shellQuote } from "@paperclipai/adapter-utils/ssh";
import {
createAcpRuntime,
createAgentRegistry,
createRuntimeStore,
isAcpRuntimeError,
type AcpAgentRegistry,
type AcpRuntime,
type AcpRuntimeEvent,
type AcpRuntimeHandle,
type AcpRuntimeOptions,
type AcpRuntimeTurn,
type AcpRuntimeTurnResult,
} from "acpx/runtime";
import {
DEFAULT_ACPX_LOCAL_AGENT,
DEFAULT_ACPX_LOCAL_MODE,
DEFAULT_ACPX_LOCAL_NON_INTERACTIVE_PERMISSIONS,
DEFAULT_ACPX_LOCAL_PERMISSION_MODE,
DEFAULT_ACPX_LOCAL_TIMEOUT_SEC,
Improve ACPX adapter configuration (#5290) ## Thinking Path > - Paperclip orchestrates AI agents across several adapter implementations. > - ACPX is a local adapter path that can proxy Claude and Codex-style execution. > - Its configuration needed stronger schema defaults, provider-aware model handling, and better UI support. > - Plugin authors also need clear docs for managed resources. > - This pull request improves ACPX adapter configuration and documents plugin-managed resources. > - The benefit is a more predictable adapter setup path without changing unrelated control-plane behavior. ## What Changed - Improved ACPX config schema, execution config handling, UI build config, and route coverage. - Added ACPX model filtering support and tests. - Updated the agent config form and storybook coverage for ACPX model/provider behavior. - Expanded plugin authoring documentation for managed resources. ## Verification - `pnpm install --frozen-lockfile` - `pnpm exec vitest run server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/adapter-routes.test.ts ui/src/lib/acpx-model-filter.test.ts` ## Risks - Low-to-medium risk: adapter configuration behavior changes can affect ACPX users, but the change is isolated to ACPX/plugin-doc surfaces and covered by targeted adapter tests. ## Model Used - OpenAI GPT-5 Codex via Paperclip `codex_local` adapter, with shell/git/GitHub CLI tool use. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-05-06 06:06:47 -05:00
DEFAULT_ACPX_LOCAL_WARM_HANDLE_IDLE_MS,
Add ACPX local adapter runtime (#4893) ## Thinking Path > - Paperclip orchestrates AI-agent companies through a control plane that can start, supervise, and recover agent runs. > - Local adapters are the bridge between Paperclip issues and concrete agent runtimes such as Claude, Codex, and other ACP-compatible tools. > - The roadmap calls out broader “bring your own agent” and claw-style agent support, and ACPX gives Paperclip one path to normalize multiple ACP agents behind a single adapter. > - The branch needed to become one reviewable PR against current `paperclipai/paperclip:master`, without carrying stale base conflicts or generated lockfile churn. > - This pull request adds an experimental built-in `acpx_local` adapter, integrates it through the server/CLI/UI adapter surfaces, and adds regression coverage for runtime execution, skill sync, stream parsing, diagnostics, and log redaction. > - The benefit is that Paperclip can run Claude/Codex/custom ACP agents through ACPX while keeping operator configuration, skills, logging, and transcript rendering inside the existing adapter model. ## What Changed - Added `@paperclipai/adapter-acpx-local` with server execution, config schema, ACPX session handling, CLI formatting, UI config helpers, and stdout parsing. - Registered `acpx_local` across CLI, server, shared constants, UI adapter metadata, adapter capabilities, and agent creation/editing surfaces. - Added ACPX runtime execution support with persistent sessions, local-agent JWT environment handling, skill snapshots, runtime skill materialization, and isolation/security regressions. - Added ACPX adapter diagnostics and marked the adapter experimental in the UI. - Added command/env secret redaction for resolved command metadata in adapter-utils, server event storage, and the Agent Detail invocation UI. - Added Storybook coverage for ACPX config, transcript rendering, and skill states, plus PR screenshots under `docs/pr-screenshots/pap-2944/`. - Rebased the branch onto current `public-gh/master`; `pnpm-lock.yaml` is intentionally not included and there are no migration/schema changes. ## Verification - `pnpm exec vitest run packages/adapters/acpx-local/src/server/execute.test.ts packages/adapters/acpx-local/src/server/test.test.ts packages/adapters/acpx-local/src/cli/format-event.test.ts packages/adapters/acpx-local/src/ui/parse-stdout.test.ts packages/adapter-utils/src/server-utils.test.ts server/src/__tests__/redaction.test.ts server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/acpx-local-skill-sync.test.ts server/src/__tests__/acpx-local-adapter-environment.test.ts server/src/__tests__/adapter-routes.test.ts server/src/__tests__/agent-skills-routes.test.ts ui/src/adapters/metadata.test.ts` — 12 files, 87 tests passed. - `pnpm --filter @paperclipai/adapter-acpx-local typecheck` — passed. - `pnpm --filter @paperclipai/server typecheck` — passed. - `pnpm --filter @paperclipai/ui typecheck` — passed. - Confirmed PR diff does not include `pnpm-lock.yaml`, database schema files, or migrations. Screenshots: ![ACPX Claude skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-light.png?raw=true) ![ACPX Claude skills dark](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-dark.png?raw=true) ![ACPX custom skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-custom-light.png?raw=true) ## Risks - Medium risk: this introduces a new built-in adapter package and touches runtime execution, adapter registration, agent config, skills, and transcript rendering. - ACPX and ACP agent behavior can vary by installed tool versions; the adapter is marked experimental to set operator expectations. - `pnpm-lock.yaml` is excluded per repository PR policy, so dependency lock refresh must be handled by the repo’s automation or maintainers. - No database migration risk: no schema or migration files changed. > 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 coding agent based on GPT-5, with repository tool use, shell execution, git operations, and local verification. Exact hosted context window was not exposed in this environment. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-30 19:57:05 -05:00
} from "../index.js";
const __moduleDir = path.dirname(fileURLToPath(import.meta.url));
const WRAPPER_CLEANUP_RETENTION_MS = 15 * 60 * 1000;
const PAPERCLIP_MANAGED_CODEX_SKILLS_MANIFEST = ".paperclip-managed-skills.json";
type AcpxRuntimeFactory = (options: AcpRuntimeOptions) => AcpRuntime;
interface RuntimeCacheEntry {
runtime: AcpRuntime;
handle: AcpRuntimeHandle;
fingerprint: string;
lastUsedAt: number;
Improve ACPX adapter configuration (#5290) ## Thinking Path > - Paperclip orchestrates AI agents across several adapter implementations. > - ACPX is a local adapter path that can proxy Claude and Codex-style execution. > - Its configuration needed stronger schema defaults, provider-aware model handling, and better UI support. > - Plugin authors also need clear docs for managed resources. > - This pull request improves ACPX adapter configuration and documents plugin-managed resources. > - The benefit is a more predictable adapter setup path without changing unrelated control-plane behavior. ## What Changed - Improved ACPX config schema, execution config handling, UI build config, and route coverage. - Added ACPX model filtering support and tests. - Updated the agent config form and storybook coverage for ACPX model/provider behavior. - Expanded plugin authoring documentation for managed resources. ## Verification - `pnpm install --frozen-lockfile` - `pnpm exec vitest run server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/adapter-routes.test.ts ui/src/lib/acpx-model-filter.test.ts` ## Risks - Low-to-medium risk: adapter configuration behavior changes can affect ACPX users, but the change is isolated to ACPX/plugin-doc surfaces and covered by targeted adapter tests. ## Model Used - OpenAI GPT-5 Codex via Paperclip `codex_local` adapter, with shell/git/GitHub CLI tool use. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-05-06 06:06:47 -05:00
cleanupTimer?: NodeJS.Timeout;
Add ACPX local adapter runtime (#4893) ## Thinking Path > - Paperclip orchestrates AI-agent companies through a control plane that can start, supervise, and recover agent runs. > - Local adapters are the bridge between Paperclip issues and concrete agent runtimes such as Claude, Codex, and other ACP-compatible tools. > - The roadmap calls out broader “bring your own agent” and claw-style agent support, and ACPX gives Paperclip one path to normalize multiple ACP agents behind a single adapter. > - The branch needed to become one reviewable PR against current `paperclipai/paperclip:master`, without carrying stale base conflicts or generated lockfile churn. > - This pull request adds an experimental built-in `acpx_local` adapter, integrates it through the server/CLI/UI adapter surfaces, and adds regression coverage for runtime execution, skill sync, stream parsing, diagnostics, and log redaction. > - The benefit is that Paperclip can run Claude/Codex/custom ACP agents through ACPX while keeping operator configuration, skills, logging, and transcript rendering inside the existing adapter model. ## What Changed - Added `@paperclipai/adapter-acpx-local` with server execution, config schema, ACPX session handling, CLI formatting, UI config helpers, and stdout parsing. - Registered `acpx_local` across CLI, server, shared constants, UI adapter metadata, adapter capabilities, and agent creation/editing surfaces. - Added ACPX runtime execution support with persistent sessions, local-agent JWT environment handling, skill snapshots, runtime skill materialization, and isolation/security regressions. - Added ACPX adapter diagnostics and marked the adapter experimental in the UI. - Added command/env secret redaction for resolved command metadata in adapter-utils, server event storage, and the Agent Detail invocation UI. - Added Storybook coverage for ACPX config, transcript rendering, and skill states, plus PR screenshots under `docs/pr-screenshots/pap-2944/`. - Rebased the branch onto current `public-gh/master`; `pnpm-lock.yaml` is intentionally not included and there are no migration/schema changes. ## Verification - `pnpm exec vitest run packages/adapters/acpx-local/src/server/execute.test.ts packages/adapters/acpx-local/src/server/test.test.ts packages/adapters/acpx-local/src/cli/format-event.test.ts packages/adapters/acpx-local/src/ui/parse-stdout.test.ts packages/adapter-utils/src/server-utils.test.ts server/src/__tests__/redaction.test.ts server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/acpx-local-skill-sync.test.ts server/src/__tests__/acpx-local-adapter-environment.test.ts server/src/__tests__/adapter-routes.test.ts server/src/__tests__/agent-skills-routes.test.ts ui/src/adapters/metadata.test.ts` — 12 files, 87 tests passed. - `pnpm --filter @paperclipai/adapter-acpx-local typecheck` — passed. - `pnpm --filter @paperclipai/server typecheck` — passed. - `pnpm --filter @paperclipai/ui typecheck` — passed. - Confirmed PR diff does not include `pnpm-lock.yaml`, database schema files, or migrations. Screenshots: ![ACPX Claude skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-light.png?raw=true) ![ACPX Claude skills dark](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-dark.png?raw=true) ![ACPX custom skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-custom-light.png?raw=true) ## Risks - Medium risk: this introduces a new built-in adapter package and touches runtime execution, adapter registration, agent config, skills, and transcript rendering. - ACPX and ACP agent behavior can vary by installed tool versions; the adapter is marked experimental to set operator expectations. - `pnpm-lock.yaml` is excluded per repository PR policy, so dependency lock refresh must be handled by the repo’s automation or maintainers. - No database migration risk: no schema or migration files changed. > 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 coding agent based on GPT-5, with repository tool use, shell execution, git operations, and local verification. Exact hosted context window was not exposed in this environment. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-30 19:57:05 -05:00
}
interface ExecuteDeps {
createRuntime?: AcpxRuntimeFactory;
now?: () => number;
warmHandles?: Map<string, RuntimeCacheEntry>;
}
interface AcpxPreparedRuntime {
acpxAgent: string;
mode: "persistent" | "oneshot";
cwd: string;
workspaceId: string;
workspaceRepoUrl: string;
workspaceRepoRef: string;
env: Record<string, string>;
loggedEnv: Record<string, string>;
stateDir: string;
permissionMode: "approve-all" | "approve-reads" | "deny-all";
nonInteractivePermissions: "deny" | "fail";
Improve ACPX adapter configuration (#5290) ## Thinking Path > - Paperclip orchestrates AI agents across several adapter implementations. > - ACPX is a local adapter path that can proxy Claude and Codex-style execution. > - Its configuration needed stronger schema defaults, provider-aware model handling, and better UI support. > - Plugin authors also need clear docs for managed resources. > - This pull request improves ACPX adapter configuration and documents plugin-managed resources. > - The benefit is a more predictable adapter setup path without changing unrelated control-plane behavior. ## What Changed - Improved ACPX config schema, execution config handling, UI build config, and route coverage. - Added ACPX model filtering support and tests. - Updated the agent config form and storybook coverage for ACPX model/provider behavior. - Expanded plugin authoring documentation for managed resources. ## Verification - `pnpm install --frozen-lockfile` - `pnpm exec vitest run server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/adapter-routes.test.ts ui/src/lib/acpx-model-filter.test.ts` ## Risks - Low-to-medium risk: adapter configuration behavior changes can affect ACPX users, but the change is isolated to ACPX/plugin-doc surfaces and covered by targeted adapter tests. ## Model Used - OpenAI GPT-5 Codex via Paperclip `codex_local` adapter, with shell/git/GitHub CLI tool use. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-05-06 06:06:47 -05:00
requestedModel: string;
requestedThinkingEffort: string;
fastMode: boolean;
Add ACPX local adapter runtime (#4893) ## Thinking Path > - Paperclip orchestrates AI-agent companies through a control plane that can start, supervise, and recover agent runs. > - Local adapters are the bridge between Paperclip issues and concrete agent runtimes such as Claude, Codex, and other ACP-compatible tools. > - The roadmap calls out broader “bring your own agent” and claw-style agent support, and ACPX gives Paperclip one path to normalize multiple ACP agents behind a single adapter. > - The branch needed to become one reviewable PR against current `paperclipai/paperclip:master`, without carrying stale base conflicts or generated lockfile churn. > - This pull request adds an experimental built-in `acpx_local` adapter, integrates it through the server/CLI/UI adapter surfaces, and adds regression coverage for runtime execution, skill sync, stream parsing, diagnostics, and log redaction. > - The benefit is that Paperclip can run Claude/Codex/custom ACP agents through ACPX while keeping operator configuration, skills, logging, and transcript rendering inside the existing adapter model. ## What Changed - Added `@paperclipai/adapter-acpx-local` with server execution, config schema, ACPX session handling, CLI formatting, UI config helpers, and stdout parsing. - Registered `acpx_local` across CLI, server, shared constants, UI adapter metadata, adapter capabilities, and agent creation/editing surfaces. - Added ACPX runtime execution support with persistent sessions, local-agent JWT environment handling, skill snapshots, runtime skill materialization, and isolation/security regressions. - Added ACPX adapter diagnostics and marked the adapter experimental in the UI. - Added command/env secret redaction for resolved command metadata in adapter-utils, server event storage, and the Agent Detail invocation UI. - Added Storybook coverage for ACPX config, transcript rendering, and skill states, plus PR screenshots under `docs/pr-screenshots/pap-2944/`. - Rebased the branch onto current `public-gh/master`; `pnpm-lock.yaml` is intentionally not included and there are no migration/schema changes. ## Verification - `pnpm exec vitest run packages/adapters/acpx-local/src/server/execute.test.ts packages/adapters/acpx-local/src/server/test.test.ts packages/adapters/acpx-local/src/cli/format-event.test.ts packages/adapters/acpx-local/src/ui/parse-stdout.test.ts packages/adapter-utils/src/server-utils.test.ts server/src/__tests__/redaction.test.ts server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/acpx-local-skill-sync.test.ts server/src/__tests__/acpx-local-adapter-environment.test.ts server/src/__tests__/adapter-routes.test.ts server/src/__tests__/agent-skills-routes.test.ts ui/src/adapters/metadata.test.ts` — 12 files, 87 tests passed. - `pnpm --filter @paperclipai/adapter-acpx-local typecheck` — passed. - `pnpm --filter @paperclipai/server typecheck` — passed. - `pnpm --filter @paperclipai/ui typecheck` — passed. - Confirmed PR diff does not include `pnpm-lock.yaml`, database schema files, or migrations. Screenshots: ![ACPX Claude skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-light.png?raw=true) ![ACPX Claude skills dark](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-dark.png?raw=true) ![ACPX custom skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-custom-light.png?raw=true) ## Risks - Medium risk: this introduces a new built-in adapter package and touches runtime execution, adapter registration, agent config, skills, and transcript rendering. - ACPX and ACP agent behavior can vary by installed tool versions; the adapter is marked experimental to set operator expectations. - `pnpm-lock.yaml` is excluded per repository PR policy, so dependency lock refresh must be handled by the repo’s automation or maintainers. - No database migration risk: no schema or migration files changed. > 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 coding agent based on GPT-5, with repository tool use, shell execution, git operations, and local verification. Exact hosted context window was not exposed in this environment. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-30 19:57:05 -05:00
timeoutSec: number;
sessionKey: string;
fingerprint: string;
agentCommand: string | null;
agentRegistry: AcpAgentRegistry;
remoteExecutionIdentity: Record<string, unknown> | null;
skillPromptInstructions: string;
skillsIdentity: Record<string, unknown>;
Make ACPX-Claude adapter work seamlessly (PAPA-388) (#6590) ## Thinking Path > - Paperclip orchestrates AI agents for zero-human companies, so when an adapter fails, the platform must surface enough detail for the next agent (or human reviewer) to act > - The `acpx_local` adapter wraps `claude-agent-acp`, which in turn drives the Claude Code SDK — three layers, three different permission and error-handling models > - A user created a `Claude Local ACPX` agent in PAPA-387 and it failed instantly with the generic `acpx.error / "Internal error"` log, stranding the work and triggering an opaque `stranded_assigned_issue` recovery to the CTO > - Once the diagnostic blackbox was opened, the underlying cause turned out to be two SDK-level mismatches: a model-name allowlist that rejects bare IDs like `claude-opus-4-7`, and a Claude Code permission/Read-sandbox configuration that silently denies every non-allowlisted tool when the user's `~/.claude/settings.json` has `defaultMode: "dontAsk"` > - This pull request fixes both classes of failure in the adapter itself so new ACPX agents work seamlessly without per-host configuration, and widens the diagnostic surface so the *next* failure of any kind is actionable > - The benefit is that ACPX-Claude can join the regular agent roster — verified end to end on PAPA-401, where the agent successfully reached the Paperclip API, opened a worktree, surveyed existing notification PRs, and posted a structured plan ## What Changed - Widen ACPX failure diagnostics (`packages/adapters/acpx-local/src/server/execute.ts`): - Capture `err.name`, ACP code, `cause.message`, retryable flag, and a 5-frame stack preview into `errorMeta`. - Promote phase-specific error codes: `ensure_session → acpx_session_init_failed`, `configure_session → acpx_session_config_failed`, `turn → acpx_turn_failed`, plus mapping for `ACP_BACKEND_MISSING` / `ACP_BACKEND_UNAVAILABLE`. - Set `verbose: true` on the ACPX runtime so its session-event log flows through `ctx.onLog`. - Capture child-process stderr via a wrapper-script tee into `<stateDir>/run-stderr/<runId>.log`, inline the tail into the `acpx.error` payload as `childStderrTail`, and forward it through `ctx.onLog("stderr", …)` so it lands in the heartbeat `stderrExcerpt` column (existing redaction applies). - Set the model via `ANTHROPIC_MODEL` env for the `claude` agent instead of `set_config_option(model, …)`. The ACP server's `set_config_option` handler validates against an internal allowlist and rejects bare IDs like `claude-opus-4-7`. `ANTHROPIC_MODEL` is read during initialization and bypasses that check. - Seed `<worktree>/.claude/settings.local.json` before spawning `claude-agent-acp` (the seamless-API fix). Since `claude-agent-acp` hard-codes `settingSources: ["user", "project", "local"]` and "local" has the highest precedence: - Set `permissions.defaultMode: "default"`, but **only** if the user's value is missing or `"dontAsk"` (the broken case). Other modes like `acceptEdits`/`plan` are preserved. - Pre-allow Paperclip's Bash surface (`Bash(curl:*)`, `Bash(env:*)`, `Bash(<cwd>/scripts/paperclip-issue-update.sh:*)`, `Bash(<cwd>/scripts/paperclip:*)`). - Widen `permissions.additionalDirectories` to include `stateDir`, `agentHome`, and the per-company instance root (`~/.paperclip/instances/<id>/companies/<companyId>`). Scoped to this company only — does not expose other tenants. - Existing user entries are merged, not replaced. The resolved roots are folded into the session fingerprint so warm-session handles invalidate when they change. - Sync the existing server-side integration test (`server/src/__tests__/acpx-local-execute.test.ts`) to assert `acpx_session_init_failed` instead of the now-removed `acpx_protocol_error` for `ACP_SESSION_INIT_FAILED` (a follow-up to commit 1). ## Verification - `pnpm --filter "@paperclipai/adapter-acpx-local" run typecheck` — passes. - `pnpm vitest run` in `packages/adapters/acpx-local` — 35/35 pass, includes 4 new tests covering the settings.local.json write path (claude only, merge with pre-existing content, `dontAsk` override, codex no-op). - `pnpm vitest run src/__tests__/acpx-local-execute.test.ts` in `server/` — 15/15 pass after the test-sync commit. - End-to-end manual verification (PAPA-401): the `Claude Local ACPX` agent that previously hit "restricted environment" now successfully reaches the Paperclip API, opens its worktree, posts structured plan comments, and flips the issue to `in_review` without any external configuration. ## Risks - **Low**, scoped to the `acpx_local` adapter. The settings.local.json write is per-worktree (worktrees live under `.paperclip/worktrees/<issue>/`) and only triggers when `acpxAgent === "claude"`. Existing user content is merged with `[...existing, ...paperclip]` and deduped — nothing is overwritten outright. - The `defaultMode` override is intentionally narrow: it only flips `"dontAsk"` (which silently denies every tool and is the root cause) to `"default"`. Users who explicitly picked `acceptEdits`, `plan`, or any other mode keep their choice. - Stderr capture goes through the existing `log-redaction` pass before persisting, so `PAPERCLIP_API_KEY` and similar secrets in the wrapper env don't leak into heartbeat logs. > 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 4.7 (`claude-opus-4-7`), running in the `claude_local` adapter via Paperclip's harness. Extended thinking enabled, tool use enabled. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [ ] If this change affects the UI, I have included before/after screenshots — N/A (adapter-only) - [ ] I have updated relevant documentation to reflect my changes — no user-facing docs changed; internal commentary in the code change explains the SDK constraints - [x] I have considered and documented any risks above - [ ] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-05-23 13:01:27 -07:00
childStderrLogPath: string | null;
paperclipClaudeSettings: PaperclipClaudeSettingsResult | null;
Add ACPX local adapter runtime (#4893) ## Thinking Path > - Paperclip orchestrates AI-agent companies through a control plane that can start, supervise, and recover agent runs. > - Local adapters are the bridge between Paperclip issues and concrete agent runtimes such as Claude, Codex, and other ACP-compatible tools. > - The roadmap calls out broader “bring your own agent” and claw-style agent support, and ACPX gives Paperclip one path to normalize multiple ACP agents behind a single adapter. > - The branch needed to become one reviewable PR against current `paperclipai/paperclip:master`, without carrying stale base conflicts or generated lockfile churn. > - This pull request adds an experimental built-in `acpx_local` adapter, integrates it through the server/CLI/UI adapter surfaces, and adds regression coverage for runtime execution, skill sync, stream parsing, diagnostics, and log redaction. > - The benefit is that Paperclip can run Claude/Codex/custom ACP agents through ACPX while keeping operator configuration, skills, logging, and transcript rendering inside the existing adapter model. ## What Changed - Added `@paperclipai/adapter-acpx-local` with server execution, config schema, ACPX session handling, CLI formatting, UI config helpers, and stdout parsing. - Registered `acpx_local` across CLI, server, shared constants, UI adapter metadata, adapter capabilities, and agent creation/editing surfaces. - Added ACPX runtime execution support with persistent sessions, local-agent JWT environment handling, skill snapshots, runtime skill materialization, and isolation/security regressions. - Added ACPX adapter diagnostics and marked the adapter experimental in the UI. - Added command/env secret redaction for resolved command metadata in adapter-utils, server event storage, and the Agent Detail invocation UI. - Added Storybook coverage for ACPX config, transcript rendering, and skill states, plus PR screenshots under `docs/pr-screenshots/pap-2944/`. - Rebased the branch onto current `public-gh/master`; `pnpm-lock.yaml` is intentionally not included and there are no migration/schema changes. ## Verification - `pnpm exec vitest run packages/adapters/acpx-local/src/server/execute.test.ts packages/adapters/acpx-local/src/server/test.test.ts packages/adapters/acpx-local/src/cli/format-event.test.ts packages/adapters/acpx-local/src/ui/parse-stdout.test.ts packages/adapter-utils/src/server-utils.test.ts server/src/__tests__/redaction.test.ts server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/acpx-local-skill-sync.test.ts server/src/__tests__/acpx-local-adapter-environment.test.ts server/src/__tests__/adapter-routes.test.ts server/src/__tests__/agent-skills-routes.test.ts ui/src/adapters/metadata.test.ts` — 12 files, 87 tests passed. - `pnpm --filter @paperclipai/adapter-acpx-local typecheck` — passed. - `pnpm --filter @paperclipai/server typecheck` — passed. - `pnpm --filter @paperclipai/ui typecheck` — passed. - Confirmed PR diff does not include `pnpm-lock.yaml`, database schema files, or migrations. Screenshots: ![ACPX Claude skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-light.png?raw=true) ![ACPX Claude skills dark](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-dark.png?raw=true) ![ACPX custom skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-custom-light.png?raw=true) ## Risks - Medium risk: this introduces a new built-in adapter package and touches runtime execution, adapter registration, agent config, skills, and transcript rendering. - ACPX and ACP agent behavior can vary by installed tool versions; the adapter is marked experimental to set operator expectations. - `pnpm-lock.yaml` is excluded per repository PR policy, so dependency lock refresh must be handled by the repo’s automation or maintainers. - No database migration risk: no schema or migration files changed. > 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 coding agent based on GPT-5, with repository tool use, shell execution, git operations, and local verification. Exact hosted context window was not exposed in this environment. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-30 19:57:05 -05:00
}
const defaultWarmHandles = new Map<string, RuntimeCacheEntry>();
function stableJson(value: unknown): string {
if (Array.isArray(value)) return `[${value.map(stableJson).join(",")}]`;
if (value && typeof value === "object") {
return `{${Object.entries(value as Record<string, unknown>)
.sort(([a], [b]) => a.localeCompare(b))
.map(([key, entry]) => `${JSON.stringify(key)}:${stableJson(entry)}`)
.join(",")}}`;
}
return JSON.stringify(value);
}
function shortHash(value: unknown): string {
return createHash("sha256").update(stableJson(value)).digest("hex").slice(0, 16);
}
function defaultPaperclipInstanceDir(): string {
const home = process.env.PAPERCLIP_HOME?.trim() || path.join(os.homedir(), ".paperclip");
const instanceId = process.env.PAPERCLIP_INSTANCE_ID?.trim() || "default";
[codex] Add LLM Wiki plugin host support (#5597) ## Thinking Path > - Paperclip orchestrates AI agents for zero-human companies. > - The plugin system needs host contracts and runtime support before large plugins can integrate cleanly. > - The source branch mixed the LLM Wiki package with supporting host/runtime work, managed plugin skills, root-level storage spaces, and a bookmarks reference plugin. > - [PAP-9173](/PAP/issues/PAP-9173) asked for the current branch to be split by file boundary: plugin package separately from everything else. > - [PAP-9188](/PAP/issues/PAP-9188) clarified that LLM Wiki may have plugin-local spaces, but Paperclip core should not reorganize top-level local storage into spaces. > - Follow-up review clarified that the bookmarks example should not ship in this PR either. > - This pull request contains the non-`packages/plugins/plugin-llm-wiki/` host/runtime work, keeps runtime state under the selected Paperclip instance root, and no longer includes the bookmarks example. ## What Changed - Added/updated plugin host contracts, SDK types, worker RPC plumbing, managed plugin skill support, and related server tests. - Removed the bookmarks example plugin package and its bundled-example/workspace references. - Removed the root-level local spaces CLI/migration surface and restored instance-root runtime defaults for config, db, logs, storage, secrets, workspaces, projects, and adapter homes. - Replaced shared root `space-paths` helpers with `home-paths` helpers for core runtime storage. - Tightened stranded recovery unique-conflict detection so concurrent recovery scans reuse the raced recovery issue when Postgres errors are wrapped. - Kept `packages/plugins/plugin-llm-wiki/` out of this PR diff; plugin-local spaces remain in the stacked plugin-only PR. ## Verification - `pnpm exec vitest run cli/src/__tests__/data-dir.test.ts cli/src/__tests__/home-paths.test.ts cli/src/__tests__/onboard.test.ts packages/shared/src/home-paths.test.ts packages/db/src/runtime-config.test.ts server/src/__tests__/agent-instructions-service.test.ts server/src/__tests__/claude-local-execute.test.ts server/src/__tests__/codex-local-execute.test.ts` - `pnpm exec vitest run packages/db/src/runtime-config.test.ts` - `pnpm exec vitest run server/src/__tests__/plugin-routes-authz.test.ts` - `pnpm --filter @paperclipai/server typecheck` - `pnpm exec vitest run server/src/__tests__/heartbeat-process-recovery.test.ts -t "reuses the raced stranded recovery issue"` skipped locally because embedded Postgres did not initialize on this macOS temp host; the code path was typechecked and is covered by Linux CI. - Boundary check: no core references remain for `PAPERCLIP_SPACE_ID`, `spaces migrate-default`, `@paperclipai/shared/space-paths`, `registerSpacesCommands`, or the removed bookmarks example. - Previous PR head `4f23e034` had green GitHub checks: `verify`, all four serialized server shards, `e2e`, `Canary Dry Run`, `policy`, Snyk, and `Greptile Review`. Current head `582f466d` is re-running checks after the bookmarks deletion. ## Risks - Plugin host changes touch shared runtime paths, so regressions would most likely appear in adapter startup, plugin loading, or local dev path defaults. - Removing the bookmarks example also removes one demonstration of plugin database namespaces plus local-folder persistence; remaining plugin examples still cover bundled example discovery and plugin host flows. - The plugin package itself is intentionally deferred to the stacked plugin-only PR, where LLM Wiki plugin-local spaces live. - Existing installs that tested the transient root-level spaces CLI should stop using it; this PR intentionally removes that unsupported migration surface before merge. > For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and discuss it in `#dev` before opening the PR. Feature PRs that overlap with planned core work may need to be redirected — check the roadmap first. See `CONTRIBUTING.md`. ## Model Used - OpenAI GPT-5 Codex via Codex CLI, tool use and local code execution enabled; context window not exposed. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass, except where noted above for host-specific embedded Postgres initialization - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge Stacked follow-up: PR #5592 contains only `packages/plugins/plugin-llm-wiki/` and targets this branch. --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-05-10 07:34:12 -05:00
return resolvePaperclipInstanceRootForAdapter({
homeDir: home,
instanceId,
});
Add ACPX local adapter runtime (#4893) ## Thinking Path > - Paperclip orchestrates AI-agent companies through a control plane that can start, supervise, and recover agent runs. > - Local adapters are the bridge between Paperclip issues and concrete agent runtimes such as Claude, Codex, and other ACP-compatible tools. > - The roadmap calls out broader “bring your own agent” and claw-style agent support, and ACPX gives Paperclip one path to normalize multiple ACP agents behind a single adapter. > - The branch needed to become one reviewable PR against current `paperclipai/paperclip:master`, without carrying stale base conflicts or generated lockfile churn. > - This pull request adds an experimental built-in `acpx_local` adapter, integrates it through the server/CLI/UI adapter surfaces, and adds regression coverage for runtime execution, skill sync, stream parsing, diagnostics, and log redaction. > - The benefit is that Paperclip can run Claude/Codex/custom ACP agents through ACPX while keeping operator configuration, skills, logging, and transcript rendering inside the existing adapter model. ## What Changed - Added `@paperclipai/adapter-acpx-local` with server execution, config schema, ACPX session handling, CLI formatting, UI config helpers, and stdout parsing. - Registered `acpx_local` across CLI, server, shared constants, UI adapter metadata, adapter capabilities, and agent creation/editing surfaces. - Added ACPX runtime execution support with persistent sessions, local-agent JWT environment handling, skill snapshots, runtime skill materialization, and isolation/security regressions. - Added ACPX adapter diagnostics and marked the adapter experimental in the UI. - Added command/env secret redaction for resolved command metadata in adapter-utils, server event storage, and the Agent Detail invocation UI. - Added Storybook coverage for ACPX config, transcript rendering, and skill states, plus PR screenshots under `docs/pr-screenshots/pap-2944/`. - Rebased the branch onto current `public-gh/master`; `pnpm-lock.yaml` is intentionally not included and there are no migration/schema changes. ## Verification - `pnpm exec vitest run packages/adapters/acpx-local/src/server/execute.test.ts packages/adapters/acpx-local/src/server/test.test.ts packages/adapters/acpx-local/src/cli/format-event.test.ts packages/adapters/acpx-local/src/ui/parse-stdout.test.ts packages/adapter-utils/src/server-utils.test.ts server/src/__tests__/redaction.test.ts server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/acpx-local-skill-sync.test.ts server/src/__tests__/acpx-local-adapter-environment.test.ts server/src/__tests__/adapter-routes.test.ts server/src/__tests__/agent-skills-routes.test.ts ui/src/adapters/metadata.test.ts` — 12 files, 87 tests passed. - `pnpm --filter @paperclipai/adapter-acpx-local typecheck` — passed. - `pnpm --filter @paperclipai/server typecheck` — passed. - `pnpm --filter @paperclipai/ui typecheck` — passed. - Confirmed PR diff does not include `pnpm-lock.yaml`, database schema files, or migrations. Screenshots: ![ACPX Claude skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-light.png?raw=true) ![ACPX Claude skills dark](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-dark.png?raw=true) ![ACPX custom skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-custom-light.png?raw=true) ## Risks - Medium risk: this introduces a new built-in adapter package and touches runtime execution, adapter registration, agent config, skills, and transcript rendering. - ACPX and ACP agent behavior can vary by installed tool versions; the adapter is marked experimental to set operator expectations. - `pnpm-lock.yaml` is excluded per repository PR policy, so dependency lock refresh must be handled by the repo’s automation or maintainers. - No database migration risk: no schema or migration files changed. > 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 coding agent based on GPT-5, with repository tool use, shell execution, git operations, and local verification. Exact hosted context window was not exposed in this environment. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-30 19:57:05 -05:00
}
function defaultStateDir(companyId: string, agentId: string): string {
return path.join(defaultPaperclipInstanceDir(), "companies", companyId, "acpx-local", "agents", agentId);
}
function resolveManagedCodexHomeDir(companyId: string): string {
return path.join(defaultPaperclipInstanceDir(), "companies", companyId, "codex-home");
}
function packageRootDir(): string {
return path.resolve(__moduleDir, "../..");
}
function resolveBuiltInAgentCommand(agent: string): string | null {
const binName =
agent === "claude"
? "claude-agent-acp"
: agent === "codex"
? "codex-acp"
: null;
if (!binName) return null;
return path.join(packageRootDir(), "node_modules", ".bin", binName);
}
function normalizeAgent(config: Record<string, unknown>): string {
const agent = asString(config.agent, DEFAULT_ACPX_LOCAL_AGENT).trim();
return agent || DEFAULT_ACPX_LOCAL_AGENT;
}
async function pathExists(candidate: string): Promise<boolean> {
return fs.access(candidate).then(() => true).catch(() => false);
}
async function ensureParentDir(target: string): Promise<void> {
await fs.mkdir(path.dirname(target), { recursive: true });
}
async function writeFileAtomically(input: {
target: string;
contents: string;
mode: number;
}): Promise<void> {
await ensureParentDir(input.target);
const tempPath = `${input.target}.tmp-${process.pid}-${randomUUID()}`;
const handle = await fs.open(tempPath, "wx", input.mode);
try {
await handle.writeFile(input.contents, "utf8");
await handle.close();
await fs.rename(tempPath, input.target);
await fs.chmod(input.target, input.mode).catch(() => {});
} catch (err) {
await handle.close().catch(() => {});
await fs.rm(tempPath, { force: true }).catch(() => {});
throw err;
}
}
async function ensureSymlink(target: string, source: string): Promise<void> {
const resolvedSource = path.resolve(source);
const existing = await fs.lstat(target).catch(() => null);
if (!existing) {
await ensureParentDir(target);
await fs.symlink(resolvedSource, target);
return;
}
if (!existing.isSymbolicLink()) {
await fs.rm(target, { recursive: true, force: true });
await fs.symlink(resolvedSource, target);
return;
}
const linkedPath = await fs.readlink(target).catch(() => null);
if (!linkedPath) return;
const resolvedLinkedPath = path.resolve(path.dirname(target), linkedPath);
if (resolvedLinkedPath === resolvedSource) return;
await fs.unlink(target);
await fs.symlink(resolvedSource, target);
}
async function ensureCopiedFile(target: string, source: string): Promise<void> {
if (await pathExists(target)) return;
await ensureParentDir(target);
await fs.copyFile(source, target);
}
async function prepareManagedCodexHome(input: {
companyId: string;
sourceHome: string;
targetHome: string;
onLog: AdapterExecutionContext["onLog"];
}): Promise<string> {
const { sourceHome, targetHome, onLog } = input;
if (path.resolve(sourceHome) === path.resolve(targetHome)) return targetHome;
await fs.mkdir(targetHome, { recursive: true });
const authJson = path.join(sourceHome, "auth.json");
if (await pathExists(authJson)) await ensureSymlink(path.join(targetHome, "auth.json"), authJson);
for (const name of ["config.json", "config.toml", "instructions.md"]) {
const source = path.join(sourceHome, name);
if (await pathExists(source)) await ensureCopiedFile(path.join(targetHome, name), source);
}
await onLog(
"stdout",
`[paperclip] Using Paperclip-managed ACPX Codex home "${targetHome}" (seeded from "${sourceHome}").\n`,
);
return targetHome;
}
async function hashPathContents(
candidate: string,
hash: ReturnType<typeof createHash>,
relativePath: string,
seenDirectories: Set<string>,
): Promise<void> {
const stat = await fs.lstat(candidate);
if (stat.isSymbolicLink()) {
hash.update(`symlink-skipped:${relativePath}\n`);
return;
}
if (stat.isDirectory()) {
const realDir = await fs.realpath(candidate).catch(() => candidate);
hash.update(`dir:${relativePath}\n`);
if (seenDirectories.has(realDir)) {
hash.update("loop\n");
return;
}
seenDirectories.add(realDir);
const entries = await fs.readdir(candidate, { withFileTypes: true });
entries.sort((left, right) => left.name.localeCompare(right.name));
for (const entry of entries) {
const childRelativePath = relativePath.length > 0 ? `${relativePath}/${entry.name}` : entry.name;
await hashPathContents(path.join(candidate, entry.name), hash, childRelativePath, seenDirectories);
}
return;
}
if (stat.isFile()) {
hash.update(`file:${relativePath}\n`);
hash.update(await fs.readFile(candidate));
hash.update("\n");
return;
}
hash.update(`other:${relativePath}:${stat.mode}\n`);
}
async function buildSkillSetKey(input: {
skills: PaperclipSkillEntry[];
label: string;
}): Promise<string> {
const hash = createHash("sha256");
hash.update(`paperclip-acpx-${input.label}-skills:v1\n`);
const sorted = [...input.skills].sort((left, right) => left.runtimeName.localeCompare(right.runtimeName));
for (const entry of sorted) {
hash.update(`skill:${entry.key}:${entry.runtimeName}\n`);
await hashPathContents(entry.source, hash, entry.runtimeName, new Set<string>());
}
return hash.digest("hex");
}
async function resolveSelectedRuntimeSkills(
config: Record<string, unknown>,
): Promise<{ allSkills: PaperclipSkillEntry[]; selectedSkills: PaperclipSkillEntry[]; desiredSkillNames: string[] }> {
const allSkills = await readPaperclipRuntimeSkillEntries(config, __moduleDir);
const desiredSkillNames = resolvePaperclipDesiredSkillNames(config, allSkills);
const desiredSet = new Set(desiredSkillNames);
return {
allSkills,
selectedSkills: allSkills.filter((entry) => desiredSet.has(entry.key)),
desiredSkillNames,
};
}
async function prepareClaudeSkillRuntime(input: {
stateDir: string;
config: Record<string, unknown>;
onLog: AdapterExecutionContext["onLog"];
}): Promise<{
identity: Record<string, unknown>;
promptInstructions: string;
commandNotes: string[];
}> {
const { selectedSkills, desiredSkillNames } = await resolveSelectedRuntimeSkills(input.config);
const skillSetKey = await buildSkillSetKey({ skills: selectedSkills, label: "claude" });
const bundleRoot = path.join(input.stateDir, "runtime-skills", "claude", skillSetKey);
const skillsHome = path.join(bundleRoot, ".claude", "skills");
await fs.mkdir(skillsHome, { recursive: true });
for (const entry of selectedSkills) {
const target = path.join(skillsHome, entry.runtimeName);
try {
const result = await materializePaperclipSkillCopy(entry.source, target);
if (result.skippedSymlinks.length > 0) {
await input.onLog(
"stdout",
`[paperclip] Materialized ACPX Claude skill "${entry.runtimeName}" into ${skillsHome} and skipped ${result.skippedSymlinks.length} symlink(s).\n`,
);
}
} catch (err) {
await input.onLog(
"stderr",
`[paperclip] Failed to materialize ACPX Claude skill "${entry.key}" into ${skillsHome}: ${err instanceof Error ? err.message : String(err)}\n`,
);
}
}
const selectedNames = selectedSkills.map((entry) => entry.runtimeName).sort();
const promptInstructions = selectedSkills.length > 0
? [
"Paperclip has materialized selected runtime skills for this ACPX Claude session.",
`Skill root: ${skillsHome}`,
selectedNames.length > 0 ? `Selected skills: ${selectedNames.join(", ")}` : "",
"When a task calls for one of these skills, read its SKILL.md from that root and follow it.",
].filter(Boolean).join("\n")
: "";
return {
identity: {
mode: "claude",
skillSetKey,
desiredSkillNames,
selectedSkills: selectedNames,
skillRoot: selectedSkills.length > 0 ? skillsHome : null,
},
promptInstructions,
commandNotes: selectedSkills.length > 0
? [`Materialized ${selectedSkills.length} Paperclip skill(s) for ACPX Claude at ${skillsHome}.`]
: [],
};
}
async function readManagedCodexSkillsManifest(skillsHome: string): Promise<Set<string>> {
const manifestPath = path.join(skillsHome, PAPERCLIP_MANAGED_CODEX_SKILLS_MANIFEST);
try {
const raw = JSON.parse(await fs.readFile(manifestPath, "utf8")) as unknown;
const parsed = parseObject(raw);
const skills = Array.isArray(parsed.managedSkillNames)
? parsed.managedSkillNames.filter((value): value is string => typeof value === "string" && value.trim().length > 0)
: [];
return new Set(skills);
} catch {
return new Set();
}
}
async function writeManagedCodexSkillsManifest(skillsHome: string, skillNames: Iterable<string>): Promise<void> {
const managedSkillNames = Array.from(new Set(skillNames)).sort();
await fs.writeFile(
path.join(skillsHome, PAPERCLIP_MANAGED_CODEX_SKILLS_MANIFEST),
`${JSON.stringify({ version: 1, managedSkillNames }, null, 2)}\n`,
"utf8",
);
}
async function removeSkillTarget(target: string): Promise<boolean> {
const existing = await fs.lstat(target).catch(() => null);
if (!existing) return false;
await fs.rm(target, { recursive: true, force: true });
return true;
}
async function reconcileManagedCodexSkills(input: {
skillsHome: string;
allSkills: PaperclipSkillEntry[];
selectedSkills: PaperclipSkillEntry[];
onLog: AdapterExecutionContext["onLog"];
}): Promise<void> {
const desired = new Set(input.selectedSkills.map((entry) => entry.runtimeName));
const managed = await readManagedCodexSkillsManifest(input.skillsHome);
const availableByRuntimeName = new Map(input.allSkills.map((entry) => [entry.runtimeName, entry]));
for (const name of managed) {
if (desired.has(name)) continue;
if (await removeSkillTarget(path.join(input.skillsHome, name))) {
await input.onLog("stdout", `[paperclip] Revoked ACPX Codex skill "${name}" from ${input.skillsHome}\n`);
}
}
for (const entry of input.allSkills) {
if (desired.has(entry.runtimeName) || managed.has(entry.runtimeName)) continue;
const target = path.join(input.skillsHome, entry.runtimeName);
const existing = await fs.lstat(target).catch(() => null);
if (!existing?.isSymbolicLink()) continue;
const linkedPath = await fs.readlink(target).catch(() => null);
if (!linkedPath) continue;
const resolvedLinkedPath = path.resolve(path.dirname(target), linkedPath);
if (resolvedLinkedPath !== path.resolve(entry.source)) continue;
if (await removeSkillTarget(target)) {
await input.onLog("stdout", `[paperclip] Revoked legacy ACPX Codex skill "${entry.runtimeName}" from ${input.skillsHome}\n`);
}
}
for (const name of managed) {
if (desired.has(name) || availableByRuntimeName.has(name)) continue;
if (await removeSkillTarget(path.join(input.skillsHome, name))) {
await input.onLog("stdout", `[paperclip] Revoked unavailable ACPX Codex skill "${name}" from ${input.skillsHome}\n`);
}
}
}
async function prepareCodexSkillRuntime(input: {
companyId: string;
config: Record<string, unknown>;
env: Record<string, string>;
onLog: AdapterExecutionContext["onLog"];
}): Promise<{ identity: Record<string, unknown>; commandNotes: string[] }> {
const envConfig = parseObject(input.config.env);
const configuredCodexHome =
typeof envConfig.CODEX_HOME === "string" && envConfig.CODEX_HOME.trim().length > 0
? path.resolve(envConfig.CODEX_HOME.trim())
: null;
const sourceCodexHome =
typeof process.env.CODEX_HOME === "string" && process.env.CODEX_HOME.trim().length > 0
? path.resolve(process.env.CODEX_HOME.trim())
: path.join(os.homedir(), ".codex");
const managedCodexHome = resolveManagedCodexHomeDir(input.companyId);
const effectiveCodexHome = configuredCodexHome ??
await prepareManagedCodexHome({
companyId: input.companyId,
sourceHome: sourceCodexHome,
targetHome: managedCodexHome,
onLog: input.onLog,
});
const { allSkills, selectedSkills, desiredSkillNames } = await resolveSelectedRuntimeSkills(input.config);
const skillSetKey = await buildSkillSetKey({ skills: selectedSkills, label: "codex" });
const skillsHome = path.join(effectiveCodexHome, "skills");
await fs.mkdir(skillsHome, { recursive: true });
await reconcileManagedCodexSkills({
skillsHome,
allSkills,
selectedSkills,
onLog: input.onLog,
});
for (const entry of selectedSkills) {
const target = path.join(skillsHome, entry.runtimeName);
try {
const result = await materializePaperclipSkillCopy(entry.source, target);
if (result.skippedSymlinks.length > 0) {
await input.onLog(
"stdout",
`[paperclip] Materialized ACPX Codex skill "${entry.runtimeName}" into ${skillsHome} and skipped ${result.skippedSymlinks.length} symlink(s).\n`,
);
}
} catch (err) {
await input.onLog(
"stderr",
`[paperclip] Failed to inject ACPX Codex skill "${entry.key}" into ${skillsHome}: ${err instanceof Error ? err.message : String(err)}\n`,
);
}
}
await writeManagedCodexSkillsManifest(skillsHome, selectedSkills.map((entry) => entry.runtimeName));
input.env.CODEX_HOME = effectiveCodexHome;
return {
identity: {
mode: "codex",
skillSetKey,
desiredSkillNames,
selectedSkills: selectedSkills.map((entry) => entry.runtimeName).sort(),
codexHome: effectiveCodexHome,
skillsHome,
},
commandNotes: [`Prepared ACPX Codex skill home at ${skillsHome}.`],
};
}
function normalizeMode(config: Record<string, unknown>): "persistent" | "oneshot" {
return asString(config.mode, DEFAULT_ACPX_LOCAL_MODE) === "oneshot" ? "oneshot" : "persistent";
}
function normalizePermissionMode(config: Record<string, unknown>): "approve-all" | "approve-reads" | "deny-all" {
const value = asString(config.permissionMode, DEFAULT_ACPX_LOCAL_PERMISSION_MODE).trim();
if (value === "approve-reads" || value === "deny-all") return value;
if (value === "default") return "approve-reads";
return "approve-all";
}
function normalizeNonInteractivePermissions(config: Record<string, unknown>): "deny" | "fail" {
return asString(config.nonInteractivePermissions, DEFAULT_ACPX_LOCAL_NON_INTERACTIVE_PERMISSIONS) === "fail"
? "fail"
: "deny";
}
Improve ACPX adapter configuration (#5290) ## Thinking Path > - Paperclip orchestrates AI agents across several adapter implementations. > - ACPX is a local adapter path that can proxy Claude and Codex-style execution. > - Its configuration needed stronger schema defaults, provider-aware model handling, and better UI support. > - Plugin authors also need clear docs for managed resources. > - This pull request improves ACPX adapter configuration and documents plugin-managed resources. > - The benefit is a more predictable adapter setup path without changing unrelated control-plane behavior. ## What Changed - Improved ACPX config schema, execution config handling, UI build config, and route coverage. - Added ACPX model filtering support and tests. - Updated the agent config form and storybook coverage for ACPX model/provider behavior. - Expanded plugin authoring documentation for managed resources. ## Verification - `pnpm install --frozen-lockfile` - `pnpm exec vitest run server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/adapter-routes.test.ts ui/src/lib/acpx-model-filter.test.ts` ## Risks - Low-to-medium risk: adapter configuration behavior changes can affect ACPX users, but the change is isolated to ACPX/plugin-doc surfaces and covered by targeted adapter tests. ## Model Used - OpenAI GPT-5 Codex via Paperclip `codex_local` adapter, with shell/git/GitHub CLI tool use. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-05-06 06:06:47 -05:00
function normalizeRequestedThinkingEffort(config: Record<string, unknown>): string {
return (
asString(config.modelReasoningEffort, "") ||
asString(config.reasoningEffort, "") ||
asString(config.thinkingEffort, "") ||
asString(config.effort, "")
).trim();
}
Add ACPX local adapter runtime (#4893) ## Thinking Path > - Paperclip orchestrates AI-agent companies through a control plane that can start, supervise, and recover agent runs. > - Local adapters are the bridge between Paperclip issues and concrete agent runtimes such as Claude, Codex, and other ACP-compatible tools. > - The roadmap calls out broader “bring your own agent” and claw-style agent support, and ACPX gives Paperclip one path to normalize multiple ACP agents behind a single adapter. > - The branch needed to become one reviewable PR against current `paperclipai/paperclip:master`, without carrying stale base conflicts or generated lockfile churn. > - This pull request adds an experimental built-in `acpx_local` adapter, integrates it through the server/CLI/UI adapter surfaces, and adds regression coverage for runtime execution, skill sync, stream parsing, diagnostics, and log redaction. > - The benefit is that Paperclip can run Claude/Codex/custom ACP agents through ACPX while keeping operator configuration, skills, logging, and transcript rendering inside the existing adapter model. ## What Changed - Added `@paperclipai/adapter-acpx-local` with server execution, config schema, ACPX session handling, CLI formatting, UI config helpers, and stdout parsing. - Registered `acpx_local` across CLI, server, shared constants, UI adapter metadata, adapter capabilities, and agent creation/editing surfaces. - Added ACPX runtime execution support with persistent sessions, local-agent JWT environment handling, skill snapshots, runtime skill materialization, and isolation/security regressions. - Added ACPX adapter diagnostics and marked the adapter experimental in the UI. - Added command/env secret redaction for resolved command metadata in adapter-utils, server event storage, and the Agent Detail invocation UI. - Added Storybook coverage for ACPX config, transcript rendering, and skill states, plus PR screenshots under `docs/pr-screenshots/pap-2944/`. - Rebased the branch onto current `public-gh/master`; `pnpm-lock.yaml` is intentionally not included and there are no migration/schema changes. ## Verification - `pnpm exec vitest run packages/adapters/acpx-local/src/server/execute.test.ts packages/adapters/acpx-local/src/server/test.test.ts packages/adapters/acpx-local/src/cli/format-event.test.ts packages/adapters/acpx-local/src/ui/parse-stdout.test.ts packages/adapter-utils/src/server-utils.test.ts server/src/__tests__/redaction.test.ts server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/acpx-local-skill-sync.test.ts server/src/__tests__/acpx-local-adapter-environment.test.ts server/src/__tests__/adapter-routes.test.ts server/src/__tests__/agent-skills-routes.test.ts ui/src/adapters/metadata.test.ts` — 12 files, 87 tests passed. - `pnpm --filter @paperclipai/adapter-acpx-local typecheck` — passed. - `pnpm --filter @paperclipai/server typecheck` — passed. - `pnpm --filter @paperclipai/ui typecheck` — passed. - Confirmed PR diff does not include `pnpm-lock.yaml`, database schema files, or migrations. Screenshots: ![ACPX Claude skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-light.png?raw=true) ![ACPX Claude skills dark](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-dark.png?raw=true) ![ACPX custom skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-custom-light.png?raw=true) ## Risks - Medium risk: this introduces a new built-in adapter package and touches runtime execution, adapter registration, agent config, skills, and transcript rendering. - ACPX and ACP agent behavior can vary by installed tool versions; the adapter is marked experimental to set operator expectations. - `pnpm-lock.yaml` is excluded per repository PR policy, so dependency lock refresh must be handled by the repo’s automation or maintainers. - No database migration risk: no schema or migration files changed. > 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 coding agent based on GPT-5, with repository tool use, shell execution, git operations, and local verification. Exact hosted context window was not exposed in this environment. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-30 19:57:05 -05:00
function isCompatibleSession(
params: Record<string, unknown>,
runtime: Pick<AcpxPreparedRuntime, "fingerprint" | "sessionKey" | "cwd" | "mode" | "acpxAgent" | "remoteExecutionIdentity">,
): boolean {
if (asString(params.configFingerprint, "") !== runtime.fingerprint) return false;
if (asString(params.sessionKey, "") !== runtime.sessionKey) return false;
if (asString(params.agent, "") !== runtime.acpxAgent) return false;
if (asString(params.mode, "") !== runtime.mode) return false;
const savedCwd = asString(params.cwd, "");
if (!savedCwd || path.resolve(savedCwd) !== path.resolve(runtime.cwd)) return false;
const savedRemote = parseObject(params.remoteExecution);
return stableJson(savedRemote) === stableJson(runtime.remoteExecutionIdentity ?? {});
}
function buildSessionParams(input: {
prepared: AcpxPreparedRuntime;
handle: AcpRuntimeHandle;
}): Record<string, unknown> {
const { prepared, handle } = input;
return {
sessionKey: prepared.sessionKey,
runtimeSessionName: handle.runtimeSessionName,
acpxRecordId: handle.acpxRecordId,
acpSessionId: handle.backendSessionId,
agentSessionId: handle.agentSessionId,
agent: prepared.acpxAgent,
cwd: prepared.cwd,
mode: prepared.mode,
stateDir: prepared.stateDir,
configFingerprint: prepared.fingerprint,
Improve ACPX adapter configuration (#5290) ## Thinking Path > - Paperclip orchestrates AI agents across several adapter implementations. > - ACPX is a local adapter path that can proxy Claude and Codex-style execution. > - Its configuration needed stronger schema defaults, provider-aware model handling, and better UI support. > - Plugin authors also need clear docs for managed resources. > - This pull request improves ACPX adapter configuration and documents plugin-managed resources. > - The benefit is a more predictable adapter setup path without changing unrelated control-plane behavior. ## What Changed - Improved ACPX config schema, execution config handling, UI build config, and route coverage. - Added ACPX model filtering support and tests. - Updated the agent config form and storybook coverage for ACPX model/provider behavior. - Expanded plugin authoring documentation for managed resources. ## Verification - `pnpm install --frozen-lockfile` - `pnpm exec vitest run server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/adapter-routes.test.ts ui/src/lib/acpx-model-filter.test.ts` ## Risks - Low-to-medium risk: adapter configuration behavior changes can affect ACPX users, but the change is isolated to ACPX/plugin-doc surfaces and covered by targeted adapter tests. ## Model Used - OpenAI GPT-5 Codex via Paperclip `codex_local` adapter, with shell/git/GitHub CLI tool use. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-05-06 06:06:47 -05:00
...(prepared.requestedModel ? { model: prepared.requestedModel } : {}),
...(prepared.requestedThinkingEffort ? { thinkingEffort: prepared.requestedThinkingEffort } : {}),
...(prepared.fastMode ? { fastMode: true } : {}),
Add ACPX local adapter runtime (#4893) ## Thinking Path > - Paperclip orchestrates AI-agent companies through a control plane that can start, supervise, and recover agent runs. > - Local adapters are the bridge between Paperclip issues and concrete agent runtimes such as Claude, Codex, and other ACP-compatible tools. > - The roadmap calls out broader “bring your own agent” and claw-style agent support, and ACPX gives Paperclip one path to normalize multiple ACP agents behind a single adapter. > - The branch needed to become one reviewable PR against current `paperclipai/paperclip:master`, without carrying stale base conflicts or generated lockfile churn. > - This pull request adds an experimental built-in `acpx_local` adapter, integrates it through the server/CLI/UI adapter surfaces, and adds regression coverage for runtime execution, skill sync, stream parsing, diagnostics, and log redaction. > - The benefit is that Paperclip can run Claude/Codex/custom ACP agents through ACPX while keeping operator configuration, skills, logging, and transcript rendering inside the existing adapter model. ## What Changed - Added `@paperclipai/adapter-acpx-local` with server execution, config schema, ACPX session handling, CLI formatting, UI config helpers, and stdout parsing. - Registered `acpx_local` across CLI, server, shared constants, UI adapter metadata, adapter capabilities, and agent creation/editing surfaces. - Added ACPX runtime execution support with persistent sessions, local-agent JWT environment handling, skill snapshots, runtime skill materialization, and isolation/security regressions. - Added ACPX adapter diagnostics and marked the adapter experimental in the UI. - Added command/env secret redaction for resolved command metadata in adapter-utils, server event storage, and the Agent Detail invocation UI. - Added Storybook coverage for ACPX config, transcript rendering, and skill states, plus PR screenshots under `docs/pr-screenshots/pap-2944/`. - Rebased the branch onto current `public-gh/master`; `pnpm-lock.yaml` is intentionally not included and there are no migration/schema changes. ## Verification - `pnpm exec vitest run packages/adapters/acpx-local/src/server/execute.test.ts packages/adapters/acpx-local/src/server/test.test.ts packages/adapters/acpx-local/src/cli/format-event.test.ts packages/adapters/acpx-local/src/ui/parse-stdout.test.ts packages/adapter-utils/src/server-utils.test.ts server/src/__tests__/redaction.test.ts server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/acpx-local-skill-sync.test.ts server/src/__tests__/acpx-local-adapter-environment.test.ts server/src/__tests__/adapter-routes.test.ts server/src/__tests__/agent-skills-routes.test.ts ui/src/adapters/metadata.test.ts` — 12 files, 87 tests passed. - `pnpm --filter @paperclipai/adapter-acpx-local typecheck` — passed. - `pnpm --filter @paperclipai/server typecheck` — passed. - `pnpm --filter @paperclipai/ui typecheck` — passed. - Confirmed PR diff does not include `pnpm-lock.yaml`, database schema files, or migrations. Screenshots: ![ACPX Claude skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-light.png?raw=true) ![ACPX Claude skills dark](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-dark.png?raw=true) ![ACPX custom skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-custom-light.png?raw=true) ## Risks - Medium risk: this introduces a new built-in adapter package and touches runtime execution, adapter registration, agent config, skills, and transcript rendering. - ACPX and ACP agent behavior can vary by installed tool versions; the adapter is marked experimental to set operator expectations. - `pnpm-lock.yaml` is excluded per repository PR policy, so dependency lock refresh must be handled by the repo’s automation or maintainers. - No database migration risk: no schema or migration files changed. > 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 coding agent based on GPT-5, with repository tool use, shell execution, git operations, and local verification. Exact hosted context window was not exposed in this environment. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-30 19:57:05 -05:00
skills: prepared.skillsIdentity,
...(prepared.workspaceId ? { workspaceId: prepared.workspaceId } : {}),
...(prepared.workspaceRepoUrl ? { repoUrl: prepared.workspaceRepoUrl } : {}),
...(prepared.workspaceRepoRef ? { repoRef: prepared.workspaceRepoRef } : {}),
...(prepared.remoteExecutionIdentity ? { remoteExecution: prepared.remoteExecutionIdentity } : {}),
};
}
Make ACPX-Claude adapter work seamlessly (PAPA-388) (#6590) ## Thinking Path > - Paperclip orchestrates AI agents for zero-human companies, so when an adapter fails, the platform must surface enough detail for the next agent (or human reviewer) to act > - The `acpx_local` adapter wraps `claude-agent-acp`, which in turn drives the Claude Code SDK — three layers, three different permission and error-handling models > - A user created a `Claude Local ACPX` agent in PAPA-387 and it failed instantly with the generic `acpx.error / "Internal error"` log, stranding the work and triggering an opaque `stranded_assigned_issue` recovery to the CTO > - Once the diagnostic blackbox was opened, the underlying cause turned out to be two SDK-level mismatches: a model-name allowlist that rejects bare IDs like `claude-opus-4-7`, and a Claude Code permission/Read-sandbox configuration that silently denies every non-allowlisted tool when the user's `~/.claude/settings.json` has `defaultMode: "dontAsk"` > - This pull request fixes both classes of failure in the adapter itself so new ACPX agents work seamlessly without per-host configuration, and widens the diagnostic surface so the *next* failure of any kind is actionable > - The benefit is that ACPX-Claude can join the regular agent roster — verified end to end on PAPA-401, where the agent successfully reached the Paperclip API, opened a worktree, surveyed existing notification PRs, and posted a structured plan ## What Changed - Widen ACPX failure diagnostics (`packages/adapters/acpx-local/src/server/execute.ts`): - Capture `err.name`, ACP code, `cause.message`, retryable flag, and a 5-frame stack preview into `errorMeta`. - Promote phase-specific error codes: `ensure_session → acpx_session_init_failed`, `configure_session → acpx_session_config_failed`, `turn → acpx_turn_failed`, plus mapping for `ACP_BACKEND_MISSING` / `ACP_BACKEND_UNAVAILABLE`. - Set `verbose: true` on the ACPX runtime so its session-event log flows through `ctx.onLog`. - Capture child-process stderr via a wrapper-script tee into `<stateDir>/run-stderr/<runId>.log`, inline the tail into the `acpx.error` payload as `childStderrTail`, and forward it through `ctx.onLog("stderr", …)` so it lands in the heartbeat `stderrExcerpt` column (existing redaction applies). - Set the model via `ANTHROPIC_MODEL` env for the `claude` agent instead of `set_config_option(model, …)`. The ACP server's `set_config_option` handler validates against an internal allowlist and rejects bare IDs like `claude-opus-4-7`. `ANTHROPIC_MODEL` is read during initialization and bypasses that check. - Seed `<worktree>/.claude/settings.local.json` before spawning `claude-agent-acp` (the seamless-API fix). Since `claude-agent-acp` hard-codes `settingSources: ["user", "project", "local"]` and "local" has the highest precedence: - Set `permissions.defaultMode: "default"`, but **only** if the user's value is missing or `"dontAsk"` (the broken case). Other modes like `acceptEdits`/`plan` are preserved. - Pre-allow Paperclip's Bash surface (`Bash(curl:*)`, `Bash(env:*)`, `Bash(<cwd>/scripts/paperclip-issue-update.sh:*)`, `Bash(<cwd>/scripts/paperclip:*)`). - Widen `permissions.additionalDirectories` to include `stateDir`, `agentHome`, and the per-company instance root (`~/.paperclip/instances/<id>/companies/<companyId>`). Scoped to this company only — does not expose other tenants. - Existing user entries are merged, not replaced. The resolved roots are folded into the session fingerprint so warm-session handles invalidate when they change. - Sync the existing server-side integration test (`server/src/__tests__/acpx-local-execute.test.ts`) to assert `acpx_session_init_failed` instead of the now-removed `acpx_protocol_error` for `ACP_SESSION_INIT_FAILED` (a follow-up to commit 1). ## Verification - `pnpm --filter "@paperclipai/adapter-acpx-local" run typecheck` — passes. - `pnpm vitest run` in `packages/adapters/acpx-local` — 35/35 pass, includes 4 new tests covering the settings.local.json write path (claude only, merge with pre-existing content, `dontAsk` override, codex no-op). - `pnpm vitest run src/__tests__/acpx-local-execute.test.ts` in `server/` — 15/15 pass after the test-sync commit. - End-to-end manual verification (PAPA-401): the `Claude Local ACPX` agent that previously hit "restricted environment" now successfully reaches the Paperclip API, opens its worktree, posts structured plan comments, and flips the issue to `in_review` without any external configuration. ## Risks - **Low**, scoped to the `acpx_local` adapter. The settings.local.json write is per-worktree (worktrees live under `.paperclip/worktrees/<issue>/`) and only triggers when `acpxAgent === "claude"`. Existing user content is merged with `[...existing, ...paperclip]` and deduped — nothing is overwritten outright. - The `defaultMode` override is intentionally narrow: it only flips `"dontAsk"` (which silently denies every tool and is the root cause) to `"default"`. Users who explicitly picked `acceptEdits`, `plan`, or any other mode keep their choice. - Stderr capture goes through the existing `log-redaction` pass before persisting, so `PAPERCLIP_API_KEY` and similar secrets in the wrapper env don't leak into heartbeat logs. > 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 4.7 (`claude-opus-4-7`), running in the `claude_local` adapter via Paperclip's harness. Extended thinking enabled, tool use enabled. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [ ] If this change affects the UI, I have included before/after screenshots — N/A (adapter-only) - [ ] I have updated relevant documentation to reflect my changes — no user-facing docs changed; internal commentary in the code change explains the SDK constraints - [x] I have considered and documented any risks above - [ ] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-05-23 13:01:27 -07:00
interface PaperclipClaudeSettingsResult {
filePath: string;
allow: string[];
additionalDirectories: string[];
defaultMode: string;
overrodeDontAsk: boolean;
}
function uniqueSorted(values: Array<string | null | undefined>): string[] {
return [...new Set(values.filter((value): value is string => typeof value === "string" && value.length > 0))].sort();
}
// Phase 4.1 (PAPA-388): the Claude Code SDK that `claude-agent-acp` runs uses
// `settingSources: ["user", "project", "local"]`. By writing a per-worktree
// `.claude/settings.local.json` we override the user's potentially-restrictive
// `~/.claude/settings.json` (e.g. `defaultMode: "dontAsk"`, which silently
// denies every non-allowlisted tool and never reaches `canUseTool`), and we
// widen the SDK's Read sandbox to include the Paperclip state dirs the agent
// needs to talk to its own control plane.
async function writePaperclipClaudeSettings(input: {
cwd: string;
stateDir: string;
agentHome: string;
companyId: string;
}): Promise<PaperclipClaudeSettingsResult> {
const filePath = path.join(input.cwd, ".claude", "settings.local.json");
const instanceRoot = defaultPaperclipInstanceDir();
const companyRoot = path.join(instanceRoot, "companies", input.companyId);
const paperclipAdditionalDirectories = uniqueSorted([
input.stateDir,
input.agentHome,
companyRoot,
]);
const paperclipAllow = uniqueSorted([
"Bash(curl:*)",
"Bash(env:*)",
"Bash(env)",
`Bash(${input.cwd}/scripts/paperclip-issue-update.sh:*)`,
`Bash(${input.cwd}/scripts/paperclip:*)`,
]);
let existing: Record<string, unknown> = {};
const existingRaw = await fs.readFile(filePath, "utf8").catch(() => null);
if (existingRaw) {
try {
const parsed = JSON.parse(existingRaw);
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) existing = parsed as Record<string, unknown>;
} catch {
// Malformed settings file — leave it alone in `existing` and our merge will replace it with a valid one.
}
}
const existingPerms =
existing.permissions && typeof existing.permissions === "object" && !Array.isArray(existing.permissions)
? (existing.permissions as Record<string, unknown>)
: {};
const existingAllow = Array.isArray(existingPerms.allow)
? (existingPerms.allow as unknown[]).filter((value): value is string => typeof value === "string")
: [];
const existingAdditionalDirectories = Array.isArray(existingPerms.additionalDirectories)
? (existingPerms.additionalDirectories as unknown[]).filter((value): value is string => typeof value === "string")
: [];
const mergedAllow = uniqueSorted([...existingAllow, ...paperclipAllow]);
const mergedAdditionalDirectories = uniqueSorted([
...existingAdditionalDirectories,
...paperclipAdditionalDirectories,
]);
const existingDefaultMode =
typeof existingPerms.defaultMode === "string" ? (existingPerms.defaultMode as string) : "";
const defaultMode =
existingDefaultMode && existingDefaultMode !== "dontAsk" ? existingDefaultMode : "default";
const overrodeDontAsk = existingDefaultMode === "dontAsk";
const nextPermissions: Record<string, unknown> = {
...existingPerms,
allow: mergedAllow,
additionalDirectories: mergedAdditionalDirectories,
defaultMode,
};
const next: Record<string, unknown> = { ...existing, permissions: nextPermissions };
await writeFileAtomically({
target: filePath,
contents: `${JSON.stringify(next, null, 2)}\n`,
mode: 0o600,
});
return {
filePath,
allow: mergedAllow,
additionalDirectories: mergedAdditionalDirectories,
defaultMode,
overrodeDontAsk,
};
}
Add ACPX local adapter runtime (#4893) ## Thinking Path > - Paperclip orchestrates AI-agent companies through a control plane that can start, supervise, and recover agent runs. > - Local adapters are the bridge between Paperclip issues and concrete agent runtimes such as Claude, Codex, and other ACP-compatible tools. > - The roadmap calls out broader “bring your own agent” and claw-style agent support, and ACPX gives Paperclip one path to normalize multiple ACP agents behind a single adapter. > - The branch needed to become one reviewable PR against current `paperclipai/paperclip:master`, without carrying stale base conflicts or generated lockfile churn. > - This pull request adds an experimental built-in `acpx_local` adapter, integrates it through the server/CLI/UI adapter surfaces, and adds regression coverage for runtime execution, skill sync, stream parsing, diagnostics, and log redaction. > - The benefit is that Paperclip can run Claude/Codex/custom ACP agents through ACPX while keeping operator configuration, skills, logging, and transcript rendering inside the existing adapter model. ## What Changed - Added `@paperclipai/adapter-acpx-local` with server execution, config schema, ACPX session handling, CLI formatting, UI config helpers, and stdout parsing. - Registered `acpx_local` across CLI, server, shared constants, UI adapter metadata, adapter capabilities, and agent creation/editing surfaces. - Added ACPX runtime execution support with persistent sessions, local-agent JWT environment handling, skill snapshots, runtime skill materialization, and isolation/security regressions. - Added ACPX adapter diagnostics and marked the adapter experimental in the UI. - Added command/env secret redaction for resolved command metadata in adapter-utils, server event storage, and the Agent Detail invocation UI. - Added Storybook coverage for ACPX config, transcript rendering, and skill states, plus PR screenshots under `docs/pr-screenshots/pap-2944/`. - Rebased the branch onto current `public-gh/master`; `pnpm-lock.yaml` is intentionally not included and there are no migration/schema changes. ## Verification - `pnpm exec vitest run packages/adapters/acpx-local/src/server/execute.test.ts packages/adapters/acpx-local/src/server/test.test.ts packages/adapters/acpx-local/src/cli/format-event.test.ts packages/adapters/acpx-local/src/ui/parse-stdout.test.ts packages/adapter-utils/src/server-utils.test.ts server/src/__tests__/redaction.test.ts server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/acpx-local-skill-sync.test.ts server/src/__tests__/acpx-local-adapter-environment.test.ts server/src/__tests__/adapter-routes.test.ts server/src/__tests__/agent-skills-routes.test.ts ui/src/adapters/metadata.test.ts` — 12 files, 87 tests passed. - `pnpm --filter @paperclipai/adapter-acpx-local typecheck` — passed. - `pnpm --filter @paperclipai/server typecheck` — passed. - `pnpm --filter @paperclipai/ui typecheck` — passed. - Confirmed PR diff does not include `pnpm-lock.yaml`, database schema files, or migrations. Screenshots: ![ACPX Claude skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-light.png?raw=true) ![ACPX Claude skills dark](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-dark.png?raw=true) ![ACPX custom skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-custom-light.png?raw=true) ## Risks - Medium risk: this introduces a new built-in adapter package and touches runtime execution, adapter registration, agent config, skills, and transcript rendering. - ACPX and ACP agent behavior can vary by installed tool versions; the adapter is marked experimental to set operator expectations. - `pnpm-lock.yaml` is excluded per repository PR policy, so dependency lock refresh must be handled by the repo’s automation or maintainers. - No database migration risk: no schema or migration files changed. > 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 coding agent based on GPT-5, with repository tool use, shell execution, git operations, and local verification. Exact hosted context window was not exposed in this environment. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-30 19:57:05 -05:00
async function writeAgentWrapper(input: {
stateDir: string;
acpxAgent: string;
agentCommandShell: string;
env: Record<string, string>;
Make ACPX-Claude adapter work seamlessly (PAPA-388) (#6590) ## Thinking Path > - Paperclip orchestrates AI agents for zero-human companies, so when an adapter fails, the platform must surface enough detail for the next agent (or human reviewer) to act > - The `acpx_local` adapter wraps `claude-agent-acp`, which in turn drives the Claude Code SDK — three layers, three different permission and error-handling models > - A user created a `Claude Local ACPX` agent in PAPA-387 and it failed instantly with the generic `acpx.error / "Internal error"` log, stranding the work and triggering an opaque `stranded_assigned_issue` recovery to the CTO > - Once the diagnostic blackbox was opened, the underlying cause turned out to be two SDK-level mismatches: a model-name allowlist that rejects bare IDs like `claude-opus-4-7`, and a Claude Code permission/Read-sandbox configuration that silently denies every non-allowlisted tool when the user's `~/.claude/settings.json` has `defaultMode: "dontAsk"` > - This pull request fixes both classes of failure in the adapter itself so new ACPX agents work seamlessly without per-host configuration, and widens the diagnostic surface so the *next* failure of any kind is actionable > - The benefit is that ACPX-Claude can join the regular agent roster — verified end to end on PAPA-401, where the agent successfully reached the Paperclip API, opened a worktree, surveyed existing notification PRs, and posted a structured plan ## What Changed - Widen ACPX failure diagnostics (`packages/adapters/acpx-local/src/server/execute.ts`): - Capture `err.name`, ACP code, `cause.message`, retryable flag, and a 5-frame stack preview into `errorMeta`. - Promote phase-specific error codes: `ensure_session → acpx_session_init_failed`, `configure_session → acpx_session_config_failed`, `turn → acpx_turn_failed`, plus mapping for `ACP_BACKEND_MISSING` / `ACP_BACKEND_UNAVAILABLE`. - Set `verbose: true` on the ACPX runtime so its session-event log flows through `ctx.onLog`. - Capture child-process stderr via a wrapper-script tee into `<stateDir>/run-stderr/<runId>.log`, inline the tail into the `acpx.error` payload as `childStderrTail`, and forward it through `ctx.onLog("stderr", …)` so it lands in the heartbeat `stderrExcerpt` column (existing redaction applies). - Set the model via `ANTHROPIC_MODEL` env for the `claude` agent instead of `set_config_option(model, …)`. The ACP server's `set_config_option` handler validates against an internal allowlist and rejects bare IDs like `claude-opus-4-7`. `ANTHROPIC_MODEL` is read during initialization and bypasses that check. - Seed `<worktree>/.claude/settings.local.json` before spawning `claude-agent-acp` (the seamless-API fix). Since `claude-agent-acp` hard-codes `settingSources: ["user", "project", "local"]` and "local" has the highest precedence: - Set `permissions.defaultMode: "default"`, but **only** if the user's value is missing or `"dontAsk"` (the broken case). Other modes like `acceptEdits`/`plan` are preserved. - Pre-allow Paperclip's Bash surface (`Bash(curl:*)`, `Bash(env:*)`, `Bash(<cwd>/scripts/paperclip-issue-update.sh:*)`, `Bash(<cwd>/scripts/paperclip:*)`). - Widen `permissions.additionalDirectories` to include `stateDir`, `agentHome`, and the per-company instance root (`~/.paperclip/instances/<id>/companies/<companyId>`). Scoped to this company only — does not expose other tenants. - Existing user entries are merged, not replaced. The resolved roots are folded into the session fingerprint so warm-session handles invalidate when they change. - Sync the existing server-side integration test (`server/src/__tests__/acpx-local-execute.test.ts`) to assert `acpx_session_init_failed` instead of the now-removed `acpx_protocol_error` for `ACP_SESSION_INIT_FAILED` (a follow-up to commit 1). ## Verification - `pnpm --filter "@paperclipai/adapter-acpx-local" run typecheck` — passes. - `pnpm vitest run` in `packages/adapters/acpx-local` — 35/35 pass, includes 4 new tests covering the settings.local.json write path (claude only, merge with pre-existing content, `dontAsk` override, codex no-op). - `pnpm vitest run src/__tests__/acpx-local-execute.test.ts` in `server/` — 15/15 pass after the test-sync commit. - End-to-end manual verification (PAPA-401): the `Claude Local ACPX` agent that previously hit "restricted environment" now successfully reaches the Paperclip API, opens its worktree, posts structured plan comments, and flips the issue to `in_review` without any external configuration. ## Risks - **Low**, scoped to the `acpx_local` adapter. The settings.local.json write is per-worktree (worktrees live under `.paperclip/worktrees/<issue>/`) and only triggers when `acpxAgent === "claude"`. Existing user content is merged with `[...existing, ...paperclip]` and deduped — nothing is overwritten outright. - The `defaultMode` override is intentionally narrow: it only flips `"dontAsk"` (which silently denies every tool and is the root cause) to `"default"`. Users who explicitly picked `acceptEdits`, `plan`, or any other mode keep their choice. - Stderr capture goes through the existing `log-redaction` pass before persisting, so `PAPERCLIP_API_KEY` and similar secrets in the wrapper env don't leak into heartbeat logs. > 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 4.7 (`claude-opus-4-7`), running in the `claude_local` adapter via Paperclip's harness. Extended thinking enabled, tool use enabled. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [ ] If this change affects the UI, I have included before/after screenshots — N/A (adapter-only) - [ ] I have updated relevant documentation to reflect my changes — no user-facing docs changed; internal commentary in the code change explains the SDK constraints - [x] I have considered and documented any risks above - [ ] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-05-23 13:01:27 -07:00
childStderrDir: string;
Add ACPX local adapter runtime (#4893) ## Thinking Path > - Paperclip orchestrates AI-agent companies through a control plane that can start, supervise, and recover agent runs. > - Local adapters are the bridge between Paperclip issues and concrete agent runtimes such as Claude, Codex, and other ACP-compatible tools. > - The roadmap calls out broader “bring your own agent” and claw-style agent support, and ACPX gives Paperclip one path to normalize multiple ACP agents behind a single adapter. > - The branch needed to become one reviewable PR against current `paperclipai/paperclip:master`, without carrying stale base conflicts or generated lockfile churn. > - This pull request adds an experimental built-in `acpx_local` adapter, integrates it through the server/CLI/UI adapter surfaces, and adds regression coverage for runtime execution, skill sync, stream parsing, diagnostics, and log redaction. > - The benefit is that Paperclip can run Claude/Codex/custom ACP agents through ACPX while keeping operator configuration, skills, logging, and transcript rendering inside the existing adapter model. ## What Changed - Added `@paperclipai/adapter-acpx-local` with server execution, config schema, ACPX session handling, CLI formatting, UI config helpers, and stdout parsing. - Registered `acpx_local` across CLI, server, shared constants, UI adapter metadata, adapter capabilities, and agent creation/editing surfaces. - Added ACPX runtime execution support with persistent sessions, local-agent JWT environment handling, skill snapshots, runtime skill materialization, and isolation/security regressions. - Added ACPX adapter diagnostics and marked the adapter experimental in the UI. - Added command/env secret redaction for resolved command metadata in adapter-utils, server event storage, and the Agent Detail invocation UI. - Added Storybook coverage for ACPX config, transcript rendering, and skill states, plus PR screenshots under `docs/pr-screenshots/pap-2944/`. - Rebased the branch onto current `public-gh/master`; `pnpm-lock.yaml` is intentionally not included and there are no migration/schema changes. ## Verification - `pnpm exec vitest run packages/adapters/acpx-local/src/server/execute.test.ts packages/adapters/acpx-local/src/server/test.test.ts packages/adapters/acpx-local/src/cli/format-event.test.ts packages/adapters/acpx-local/src/ui/parse-stdout.test.ts packages/adapter-utils/src/server-utils.test.ts server/src/__tests__/redaction.test.ts server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/acpx-local-skill-sync.test.ts server/src/__tests__/acpx-local-adapter-environment.test.ts server/src/__tests__/adapter-routes.test.ts server/src/__tests__/agent-skills-routes.test.ts ui/src/adapters/metadata.test.ts` — 12 files, 87 tests passed. - `pnpm --filter @paperclipai/adapter-acpx-local typecheck` — passed. - `pnpm --filter @paperclipai/server typecheck` — passed. - `pnpm --filter @paperclipai/ui typecheck` — passed. - Confirmed PR diff does not include `pnpm-lock.yaml`, database schema files, or migrations. Screenshots: ![ACPX Claude skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-light.png?raw=true) ![ACPX Claude skills dark](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-dark.png?raw=true) ![ACPX custom skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-custom-light.png?raw=true) ## Risks - Medium risk: this introduces a new built-in adapter package and touches runtime execution, adapter registration, agent config, skills, and transcript rendering. - ACPX and ACP agent behavior can vary by installed tool versions; the adapter is marked experimental to set operator expectations. - `pnpm-lock.yaml` is excluded per repository PR policy, so dependency lock refresh must be handled by the repo’s automation or maintainers. - No database migration risk: no schema or migration files changed. > 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 coding agent based on GPT-5, with repository tool use, shell execution, git operations, and local verification. Exact hosted context window was not exposed in this environment. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-30 19:57:05 -05:00
}): Promise<{ wrapperPath: string; envFilePath: string }> {
const wrappersDir = path.join(input.stateDir, "wrappers");
await fs.mkdir(wrappersDir, { recursive: true });
const envLines = Object.entries(input.env)
.filter(([key]) => /^[A-Za-z_][A-Za-z0-9_]*$/.test(key))
.sort(([left], [right]) => left.localeCompare(right))
.map(([key, value]) => `${key}=${shellQuote(value)}`);
const wrapperHash = shortHash({
agent: input.acpxAgent,
command: input.agentCommandShell,
env: envLines,
Make ACPX-Claude adapter work seamlessly (PAPA-388) (#6590) ## Thinking Path > - Paperclip orchestrates AI agents for zero-human companies, so when an adapter fails, the platform must surface enough detail for the next agent (or human reviewer) to act > - The `acpx_local` adapter wraps `claude-agent-acp`, which in turn drives the Claude Code SDK — three layers, three different permission and error-handling models > - A user created a `Claude Local ACPX` agent in PAPA-387 and it failed instantly with the generic `acpx.error / "Internal error"` log, stranding the work and triggering an opaque `stranded_assigned_issue` recovery to the CTO > - Once the diagnostic blackbox was opened, the underlying cause turned out to be two SDK-level mismatches: a model-name allowlist that rejects bare IDs like `claude-opus-4-7`, and a Claude Code permission/Read-sandbox configuration that silently denies every non-allowlisted tool when the user's `~/.claude/settings.json` has `defaultMode: "dontAsk"` > - This pull request fixes both classes of failure in the adapter itself so new ACPX agents work seamlessly without per-host configuration, and widens the diagnostic surface so the *next* failure of any kind is actionable > - The benefit is that ACPX-Claude can join the regular agent roster — verified end to end on PAPA-401, where the agent successfully reached the Paperclip API, opened a worktree, surveyed existing notification PRs, and posted a structured plan ## What Changed - Widen ACPX failure diagnostics (`packages/adapters/acpx-local/src/server/execute.ts`): - Capture `err.name`, ACP code, `cause.message`, retryable flag, and a 5-frame stack preview into `errorMeta`. - Promote phase-specific error codes: `ensure_session → acpx_session_init_failed`, `configure_session → acpx_session_config_failed`, `turn → acpx_turn_failed`, plus mapping for `ACP_BACKEND_MISSING` / `ACP_BACKEND_UNAVAILABLE`. - Set `verbose: true` on the ACPX runtime so its session-event log flows through `ctx.onLog`. - Capture child-process stderr via a wrapper-script tee into `<stateDir>/run-stderr/<runId>.log`, inline the tail into the `acpx.error` payload as `childStderrTail`, and forward it through `ctx.onLog("stderr", …)` so it lands in the heartbeat `stderrExcerpt` column (existing redaction applies). - Set the model via `ANTHROPIC_MODEL` env for the `claude` agent instead of `set_config_option(model, …)`. The ACP server's `set_config_option` handler validates against an internal allowlist and rejects bare IDs like `claude-opus-4-7`. `ANTHROPIC_MODEL` is read during initialization and bypasses that check. - Seed `<worktree>/.claude/settings.local.json` before spawning `claude-agent-acp` (the seamless-API fix). Since `claude-agent-acp` hard-codes `settingSources: ["user", "project", "local"]` and "local" has the highest precedence: - Set `permissions.defaultMode: "default"`, but **only** if the user's value is missing or `"dontAsk"` (the broken case). Other modes like `acceptEdits`/`plan` are preserved. - Pre-allow Paperclip's Bash surface (`Bash(curl:*)`, `Bash(env:*)`, `Bash(<cwd>/scripts/paperclip-issue-update.sh:*)`, `Bash(<cwd>/scripts/paperclip:*)`). - Widen `permissions.additionalDirectories` to include `stateDir`, `agentHome`, and the per-company instance root (`~/.paperclip/instances/<id>/companies/<companyId>`). Scoped to this company only — does not expose other tenants. - Existing user entries are merged, not replaced. The resolved roots are folded into the session fingerprint so warm-session handles invalidate when they change. - Sync the existing server-side integration test (`server/src/__tests__/acpx-local-execute.test.ts`) to assert `acpx_session_init_failed` instead of the now-removed `acpx_protocol_error` for `ACP_SESSION_INIT_FAILED` (a follow-up to commit 1). ## Verification - `pnpm --filter "@paperclipai/adapter-acpx-local" run typecheck` — passes. - `pnpm vitest run` in `packages/adapters/acpx-local` — 35/35 pass, includes 4 new tests covering the settings.local.json write path (claude only, merge with pre-existing content, `dontAsk` override, codex no-op). - `pnpm vitest run src/__tests__/acpx-local-execute.test.ts` in `server/` — 15/15 pass after the test-sync commit. - End-to-end manual verification (PAPA-401): the `Claude Local ACPX` agent that previously hit "restricted environment" now successfully reaches the Paperclip API, opens its worktree, posts structured plan comments, and flips the issue to `in_review` without any external configuration. ## Risks - **Low**, scoped to the `acpx_local` adapter. The settings.local.json write is per-worktree (worktrees live under `.paperclip/worktrees/<issue>/`) and only triggers when `acpxAgent === "claude"`. Existing user content is merged with `[...existing, ...paperclip]` and deduped — nothing is overwritten outright. - The `defaultMode` override is intentionally narrow: it only flips `"dontAsk"` (which silently denies every tool and is the root cause) to `"default"`. Users who explicitly picked `acceptEdits`, `plan`, or any other mode keep their choice. - Stderr capture goes through the existing `log-redaction` pass before persisting, so `PAPERCLIP_API_KEY` and similar secrets in the wrapper env don't leak into heartbeat logs. > 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 4.7 (`claude-opus-4-7`), running in the `claude_local` adapter via Paperclip's harness. Extended thinking enabled, tool use enabled. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [ ] If this change affects the UI, I have included before/after screenshots — N/A (adapter-only) - [ ] I have updated relevant documentation to reflect my changes — no user-facing docs changed; internal commentary in the code change explains the SDK constraints - [x] I have considered and documented any risks above - [ ] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-05-23 13:01:27 -07:00
childStderrDir: input.childStderrDir,
Add ACPX local adapter runtime (#4893) ## Thinking Path > - Paperclip orchestrates AI-agent companies through a control plane that can start, supervise, and recover agent runs. > - Local adapters are the bridge between Paperclip issues and concrete agent runtimes such as Claude, Codex, and other ACP-compatible tools. > - The roadmap calls out broader “bring your own agent” and claw-style agent support, and ACPX gives Paperclip one path to normalize multiple ACP agents behind a single adapter. > - The branch needed to become one reviewable PR against current `paperclipai/paperclip:master`, without carrying stale base conflicts or generated lockfile churn. > - This pull request adds an experimental built-in `acpx_local` adapter, integrates it through the server/CLI/UI adapter surfaces, and adds regression coverage for runtime execution, skill sync, stream parsing, diagnostics, and log redaction. > - The benefit is that Paperclip can run Claude/Codex/custom ACP agents through ACPX while keeping operator configuration, skills, logging, and transcript rendering inside the existing adapter model. ## What Changed - Added `@paperclipai/adapter-acpx-local` with server execution, config schema, ACPX session handling, CLI formatting, UI config helpers, and stdout parsing. - Registered `acpx_local` across CLI, server, shared constants, UI adapter metadata, adapter capabilities, and agent creation/editing surfaces. - Added ACPX runtime execution support with persistent sessions, local-agent JWT environment handling, skill snapshots, runtime skill materialization, and isolation/security regressions. - Added ACPX adapter diagnostics and marked the adapter experimental in the UI. - Added command/env secret redaction for resolved command metadata in adapter-utils, server event storage, and the Agent Detail invocation UI. - Added Storybook coverage for ACPX config, transcript rendering, and skill states, plus PR screenshots under `docs/pr-screenshots/pap-2944/`. - Rebased the branch onto current `public-gh/master`; `pnpm-lock.yaml` is intentionally not included and there are no migration/schema changes. ## Verification - `pnpm exec vitest run packages/adapters/acpx-local/src/server/execute.test.ts packages/adapters/acpx-local/src/server/test.test.ts packages/adapters/acpx-local/src/cli/format-event.test.ts packages/adapters/acpx-local/src/ui/parse-stdout.test.ts packages/adapter-utils/src/server-utils.test.ts server/src/__tests__/redaction.test.ts server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/acpx-local-skill-sync.test.ts server/src/__tests__/acpx-local-adapter-environment.test.ts server/src/__tests__/adapter-routes.test.ts server/src/__tests__/agent-skills-routes.test.ts ui/src/adapters/metadata.test.ts` — 12 files, 87 tests passed. - `pnpm --filter @paperclipai/adapter-acpx-local typecheck` — passed. - `pnpm --filter @paperclipai/server typecheck` — passed. - `pnpm --filter @paperclipai/ui typecheck` — passed. - Confirmed PR diff does not include `pnpm-lock.yaml`, database schema files, or migrations. Screenshots: ![ACPX Claude skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-light.png?raw=true) ![ACPX Claude skills dark](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-dark.png?raw=true) ![ACPX custom skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-custom-light.png?raw=true) ## Risks - Medium risk: this introduces a new built-in adapter package and touches runtime execution, adapter registration, agent config, skills, and transcript rendering. - ACPX and ACP agent behavior can vary by installed tool versions; the adapter is marked experimental to set operator expectations. - `pnpm-lock.yaml` is excluded per repository PR policy, so dependency lock refresh must be handled by the repo’s automation or maintainers. - No database migration risk: no schema or migration files changed. > 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 coding agent based on GPT-5, with repository tool use, shell execution, git operations, and local verification. Exact hosted context window was not exposed in this environment. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-30 19:57:05 -05:00
});
const wrapperPath = path.join(wrappersDir, `${input.acpxAgent}-${wrapperHash}.sh`);
const envFilePath = path.join(wrappersDir, `${input.acpxAgent}-${wrapperHash}.env`);
const script = [
"#!/usr/bin/env bash",
"set -euo pipefail",
`env_file=${shellQuote(envFilePath)}`,
"if [[ -f \"$env_file\" ]]; then",
" set -a",
" source \"$env_file\"",
" set +a",
"fi",
Make ACPX-Claude adapter work seamlessly (PAPA-388) (#6590) ## Thinking Path > - Paperclip orchestrates AI agents for zero-human companies, so when an adapter fails, the platform must surface enough detail for the next agent (or human reviewer) to act > - The `acpx_local` adapter wraps `claude-agent-acp`, which in turn drives the Claude Code SDK — three layers, three different permission and error-handling models > - A user created a `Claude Local ACPX` agent in PAPA-387 and it failed instantly with the generic `acpx.error / "Internal error"` log, stranding the work and triggering an opaque `stranded_assigned_issue` recovery to the CTO > - Once the diagnostic blackbox was opened, the underlying cause turned out to be two SDK-level mismatches: a model-name allowlist that rejects bare IDs like `claude-opus-4-7`, and a Claude Code permission/Read-sandbox configuration that silently denies every non-allowlisted tool when the user's `~/.claude/settings.json` has `defaultMode: "dontAsk"` > - This pull request fixes both classes of failure in the adapter itself so new ACPX agents work seamlessly without per-host configuration, and widens the diagnostic surface so the *next* failure of any kind is actionable > - The benefit is that ACPX-Claude can join the regular agent roster — verified end to end on PAPA-401, where the agent successfully reached the Paperclip API, opened a worktree, surveyed existing notification PRs, and posted a structured plan ## What Changed - Widen ACPX failure diagnostics (`packages/adapters/acpx-local/src/server/execute.ts`): - Capture `err.name`, ACP code, `cause.message`, retryable flag, and a 5-frame stack preview into `errorMeta`. - Promote phase-specific error codes: `ensure_session → acpx_session_init_failed`, `configure_session → acpx_session_config_failed`, `turn → acpx_turn_failed`, plus mapping for `ACP_BACKEND_MISSING` / `ACP_BACKEND_UNAVAILABLE`. - Set `verbose: true` on the ACPX runtime so its session-event log flows through `ctx.onLog`. - Capture child-process stderr via a wrapper-script tee into `<stateDir>/run-stderr/<runId>.log`, inline the tail into the `acpx.error` payload as `childStderrTail`, and forward it through `ctx.onLog("stderr", …)` so it lands in the heartbeat `stderrExcerpt` column (existing redaction applies). - Set the model via `ANTHROPIC_MODEL` env for the `claude` agent instead of `set_config_option(model, …)`. The ACP server's `set_config_option` handler validates against an internal allowlist and rejects bare IDs like `claude-opus-4-7`. `ANTHROPIC_MODEL` is read during initialization and bypasses that check. - Seed `<worktree>/.claude/settings.local.json` before spawning `claude-agent-acp` (the seamless-API fix). Since `claude-agent-acp` hard-codes `settingSources: ["user", "project", "local"]` and "local" has the highest precedence: - Set `permissions.defaultMode: "default"`, but **only** if the user's value is missing or `"dontAsk"` (the broken case). Other modes like `acceptEdits`/`plan` are preserved. - Pre-allow Paperclip's Bash surface (`Bash(curl:*)`, `Bash(env:*)`, `Bash(<cwd>/scripts/paperclip-issue-update.sh:*)`, `Bash(<cwd>/scripts/paperclip:*)`). - Widen `permissions.additionalDirectories` to include `stateDir`, `agentHome`, and the per-company instance root (`~/.paperclip/instances/<id>/companies/<companyId>`). Scoped to this company only — does not expose other tenants. - Existing user entries are merged, not replaced. The resolved roots are folded into the session fingerprint so warm-session handles invalidate when they change. - Sync the existing server-side integration test (`server/src/__tests__/acpx-local-execute.test.ts`) to assert `acpx_session_init_failed` instead of the now-removed `acpx_protocol_error` for `ACP_SESSION_INIT_FAILED` (a follow-up to commit 1). ## Verification - `pnpm --filter "@paperclipai/adapter-acpx-local" run typecheck` — passes. - `pnpm vitest run` in `packages/adapters/acpx-local` — 35/35 pass, includes 4 new tests covering the settings.local.json write path (claude only, merge with pre-existing content, `dontAsk` override, codex no-op). - `pnpm vitest run src/__tests__/acpx-local-execute.test.ts` in `server/` — 15/15 pass after the test-sync commit. - End-to-end manual verification (PAPA-401): the `Claude Local ACPX` agent that previously hit "restricted environment" now successfully reaches the Paperclip API, opens its worktree, posts structured plan comments, and flips the issue to `in_review` without any external configuration. ## Risks - **Low**, scoped to the `acpx_local` adapter. The settings.local.json write is per-worktree (worktrees live under `.paperclip/worktrees/<issue>/`) and only triggers when `acpxAgent === "claude"`. Existing user content is merged with `[...existing, ...paperclip]` and deduped — nothing is overwritten outright. - The `defaultMode` override is intentionally narrow: it only flips `"dontAsk"` (which silently denies every tool and is the root cause) to `"default"`. Users who explicitly picked `acceptEdits`, `plan`, or any other mode keep their choice. - Stderr capture goes through the existing `log-redaction` pass before persisting, so `PAPERCLIP_API_KEY` and similar secrets in the wrapper env don't leak into heartbeat logs. > 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 4.7 (`claude-opus-4-7`), running in the `claude_local` adapter via Paperclip's harness. Extended thinking enabled, tool use enabled. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [ ] If this change affects the UI, I have included before/after screenshots — N/A (adapter-only) - [ ] I have updated relevant documentation to reflect my changes — no user-facing docs changed; internal commentary in the code change explains the SDK constraints - [x] I have considered and documented any risks above - [ ] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-05-23 13:01:27 -07:00
`stderr_dir=${shellQuote(input.childStderrDir)}`,
"if [[ -n \"${PAPERCLIP_RUN_ID:-}\" ]]; then",
" mkdir -p \"$stderr_dir\"",
" exec 2> >(tee -a \"$stderr_dir/$PAPERCLIP_RUN_ID.log\" >&2)",
"fi",
Add ACPX local adapter runtime (#4893) ## Thinking Path > - Paperclip orchestrates AI-agent companies through a control plane that can start, supervise, and recover agent runs. > - Local adapters are the bridge between Paperclip issues and concrete agent runtimes such as Claude, Codex, and other ACP-compatible tools. > - The roadmap calls out broader “bring your own agent” and claw-style agent support, and ACPX gives Paperclip one path to normalize multiple ACP agents behind a single adapter. > - The branch needed to become one reviewable PR against current `paperclipai/paperclip:master`, without carrying stale base conflicts or generated lockfile churn. > - This pull request adds an experimental built-in `acpx_local` adapter, integrates it through the server/CLI/UI adapter surfaces, and adds regression coverage for runtime execution, skill sync, stream parsing, diagnostics, and log redaction. > - The benefit is that Paperclip can run Claude/Codex/custom ACP agents through ACPX while keeping operator configuration, skills, logging, and transcript rendering inside the existing adapter model. ## What Changed - Added `@paperclipai/adapter-acpx-local` with server execution, config schema, ACPX session handling, CLI formatting, UI config helpers, and stdout parsing. - Registered `acpx_local` across CLI, server, shared constants, UI adapter metadata, adapter capabilities, and agent creation/editing surfaces. - Added ACPX runtime execution support with persistent sessions, local-agent JWT environment handling, skill snapshots, runtime skill materialization, and isolation/security regressions. - Added ACPX adapter diagnostics and marked the adapter experimental in the UI. - Added command/env secret redaction for resolved command metadata in adapter-utils, server event storage, and the Agent Detail invocation UI. - Added Storybook coverage for ACPX config, transcript rendering, and skill states, plus PR screenshots under `docs/pr-screenshots/pap-2944/`. - Rebased the branch onto current `public-gh/master`; `pnpm-lock.yaml` is intentionally not included and there are no migration/schema changes. ## Verification - `pnpm exec vitest run packages/adapters/acpx-local/src/server/execute.test.ts packages/adapters/acpx-local/src/server/test.test.ts packages/adapters/acpx-local/src/cli/format-event.test.ts packages/adapters/acpx-local/src/ui/parse-stdout.test.ts packages/adapter-utils/src/server-utils.test.ts server/src/__tests__/redaction.test.ts server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/acpx-local-skill-sync.test.ts server/src/__tests__/acpx-local-adapter-environment.test.ts server/src/__tests__/adapter-routes.test.ts server/src/__tests__/agent-skills-routes.test.ts ui/src/adapters/metadata.test.ts` — 12 files, 87 tests passed. - `pnpm --filter @paperclipai/adapter-acpx-local typecheck` — passed. - `pnpm --filter @paperclipai/server typecheck` — passed. - `pnpm --filter @paperclipai/ui typecheck` — passed. - Confirmed PR diff does not include `pnpm-lock.yaml`, database schema files, or migrations. Screenshots: ![ACPX Claude skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-light.png?raw=true) ![ACPX Claude skills dark](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-dark.png?raw=true) ![ACPX custom skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-custom-light.png?raw=true) ## Risks - Medium risk: this introduces a new built-in adapter package and touches runtime execution, adapter registration, agent config, skills, and transcript rendering. - ACPX and ACP agent behavior can vary by installed tool versions; the adapter is marked experimental to set operator expectations. - `pnpm-lock.yaml` is excluded per repository PR policy, so dependency lock refresh must be handled by the repo’s automation or maintainers. - No database migration risk: no schema or migration files changed. > 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 coding agent based on GPT-5, with repository tool use, shell execution, git operations, and local verification. Exact hosted context window was not exposed in this environment. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-30 19:57:05 -05:00
`exec ${input.agentCommandShell} "$@"`,
"",
].join("\n");
await writeFileAtomically({
target: envFilePath,
contents: `${envLines.join("\n")}\n`,
mode: 0o600,
});
await writeFileAtomically({
target: wrapperPath,
contents: script,
mode: 0o700,
});
await cleanupStaleAgentWrappers({
wrappersDir,
currentFileNames: new Set([path.basename(wrapperPath), path.basename(envFilePath)]),
});
return { wrapperPath, envFilePath };
}
async function cleanupStaleAgentWrappers(input: { wrappersDir: string; currentFileNames: Set<string> }) {
const wrappers = await fs.readdir(input.wrappersDir).catch(() => []);
const now = Date.now();
await Promise.all(
wrappers.map(async (name) => {
const isManagedWrapperFile = name.endsWith(".sh") || name.endsWith(".env");
if (!isManagedWrapperFile || input.currentFileNames.has(name)) return;
const wrapperPath = path.join(input.wrappersDir, name);
const stats = await fs.stat(wrapperPath).catch(() => null);
if (!stats || now - stats.mtimeMs < WRAPPER_CLEANUP_RETENTION_MS) return;
await fs.rm(wrapperPath, { force: true });
}),
);
}
async function buildRuntime(input: {
ctx: AdapterExecutionContext;
}): Promise<AcpxPreparedRuntime> {
const { runId, agent, config, context, authToken } = input.ctx;
const workspaceContext = parseObject(context.paperclipWorkspace);
const workspaceCwd = asString(workspaceContext.cwd, "");
const workspaceSource = asString(workspaceContext.source, "");
const workspaceStrategy = asString(workspaceContext.strategy, "");
const workspaceId = asString(workspaceContext.workspaceId, "");
const workspaceRepoUrl = asString(workspaceContext.repoUrl, "");
const workspaceRepoRef = asString(workspaceContext.repoRef, "");
const workspaceBranch = asString(workspaceContext.branchName, "");
const workspaceWorktreePath = asString(workspaceContext.worktreePath, "");
const agentHome = asString(workspaceContext.agentHome, "");
const configuredCwd = asString(config.cwd, "");
const useConfiguredInsteadOfAgentHome = workspaceSource === "agent_home" && configuredCwd.length > 0;
const effectiveWorkspaceCwd = useConfiguredInsteadOfAgentHome ? "" : workspaceCwd;
const cwd = effectiveWorkspaceCwd || configuredCwd || process.cwd();
Fix remote workspace environment shaping (#5118) > **Stacked PR (part 5 of 7).** Depends on: - PR #5114 - PR #5115 - PR #5116 - PR #5117 > Diff against `master` includes commits from earlier PRs in the stack — the new commit in this PR is the topmost one. ## Thinking Path > - Paperclip orchestrates AI agents for zero-human companies > - Agents run with a Paperclip-shaped environment (`PAPERCLIP_WORKSPACE_CWD`, > worktree path, `PAPERCLIP_WORKSPACES_JSON` hints) so the CLI can locate the > correct project tree > - SSH testing reproduced a real failure: a Codex SSH run wrote to > `/tmp/paperclip-env-matrix-...` (the *host* path) instead of the realized > remote workspace at `/home/<user>/paperclip-env-matrix-ssh-claude/...` > because the adapter injected `PAPERCLIP_WORKSPACE_CWD=/tmp/...` into the > remote env > - Code review on the initial codex-only fix asked to roll the same approach > into every other SSH-capable adapter (claude, acpx, cursor, opencode, gemini, > pi) via a shared helper rather than duplicating per-adapter > - This PR adds `shapePaperclipWorkspaceEnvForExecution` in adapter-utils that, > when the execution target is remote: replaces local cwd with the realized > execution cwd, nulls out worktree path (which has no remote meaning), and > rewrites/strips `cwd` entries in workspace hints based on what was actually > synced. Every adapter calls it before invoking the remote runner > - The benefit is that remote runs see the realized remote workspace, host-local > paths stop leaking into remote env, and the rule is unit-tested in one place ## What Changed - Added `shapePaperclipWorkspaceEnvForExecution` to `packages/adapter-utils/src/server-utils.ts` with full unit coverage (`server-utils.test.ts`) - Each of acpx-local, claude-local, codex-local, cursor-local, gemini-local, opencode-local, pi-local now calls the new shaper before issuing the remote command and feeds the shaped values into `applyPaperclipWorkspaceEnv` - Per-adapter `execute.remote.test.ts` files extended to cover the new shaping behaviour: localhost paths replaced with remote cwd, foreign-cwd hints stripped, worktree path nulled out for remote targets - `acpx-local/src/server/execute.test.ts` extended with shaping coverage ## Verification - `pnpm test -- server-utils execute.remote` - `pnpm --filter @paperclipai/adapter-acpx-local test` - Manual QA reproducing the original failure: 1. Provision an E2B sandbox environment for the Paperclip QA company 2. Assign an issue to a remote-targeted claude-local agent and confirm the run starts in the correct remote cwd (no `/Users/...` path leakage in the run logs) 3. Repeat for opencode-local and pi-local ## Risks - Behavioural shift: hints whose `cwd` doesn't match the workspace cwd are now stripped on remote targets. If any adapter relied on a leaked local hint cwd, it will see a missing `cwd` instead. Reviewed all current callers — none do. - Adds a small per-run cost (path resolve + string normalisation) on every remote execution. Negligible. - Worktree path is now nulled out on remote (it has no meaning there). Adapters that previously read the value defensively will continue to work. ## Model Used - OpenAI GPT-5.4 (reasoning effort: high) via Codex CLI - Provider: OpenAI - Used to author the code changes in this PR ## 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 run tests locally and they pass - [x] I have added or updated tests where applicable - [ ] If this change affects the UI, I have included before/after screenshots — N/A - [ ] I have updated relevant documentation to reflect my changes — N/A - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge
2026-05-03 13:17:52 -07:00
const executionTarget = readAdapterExecutionTarget({
executionTarget: input.ctx.executionTarget,
legacyRemoteExecution: input.ctx.executionTransport?.remoteExecution,
});
const remoteExecutionIdentity = adapterExecutionTargetSessionIdentity(executionTarget);
const effectiveExecutionCwd =
remoteExecutionIdentity && typeof remoteExecutionIdentity.remoteCwd === "string"
? remoteExecutionIdentity.remoteCwd
: cwd;
Harden remote workspace sync and restore flows (#5444) ## Thinking Path > - Paperclip orchestrates AI agents for zero-human companies > - When an agent runs against a remote target, Paperclip syncs the workspace out to the remote at run start and restores changes back to the local workspace at run end > - The previous restore flow naïvely overwrote local files with whatever the remote returned, so files that the remote run never touched but had timestamp/mode drift could be needlessly rewritten — and a single static `refs/paperclip/ssh-sync/imported` ref made concurrent SSH workspace exports race on the same git ref > - This pull request adds a `workspace-restore-merge` module that diffs a pre-run snapshot against the post-run remote state and only writes back files the remote actually changed; SSH workspace exports now use a per-import unique ref so concurrent runs can't trample each other > - Every adapter's execute path threads the snapshot through `prepareAdapterExecutionTargetRuntime` so the merge has the baseline it needs > - The benefit is workspace restores no longer churn untouched files, and concurrent SSH runs no longer collide on the import ref ## What Changed - `packages/adapter-utils/src/workspace-restore-merge.{ts,test.ts}`: new module — directory snapshot (kind/mode/sha256/symlink target) plus snapshot-aware merge that writes only the files the remote changed - `packages/adapter-utils/src/ssh.ts`: SSH workspace export uses a per-import unique ref (`refs/paperclip/ssh-sync/imported/<uuid>`); restore goes through the new merge helper; `ssh-fixture.test.ts` covers the unique-ref + merge paths - `packages/adapter-utils/src/sandbox-managed-runtime.ts` + `remote-managed-runtime.ts`: thread the snapshot/merge through the sandbox and SSH paths - `packages/adapter-utils/src/server-utils.{ts,test.ts}` + `execution-target.ts`: helpers for capturing the pre-run snapshot; `prepareAdapterExecutionTargetRuntime` gains required `runId` and optional `workspaceRemoteDir`, and returns the realized `workspaceRemoteDir` - Each adapter's `execute.ts` (acpx, claude, codex, cursor, gemini, opencode, pi) takes the snapshot at run start and passes it through to the runtime restore - Remote execute test mocks updated to match the new `prepareWorkspaceForSshExecution` return shape and the per-run `${managedRemoteWorkspace}` cwd subdirectory ## Verification - `pnpm vitest run --no-coverage --project @paperclipai/adapter-utils --project @paperclipai/adapter-acpx-local --project @paperclipai/adapter-claude-local --project @paperclipai/adapter-codex-local --project @paperclipai/adapter-cursor-local --project @paperclipai/adapter-gemini-local --project @paperclipai/adapter-opencode-local --project @paperclipai/adapter-pi-local` — 196/196 passing - `pnpm typecheck` clean across the workspace ## Risks Medium. The restore path now writes a strict subset of what it previously did — files the remote did not touch are no longer rewritten. If any flow was relying on a touch-without-content-change being copied back (timestamp or permission propagation only), that behavior is now skipped. Snapshot capture adds an O(N-files-in-workspace) hash pass at run start; the cost is bounded by the existing exclude list. The `runId` parameter on `prepareAdapterExecutionTargetRuntime` is now required — every in-tree caller is updated; out-of-tree adapter authors need to pass it. ## Model Used Claude Opus 4.7 (1M context) ## 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 run tests locally and they pass - [x] I have added or updated tests where applicable — new module + every adapter execute path covered - [x] If this change affects the UI, I have included before/after screenshots — N/A (no UI) - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge
2026-05-07 14:44:45 -07:00
const executionTargetIsRemote = remoteExecutionIdentity !== null;
Fix remote workspace environment shaping (#5118) > **Stacked PR (part 5 of 7).** Depends on: - PR #5114 - PR #5115 - PR #5116 - PR #5117 > Diff against `master` includes commits from earlier PRs in the stack — the new commit in this PR is the topmost one. ## Thinking Path > - Paperclip orchestrates AI agents for zero-human companies > - Agents run with a Paperclip-shaped environment (`PAPERCLIP_WORKSPACE_CWD`, > worktree path, `PAPERCLIP_WORKSPACES_JSON` hints) so the CLI can locate the > correct project tree > - SSH testing reproduced a real failure: a Codex SSH run wrote to > `/tmp/paperclip-env-matrix-...` (the *host* path) instead of the realized > remote workspace at `/home/<user>/paperclip-env-matrix-ssh-claude/...` > because the adapter injected `PAPERCLIP_WORKSPACE_CWD=/tmp/...` into the > remote env > - Code review on the initial codex-only fix asked to roll the same approach > into every other SSH-capable adapter (claude, acpx, cursor, opencode, gemini, > pi) via a shared helper rather than duplicating per-adapter > - This PR adds `shapePaperclipWorkspaceEnvForExecution` in adapter-utils that, > when the execution target is remote: replaces local cwd with the realized > execution cwd, nulls out worktree path (which has no remote meaning), and > rewrites/strips `cwd` entries in workspace hints based on what was actually > synced. Every adapter calls it before invoking the remote runner > - The benefit is that remote runs see the realized remote workspace, host-local > paths stop leaking into remote env, and the rule is unit-tested in one place ## What Changed - Added `shapePaperclipWorkspaceEnvForExecution` to `packages/adapter-utils/src/server-utils.ts` with full unit coverage (`server-utils.test.ts`) - Each of acpx-local, claude-local, codex-local, cursor-local, gemini-local, opencode-local, pi-local now calls the new shaper before issuing the remote command and feeds the shaped values into `applyPaperclipWorkspaceEnv` - Per-adapter `execute.remote.test.ts` files extended to cover the new shaping behaviour: localhost paths replaced with remote cwd, foreign-cwd hints stripped, worktree path nulled out for remote targets - `acpx-local/src/server/execute.test.ts` extended with shaping coverage ## Verification - `pnpm test -- server-utils execute.remote` - `pnpm --filter @paperclipai/adapter-acpx-local test` - Manual QA reproducing the original failure: 1. Provision an E2B sandbox environment for the Paperclip QA company 2. Assign an issue to a remote-targeted claude-local agent and confirm the run starts in the correct remote cwd (no `/Users/...` path leakage in the run logs) 3. Repeat for opencode-local and pi-local ## Risks - Behavioural shift: hints whose `cwd` doesn't match the workspace cwd are now stripped on remote targets. If any adapter relied on a leaked local hint cwd, it will see a missing `cwd` instead. Reviewed all current callers — none do. - Adds a small per-run cost (path resolve + string normalisation) on every remote execution. Negligible. - Worktree path is now nulled out on remote (it has no meaning there). Adapters that previously read the value defensively will continue to work. ## Model Used - OpenAI GPT-5.4 (reasoning effort: high) via Codex CLI - Provider: OpenAI - Used to author the code changes in this PR ## 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 run tests locally and they pass - [x] I have added or updated tests where applicable - [ ] If this change affects the UI, I have included before/after screenshots — N/A - [ ] I have updated relevant documentation to reflect my changes — N/A - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge
2026-05-03 13:17:52 -07:00
const shapedWorkspaceEnv = shapePaperclipWorkspaceEnvForExecution({
workspaceCwd: effectiveWorkspaceCwd,
workspaceWorktreePath,
Harden remote workspace sync and restore flows (#5444) ## Thinking Path > - Paperclip orchestrates AI agents for zero-human companies > - When an agent runs against a remote target, Paperclip syncs the workspace out to the remote at run start and restores changes back to the local workspace at run end > - The previous restore flow naïvely overwrote local files with whatever the remote returned, so files that the remote run never touched but had timestamp/mode drift could be needlessly rewritten — and a single static `refs/paperclip/ssh-sync/imported` ref made concurrent SSH workspace exports race on the same git ref > - This pull request adds a `workspace-restore-merge` module that diffs a pre-run snapshot against the post-run remote state and only writes back files the remote actually changed; SSH workspace exports now use a per-import unique ref so concurrent runs can't trample each other > - Every adapter's execute path threads the snapshot through `prepareAdapterExecutionTargetRuntime` so the merge has the baseline it needs > - The benefit is workspace restores no longer churn untouched files, and concurrent SSH runs no longer collide on the import ref ## What Changed - `packages/adapter-utils/src/workspace-restore-merge.{ts,test.ts}`: new module — directory snapshot (kind/mode/sha256/symlink target) plus snapshot-aware merge that writes only the files the remote changed - `packages/adapter-utils/src/ssh.ts`: SSH workspace export uses a per-import unique ref (`refs/paperclip/ssh-sync/imported/<uuid>`); restore goes through the new merge helper; `ssh-fixture.test.ts` covers the unique-ref + merge paths - `packages/adapter-utils/src/sandbox-managed-runtime.ts` + `remote-managed-runtime.ts`: thread the snapshot/merge through the sandbox and SSH paths - `packages/adapter-utils/src/server-utils.{ts,test.ts}` + `execution-target.ts`: helpers for capturing the pre-run snapshot; `prepareAdapterExecutionTargetRuntime` gains required `runId` and optional `workspaceRemoteDir`, and returns the realized `workspaceRemoteDir` - Each adapter's `execute.ts` (acpx, claude, codex, cursor, gemini, opencode, pi) takes the snapshot at run start and passes it through to the runtime restore - Remote execute test mocks updated to match the new `prepareWorkspaceForSshExecution` return shape and the per-run `${managedRemoteWorkspace}` cwd subdirectory ## Verification - `pnpm vitest run --no-coverage --project @paperclipai/adapter-utils --project @paperclipai/adapter-acpx-local --project @paperclipai/adapter-claude-local --project @paperclipai/adapter-codex-local --project @paperclipai/adapter-cursor-local --project @paperclipai/adapter-gemini-local --project @paperclipai/adapter-opencode-local --project @paperclipai/adapter-pi-local` — 196/196 passing - `pnpm typecheck` clean across the workspace ## Risks Medium. The restore path now writes a strict subset of what it previously did — files the remote did not touch are no longer rewritten. If any flow was relying on a touch-without-content-change being copied back (timestamp or permission propagation only), that behavior is now skipped. Snapshot capture adds an O(N-files-in-workspace) hash pass at run start; the cost is bounded by the existing exclude list. The `runId` parameter on `prepareAdapterExecutionTargetRuntime` is now required — every in-tree caller is updated; out-of-tree adapter authors need to pass it. ## Model Used Claude Opus 4.7 (1M context) ## 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 run tests locally and they pass - [x] I have added or updated tests where applicable — new module + every adapter execute path covered - [x] If this change affects the UI, I have included before/after screenshots — N/A (no UI) - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge
2026-05-07 14:44:45 -07:00
executionTargetIsRemote,
Fix remote workspace environment shaping (#5118) > **Stacked PR (part 5 of 7).** Depends on: - PR #5114 - PR #5115 - PR #5116 - PR #5117 > Diff against `master` includes commits from earlier PRs in the stack — the new commit in this PR is the topmost one. ## Thinking Path > - Paperclip orchestrates AI agents for zero-human companies > - Agents run with a Paperclip-shaped environment (`PAPERCLIP_WORKSPACE_CWD`, > worktree path, `PAPERCLIP_WORKSPACES_JSON` hints) so the CLI can locate the > correct project tree > - SSH testing reproduced a real failure: a Codex SSH run wrote to > `/tmp/paperclip-env-matrix-...` (the *host* path) instead of the realized > remote workspace at `/home/<user>/paperclip-env-matrix-ssh-claude/...` > because the adapter injected `PAPERCLIP_WORKSPACE_CWD=/tmp/...` into the > remote env > - Code review on the initial codex-only fix asked to roll the same approach > into every other SSH-capable adapter (claude, acpx, cursor, opencode, gemini, > pi) via a shared helper rather than duplicating per-adapter > - This PR adds `shapePaperclipWorkspaceEnvForExecution` in adapter-utils that, > when the execution target is remote: replaces local cwd with the realized > execution cwd, nulls out worktree path (which has no remote meaning), and > rewrites/strips `cwd` entries in workspace hints based on what was actually > synced. Every adapter calls it before invoking the remote runner > - The benefit is that remote runs see the realized remote workspace, host-local > paths stop leaking into remote env, and the rule is unit-tested in one place ## What Changed - Added `shapePaperclipWorkspaceEnvForExecution` to `packages/adapter-utils/src/server-utils.ts` with full unit coverage (`server-utils.test.ts`) - Each of acpx-local, claude-local, codex-local, cursor-local, gemini-local, opencode-local, pi-local now calls the new shaper before issuing the remote command and feeds the shaped values into `applyPaperclipWorkspaceEnv` - Per-adapter `execute.remote.test.ts` files extended to cover the new shaping behaviour: localhost paths replaced with remote cwd, foreign-cwd hints stripped, worktree path nulled out for remote targets - `acpx-local/src/server/execute.test.ts` extended with shaping coverage ## Verification - `pnpm test -- server-utils execute.remote` - `pnpm --filter @paperclipai/adapter-acpx-local test` - Manual QA reproducing the original failure: 1. Provision an E2B sandbox environment for the Paperclip QA company 2. Assign an issue to a remote-targeted claude-local agent and confirm the run starts in the correct remote cwd (no `/Users/...` path leakage in the run logs) 3. Repeat for opencode-local and pi-local ## Risks - Behavioural shift: hints whose `cwd` doesn't match the workspace cwd are now stripped on remote targets. If any adapter relied on a leaked local hint cwd, it will see a missing `cwd` instead. Reviewed all current callers — none do. - Adds a small per-run cost (path resolve + string normalisation) on every remote execution. Negligible. - Worktree path is now nulled out on remote (it has no meaning there). Adapters that previously read the value defensively will continue to work. ## Model Used - OpenAI GPT-5.4 (reasoning effort: high) via Codex CLI - Provider: OpenAI - Used to author the code changes in this PR ## 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 run tests locally and they pass - [x] I have added or updated tests where applicable - [ ] If this change affects the UI, I have included before/after screenshots — N/A - [ ] I have updated relevant documentation to reflect my changes — N/A - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge
2026-05-03 13:17:52 -07:00
executionCwd: effectiveExecutionCwd,
});
Add ACPX local adapter runtime (#4893) ## Thinking Path > - Paperclip orchestrates AI-agent companies through a control plane that can start, supervise, and recover agent runs. > - Local adapters are the bridge between Paperclip issues and concrete agent runtimes such as Claude, Codex, and other ACP-compatible tools. > - The roadmap calls out broader “bring your own agent” and claw-style agent support, and ACPX gives Paperclip one path to normalize multiple ACP agents behind a single adapter. > - The branch needed to become one reviewable PR against current `paperclipai/paperclip:master`, without carrying stale base conflicts or generated lockfile churn. > - This pull request adds an experimental built-in `acpx_local` adapter, integrates it through the server/CLI/UI adapter surfaces, and adds regression coverage for runtime execution, skill sync, stream parsing, diagnostics, and log redaction. > - The benefit is that Paperclip can run Claude/Codex/custom ACP agents through ACPX while keeping operator configuration, skills, logging, and transcript rendering inside the existing adapter model. ## What Changed - Added `@paperclipai/adapter-acpx-local` with server execution, config schema, ACPX session handling, CLI formatting, UI config helpers, and stdout parsing. - Registered `acpx_local` across CLI, server, shared constants, UI adapter metadata, adapter capabilities, and agent creation/editing surfaces. - Added ACPX runtime execution support with persistent sessions, local-agent JWT environment handling, skill snapshots, runtime skill materialization, and isolation/security regressions. - Added ACPX adapter diagnostics and marked the adapter experimental in the UI. - Added command/env secret redaction for resolved command metadata in adapter-utils, server event storage, and the Agent Detail invocation UI. - Added Storybook coverage for ACPX config, transcript rendering, and skill states, plus PR screenshots under `docs/pr-screenshots/pap-2944/`. - Rebased the branch onto current `public-gh/master`; `pnpm-lock.yaml` is intentionally not included and there are no migration/schema changes. ## Verification - `pnpm exec vitest run packages/adapters/acpx-local/src/server/execute.test.ts packages/adapters/acpx-local/src/server/test.test.ts packages/adapters/acpx-local/src/cli/format-event.test.ts packages/adapters/acpx-local/src/ui/parse-stdout.test.ts packages/adapter-utils/src/server-utils.test.ts server/src/__tests__/redaction.test.ts server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/acpx-local-skill-sync.test.ts server/src/__tests__/acpx-local-adapter-environment.test.ts server/src/__tests__/adapter-routes.test.ts server/src/__tests__/agent-skills-routes.test.ts ui/src/adapters/metadata.test.ts` — 12 files, 87 tests passed. - `pnpm --filter @paperclipai/adapter-acpx-local typecheck` — passed. - `pnpm --filter @paperclipai/server typecheck` — passed. - `pnpm --filter @paperclipai/ui typecheck` — passed. - Confirmed PR diff does not include `pnpm-lock.yaml`, database schema files, or migrations. Screenshots: ![ACPX Claude skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-light.png?raw=true) ![ACPX Claude skills dark](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-dark.png?raw=true) ![ACPX custom skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-custom-light.png?raw=true) ## Risks - Medium risk: this introduces a new built-in adapter package and touches runtime execution, adapter registration, agent config, skills, and transcript rendering. - ACPX and ACP agent behavior can vary by installed tool versions; the adapter is marked experimental to set operator expectations. - `pnpm-lock.yaml` is excluded per repository PR policy, so dependency lock refresh must be handled by the repo’s automation or maintainers. - No database migration risk: no schema or migration files changed. > 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 coding agent based on GPT-5, with repository tool use, shell execution, git operations, and local verification. Exact hosted context window was not exposed in this environment. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-30 19:57:05 -05:00
await ensureAbsoluteDirectory(cwd, { createIfMissing: true });
const acpxAgent = normalizeAgent(config);
const mode = normalizeMode(config);
const permissionMode = normalizePermissionMode(config);
const nonInteractivePermissions = normalizeNonInteractivePermissions(config);
Improve ACPX adapter configuration (#5290) ## Thinking Path > - Paperclip orchestrates AI agents across several adapter implementations. > - ACPX is a local adapter path that can proxy Claude and Codex-style execution. > - Its configuration needed stronger schema defaults, provider-aware model handling, and better UI support. > - Plugin authors also need clear docs for managed resources. > - This pull request improves ACPX adapter configuration and documents plugin-managed resources. > - The benefit is a more predictable adapter setup path without changing unrelated control-plane behavior. ## What Changed - Improved ACPX config schema, execution config handling, UI build config, and route coverage. - Added ACPX model filtering support and tests. - Updated the agent config form and storybook coverage for ACPX model/provider behavior. - Expanded plugin authoring documentation for managed resources. ## Verification - `pnpm install --frozen-lockfile` - `pnpm exec vitest run server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/adapter-routes.test.ts ui/src/lib/acpx-model-filter.test.ts` ## Risks - Low-to-medium risk: adapter configuration behavior changes can affect ACPX users, but the change is isolated to ACPX/plugin-doc surfaces and covered by targeted adapter tests. ## Model Used - OpenAI GPT-5 Codex via Paperclip `codex_local` adapter, with shell/git/GitHub CLI tool use. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-05-06 06:06:47 -05:00
const requestedModel = asString(config.model, "").trim();
const requestedThinkingEffort = normalizeRequestedThinkingEffort(config);
const fastMode = acpxAgent === "codex" && config.fastMode === true;
Add ACPX local adapter runtime (#4893) ## Thinking Path > - Paperclip orchestrates AI-agent companies through a control plane that can start, supervise, and recover agent runs. > - Local adapters are the bridge between Paperclip issues and concrete agent runtimes such as Claude, Codex, and other ACP-compatible tools. > - The roadmap calls out broader “bring your own agent” and claw-style agent support, and ACPX gives Paperclip one path to normalize multiple ACP agents behind a single adapter. > - The branch needed to become one reviewable PR against current `paperclipai/paperclip:master`, without carrying stale base conflicts or generated lockfile churn. > - This pull request adds an experimental built-in `acpx_local` adapter, integrates it through the server/CLI/UI adapter surfaces, and adds regression coverage for runtime execution, skill sync, stream parsing, diagnostics, and log redaction. > - The benefit is that Paperclip can run Claude/Codex/custom ACP agents through ACPX while keeping operator configuration, skills, logging, and transcript rendering inside the existing adapter model. ## What Changed - Added `@paperclipai/adapter-acpx-local` with server execution, config schema, ACPX session handling, CLI formatting, UI config helpers, and stdout parsing. - Registered `acpx_local` across CLI, server, shared constants, UI adapter metadata, adapter capabilities, and agent creation/editing surfaces. - Added ACPX runtime execution support with persistent sessions, local-agent JWT environment handling, skill snapshots, runtime skill materialization, and isolation/security regressions. - Added ACPX adapter diagnostics and marked the adapter experimental in the UI. - Added command/env secret redaction for resolved command metadata in adapter-utils, server event storage, and the Agent Detail invocation UI. - Added Storybook coverage for ACPX config, transcript rendering, and skill states, plus PR screenshots under `docs/pr-screenshots/pap-2944/`. - Rebased the branch onto current `public-gh/master`; `pnpm-lock.yaml` is intentionally not included and there are no migration/schema changes. ## Verification - `pnpm exec vitest run packages/adapters/acpx-local/src/server/execute.test.ts packages/adapters/acpx-local/src/server/test.test.ts packages/adapters/acpx-local/src/cli/format-event.test.ts packages/adapters/acpx-local/src/ui/parse-stdout.test.ts packages/adapter-utils/src/server-utils.test.ts server/src/__tests__/redaction.test.ts server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/acpx-local-skill-sync.test.ts server/src/__tests__/acpx-local-adapter-environment.test.ts server/src/__tests__/adapter-routes.test.ts server/src/__tests__/agent-skills-routes.test.ts ui/src/adapters/metadata.test.ts` — 12 files, 87 tests passed. - `pnpm --filter @paperclipai/adapter-acpx-local typecheck` — passed. - `pnpm --filter @paperclipai/server typecheck` — passed. - `pnpm --filter @paperclipai/ui typecheck` — passed. - Confirmed PR diff does not include `pnpm-lock.yaml`, database schema files, or migrations. Screenshots: ![ACPX Claude skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-light.png?raw=true) ![ACPX Claude skills dark](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-dark.png?raw=true) ![ACPX custom skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-custom-light.png?raw=true) ## Risks - Medium risk: this introduces a new built-in adapter package and touches runtime execution, adapter registration, agent config, skills, and transcript rendering. - ACPX and ACP agent behavior can vary by installed tool versions; the adapter is marked experimental to set operator expectations. - `pnpm-lock.yaml` is excluded per repository PR policy, so dependency lock refresh must be handled by the repo’s automation or maintainers. - No database migration risk: no schema or migration files changed. > 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 coding agent based on GPT-5, with repository tool use, shell execution, git operations, and local verification. Exact hosted context window was not exposed in this environment. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-30 19:57:05 -05:00
const timeoutSec = asNumber(config.timeoutSec, DEFAULT_ACPX_LOCAL_TIMEOUT_SEC);
const stateDir = path.resolve(asString(config.stateDir, "") || defaultStateDir(agent.companyId, agent.id));
await fs.mkdir(stateDir, { recursive: true });
const envConfig = parseObject(config.env);
const hasExplicitApiKey =
typeof envConfig.PAPERCLIP_API_KEY === "string" && envConfig.PAPERCLIP_API_KEY.trim().length > 0;
const env: Record<string, string> = { ...buildPaperclipEnv(agent), PAPERCLIP_RUN_ID: runId };
const wakeTaskId =
(typeof context.taskId === "string" && context.taskId.trim()) ||
(typeof context.issueId === "string" && context.issueId.trim()) ||
"";
const wakeReason = typeof context.wakeReason === "string" ? context.wakeReason.trim() : "";
const wakeCommentId =
(typeof context.wakeCommentId === "string" && context.wakeCommentId.trim()) ||
(typeof context.commentId === "string" && context.commentId.trim()) ||
"";
const approvalId = typeof context.approvalId === "string" ? context.approvalId.trim() : "";
const approvalStatus = typeof context.approvalStatus === "string" ? context.approvalStatus.trim() : "";
const linkedIssueIds = Array.isArray(context.issueIds)
? context.issueIds.filter((value): value is string => typeof value === "string" && value.trim().length > 0)
: [];
const wakePayloadJson = stringifyPaperclipWakePayload(context.paperclipWake);
Add planning mode for issue work (#5353) ## Thinking Path > - Paperclip is a control plane for autonomous AI companies. > - Issues are the core unit of work, and issue comments are how board users and agents coordinate execution. > - Some issue conversations need to produce plans and approvals instead of immediate implementation work. > - The existing issue contract did not distinguish standard execution comments from planning-oriented issue work. > - This pull request adds an issue work-mode contract and board UI affordances for standard vs planning mode. > - The benefit is that planning-mode issues can be created, displayed, discussed, and carried through agent heartbeat context without losing the normal issue workflow. ## What Changed - Added `standard` / `planning` issue work-mode contracts across DB, shared validators/types, server issue flows, plugin protocol, and adapter heartbeat payloads. - Added an idempotent `0081_optimal_dormammu` migration for `issues.work_mode`, ordered after current `public-gh/master` migrations. - Updated heartbeat/context summaries and issue-thread interaction behavior so planning work mode is preserved when creating suggested follow-up issues. - Added UI support for planning-mode issue creation, issue rows, detail composer styling, and composer work-mode toggles. - Added focused server/shared/UI tests plus a Playwright visual verification spec for planning-mode surfaces. - Rebased the branch onto current `public-gh/master` and added durable planning-mode screenshots under `doc/assets/pap-3368/`. ## Verification - `pnpm --filter @paperclipai/db run check:migrations` - `pnpm exec vitest run --project @paperclipai/shared packages/shared/src/validators/issue.test.ts` - `pnpm exec vitest run --project @paperclipai/server server/src/__tests__/heartbeat-context-summary.test.ts server/src/__tests__/issue-thread-interactions-service.test.ts server/src/__tests__/issues-goal-context-routes.test.ts --pool=forks --poolOptions.forks.isolate=true` - `pnpm exec vitest run --project @paperclipai/ui ui/src/components/IssueChatThread.test.tsx ui/src/components/NewIssueDialog.test.tsx ui/src/components/IssueRow.test.tsx ui/src/pages/IssueDetail.test.tsx` - `pnpm exec vitest run --project @paperclipai/adapter-utils packages/adapter-utils/src/server-utils.test.ts` - `PAPERCLIP_E2E_SKIP_LLM=true npx playwright test --config tests/e2e/playwright.config.ts tests/e2e/planning-mode-visual-verification.spec.ts` ## Screenshots Desktop planning detail: ![Desktop planning detail](https://raw.githubusercontent.com/paperclipai/paperclip/PAP-3368-plan-a-planning-mode-for-issues/doc/assets/pap-3368/desktop-planning-detail.png) Desktop planning row: ![Desktop planning row](https://raw.githubusercontent.com/paperclipai/paperclip/PAP-3368-plan-a-planning-mode-for-issues/doc/assets/pap-3368/desktop-planning-row.png) Desktop staged standard toggle: ![Desktop staged standard toggle](https://raw.githubusercontent.com/paperclipai/paperclip/PAP-3368-plan-a-planning-mode-for-issues/doc/assets/pap-3368/desktop-standard-toggle.png) Mobile planning detail: ![Mobile planning detail](https://raw.githubusercontent.com/paperclipai/paperclip/PAP-3368-plan-a-planning-mode-for-issues/doc/assets/pap-3368/mobile-planning-detail.png) Mobile planning row: ![Mobile planning row](https://raw.githubusercontent.com/paperclipai/paperclip/PAP-3368-plan-a-planning-mode-for-issues/doc/assets/pap-3368/mobile-planning-row.png) ## Risks - Medium migration risk: this adds a non-null issue column. The migration uses `ADD COLUMN IF NOT EXISTS` so installations that applied an older branch-local migration number can still apply the final numbered migration safely. - Medium contract risk: issue payloads, plugin payloads, and adapter heartbeat payloads now include work mode; compatibility is handled by defaulting missing values to `standard`. - UI risk is moderate because composer controls changed; focused component tests and visual e2e coverage exercise standard vs planning display and toggle behavior. > For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and discuss it in `#dev` before opening the PR. Feature PRs that overlap with planned core work may need to be redirected — check the roadmap first. See `CONTRIBUTING.md`. ## Model Used - OpenAI Codex, GPT-5 coding agent in a local Paperclip worktree, with shell/tool use. Exact context-window size is not exposed in this runtime. ## 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 run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-05-06 07:01:28 -05:00
const issueWorkMode = readPaperclipIssueWorkModeFromContext(context);
Add ACPX local adapter runtime (#4893) ## Thinking Path > - Paperclip orchestrates AI-agent companies through a control plane that can start, supervise, and recover agent runs. > - Local adapters are the bridge between Paperclip issues and concrete agent runtimes such as Claude, Codex, and other ACP-compatible tools. > - The roadmap calls out broader “bring your own agent” and claw-style agent support, and ACPX gives Paperclip one path to normalize multiple ACP agents behind a single adapter. > - The branch needed to become one reviewable PR against current `paperclipai/paperclip:master`, without carrying stale base conflicts or generated lockfile churn. > - This pull request adds an experimental built-in `acpx_local` adapter, integrates it through the server/CLI/UI adapter surfaces, and adds regression coverage for runtime execution, skill sync, stream parsing, diagnostics, and log redaction. > - The benefit is that Paperclip can run Claude/Codex/custom ACP agents through ACPX while keeping operator configuration, skills, logging, and transcript rendering inside the existing adapter model. ## What Changed - Added `@paperclipai/adapter-acpx-local` with server execution, config schema, ACPX session handling, CLI formatting, UI config helpers, and stdout parsing. - Registered `acpx_local` across CLI, server, shared constants, UI adapter metadata, adapter capabilities, and agent creation/editing surfaces. - Added ACPX runtime execution support with persistent sessions, local-agent JWT environment handling, skill snapshots, runtime skill materialization, and isolation/security regressions. - Added ACPX adapter diagnostics and marked the adapter experimental in the UI. - Added command/env secret redaction for resolved command metadata in adapter-utils, server event storage, and the Agent Detail invocation UI. - Added Storybook coverage for ACPX config, transcript rendering, and skill states, plus PR screenshots under `docs/pr-screenshots/pap-2944/`. - Rebased the branch onto current `public-gh/master`; `pnpm-lock.yaml` is intentionally not included and there are no migration/schema changes. ## Verification - `pnpm exec vitest run packages/adapters/acpx-local/src/server/execute.test.ts packages/adapters/acpx-local/src/server/test.test.ts packages/adapters/acpx-local/src/cli/format-event.test.ts packages/adapters/acpx-local/src/ui/parse-stdout.test.ts packages/adapter-utils/src/server-utils.test.ts server/src/__tests__/redaction.test.ts server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/acpx-local-skill-sync.test.ts server/src/__tests__/acpx-local-adapter-environment.test.ts server/src/__tests__/adapter-routes.test.ts server/src/__tests__/agent-skills-routes.test.ts ui/src/adapters/metadata.test.ts` — 12 files, 87 tests passed. - `pnpm --filter @paperclipai/adapter-acpx-local typecheck` — passed. - `pnpm --filter @paperclipai/server typecheck` — passed. - `pnpm --filter @paperclipai/ui typecheck` — passed. - Confirmed PR diff does not include `pnpm-lock.yaml`, database schema files, or migrations. Screenshots: ![ACPX Claude skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-light.png?raw=true) ![ACPX Claude skills dark](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-dark.png?raw=true) ![ACPX custom skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-custom-light.png?raw=true) ## Risks - Medium risk: this introduces a new built-in adapter package and touches runtime execution, adapter registration, agent config, skills, and transcript rendering. - ACPX and ACP agent behavior can vary by installed tool versions; the adapter is marked experimental to set operator expectations. - `pnpm-lock.yaml` is excluded per repository PR policy, so dependency lock refresh must be handled by the repo’s automation or maintainers. - No database migration risk: no schema or migration files changed. > 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 coding agent based on GPT-5, with repository tool use, shell execution, git operations, and local verification. Exact hosted context window was not exposed in this environment. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-30 19:57:05 -05:00
if (wakeTaskId) env.PAPERCLIP_TASK_ID = wakeTaskId;
Add planning mode for issue work (#5353) ## Thinking Path > - Paperclip is a control plane for autonomous AI companies. > - Issues are the core unit of work, and issue comments are how board users and agents coordinate execution. > - Some issue conversations need to produce plans and approvals instead of immediate implementation work. > - The existing issue contract did not distinguish standard execution comments from planning-oriented issue work. > - This pull request adds an issue work-mode contract and board UI affordances for standard vs planning mode. > - The benefit is that planning-mode issues can be created, displayed, discussed, and carried through agent heartbeat context without losing the normal issue workflow. ## What Changed - Added `standard` / `planning` issue work-mode contracts across DB, shared validators/types, server issue flows, plugin protocol, and adapter heartbeat payloads. - Added an idempotent `0081_optimal_dormammu` migration for `issues.work_mode`, ordered after current `public-gh/master` migrations. - Updated heartbeat/context summaries and issue-thread interaction behavior so planning work mode is preserved when creating suggested follow-up issues. - Added UI support for planning-mode issue creation, issue rows, detail composer styling, and composer work-mode toggles. - Added focused server/shared/UI tests plus a Playwright visual verification spec for planning-mode surfaces. - Rebased the branch onto current `public-gh/master` and added durable planning-mode screenshots under `doc/assets/pap-3368/`. ## Verification - `pnpm --filter @paperclipai/db run check:migrations` - `pnpm exec vitest run --project @paperclipai/shared packages/shared/src/validators/issue.test.ts` - `pnpm exec vitest run --project @paperclipai/server server/src/__tests__/heartbeat-context-summary.test.ts server/src/__tests__/issue-thread-interactions-service.test.ts server/src/__tests__/issues-goal-context-routes.test.ts --pool=forks --poolOptions.forks.isolate=true` - `pnpm exec vitest run --project @paperclipai/ui ui/src/components/IssueChatThread.test.tsx ui/src/components/NewIssueDialog.test.tsx ui/src/components/IssueRow.test.tsx ui/src/pages/IssueDetail.test.tsx` - `pnpm exec vitest run --project @paperclipai/adapter-utils packages/adapter-utils/src/server-utils.test.ts` - `PAPERCLIP_E2E_SKIP_LLM=true npx playwright test --config tests/e2e/playwright.config.ts tests/e2e/planning-mode-visual-verification.spec.ts` ## Screenshots Desktop planning detail: ![Desktop planning detail](https://raw.githubusercontent.com/paperclipai/paperclip/PAP-3368-plan-a-planning-mode-for-issues/doc/assets/pap-3368/desktop-planning-detail.png) Desktop planning row: ![Desktop planning row](https://raw.githubusercontent.com/paperclipai/paperclip/PAP-3368-plan-a-planning-mode-for-issues/doc/assets/pap-3368/desktop-planning-row.png) Desktop staged standard toggle: ![Desktop staged standard toggle](https://raw.githubusercontent.com/paperclipai/paperclip/PAP-3368-plan-a-planning-mode-for-issues/doc/assets/pap-3368/desktop-standard-toggle.png) Mobile planning detail: ![Mobile planning detail](https://raw.githubusercontent.com/paperclipai/paperclip/PAP-3368-plan-a-planning-mode-for-issues/doc/assets/pap-3368/mobile-planning-detail.png) Mobile planning row: ![Mobile planning row](https://raw.githubusercontent.com/paperclipai/paperclip/PAP-3368-plan-a-planning-mode-for-issues/doc/assets/pap-3368/mobile-planning-row.png) ## Risks - Medium migration risk: this adds a non-null issue column. The migration uses `ADD COLUMN IF NOT EXISTS` so installations that applied an older branch-local migration number can still apply the final numbered migration safely. - Medium contract risk: issue payloads, plugin payloads, and adapter heartbeat payloads now include work mode; compatibility is handled by defaulting missing values to `standard`. - UI risk is moderate because composer controls changed; focused component tests and visual e2e coverage exercise standard vs planning display and toggle behavior. > For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and discuss it in `#dev` before opening the PR. Feature PRs that overlap with planned core work may need to be redirected — check the roadmap first. See `CONTRIBUTING.md`. ## Model Used - OpenAI Codex, GPT-5 coding agent in a local Paperclip worktree, with shell/tool use. Exact context-window size is not exposed in this runtime. ## 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 run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-05-06 07:01:28 -05:00
if (issueWorkMode) env.PAPERCLIP_ISSUE_WORK_MODE = issueWorkMode;
Add ACPX local adapter runtime (#4893) ## Thinking Path > - Paperclip orchestrates AI-agent companies through a control plane that can start, supervise, and recover agent runs. > - Local adapters are the bridge between Paperclip issues and concrete agent runtimes such as Claude, Codex, and other ACP-compatible tools. > - The roadmap calls out broader “bring your own agent” and claw-style agent support, and ACPX gives Paperclip one path to normalize multiple ACP agents behind a single adapter. > - The branch needed to become one reviewable PR against current `paperclipai/paperclip:master`, without carrying stale base conflicts or generated lockfile churn. > - This pull request adds an experimental built-in `acpx_local` adapter, integrates it through the server/CLI/UI adapter surfaces, and adds regression coverage for runtime execution, skill sync, stream parsing, diagnostics, and log redaction. > - The benefit is that Paperclip can run Claude/Codex/custom ACP agents through ACPX while keeping operator configuration, skills, logging, and transcript rendering inside the existing adapter model. ## What Changed - Added `@paperclipai/adapter-acpx-local` with server execution, config schema, ACPX session handling, CLI formatting, UI config helpers, and stdout parsing. - Registered `acpx_local` across CLI, server, shared constants, UI adapter metadata, adapter capabilities, and agent creation/editing surfaces. - Added ACPX runtime execution support with persistent sessions, local-agent JWT environment handling, skill snapshots, runtime skill materialization, and isolation/security regressions. - Added ACPX adapter diagnostics and marked the adapter experimental in the UI. - Added command/env secret redaction for resolved command metadata in adapter-utils, server event storage, and the Agent Detail invocation UI. - Added Storybook coverage for ACPX config, transcript rendering, and skill states, plus PR screenshots under `docs/pr-screenshots/pap-2944/`. - Rebased the branch onto current `public-gh/master`; `pnpm-lock.yaml` is intentionally not included and there are no migration/schema changes. ## Verification - `pnpm exec vitest run packages/adapters/acpx-local/src/server/execute.test.ts packages/adapters/acpx-local/src/server/test.test.ts packages/adapters/acpx-local/src/cli/format-event.test.ts packages/adapters/acpx-local/src/ui/parse-stdout.test.ts packages/adapter-utils/src/server-utils.test.ts server/src/__tests__/redaction.test.ts server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/acpx-local-skill-sync.test.ts server/src/__tests__/acpx-local-adapter-environment.test.ts server/src/__tests__/adapter-routes.test.ts server/src/__tests__/agent-skills-routes.test.ts ui/src/adapters/metadata.test.ts` — 12 files, 87 tests passed. - `pnpm --filter @paperclipai/adapter-acpx-local typecheck` — passed. - `pnpm --filter @paperclipai/server typecheck` — passed. - `pnpm --filter @paperclipai/ui typecheck` — passed. - Confirmed PR diff does not include `pnpm-lock.yaml`, database schema files, or migrations. Screenshots: ![ACPX Claude skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-light.png?raw=true) ![ACPX Claude skills dark](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-dark.png?raw=true) ![ACPX custom skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-custom-light.png?raw=true) ## Risks - Medium risk: this introduces a new built-in adapter package and touches runtime execution, adapter registration, agent config, skills, and transcript rendering. - ACPX and ACP agent behavior can vary by installed tool versions; the adapter is marked experimental to set operator expectations. - `pnpm-lock.yaml` is excluded per repository PR policy, so dependency lock refresh must be handled by the repo’s automation or maintainers. - No database migration risk: no schema or migration files changed. > 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 coding agent based on GPT-5, with repository tool use, shell execution, git operations, and local verification. Exact hosted context window was not exposed in this environment. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-30 19:57:05 -05:00
if (wakeReason) env.PAPERCLIP_WAKE_REASON = wakeReason;
if (wakeCommentId) env.PAPERCLIP_WAKE_COMMENT_ID = wakeCommentId;
if (approvalId) env.PAPERCLIP_APPROVAL_ID = approvalId;
if (approvalStatus) env.PAPERCLIP_APPROVAL_STATUS = approvalStatus;
if (linkedIssueIds.length > 0) env.PAPERCLIP_LINKED_ISSUE_IDS = linkedIssueIds.join(",");
if (wakePayloadJson) env.PAPERCLIP_WAKE_PAYLOAD_JSON = wakePayloadJson;
applyPaperclipWorkspaceEnv(env, {
Fix remote workspace environment shaping (#5118) > **Stacked PR (part 5 of 7).** Depends on: - PR #5114 - PR #5115 - PR #5116 - PR #5117 > Diff against `master` includes commits from earlier PRs in the stack — the new commit in this PR is the topmost one. ## Thinking Path > - Paperclip orchestrates AI agents for zero-human companies > - Agents run with a Paperclip-shaped environment (`PAPERCLIP_WORKSPACE_CWD`, > worktree path, `PAPERCLIP_WORKSPACES_JSON` hints) so the CLI can locate the > correct project tree > - SSH testing reproduced a real failure: a Codex SSH run wrote to > `/tmp/paperclip-env-matrix-...` (the *host* path) instead of the realized > remote workspace at `/home/<user>/paperclip-env-matrix-ssh-claude/...` > because the adapter injected `PAPERCLIP_WORKSPACE_CWD=/tmp/...` into the > remote env > - Code review on the initial codex-only fix asked to roll the same approach > into every other SSH-capable adapter (claude, acpx, cursor, opencode, gemini, > pi) via a shared helper rather than duplicating per-adapter > - This PR adds `shapePaperclipWorkspaceEnvForExecution` in adapter-utils that, > when the execution target is remote: replaces local cwd with the realized > execution cwd, nulls out worktree path (which has no remote meaning), and > rewrites/strips `cwd` entries in workspace hints based on what was actually > synced. Every adapter calls it before invoking the remote runner > - The benefit is that remote runs see the realized remote workspace, host-local > paths stop leaking into remote env, and the rule is unit-tested in one place ## What Changed - Added `shapePaperclipWorkspaceEnvForExecution` to `packages/adapter-utils/src/server-utils.ts` with full unit coverage (`server-utils.test.ts`) - Each of acpx-local, claude-local, codex-local, cursor-local, gemini-local, opencode-local, pi-local now calls the new shaper before issuing the remote command and feeds the shaped values into `applyPaperclipWorkspaceEnv` - Per-adapter `execute.remote.test.ts` files extended to cover the new shaping behaviour: localhost paths replaced with remote cwd, foreign-cwd hints stripped, worktree path nulled out for remote targets - `acpx-local/src/server/execute.test.ts` extended with shaping coverage ## Verification - `pnpm test -- server-utils execute.remote` - `pnpm --filter @paperclipai/adapter-acpx-local test` - Manual QA reproducing the original failure: 1. Provision an E2B sandbox environment for the Paperclip QA company 2. Assign an issue to a remote-targeted claude-local agent and confirm the run starts in the correct remote cwd (no `/Users/...` path leakage in the run logs) 3. Repeat for opencode-local and pi-local ## Risks - Behavioural shift: hints whose `cwd` doesn't match the workspace cwd are now stripped on remote targets. If any adapter relied on a leaked local hint cwd, it will see a missing `cwd` instead. Reviewed all current callers — none do. - Adds a small per-run cost (path resolve + string normalisation) on every remote execution. Negligible. - Worktree path is now nulled out on remote (it has no meaning there). Adapters that previously read the value defensively will continue to work. ## Model Used - OpenAI GPT-5.4 (reasoning effort: high) via Codex CLI - Provider: OpenAI - Used to author the code changes in this PR ## 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 run tests locally and they pass - [x] I have added or updated tests where applicable - [ ] If this change affects the UI, I have included before/after screenshots — N/A - [ ] I have updated relevant documentation to reflect my changes — N/A - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge
2026-05-03 13:17:52 -07:00
workspaceCwd: shapedWorkspaceEnv.workspaceCwd,
Add ACPX local adapter runtime (#4893) ## Thinking Path > - Paperclip orchestrates AI-agent companies through a control plane that can start, supervise, and recover agent runs. > - Local adapters are the bridge between Paperclip issues and concrete agent runtimes such as Claude, Codex, and other ACP-compatible tools. > - The roadmap calls out broader “bring your own agent” and claw-style agent support, and ACPX gives Paperclip one path to normalize multiple ACP agents behind a single adapter. > - The branch needed to become one reviewable PR against current `paperclipai/paperclip:master`, without carrying stale base conflicts or generated lockfile churn. > - This pull request adds an experimental built-in `acpx_local` adapter, integrates it through the server/CLI/UI adapter surfaces, and adds regression coverage for runtime execution, skill sync, stream parsing, diagnostics, and log redaction. > - The benefit is that Paperclip can run Claude/Codex/custom ACP agents through ACPX while keeping operator configuration, skills, logging, and transcript rendering inside the existing adapter model. ## What Changed - Added `@paperclipai/adapter-acpx-local` with server execution, config schema, ACPX session handling, CLI formatting, UI config helpers, and stdout parsing. - Registered `acpx_local` across CLI, server, shared constants, UI adapter metadata, adapter capabilities, and agent creation/editing surfaces. - Added ACPX runtime execution support with persistent sessions, local-agent JWT environment handling, skill snapshots, runtime skill materialization, and isolation/security regressions. - Added ACPX adapter diagnostics and marked the adapter experimental in the UI. - Added command/env secret redaction for resolved command metadata in adapter-utils, server event storage, and the Agent Detail invocation UI. - Added Storybook coverage for ACPX config, transcript rendering, and skill states, plus PR screenshots under `docs/pr-screenshots/pap-2944/`. - Rebased the branch onto current `public-gh/master`; `pnpm-lock.yaml` is intentionally not included and there are no migration/schema changes. ## Verification - `pnpm exec vitest run packages/adapters/acpx-local/src/server/execute.test.ts packages/adapters/acpx-local/src/server/test.test.ts packages/adapters/acpx-local/src/cli/format-event.test.ts packages/adapters/acpx-local/src/ui/parse-stdout.test.ts packages/adapter-utils/src/server-utils.test.ts server/src/__tests__/redaction.test.ts server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/acpx-local-skill-sync.test.ts server/src/__tests__/acpx-local-adapter-environment.test.ts server/src/__tests__/adapter-routes.test.ts server/src/__tests__/agent-skills-routes.test.ts ui/src/adapters/metadata.test.ts` — 12 files, 87 tests passed. - `pnpm --filter @paperclipai/adapter-acpx-local typecheck` — passed. - `pnpm --filter @paperclipai/server typecheck` — passed. - `pnpm --filter @paperclipai/ui typecheck` — passed. - Confirmed PR diff does not include `pnpm-lock.yaml`, database schema files, or migrations. Screenshots: ![ACPX Claude skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-light.png?raw=true) ![ACPX Claude skills dark](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-dark.png?raw=true) ![ACPX custom skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-custom-light.png?raw=true) ## Risks - Medium risk: this introduces a new built-in adapter package and touches runtime execution, adapter registration, agent config, skills, and transcript rendering. - ACPX and ACP agent behavior can vary by installed tool versions; the adapter is marked experimental to set operator expectations. - `pnpm-lock.yaml` is excluded per repository PR policy, so dependency lock refresh must be handled by the repo’s automation or maintainers. - No database migration risk: no schema or migration files changed. > 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 coding agent based on GPT-5, with repository tool use, shell execution, git operations, and local verification. Exact hosted context window was not exposed in this environment. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-30 19:57:05 -05:00
workspaceSource,
workspaceStrategy,
workspaceId,
workspaceRepoUrl,
workspaceRepoRef,
workspaceBranch,
Fix remote workspace environment shaping (#5118) > **Stacked PR (part 5 of 7).** Depends on: - PR #5114 - PR #5115 - PR #5116 - PR #5117 > Diff against `master` includes commits from earlier PRs in the stack — the new commit in this PR is the topmost one. ## Thinking Path > - Paperclip orchestrates AI agents for zero-human companies > - Agents run with a Paperclip-shaped environment (`PAPERCLIP_WORKSPACE_CWD`, > worktree path, `PAPERCLIP_WORKSPACES_JSON` hints) so the CLI can locate the > correct project tree > - SSH testing reproduced a real failure: a Codex SSH run wrote to > `/tmp/paperclip-env-matrix-...` (the *host* path) instead of the realized > remote workspace at `/home/<user>/paperclip-env-matrix-ssh-claude/...` > because the adapter injected `PAPERCLIP_WORKSPACE_CWD=/tmp/...` into the > remote env > - Code review on the initial codex-only fix asked to roll the same approach > into every other SSH-capable adapter (claude, acpx, cursor, opencode, gemini, > pi) via a shared helper rather than duplicating per-adapter > - This PR adds `shapePaperclipWorkspaceEnvForExecution` in adapter-utils that, > when the execution target is remote: replaces local cwd with the realized > execution cwd, nulls out worktree path (which has no remote meaning), and > rewrites/strips `cwd` entries in workspace hints based on what was actually > synced. Every adapter calls it before invoking the remote runner > - The benefit is that remote runs see the realized remote workspace, host-local > paths stop leaking into remote env, and the rule is unit-tested in one place ## What Changed - Added `shapePaperclipWorkspaceEnvForExecution` to `packages/adapter-utils/src/server-utils.ts` with full unit coverage (`server-utils.test.ts`) - Each of acpx-local, claude-local, codex-local, cursor-local, gemini-local, opencode-local, pi-local now calls the new shaper before issuing the remote command and feeds the shaped values into `applyPaperclipWorkspaceEnv` - Per-adapter `execute.remote.test.ts` files extended to cover the new shaping behaviour: localhost paths replaced with remote cwd, foreign-cwd hints stripped, worktree path nulled out for remote targets - `acpx-local/src/server/execute.test.ts` extended with shaping coverage ## Verification - `pnpm test -- server-utils execute.remote` - `pnpm --filter @paperclipai/adapter-acpx-local test` - Manual QA reproducing the original failure: 1. Provision an E2B sandbox environment for the Paperclip QA company 2. Assign an issue to a remote-targeted claude-local agent and confirm the run starts in the correct remote cwd (no `/Users/...` path leakage in the run logs) 3. Repeat for opencode-local and pi-local ## Risks - Behavioural shift: hints whose `cwd` doesn't match the workspace cwd are now stripped on remote targets. If any adapter relied on a leaked local hint cwd, it will see a missing `cwd` instead. Reviewed all current callers — none do. - Adds a small per-run cost (path resolve + string normalisation) on every remote execution. Negligible. - Worktree path is now nulled out on remote (it has no meaning there). Adapters that previously read the value defensively will continue to work. ## Model Used - OpenAI GPT-5.4 (reasoning effort: high) via Codex CLI - Provider: OpenAI - Used to author the code changes in this PR ## 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 run tests locally and they pass - [x] I have added or updated tests where applicable - [ ] If this change affects the UI, I have included before/after screenshots — N/A - [ ] I have updated relevant documentation to reflect my changes — N/A - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge
2026-05-03 13:17:52 -07:00
workspaceWorktreePath: shapedWorkspaceEnv.workspaceWorktreePath,
Add ACPX local adapter runtime (#4893) ## Thinking Path > - Paperclip orchestrates AI-agent companies through a control plane that can start, supervise, and recover agent runs. > - Local adapters are the bridge between Paperclip issues and concrete agent runtimes such as Claude, Codex, and other ACP-compatible tools. > - The roadmap calls out broader “bring your own agent” and claw-style agent support, and ACPX gives Paperclip one path to normalize multiple ACP agents behind a single adapter. > - The branch needed to become one reviewable PR against current `paperclipai/paperclip:master`, without carrying stale base conflicts or generated lockfile churn. > - This pull request adds an experimental built-in `acpx_local` adapter, integrates it through the server/CLI/UI adapter surfaces, and adds regression coverage for runtime execution, skill sync, stream parsing, diagnostics, and log redaction. > - The benefit is that Paperclip can run Claude/Codex/custom ACP agents through ACPX while keeping operator configuration, skills, logging, and transcript rendering inside the existing adapter model. ## What Changed - Added `@paperclipai/adapter-acpx-local` with server execution, config schema, ACPX session handling, CLI formatting, UI config helpers, and stdout parsing. - Registered `acpx_local` across CLI, server, shared constants, UI adapter metadata, adapter capabilities, and agent creation/editing surfaces. - Added ACPX runtime execution support with persistent sessions, local-agent JWT environment handling, skill snapshots, runtime skill materialization, and isolation/security regressions. - Added ACPX adapter diagnostics and marked the adapter experimental in the UI. - Added command/env secret redaction for resolved command metadata in adapter-utils, server event storage, and the Agent Detail invocation UI. - Added Storybook coverage for ACPX config, transcript rendering, and skill states, plus PR screenshots under `docs/pr-screenshots/pap-2944/`. - Rebased the branch onto current `public-gh/master`; `pnpm-lock.yaml` is intentionally not included and there are no migration/schema changes. ## Verification - `pnpm exec vitest run packages/adapters/acpx-local/src/server/execute.test.ts packages/adapters/acpx-local/src/server/test.test.ts packages/adapters/acpx-local/src/cli/format-event.test.ts packages/adapters/acpx-local/src/ui/parse-stdout.test.ts packages/adapter-utils/src/server-utils.test.ts server/src/__tests__/redaction.test.ts server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/acpx-local-skill-sync.test.ts server/src/__tests__/acpx-local-adapter-environment.test.ts server/src/__tests__/adapter-routes.test.ts server/src/__tests__/agent-skills-routes.test.ts ui/src/adapters/metadata.test.ts` — 12 files, 87 tests passed. - `pnpm --filter @paperclipai/adapter-acpx-local typecheck` — passed. - `pnpm --filter @paperclipai/server typecheck` — passed. - `pnpm --filter @paperclipai/ui typecheck` — passed. - Confirmed PR diff does not include `pnpm-lock.yaml`, database schema files, or migrations. Screenshots: ![ACPX Claude skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-light.png?raw=true) ![ACPX Claude skills dark](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-dark.png?raw=true) ![ACPX custom skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-custom-light.png?raw=true) ## Risks - Medium risk: this introduces a new built-in adapter package and touches runtime execution, adapter registration, agent config, skills, and transcript rendering. - ACPX and ACP agent behavior can vary by installed tool versions; the adapter is marked experimental to set operator expectations. - `pnpm-lock.yaml` is excluded per repository PR policy, so dependency lock refresh must be handled by the repo’s automation or maintainers. - No database migration risk: no schema or migration files changed. > 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 coding agent based on GPT-5, with repository tool use, shell execution, git operations, and local verification. Exact hosted context window was not exposed in this environment. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-30 19:57:05 -05:00
agentHome,
});
Harden remote workspace sync and restore flows (#5444) ## Thinking Path > - Paperclip orchestrates AI agents for zero-human companies > - When an agent runs against a remote target, Paperclip syncs the workspace out to the remote at run start and restores changes back to the local workspace at run end > - The previous restore flow naïvely overwrote local files with whatever the remote returned, so files that the remote run never touched but had timestamp/mode drift could be needlessly rewritten — and a single static `refs/paperclip/ssh-sync/imported` ref made concurrent SSH workspace exports race on the same git ref > - This pull request adds a `workspace-restore-merge` module that diffs a pre-run snapshot against the post-run remote state and only writes back files the remote actually changed; SSH workspace exports now use a per-import unique ref so concurrent runs can't trample each other > - Every adapter's execute path threads the snapshot through `prepareAdapterExecutionTargetRuntime` so the merge has the baseline it needs > - The benefit is workspace restores no longer churn untouched files, and concurrent SSH runs no longer collide on the import ref ## What Changed - `packages/adapter-utils/src/workspace-restore-merge.{ts,test.ts}`: new module — directory snapshot (kind/mode/sha256/symlink target) plus snapshot-aware merge that writes only the files the remote changed - `packages/adapter-utils/src/ssh.ts`: SSH workspace export uses a per-import unique ref (`refs/paperclip/ssh-sync/imported/<uuid>`); restore goes through the new merge helper; `ssh-fixture.test.ts` covers the unique-ref + merge paths - `packages/adapter-utils/src/sandbox-managed-runtime.ts` + `remote-managed-runtime.ts`: thread the snapshot/merge through the sandbox and SSH paths - `packages/adapter-utils/src/server-utils.{ts,test.ts}` + `execution-target.ts`: helpers for capturing the pre-run snapshot; `prepareAdapterExecutionTargetRuntime` gains required `runId` and optional `workspaceRemoteDir`, and returns the realized `workspaceRemoteDir` - Each adapter's `execute.ts` (acpx, claude, codex, cursor, gemini, opencode, pi) takes the snapshot at run start and passes it through to the runtime restore - Remote execute test mocks updated to match the new `prepareWorkspaceForSshExecution` return shape and the per-run `${managedRemoteWorkspace}` cwd subdirectory ## Verification - `pnpm vitest run --no-coverage --project @paperclipai/adapter-utils --project @paperclipai/adapter-acpx-local --project @paperclipai/adapter-claude-local --project @paperclipai/adapter-codex-local --project @paperclipai/adapter-cursor-local --project @paperclipai/adapter-gemini-local --project @paperclipai/adapter-opencode-local --project @paperclipai/adapter-pi-local` — 196/196 passing - `pnpm typecheck` clean across the workspace ## Risks Medium. The restore path now writes a strict subset of what it previously did — files the remote did not touch are no longer rewritten. If any flow was relying on a touch-without-content-change being copied back (timestamp or permission propagation only), that behavior is now skipped. Snapshot capture adds an O(N-files-in-workspace) hash pass at run start; the cost is bounded by the existing exclude list. The `runId` parameter on `prepareAdapterExecutionTargetRuntime` is now required — every in-tree caller is updated; out-of-tree adapter authors need to pass it. ## Model Used Claude Opus 4.7 (1M context) ## 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 run tests locally and they pass - [x] I have added or updated tests where applicable — new module + every adapter execute path covered - [x] If this change affects the UI, I have included before/after screenshots — N/A (no UI) - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge
2026-05-07 14:44:45 -07:00
const shapedEnvConfig = rewriteWorkspaceCwdEnvVarsForExecution({
env: envConfig,
workspaceCwd: effectiveWorkspaceCwd,
executionCwd: shapedWorkspaceEnv.workspaceCwd,
executionTargetIsRemote,
});
for (const [key, value] of Object.entries(shapedEnvConfig)) {
Add ACPX local adapter runtime (#4893) ## Thinking Path > - Paperclip orchestrates AI-agent companies through a control plane that can start, supervise, and recover agent runs. > - Local adapters are the bridge between Paperclip issues and concrete agent runtimes such as Claude, Codex, and other ACP-compatible tools. > - The roadmap calls out broader “bring your own agent” and claw-style agent support, and ACPX gives Paperclip one path to normalize multiple ACP agents behind a single adapter. > - The branch needed to become one reviewable PR against current `paperclipai/paperclip:master`, without carrying stale base conflicts or generated lockfile churn. > - This pull request adds an experimental built-in `acpx_local` adapter, integrates it through the server/CLI/UI adapter surfaces, and adds regression coverage for runtime execution, skill sync, stream parsing, diagnostics, and log redaction. > - The benefit is that Paperclip can run Claude/Codex/custom ACP agents through ACPX while keeping operator configuration, skills, logging, and transcript rendering inside the existing adapter model. ## What Changed - Added `@paperclipai/adapter-acpx-local` with server execution, config schema, ACPX session handling, CLI formatting, UI config helpers, and stdout parsing. - Registered `acpx_local` across CLI, server, shared constants, UI adapter metadata, adapter capabilities, and agent creation/editing surfaces. - Added ACPX runtime execution support with persistent sessions, local-agent JWT environment handling, skill snapshots, runtime skill materialization, and isolation/security regressions. - Added ACPX adapter diagnostics and marked the adapter experimental in the UI. - Added command/env secret redaction for resolved command metadata in adapter-utils, server event storage, and the Agent Detail invocation UI. - Added Storybook coverage for ACPX config, transcript rendering, and skill states, plus PR screenshots under `docs/pr-screenshots/pap-2944/`. - Rebased the branch onto current `public-gh/master`; `pnpm-lock.yaml` is intentionally not included and there are no migration/schema changes. ## Verification - `pnpm exec vitest run packages/adapters/acpx-local/src/server/execute.test.ts packages/adapters/acpx-local/src/server/test.test.ts packages/adapters/acpx-local/src/cli/format-event.test.ts packages/adapters/acpx-local/src/ui/parse-stdout.test.ts packages/adapter-utils/src/server-utils.test.ts server/src/__tests__/redaction.test.ts server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/acpx-local-skill-sync.test.ts server/src/__tests__/acpx-local-adapter-environment.test.ts server/src/__tests__/adapter-routes.test.ts server/src/__tests__/agent-skills-routes.test.ts ui/src/adapters/metadata.test.ts` — 12 files, 87 tests passed. - `pnpm --filter @paperclipai/adapter-acpx-local typecheck` — passed. - `pnpm --filter @paperclipai/server typecheck` — passed. - `pnpm --filter @paperclipai/ui typecheck` — passed. - Confirmed PR diff does not include `pnpm-lock.yaml`, database schema files, or migrations. Screenshots: ![ACPX Claude skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-light.png?raw=true) ![ACPX Claude skills dark](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-dark.png?raw=true) ![ACPX custom skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-custom-light.png?raw=true) ## Risks - Medium risk: this introduces a new built-in adapter package and touches runtime execution, adapter registration, agent config, skills, and transcript rendering. - ACPX and ACP agent behavior can vary by installed tool versions; the adapter is marked experimental to set operator expectations. - `pnpm-lock.yaml` is excluded per repository PR policy, so dependency lock refresh must be handled by the repo’s automation or maintainers. - No database migration risk: no schema or migration files changed. > 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 coding agent based on GPT-5, with repository tool use, shell execution, git operations, and local verification. Exact hosted context window was not exposed in this environment. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-30 19:57:05 -05:00
if (typeof value === "string") env[key] = value;
}
if (!hasExplicitApiKey && authToken) env.PAPERCLIP_API_KEY = authToken;
Make ACPX-Claude adapter work seamlessly (PAPA-388) (#6590) ## Thinking Path > - Paperclip orchestrates AI agents for zero-human companies, so when an adapter fails, the platform must surface enough detail for the next agent (or human reviewer) to act > - The `acpx_local` adapter wraps `claude-agent-acp`, which in turn drives the Claude Code SDK — three layers, three different permission and error-handling models > - A user created a `Claude Local ACPX` agent in PAPA-387 and it failed instantly with the generic `acpx.error / "Internal error"` log, stranding the work and triggering an opaque `stranded_assigned_issue` recovery to the CTO > - Once the diagnostic blackbox was opened, the underlying cause turned out to be two SDK-level mismatches: a model-name allowlist that rejects bare IDs like `claude-opus-4-7`, and a Claude Code permission/Read-sandbox configuration that silently denies every non-allowlisted tool when the user's `~/.claude/settings.json` has `defaultMode: "dontAsk"` > - This pull request fixes both classes of failure in the adapter itself so new ACPX agents work seamlessly without per-host configuration, and widens the diagnostic surface so the *next* failure of any kind is actionable > - The benefit is that ACPX-Claude can join the regular agent roster — verified end to end on PAPA-401, where the agent successfully reached the Paperclip API, opened a worktree, surveyed existing notification PRs, and posted a structured plan ## What Changed - Widen ACPX failure diagnostics (`packages/adapters/acpx-local/src/server/execute.ts`): - Capture `err.name`, ACP code, `cause.message`, retryable flag, and a 5-frame stack preview into `errorMeta`. - Promote phase-specific error codes: `ensure_session → acpx_session_init_failed`, `configure_session → acpx_session_config_failed`, `turn → acpx_turn_failed`, plus mapping for `ACP_BACKEND_MISSING` / `ACP_BACKEND_UNAVAILABLE`. - Set `verbose: true` on the ACPX runtime so its session-event log flows through `ctx.onLog`. - Capture child-process stderr via a wrapper-script tee into `<stateDir>/run-stderr/<runId>.log`, inline the tail into the `acpx.error` payload as `childStderrTail`, and forward it through `ctx.onLog("stderr", …)` so it lands in the heartbeat `stderrExcerpt` column (existing redaction applies). - Set the model via `ANTHROPIC_MODEL` env for the `claude` agent instead of `set_config_option(model, …)`. The ACP server's `set_config_option` handler validates against an internal allowlist and rejects bare IDs like `claude-opus-4-7`. `ANTHROPIC_MODEL` is read during initialization and bypasses that check. - Seed `<worktree>/.claude/settings.local.json` before spawning `claude-agent-acp` (the seamless-API fix). Since `claude-agent-acp` hard-codes `settingSources: ["user", "project", "local"]` and "local" has the highest precedence: - Set `permissions.defaultMode: "default"`, but **only** if the user's value is missing or `"dontAsk"` (the broken case). Other modes like `acceptEdits`/`plan` are preserved. - Pre-allow Paperclip's Bash surface (`Bash(curl:*)`, `Bash(env:*)`, `Bash(<cwd>/scripts/paperclip-issue-update.sh:*)`, `Bash(<cwd>/scripts/paperclip:*)`). - Widen `permissions.additionalDirectories` to include `stateDir`, `agentHome`, and the per-company instance root (`~/.paperclip/instances/<id>/companies/<companyId>`). Scoped to this company only — does not expose other tenants. - Existing user entries are merged, not replaced. The resolved roots are folded into the session fingerprint so warm-session handles invalidate when they change. - Sync the existing server-side integration test (`server/src/__tests__/acpx-local-execute.test.ts`) to assert `acpx_session_init_failed` instead of the now-removed `acpx_protocol_error` for `ACP_SESSION_INIT_FAILED` (a follow-up to commit 1). ## Verification - `pnpm --filter "@paperclipai/adapter-acpx-local" run typecheck` — passes. - `pnpm vitest run` in `packages/adapters/acpx-local` — 35/35 pass, includes 4 new tests covering the settings.local.json write path (claude only, merge with pre-existing content, `dontAsk` override, codex no-op). - `pnpm vitest run src/__tests__/acpx-local-execute.test.ts` in `server/` — 15/15 pass after the test-sync commit. - End-to-end manual verification (PAPA-401): the `Claude Local ACPX` agent that previously hit "restricted environment" now successfully reaches the Paperclip API, opens its worktree, posts structured plan comments, and flips the issue to `in_review` without any external configuration. ## Risks - **Low**, scoped to the `acpx_local` adapter. The settings.local.json write is per-worktree (worktrees live under `.paperclip/worktrees/<issue>/`) and only triggers when `acpxAgent === "claude"`. Existing user content is merged with `[...existing, ...paperclip]` and deduped — nothing is overwritten outright. - The `defaultMode` override is intentionally narrow: it only flips `"dontAsk"` (which silently denies every tool and is the root cause) to `"default"`. Users who explicitly picked `acceptEdits`, `plan`, or any other mode keep their choice. - Stderr capture goes through the existing `log-redaction` pass before persisting, so `PAPERCLIP_API_KEY` and similar secrets in the wrapper env don't leak into heartbeat logs. > 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 4.7 (`claude-opus-4-7`), running in the `claude_local` adapter via Paperclip's harness. Extended thinking enabled, tool use enabled. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [ ] If this change affects the UI, I have included before/after screenshots — N/A (adapter-only) - [ ] I have updated relevant documentation to reflect my changes — no user-facing docs changed; internal commentary in the code change explains the SDK constraints - [x] I have considered and documented any risks above - [ ] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-05-23 13:01:27 -07:00
// For the claude agent, set model via ANTHROPIC_MODEL at startup rather than
// via session/set_config_option — the ACP server's set_config_option handler
// validates the value against its internal available-models list and rejects
// bare model IDs (e.g. "claude-opus-4-7") that don't exactly match a model
// entry in some versions. ANTHROPIC_MODEL is read during initialization, so
// it reliably sets the model before any turns are run.
if (requestedModel && acpxAgent === "claude" && !env.ANTHROPIC_MODEL) {
env.ANTHROPIC_MODEL = requestedModel;
}
Add ACPX local adapter runtime (#4893) ## Thinking Path > - Paperclip orchestrates AI-agent companies through a control plane that can start, supervise, and recover agent runs. > - Local adapters are the bridge between Paperclip issues and concrete agent runtimes such as Claude, Codex, and other ACP-compatible tools. > - The roadmap calls out broader “bring your own agent” and claw-style agent support, and ACPX gives Paperclip one path to normalize multiple ACP agents behind a single adapter. > - The branch needed to become one reviewable PR against current `paperclipai/paperclip:master`, without carrying stale base conflicts or generated lockfile churn. > - This pull request adds an experimental built-in `acpx_local` adapter, integrates it through the server/CLI/UI adapter surfaces, and adds regression coverage for runtime execution, skill sync, stream parsing, diagnostics, and log redaction. > - The benefit is that Paperclip can run Claude/Codex/custom ACP agents through ACPX while keeping operator configuration, skills, logging, and transcript rendering inside the existing adapter model. ## What Changed - Added `@paperclipai/adapter-acpx-local` with server execution, config schema, ACPX session handling, CLI formatting, UI config helpers, and stdout parsing. - Registered `acpx_local` across CLI, server, shared constants, UI adapter metadata, adapter capabilities, and agent creation/editing surfaces. - Added ACPX runtime execution support with persistent sessions, local-agent JWT environment handling, skill snapshots, runtime skill materialization, and isolation/security regressions. - Added ACPX adapter diagnostics and marked the adapter experimental in the UI. - Added command/env secret redaction for resolved command metadata in adapter-utils, server event storage, and the Agent Detail invocation UI. - Added Storybook coverage for ACPX config, transcript rendering, and skill states, plus PR screenshots under `docs/pr-screenshots/pap-2944/`. - Rebased the branch onto current `public-gh/master`; `pnpm-lock.yaml` is intentionally not included and there are no migration/schema changes. ## Verification - `pnpm exec vitest run packages/adapters/acpx-local/src/server/execute.test.ts packages/adapters/acpx-local/src/server/test.test.ts packages/adapters/acpx-local/src/cli/format-event.test.ts packages/adapters/acpx-local/src/ui/parse-stdout.test.ts packages/adapter-utils/src/server-utils.test.ts server/src/__tests__/redaction.test.ts server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/acpx-local-skill-sync.test.ts server/src/__tests__/acpx-local-adapter-environment.test.ts server/src/__tests__/adapter-routes.test.ts server/src/__tests__/agent-skills-routes.test.ts ui/src/adapters/metadata.test.ts` — 12 files, 87 tests passed. - `pnpm --filter @paperclipai/adapter-acpx-local typecheck` — passed. - `pnpm --filter @paperclipai/server typecheck` — passed. - `pnpm --filter @paperclipai/ui typecheck` — passed. - Confirmed PR diff does not include `pnpm-lock.yaml`, database schema files, or migrations. Screenshots: ![ACPX Claude skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-light.png?raw=true) ![ACPX Claude skills dark](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-dark.png?raw=true) ![ACPX custom skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-custom-light.png?raw=true) ## Risks - Medium risk: this introduces a new built-in adapter package and touches runtime execution, adapter registration, agent config, skills, and transcript rendering. - ACPX and ACP agent behavior can vary by installed tool versions; the adapter is marked experimental to set operator expectations. - `pnpm-lock.yaml` is excluded per repository PR policy, so dependency lock refresh must be handled by the repo’s automation or maintainers. - No database migration risk: no schema or migration files changed. > 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 coding agent based on GPT-5, with repository tool use, shell execution, git operations, and local verification. Exact hosted context window was not exposed in this environment. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-30 19:57:05 -05:00
let skillPromptInstructions = "";
let skillsIdentity: Record<string, unknown> = { mode: "unsupported" };
const skillCommandNotes: string[] = [];
Make ACPX-Claude adapter work seamlessly (PAPA-388) (#6590) ## Thinking Path > - Paperclip orchestrates AI agents for zero-human companies, so when an adapter fails, the platform must surface enough detail for the next agent (or human reviewer) to act > - The `acpx_local` adapter wraps `claude-agent-acp`, which in turn drives the Claude Code SDK — three layers, three different permission and error-handling models > - A user created a `Claude Local ACPX` agent in PAPA-387 and it failed instantly with the generic `acpx.error / "Internal error"` log, stranding the work and triggering an opaque `stranded_assigned_issue` recovery to the CTO > - Once the diagnostic blackbox was opened, the underlying cause turned out to be two SDK-level mismatches: a model-name allowlist that rejects bare IDs like `claude-opus-4-7`, and a Claude Code permission/Read-sandbox configuration that silently denies every non-allowlisted tool when the user's `~/.claude/settings.json` has `defaultMode: "dontAsk"` > - This pull request fixes both classes of failure in the adapter itself so new ACPX agents work seamlessly without per-host configuration, and widens the diagnostic surface so the *next* failure of any kind is actionable > - The benefit is that ACPX-Claude can join the regular agent roster — verified end to end on PAPA-401, where the agent successfully reached the Paperclip API, opened a worktree, surveyed existing notification PRs, and posted a structured plan ## What Changed - Widen ACPX failure diagnostics (`packages/adapters/acpx-local/src/server/execute.ts`): - Capture `err.name`, ACP code, `cause.message`, retryable flag, and a 5-frame stack preview into `errorMeta`. - Promote phase-specific error codes: `ensure_session → acpx_session_init_failed`, `configure_session → acpx_session_config_failed`, `turn → acpx_turn_failed`, plus mapping for `ACP_BACKEND_MISSING` / `ACP_BACKEND_UNAVAILABLE`. - Set `verbose: true` on the ACPX runtime so its session-event log flows through `ctx.onLog`. - Capture child-process stderr via a wrapper-script tee into `<stateDir>/run-stderr/<runId>.log`, inline the tail into the `acpx.error` payload as `childStderrTail`, and forward it through `ctx.onLog("stderr", …)` so it lands in the heartbeat `stderrExcerpt` column (existing redaction applies). - Set the model via `ANTHROPIC_MODEL` env for the `claude` agent instead of `set_config_option(model, …)`. The ACP server's `set_config_option` handler validates against an internal allowlist and rejects bare IDs like `claude-opus-4-7`. `ANTHROPIC_MODEL` is read during initialization and bypasses that check. - Seed `<worktree>/.claude/settings.local.json` before spawning `claude-agent-acp` (the seamless-API fix). Since `claude-agent-acp` hard-codes `settingSources: ["user", "project", "local"]` and "local" has the highest precedence: - Set `permissions.defaultMode: "default"`, but **only** if the user's value is missing or `"dontAsk"` (the broken case). Other modes like `acceptEdits`/`plan` are preserved. - Pre-allow Paperclip's Bash surface (`Bash(curl:*)`, `Bash(env:*)`, `Bash(<cwd>/scripts/paperclip-issue-update.sh:*)`, `Bash(<cwd>/scripts/paperclip:*)`). - Widen `permissions.additionalDirectories` to include `stateDir`, `agentHome`, and the per-company instance root (`~/.paperclip/instances/<id>/companies/<companyId>`). Scoped to this company only — does not expose other tenants. - Existing user entries are merged, not replaced. The resolved roots are folded into the session fingerprint so warm-session handles invalidate when they change. - Sync the existing server-side integration test (`server/src/__tests__/acpx-local-execute.test.ts`) to assert `acpx_session_init_failed` instead of the now-removed `acpx_protocol_error` for `ACP_SESSION_INIT_FAILED` (a follow-up to commit 1). ## Verification - `pnpm --filter "@paperclipai/adapter-acpx-local" run typecheck` — passes. - `pnpm vitest run` in `packages/adapters/acpx-local` — 35/35 pass, includes 4 new tests covering the settings.local.json write path (claude only, merge with pre-existing content, `dontAsk` override, codex no-op). - `pnpm vitest run src/__tests__/acpx-local-execute.test.ts` in `server/` — 15/15 pass after the test-sync commit. - End-to-end manual verification (PAPA-401): the `Claude Local ACPX` agent that previously hit "restricted environment" now successfully reaches the Paperclip API, opens its worktree, posts structured plan comments, and flips the issue to `in_review` without any external configuration. ## Risks - **Low**, scoped to the `acpx_local` adapter. The settings.local.json write is per-worktree (worktrees live under `.paperclip/worktrees/<issue>/`) and only triggers when `acpxAgent === "claude"`. Existing user content is merged with `[...existing, ...paperclip]` and deduped — nothing is overwritten outright. - The `defaultMode` override is intentionally narrow: it only flips `"dontAsk"` (which silently denies every tool and is the root cause) to `"default"`. Users who explicitly picked `acceptEdits`, `plan`, or any other mode keep their choice. - Stderr capture goes through the existing `log-redaction` pass before persisting, so `PAPERCLIP_API_KEY` and similar secrets in the wrapper env don't leak into heartbeat logs. > 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 4.7 (`claude-opus-4-7`), running in the `claude_local` adapter via Paperclip's harness. Extended thinking enabled, tool use enabled. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [ ] If this change affects the UI, I have included before/after screenshots — N/A (adapter-only) - [ ] I have updated relevant documentation to reflect my changes — no user-facing docs changed; internal commentary in the code change explains the SDK constraints - [x] I have considered and documented any risks above - [ ] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-05-23 13:01:27 -07:00
let paperclipClaudeSettings: PaperclipClaudeSettingsResult | null = null;
Add ACPX local adapter runtime (#4893) ## Thinking Path > - Paperclip orchestrates AI-agent companies through a control plane that can start, supervise, and recover agent runs. > - Local adapters are the bridge between Paperclip issues and concrete agent runtimes such as Claude, Codex, and other ACP-compatible tools. > - The roadmap calls out broader “bring your own agent” and claw-style agent support, and ACPX gives Paperclip one path to normalize multiple ACP agents behind a single adapter. > - The branch needed to become one reviewable PR against current `paperclipai/paperclip:master`, without carrying stale base conflicts or generated lockfile churn. > - This pull request adds an experimental built-in `acpx_local` adapter, integrates it through the server/CLI/UI adapter surfaces, and adds regression coverage for runtime execution, skill sync, stream parsing, diagnostics, and log redaction. > - The benefit is that Paperclip can run Claude/Codex/custom ACP agents through ACPX while keeping operator configuration, skills, logging, and transcript rendering inside the existing adapter model. ## What Changed - Added `@paperclipai/adapter-acpx-local` with server execution, config schema, ACPX session handling, CLI formatting, UI config helpers, and stdout parsing. - Registered `acpx_local` across CLI, server, shared constants, UI adapter metadata, adapter capabilities, and agent creation/editing surfaces. - Added ACPX runtime execution support with persistent sessions, local-agent JWT environment handling, skill snapshots, runtime skill materialization, and isolation/security regressions. - Added ACPX adapter diagnostics and marked the adapter experimental in the UI. - Added command/env secret redaction for resolved command metadata in adapter-utils, server event storage, and the Agent Detail invocation UI. - Added Storybook coverage for ACPX config, transcript rendering, and skill states, plus PR screenshots under `docs/pr-screenshots/pap-2944/`. - Rebased the branch onto current `public-gh/master`; `pnpm-lock.yaml` is intentionally not included and there are no migration/schema changes. ## Verification - `pnpm exec vitest run packages/adapters/acpx-local/src/server/execute.test.ts packages/adapters/acpx-local/src/server/test.test.ts packages/adapters/acpx-local/src/cli/format-event.test.ts packages/adapters/acpx-local/src/ui/parse-stdout.test.ts packages/adapter-utils/src/server-utils.test.ts server/src/__tests__/redaction.test.ts server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/acpx-local-skill-sync.test.ts server/src/__tests__/acpx-local-adapter-environment.test.ts server/src/__tests__/adapter-routes.test.ts server/src/__tests__/agent-skills-routes.test.ts ui/src/adapters/metadata.test.ts` — 12 files, 87 tests passed. - `pnpm --filter @paperclipai/adapter-acpx-local typecheck` — passed. - `pnpm --filter @paperclipai/server typecheck` — passed. - `pnpm --filter @paperclipai/ui typecheck` — passed. - Confirmed PR diff does not include `pnpm-lock.yaml`, database schema files, or migrations. Screenshots: ![ACPX Claude skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-light.png?raw=true) ![ACPX Claude skills dark](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-dark.png?raw=true) ![ACPX custom skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-custom-light.png?raw=true) ## Risks - Medium risk: this introduces a new built-in adapter package and touches runtime execution, adapter registration, agent config, skills, and transcript rendering. - ACPX and ACP agent behavior can vary by installed tool versions; the adapter is marked experimental to set operator expectations. - `pnpm-lock.yaml` is excluded per repository PR policy, so dependency lock refresh must be handled by the repo’s automation or maintainers. - No database migration risk: no schema or migration files changed. > 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 coding agent based on GPT-5, with repository tool use, shell execution, git operations, and local verification. Exact hosted context window was not exposed in this environment. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-30 19:57:05 -05:00
if (acpxAgent === "claude") {
const preparedSkills = await prepareClaudeSkillRuntime({
stateDir,
config,
onLog: input.ctx.onLog,
});
skillPromptInstructions = preparedSkills.promptInstructions;
skillsIdentity = preparedSkills.identity;
skillCommandNotes.push(...preparedSkills.commandNotes);
Make ACPX-Claude adapter work seamlessly (PAPA-388) (#6590) ## Thinking Path > - Paperclip orchestrates AI agents for zero-human companies, so when an adapter fails, the platform must surface enough detail for the next agent (or human reviewer) to act > - The `acpx_local` adapter wraps `claude-agent-acp`, which in turn drives the Claude Code SDK — three layers, three different permission and error-handling models > - A user created a `Claude Local ACPX` agent in PAPA-387 and it failed instantly with the generic `acpx.error / "Internal error"` log, stranding the work and triggering an opaque `stranded_assigned_issue` recovery to the CTO > - Once the diagnostic blackbox was opened, the underlying cause turned out to be two SDK-level mismatches: a model-name allowlist that rejects bare IDs like `claude-opus-4-7`, and a Claude Code permission/Read-sandbox configuration that silently denies every non-allowlisted tool when the user's `~/.claude/settings.json` has `defaultMode: "dontAsk"` > - This pull request fixes both classes of failure in the adapter itself so new ACPX agents work seamlessly without per-host configuration, and widens the diagnostic surface so the *next* failure of any kind is actionable > - The benefit is that ACPX-Claude can join the regular agent roster — verified end to end on PAPA-401, where the agent successfully reached the Paperclip API, opened a worktree, surveyed existing notification PRs, and posted a structured plan ## What Changed - Widen ACPX failure diagnostics (`packages/adapters/acpx-local/src/server/execute.ts`): - Capture `err.name`, ACP code, `cause.message`, retryable flag, and a 5-frame stack preview into `errorMeta`. - Promote phase-specific error codes: `ensure_session → acpx_session_init_failed`, `configure_session → acpx_session_config_failed`, `turn → acpx_turn_failed`, plus mapping for `ACP_BACKEND_MISSING` / `ACP_BACKEND_UNAVAILABLE`. - Set `verbose: true` on the ACPX runtime so its session-event log flows through `ctx.onLog`. - Capture child-process stderr via a wrapper-script tee into `<stateDir>/run-stderr/<runId>.log`, inline the tail into the `acpx.error` payload as `childStderrTail`, and forward it through `ctx.onLog("stderr", …)` so it lands in the heartbeat `stderrExcerpt` column (existing redaction applies). - Set the model via `ANTHROPIC_MODEL` env for the `claude` agent instead of `set_config_option(model, …)`. The ACP server's `set_config_option` handler validates against an internal allowlist and rejects bare IDs like `claude-opus-4-7`. `ANTHROPIC_MODEL` is read during initialization and bypasses that check. - Seed `<worktree>/.claude/settings.local.json` before spawning `claude-agent-acp` (the seamless-API fix). Since `claude-agent-acp` hard-codes `settingSources: ["user", "project", "local"]` and "local" has the highest precedence: - Set `permissions.defaultMode: "default"`, but **only** if the user's value is missing or `"dontAsk"` (the broken case). Other modes like `acceptEdits`/`plan` are preserved. - Pre-allow Paperclip's Bash surface (`Bash(curl:*)`, `Bash(env:*)`, `Bash(<cwd>/scripts/paperclip-issue-update.sh:*)`, `Bash(<cwd>/scripts/paperclip:*)`). - Widen `permissions.additionalDirectories` to include `stateDir`, `agentHome`, and the per-company instance root (`~/.paperclip/instances/<id>/companies/<companyId>`). Scoped to this company only — does not expose other tenants. - Existing user entries are merged, not replaced. The resolved roots are folded into the session fingerprint so warm-session handles invalidate when they change. - Sync the existing server-side integration test (`server/src/__tests__/acpx-local-execute.test.ts`) to assert `acpx_session_init_failed` instead of the now-removed `acpx_protocol_error` for `ACP_SESSION_INIT_FAILED` (a follow-up to commit 1). ## Verification - `pnpm --filter "@paperclipai/adapter-acpx-local" run typecheck` — passes. - `pnpm vitest run` in `packages/adapters/acpx-local` — 35/35 pass, includes 4 new tests covering the settings.local.json write path (claude only, merge with pre-existing content, `dontAsk` override, codex no-op). - `pnpm vitest run src/__tests__/acpx-local-execute.test.ts` in `server/` — 15/15 pass after the test-sync commit. - End-to-end manual verification (PAPA-401): the `Claude Local ACPX` agent that previously hit "restricted environment" now successfully reaches the Paperclip API, opens its worktree, posts structured plan comments, and flips the issue to `in_review` without any external configuration. ## Risks - **Low**, scoped to the `acpx_local` adapter. The settings.local.json write is per-worktree (worktrees live under `.paperclip/worktrees/<issue>/`) and only triggers when `acpxAgent === "claude"`. Existing user content is merged with `[...existing, ...paperclip]` and deduped — nothing is overwritten outright. - The `defaultMode` override is intentionally narrow: it only flips `"dontAsk"` (which silently denies every tool and is the root cause) to `"default"`. Users who explicitly picked `acceptEdits`, `plan`, or any other mode keep their choice. - Stderr capture goes through the existing `log-redaction` pass before persisting, so `PAPERCLIP_API_KEY` and similar secrets in the wrapper env don't leak into heartbeat logs. > 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 4.7 (`claude-opus-4-7`), running in the `claude_local` adapter via Paperclip's harness. Extended thinking enabled, tool use enabled. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [ ] If this change affects the UI, I have included before/after screenshots — N/A (adapter-only) - [ ] I have updated relevant documentation to reflect my changes — no user-facing docs changed; internal commentary in the code change explains the SDK constraints - [x] I have considered and documented any risks above - [ ] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-05-23 13:01:27 -07:00
paperclipClaudeSettings = await writePaperclipClaudeSettings({
cwd,
stateDir,
agentHome,
companyId: agent.companyId,
});
skillCommandNotes.push(
`Wrote Paperclip-managed Claude settings to ${paperclipClaudeSettings.filePath} (defaultMode=${paperclipClaudeSettings.defaultMode}${
paperclipClaudeSettings.overrodeDontAsk ? "; overrode user dontAsk" : ""
}, +${paperclipClaudeSettings.additionalDirectories.length} read root(s), +${paperclipClaudeSettings.allow.length} allow rule(s)).`,
);
Add ACPX local adapter runtime (#4893) ## Thinking Path > - Paperclip orchestrates AI-agent companies through a control plane that can start, supervise, and recover agent runs. > - Local adapters are the bridge between Paperclip issues and concrete agent runtimes such as Claude, Codex, and other ACP-compatible tools. > - The roadmap calls out broader “bring your own agent” and claw-style agent support, and ACPX gives Paperclip one path to normalize multiple ACP agents behind a single adapter. > - The branch needed to become one reviewable PR against current `paperclipai/paperclip:master`, without carrying stale base conflicts or generated lockfile churn. > - This pull request adds an experimental built-in `acpx_local` adapter, integrates it through the server/CLI/UI adapter surfaces, and adds regression coverage for runtime execution, skill sync, stream parsing, diagnostics, and log redaction. > - The benefit is that Paperclip can run Claude/Codex/custom ACP agents through ACPX while keeping operator configuration, skills, logging, and transcript rendering inside the existing adapter model. ## What Changed - Added `@paperclipai/adapter-acpx-local` with server execution, config schema, ACPX session handling, CLI formatting, UI config helpers, and stdout parsing. - Registered `acpx_local` across CLI, server, shared constants, UI adapter metadata, adapter capabilities, and agent creation/editing surfaces. - Added ACPX runtime execution support with persistent sessions, local-agent JWT environment handling, skill snapshots, runtime skill materialization, and isolation/security regressions. - Added ACPX adapter diagnostics and marked the adapter experimental in the UI. - Added command/env secret redaction for resolved command metadata in adapter-utils, server event storage, and the Agent Detail invocation UI. - Added Storybook coverage for ACPX config, transcript rendering, and skill states, plus PR screenshots under `docs/pr-screenshots/pap-2944/`. - Rebased the branch onto current `public-gh/master`; `pnpm-lock.yaml` is intentionally not included and there are no migration/schema changes. ## Verification - `pnpm exec vitest run packages/adapters/acpx-local/src/server/execute.test.ts packages/adapters/acpx-local/src/server/test.test.ts packages/adapters/acpx-local/src/cli/format-event.test.ts packages/adapters/acpx-local/src/ui/parse-stdout.test.ts packages/adapter-utils/src/server-utils.test.ts server/src/__tests__/redaction.test.ts server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/acpx-local-skill-sync.test.ts server/src/__tests__/acpx-local-adapter-environment.test.ts server/src/__tests__/adapter-routes.test.ts server/src/__tests__/agent-skills-routes.test.ts ui/src/adapters/metadata.test.ts` — 12 files, 87 tests passed. - `pnpm --filter @paperclipai/adapter-acpx-local typecheck` — passed. - `pnpm --filter @paperclipai/server typecheck` — passed. - `pnpm --filter @paperclipai/ui typecheck` — passed. - Confirmed PR diff does not include `pnpm-lock.yaml`, database schema files, or migrations. Screenshots: ![ACPX Claude skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-light.png?raw=true) ![ACPX Claude skills dark](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-dark.png?raw=true) ![ACPX custom skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-custom-light.png?raw=true) ## Risks - Medium risk: this introduces a new built-in adapter package and touches runtime execution, adapter registration, agent config, skills, and transcript rendering. - ACPX and ACP agent behavior can vary by installed tool versions; the adapter is marked experimental to set operator expectations. - `pnpm-lock.yaml` is excluded per repository PR policy, so dependency lock refresh must be handled by the repo’s automation or maintainers. - No database migration risk: no schema or migration files changed. > 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 coding agent based on GPT-5, with repository tool use, shell execution, git operations, and local verification. Exact hosted context window was not exposed in this environment. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-30 19:57:05 -05:00
} else if (acpxAgent === "codex") {
const preparedSkills = await prepareCodexSkillRuntime({
companyId: agent.companyId,
config,
env,
onLog: input.ctx.onLog,
});
skillsIdentity = preparedSkills.identity;
skillCommandNotes.push(...preparedSkills.commandNotes);
} else {
const desired = resolvePaperclipDesiredSkillNames(config, await readPaperclipRuntimeSkillEntries(config, __moduleDir));
skillsIdentity = { mode: "custom_unsupported", desiredSkillNames: desired };
if (desired.length > 0) {
skillCommandNotes.push("Selected Paperclip skills are tracked only; ACPX custom commands do not expose a runtime skill contract yet.");
}
}
const configuredCommand = asString(config.agentCommand, "").trim();
const builtInCommand = resolveBuiltInAgentCommand(acpxAgent);
const agentCommand = configuredCommand || builtInCommand || null;
const agentCommandShell = configuredCommand || (builtInCommand ? shellQuote(builtInCommand) : "");
Make ACPX-Claude adapter work seamlessly (PAPA-388) (#6590) ## Thinking Path > - Paperclip orchestrates AI agents for zero-human companies, so when an adapter fails, the platform must surface enough detail for the next agent (or human reviewer) to act > - The `acpx_local` adapter wraps `claude-agent-acp`, which in turn drives the Claude Code SDK — three layers, three different permission and error-handling models > - A user created a `Claude Local ACPX` agent in PAPA-387 and it failed instantly with the generic `acpx.error / "Internal error"` log, stranding the work and triggering an opaque `stranded_assigned_issue` recovery to the CTO > - Once the diagnostic blackbox was opened, the underlying cause turned out to be two SDK-level mismatches: a model-name allowlist that rejects bare IDs like `claude-opus-4-7`, and a Claude Code permission/Read-sandbox configuration that silently denies every non-allowlisted tool when the user's `~/.claude/settings.json` has `defaultMode: "dontAsk"` > - This pull request fixes both classes of failure in the adapter itself so new ACPX agents work seamlessly without per-host configuration, and widens the diagnostic surface so the *next* failure of any kind is actionable > - The benefit is that ACPX-Claude can join the regular agent roster — verified end to end on PAPA-401, where the agent successfully reached the Paperclip API, opened a worktree, surveyed existing notification PRs, and posted a structured plan ## What Changed - Widen ACPX failure diagnostics (`packages/adapters/acpx-local/src/server/execute.ts`): - Capture `err.name`, ACP code, `cause.message`, retryable flag, and a 5-frame stack preview into `errorMeta`. - Promote phase-specific error codes: `ensure_session → acpx_session_init_failed`, `configure_session → acpx_session_config_failed`, `turn → acpx_turn_failed`, plus mapping for `ACP_BACKEND_MISSING` / `ACP_BACKEND_UNAVAILABLE`. - Set `verbose: true` on the ACPX runtime so its session-event log flows through `ctx.onLog`. - Capture child-process stderr via a wrapper-script tee into `<stateDir>/run-stderr/<runId>.log`, inline the tail into the `acpx.error` payload as `childStderrTail`, and forward it through `ctx.onLog("stderr", …)` so it lands in the heartbeat `stderrExcerpt` column (existing redaction applies). - Set the model via `ANTHROPIC_MODEL` env for the `claude` agent instead of `set_config_option(model, …)`. The ACP server's `set_config_option` handler validates against an internal allowlist and rejects bare IDs like `claude-opus-4-7`. `ANTHROPIC_MODEL` is read during initialization and bypasses that check. - Seed `<worktree>/.claude/settings.local.json` before spawning `claude-agent-acp` (the seamless-API fix). Since `claude-agent-acp` hard-codes `settingSources: ["user", "project", "local"]` and "local" has the highest precedence: - Set `permissions.defaultMode: "default"`, but **only** if the user's value is missing or `"dontAsk"` (the broken case). Other modes like `acceptEdits`/`plan` are preserved. - Pre-allow Paperclip's Bash surface (`Bash(curl:*)`, `Bash(env:*)`, `Bash(<cwd>/scripts/paperclip-issue-update.sh:*)`, `Bash(<cwd>/scripts/paperclip:*)`). - Widen `permissions.additionalDirectories` to include `stateDir`, `agentHome`, and the per-company instance root (`~/.paperclip/instances/<id>/companies/<companyId>`). Scoped to this company only — does not expose other tenants. - Existing user entries are merged, not replaced. The resolved roots are folded into the session fingerprint so warm-session handles invalidate when they change. - Sync the existing server-side integration test (`server/src/__tests__/acpx-local-execute.test.ts`) to assert `acpx_session_init_failed` instead of the now-removed `acpx_protocol_error` for `ACP_SESSION_INIT_FAILED` (a follow-up to commit 1). ## Verification - `pnpm --filter "@paperclipai/adapter-acpx-local" run typecheck` — passes. - `pnpm vitest run` in `packages/adapters/acpx-local` — 35/35 pass, includes 4 new tests covering the settings.local.json write path (claude only, merge with pre-existing content, `dontAsk` override, codex no-op). - `pnpm vitest run src/__tests__/acpx-local-execute.test.ts` in `server/` — 15/15 pass after the test-sync commit. - End-to-end manual verification (PAPA-401): the `Claude Local ACPX` agent that previously hit "restricted environment" now successfully reaches the Paperclip API, opens its worktree, posts structured plan comments, and flips the issue to `in_review` without any external configuration. ## Risks - **Low**, scoped to the `acpx_local` adapter. The settings.local.json write is per-worktree (worktrees live under `.paperclip/worktrees/<issue>/`) and only triggers when `acpxAgent === "claude"`. Existing user content is merged with `[...existing, ...paperclip]` and deduped — nothing is overwritten outright. - The `defaultMode` override is intentionally narrow: it only flips `"dontAsk"` (which silently denies every tool and is the root cause) to `"default"`. Users who explicitly picked `acceptEdits`, `plan`, or any other mode keep their choice. - Stderr capture goes through the existing `log-redaction` pass before persisting, so `PAPERCLIP_API_KEY` and similar secrets in the wrapper env don't leak into heartbeat logs. > 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 4.7 (`claude-opus-4-7`), running in the `claude_local` adapter via Paperclip's harness. Extended thinking enabled, tool use enabled. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [ ] If this change affects the UI, I have included before/after screenshots — N/A (adapter-only) - [ ] I have updated relevant documentation to reflect my changes — no user-facing docs changed; internal commentary in the code change explains the SDK constraints - [x] I have considered and documented any risks above - [ ] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-05-23 13:01:27 -07:00
const childStderrDir = path.join(stateDir, "run-stderr");
const childStderrLogPath = agentCommand ? path.join(childStderrDir, `${runId}.log`) : null;
Add ACPX local adapter runtime (#4893) ## Thinking Path > - Paperclip orchestrates AI-agent companies through a control plane that can start, supervise, and recover agent runs. > - Local adapters are the bridge between Paperclip issues and concrete agent runtimes such as Claude, Codex, and other ACP-compatible tools. > - The roadmap calls out broader “bring your own agent” and claw-style agent support, and ACPX gives Paperclip one path to normalize multiple ACP agents behind a single adapter. > - The branch needed to become one reviewable PR against current `paperclipai/paperclip:master`, without carrying stale base conflicts or generated lockfile churn. > - This pull request adds an experimental built-in `acpx_local` adapter, integrates it through the server/CLI/UI adapter surfaces, and adds regression coverage for runtime execution, skill sync, stream parsing, diagnostics, and log redaction. > - The benefit is that Paperclip can run Claude/Codex/custom ACP agents through ACPX while keeping operator configuration, skills, logging, and transcript rendering inside the existing adapter model. ## What Changed - Added `@paperclipai/adapter-acpx-local` with server execution, config schema, ACPX session handling, CLI formatting, UI config helpers, and stdout parsing. - Registered `acpx_local` across CLI, server, shared constants, UI adapter metadata, adapter capabilities, and agent creation/editing surfaces. - Added ACPX runtime execution support with persistent sessions, local-agent JWT environment handling, skill snapshots, runtime skill materialization, and isolation/security regressions. - Added ACPX adapter diagnostics and marked the adapter experimental in the UI. - Added command/env secret redaction for resolved command metadata in adapter-utils, server event storage, and the Agent Detail invocation UI. - Added Storybook coverage for ACPX config, transcript rendering, and skill states, plus PR screenshots under `docs/pr-screenshots/pap-2944/`. - Rebased the branch onto current `public-gh/master`; `pnpm-lock.yaml` is intentionally not included and there are no migration/schema changes. ## Verification - `pnpm exec vitest run packages/adapters/acpx-local/src/server/execute.test.ts packages/adapters/acpx-local/src/server/test.test.ts packages/adapters/acpx-local/src/cli/format-event.test.ts packages/adapters/acpx-local/src/ui/parse-stdout.test.ts packages/adapter-utils/src/server-utils.test.ts server/src/__tests__/redaction.test.ts server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/acpx-local-skill-sync.test.ts server/src/__tests__/acpx-local-adapter-environment.test.ts server/src/__tests__/adapter-routes.test.ts server/src/__tests__/agent-skills-routes.test.ts ui/src/adapters/metadata.test.ts` — 12 files, 87 tests passed. - `pnpm --filter @paperclipai/adapter-acpx-local typecheck` — passed. - `pnpm --filter @paperclipai/server typecheck` — passed. - `pnpm --filter @paperclipai/ui typecheck` — passed. - Confirmed PR diff does not include `pnpm-lock.yaml`, database schema files, or migrations. Screenshots: ![ACPX Claude skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-light.png?raw=true) ![ACPX Claude skills dark](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-dark.png?raw=true) ![ACPX custom skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-custom-light.png?raw=true) ## Risks - Medium risk: this introduces a new built-in adapter package and touches runtime execution, adapter registration, agent config, skills, and transcript rendering. - ACPX and ACP agent behavior can vary by installed tool versions; the adapter is marked experimental to set operator expectations. - `pnpm-lock.yaml` is excluded per repository PR policy, so dependency lock refresh must be handled by the repo’s automation or maintainers. - No database migration risk: no schema or migration files changed. > 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 coding agent based on GPT-5, with repository tool use, shell execution, git operations, and local verification. Exact hosted context window was not exposed in this environment. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-30 19:57:05 -05:00
const wrapper = agentCommand
? await writeAgentWrapper({
stateDir,
acpxAgent,
agentCommandShell,
env,
Make ACPX-Claude adapter work seamlessly (PAPA-388) (#6590) ## Thinking Path > - Paperclip orchestrates AI agents for zero-human companies, so when an adapter fails, the platform must surface enough detail for the next agent (or human reviewer) to act > - The `acpx_local` adapter wraps `claude-agent-acp`, which in turn drives the Claude Code SDK — three layers, three different permission and error-handling models > - A user created a `Claude Local ACPX` agent in PAPA-387 and it failed instantly with the generic `acpx.error / "Internal error"` log, stranding the work and triggering an opaque `stranded_assigned_issue` recovery to the CTO > - Once the diagnostic blackbox was opened, the underlying cause turned out to be two SDK-level mismatches: a model-name allowlist that rejects bare IDs like `claude-opus-4-7`, and a Claude Code permission/Read-sandbox configuration that silently denies every non-allowlisted tool when the user's `~/.claude/settings.json` has `defaultMode: "dontAsk"` > - This pull request fixes both classes of failure in the adapter itself so new ACPX agents work seamlessly without per-host configuration, and widens the diagnostic surface so the *next* failure of any kind is actionable > - The benefit is that ACPX-Claude can join the regular agent roster — verified end to end on PAPA-401, where the agent successfully reached the Paperclip API, opened a worktree, surveyed existing notification PRs, and posted a structured plan ## What Changed - Widen ACPX failure diagnostics (`packages/adapters/acpx-local/src/server/execute.ts`): - Capture `err.name`, ACP code, `cause.message`, retryable flag, and a 5-frame stack preview into `errorMeta`. - Promote phase-specific error codes: `ensure_session → acpx_session_init_failed`, `configure_session → acpx_session_config_failed`, `turn → acpx_turn_failed`, plus mapping for `ACP_BACKEND_MISSING` / `ACP_BACKEND_UNAVAILABLE`. - Set `verbose: true` on the ACPX runtime so its session-event log flows through `ctx.onLog`. - Capture child-process stderr via a wrapper-script tee into `<stateDir>/run-stderr/<runId>.log`, inline the tail into the `acpx.error` payload as `childStderrTail`, and forward it through `ctx.onLog("stderr", …)` so it lands in the heartbeat `stderrExcerpt` column (existing redaction applies). - Set the model via `ANTHROPIC_MODEL` env for the `claude` agent instead of `set_config_option(model, …)`. The ACP server's `set_config_option` handler validates against an internal allowlist and rejects bare IDs like `claude-opus-4-7`. `ANTHROPIC_MODEL` is read during initialization and bypasses that check. - Seed `<worktree>/.claude/settings.local.json` before spawning `claude-agent-acp` (the seamless-API fix). Since `claude-agent-acp` hard-codes `settingSources: ["user", "project", "local"]` and "local" has the highest precedence: - Set `permissions.defaultMode: "default"`, but **only** if the user's value is missing or `"dontAsk"` (the broken case). Other modes like `acceptEdits`/`plan` are preserved. - Pre-allow Paperclip's Bash surface (`Bash(curl:*)`, `Bash(env:*)`, `Bash(<cwd>/scripts/paperclip-issue-update.sh:*)`, `Bash(<cwd>/scripts/paperclip:*)`). - Widen `permissions.additionalDirectories` to include `stateDir`, `agentHome`, and the per-company instance root (`~/.paperclip/instances/<id>/companies/<companyId>`). Scoped to this company only — does not expose other tenants. - Existing user entries are merged, not replaced. The resolved roots are folded into the session fingerprint so warm-session handles invalidate when they change. - Sync the existing server-side integration test (`server/src/__tests__/acpx-local-execute.test.ts`) to assert `acpx_session_init_failed` instead of the now-removed `acpx_protocol_error` for `ACP_SESSION_INIT_FAILED` (a follow-up to commit 1). ## Verification - `pnpm --filter "@paperclipai/adapter-acpx-local" run typecheck` — passes. - `pnpm vitest run` in `packages/adapters/acpx-local` — 35/35 pass, includes 4 new tests covering the settings.local.json write path (claude only, merge with pre-existing content, `dontAsk` override, codex no-op). - `pnpm vitest run src/__tests__/acpx-local-execute.test.ts` in `server/` — 15/15 pass after the test-sync commit. - End-to-end manual verification (PAPA-401): the `Claude Local ACPX` agent that previously hit "restricted environment" now successfully reaches the Paperclip API, opens its worktree, posts structured plan comments, and flips the issue to `in_review` without any external configuration. ## Risks - **Low**, scoped to the `acpx_local` adapter. The settings.local.json write is per-worktree (worktrees live under `.paperclip/worktrees/<issue>/`) and only triggers when `acpxAgent === "claude"`. Existing user content is merged with `[...existing, ...paperclip]` and deduped — nothing is overwritten outright. - The `defaultMode` override is intentionally narrow: it only flips `"dontAsk"` (which silently denies every tool and is the root cause) to `"default"`. Users who explicitly picked `acceptEdits`, `plan`, or any other mode keep their choice. - Stderr capture goes through the existing `log-redaction` pass before persisting, so `PAPERCLIP_API_KEY` and similar secrets in the wrapper env don't leak into heartbeat logs. > 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 4.7 (`claude-opus-4-7`), running in the `claude_local` adapter via Paperclip's harness. Extended thinking enabled, tool use enabled. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [ ] If this change affects the UI, I have included before/after screenshots — N/A (adapter-only) - [ ] I have updated relevant documentation to reflect my changes — no user-facing docs changed; internal commentary in the code change explains the SDK constraints - [x] I have considered and documented any risks above - [ ] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-05-23 13:01:27 -07:00
childStderrDir,
Add ACPX local adapter runtime (#4893) ## Thinking Path > - Paperclip orchestrates AI-agent companies through a control plane that can start, supervise, and recover agent runs. > - Local adapters are the bridge between Paperclip issues and concrete agent runtimes such as Claude, Codex, and other ACP-compatible tools. > - The roadmap calls out broader “bring your own agent” and claw-style agent support, and ACPX gives Paperclip one path to normalize multiple ACP agents behind a single adapter. > - The branch needed to become one reviewable PR against current `paperclipai/paperclip:master`, without carrying stale base conflicts or generated lockfile churn. > - This pull request adds an experimental built-in `acpx_local` adapter, integrates it through the server/CLI/UI adapter surfaces, and adds regression coverage for runtime execution, skill sync, stream parsing, diagnostics, and log redaction. > - The benefit is that Paperclip can run Claude/Codex/custom ACP agents through ACPX while keeping operator configuration, skills, logging, and transcript rendering inside the existing adapter model. ## What Changed - Added `@paperclipai/adapter-acpx-local` with server execution, config schema, ACPX session handling, CLI formatting, UI config helpers, and stdout parsing. - Registered `acpx_local` across CLI, server, shared constants, UI adapter metadata, adapter capabilities, and agent creation/editing surfaces. - Added ACPX runtime execution support with persistent sessions, local-agent JWT environment handling, skill snapshots, runtime skill materialization, and isolation/security regressions. - Added ACPX adapter diagnostics and marked the adapter experimental in the UI. - Added command/env secret redaction for resolved command metadata in adapter-utils, server event storage, and the Agent Detail invocation UI. - Added Storybook coverage for ACPX config, transcript rendering, and skill states, plus PR screenshots under `docs/pr-screenshots/pap-2944/`. - Rebased the branch onto current `public-gh/master`; `pnpm-lock.yaml` is intentionally not included and there are no migration/schema changes. ## Verification - `pnpm exec vitest run packages/adapters/acpx-local/src/server/execute.test.ts packages/adapters/acpx-local/src/server/test.test.ts packages/adapters/acpx-local/src/cli/format-event.test.ts packages/adapters/acpx-local/src/ui/parse-stdout.test.ts packages/adapter-utils/src/server-utils.test.ts server/src/__tests__/redaction.test.ts server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/acpx-local-skill-sync.test.ts server/src/__tests__/acpx-local-adapter-environment.test.ts server/src/__tests__/adapter-routes.test.ts server/src/__tests__/agent-skills-routes.test.ts ui/src/adapters/metadata.test.ts` — 12 files, 87 tests passed. - `pnpm --filter @paperclipai/adapter-acpx-local typecheck` — passed. - `pnpm --filter @paperclipai/server typecheck` — passed. - `pnpm --filter @paperclipai/ui typecheck` — passed. - Confirmed PR diff does not include `pnpm-lock.yaml`, database schema files, or migrations. Screenshots: ![ACPX Claude skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-light.png?raw=true) ![ACPX Claude skills dark](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-dark.png?raw=true) ![ACPX custom skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-custom-light.png?raw=true) ## Risks - Medium risk: this introduces a new built-in adapter package and touches runtime execution, adapter registration, agent config, skills, and transcript rendering. - ACPX and ACP agent behavior can vary by installed tool versions; the adapter is marked experimental to set operator expectations. - `pnpm-lock.yaml` is excluded per repository PR policy, so dependency lock refresh must be handled by the repo’s automation or maintainers. - No database migration risk: no schema or migration files changed. > 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 coding agent based on GPT-5, with repository tool use, shell execution, git operations, and local verification. Exact hosted context window was not exposed in this environment. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-30 19:57:05 -05:00
})
: null;
const wrapperPath = wrapper?.wrapperPath ?? null;
const overrides = wrapperPath ? { [acpxAgent]: wrapperPath } : undefined;
const agentRegistry = createAgentRegistry({ overrides });
const fingerprint = shortHash({
acpxAgent,
agentCommand: agentCommand ?? acpxAgent,
cwd: path.resolve(cwd),
mode,
permissionMode,
nonInteractivePermissions,
Improve ACPX adapter configuration (#5290) ## Thinking Path > - Paperclip orchestrates AI agents across several adapter implementations. > - ACPX is a local adapter path that can proxy Claude and Codex-style execution. > - Its configuration needed stronger schema defaults, provider-aware model handling, and better UI support. > - Plugin authors also need clear docs for managed resources. > - This pull request improves ACPX adapter configuration and documents plugin-managed resources. > - The benefit is a more predictable adapter setup path without changing unrelated control-plane behavior. ## What Changed - Improved ACPX config schema, execution config handling, UI build config, and route coverage. - Added ACPX model filtering support and tests. - Updated the agent config form and storybook coverage for ACPX model/provider behavior. - Expanded plugin authoring documentation for managed resources. ## Verification - `pnpm install --frozen-lockfile` - `pnpm exec vitest run server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/adapter-routes.test.ts ui/src/lib/acpx-model-filter.test.ts` ## Risks - Low-to-medium risk: adapter configuration behavior changes can affect ACPX users, but the change is isolated to ACPX/plugin-doc surfaces and covered by targeted adapter tests. ## Model Used - OpenAI GPT-5 Codex via Paperclip `codex_local` adapter, with shell/git/GitHub CLI tool use. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-05-06 06:06:47 -05:00
requestedModel,
requestedThinkingEffort,
fastMode,
Add ACPX local adapter runtime (#4893) ## Thinking Path > - Paperclip orchestrates AI-agent companies through a control plane that can start, supervise, and recover agent runs. > - Local adapters are the bridge between Paperclip issues and concrete agent runtimes such as Claude, Codex, and other ACP-compatible tools. > - The roadmap calls out broader “bring your own agent” and claw-style agent support, and ACPX gives Paperclip one path to normalize multiple ACP agents behind a single adapter. > - The branch needed to become one reviewable PR against current `paperclipai/paperclip:master`, without carrying stale base conflicts or generated lockfile churn. > - This pull request adds an experimental built-in `acpx_local` adapter, integrates it through the server/CLI/UI adapter surfaces, and adds regression coverage for runtime execution, skill sync, stream parsing, diagnostics, and log redaction. > - The benefit is that Paperclip can run Claude/Codex/custom ACP agents through ACPX while keeping operator configuration, skills, logging, and transcript rendering inside the existing adapter model. ## What Changed - Added `@paperclipai/adapter-acpx-local` with server execution, config schema, ACPX session handling, CLI formatting, UI config helpers, and stdout parsing. - Registered `acpx_local` across CLI, server, shared constants, UI adapter metadata, adapter capabilities, and agent creation/editing surfaces. - Added ACPX runtime execution support with persistent sessions, local-agent JWT environment handling, skill snapshots, runtime skill materialization, and isolation/security regressions. - Added ACPX adapter diagnostics and marked the adapter experimental in the UI. - Added command/env secret redaction for resolved command metadata in adapter-utils, server event storage, and the Agent Detail invocation UI. - Added Storybook coverage for ACPX config, transcript rendering, and skill states, plus PR screenshots under `docs/pr-screenshots/pap-2944/`. - Rebased the branch onto current `public-gh/master`; `pnpm-lock.yaml` is intentionally not included and there are no migration/schema changes. ## Verification - `pnpm exec vitest run packages/adapters/acpx-local/src/server/execute.test.ts packages/adapters/acpx-local/src/server/test.test.ts packages/adapters/acpx-local/src/cli/format-event.test.ts packages/adapters/acpx-local/src/ui/parse-stdout.test.ts packages/adapter-utils/src/server-utils.test.ts server/src/__tests__/redaction.test.ts server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/acpx-local-skill-sync.test.ts server/src/__tests__/acpx-local-adapter-environment.test.ts server/src/__tests__/adapter-routes.test.ts server/src/__tests__/agent-skills-routes.test.ts ui/src/adapters/metadata.test.ts` — 12 files, 87 tests passed. - `pnpm --filter @paperclipai/adapter-acpx-local typecheck` — passed. - `pnpm --filter @paperclipai/server typecheck` — passed. - `pnpm --filter @paperclipai/ui typecheck` — passed. - Confirmed PR diff does not include `pnpm-lock.yaml`, database schema files, or migrations. Screenshots: ![ACPX Claude skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-light.png?raw=true) ![ACPX Claude skills dark](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-dark.png?raw=true) ![ACPX custom skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-custom-light.png?raw=true) ## Risks - Medium risk: this introduces a new built-in adapter package and touches runtime execution, adapter registration, agent config, skills, and transcript rendering. - ACPX and ACP agent behavior can vary by installed tool versions; the adapter is marked experimental to set operator expectations. - `pnpm-lock.yaml` is excluded per repository PR policy, so dependency lock refresh must be handled by the repo’s automation or maintainers. - No database migration risk: no schema or migration files changed. > 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 coding agent based on GPT-5, with repository tool use, shell execution, git operations, and local verification. Exact hosted context window was not exposed in this environment. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-30 19:57:05 -05:00
remoteExecutionIdentity,
skillsIdentity,
skillPromptInstructions,
Make ACPX-Claude adapter work seamlessly (PAPA-388) (#6590) ## Thinking Path > - Paperclip orchestrates AI agents for zero-human companies, so when an adapter fails, the platform must surface enough detail for the next agent (or human reviewer) to act > - The `acpx_local` adapter wraps `claude-agent-acp`, which in turn drives the Claude Code SDK — three layers, three different permission and error-handling models > - A user created a `Claude Local ACPX` agent in PAPA-387 and it failed instantly with the generic `acpx.error / "Internal error"` log, stranding the work and triggering an opaque `stranded_assigned_issue` recovery to the CTO > - Once the diagnostic blackbox was opened, the underlying cause turned out to be two SDK-level mismatches: a model-name allowlist that rejects bare IDs like `claude-opus-4-7`, and a Claude Code permission/Read-sandbox configuration that silently denies every non-allowlisted tool when the user's `~/.claude/settings.json` has `defaultMode: "dontAsk"` > - This pull request fixes both classes of failure in the adapter itself so new ACPX agents work seamlessly without per-host configuration, and widens the diagnostic surface so the *next* failure of any kind is actionable > - The benefit is that ACPX-Claude can join the regular agent roster — verified end to end on PAPA-401, where the agent successfully reached the Paperclip API, opened a worktree, surveyed existing notification PRs, and posted a structured plan ## What Changed - Widen ACPX failure diagnostics (`packages/adapters/acpx-local/src/server/execute.ts`): - Capture `err.name`, ACP code, `cause.message`, retryable flag, and a 5-frame stack preview into `errorMeta`. - Promote phase-specific error codes: `ensure_session → acpx_session_init_failed`, `configure_session → acpx_session_config_failed`, `turn → acpx_turn_failed`, plus mapping for `ACP_BACKEND_MISSING` / `ACP_BACKEND_UNAVAILABLE`. - Set `verbose: true` on the ACPX runtime so its session-event log flows through `ctx.onLog`. - Capture child-process stderr via a wrapper-script tee into `<stateDir>/run-stderr/<runId>.log`, inline the tail into the `acpx.error` payload as `childStderrTail`, and forward it through `ctx.onLog("stderr", …)` so it lands in the heartbeat `stderrExcerpt` column (existing redaction applies). - Set the model via `ANTHROPIC_MODEL` env for the `claude` agent instead of `set_config_option(model, …)`. The ACP server's `set_config_option` handler validates against an internal allowlist and rejects bare IDs like `claude-opus-4-7`. `ANTHROPIC_MODEL` is read during initialization and bypasses that check. - Seed `<worktree>/.claude/settings.local.json` before spawning `claude-agent-acp` (the seamless-API fix). Since `claude-agent-acp` hard-codes `settingSources: ["user", "project", "local"]` and "local" has the highest precedence: - Set `permissions.defaultMode: "default"`, but **only** if the user's value is missing or `"dontAsk"` (the broken case). Other modes like `acceptEdits`/`plan` are preserved. - Pre-allow Paperclip's Bash surface (`Bash(curl:*)`, `Bash(env:*)`, `Bash(<cwd>/scripts/paperclip-issue-update.sh:*)`, `Bash(<cwd>/scripts/paperclip:*)`). - Widen `permissions.additionalDirectories` to include `stateDir`, `agentHome`, and the per-company instance root (`~/.paperclip/instances/<id>/companies/<companyId>`). Scoped to this company only — does not expose other tenants. - Existing user entries are merged, not replaced. The resolved roots are folded into the session fingerprint so warm-session handles invalidate when they change. - Sync the existing server-side integration test (`server/src/__tests__/acpx-local-execute.test.ts`) to assert `acpx_session_init_failed` instead of the now-removed `acpx_protocol_error` for `ACP_SESSION_INIT_FAILED` (a follow-up to commit 1). ## Verification - `pnpm --filter "@paperclipai/adapter-acpx-local" run typecheck` — passes. - `pnpm vitest run` in `packages/adapters/acpx-local` — 35/35 pass, includes 4 new tests covering the settings.local.json write path (claude only, merge with pre-existing content, `dontAsk` override, codex no-op). - `pnpm vitest run src/__tests__/acpx-local-execute.test.ts` in `server/` — 15/15 pass after the test-sync commit. - End-to-end manual verification (PAPA-401): the `Claude Local ACPX` agent that previously hit "restricted environment" now successfully reaches the Paperclip API, opens its worktree, posts structured plan comments, and flips the issue to `in_review` without any external configuration. ## Risks - **Low**, scoped to the `acpx_local` adapter. The settings.local.json write is per-worktree (worktrees live under `.paperclip/worktrees/<issue>/`) and only triggers when `acpxAgent === "claude"`. Existing user content is merged with `[...existing, ...paperclip]` and deduped — nothing is overwritten outright. - The `defaultMode` override is intentionally narrow: it only flips `"dontAsk"` (which silently denies every tool and is the root cause) to `"default"`. Users who explicitly picked `acceptEdits`, `plan`, or any other mode keep their choice. - Stderr capture goes through the existing `log-redaction` pass before persisting, so `PAPERCLIP_API_KEY` and similar secrets in the wrapper env don't leak into heartbeat logs. > 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 4.7 (`claude-opus-4-7`), running in the `claude_local` adapter via Paperclip's harness. Extended thinking enabled, tool use enabled. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [ ] If this change affects the UI, I have included before/after screenshots — N/A (adapter-only) - [ ] I have updated relevant documentation to reflect my changes — no user-facing docs changed; internal commentary in the code change explains the SDK constraints - [x] I have considered and documented any risks above - [ ] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-05-23 13:01:27 -07:00
paperclipClaudeSettings: paperclipClaudeSettings
? {
allow: paperclipClaudeSettings.allow,
additionalDirectories: paperclipClaudeSettings.additionalDirectories,
defaultMode: paperclipClaudeSettings.defaultMode,
}
: null,
Add ACPX local adapter runtime (#4893) ## Thinking Path > - Paperclip orchestrates AI-agent companies through a control plane that can start, supervise, and recover agent runs. > - Local adapters are the bridge between Paperclip issues and concrete agent runtimes such as Claude, Codex, and other ACP-compatible tools. > - The roadmap calls out broader “bring your own agent” and claw-style agent support, and ACPX gives Paperclip one path to normalize multiple ACP agents behind a single adapter. > - The branch needed to become one reviewable PR against current `paperclipai/paperclip:master`, without carrying stale base conflicts or generated lockfile churn. > - This pull request adds an experimental built-in `acpx_local` adapter, integrates it through the server/CLI/UI adapter surfaces, and adds regression coverage for runtime execution, skill sync, stream parsing, diagnostics, and log redaction. > - The benefit is that Paperclip can run Claude/Codex/custom ACP agents through ACPX while keeping operator configuration, skills, logging, and transcript rendering inside the existing adapter model. ## What Changed - Added `@paperclipai/adapter-acpx-local` with server execution, config schema, ACPX session handling, CLI formatting, UI config helpers, and stdout parsing. - Registered `acpx_local` across CLI, server, shared constants, UI adapter metadata, adapter capabilities, and agent creation/editing surfaces. - Added ACPX runtime execution support with persistent sessions, local-agent JWT environment handling, skill snapshots, runtime skill materialization, and isolation/security regressions. - Added ACPX adapter diagnostics and marked the adapter experimental in the UI. - Added command/env secret redaction for resolved command metadata in adapter-utils, server event storage, and the Agent Detail invocation UI. - Added Storybook coverage for ACPX config, transcript rendering, and skill states, plus PR screenshots under `docs/pr-screenshots/pap-2944/`. - Rebased the branch onto current `public-gh/master`; `pnpm-lock.yaml` is intentionally not included and there are no migration/schema changes. ## Verification - `pnpm exec vitest run packages/adapters/acpx-local/src/server/execute.test.ts packages/adapters/acpx-local/src/server/test.test.ts packages/adapters/acpx-local/src/cli/format-event.test.ts packages/adapters/acpx-local/src/ui/parse-stdout.test.ts packages/adapter-utils/src/server-utils.test.ts server/src/__tests__/redaction.test.ts server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/acpx-local-skill-sync.test.ts server/src/__tests__/acpx-local-adapter-environment.test.ts server/src/__tests__/adapter-routes.test.ts server/src/__tests__/agent-skills-routes.test.ts ui/src/adapters/metadata.test.ts` — 12 files, 87 tests passed. - `pnpm --filter @paperclipai/adapter-acpx-local typecheck` — passed. - `pnpm --filter @paperclipai/server typecheck` — passed. - `pnpm --filter @paperclipai/ui typecheck` — passed. - Confirmed PR diff does not include `pnpm-lock.yaml`, database schema files, or migrations. Screenshots: ![ACPX Claude skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-light.png?raw=true) ![ACPX Claude skills dark](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-dark.png?raw=true) ![ACPX custom skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-custom-light.png?raw=true) ## Risks - Medium risk: this introduces a new built-in adapter package and touches runtime execution, adapter registration, agent config, skills, and transcript rendering. - ACPX and ACP agent behavior can vary by installed tool versions; the adapter is marked experimental to set operator expectations. - `pnpm-lock.yaml` is excluded per repository PR policy, so dependency lock refresh must be handled by the repo’s automation or maintainers. - No database migration risk: no schema or migration files changed. > 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 coding agent based on GPT-5, with repository tool use, shell execution, git operations, and local verification. Exact hosted context window was not exposed in this environment. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-30 19:57:05 -05:00
});
const taskKey = asString(input.ctx.runtime.taskKey, "") || wakeTaskId || workspaceId || "default";
const sessionKey = `paperclip:${agent.companyId}:${agent.id}:${taskKey}:${fingerprint}`;
const runtimeEnv = ensurePathInEnv({ ...process.env, ...env });
const loggedEnv = buildInvocationEnvForLogs(env, {
runtimeEnv,
includeRuntimeKeys: ["HOME"],
resolvedCommand: wrapperPath ?? agentCommand ?? acpxAgent,
});
return {
acpxAgent,
mode,
cwd,
workspaceId,
workspaceRepoUrl,
workspaceRepoRef,
env,
loggedEnv,
stateDir,
permissionMode,
nonInteractivePermissions,
Improve ACPX adapter configuration (#5290) ## Thinking Path > - Paperclip orchestrates AI agents across several adapter implementations. > - ACPX is a local adapter path that can proxy Claude and Codex-style execution. > - Its configuration needed stronger schema defaults, provider-aware model handling, and better UI support. > - Plugin authors also need clear docs for managed resources. > - This pull request improves ACPX adapter configuration and documents plugin-managed resources. > - The benefit is a more predictable adapter setup path without changing unrelated control-plane behavior. ## What Changed - Improved ACPX config schema, execution config handling, UI build config, and route coverage. - Added ACPX model filtering support and tests. - Updated the agent config form and storybook coverage for ACPX model/provider behavior. - Expanded plugin authoring documentation for managed resources. ## Verification - `pnpm install --frozen-lockfile` - `pnpm exec vitest run server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/adapter-routes.test.ts ui/src/lib/acpx-model-filter.test.ts` ## Risks - Low-to-medium risk: adapter configuration behavior changes can affect ACPX users, but the change is isolated to ACPX/plugin-doc surfaces and covered by targeted adapter tests. ## Model Used - OpenAI GPT-5 Codex via Paperclip `codex_local` adapter, with shell/git/GitHub CLI tool use. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-05-06 06:06:47 -05:00
requestedModel,
requestedThinkingEffort,
fastMode,
Add ACPX local adapter runtime (#4893) ## Thinking Path > - Paperclip orchestrates AI-agent companies through a control plane that can start, supervise, and recover agent runs. > - Local adapters are the bridge between Paperclip issues and concrete agent runtimes such as Claude, Codex, and other ACP-compatible tools. > - The roadmap calls out broader “bring your own agent” and claw-style agent support, and ACPX gives Paperclip one path to normalize multiple ACP agents behind a single adapter. > - The branch needed to become one reviewable PR against current `paperclipai/paperclip:master`, without carrying stale base conflicts or generated lockfile churn. > - This pull request adds an experimental built-in `acpx_local` adapter, integrates it through the server/CLI/UI adapter surfaces, and adds regression coverage for runtime execution, skill sync, stream parsing, diagnostics, and log redaction. > - The benefit is that Paperclip can run Claude/Codex/custom ACP agents through ACPX while keeping operator configuration, skills, logging, and transcript rendering inside the existing adapter model. ## What Changed - Added `@paperclipai/adapter-acpx-local` with server execution, config schema, ACPX session handling, CLI formatting, UI config helpers, and stdout parsing. - Registered `acpx_local` across CLI, server, shared constants, UI adapter metadata, adapter capabilities, and agent creation/editing surfaces. - Added ACPX runtime execution support with persistent sessions, local-agent JWT environment handling, skill snapshots, runtime skill materialization, and isolation/security regressions. - Added ACPX adapter diagnostics and marked the adapter experimental in the UI. - Added command/env secret redaction for resolved command metadata in adapter-utils, server event storage, and the Agent Detail invocation UI. - Added Storybook coverage for ACPX config, transcript rendering, and skill states, plus PR screenshots under `docs/pr-screenshots/pap-2944/`. - Rebased the branch onto current `public-gh/master`; `pnpm-lock.yaml` is intentionally not included and there are no migration/schema changes. ## Verification - `pnpm exec vitest run packages/adapters/acpx-local/src/server/execute.test.ts packages/adapters/acpx-local/src/server/test.test.ts packages/adapters/acpx-local/src/cli/format-event.test.ts packages/adapters/acpx-local/src/ui/parse-stdout.test.ts packages/adapter-utils/src/server-utils.test.ts server/src/__tests__/redaction.test.ts server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/acpx-local-skill-sync.test.ts server/src/__tests__/acpx-local-adapter-environment.test.ts server/src/__tests__/adapter-routes.test.ts server/src/__tests__/agent-skills-routes.test.ts ui/src/adapters/metadata.test.ts` — 12 files, 87 tests passed. - `pnpm --filter @paperclipai/adapter-acpx-local typecheck` — passed. - `pnpm --filter @paperclipai/server typecheck` — passed. - `pnpm --filter @paperclipai/ui typecheck` — passed. - Confirmed PR diff does not include `pnpm-lock.yaml`, database schema files, or migrations. Screenshots: ![ACPX Claude skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-light.png?raw=true) ![ACPX Claude skills dark](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-dark.png?raw=true) ![ACPX custom skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-custom-light.png?raw=true) ## Risks - Medium risk: this introduces a new built-in adapter package and touches runtime execution, adapter registration, agent config, skills, and transcript rendering. - ACPX and ACP agent behavior can vary by installed tool versions; the adapter is marked experimental to set operator expectations. - `pnpm-lock.yaml` is excluded per repository PR policy, so dependency lock refresh must be handled by the repo’s automation or maintainers. - No database migration risk: no schema or migration files changed. > 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 coding agent based on GPT-5, with repository tool use, shell execution, git operations, and local verification. Exact hosted context window was not exposed in this environment. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-30 19:57:05 -05:00
timeoutSec,
sessionKey,
fingerprint,
agentCommand,
agentRegistry,
remoteExecutionIdentity,
Improve ACPX adapter configuration (#5290) ## Thinking Path > - Paperclip orchestrates AI agents across several adapter implementations. > - ACPX is a local adapter path that can proxy Claude and Codex-style execution. > - Its configuration needed stronger schema defaults, provider-aware model handling, and better UI support. > - Plugin authors also need clear docs for managed resources. > - This pull request improves ACPX adapter configuration and documents plugin-managed resources. > - The benefit is a more predictable adapter setup path without changing unrelated control-plane behavior. ## What Changed - Improved ACPX config schema, execution config handling, UI build config, and route coverage. - Added ACPX model filtering support and tests. - Updated the agent config form and storybook coverage for ACPX model/provider behavior. - Expanded plugin authoring documentation for managed resources. ## Verification - `pnpm install --frozen-lockfile` - `pnpm exec vitest run server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/adapter-routes.test.ts ui/src/lib/acpx-model-filter.test.ts` ## Risks - Low-to-medium risk: adapter configuration behavior changes can affect ACPX users, but the change is isolated to ACPX/plugin-doc surfaces and covered by targeted adapter tests. ## Model Used - OpenAI GPT-5 Codex via Paperclip `codex_local` adapter, with shell/git/GitHub CLI tool use. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-05-06 06:06:47 -05:00
skillPromptInstructions,
Add ACPX local adapter runtime (#4893) ## Thinking Path > - Paperclip orchestrates AI-agent companies through a control plane that can start, supervise, and recover agent runs. > - Local adapters are the bridge between Paperclip issues and concrete agent runtimes such as Claude, Codex, and other ACP-compatible tools. > - The roadmap calls out broader “bring your own agent” and claw-style agent support, and ACPX gives Paperclip one path to normalize multiple ACP agents behind a single adapter. > - The branch needed to become one reviewable PR against current `paperclipai/paperclip:master`, without carrying stale base conflicts or generated lockfile churn. > - This pull request adds an experimental built-in `acpx_local` adapter, integrates it through the server/CLI/UI adapter surfaces, and adds regression coverage for runtime execution, skill sync, stream parsing, diagnostics, and log redaction. > - The benefit is that Paperclip can run Claude/Codex/custom ACP agents through ACPX while keeping operator configuration, skills, logging, and transcript rendering inside the existing adapter model. ## What Changed - Added `@paperclipai/adapter-acpx-local` with server execution, config schema, ACPX session handling, CLI formatting, UI config helpers, and stdout parsing. - Registered `acpx_local` across CLI, server, shared constants, UI adapter metadata, adapter capabilities, and agent creation/editing surfaces. - Added ACPX runtime execution support with persistent sessions, local-agent JWT environment handling, skill snapshots, runtime skill materialization, and isolation/security regressions. - Added ACPX adapter diagnostics and marked the adapter experimental in the UI. - Added command/env secret redaction for resolved command metadata in adapter-utils, server event storage, and the Agent Detail invocation UI. - Added Storybook coverage for ACPX config, transcript rendering, and skill states, plus PR screenshots under `docs/pr-screenshots/pap-2944/`. - Rebased the branch onto current `public-gh/master`; `pnpm-lock.yaml` is intentionally not included and there are no migration/schema changes. ## Verification - `pnpm exec vitest run packages/adapters/acpx-local/src/server/execute.test.ts packages/adapters/acpx-local/src/server/test.test.ts packages/adapters/acpx-local/src/cli/format-event.test.ts packages/adapters/acpx-local/src/ui/parse-stdout.test.ts packages/adapter-utils/src/server-utils.test.ts server/src/__tests__/redaction.test.ts server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/acpx-local-skill-sync.test.ts server/src/__tests__/acpx-local-adapter-environment.test.ts server/src/__tests__/adapter-routes.test.ts server/src/__tests__/agent-skills-routes.test.ts ui/src/adapters/metadata.test.ts` — 12 files, 87 tests passed. - `pnpm --filter @paperclipai/adapter-acpx-local typecheck` — passed. - `pnpm --filter @paperclipai/server typecheck` — passed. - `pnpm --filter @paperclipai/ui typecheck` — passed. - Confirmed PR diff does not include `pnpm-lock.yaml`, database schema files, or migrations. Screenshots: ![ACPX Claude skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-light.png?raw=true) ![ACPX Claude skills dark](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-dark.png?raw=true) ![ACPX custom skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-custom-light.png?raw=true) ## Risks - Medium risk: this introduces a new built-in adapter package and touches runtime execution, adapter registration, agent config, skills, and transcript rendering. - ACPX and ACP agent behavior can vary by installed tool versions; the adapter is marked experimental to set operator expectations. - `pnpm-lock.yaml` is excluded per repository PR policy, so dependency lock refresh must be handled by the repo’s automation or maintainers. - No database migration risk: no schema or migration files changed. > 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 coding agent based on GPT-5, with repository tool use, shell execution, git operations, and local verification. Exact hosted context window was not exposed in this environment. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-30 19:57:05 -05:00
skillsIdentity: {
...skillsIdentity,
commandNotes: skillCommandNotes,
},
Make ACPX-Claude adapter work seamlessly (PAPA-388) (#6590) ## Thinking Path > - Paperclip orchestrates AI agents for zero-human companies, so when an adapter fails, the platform must surface enough detail for the next agent (or human reviewer) to act > - The `acpx_local` adapter wraps `claude-agent-acp`, which in turn drives the Claude Code SDK — three layers, three different permission and error-handling models > - A user created a `Claude Local ACPX` agent in PAPA-387 and it failed instantly with the generic `acpx.error / "Internal error"` log, stranding the work and triggering an opaque `stranded_assigned_issue` recovery to the CTO > - Once the diagnostic blackbox was opened, the underlying cause turned out to be two SDK-level mismatches: a model-name allowlist that rejects bare IDs like `claude-opus-4-7`, and a Claude Code permission/Read-sandbox configuration that silently denies every non-allowlisted tool when the user's `~/.claude/settings.json` has `defaultMode: "dontAsk"` > - This pull request fixes both classes of failure in the adapter itself so new ACPX agents work seamlessly without per-host configuration, and widens the diagnostic surface so the *next* failure of any kind is actionable > - The benefit is that ACPX-Claude can join the regular agent roster — verified end to end on PAPA-401, where the agent successfully reached the Paperclip API, opened a worktree, surveyed existing notification PRs, and posted a structured plan ## What Changed - Widen ACPX failure diagnostics (`packages/adapters/acpx-local/src/server/execute.ts`): - Capture `err.name`, ACP code, `cause.message`, retryable flag, and a 5-frame stack preview into `errorMeta`. - Promote phase-specific error codes: `ensure_session → acpx_session_init_failed`, `configure_session → acpx_session_config_failed`, `turn → acpx_turn_failed`, plus mapping for `ACP_BACKEND_MISSING` / `ACP_BACKEND_UNAVAILABLE`. - Set `verbose: true` on the ACPX runtime so its session-event log flows through `ctx.onLog`. - Capture child-process stderr via a wrapper-script tee into `<stateDir>/run-stderr/<runId>.log`, inline the tail into the `acpx.error` payload as `childStderrTail`, and forward it through `ctx.onLog("stderr", …)` so it lands in the heartbeat `stderrExcerpt` column (existing redaction applies). - Set the model via `ANTHROPIC_MODEL` env for the `claude` agent instead of `set_config_option(model, …)`. The ACP server's `set_config_option` handler validates against an internal allowlist and rejects bare IDs like `claude-opus-4-7`. `ANTHROPIC_MODEL` is read during initialization and bypasses that check. - Seed `<worktree>/.claude/settings.local.json` before spawning `claude-agent-acp` (the seamless-API fix). Since `claude-agent-acp` hard-codes `settingSources: ["user", "project", "local"]` and "local" has the highest precedence: - Set `permissions.defaultMode: "default"`, but **only** if the user's value is missing or `"dontAsk"` (the broken case). Other modes like `acceptEdits`/`plan` are preserved. - Pre-allow Paperclip's Bash surface (`Bash(curl:*)`, `Bash(env:*)`, `Bash(<cwd>/scripts/paperclip-issue-update.sh:*)`, `Bash(<cwd>/scripts/paperclip:*)`). - Widen `permissions.additionalDirectories` to include `stateDir`, `agentHome`, and the per-company instance root (`~/.paperclip/instances/<id>/companies/<companyId>`). Scoped to this company only — does not expose other tenants. - Existing user entries are merged, not replaced. The resolved roots are folded into the session fingerprint so warm-session handles invalidate when they change. - Sync the existing server-side integration test (`server/src/__tests__/acpx-local-execute.test.ts`) to assert `acpx_session_init_failed` instead of the now-removed `acpx_protocol_error` for `ACP_SESSION_INIT_FAILED` (a follow-up to commit 1). ## Verification - `pnpm --filter "@paperclipai/adapter-acpx-local" run typecheck` — passes. - `pnpm vitest run` in `packages/adapters/acpx-local` — 35/35 pass, includes 4 new tests covering the settings.local.json write path (claude only, merge with pre-existing content, `dontAsk` override, codex no-op). - `pnpm vitest run src/__tests__/acpx-local-execute.test.ts` in `server/` — 15/15 pass after the test-sync commit. - End-to-end manual verification (PAPA-401): the `Claude Local ACPX` agent that previously hit "restricted environment" now successfully reaches the Paperclip API, opens its worktree, posts structured plan comments, and flips the issue to `in_review` without any external configuration. ## Risks - **Low**, scoped to the `acpx_local` adapter. The settings.local.json write is per-worktree (worktrees live under `.paperclip/worktrees/<issue>/`) and only triggers when `acpxAgent === "claude"`. Existing user content is merged with `[...existing, ...paperclip]` and deduped — nothing is overwritten outright. - The `defaultMode` override is intentionally narrow: it only flips `"dontAsk"` (which silently denies every tool and is the root cause) to `"default"`. Users who explicitly picked `acceptEdits`, `plan`, or any other mode keep their choice. - Stderr capture goes through the existing `log-redaction` pass before persisting, so `PAPERCLIP_API_KEY` and similar secrets in the wrapper env don't leak into heartbeat logs. > 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 4.7 (`claude-opus-4-7`), running in the `claude_local` adapter via Paperclip's harness. Extended thinking enabled, tool use enabled. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [ ] If this change affects the UI, I have included before/after screenshots — N/A (adapter-only) - [ ] I have updated relevant documentation to reflect my changes — no user-facing docs changed; internal commentary in the code change explains the SDK constraints - [x] I have considered and documented any risks above - [ ] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-05-23 13:01:27 -07:00
childStderrLogPath,
paperclipClaudeSettings,
Add ACPX local adapter runtime (#4893) ## Thinking Path > - Paperclip orchestrates AI-agent companies through a control plane that can start, supervise, and recover agent runs. > - Local adapters are the bridge between Paperclip issues and concrete agent runtimes such as Claude, Codex, and other ACP-compatible tools. > - The roadmap calls out broader “bring your own agent” and claw-style agent support, and ACPX gives Paperclip one path to normalize multiple ACP agents behind a single adapter. > - The branch needed to become one reviewable PR against current `paperclipai/paperclip:master`, without carrying stale base conflicts or generated lockfile churn. > - This pull request adds an experimental built-in `acpx_local` adapter, integrates it through the server/CLI/UI adapter surfaces, and adds regression coverage for runtime execution, skill sync, stream parsing, diagnostics, and log redaction. > - The benefit is that Paperclip can run Claude/Codex/custom ACP agents through ACPX while keeping operator configuration, skills, logging, and transcript rendering inside the existing adapter model. ## What Changed - Added `@paperclipai/adapter-acpx-local` with server execution, config schema, ACPX session handling, CLI formatting, UI config helpers, and stdout parsing. - Registered `acpx_local` across CLI, server, shared constants, UI adapter metadata, adapter capabilities, and agent creation/editing surfaces. - Added ACPX runtime execution support with persistent sessions, local-agent JWT environment handling, skill snapshots, runtime skill materialization, and isolation/security regressions. - Added ACPX adapter diagnostics and marked the adapter experimental in the UI. - Added command/env secret redaction for resolved command metadata in adapter-utils, server event storage, and the Agent Detail invocation UI. - Added Storybook coverage for ACPX config, transcript rendering, and skill states, plus PR screenshots under `docs/pr-screenshots/pap-2944/`. - Rebased the branch onto current `public-gh/master`; `pnpm-lock.yaml` is intentionally not included and there are no migration/schema changes. ## Verification - `pnpm exec vitest run packages/adapters/acpx-local/src/server/execute.test.ts packages/adapters/acpx-local/src/server/test.test.ts packages/adapters/acpx-local/src/cli/format-event.test.ts packages/adapters/acpx-local/src/ui/parse-stdout.test.ts packages/adapter-utils/src/server-utils.test.ts server/src/__tests__/redaction.test.ts server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/acpx-local-skill-sync.test.ts server/src/__tests__/acpx-local-adapter-environment.test.ts server/src/__tests__/adapter-routes.test.ts server/src/__tests__/agent-skills-routes.test.ts ui/src/adapters/metadata.test.ts` — 12 files, 87 tests passed. - `pnpm --filter @paperclipai/adapter-acpx-local typecheck` — passed. - `pnpm --filter @paperclipai/server typecheck` — passed. - `pnpm --filter @paperclipai/ui typecheck` — passed. - Confirmed PR diff does not include `pnpm-lock.yaml`, database schema files, or migrations. Screenshots: ![ACPX Claude skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-light.png?raw=true) ![ACPX Claude skills dark](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-dark.png?raw=true) ![ACPX custom skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-custom-light.png?raw=true) ## Risks - Medium risk: this introduces a new built-in adapter package and touches runtime execution, adapter registration, agent config, skills, and transcript rendering. - ACPX and ACP agent behavior can vary by installed tool versions; the adapter is marked experimental to set operator expectations. - `pnpm-lock.yaml` is excluded per repository PR policy, so dependency lock refresh must be handled by the repo’s automation or maintainers. - No database migration risk: no schema or migration files changed. > 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 coding agent based on GPT-5, with repository tool use, shell execution, git operations, and local verification. Exact hosted context window was not exposed in this environment. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-30 19:57:05 -05:00
};
}
Improve ACPX adapter configuration (#5290) ## Thinking Path > - Paperclip orchestrates AI agents across several adapter implementations. > - ACPX is a local adapter path that can proxy Claude and Codex-style execution. > - Its configuration needed stronger schema defaults, provider-aware model handling, and better UI support. > - Plugin authors also need clear docs for managed resources. > - This pull request improves ACPX adapter configuration and documents plugin-managed resources. > - The benefit is a more predictable adapter setup path without changing unrelated control-plane behavior. ## What Changed - Improved ACPX config schema, execution config handling, UI build config, and route coverage. - Added ACPX model filtering support and tests. - Updated the agent config form and storybook coverage for ACPX model/provider behavior. - Expanded plugin authoring documentation for managed resources. ## Verification - `pnpm install --frozen-lockfile` - `pnpm exec vitest run server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/adapter-routes.test.ts ui/src/lib/acpx-model-filter.test.ts` ## Risks - Low-to-medium risk: adapter configuration behavior changes can affect ACPX users, but the change is isolated to ACPX/plugin-doc surfaces and covered by targeted adapter tests. ## Model Used - OpenAI GPT-5 Codex via Paperclip `codex_local` adapter, with shell/git/GitHub CLI tool use. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-05-06 06:06:47 -05:00
function sessionConfigOptions(prepared: AcpxPreparedRuntime): Array<{ key: string; value: string }> {
const options: Array<{ key: string; value: string }> = [];
Make ACPX-Claude adapter work seamlessly (PAPA-388) (#6590) ## Thinking Path > - Paperclip orchestrates AI agents for zero-human companies, so when an adapter fails, the platform must surface enough detail for the next agent (or human reviewer) to act > - The `acpx_local` adapter wraps `claude-agent-acp`, which in turn drives the Claude Code SDK — three layers, three different permission and error-handling models > - A user created a `Claude Local ACPX` agent in PAPA-387 and it failed instantly with the generic `acpx.error / "Internal error"` log, stranding the work and triggering an opaque `stranded_assigned_issue` recovery to the CTO > - Once the diagnostic blackbox was opened, the underlying cause turned out to be two SDK-level mismatches: a model-name allowlist that rejects bare IDs like `claude-opus-4-7`, and a Claude Code permission/Read-sandbox configuration that silently denies every non-allowlisted tool when the user's `~/.claude/settings.json` has `defaultMode: "dontAsk"` > - This pull request fixes both classes of failure in the adapter itself so new ACPX agents work seamlessly without per-host configuration, and widens the diagnostic surface so the *next* failure of any kind is actionable > - The benefit is that ACPX-Claude can join the regular agent roster — verified end to end on PAPA-401, where the agent successfully reached the Paperclip API, opened a worktree, surveyed existing notification PRs, and posted a structured plan ## What Changed - Widen ACPX failure diagnostics (`packages/adapters/acpx-local/src/server/execute.ts`): - Capture `err.name`, ACP code, `cause.message`, retryable flag, and a 5-frame stack preview into `errorMeta`. - Promote phase-specific error codes: `ensure_session → acpx_session_init_failed`, `configure_session → acpx_session_config_failed`, `turn → acpx_turn_failed`, plus mapping for `ACP_BACKEND_MISSING` / `ACP_BACKEND_UNAVAILABLE`. - Set `verbose: true` on the ACPX runtime so its session-event log flows through `ctx.onLog`. - Capture child-process stderr via a wrapper-script tee into `<stateDir>/run-stderr/<runId>.log`, inline the tail into the `acpx.error` payload as `childStderrTail`, and forward it through `ctx.onLog("stderr", …)` so it lands in the heartbeat `stderrExcerpt` column (existing redaction applies). - Set the model via `ANTHROPIC_MODEL` env for the `claude` agent instead of `set_config_option(model, …)`. The ACP server's `set_config_option` handler validates against an internal allowlist and rejects bare IDs like `claude-opus-4-7`. `ANTHROPIC_MODEL` is read during initialization and bypasses that check. - Seed `<worktree>/.claude/settings.local.json` before spawning `claude-agent-acp` (the seamless-API fix). Since `claude-agent-acp` hard-codes `settingSources: ["user", "project", "local"]` and "local" has the highest precedence: - Set `permissions.defaultMode: "default"`, but **only** if the user's value is missing or `"dontAsk"` (the broken case). Other modes like `acceptEdits`/`plan` are preserved. - Pre-allow Paperclip's Bash surface (`Bash(curl:*)`, `Bash(env:*)`, `Bash(<cwd>/scripts/paperclip-issue-update.sh:*)`, `Bash(<cwd>/scripts/paperclip:*)`). - Widen `permissions.additionalDirectories` to include `stateDir`, `agentHome`, and the per-company instance root (`~/.paperclip/instances/<id>/companies/<companyId>`). Scoped to this company only — does not expose other tenants. - Existing user entries are merged, not replaced. The resolved roots are folded into the session fingerprint so warm-session handles invalidate when they change. - Sync the existing server-side integration test (`server/src/__tests__/acpx-local-execute.test.ts`) to assert `acpx_session_init_failed` instead of the now-removed `acpx_protocol_error` for `ACP_SESSION_INIT_FAILED` (a follow-up to commit 1). ## Verification - `pnpm --filter "@paperclipai/adapter-acpx-local" run typecheck` — passes. - `pnpm vitest run` in `packages/adapters/acpx-local` — 35/35 pass, includes 4 new tests covering the settings.local.json write path (claude only, merge with pre-existing content, `dontAsk` override, codex no-op). - `pnpm vitest run src/__tests__/acpx-local-execute.test.ts` in `server/` — 15/15 pass after the test-sync commit. - End-to-end manual verification (PAPA-401): the `Claude Local ACPX` agent that previously hit "restricted environment" now successfully reaches the Paperclip API, opens its worktree, posts structured plan comments, and flips the issue to `in_review` without any external configuration. ## Risks - **Low**, scoped to the `acpx_local` adapter. The settings.local.json write is per-worktree (worktrees live under `.paperclip/worktrees/<issue>/`) and only triggers when `acpxAgent === "claude"`. Existing user content is merged with `[...existing, ...paperclip]` and deduped — nothing is overwritten outright. - The `defaultMode` override is intentionally narrow: it only flips `"dontAsk"` (which silently denies every tool and is the root cause) to `"default"`. Users who explicitly picked `acceptEdits`, `plan`, or any other mode keep their choice. - Stderr capture goes through the existing `log-redaction` pass before persisting, so `PAPERCLIP_API_KEY` and similar secrets in the wrapper env don't leak into heartbeat logs. > 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 4.7 (`claude-opus-4-7`), running in the `claude_local` adapter via Paperclip's harness. Extended thinking enabled, tool use enabled. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [ ] If this change affects the UI, I have included before/after screenshots — N/A (adapter-only) - [ ] I have updated relevant documentation to reflect my changes — no user-facing docs changed; internal commentary in the code change explains the SDK constraints - [x] I have considered and documented any risks above - [ ] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-05-23 13:01:27 -07:00
// Model for the claude agent is pre-set via ANTHROPIC_MODEL env var at
// startup; skip set_config_option to avoid ACP-server model-name validation
// that rejects bare IDs like "claude-opus-4-7" in some runtime versions.
if (prepared.requestedModel && prepared.acpxAgent !== "claude") {
options.push({ key: "model", value: prepared.requestedModel });
}
Improve ACPX adapter configuration (#5290) ## Thinking Path > - Paperclip orchestrates AI agents across several adapter implementations. > - ACPX is a local adapter path that can proxy Claude and Codex-style execution. > - Its configuration needed stronger schema defaults, provider-aware model handling, and better UI support. > - Plugin authors also need clear docs for managed resources. > - This pull request improves ACPX adapter configuration and documents plugin-managed resources. > - The benefit is a more predictable adapter setup path without changing unrelated control-plane behavior. ## What Changed - Improved ACPX config schema, execution config handling, UI build config, and route coverage. - Added ACPX model filtering support and tests. - Updated the agent config form and storybook coverage for ACPX model/provider behavior. - Expanded plugin authoring documentation for managed resources. ## Verification - `pnpm install --frozen-lockfile` - `pnpm exec vitest run server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/adapter-routes.test.ts ui/src/lib/acpx-model-filter.test.ts` ## Risks - Low-to-medium risk: adapter configuration behavior changes can affect ACPX users, but the change is isolated to ACPX/plugin-doc surfaces and covered by targeted adapter tests. ## Model Used - OpenAI GPT-5 Codex via Paperclip `codex_local` adapter, with shell/git/GitHub CLI tool use. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-05-06 06:06:47 -05:00
if (prepared.requestedThinkingEffort) {
options.push({
key: prepared.acpxAgent === "codex" ? "reasoning_effort" : "effort",
value: prepared.requestedThinkingEffort,
});
}
if (prepared.fastMode) {
options.push(
{ key: "service_tier", value: "fast" },
{ key: "features.fast_mode", value: "true" },
);
}
return options;
}
async function applySessionConfigOptions(input: {
runtime: AcpRuntime;
handle: AcpRuntimeHandle;
prepared: AcpxPreparedRuntime;
onLog: AdapterExecutionContext["onLog"];
}) {
const options = sessionConfigOptions(input.prepared);
if (options.length === 0) return;
if (!input.runtime.setConfigOption) {
const message =
"ACPX runtime does not expose session config controls; upgrade ACPX or remove configured model, effort, and fast mode overrides.";
await input.onLog("stderr", `[paperclip] ${message}\n`);
throw new Error(message);
}
for (const option of options) {
await input.runtime.setConfigOption({
handle: input.handle,
key: option.key,
value: option.value,
});
await input.onLog(
"stdout",
`[paperclip] Applied ACPX ${input.prepared.acpxAgent} config ${option.key}=${option.value}\n`,
);
}
}
Add ACPX local adapter runtime (#4893) ## Thinking Path > - Paperclip orchestrates AI-agent companies through a control plane that can start, supervise, and recover agent runs. > - Local adapters are the bridge between Paperclip issues and concrete agent runtimes such as Claude, Codex, and other ACP-compatible tools. > - The roadmap calls out broader “bring your own agent” and claw-style agent support, and ACPX gives Paperclip one path to normalize multiple ACP agents behind a single adapter. > - The branch needed to become one reviewable PR against current `paperclipai/paperclip:master`, without carrying stale base conflicts or generated lockfile churn. > - This pull request adds an experimental built-in `acpx_local` adapter, integrates it through the server/CLI/UI adapter surfaces, and adds regression coverage for runtime execution, skill sync, stream parsing, diagnostics, and log redaction. > - The benefit is that Paperclip can run Claude/Codex/custom ACP agents through ACPX while keeping operator configuration, skills, logging, and transcript rendering inside the existing adapter model. ## What Changed - Added `@paperclipai/adapter-acpx-local` with server execution, config schema, ACPX session handling, CLI formatting, UI config helpers, and stdout parsing. - Registered `acpx_local` across CLI, server, shared constants, UI adapter metadata, adapter capabilities, and agent creation/editing surfaces. - Added ACPX runtime execution support with persistent sessions, local-agent JWT environment handling, skill snapshots, runtime skill materialization, and isolation/security regressions. - Added ACPX adapter diagnostics and marked the adapter experimental in the UI. - Added command/env secret redaction for resolved command metadata in adapter-utils, server event storage, and the Agent Detail invocation UI. - Added Storybook coverage for ACPX config, transcript rendering, and skill states, plus PR screenshots under `docs/pr-screenshots/pap-2944/`. - Rebased the branch onto current `public-gh/master`; `pnpm-lock.yaml` is intentionally not included and there are no migration/schema changes. ## Verification - `pnpm exec vitest run packages/adapters/acpx-local/src/server/execute.test.ts packages/adapters/acpx-local/src/server/test.test.ts packages/adapters/acpx-local/src/cli/format-event.test.ts packages/adapters/acpx-local/src/ui/parse-stdout.test.ts packages/adapter-utils/src/server-utils.test.ts server/src/__tests__/redaction.test.ts server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/acpx-local-skill-sync.test.ts server/src/__tests__/acpx-local-adapter-environment.test.ts server/src/__tests__/adapter-routes.test.ts server/src/__tests__/agent-skills-routes.test.ts ui/src/adapters/metadata.test.ts` — 12 files, 87 tests passed. - `pnpm --filter @paperclipai/adapter-acpx-local typecheck` — passed. - `pnpm --filter @paperclipai/server typecheck` — passed. - `pnpm --filter @paperclipai/ui typecheck` — passed. - Confirmed PR diff does not include `pnpm-lock.yaml`, database schema files, or migrations. Screenshots: ![ACPX Claude skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-light.png?raw=true) ![ACPX Claude skills dark](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-dark.png?raw=true) ![ACPX custom skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-custom-light.png?raw=true) ## Risks - Medium risk: this introduces a new built-in adapter package and touches runtime execution, adapter registration, agent config, skills, and transcript rendering. - ACPX and ACP agent behavior can vary by installed tool versions; the adapter is marked experimental to set operator expectations. - `pnpm-lock.yaml` is excluded per repository PR policy, so dependency lock refresh must be handled by the repo’s automation or maintainers. - No database migration risk: no schema or migration files changed. > 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 coding agent based on GPT-5, with repository tool use, shell execution, git operations, and local verification. Exact hosted context window was not exposed in this environment. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-30 19:57:05 -05:00
async function buildPrompt(ctx: AdapterExecutionContext, resumedSession: boolean): Promise<{
prompt: string;
promptMetrics: Record<string, number>;
commandNotes: string[];
}> {
const { agent, runId, config, context, onLog } = ctx;
const promptTemplate = asString(config.promptTemplate, DEFAULT_PAPERCLIP_AGENT_PROMPT_TEMPLATE);
const instructionsFilePath = asString(config.instructionsFilePath, "").trim();
const instructionsDir = instructionsFilePath ? `${path.dirname(instructionsFilePath)}/` : "";
let instructionsPrefix = "";
const commandNotes: string[] = [];
if (instructionsFilePath) {
try {
const instructionsContents = await fs.readFile(instructionsFilePath, "utf8");
instructionsPrefix =
`${instructionsContents}\n\n` +
`The above agent instructions were loaded from ${instructionsFilePath}. ` +
`Resolve any relative file references from ${instructionsDir}.\n\n`;
commandNotes.push(
`Loaded agent instructions from ${instructionsFilePath}`,
`Prepended instructions + path directive to the ACPX prompt (relative references from ${instructionsDir}).`,
);
} catch (err) {
const reason = err instanceof Error ? err.message : String(err);
await onLog(
"stderr",
`[paperclip] Warning: could not read agent instructions file "${instructionsFilePath}": ${reason}\n`,
);
commandNotes.push(`Configured instructionsFilePath ${instructionsFilePath}, but file could not be read.`);
}
}
const bootstrapPromptTemplate = asString(config.bootstrapPromptTemplate, "");
const templateData = {
agentId: agent.id,
companyId: agent.companyId,
runId,
company: { id: agent.companyId },
agent,
run: { id: runId, source: "on_demand" },
context,
};
const renderedBootstrapPrompt =
!resumedSession && bootstrapPromptTemplate.trim().length > 0
? renderTemplate(bootstrapPromptTemplate, templateData).trim()
: "";
const wakePrompt = renderPaperclipWakePrompt(context.paperclipWake, { resumedSession });
const shouldUseResumeDeltaPrompt = resumedSession && wakePrompt.length > 0;
const promptInstructionsPrefix = shouldUseResumeDeltaPrompt ? "" : instructionsPrefix;
const renderedPrompt = shouldUseResumeDeltaPrompt ? "" : renderTemplate(promptTemplate, templateData);
const sessionHandoffNote = asString(context.paperclipSessionHandoffMarkdown, "").trim();
const taskContextNote = asString(context.paperclipTaskMarkdown, "").trim();
const prompt = joinPromptSections([
promptInstructionsPrefix,
renderedBootstrapPrompt,
wakePrompt,
sessionHandoffNote,
taskContextNote,
renderedPrompt,
]);
return {
prompt,
commandNotes,
promptMetrics: {
promptChars: prompt.length,
instructionsChars: promptInstructionsPrefix.length,
bootstrapPromptChars: renderedBootstrapPrompt.length,
wakePromptChars: wakePrompt.length,
sessionHandoffChars: sessionHandoffNote.length,
taskContextChars: taskContextNote.length,
heartbeatPromptChars: renderedPrompt.length,
},
};
}
async function emitAcpxLog(ctx: AdapterExecutionContext, payload: Record<string, unknown>) {
await ctx.onLog("stdout", `${JSON.stringify(payload)}\n`);
}
async function emitRuntimeEvent(ctx: AdapterExecutionContext, event: AcpRuntimeEvent) {
if (event.type === "text_delta") {
await emitAcpxLog(ctx, {
type: "acpx.text_delta",
text: event.text,
channel: event.stream === "thought" ? "thought" : "output",
tag: event.tag,
});
return;
}
if (event.type === "tool_call") {
await emitAcpxLog(ctx, {
type: "acpx.tool_call",
name: event.title ?? "acp_tool",
toolCallId: event.toolCallId,
status: event.status,
text: event.text,
tag: event.tag,
});
return;
}
if (event.type === "status") {
await emitAcpxLog(ctx, {
type: "acpx.status",
text: event.text,
tag: event.tag,
used: event.used,
size: event.size,
});
return;
}
if (event.type === "done") {
await emitAcpxLog(ctx, {
type: "acpx.result",
summary: event.stopReason ?? "completed",
stopReason: event.stopReason,
});
return;
}
if (event.type === "error") {
await emitAcpxLog(ctx, {
type: "acpx.error",
message: event.message,
code: event.code,
retryable: event.retryable,
});
}
}
function resultErrorMessage(result: AcpRuntimeTurnResult): string | null {
if (result.status !== "failed") return null;
return result.error.message;
}
Make ACPX-Claude adapter work seamlessly (PAPA-388) (#6590) ## Thinking Path > - Paperclip orchestrates AI agents for zero-human companies, so when an adapter fails, the platform must surface enough detail for the next agent (or human reviewer) to act > - The `acpx_local` adapter wraps `claude-agent-acp`, which in turn drives the Claude Code SDK — three layers, three different permission and error-handling models > - A user created a `Claude Local ACPX` agent in PAPA-387 and it failed instantly with the generic `acpx.error / "Internal error"` log, stranding the work and triggering an opaque `stranded_assigned_issue` recovery to the CTO > - Once the diagnostic blackbox was opened, the underlying cause turned out to be two SDK-level mismatches: a model-name allowlist that rejects bare IDs like `claude-opus-4-7`, and a Claude Code permission/Read-sandbox configuration that silently denies every non-allowlisted tool when the user's `~/.claude/settings.json` has `defaultMode: "dontAsk"` > - This pull request fixes both classes of failure in the adapter itself so new ACPX agents work seamlessly without per-host configuration, and widens the diagnostic surface so the *next* failure of any kind is actionable > - The benefit is that ACPX-Claude can join the regular agent roster — verified end to end on PAPA-401, where the agent successfully reached the Paperclip API, opened a worktree, surveyed existing notification PRs, and posted a structured plan ## What Changed - Widen ACPX failure diagnostics (`packages/adapters/acpx-local/src/server/execute.ts`): - Capture `err.name`, ACP code, `cause.message`, retryable flag, and a 5-frame stack preview into `errorMeta`. - Promote phase-specific error codes: `ensure_session → acpx_session_init_failed`, `configure_session → acpx_session_config_failed`, `turn → acpx_turn_failed`, plus mapping for `ACP_BACKEND_MISSING` / `ACP_BACKEND_UNAVAILABLE`. - Set `verbose: true` on the ACPX runtime so its session-event log flows through `ctx.onLog`. - Capture child-process stderr via a wrapper-script tee into `<stateDir>/run-stderr/<runId>.log`, inline the tail into the `acpx.error` payload as `childStderrTail`, and forward it through `ctx.onLog("stderr", …)` so it lands in the heartbeat `stderrExcerpt` column (existing redaction applies). - Set the model via `ANTHROPIC_MODEL` env for the `claude` agent instead of `set_config_option(model, …)`. The ACP server's `set_config_option` handler validates against an internal allowlist and rejects bare IDs like `claude-opus-4-7`. `ANTHROPIC_MODEL` is read during initialization and bypasses that check. - Seed `<worktree>/.claude/settings.local.json` before spawning `claude-agent-acp` (the seamless-API fix). Since `claude-agent-acp` hard-codes `settingSources: ["user", "project", "local"]` and "local" has the highest precedence: - Set `permissions.defaultMode: "default"`, but **only** if the user's value is missing or `"dontAsk"` (the broken case). Other modes like `acceptEdits`/`plan` are preserved. - Pre-allow Paperclip's Bash surface (`Bash(curl:*)`, `Bash(env:*)`, `Bash(<cwd>/scripts/paperclip-issue-update.sh:*)`, `Bash(<cwd>/scripts/paperclip:*)`). - Widen `permissions.additionalDirectories` to include `stateDir`, `agentHome`, and the per-company instance root (`~/.paperclip/instances/<id>/companies/<companyId>`). Scoped to this company only — does not expose other tenants. - Existing user entries are merged, not replaced. The resolved roots are folded into the session fingerprint so warm-session handles invalidate when they change. - Sync the existing server-side integration test (`server/src/__tests__/acpx-local-execute.test.ts`) to assert `acpx_session_init_failed` instead of the now-removed `acpx_protocol_error` for `ACP_SESSION_INIT_FAILED` (a follow-up to commit 1). ## Verification - `pnpm --filter "@paperclipai/adapter-acpx-local" run typecheck` — passes. - `pnpm vitest run` in `packages/adapters/acpx-local` — 35/35 pass, includes 4 new tests covering the settings.local.json write path (claude only, merge with pre-existing content, `dontAsk` override, codex no-op). - `pnpm vitest run src/__tests__/acpx-local-execute.test.ts` in `server/` — 15/15 pass after the test-sync commit. - End-to-end manual verification (PAPA-401): the `Claude Local ACPX` agent that previously hit "restricted environment" now successfully reaches the Paperclip API, opens its worktree, posts structured plan comments, and flips the issue to `in_review` without any external configuration. ## Risks - **Low**, scoped to the `acpx_local` adapter. The settings.local.json write is per-worktree (worktrees live under `.paperclip/worktrees/<issue>/`) and only triggers when `acpxAgent === "claude"`. Existing user content is merged with `[...existing, ...paperclip]` and deduped — nothing is overwritten outright. - The `defaultMode` override is intentionally narrow: it only flips `"dontAsk"` (which silently denies every tool and is the root cause) to `"default"`. Users who explicitly picked `acceptEdits`, `plan`, or any other mode keep their choice. - Stderr capture goes through the existing `log-redaction` pass before persisting, so `PAPERCLIP_API_KEY` and similar secrets in the wrapper env don't leak into heartbeat logs. > 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 4.7 (`claude-opus-4-7`), running in the `claude_local` adapter via Paperclip's harness. Extended thinking enabled, tool use enabled. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [ ] If this change affects the UI, I have included before/after screenshots — N/A (adapter-only) - [ ] I have updated relevant documentation to reflect my changes — no user-facing docs changed; internal commentary in the code change explains the SDK constraints - [x] I have considered and documented any risks above - [ ] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-05-23 13:01:27 -07:00
type AcpxExecutionPhase = "ensure_session" | "configure_session" | "turn";
function describeErrorDiagnostics(err: unknown): {
errorName: string;
acpCode: string | null;
causeMessage: string | null;
retryable: boolean | null;
stackPreview: string | null;
} {
const errorName =
err instanceof Error ? err.name || err.constructor.name : typeof err;
Add ACPX local adapter runtime (#4893) ## Thinking Path > - Paperclip orchestrates AI-agent companies through a control plane that can start, supervise, and recover agent runs. > - Local adapters are the bridge between Paperclip issues and concrete agent runtimes such as Claude, Codex, and other ACP-compatible tools. > - The roadmap calls out broader “bring your own agent” and claw-style agent support, and ACPX gives Paperclip one path to normalize multiple ACP agents behind a single adapter. > - The branch needed to become one reviewable PR against current `paperclipai/paperclip:master`, without carrying stale base conflicts or generated lockfile churn. > - This pull request adds an experimental built-in `acpx_local` adapter, integrates it through the server/CLI/UI adapter surfaces, and adds regression coverage for runtime execution, skill sync, stream parsing, diagnostics, and log redaction. > - The benefit is that Paperclip can run Claude/Codex/custom ACP agents through ACPX while keeping operator configuration, skills, logging, and transcript rendering inside the existing adapter model. ## What Changed - Added `@paperclipai/adapter-acpx-local` with server execution, config schema, ACPX session handling, CLI formatting, UI config helpers, and stdout parsing. - Registered `acpx_local` across CLI, server, shared constants, UI adapter metadata, adapter capabilities, and agent creation/editing surfaces. - Added ACPX runtime execution support with persistent sessions, local-agent JWT environment handling, skill snapshots, runtime skill materialization, and isolation/security regressions. - Added ACPX adapter diagnostics and marked the adapter experimental in the UI. - Added command/env secret redaction for resolved command metadata in adapter-utils, server event storage, and the Agent Detail invocation UI. - Added Storybook coverage for ACPX config, transcript rendering, and skill states, plus PR screenshots under `docs/pr-screenshots/pap-2944/`. - Rebased the branch onto current `public-gh/master`; `pnpm-lock.yaml` is intentionally not included and there are no migration/schema changes. ## Verification - `pnpm exec vitest run packages/adapters/acpx-local/src/server/execute.test.ts packages/adapters/acpx-local/src/server/test.test.ts packages/adapters/acpx-local/src/cli/format-event.test.ts packages/adapters/acpx-local/src/ui/parse-stdout.test.ts packages/adapter-utils/src/server-utils.test.ts server/src/__tests__/redaction.test.ts server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/acpx-local-skill-sync.test.ts server/src/__tests__/acpx-local-adapter-environment.test.ts server/src/__tests__/adapter-routes.test.ts server/src/__tests__/agent-skills-routes.test.ts ui/src/adapters/metadata.test.ts` — 12 files, 87 tests passed. - `pnpm --filter @paperclipai/adapter-acpx-local typecheck` — passed. - `pnpm --filter @paperclipai/server typecheck` — passed. - `pnpm --filter @paperclipai/ui typecheck` — passed. - Confirmed PR diff does not include `pnpm-lock.yaml`, database schema files, or migrations. Screenshots: ![ACPX Claude skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-light.png?raw=true) ![ACPX Claude skills dark](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-dark.png?raw=true) ![ACPX custom skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-custom-light.png?raw=true) ## Risks - Medium risk: this introduces a new built-in adapter package and touches runtime execution, adapter registration, agent config, skills, and transcript rendering. - ACPX and ACP agent behavior can vary by installed tool versions; the adapter is marked experimental to set operator expectations. - `pnpm-lock.yaml` is excluded per repository PR policy, so dependency lock refresh must be handled by the repo’s automation or maintainers. - No database migration risk: no schema or migration files changed. > 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 coding agent based on GPT-5, with repository tool use, shell execution, git operations, and local verification. Exact hosted context window was not exposed in this environment. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-30 19:57:05 -05:00
const maybeCode =
err && typeof err === "object" && typeof (err as { code?: unknown }).code === "string"
? (err as { code: string }).code
: null;
Make ACPX-Claude adapter work seamlessly (PAPA-388) (#6590) ## Thinking Path > - Paperclip orchestrates AI agents for zero-human companies, so when an adapter fails, the platform must surface enough detail for the next agent (or human reviewer) to act > - The `acpx_local` adapter wraps `claude-agent-acp`, which in turn drives the Claude Code SDK — three layers, three different permission and error-handling models > - A user created a `Claude Local ACPX` agent in PAPA-387 and it failed instantly with the generic `acpx.error / "Internal error"` log, stranding the work and triggering an opaque `stranded_assigned_issue` recovery to the CTO > - Once the diagnostic blackbox was opened, the underlying cause turned out to be two SDK-level mismatches: a model-name allowlist that rejects bare IDs like `claude-opus-4-7`, and a Claude Code permission/Read-sandbox configuration that silently denies every non-allowlisted tool when the user's `~/.claude/settings.json` has `defaultMode: "dontAsk"` > - This pull request fixes both classes of failure in the adapter itself so new ACPX agents work seamlessly without per-host configuration, and widens the diagnostic surface so the *next* failure of any kind is actionable > - The benefit is that ACPX-Claude can join the regular agent roster — verified end to end on PAPA-401, where the agent successfully reached the Paperclip API, opened a worktree, surveyed existing notification PRs, and posted a structured plan ## What Changed - Widen ACPX failure diagnostics (`packages/adapters/acpx-local/src/server/execute.ts`): - Capture `err.name`, ACP code, `cause.message`, retryable flag, and a 5-frame stack preview into `errorMeta`. - Promote phase-specific error codes: `ensure_session → acpx_session_init_failed`, `configure_session → acpx_session_config_failed`, `turn → acpx_turn_failed`, plus mapping for `ACP_BACKEND_MISSING` / `ACP_BACKEND_UNAVAILABLE`. - Set `verbose: true` on the ACPX runtime so its session-event log flows through `ctx.onLog`. - Capture child-process stderr via a wrapper-script tee into `<stateDir>/run-stderr/<runId>.log`, inline the tail into the `acpx.error` payload as `childStderrTail`, and forward it through `ctx.onLog("stderr", …)` so it lands in the heartbeat `stderrExcerpt` column (existing redaction applies). - Set the model via `ANTHROPIC_MODEL` env for the `claude` agent instead of `set_config_option(model, …)`. The ACP server's `set_config_option` handler validates against an internal allowlist and rejects bare IDs like `claude-opus-4-7`. `ANTHROPIC_MODEL` is read during initialization and bypasses that check. - Seed `<worktree>/.claude/settings.local.json` before spawning `claude-agent-acp` (the seamless-API fix). Since `claude-agent-acp` hard-codes `settingSources: ["user", "project", "local"]` and "local" has the highest precedence: - Set `permissions.defaultMode: "default"`, but **only** if the user's value is missing or `"dontAsk"` (the broken case). Other modes like `acceptEdits`/`plan` are preserved. - Pre-allow Paperclip's Bash surface (`Bash(curl:*)`, `Bash(env:*)`, `Bash(<cwd>/scripts/paperclip-issue-update.sh:*)`, `Bash(<cwd>/scripts/paperclip:*)`). - Widen `permissions.additionalDirectories` to include `stateDir`, `agentHome`, and the per-company instance root (`~/.paperclip/instances/<id>/companies/<companyId>`). Scoped to this company only — does not expose other tenants. - Existing user entries are merged, not replaced. The resolved roots are folded into the session fingerprint so warm-session handles invalidate when they change. - Sync the existing server-side integration test (`server/src/__tests__/acpx-local-execute.test.ts`) to assert `acpx_session_init_failed` instead of the now-removed `acpx_protocol_error` for `ACP_SESSION_INIT_FAILED` (a follow-up to commit 1). ## Verification - `pnpm --filter "@paperclipai/adapter-acpx-local" run typecheck` — passes. - `pnpm vitest run` in `packages/adapters/acpx-local` — 35/35 pass, includes 4 new tests covering the settings.local.json write path (claude only, merge with pre-existing content, `dontAsk` override, codex no-op). - `pnpm vitest run src/__tests__/acpx-local-execute.test.ts` in `server/` — 15/15 pass after the test-sync commit. - End-to-end manual verification (PAPA-401): the `Claude Local ACPX` agent that previously hit "restricted environment" now successfully reaches the Paperclip API, opens its worktree, posts structured plan comments, and flips the issue to `in_review` without any external configuration. ## Risks - **Low**, scoped to the `acpx_local` adapter. The settings.local.json write is per-worktree (worktrees live under `.paperclip/worktrees/<issue>/`) and only triggers when `acpxAgent === "claude"`. Existing user content is merged with `[...existing, ...paperclip]` and deduped — nothing is overwritten outright. - The `defaultMode` override is intentionally narrow: it only flips `"dontAsk"` (which silently denies every tool and is the root cause) to `"default"`. Users who explicitly picked `acceptEdits`, `plan`, or any other mode keep their choice. - Stderr capture goes through the existing `log-redaction` pass before persisting, so `PAPERCLIP_API_KEY` and similar secrets in the wrapper env don't leak into heartbeat logs. > 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 4.7 (`claude-opus-4-7`), running in the `claude_local` adapter via Paperclip's harness. Extended thinking enabled, tool use enabled. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [ ] If this change affects the UI, I have included before/after screenshots — N/A (adapter-only) - [ ] I have updated relevant documentation to reflect my changes — no user-facing docs changed; internal commentary in the code change explains the SDK constraints - [x] I have considered and documented any risks above - [ ] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-05-23 13:01:27 -07:00
const acpCode =
isAcpRuntimeError(err) || (maybeCode?.startsWith("ACP_") ?? false) ? maybeCode : null;
const cause =
err && typeof err === "object" && (err as { cause?: unknown }).cause !== undefined
? (err as { cause?: unknown }).cause
: undefined;
const causeMessage =
cause instanceof Error
? cause.message
: typeof cause === "string"
? cause
: null;
const retryable =
err && typeof err === "object" && typeof (err as { retryable?: unknown }).retryable === "boolean"
? (err as { retryable: boolean }).retryable
: null;
const stack = err instanceof Error && typeof err.stack === "string" ? err.stack : "";
const stackPreview = stack ? stack.split("\n").slice(0, 6).join("\n") : null;
return { errorName, acpCode, causeMessage, retryable, stackPreview };
}
function classifyError(
err: unknown,
phase?: AcpxExecutionPhase,
): Pick<AdapterExecutionResult, "errorCode" | "errorMeta"> {
const message = err instanceof Error ? err.message : String(err);
const diagnostics = describeErrorDiagnostics(err);
const { acpCode, errorName, causeMessage, retryable, stackPreview } = diagnostics;
const baseMeta: Record<string, unknown> = {
errorName,
...(acpCode ? { acpCode } : {}),
...(causeMessage ? { causeMessage } : {}),
...(retryable !== null ? { retryable } : {}),
...(stackPreview ? { stackPreview } : {}),
...(phase ? { phase } : {}),
};
Add ACPX local adapter runtime (#4893) ## Thinking Path > - Paperclip orchestrates AI-agent companies through a control plane that can start, supervise, and recover agent runs. > - Local adapters are the bridge between Paperclip issues and concrete agent runtimes such as Claude, Codex, and other ACP-compatible tools. > - The roadmap calls out broader “bring your own agent” and claw-style agent support, and ACPX gives Paperclip one path to normalize multiple ACP agents behind a single adapter. > - The branch needed to become one reviewable PR against current `paperclipai/paperclip:master`, without carrying stale base conflicts or generated lockfile churn. > - This pull request adds an experimental built-in `acpx_local` adapter, integrates it through the server/CLI/UI adapter surfaces, and adds regression coverage for runtime execution, skill sync, stream parsing, diagnostics, and log redaction. > - The benefit is that Paperclip can run Claude/Codex/custom ACP agents through ACPX while keeping operator configuration, skills, logging, and transcript rendering inside the existing adapter model. ## What Changed - Added `@paperclipai/adapter-acpx-local` with server execution, config schema, ACPX session handling, CLI formatting, UI config helpers, and stdout parsing. - Registered `acpx_local` across CLI, server, shared constants, UI adapter metadata, adapter capabilities, and agent creation/editing surfaces. - Added ACPX runtime execution support with persistent sessions, local-agent JWT environment handling, skill snapshots, runtime skill materialization, and isolation/security regressions. - Added ACPX adapter diagnostics and marked the adapter experimental in the UI. - Added command/env secret redaction for resolved command metadata in adapter-utils, server event storage, and the Agent Detail invocation UI. - Added Storybook coverage for ACPX config, transcript rendering, and skill states, plus PR screenshots under `docs/pr-screenshots/pap-2944/`. - Rebased the branch onto current `public-gh/master`; `pnpm-lock.yaml` is intentionally not included and there are no migration/schema changes. ## Verification - `pnpm exec vitest run packages/adapters/acpx-local/src/server/execute.test.ts packages/adapters/acpx-local/src/server/test.test.ts packages/adapters/acpx-local/src/cli/format-event.test.ts packages/adapters/acpx-local/src/ui/parse-stdout.test.ts packages/adapter-utils/src/server-utils.test.ts server/src/__tests__/redaction.test.ts server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/acpx-local-skill-sync.test.ts server/src/__tests__/acpx-local-adapter-environment.test.ts server/src/__tests__/adapter-routes.test.ts server/src/__tests__/agent-skills-routes.test.ts ui/src/adapters/metadata.test.ts` — 12 files, 87 tests passed. - `pnpm --filter @paperclipai/adapter-acpx-local typecheck` — passed. - `pnpm --filter @paperclipai/server typecheck` — passed. - `pnpm --filter @paperclipai/ui typecheck` — passed. - Confirmed PR diff does not include `pnpm-lock.yaml`, database schema files, or migrations. Screenshots: ![ACPX Claude skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-light.png?raw=true) ![ACPX Claude skills dark](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-dark.png?raw=true) ![ACPX custom skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-custom-light.png?raw=true) ## Risks - Medium risk: this introduces a new built-in adapter package and touches runtime execution, adapter registration, agent config, skills, and transcript rendering. - ACPX and ACP agent behavior can vary by installed tool versions; the adapter is marked experimental to set operator expectations. - `pnpm-lock.yaml` is excluded per repository PR policy, so dependency lock refresh must be handled by the repo’s automation or maintainers. - No database migration risk: no schema or migration files changed. > 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 coding agent based on GPT-5, with repository tool use, shell execution, git operations, and local verification. Exact hosted context window was not exposed in this environment. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-30 19:57:05 -05:00
const lower = message.toLowerCase();
const authLike = lower.includes("auth") || lower.includes("login") || lower.includes("credential");
if (authLike) {
return {
errorCode: "acpx_auth_required",
Make ACPX-Claude adapter work seamlessly (PAPA-388) (#6590) ## Thinking Path > - Paperclip orchestrates AI agents for zero-human companies, so when an adapter fails, the platform must surface enough detail for the next agent (or human reviewer) to act > - The `acpx_local` adapter wraps `claude-agent-acp`, which in turn drives the Claude Code SDK — three layers, three different permission and error-handling models > - A user created a `Claude Local ACPX` agent in PAPA-387 and it failed instantly with the generic `acpx.error / "Internal error"` log, stranding the work and triggering an opaque `stranded_assigned_issue` recovery to the CTO > - Once the diagnostic blackbox was opened, the underlying cause turned out to be two SDK-level mismatches: a model-name allowlist that rejects bare IDs like `claude-opus-4-7`, and a Claude Code permission/Read-sandbox configuration that silently denies every non-allowlisted tool when the user's `~/.claude/settings.json` has `defaultMode: "dontAsk"` > - This pull request fixes both classes of failure in the adapter itself so new ACPX agents work seamlessly without per-host configuration, and widens the diagnostic surface so the *next* failure of any kind is actionable > - The benefit is that ACPX-Claude can join the regular agent roster — verified end to end on PAPA-401, where the agent successfully reached the Paperclip API, opened a worktree, surveyed existing notification PRs, and posted a structured plan ## What Changed - Widen ACPX failure diagnostics (`packages/adapters/acpx-local/src/server/execute.ts`): - Capture `err.name`, ACP code, `cause.message`, retryable flag, and a 5-frame stack preview into `errorMeta`. - Promote phase-specific error codes: `ensure_session → acpx_session_init_failed`, `configure_session → acpx_session_config_failed`, `turn → acpx_turn_failed`, plus mapping for `ACP_BACKEND_MISSING` / `ACP_BACKEND_UNAVAILABLE`. - Set `verbose: true` on the ACPX runtime so its session-event log flows through `ctx.onLog`. - Capture child-process stderr via a wrapper-script tee into `<stateDir>/run-stderr/<runId>.log`, inline the tail into the `acpx.error` payload as `childStderrTail`, and forward it through `ctx.onLog("stderr", …)` so it lands in the heartbeat `stderrExcerpt` column (existing redaction applies). - Set the model via `ANTHROPIC_MODEL` env for the `claude` agent instead of `set_config_option(model, …)`. The ACP server's `set_config_option` handler validates against an internal allowlist and rejects bare IDs like `claude-opus-4-7`. `ANTHROPIC_MODEL` is read during initialization and bypasses that check. - Seed `<worktree>/.claude/settings.local.json` before spawning `claude-agent-acp` (the seamless-API fix). Since `claude-agent-acp` hard-codes `settingSources: ["user", "project", "local"]` and "local" has the highest precedence: - Set `permissions.defaultMode: "default"`, but **only** if the user's value is missing or `"dontAsk"` (the broken case). Other modes like `acceptEdits`/`plan` are preserved. - Pre-allow Paperclip's Bash surface (`Bash(curl:*)`, `Bash(env:*)`, `Bash(<cwd>/scripts/paperclip-issue-update.sh:*)`, `Bash(<cwd>/scripts/paperclip:*)`). - Widen `permissions.additionalDirectories` to include `stateDir`, `agentHome`, and the per-company instance root (`~/.paperclip/instances/<id>/companies/<companyId>`). Scoped to this company only — does not expose other tenants. - Existing user entries are merged, not replaced. The resolved roots are folded into the session fingerprint so warm-session handles invalidate when they change. - Sync the existing server-side integration test (`server/src/__tests__/acpx-local-execute.test.ts`) to assert `acpx_session_init_failed` instead of the now-removed `acpx_protocol_error` for `ACP_SESSION_INIT_FAILED` (a follow-up to commit 1). ## Verification - `pnpm --filter "@paperclipai/adapter-acpx-local" run typecheck` — passes. - `pnpm vitest run` in `packages/adapters/acpx-local` — 35/35 pass, includes 4 new tests covering the settings.local.json write path (claude only, merge with pre-existing content, `dontAsk` override, codex no-op). - `pnpm vitest run src/__tests__/acpx-local-execute.test.ts` in `server/` — 15/15 pass after the test-sync commit. - End-to-end manual verification (PAPA-401): the `Claude Local ACPX` agent that previously hit "restricted environment" now successfully reaches the Paperclip API, opens its worktree, posts structured plan comments, and flips the issue to `in_review` without any external configuration. ## Risks - **Low**, scoped to the `acpx_local` adapter. The settings.local.json write is per-worktree (worktrees live under `.paperclip/worktrees/<issue>/`) and only triggers when `acpxAgent === "claude"`. Existing user content is merged with `[...existing, ...paperclip]` and deduped — nothing is overwritten outright. - The `defaultMode` override is intentionally narrow: it only flips `"dontAsk"` (which silently denies every tool and is the root cause) to `"default"`. Users who explicitly picked `acceptEdits`, `plan`, or any other mode keep their choice. - Stderr capture goes through the existing `log-redaction` pass before persisting, so `PAPERCLIP_API_KEY` and similar secrets in the wrapper env don't leak into heartbeat logs. > 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 4.7 (`claude-opus-4-7`), running in the `claude_local` adapter via Paperclip's harness. Extended thinking enabled, tool use enabled. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [ ] If this change affects the UI, I have included before/after screenshots — N/A (adapter-only) - [ ] I have updated relevant documentation to reflect my changes — no user-facing docs changed; internal commentary in the code change explains the SDK constraints - [x] I have considered and documented any risks above - [ ] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-05-23 13:01:27 -07:00
errorMeta: { category: "auth", ...baseMeta },
};
}
const phaseCode = (() => {
if (acpCode === "ACP_SESSION_INIT_FAILED") return "acpx_session_init_failed";
if (acpCode === "ACP_TURN_FAILED") return "acpx_turn_failed";
if (acpCode === "ACP_BACKEND_MISSING") return "acpx_backend_missing";
if (acpCode === "ACP_BACKEND_UNAVAILABLE") return "acpx_backend_unavailable";
if (phase === "ensure_session") return "acpx_session_init_failed";
if (phase === "configure_session") return "acpx_session_config_failed";
if (phase === "turn") return "acpx_turn_failed";
return null;
})();
if (phaseCode) {
return {
errorCode: phaseCode,
errorMeta: { category: acpCode ? "protocol" : "runtime", ...baseMeta },
Add ACPX local adapter runtime (#4893) ## Thinking Path > - Paperclip orchestrates AI-agent companies through a control plane that can start, supervise, and recover agent runs. > - Local adapters are the bridge between Paperclip issues and concrete agent runtimes such as Claude, Codex, and other ACP-compatible tools. > - The roadmap calls out broader “bring your own agent” and claw-style agent support, and ACPX gives Paperclip one path to normalize multiple ACP agents behind a single adapter. > - The branch needed to become one reviewable PR against current `paperclipai/paperclip:master`, without carrying stale base conflicts or generated lockfile churn. > - This pull request adds an experimental built-in `acpx_local` adapter, integrates it through the server/CLI/UI adapter surfaces, and adds regression coverage for runtime execution, skill sync, stream parsing, diagnostics, and log redaction. > - The benefit is that Paperclip can run Claude/Codex/custom ACP agents through ACPX while keeping operator configuration, skills, logging, and transcript rendering inside the existing adapter model. ## What Changed - Added `@paperclipai/adapter-acpx-local` with server execution, config schema, ACPX session handling, CLI formatting, UI config helpers, and stdout parsing. - Registered `acpx_local` across CLI, server, shared constants, UI adapter metadata, adapter capabilities, and agent creation/editing surfaces. - Added ACPX runtime execution support with persistent sessions, local-agent JWT environment handling, skill snapshots, runtime skill materialization, and isolation/security regressions. - Added ACPX adapter diagnostics and marked the adapter experimental in the UI. - Added command/env secret redaction for resolved command metadata in adapter-utils, server event storage, and the Agent Detail invocation UI. - Added Storybook coverage for ACPX config, transcript rendering, and skill states, plus PR screenshots under `docs/pr-screenshots/pap-2944/`. - Rebased the branch onto current `public-gh/master`; `pnpm-lock.yaml` is intentionally not included and there are no migration/schema changes. ## Verification - `pnpm exec vitest run packages/adapters/acpx-local/src/server/execute.test.ts packages/adapters/acpx-local/src/server/test.test.ts packages/adapters/acpx-local/src/cli/format-event.test.ts packages/adapters/acpx-local/src/ui/parse-stdout.test.ts packages/adapter-utils/src/server-utils.test.ts server/src/__tests__/redaction.test.ts server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/acpx-local-skill-sync.test.ts server/src/__tests__/acpx-local-adapter-environment.test.ts server/src/__tests__/adapter-routes.test.ts server/src/__tests__/agent-skills-routes.test.ts ui/src/adapters/metadata.test.ts` — 12 files, 87 tests passed. - `pnpm --filter @paperclipai/adapter-acpx-local typecheck` — passed. - `pnpm --filter @paperclipai/server typecheck` — passed. - `pnpm --filter @paperclipai/ui typecheck` — passed. - Confirmed PR diff does not include `pnpm-lock.yaml`, database schema files, or migrations. Screenshots: ![ACPX Claude skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-light.png?raw=true) ![ACPX Claude skills dark](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-dark.png?raw=true) ![ACPX custom skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-custom-light.png?raw=true) ## Risks - Medium risk: this introduces a new built-in adapter package and touches runtime execution, adapter registration, agent config, skills, and transcript rendering. - ACPX and ACP agent behavior can vary by installed tool versions; the adapter is marked experimental to set operator expectations. - `pnpm-lock.yaml` is excluded per repository PR policy, so dependency lock refresh must be handled by the repo’s automation or maintainers. - No database migration risk: no schema or migration files changed. > 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 coding agent based on GPT-5, with repository tool use, shell execution, git operations, and local verification. Exact hosted context window was not exposed in this environment. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-30 19:57:05 -05:00
};
}
if (acpCode) {
return {
errorCode: "acpx_protocol_error",
Make ACPX-Claude adapter work seamlessly (PAPA-388) (#6590) ## Thinking Path > - Paperclip orchestrates AI agents for zero-human companies, so when an adapter fails, the platform must surface enough detail for the next agent (or human reviewer) to act > - The `acpx_local` adapter wraps `claude-agent-acp`, which in turn drives the Claude Code SDK — three layers, three different permission and error-handling models > - A user created a `Claude Local ACPX` agent in PAPA-387 and it failed instantly with the generic `acpx.error / "Internal error"` log, stranding the work and triggering an opaque `stranded_assigned_issue` recovery to the CTO > - Once the diagnostic blackbox was opened, the underlying cause turned out to be two SDK-level mismatches: a model-name allowlist that rejects bare IDs like `claude-opus-4-7`, and a Claude Code permission/Read-sandbox configuration that silently denies every non-allowlisted tool when the user's `~/.claude/settings.json` has `defaultMode: "dontAsk"` > - This pull request fixes both classes of failure in the adapter itself so new ACPX agents work seamlessly without per-host configuration, and widens the diagnostic surface so the *next* failure of any kind is actionable > - The benefit is that ACPX-Claude can join the regular agent roster — verified end to end on PAPA-401, where the agent successfully reached the Paperclip API, opened a worktree, surveyed existing notification PRs, and posted a structured plan ## What Changed - Widen ACPX failure diagnostics (`packages/adapters/acpx-local/src/server/execute.ts`): - Capture `err.name`, ACP code, `cause.message`, retryable flag, and a 5-frame stack preview into `errorMeta`. - Promote phase-specific error codes: `ensure_session → acpx_session_init_failed`, `configure_session → acpx_session_config_failed`, `turn → acpx_turn_failed`, plus mapping for `ACP_BACKEND_MISSING` / `ACP_BACKEND_UNAVAILABLE`. - Set `verbose: true` on the ACPX runtime so its session-event log flows through `ctx.onLog`. - Capture child-process stderr via a wrapper-script tee into `<stateDir>/run-stderr/<runId>.log`, inline the tail into the `acpx.error` payload as `childStderrTail`, and forward it through `ctx.onLog("stderr", …)` so it lands in the heartbeat `stderrExcerpt` column (existing redaction applies). - Set the model via `ANTHROPIC_MODEL` env for the `claude` agent instead of `set_config_option(model, …)`. The ACP server's `set_config_option` handler validates against an internal allowlist and rejects bare IDs like `claude-opus-4-7`. `ANTHROPIC_MODEL` is read during initialization and bypasses that check. - Seed `<worktree>/.claude/settings.local.json` before spawning `claude-agent-acp` (the seamless-API fix). Since `claude-agent-acp` hard-codes `settingSources: ["user", "project", "local"]` and "local" has the highest precedence: - Set `permissions.defaultMode: "default"`, but **only** if the user's value is missing or `"dontAsk"` (the broken case). Other modes like `acceptEdits`/`plan` are preserved. - Pre-allow Paperclip's Bash surface (`Bash(curl:*)`, `Bash(env:*)`, `Bash(<cwd>/scripts/paperclip-issue-update.sh:*)`, `Bash(<cwd>/scripts/paperclip:*)`). - Widen `permissions.additionalDirectories` to include `stateDir`, `agentHome`, and the per-company instance root (`~/.paperclip/instances/<id>/companies/<companyId>`). Scoped to this company only — does not expose other tenants. - Existing user entries are merged, not replaced. The resolved roots are folded into the session fingerprint so warm-session handles invalidate when they change. - Sync the existing server-side integration test (`server/src/__tests__/acpx-local-execute.test.ts`) to assert `acpx_session_init_failed` instead of the now-removed `acpx_protocol_error` for `ACP_SESSION_INIT_FAILED` (a follow-up to commit 1). ## Verification - `pnpm --filter "@paperclipai/adapter-acpx-local" run typecheck` — passes. - `pnpm vitest run` in `packages/adapters/acpx-local` — 35/35 pass, includes 4 new tests covering the settings.local.json write path (claude only, merge with pre-existing content, `dontAsk` override, codex no-op). - `pnpm vitest run src/__tests__/acpx-local-execute.test.ts` in `server/` — 15/15 pass after the test-sync commit. - End-to-end manual verification (PAPA-401): the `Claude Local ACPX` agent that previously hit "restricted environment" now successfully reaches the Paperclip API, opens its worktree, posts structured plan comments, and flips the issue to `in_review` without any external configuration. ## Risks - **Low**, scoped to the `acpx_local` adapter. The settings.local.json write is per-worktree (worktrees live under `.paperclip/worktrees/<issue>/`) and only triggers when `acpxAgent === "claude"`. Existing user content is merged with `[...existing, ...paperclip]` and deduped — nothing is overwritten outright. - The `defaultMode` override is intentionally narrow: it only flips `"dontAsk"` (which silently denies every tool and is the root cause) to `"default"`. Users who explicitly picked `acceptEdits`, `plan`, or any other mode keep their choice. - Stderr capture goes through the existing `log-redaction` pass before persisting, so `PAPERCLIP_API_KEY` and similar secrets in the wrapper env don't leak into heartbeat logs. > 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 4.7 (`claude-opus-4-7`), running in the `claude_local` adapter via Paperclip's harness. Extended thinking enabled, tool use enabled. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [ ] If this change affects the UI, I have included before/after screenshots — N/A (adapter-only) - [ ] I have updated relevant documentation to reflect my changes — no user-facing docs changed; internal commentary in the code change explains the SDK constraints - [x] I have considered and documented any risks above - [ ] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-05-23 13:01:27 -07:00
errorMeta: { category: "protocol", ...baseMeta },
Add ACPX local adapter runtime (#4893) ## Thinking Path > - Paperclip orchestrates AI-agent companies through a control plane that can start, supervise, and recover agent runs. > - Local adapters are the bridge between Paperclip issues and concrete agent runtimes such as Claude, Codex, and other ACP-compatible tools. > - The roadmap calls out broader “bring your own agent” and claw-style agent support, and ACPX gives Paperclip one path to normalize multiple ACP agents behind a single adapter. > - The branch needed to become one reviewable PR against current `paperclipai/paperclip:master`, without carrying stale base conflicts or generated lockfile churn. > - This pull request adds an experimental built-in `acpx_local` adapter, integrates it through the server/CLI/UI adapter surfaces, and adds regression coverage for runtime execution, skill sync, stream parsing, diagnostics, and log redaction. > - The benefit is that Paperclip can run Claude/Codex/custom ACP agents through ACPX while keeping operator configuration, skills, logging, and transcript rendering inside the existing adapter model. ## What Changed - Added `@paperclipai/adapter-acpx-local` with server execution, config schema, ACPX session handling, CLI formatting, UI config helpers, and stdout parsing. - Registered `acpx_local` across CLI, server, shared constants, UI adapter metadata, adapter capabilities, and agent creation/editing surfaces. - Added ACPX runtime execution support with persistent sessions, local-agent JWT environment handling, skill snapshots, runtime skill materialization, and isolation/security regressions. - Added ACPX adapter diagnostics and marked the adapter experimental in the UI. - Added command/env secret redaction for resolved command metadata in adapter-utils, server event storage, and the Agent Detail invocation UI. - Added Storybook coverage for ACPX config, transcript rendering, and skill states, plus PR screenshots under `docs/pr-screenshots/pap-2944/`. - Rebased the branch onto current `public-gh/master`; `pnpm-lock.yaml` is intentionally not included and there are no migration/schema changes. ## Verification - `pnpm exec vitest run packages/adapters/acpx-local/src/server/execute.test.ts packages/adapters/acpx-local/src/server/test.test.ts packages/adapters/acpx-local/src/cli/format-event.test.ts packages/adapters/acpx-local/src/ui/parse-stdout.test.ts packages/adapter-utils/src/server-utils.test.ts server/src/__tests__/redaction.test.ts server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/acpx-local-skill-sync.test.ts server/src/__tests__/acpx-local-adapter-environment.test.ts server/src/__tests__/adapter-routes.test.ts server/src/__tests__/agent-skills-routes.test.ts ui/src/adapters/metadata.test.ts` — 12 files, 87 tests passed. - `pnpm --filter @paperclipai/adapter-acpx-local typecheck` — passed. - `pnpm --filter @paperclipai/server typecheck` — passed. - `pnpm --filter @paperclipai/ui typecheck` — passed. - Confirmed PR diff does not include `pnpm-lock.yaml`, database schema files, or migrations. Screenshots: ![ACPX Claude skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-light.png?raw=true) ![ACPX Claude skills dark](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-dark.png?raw=true) ![ACPX custom skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-custom-light.png?raw=true) ## Risks - Medium risk: this introduces a new built-in adapter package and touches runtime execution, adapter registration, agent config, skills, and transcript rendering. - ACPX and ACP agent behavior can vary by installed tool versions; the adapter is marked experimental to set operator expectations. - `pnpm-lock.yaml` is excluded per repository PR policy, so dependency lock refresh must be handled by the repo’s automation or maintainers. - No database migration risk: no schema or migration files changed. > 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 coding agent based on GPT-5, with repository tool use, shell execution, git operations, and local verification. Exact hosted context window was not exposed in this environment. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-30 19:57:05 -05:00
};
}
return {
errorCode: "acpx_runtime_error",
Make ACPX-Claude adapter work seamlessly (PAPA-388) (#6590) ## Thinking Path > - Paperclip orchestrates AI agents for zero-human companies, so when an adapter fails, the platform must surface enough detail for the next agent (or human reviewer) to act > - The `acpx_local` adapter wraps `claude-agent-acp`, which in turn drives the Claude Code SDK — three layers, three different permission and error-handling models > - A user created a `Claude Local ACPX` agent in PAPA-387 and it failed instantly with the generic `acpx.error / "Internal error"` log, stranding the work and triggering an opaque `stranded_assigned_issue` recovery to the CTO > - Once the diagnostic blackbox was opened, the underlying cause turned out to be two SDK-level mismatches: a model-name allowlist that rejects bare IDs like `claude-opus-4-7`, and a Claude Code permission/Read-sandbox configuration that silently denies every non-allowlisted tool when the user's `~/.claude/settings.json` has `defaultMode: "dontAsk"` > - This pull request fixes both classes of failure in the adapter itself so new ACPX agents work seamlessly without per-host configuration, and widens the diagnostic surface so the *next* failure of any kind is actionable > - The benefit is that ACPX-Claude can join the regular agent roster — verified end to end on PAPA-401, where the agent successfully reached the Paperclip API, opened a worktree, surveyed existing notification PRs, and posted a structured plan ## What Changed - Widen ACPX failure diagnostics (`packages/adapters/acpx-local/src/server/execute.ts`): - Capture `err.name`, ACP code, `cause.message`, retryable flag, and a 5-frame stack preview into `errorMeta`. - Promote phase-specific error codes: `ensure_session → acpx_session_init_failed`, `configure_session → acpx_session_config_failed`, `turn → acpx_turn_failed`, plus mapping for `ACP_BACKEND_MISSING` / `ACP_BACKEND_UNAVAILABLE`. - Set `verbose: true` on the ACPX runtime so its session-event log flows through `ctx.onLog`. - Capture child-process stderr via a wrapper-script tee into `<stateDir>/run-stderr/<runId>.log`, inline the tail into the `acpx.error` payload as `childStderrTail`, and forward it through `ctx.onLog("stderr", …)` so it lands in the heartbeat `stderrExcerpt` column (existing redaction applies). - Set the model via `ANTHROPIC_MODEL` env for the `claude` agent instead of `set_config_option(model, …)`. The ACP server's `set_config_option` handler validates against an internal allowlist and rejects bare IDs like `claude-opus-4-7`. `ANTHROPIC_MODEL` is read during initialization and bypasses that check. - Seed `<worktree>/.claude/settings.local.json` before spawning `claude-agent-acp` (the seamless-API fix). Since `claude-agent-acp` hard-codes `settingSources: ["user", "project", "local"]` and "local" has the highest precedence: - Set `permissions.defaultMode: "default"`, but **only** if the user's value is missing or `"dontAsk"` (the broken case). Other modes like `acceptEdits`/`plan` are preserved. - Pre-allow Paperclip's Bash surface (`Bash(curl:*)`, `Bash(env:*)`, `Bash(<cwd>/scripts/paperclip-issue-update.sh:*)`, `Bash(<cwd>/scripts/paperclip:*)`). - Widen `permissions.additionalDirectories` to include `stateDir`, `agentHome`, and the per-company instance root (`~/.paperclip/instances/<id>/companies/<companyId>`). Scoped to this company only — does not expose other tenants. - Existing user entries are merged, not replaced. The resolved roots are folded into the session fingerprint so warm-session handles invalidate when they change. - Sync the existing server-side integration test (`server/src/__tests__/acpx-local-execute.test.ts`) to assert `acpx_session_init_failed` instead of the now-removed `acpx_protocol_error` for `ACP_SESSION_INIT_FAILED` (a follow-up to commit 1). ## Verification - `pnpm --filter "@paperclipai/adapter-acpx-local" run typecheck` — passes. - `pnpm vitest run` in `packages/adapters/acpx-local` — 35/35 pass, includes 4 new tests covering the settings.local.json write path (claude only, merge with pre-existing content, `dontAsk` override, codex no-op). - `pnpm vitest run src/__tests__/acpx-local-execute.test.ts` in `server/` — 15/15 pass after the test-sync commit. - End-to-end manual verification (PAPA-401): the `Claude Local ACPX` agent that previously hit "restricted environment" now successfully reaches the Paperclip API, opens its worktree, posts structured plan comments, and flips the issue to `in_review` without any external configuration. ## Risks - **Low**, scoped to the `acpx_local` adapter. The settings.local.json write is per-worktree (worktrees live under `.paperclip/worktrees/<issue>/`) and only triggers when `acpxAgent === "claude"`. Existing user content is merged with `[...existing, ...paperclip]` and deduped — nothing is overwritten outright. - The `defaultMode` override is intentionally narrow: it only flips `"dontAsk"` (which silently denies every tool and is the root cause) to `"default"`. Users who explicitly picked `acceptEdits`, `plan`, or any other mode keep their choice. - Stderr capture goes through the existing `log-redaction` pass before persisting, so `PAPERCLIP_API_KEY` and similar secrets in the wrapper env don't leak into heartbeat logs. > 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 4.7 (`claude-opus-4-7`), running in the `claude_local` adapter via Paperclip's harness. Extended thinking enabled, tool use enabled. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [ ] If this change affects the UI, I have included before/after screenshots — N/A (adapter-only) - [ ] I have updated relevant documentation to reflect my changes — no user-facing docs changed; internal commentary in the code change explains the SDK constraints - [x] I have considered and documented any risks above - [ ] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-05-23 13:01:27 -07:00
errorMeta: { category: "runtime", ...baseMeta },
Add ACPX local adapter runtime (#4893) ## Thinking Path > - Paperclip orchestrates AI-agent companies through a control plane that can start, supervise, and recover agent runs. > - Local adapters are the bridge between Paperclip issues and concrete agent runtimes such as Claude, Codex, and other ACP-compatible tools. > - The roadmap calls out broader “bring your own agent” and claw-style agent support, and ACPX gives Paperclip one path to normalize multiple ACP agents behind a single adapter. > - The branch needed to become one reviewable PR against current `paperclipai/paperclip:master`, without carrying stale base conflicts or generated lockfile churn. > - This pull request adds an experimental built-in `acpx_local` adapter, integrates it through the server/CLI/UI adapter surfaces, and adds regression coverage for runtime execution, skill sync, stream parsing, diagnostics, and log redaction. > - The benefit is that Paperclip can run Claude/Codex/custom ACP agents through ACPX while keeping operator configuration, skills, logging, and transcript rendering inside the existing adapter model. ## What Changed - Added `@paperclipai/adapter-acpx-local` with server execution, config schema, ACPX session handling, CLI formatting, UI config helpers, and stdout parsing. - Registered `acpx_local` across CLI, server, shared constants, UI adapter metadata, adapter capabilities, and agent creation/editing surfaces. - Added ACPX runtime execution support with persistent sessions, local-agent JWT environment handling, skill snapshots, runtime skill materialization, and isolation/security regressions. - Added ACPX adapter diagnostics and marked the adapter experimental in the UI. - Added command/env secret redaction for resolved command metadata in adapter-utils, server event storage, and the Agent Detail invocation UI. - Added Storybook coverage for ACPX config, transcript rendering, and skill states, plus PR screenshots under `docs/pr-screenshots/pap-2944/`. - Rebased the branch onto current `public-gh/master`; `pnpm-lock.yaml` is intentionally not included and there are no migration/schema changes. ## Verification - `pnpm exec vitest run packages/adapters/acpx-local/src/server/execute.test.ts packages/adapters/acpx-local/src/server/test.test.ts packages/adapters/acpx-local/src/cli/format-event.test.ts packages/adapters/acpx-local/src/ui/parse-stdout.test.ts packages/adapter-utils/src/server-utils.test.ts server/src/__tests__/redaction.test.ts server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/acpx-local-skill-sync.test.ts server/src/__tests__/acpx-local-adapter-environment.test.ts server/src/__tests__/adapter-routes.test.ts server/src/__tests__/agent-skills-routes.test.ts ui/src/adapters/metadata.test.ts` — 12 files, 87 tests passed. - `pnpm --filter @paperclipai/adapter-acpx-local typecheck` — passed. - `pnpm --filter @paperclipai/server typecheck` — passed. - `pnpm --filter @paperclipai/ui typecheck` — passed. - Confirmed PR diff does not include `pnpm-lock.yaml`, database schema files, or migrations. Screenshots: ![ACPX Claude skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-light.png?raw=true) ![ACPX Claude skills dark](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-dark.png?raw=true) ![ACPX custom skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-custom-light.png?raw=true) ## Risks - Medium risk: this introduces a new built-in adapter package and touches runtime execution, adapter registration, agent config, skills, and transcript rendering. - ACPX and ACP agent behavior can vary by installed tool versions; the adapter is marked experimental to set operator expectations. - `pnpm-lock.yaml` is excluded per repository PR policy, so dependency lock refresh must be handled by the repo’s automation or maintainers. - No database migration risk: no schema or migration files changed. > 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 coding agent based on GPT-5, with repository tool use, shell execution, git operations, and local verification. Exact hosted context window was not exposed in this environment. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-30 19:57:05 -05:00
};
}
Make ACPX-Claude adapter work seamlessly (PAPA-388) (#6590) ## Thinking Path > - Paperclip orchestrates AI agents for zero-human companies, so when an adapter fails, the platform must surface enough detail for the next agent (or human reviewer) to act > - The `acpx_local` adapter wraps `claude-agent-acp`, which in turn drives the Claude Code SDK — three layers, three different permission and error-handling models > - A user created a `Claude Local ACPX` agent in PAPA-387 and it failed instantly with the generic `acpx.error / "Internal error"` log, stranding the work and triggering an opaque `stranded_assigned_issue` recovery to the CTO > - Once the diagnostic blackbox was opened, the underlying cause turned out to be two SDK-level mismatches: a model-name allowlist that rejects bare IDs like `claude-opus-4-7`, and a Claude Code permission/Read-sandbox configuration that silently denies every non-allowlisted tool when the user's `~/.claude/settings.json` has `defaultMode: "dontAsk"` > - This pull request fixes both classes of failure in the adapter itself so new ACPX agents work seamlessly without per-host configuration, and widens the diagnostic surface so the *next* failure of any kind is actionable > - The benefit is that ACPX-Claude can join the regular agent roster — verified end to end on PAPA-401, where the agent successfully reached the Paperclip API, opened a worktree, surveyed existing notification PRs, and posted a structured plan ## What Changed - Widen ACPX failure diagnostics (`packages/adapters/acpx-local/src/server/execute.ts`): - Capture `err.name`, ACP code, `cause.message`, retryable flag, and a 5-frame stack preview into `errorMeta`. - Promote phase-specific error codes: `ensure_session → acpx_session_init_failed`, `configure_session → acpx_session_config_failed`, `turn → acpx_turn_failed`, plus mapping for `ACP_BACKEND_MISSING` / `ACP_BACKEND_UNAVAILABLE`. - Set `verbose: true` on the ACPX runtime so its session-event log flows through `ctx.onLog`. - Capture child-process stderr via a wrapper-script tee into `<stateDir>/run-stderr/<runId>.log`, inline the tail into the `acpx.error` payload as `childStderrTail`, and forward it through `ctx.onLog("stderr", …)` so it lands in the heartbeat `stderrExcerpt` column (existing redaction applies). - Set the model via `ANTHROPIC_MODEL` env for the `claude` agent instead of `set_config_option(model, …)`. The ACP server's `set_config_option` handler validates against an internal allowlist and rejects bare IDs like `claude-opus-4-7`. `ANTHROPIC_MODEL` is read during initialization and bypasses that check. - Seed `<worktree>/.claude/settings.local.json` before spawning `claude-agent-acp` (the seamless-API fix). Since `claude-agent-acp` hard-codes `settingSources: ["user", "project", "local"]` and "local" has the highest precedence: - Set `permissions.defaultMode: "default"`, but **only** if the user's value is missing or `"dontAsk"` (the broken case). Other modes like `acceptEdits`/`plan` are preserved. - Pre-allow Paperclip's Bash surface (`Bash(curl:*)`, `Bash(env:*)`, `Bash(<cwd>/scripts/paperclip-issue-update.sh:*)`, `Bash(<cwd>/scripts/paperclip:*)`). - Widen `permissions.additionalDirectories` to include `stateDir`, `agentHome`, and the per-company instance root (`~/.paperclip/instances/<id>/companies/<companyId>`). Scoped to this company only — does not expose other tenants. - Existing user entries are merged, not replaced. The resolved roots are folded into the session fingerprint so warm-session handles invalidate when they change. - Sync the existing server-side integration test (`server/src/__tests__/acpx-local-execute.test.ts`) to assert `acpx_session_init_failed` instead of the now-removed `acpx_protocol_error` for `ACP_SESSION_INIT_FAILED` (a follow-up to commit 1). ## Verification - `pnpm --filter "@paperclipai/adapter-acpx-local" run typecheck` — passes. - `pnpm vitest run` in `packages/adapters/acpx-local` — 35/35 pass, includes 4 new tests covering the settings.local.json write path (claude only, merge with pre-existing content, `dontAsk` override, codex no-op). - `pnpm vitest run src/__tests__/acpx-local-execute.test.ts` in `server/` — 15/15 pass after the test-sync commit. - End-to-end manual verification (PAPA-401): the `Claude Local ACPX` agent that previously hit "restricted environment" now successfully reaches the Paperclip API, opens its worktree, posts structured plan comments, and flips the issue to `in_review` without any external configuration. ## Risks - **Low**, scoped to the `acpx_local` adapter. The settings.local.json write is per-worktree (worktrees live under `.paperclip/worktrees/<issue>/`) and only triggers when `acpxAgent === "claude"`. Existing user content is merged with `[...existing, ...paperclip]` and deduped — nothing is overwritten outright. - The `defaultMode` override is intentionally narrow: it only flips `"dontAsk"` (which silently denies every tool and is the root cause) to `"default"`. Users who explicitly picked `acceptEdits`, `plan`, or any other mode keep their choice. - Stderr capture goes through the existing `log-redaction` pass before persisting, so `PAPERCLIP_API_KEY` and similar secrets in the wrapper env don't leak into heartbeat logs. > 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 4.7 (`claude-opus-4-7`), running in the `claude_local` adapter via Paperclip's harness. Extended thinking enabled, tool use enabled. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [ ] If this change affects the UI, I have included before/after screenshots — N/A (adapter-only) - [ ] I have updated relevant documentation to reflect my changes — no user-facing docs changed; internal commentary in the code change explains the SDK constraints - [x] I have considered and documented any risks above - [ ] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-05-23 13:01:27 -07:00
async function readChildStderrTail(input: {
logPath: string | null;
maxBytes?: number;
}): Promise<string | null> {
if (!input.logPath) return null;
const maxBytes = input.maxBytes ?? 4096;
let handle: fs.FileHandle | null = null;
try {
const stat = await fs.stat(input.logPath);
if (stat.size === 0) return null;
handle = await fs.open(input.logPath, "r");
const readBytes = Math.min(stat.size, maxBytes);
const buffer = Buffer.alloc(readBytes);
await handle.read(buffer, 0, readBytes, Math.max(0, stat.size - readBytes));
const tail = buffer.toString("utf8").trim();
return tail.length > 0 ? tail : null;
} catch {
return null;
} finally {
if (handle) await handle.close().catch(() => {});
}
}
async function emitAcpxFailure(input: {
ctx: AdapterExecutionContext;
prepared: AcpxPreparedRuntime;
err: unknown;
phase: AcpxExecutionPhase;
// Replace the err-derived message in both the stderr-tail log header and the
// acpx.error payload. Used by the turn path to surface "Timed out after Ns"
// instead of the raw underlying error message.
messageOverride?: string;
}): Promise<{
classified: Pick<AdapterExecutionResult, "errorCode" | "errorMeta">;
message: string;
childStderrTail: string | null;
}> {
const { ctx, prepared, err, phase, messageOverride } = input;
const rawMessage = err instanceof Error ? err.message : String(err);
const message = messageOverride ?? rawMessage;
const classified = classifyError(err, phase);
const childStderrTail = await readChildStderrTail({ logPath: prepared.childStderrLogPath });
if (childStderrTail) {
await ctx.onLog(
"stderr",
`[paperclip] ACPX child stderr tail (${phase}):\n${childStderrTail}\n`,
);
}
await emitAcpxLog(ctx, {
type: "acpx.error",
message,
phase,
...classified.errorMeta,
...(childStderrTail ? { childStderrTail } : {}),
});
return { classified, message, childStderrTail };
}
Add ACPX local adapter runtime (#4893) ## Thinking Path > - Paperclip orchestrates AI-agent companies through a control plane that can start, supervise, and recover agent runs. > - Local adapters are the bridge between Paperclip issues and concrete agent runtimes such as Claude, Codex, and other ACP-compatible tools. > - The roadmap calls out broader “bring your own agent” and claw-style agent support, and ACPX gives Paperclip one path to normalize multiple ACP agents behind a single adapter. > - The branch needed to become one reviewable PR against current `paperclipai/paperclip:master`, without carrying stale base conflicts or generated lockfile churn. > - This pull request adds an experimental built-in `acpx_local` adapter, integrates it through the server/CLI/UI adapter surfaces, and adds regression coverage for runtime execution, skill sync, stream parsing, diagnostics, and log redaction. > - The benefit is that Paperclip can run Claude/Codex/custom ACP agents through ACPX while keeping operator configuration, skills, logging, and transcript rendering inside the existing adapter model. ## What Changed - Added `@paperclipai/adapter-acpx-local` with server execution, config schema, ACPX session handling, CLI formatting, UI config helpers, and stdout parsing. - Registered `acpx_local` across CLI, server, shared constants, UI adapter metadata, adapter capabilities, and agent creation/editing surfaces. - Added ACPX runtime execution support with persistent sessions, local-agent JWT environment handling, skill snapshots, runtime skill materialization, and isolation/security regressions. - Added ACPX adapter diagnostics and marked the adapter experimental in the UI. - Added command/env secret redaction for resolved command metadata in adapter-utils, server event storage, and the Agent Detail invocation UI. - Added Storybook coverage for ACPX config, transcript rendering, and skill states, plus PR screenshots under `docs/pr-screenshots/pap-2944/`. - Rebased the branch onto current `public-gh/master`; `pnpm-lock.yaml` is intentionally not included and there are no migration/schema changes. ## Verification - `pnpm exec vitest run packages/adapters/acpx-local/src/server/execute.test.ts packages/adapters/acpx-local/src/server/test.test.ts packages/adapters/acpx-local/src/cli/format-event.test.ts packages/adapters/acpx-local/src/ui/parse-stdout.test.ts packages/adapter-utils/src/server-utils.test.ts server/src/__tests__/redaction.test.ts server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/acpx-local-skill-sync.test.ts server/src/__tests__/acpx-local-adapter-environment.test.ts server/src/__tests__/adapter-routes.test.ts server/src/__tests__/agent-skills-routes.test.ts ui/src/adapters/metadata.test.ts` — 12 files, 87 tests passed. - `pnpm --filter @paperclipai/adapter-acpx-local typecheck` — passed. - `pnpm --filter @paperclipai/server typecheck` — passed. - `pnpm --filter @paperclipai/ui typecheck` — passed. - Confirmed PR diff does not include `pnpm-lock.yaml`, database schema files, or migrations. Screenshots: ![ACPX Claude skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-light.png?raw=true) ![ACPX Claude skills dark](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-dark.png?raw=true) ![ACPX custom skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-custom-light.png?raw=true) ## Risks - Medium risk: this introduces a new built-in adapter package and touches runtime execution, adapter registration, agent config, skills, and transcript rendering. - ACPX and ACP agent behavior can vary by installed tool versions; the adapter is marked experimental to set operator expectations. - `pnpm-lock.yaml` is excluded per repository PR policy, so dependency lock refresh must be handled by the repo’s automation or maintainers. - No database migration risk: no schema or migration files changed. > 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 coding agent based on GPT-5, with repository tool use, shell execution, git operations, and local verification. Exact hosted context window was not exposed in this environment. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-30 19:57:05 -05:00
function isResumeFailure(err: unknown): boolean {
const message = err instanceof Error ? err.message : String(err);
return /resume|load|not found|no session|unknown session|conversation/i.test(message);
}
async function cleanupIdleHandles(input: {
handles: Map<string, RuntimeCacheEntry>;
now: number;
idleMs: number;
}) {
Improve ACPX adapter configuration (#5290) ## Thinking Path > - Paperclip orchestrates AI agents across several adapter implementations. > - ACPX is a local adapter path that can proxy Claude and Codex-style execution. > - Its configuration needed stronger schema defaults, provider-aware model handling, and better UI support. > - Plugin authors also need clear docs for managed resources. > - This pull request improves ACPX adapter configuration and documents plugin-managed resources. > - The benefit is a more predictable adapter setup path without changing unrelated control-plane behavior. ## What Changed - Improved ACPX config schema, execution config handling, UI build config, and route coverage. - Added ACPX model filtering support and tests. - Updated the agent config form and storybook coverage for ACPX model/provider behavior. - Expanded plugin authoring documentation for managed resources. ## Verification - `pnpm install --frozen-lockfile` - `pnpm exec vitest run server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/adapter-routes.test.ts ui/src/lib/acpx-model-filter.test.ts` ## Risks - Low-to-medium risk: adapter configuration behavior changes can affect ACPX users, but the change is isolated to ACPX/plugin-doc surfaces and covered by targeted adapter tests. ## Model Used - OpenAI GPT-5 Codex via Paperclip `codex_local` adapter, with shell/git/GitHub CLI tool use. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-05-06 06:06:47 -05:00
if (input.idleMs <= 0) return;
Add ACPX local adapter runtime (#4893) ## Thinking Path > - Paperclip orchestrates AI-agent companies through a control plane that can start, supervise, and recover agent runs. > - Local adapters are the bridge between Paperclip issues and concrete agent runtimes such as Claude, Codex, and other ACP-compatible tools. > - The roadmap calls out broader “bring your own agent” and claw-style agent support, and ACPX gives Paperclip one path to normalize multiple ACP agents behind a single adapter. > - The branch needed to become one reviewable PR against current `paperclipai/paperclip:master`, without carrying stale base conflicts or generated lockfile churn. > - This pull request adds an experimental built-in `acpx_local` adapter, integrates it through the server/CLI/UI adapter surfaces, and adds regression coverage for runtime execution, skill sync, stream parsing, diagnostics, and log redaction. > - The benefit is that Paperclip can run Claude/Codex/custom ACP agents through ACPX while keeping operator configuration, skills, logging, and transcript rendering inside the existing adapter model. ## What Changed - Added `@paperclipai/adapter-acpx-local` with server execution, config schema, ACPX session handling, CLI formatting, UI config helpers, and stdout parsing. - Registered `acpx_local` across CLI, server, shared constants, UI adapter metadata, adapter capabilities, and agent creation/editing surfaces. - Added ACPX runtime execution support with persistent sessions, local-agent JWT environment handling, skill snapshots, runtime skill materialization, and isolation/security regressions. - Added ACPX adapter diagnostics and marked the adapter experimental in the UI. - Added command/env secret redaction for resolved command metadata in adapter-utils, server event storage, and the Agent Detail invocation UI. - Added Storybook coverage for ACPX config, transcript rendering, and skill states, plus PR screenshots under `docs/pr-screenshots/pap-2944/`. - Rebased the branch onto current `public-gh/master`; `pnpm-lock.yaml` is intentionally not included and there are no migration/schema changes. ## Verification - `pnpm exec vitest run packages/adapters/acpx-local/src/server/execute.test.ts packages/adapters/acpx-local/src/server/test.test.ts packages/adapters/acpx-local/src/cli/format-event.test.ts packages/adapters/acpx-local/src/ui/parse-stdout.test.ts packages/adapter-utils/src/server-utils.test.ts server/src/__tests__/redaction.test.ts server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/acpx-local-skill-sync.test.ts server/src/__tests__/acpx-local-adapter-environment.test.ts server/src/__tests__/adapter-routes.test.ts server/src/__tests__/agent-skills-routes.test.ts ui/src/adapters/metadata.test.ts` — 12 files, 87 tests passed. - `pnpm --filter @paperclipai/adapter-acpx-local typecheck` — passed. - `pnpm --filter @paperclipai/server typecheck` — passed. - `pnpm --filter @paperclipai/ui typecheck` — passed. - Confirmed PR diff does not include `pnpm-lock.yaml`, database schema files, or migrations. Screenshots: ![ACPX Claude skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-light.png?raw=true) ![ACPX Claude skills dark](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-dark.png?raw=true) ![ACPX custom skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-custom-light.png?raw=true) ## Risks - Medium risk: this introduces a new built-in adapter package and touches runtime execution, adapter registration, agent config, skills, and transcript rendering. - ACPX and ACP agent behavior can vary by installed tool versions; the adapter is marked experimental to set operator expectations. - `pnpm-lock.yaml` is excluded per repository PR policy, so dependency lock refresh must be handled by the repo’s automation or maintainers. - No database migration risk: no schema or migration files changed. > 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 coding agent based on GPT-5, with repository tool use, shell execution, git operations, and local verification. Exact hosted context window was not exposed in this environment. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-30 19:57:05 -05:00
const stale: Array<[string, RuntimeCacheEntry]> = [];
for (const entry of input.handles.entries()) {
if (input.now - entry[1].lastUsedAt >= input.idleMs) stale.push(entry);
}
for (const [key, entry] of stale) {
Improve ACPX adapter configuration (#5290) ## Thinking Path > - Paperclip orchestrates AI agents across several adapter implementations. > - ACPX is a local adapter path that can proxy Claude and Codex-style execution. > - Its configuration needed stronger schema defaults, provider-aware model handling, and better UI support. > - Plugin authors also need clear docs for managed resources. > - This pull request improves ACPX adapter configuration and documents plugin-managed resources. > - The benefit is a more predictable adapter setup path without changing unrelated control-plane behavior. ## What Changed - Improved ACPX config schema, execution config handling, UI build config, and route coverage. - Added ACPX model filtering support and tests. - Updated the agent config form and storybook coverage for ACPX model/provider behavior. - Expanded plugin authoring documentation for managed resources. ## Verification - `pnpm install --frozen-lockfile` - `pnpm exec vitest run server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/adapter-routes.test.ts ui/src/lib/acpx-model-filter.test.ts` ## Risks - Low-to-medium risk: adapter configuration behavior changes can affect ACPX users, but the change is isolated to ACPX/plugin-doc surfaces and covered by targeted adapter tests. ## Model Used - OpenAI GPT-5 Codex via Paperclip `codex_local` adapter, with shell/git/GitHub CLI tool use. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-05-06 06:06:47 -05:00
await closeWarmHandle({
handles: input.handles,
key,
entry,
Add ACPX local adapter runtime (#4893) ## Thinking Path > - Paperclip orchestrates AI-agent companies through a control plane that can start, supervise, and recover agent runs. > - Local adapters are the bridge between Paperclip issues and concrete agent runtimes such as Claude, Codex, and other ACP-compatible tools. > - The roadmap calls out broader “bring your own agent” and claw-style agent support, and ACPX gives Paperclip one path to normalize multiple ACP agents behind a single adapter. > - The branch needed to become one reviewable PR against current `paperclipai/paperclip:master`, without carrying stale base conflicts or generated lockfile churn. > - This pull request adds an experimental built-in `acpx_local` adapter, integrates it through the server/CLI/UI adapter surfaces, and adds regression coverage for runtime execution, skill sync, stream parsing, diagnostics, and log redaction. > - The benefit is that Paperclip can run Claude/Codex/custom ACP agents through ACPX while keeping operator configuration, skills, logging, and transcript rendering inside the existing adapter model. ## What Changed - Added `@paperclipai/adapter-acpx-local` with server execution, config schema, ACPX session handling, CLI formatting, UI config helpers, and stdout parsing. - Registered `acpx_local` across CLI, server, shared constants, UI adapter metadata, adapter capabilities, and agent creation/editing surfaces. - Added ACPX runtime execution support with persistent sessions, local-agent JWT environment handling, skill snapshots, runtime skill materialization, and isolation/security regressions. - Added ACPX adapter diagnostics and marked the adapter experimental in the UI. - Added command/env secret redaction for resolved command metadata in adapter-utils, server event storage, and the Agent Detail invocation UI. - Added Storybook coverage for ACPX config, transcript rendering, and skill states, plus PR screenshots under `docs/pr-screenshots/pap-2944/`. - Rebased the branch onto current `public-gh/master`; `pnpm-lock.yaml` is intentionally not included and there are no migration/schema changes. ## Verification - `pnpm exec vitest run packages/adapters/acpx-local/src/server/execute.test.ts packages/adapters/acpx-local/src/server/test.test.ts packages/adapters/acpx-local/src/cli/format-event.test.ts packages/adapters/acpx-local/src/ui/parse-stdout.test.ts packages/adapter-utils/src/server-utils.test.ts server/src/__tests__/redaction.test.ts server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/acpx-local-skill-sync.test.ts server/src/__tests__/acpx-local-adapter-environment.test.ts server/src/__tests__/adapter-routes.test.ts server/src/__tests__/agent-skills-routes.test.ts ui/src/adapters/metadata.test.ts` — 12 files, 87 tests passed. - `pnpm --filter @paperclipai/adapter-acpx-local typecheck` — passed. - `pnpm --filter @paperclipai/server typecheck` — passed. - `pnpm --filter @paperclipai/ui typecheck` — passed. - Confirmed PR diff does not include `pnpm-lock.yaml`, database schema files, or migrations. Screenshots: ![ACPX Claude skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-light.png?raw=true) ![ACPX Claude skills dark](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-dark.png?raw=true) ![ACPX custom skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-custom-light.png?raw=true) ## Risks - Medium risk: this introduces a new built-in adapter package and touches runtime execution, adapter registration, agent config, skills, and transcript rendering. - ACPX and ACP agent behavior can vary by installed tool versions; the adapter is marked experimental to set operator expectations. - `pnpm-lock.yaml` is excluded per repository PR policy, so dependency lock refresh must be handled by the repo’s automation or maintainers. - No database migration risk: no schema or migration files changed. > 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 coding agent based on GPT-5, with repository tool use, shell execution, git operations, and local verification. Exact hosted context window was not exposed in this environment. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-30 19:57:05 -05:00
reason: "paperclip idle cleanup",
Improve ACPX adapter configuration (#5290) ## Thinking Path > - Paperclip orchestrates AI agents across several adapter implementations. > - ACPX is a local adapter path that can proxy Claude and Codex-style execution. > - Its configuration needed stronger schema defaults, provider-aware model handling, and better UI support. > - Plugin authors also need clear docs for managed resources. > - This pull request improves ACPX adapter configuration and documents plugin-managed resources. > - The benefit is a more predictable adapter setup path without changing unrelated control-plane behavior. ## What Changed - Improved ACPX config schema, execution config handling, UI build config, and route coverage. - Added ACPX model filtering support and tests. - Updated the agent config form and storybook coverage for ACPX model/provider behavior. - Expanded plugin authoring documentation for managed resources. ## Verification - `pnpm install --frozen-lockfile` - `pnpm exec vitest run server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/adapter-routes.test.ts ui/src/lib/acpx-model-filter.test.ts` ## Risks - Low-to-medium risk: adapter configuration behavior changes can affect ACPX users, but the change is isolated to ACPX/plugin-doc surfaces and covered by targeted adapter tests. ## Model Used - OpenAI GPT-5 Codex via Paperclip `codex_local` adapter, with shell/git/GitHub CLI tool use. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-05-06 06:06:47 -05:00
});
Add ACPX local adapter runtime (#4893) ## Thinking Path > - Paperclip orchestrates AI-agent companies through a control plane that can start, supervise, and recover agent runs. > - Local adapters are the bridge between Paperclip issues and concrete agent runtimes such as Claude, Codex, and other ACP-compatible tools. > - The roadmap calls out broader “bring your own agent” and claw-style agent support, and ACPX gives Paperclip one path to normalize multiple ACP agents behind a single adapter. > - The branch needed to become one reviewable PR against current `paperclipai/paperclip:master`, without carrying stale base conflicts or generated lockfile churn. > - This pull request adds an experimental built-in `acpx_local` adapter, integrates it through the server/CLI/UI adapter surfaces, and adds regression coverage for runtime execution, skill sync, stream parsing, diagnostics, and log redaction. > - The benefit is that Paperclip can run Claude/Codex/custom ACP agents through ACPX while keeping operator configuration, skills, logging, and transcript rendering inside the existing adapter model. ## What Changed - Added `@paperclipai/adapter-acpx-local` with server execution, config schema, ACPX session handling, CLI formatting, UI config helpers, and stdout parsing. - Registered `acpx_local` across CLI, server, shared constants, UI adapter metadata, adapter capabilities, and agent creation/editing surfaces. - Added ACPX runtime execution support with persistent sessions, local-agent JWT environment handling, skill snapshots, runtime skill materialization, and isolation/security regressions. - Added ACPX adapter diagnostics and marked the adapter experimental in the UI. - Added command/env secret redaction for resolved command metadata in adapter-utils, server event storage, and the Agent Detail invocation UI. - Added Storybook coverage for ACPX config, transcript rendering, and skill states, plus PR screenshots under `docs/pr-screenshots/pap-2944/`. - Rebased the branch onto current `public-gh/master`; `pnpm-lock.yaml` is intentionally not included and there are no migration/schema changes. ## Verification - `pnpm exec vitest run packages/adapters/acpx-local/src/server/execute.test.ts packages/adapters/acpx-local/src/server/test.test.ts packages/adapters/acpx-local/src/cli/format-event.test.ts packages/adapters/acpx-local/src/ui/parse-stdout.test.ts packages/adapter-utils/src/server-utils.test.ts server/src/__tests__/redaction.test.ts server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/acpx-local-skill-sync.test.ts server/src/__tests__/acpx-local-adapter-environment.test.ts server/src/__tests__/adapter-routes.test.ts server/src/__tests__/agent-skills-routes.test.ts ui/src/adapters/metadata.test.ts` — 12 files, 87 tests passed. - `pnpm --filter @paperclipai/adapter-acpx-local typecheck` — passed. - `pnpm --filter @paperclipai/server typecheck` — passed. - `pnpm --filter @paperclipai/ui typecheck` — passed. - Confirmed PR diff does not include `pnpm-lock.yaml`, database schema files, or migrations. Screenshots: ![ACPX Claude skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-light.png?raw=true) ![ACPX Claude skills dark](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-dark.png?raw=true) ![ACPX custom skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-custom-light.png?raw=true) ## Risks - Medium risk: this introduces a new built-in adapter package and touches runtime execution, adapter registration, agent config, skills, and transcript rendering. - ACPX and ACP agent behavior can vary by installed tool versions; the adapter is marked experimental to set operator expectations. - `pnpm-lock.yaml` is excluded per repository PR policy, so dependency lock refresh must be handled by the repo’s automation or maintainers. - No database migration risk: no schema or migration files changed. > 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 coding agent based on GPT-5, with repository tool use, shell execution, git operations, and local verification. Exact hosted context window was not exposed in this environment. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-30 19:57:05 -05:00
}
}
Improve ACPX adapter configuration (#5290) ## Thinking Path > - Paperclip orchestrates AI agents across several adapter implementations. > - ACPX is a local adapter path that can proxy Claude and Codex-style execution. > - Its configuration needed stronger schema defaults, provider-aware model handling, and better UI support. > - Plugin authors also need clear docs for managed resources. > - This pull request improves ACPX adapter configuration and documents plugin-managed resources. > - The benefit is a more predictable adapter setup path without changing unrelated control-plane behavior. ## What Changed - Improved ACPX config schema, execution config handling, UI build config, and route coverage. - Added ACPX model filtering support and tests. - Updated the agent config form and storybook coverage for ACPX model/provider behavior. - Expanded plugin authoring documentation for managed resources. ## Verification - `pnpm install --frozen-lockfile` - `pnpm exec vitest run server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/adapter-routes.test.ts ui/src/lib/acpx-model-filter.test.ts` ## Risks - Low-to-medium risk: adapter configuration behavior changes can affect ACPX users, but the change is isolated to ACPX/plugin-doc surfaces and covered by targeted adapter tests. ## Model Used - OpenAI GPT-5 Codex via Paperclip `codex_local` adapter, with shell/git/GitHub CLI tool use. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-05-06 06:06:47 -05:00
function clearWarmHandleTimer(entry: RuntimeCacheEntry) {
if (!entry.cleanupTimer) return;
clearTimeout(entry.cleanupTimer);
entry.cleanupTimer = undefined;
}
async function closeWarmHandle(input: {
handles: Map<string, RuntimeCacheEntry>;
key: string;
entry: RuntimeCacheEntry;
reason: string;
discardPersistentState?: boolean;
}) {
if (input.handles.get(input.key) === input.entry) {
input.handles.delete(input.key);
}
clearWarmHandleTimer(input.entry);
await input.entry.runtime.close({
handle: input.entry.handle,
reason: input.reason,
discardPersistentState: input.discardPersistentState ?? false,
}).catch(() => {});
}
function scheduleIdleHandleCleanup(input: {
handles: Map<string, RuntimeCacheEntry>;
key: string;
entry: RuntimeCacheEntry;
idleMs: number;
now: () => number;
}) {
clearWarmHandleTimer(input.entry);
if (input.idleMs <= 0) return;
const delayMs = Math.max(1, input.entry.lastUsedAt + input.idleMs - input.now());
input.entry.cleanupTimer = setTimeout(() => {
void (async () => {
const current = input.handles.get(input.key);
if (current !== input.entry) return;
const idleForMs = input.now() - input.entry.lastUsedAt;
if (idleForMs < input.idleMs) {
scheduleIdleHandleCleanup(input);
return;
}
await closeWarmHandle({
handles: input.handles,
key: input.key,
entry: input.entry,
reason: "paperclip idle cleanup",
});
})();
}, delayMs);
input.entry.cleanupTimer.unref?.();
}
Add ACPX local adapter runtime (#4893) ## Thinking Path > - Paperclip orchestrates AI-agent companies through a control plane that can start, supervise, and recover agent runs. > - Local adapters are the bridge between Paperclip issues and concrete agent runtimes such as Claude, Codex, and other ACP-compatible tools. > - The roadmap calls out broader “bring your own agent” and claw-style agent support, and ACPX gives Paperclip one path to normalize multiple ACP agents behind a single adapter. > - The branch needed to become one reviewable PR against current `paperclipai/paperclip:master`, without carrying stale base conflicts or generated lockfile churn. > - This pull request adds an experimental built-in `acpx_local` adapter, integrates it through the server/CLI/UI adapter surfaces, and adds regression coverage for runtime execution, skill sync, stream parsing, diagnostics, and log redaction. > - The benefit is that Paperclip can run Claude/Codex/custom ACP agents through ACPX while keeping operator configuration, skills, logging, and transcript rendering inside the existing adapter model. ## What Changed - Added `@paperclipai/adapter-acpx-local` with server execution, config schema, ACPX session handling, CLI formatting, UI config helpers, and stdout parsing. - Registered `acpx_local` across CLI, server, shared constants, UI adapter metadata, adapter capabilities, and agent creation/editing surfaces. - Added ACPX runtime execution support with persistent sessions, local-agent JWT environment handling, skill snapshots, runtime skill materialization, and isolation/security regressions. - Added ACPX adapter diagnostics and marked the adapter experimental in the UI. - Added command/env secret redaction for resolved command metadata in adapter-utils, server event storage, and the Agent Detail invocation UI. - Added Storybook coverage for ACPX config, transcript rendering, and skill states, plus PR screenshots under `docs/pr-screenshots/pap-2944/`. - Rebased the branch onto current `public-gh/master`; `pnpm-lock.yaml` is intentionally not included and there are no migration/schema changes. ## Verification - `pnpm exec vitest run packages/adapters/acpx-local/src/server/execute.test.ts packages/adapters/acpx-local/src/server/test.test.ts packages/adapters/acpx-local/src/cli/format-event.test.ts packages/adapters/acpx-local/src/ui/parse-stdout.test.ts packages/adapter-utils/src/server-utils.test.ts server/src/__tests__/redaction.test.ts server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/acpx-local-skill-sync.test.ts server/src/__tests__/acpx-local-adapter-environment.test.ts server/src/__tests__/adapter-routes.test.ts server/src/__tests__/agent-skills-routes.test.ts ui/src/adapters/metadata.test.ts` — 12 files, 87 tests passed. - `pnpm --filter @paperclipai/adapter-acpx-local typecheck` — passed. - `pnpm --filter @paperclipai/server typecheck` — passed. - `pnpm --filter @paperclipai/ui typecheck` — passed. - Confirmed PR diff does not include `pnpm-lock.yaml`, database schema files, or migrations. Screenshots: ![ACPX Claude skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-light.png?raw=true) ![ACPX Claude skills dark](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-dark.png?raw=true) ![ACPX custom skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-custom-light.png?raw=true) ## Risks - Medium risk: this introduces a new built-in adapter package and touches runtime execution, adapter registration, agent config, skills, and transcript rendering. - ACPX and ACP agent behavior can vary by installed tool versions; the adapter is marked experimental to set operator expectations. - `pnpm-lock.yaml` is excluded per repository PR policy, so dependency lock refresh must be handled by the repo’s automation or maintainers. - No database migration risk: no schema or migration files changed. > 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 coding agent based on GPT-5, with repository tool use, shell execution, git operations, and local verification. Exact hosted context window was not exposed in this environment. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-30 19:57:05 -05:00
function warmHandleMatches(
entry: RuntimeCacheEntry | undefined,
runtime: AcpRuntime,
handle: AcpRuntimeHandle,
): boolean {
return entry?.runtime === runtime && entry.handle === handle;
}
export function createAcpxLocalExecutor(deps: ExecuteDeps = {}) {
const createRuntime = deps.createRuntime ?? createAcpRuntime;
const now = deps.now ?? (() => Date.now());
const warmHandles = deps.warmHandles ?? defaultWarmHandles;
return async function executeAcpxLocal(ctx: AdapterExecutionContext): Promise<AdapterExecutionResult> {
const prepared = await buildRuntime({ ctx });
Improve ACPX adapter configuration (#5290) ## Thinking Path > - Paperclip orchestrates AI agents across several adapter implementations. > - ACPX is a local adapter path that can proxy Claude and Codex-style execution. > - Its configuration needed stronger schema defaults, provider-aware model handling, and better UI support. > - Plugin authors also need clear docs for managed resources. > - This pull request improves ACPX adapter configuration and documents plugin-managed resources. > - The benefit is a more predictable adapter setup path without changing unrelated control-plane behavior. ## What Changed - Improved ACPX config schema, execution config handling, UI build config, and route coverage. - Added ACPX model filtering support and tests. - Updated the agent config form and storybook coverage for ACPX model/provider behavior. - Expanded plugin authoring documentation for managed resources. ## Verification - `pnpm install --frozen-lockfile` - `pnpm exec vitest run server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/adapter-routes.test.ts ui/src/lib/acpx-model-filter.test.ts` ## Risks - Low-to-medium risk: adapter configuration behavior changes can affect ACPX users, but the change is isolated to ACPX/plugin-doc surfaces and covered by targeted adapter tests. ## Model Used - OpenAI GPT-5 Codex via Paperclip `codex_local` adapter, with shell/git/GitHub CLI tool use. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-05-06 06:06:47 -05:00
const warmIdleMs = asNumber(ctx.config.warmHandleIdleMs, DEFAULT_ACPX_LOCAL_WARM_HANDLE_IDLE_MS);
Add ACPX local adapter runtime (#4893) ## Thinking Path > - Paperclip orchestrates AI-agent companies through a control plane that can start, supervise, and recover agent runs. > - Local adapters are the bridge between Paperclip issues and concrete agent runtimes such as Claude, Codex, and other ACP-compatible tools. > - The roadmap calls out broader “bring your own agent” and claw-style agent support, and ACPX gives Paperclip one path to normalize multiple ACP agents behind a single adapter. > - The branch needed to become one reviewable PR against current `paperclipai/paperclip:master`, without carrying stale base conflicts or generated lockfile churn. > - This pull request adds an experimental built-in `acpx_local` adapter, integrates it through the server/CLI/UI adapter surfaces, and adds regression coverage for runtime execution, skill sync, stream parsing, diagnostics, and log redaction. > - The benefit is that Paperclip can run Claude/Codex/custom ACP agents through ACPX while keeping operator configuration, skills, logging, and transcript rendering inside the existing adapter model. ## What Changed - Added `@paperclipai/adapter-acpx-local` with server execution, config schema, ACPX session handling, CLI formatting, UI config helpers, and stdout parsing. - Registered `acpx_local` across CLI, server, shared constants, UI adapter metadata, adapter capabilities, and agent creation/editing surfaces. - Added ACPX runtime execution support with persistent sessions, local-agent JWT environment handling, skill snapshots, runtime skill materialization, and isolation/security regressions. - Added ACPX adapter diagnostics and marked the adapter experimental in the UI. - Added command/env secret redaction for resolved command metadata in adapter-utils, server event storage, and the Agent Detail invocation UI. - Added Storybook coverage for ACPX config, transcript rendering, and skill states, plus PR screenshots under `docs/pr-screenshots/pap-2944/`. - Rebased the branch onto current `public-gh/master`; `pnpm-lock.yaml` is intentionally not included and there are no migration/schema changes. ## Verification - `pnpm exec vitest run packages/adapters/acpx-local/src/server/execute.test.ts packages/adapters/acpx-local/src/server/test.test.ts packages/adapters/acpx-local/src/cli/format-event.test.ts packages/adapters/acpx-local/src/ui/parse-stdout.test.ts packages/adapter-utils/src/server-utils.test.ts server/src/__tests__/redaction.test.ts server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/acpx-local-skill-sync.test.ts server/src/__tests__/acpx-local-adapter-environment.test.ts server/src/__tests__/adapter-routes.test.ts server/src/__tests__/agent-skills-routes.test.ts ui/src/adapters/metadata.test.ts` — 12 files, 87 tests passed. - `pnpm --filter @paperclipai/adapter-acpx-local typecheck` — passed. - `pnpm --filter @paperclipai/server typecheck` — passed. - `pnpm --filter @paperclipai/ui typecheck` — passed. - Confirmed PR diff does not include `pnpm-lock.yaml`, database schema files, or migrations. Screenshots: ![ACPX Claude skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-light.png?raw=true) ![ACPX Claude skills dark](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-dark.png?raw=true) ![ACPX custom skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-custom-light.png?raw=true) ## Risks - Medium risk: this introduces a new built-in adapter package and touches runtime execution, adapter registration, agent config, skills, and transcript rendering. - ACPX and ACP agent behavior can vary by installed tool versions; the adapter is marked experimental to set operator expectations. - `pnpm-lock.yaml` is excluded per repository PR policy, so dependency lock refresh must be handled by the repo’s automation or maintainers. - No database migration risk: no schema or migration files changed. > 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 coding agent based on GPT-5, with repository tool use, shell execution, git operations, and local verification. Exact hosted context window was not exposed in this environment. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-30 19:57:05 -05:00
await cleanupIdleHandles({ handles: warmHandles, now: now(), idleMs: warmIdleMs });
const previousParams = parseObject(ctx.runtime.sessionParams);
const canResume = isCompatibleSession(previousParams, prepared);
const resumeSessionId = canResume ? asString(previousParams.acpSessionId, "") || undefined : undefined;
const cached = canResume ? warmHandles.get(prepared.sessionKey) : undefined;
const runtimeOptions: AcpRuntimeOptions = {
cwd: prepared.cwd,
sessionStore: createRuntimeStore({ stateDir: prepared.stateDir }),
agentRegistry: prepared.agentRegistry,
permissionMode: prepared.permissionMode,
nonInteractivePermissions: prepared.nonInteractivePermissions,
timeoutMs: prepared.timeoutSec > 0 ? prepared.timeoutSec * 1000 : undefined,
Make ACPX-Claude adapter work seamlessly (PAPA-388) (#6590) ## Thinking Path > - Paperclip orchestrates AI agents for zero-human companies, so when an adapter fails, the platform must surface enough detail for the next agent (or human reviewer) to act > - The `acpx_local` adapter wraps `claude-agent-acp`, which in turn drives the Claude Code SDK — three layers, three different permission and error-handling models > - A user created a `Claude Local ACPX` agent in PAPA-387 and it failed instantly with the generic `acpx.error / "Internal error"` log, stranding the work and triggering an opaque `stranded_assigned_issue` recovery to the CTO > - Once the diagnostic blackbox was opened, the underlying cause turned out to be two SDK-level mismatches: a model-name allowlist that rejects bare IDs like `claude-opus-4-7`, and a Claude Code permission/Read-sandbox configuration that silently denies every non-allowlisted tool when the user's `~/.claude/settings.json` has `defaultMode: "dontAsk"` > - This pull request fixes both classes of failure in the adapter itself so new ACPX agents work seamlessly without per-host configuration, and widens the diagnostic surface so the *next* failure of any kind is actionable > - The benefit is that ACPX-Claude can join the regular agent roster — verified end to end on PAPA-401, where the agent successfully reached the Paperclip API, opened a worktree, surveyed existing notification PRs, and posted a structured plan ## What Changed - Widen ACPX failure diagnostics (`packages/adapters/acpx-local/src/server/execute.ts`): - Capture `err.name`, ACP code, `cause.message`, retryable flag, and a 5-frame stack preview into `errorMeta`. - Promote phase-specific error codes: `ensure_session → acpx_session_init_failed`, `configure_session → acpx_session_config_failed`, `turn → acpx_turn_failed`, plus mapping for `ACP_BACKEND_MISSING` / `ACP_BACKEND_UNAVAILABLE`. - Set `verbose: true` on the ACPX runtime so its session-event log flows through `ctx.onLog`. - Capture child-process stderr via a wrapper-script tee into `<stateDir>/run-stderr/<runId>.log`, inline the tail into the `acpx.error` payload as `childStderrTail`, and forward it through `ctx.onLog("stderr", …)` so it lands in the heartbeat `stderrExcerpt` column (existing redaction applies). - Set the model via `ANTHROPIC_MODEL` env for the `claude` agent instead of `set_config_option(model, …)`. The ACP server's `set_config_option` handler validates against an internal allowlist and rejects bare IDs like `claude-opus-4-7`. `ANTHROPIC_MODEL` is read during initialization and bypasses that check. - Seed `<worktree>/.claude/settings.local.json` before spawning `claude-agent-acp` (the seamless-API fix). Since `claude-agent-acp` hard-codes `settingSources: ["user", "project", "local"]` and "local" has the highest precedence: - Set `permissions.defaultMode: "default"`, but **only** if the user's value is missing or `"dontAsk"` (the broken case). Other modes like `acceptEdits`/`plan` are preserved. - Pre-allow Paperclip's Bash surface (`Bash(curl:*)`, `Bash(env:*)`, `Bash(<cwd>/scripts/paperclip-issue-update.sh:*)`, `Bash(<cwd>/scripts/paperclip:*)`). - Widen `permissions.additionalDirectories` to include `stateDir`, `agentHome`, and the per-company instance root (`~/.paperclip/instances/<id>/companies/<companyId>`). Scoped to this company only — does not expose other tenants. - Existing user entries are merged, not replaced. The resolved roots are folded into the session fingerprint so warm-session handles invalidate when they change. - Sync the existing server-side integration test (`server/src/__tests__/acpx-local-execute.test.ts`) to assert `acpx_session_init_failed` instead of the now-removed `acpx_protocol_error` for `ACP_SESSION_INIT_FAILED` (a follow-up to commit 1). ## Verification - `pnpm --filter "@paperclipai/adapter-acpx-local" run typecheck` — passes. - `pnpm vitest run` in `packages/adapters/acpx-local` — 35/35 pass, includes 4 new tests covering the settings.local.json write path (claude only, merge with pre-existing content, `dontAsk` override, codex no-op). - `pnpm vitest run src/__tests__/acpx-local-execute.test.ts` in `server/` — 15/15 pass after the test-sync commit. - End-to-end manual verification (PAPA-401): the `Claude Local ACPX` agent that previously hit "restricted environment" now successfully reaches the Paperclip API, opens its worktree, posts structured plan comments, and flips the issue to `in_review` without any external configuration. ## Risks - **Low**, scoped to the `acpx_local` adapter. The settings.local.json write is per-worktree (worktrees live under `.paperclip/worktrees/<issue>/`) and only triggers when `acpxAgent === "claude"`. Existing user content is merged with `[...existing, ...paperclip]` and deduped — nothing is overwritten outright. - The `defaultMode` override is intentionally narrow: it only flips `"dontAsk"` (which silently denies every tool and is the root cause) to `"default"`. Users who explicitly picked `acceptEdits`, `plan`, or any other mode keep their choice. - Stderr capture goes through the existing `log-redaction` pass before persisting, so `PAPERCLIP_API_KEY` and similar secrets in the wrapper env don't leak into heartbeat logs. > 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 4.7 (`claude-opus-4-7`), running in the `claude_local` adapter via Paperclip's harness. Extended thinking enabled, tool use enabled. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [ ] If this change affects the UI, I have included before/after screenshots — N/A (adapter-only) - [ ] I have updated relevant documentation to reflect my changes — no user-facing docs changed; internal commentary in the code change explains the SDK constraints - [x] I have considered and documented any risks above - [ ] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-05-23 13:01:27 -07:00
// Scope ACPX runtime verbose logs to the claude agent only — that's the
// surface we know needs the extra session-event detail (PAPA-388). codex
// and custom agents already emit their own per-tool output and don't
// benefit from doubling the log volume.
verbose: prepared.acpxAgent === "claude",
Add ACPX local adapter runtime (#4893) ## Thinking Path > - Paperclip orchestrates AI-agent companies through a control plane that can start, supervise, and recover agent runs. > - Local adapters are the bridge between Paperclip issues and concrete agent runtimes such as Claude, Codex, and other ACP-compatible tools. > - The roadmap calls out broader “bring your own agent” and claw-style agent support, and ACPX gives Paperclip one path to normalize multiple ACP agents behind a single adapter. > - The branch needed to become one reviewable PR against current `paperclipai/paperclip:master`, without carrying stale base conflicts or generated lockfile churn. > - This pull request adds an experimental built-in `acpx_local` adapter, integrates it through the server/CLI/UI adapter surfaces, and adds regression coverage for runtime execution, skill sync, stream parsing, diagnostics, and log redaction. > - The benefit is that Paperclip can run Claude/Codex/custom ACP agents through ACPX while keeping operator configuration, skills, logging, and transcript rendering inside the existing adapter model. ## What Changed - Added `@paperclipai/adapter-acpx-local` with server execution, config schema, ACPX session handling, CLI formatting, UI config helpers, and stdout parsing. - Registered `acpx_local` across CLI, server, shared constants, UI adapter metadata, adapter capabilities, and agent creation/editing surfaces. - Added ACPX runtime execution support with persistent sessions, local-agent JWT environment handling, skill snapshots, runtime skill materialization, and isolation/security regressions. - Added ACPX adapter diagnostics and marked the adapter experimental in the UI. - Added command/env secret redaction for resolved command metadata in adapter-utils, server event storage, and the Agent Detail invocation UI. - Added Storybook coverage for ACPX config, transcript rendering, and skill states, plus PR screenshots under `docs/pr-screenshots/pap-2944/`. - Rebased the branch onto current `public-gh/master`; `pnpm-lock.yaml` is intentionally not included and there are no migration/schema changes. ## Verification - `pnpm exec vitest run packages/adapters/acpx-local/src/server/execute.test.ts packages/adapters/acpx-local/src/server/test.test.ts packages/adapters/acpx-local/src/cli/format-event.test.ts packages/adapters/acpx-local/src/ui/parse-stdout.test.ts packages/adapter-utils/src/server-utils.test.ts server/src/__tests__/redaction.test.ts server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/acpx-local-skill-sync.test.ts server/src/__tests__/acpx-local-adapter-environment.test.ts server/src/__tests__/adapter-routes.test.ts server/src/__tests__/agent-skills-routes.test.ts ui/src/adapters/metadata.test.ts` — 12 files, 87 tests passed. - `pnpm --filter @paperclipai/adapter-acpx-local typecheck` — passed. - `pnpm --filter @paperclipai/server typecheck` — passed. - `pnpm --filter @paperclipai/ui typecheck` — passed. - Confirmed PR diff does not include `pnpm-lock.yaml`, database schema files, or migrations. Screenshots: ![ACPX Claude skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-light.png?raw=true) ![ACPX Claude skills dark](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-dark.png?raw=true) ![ACPX custom skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-custom-light.png?raw=true) ## Risks - Medium risk: this introduces a new built-in adapter package and touches runtime execution, adapter registration, agent config, skills, and transcript rendering. - ACPX and ACP agent behavior can vary by installed tool versions; the adapter is marked experimental to set operator expectations. - `pnpm-lock.yaml` is excluded per repository PR policy, so dependency lock refresh must be handled by the repo’s automation or maintainers. - No database migration risk: no schema or migration files changed. > 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 coding agent based on GPT-5, with repository tool use, shell execution, git operations, and local verification. Exact hosted context window was not exposed in this environment. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-30 19:57:05 -05:00
};
const runtime = cached?.runtime ?? createRuntime(runtimeOptions);
Improve ACPX adapter configuration (#5290) ## Thinking Path > - Paperclip orchestrates AI agents across several adapter implementations. > - ACPX is a local adapter path that can proxy Claude and Codex-style execution. > - Its configuration needed stronger schema defaults, provider-aware model handling, and better UI support. > - Plugin authors also need clear docs for managed resources. > - This pull request improves ACPX adapter configuration and documents plugin-managed resources. > - The benefit is a more predictable adapter setup path without changing unrelated control-plane behavior. ## What Changed - Improved ACPX config schema, execution config handling, UI build config, and route coverage. - Added ACPX model filtering support and tests. - Updated the agent config form and storybook coverage for ACPX model/provider behavior. - Expanded plugin authoring documentation for managed resources. ## Verification - `pnpm install --frozen-lockfile` - `pnpm exec vitest run server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/adapter-routes.test.ts ui/src/lib/acpx-model-filter.test.ts` ## Risks - Low-to-medium risk: adapter configuration behavior changes can affect ACPX users, but the change is isolated to ACPX/plugin-doc surfaces and covered by targeted adapter tests. ## Model Used - OpenAI GPT-5 Codex via Paperclip `codex_local` adapter, with shell/git/GitHub CLI tool use. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-05-06 06:06:47 -05:00
if (cached) clearWarmHandleTimer(cached);
Add ACPX local adapter runtime (#4893) ## Thinking Path > - Paperclip orchestrates AI-agent companies through a control plane that can start, supervise, and recover agent runs. > - Local adapters are the bridge between Paperclip issues and concrete agent runtimes such as Claude, Codex, and other ACP-compatible tools. > - The roadmap calls out broader “bring your own agent” and claw-style agent support, and ACPX gives Paperclip one path to normalize multiple ACP agents behind a single adapter. > - The branch needed to become one reviewable PR against current `paperclipai/paperclip:master`, without carrying stale base conflicts or generated lockfile churn. > - This pull request adds an experimental built-in `acpx_local` adapter, integrates it through the server/CLI/UI adapter surfaces, and adds regression coverage for runtime execution, skill sync, stream parsing, diagnostics, and log redaction. > - The benefit is that Paperclip can run Claude/Codex/custom ACP agents through ACPX while keeping operator configuration, skills, logging, and transcript rendering inside the existing adapter model. ## What Changed - Added `@paperclipai/adapter-acpx-local` with server execution, config schema, ACPX session handling, CLI formatting, UI config helpers, and stdout parsing. - Registered `acpx_local` across CLI, server, shared constants, UI adapter metadata, adapter capabilities, and agent creation/editing surfaces. - Added ACPX runtime execution support with persistent sessions, local-agent JWT environment handling, skill snapshots, runtime skill materialization, and isolation/security regressions. - Added ACPX adapter diagnostics and marked the adapter experimental in the UI. - Added command/env secret redaction for resolved command metadata in adapter-utils, server event storage, and the Agent Detail invocation UI. - Added Storybook coverage for ACPX config, transcript rendering, and skill states, plus PR screenshots under `docs/pr-screenshots/pap-2944/`. - Rebased the branch onto current `public-gh/master`; `pnpm-lock.yaml` is intentionally not included and there are no migration/schema changes. ## Verification - `pnpm exec vitest run packages/adapters/acpx-local/src/server/execute.test.ts packages/adapters/acpx-local/src/server/test.test.ts packages/adapters/acpx-local/src/cli/format-event.test.ts packages/adapters/acpx-local/src/ui/parse-stdout.test.ts packages/adapter-utils/src/server-utils.test.ts server/src/__tests__/redaction.test.ts server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/acpx-local-skill-sync.test.ts server/src/__tests__/acpx-local-adapter-environment.test.ts server/src/__tests__/adapter-routes.test.ts server/src/__tests__/agent-skills-routes.test.ts ui/src/adapters/metadata.test.ts` — 12 files, 87 tests passed. - `pnpm --filter @paperclipai/adapter-acpx-local typecheck` — passed. - `pnpm --filter @paperclipai/server typecheck` — passed. - `pnpm --filter @paperclipai/ui typecheck` — passed. - Confirmed PR diff does not include `pnpm-lock.yaml`, database schema files, or migrations. Screenshots: ![ACPX Claude skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-light.png?raw=true) ![ACPX Claude skills dark](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-dark.png?raw=true) ![ACPX custom skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-custom-light.png?raw=true) ## Risks - Medium risk: this introduces a new built-in adapter package and touches runtime execution, adapter registration, agent config, skills, and transcript rendering. - ACPX and ACP agent behavior can vary by installed tool versions; the adapter is marked experimental to set operator expectations. - `pnpm-lock.yaml` is excluded per repository PR policy, so dependency lock refresh must be handled by the repo’s automation or maintainers. - No database migration risk: no schema or migration files changed. > 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 coding agent based on GPT-5, with repository tool use, shell execution, git operations, and local verification. Exact hosted context window was not exposed in this environment. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-30 19:57:05 -05:00
if (!canResume && asString(previousParams.runtimeSessionName, "")) {
await ctx.onLog(
"stdout",
`[paperclip] ACPX session "${asString(previousParams.runtimeSessionName, "")}" does not match the current agent/cwd/mode/runtime identity; starting fresh in "${prepared.cwd}".\n`,
);
}
let handle = cached?.handle ?? null;
let resumedSession = Boolean(handle ?? resumeSessionId);
let clearSession = false;
try {
if (!handle) {
try {
handle = await runtime.ensureSession({
sessionKey: prepared.sessionKey,
agent: prepared.acpxAgent,
mode: prepared.mode,
cwd: prepared.cwd,
resumeSessionId,
});
} catch (err) {
if (!resumeSessionId || !isResumeFailure(err)) throw err;
clearSession = true;
resumedSession = false;
await ctx.onLog(
"stdout",
`[paperclip] ACPX resume session "${resumeSessionId}" is unavailable; retrying with a fresh session.\n`,
);
handle = await runtime.ensureSession({
sessionKey: prepared.sessionKey,
agent: prepared.acpxAgent,
mode: prepared.mode,
cwd: prepared.cwd,
});
}
}
} catch (err) {
Make ACPX-Claude adapter work seamlessly (PAPA-388) (#6590) ## Thinking Path > - Paperclip orchestrates AI agents for zero-human companies, so when an adapter fails, the platform must surface enough detail for the next agent (or human reviewer) to act > - The `acpx_local` adapter wraps `claude-agent-acp`, which in turn drives the Claude Code SDK — three layers, three different permission and error-handling models > - A user created a `Claude Local ACPX` agent in PAPA-387 and it failed instantly with the generic `acpx.error / "Internal error"` log, stranding the work and triggering an opaque `stranded_assigned_issue` recovery to the CTO > - Once the diagnostic blackbox was opened, the underlying cause turned out to be two SDK-level mismatches: a model-name allowlist that rejects bare IDs like `claude-opus-4-7`, and a Claude Code permission/Read-sandbox configuration that silently denies every non-allowlisted tool when the user's `~/.claude/settings.json` has `defaultMode: "dontAsk"` > - This pull request fixes both classes of failure in the adapter itself so new ACPX agents work seamlessly without per-host configuration, and widens the diagnostic surface so the *next* failure of any kind is actionable > - The benefit is that ACPX-Claude can join the regular agent roster — verified end to end on PAPA-401, where the agent successfully reached the Paperclip API, opened a worktree, surveyed existing notification PRs, and posted a structured plan ## What Changed - Widen ACPX failure diagnostics (`packages/adapters/acpx-local/src/server/execute.ts`): - Capture `err.name`, ACP code, `cause.message`, retryable flag, and a 5-frame stack preview into `errorMeta`. - Promote phase-specific error codes: `ensure_session → acpx_session_init_failed`, `configure_session → acpx_session_config_failed`, `turn → acpx_turn_failed`, plus mapping for `ACP_BACKEND_MISSING` / `ACP_BACKEND_UNAVAILABLE`. - Set `verbose: true` on the ACPX runtime so its session-event log flows through `ctx.onLog`. - Capture child-process stderr via a wrapper-script tee into `<stateDir>/run-stderr/<runId>.log`, inline the tail into the `acpx.error` payload as `childStderrTail`, and forward it through `ctx.onLog("stderr", …)` so it lands in the heartbeat `stderrExcerpt` column (existing redaction applies). - Set the model via `ANTHROPIC_MODEL` env for the `claude` agent instead of `set_config_option(model, …)`. The ACP server's `set_config_option` handler validates against an internal allowlist and rejects bare IDs like `claude-opus-4-7`. `ANTHROPIC_MODEL` is read during initialization and bypasses that check. - Seed `<worktree>/.claude/settings.local.json` before spawning `claude-agent-acp` (the seamless-API fix). Since `claude-agent-acp` hard-codes `settingSources: ["user", "project", "local"]` and "local" has the highest precedence: - Set `permissions.defaultMode: "default"`, but **only** if the user's value is missing or `"dontAsk"` (the broken case). Other modes like `acceptEdits`/`plan` are preserved. - Pre-allow Paperclip's Bash surface (`Bash(curl:*)`, `Bash(env:*)`, `Bash(<cwd>/scripts/paperclip-issue-update.sh:*)`, `Bash(<cwd>/scripts/paperclip:*)`). - Widen `permissions.additionalDirectories` to include `stateDir`, `agentHome`, and the per-company instance root (`~/.paperclip/instances/<id>/companies/<companyId>`). Scoped to this company only — does not expose other tenants. - Existing user entries are merged, not replaced. The resolved roots are folded into the session fingerprint so warm-session handles invalidate when they change. - Sync the existing server-side integration test (`server/src/__tests__/acpx-local-execute.test.ts`) to assert `acpx_session_init_failed` instead of the now-removed `acpx_protocol_error` for `ACP_SESSION_INIT_FAILED` (a follow-up to commit 1). ## Verification - `pnpm --filter "@paperclipai/adapter-acpx-local" run typecheck` — passes. - `pnpm vitest run` in `packages/adapters/acpx-local` — 35/35 pass, includes 4 new tests covering the settings.local.json write path (claude only, merge with pre-existing content, `dontAsk` override, codex no-op). - `pnpm vitest run src/__tests__/acpx-local-execute.test.ts` in `server/` — 15/15 pass after the test-sync commit. - End-to-end manual verification (PAPA-401): the `Claude Local ACPX` agent that previously hit "restricted environment" now successfully reaches the Paperclip API, opens its worktree, posts structured plan comments, and flips the issue to `in_review` without any external configuration. ## Risks - **Low**, scoped to the `acpx_local` adapter. The settings.local.json write is per-worktree (worktrees live under `.paperclip/worktrees/<issue>/`) and only triggers when `acpxAgent === "claude"`. Existing user content is merged with `[...existing, ...paperclip]` and deduped — nothing is overwritten outright. - The `defaultMode` override is intentionally narrow: it only flips `"dontAsk"` (which silently denies every tool and is the root cause) to `"default"`. Users who explicitly picked `acceptEdits`, `plan`, or any other mode keep their choice. - Stderr capture goes through the existing `log-redaction` pass before persisting, so `PAPERCLIP_API_KEY` and similar secrets in the wrapper env don't leak into heartbeat logs. > 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 4.7 (`claude-opus-4-7`), running in the `claude_local` adapter via Paperclip's harness. Extended thinking enabled, tool use enabled. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [ ] If this change affects the UI, I have included before/after screenshots — N/A (adapter-only) - [ ] I have updated relevant documentation to reflect my changes — no user-facing docs changed; internal commentary in the code change explains the SDK constraints - [x] I have considered and documented any risks above - [ ] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-05-23 13:01:27 -07:00
const { classified, message } = await emitAcpxFailure({
ctx,
prepared,
err,
phase: "ensure_session",
});
Add ACPX local adapter runtime (#4893) ## Thinking Path > - Paperclip orchestrates AI-agent companies through a control plane that can start, supervise, and recover agent runs. > - Local adapters are the bridge between Paperclip issues and concrete agent runtimes such as Claude, Codex, and other ACP-compatible tools. > - The roadmap calls out broader “bring your own agent” and claw-style agent support, and ACPX gives Paperclip one path to normalize multiple ACP agents behind a single adapter. > - The branch needed to become one reviewable PR against current `paperclipai/paperclip:master`, without carrying stale base conflicts or generated lockfile churn. > - This pull request adds an experimental built-in `acpx_local` adapter, integrates it through the server/CLI/UI adapter surfaces, and adds regression coverage for runtime execution, skill sync, stream parsing, diagnostics, and log redaction. > - The benefit is that Paperclip can run Claude/Codex/custom ACP agents through ACPX while keeping operator configuration, skills, logging, and transcript rendering inside the existing adapter model. ## What Changed - Added `@paperclipai/adapter-acpx-local` with server execution, config schema, ACPX session handling, CLI formatting, UI config helpers, and stdout parsing. - Registered `acpx_local` across CLI, server, shared constants, UI adapter metadata, adapter capabilities, and agent creation/editing surfaces. - Added ACPX runtime execution support with persistent sessions, local-agent JWT environment handling, skill snapshots, runtime skill materialization, and isolation/security regressions. - Added ACPX adapter diagnostics and marked the adapter experimental in the UI. - Added command/env secret redaction for resolved command metadata in adapter-utils, server event storage, and the Agent Detail invocation UI. - Added Storybook coverage for ACPX config, transcript rendering, and skill states, plus PR screenshots under `docs/pr-screenshots/pap-2944/`. - Rebased the branch onto current `public-gh/master`; `pnpm-lock.yaml` is intentionally not included and there are no migration/schema changes. ## Verification - `pnpm exec vitest run packages/adapters/acpx-local/src/server/execute.test.ts packages/adapters/acpx-local/src/server/test.test.ts packages/adapters/acpx-local/src/cli/format-event.test.ts packages/adapters/acpx-local/src/ui/parse-stdout.test.ts packages/adapter-utils/src/server-utils.test.ts server/src/__tests__/redaction.test.ts server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/acpx-local-skill-sync.test.ts server/src/__tests__/acpx-local-adapter-environment.test.ts server/src/__tests__/adapter-routes.test.ts server/src/__tests__/agent-skills-routes.test.ts ui/src/adapters/metadata.test.ts` — 12 files, 87 tests passed. - `pnpm --filter @paperclipai/adapter-acpx-local typecheck` — passed. - `pnpm --filter @paperclipai/server typecheck` — passed. - `pnpm --filter @paperclipai/ui typecheck` — passed. - Confirmed PR diff does not include `pnpm-lock.yaml`, database schema files, or migrations. Screenshots: ![ACPX Claude skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-light.png?raw=true) ![ACPX Claude skills dark](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-dark.png?raw=true) ![ACPX custom skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-custom-light.png?raw=true) ## Risks - Medium risk: this introduces a new built-in adapter package and touches runtime execution, adapter registration, agent config, skills, and transcript rendering. - ACPX and ACP agent behavior can vary by installed tool versions; the adapter is marked experimental to set operator expectations. - `pnpm-lock.yaml` is excluded per repository PR policy, so dependency lock refresh must be handled by the repo’s automation or maintainers. - No database migration risk: no schema or migration files changed. > 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 coding agent based on GPT-5, with repository tool use, shell execution, git operations, and local verification. Exact hosted context window was not exposed in this environment. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-30 19:57:05 -05:00
return {
exitCode: 1,
signal: null,
timedOut: false,
errorMessage: message,
...classified,
provider: "acpx",
Improve ACPX adapter configuration (#5290) ## Thinking Path > - Paperclip orchestrates AI agents across several adapter implementations. > - ACPX is a local adapter path that can proxy Claude and Codex-style execution. > - Its configuration needed stronger schema defaults, provider-aware model handling, and better UI support. > - Plugin authors also need clear docs for managed resources. > - This pull request improves ACPX adapter configuration and documents plugin-managed resources. > - The benefit is a more predictable adapter setup path without changing unrelated control-plane behavior. ## What Changed - Improved ACPX config schema, execution config handling, UI build config, and route coverage. - Added ACPX model filtering support and tests. - Updated the agent config form and storybook coverage for ACPX model/provider behavior. - Expanded plugin authoring documentation for managed resources. ## Verification - `pnpm install --frozen-lockfile` - `pnpm exec vitest run server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/adapter-routes.test.ts ui/src/lib/acpx-model-filter.test.ts` ## Risks - Low-to-medium risk: adapter configuration behavior changes can affect ACPX users, but the change is isolated to ACPX/plugin-doc surfaces and covered by targeted adapter tests. ## Model Used - OpenAI GPT-5 Codex via Paperclip `codex_local` adapter, with shell/git/GitHub CLI tool use. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-05-06 06:06:47 -05:00
model: prepared.requestedModel || null,
Add ACPX local adapter runtime (#4893) ## Thinking Path > - Paperclip orchestrates AI-agent companies through a control plane that can start, supervise, and recover agent runs. > - Local adapters are the bridge between Paperclip issues and concrete agent runtimes such as Claude, Codex, and other ACP-compatible tools. > - The roadmap calls out broader “bring your own agent” and claw-style agent support, and ACPX gives Paperclip one path to normalize multiple ACP agents behind a single adapter. > - The branch needed to become one reviewable PR against current `paperclipai/paperclip:master`, without carrying stale base conflicts or generated lockfile churn. > - This pull request adds an experimental built-in `acpx_local` adapter, integrates it through the server/CLI/UI adapter surfaces, and adds regression coverage for runtime execution, skill sync, stream parsing, diagnostics, and log redaction. > - The benefit is that Paperclip can run Claude/Codex/custom ACP agents through ACPX while keeping operator configuration, skills, logging, and transcript rendering inside the existing adapter model. ## What Changed - Added `@paperclipai/adapter-acpx-local` with server execution, config schema, ACPX session handling, CLI formatting, UI config helpers, and stdout parsing. - Registered `acpx_local` across CLI, server, shared constants, UI adapter metadata, adapter capabilities, and agent creation/editing surfaces. - Added ACPX runtime execution support with persistent sessions, local-agent JWT environment handling, skill snapshots, runtime skill materialization, and isolation/security regressions. - Added ACPX adapter diagnostics and marked the adapter experimental in the UI. - Added command/env secret redaction for resolved command metadata in adapter-utils, server event storage, and the Agent Detail invocation UI. - Added Storybook coverage for ACPX config, transcript rendering, and skill states, plus PR screenshots under `docs/pr-screenshots/pap-2944/`. - Rebased the branch onto current `public-gh/master`; `pnpm-lock.yaml` is intentionally not included and there are no migration/schema changes. ## Verification - `pnpm exec vitest run packages/adapters/acpx-local/src/server/execute.test.ts packages/adapters/acpx-local/src/server/test.test.ts packages/adapters/acpx-local/src/cli/format-event.test.ts packages/adapters/acpx-local/src/ui/parse-stdout.test.ts packages/adapter-utils/src/server-utils.test.ts server/src/__tests__/redaction.test.ts server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/acpx-local-skill-sync.test.ts server/src/__tests__/acpx-local-adapter-environment.test.ts server/src/__tests__/adapter-routes.test.ts server/src/__tests__/agent-skills-routes.test.ts ui/src/adapters/metadata.test.ts` — 12 files, 87 tests passed. - `pnpm --filter @paperclipai/adapter-acpx-local typecheck` — passed. - `pnpm --filter @paperclipai/server typecheck` — passed. - `pnpm --filter @paperclipai/ui typecheck` — passed. - Confirmed PR diff does not include `pnpm-lock.yaml`, database schema files, or migrations. Screenshots: ![ACPX Claude skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-light.png?raw=true) ![ACPX Claude skills dark](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-dark.png?raw=true) ![ACPX custom skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-custom-light.png?raw=true) ## Risks - Medium risk: this introduces a new built-in adapter package and touches runtime execution, adapter registration, agent config, skills, and transcript rendering. - ACPX and ACP agent behavior can vary by installed tool versions; the adapter is marked experimental to set operator expectations. - `pnpm-lock.yaml` is excluded per repository PR policy, so dependency lock refresh must be handled by the repo’s automation or maintainers. - No database migration risk: no schema or migration files changed. > 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 coding agent based on GPT-5, with repository tool use, shell execution, git operations, and local verification. Exact hosted context window was not exposed in this environment. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-30 19:57:05 -05:00
clearSession,
resultJson: { phase: "ensure_session" },
summary: message,
};
}
if (!handle) {
return {
exitCode: 1,
signal: null,
timedOut: false,
errorMessage: "ACPX did not return a runtime session handle.",
errorCode: "acpx_runtime_error",
provider: "acpx",
Improve ACPX adapter configuration (#5290) ## Thinking Path > - Paperclip orchestrates AI agents across several adapter implementations. > - ACPX is a local adapter path that can proxy Claude and Codex-style execution. > - Its configuration needed stronger schema defaults, provider-aware model handling, and better UI support. > - Plugin authors also need clear docs for managed resources. > - This pull request improves ACPX adapter configuration and documents plugin-managed resources. > - The benefit is a more predictable adapter setup path without changing unrelated control-plane behavior. ## What Changed - Improved ACPX config schema, execution config handling, UI build config, and route coverage. - Added ACPX model filtering support and tests. - Updated the agent config form and storybook coverage for ACPX model/provider behavior. - Expanded plugin authoring documentation for managed resources. ## Verification - `pnpm install --frozen-lockfile` - `pnpm exec vitest run server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/adapter-routes.test.ts ui/src/lib/acpx-model-filter.test.ts` ## Risks - Low-to-medium risk: adapter configuration behavior changes can affect ACPX users, but the change is isolated to ACPX/plugin-doc surfaces and covered by targeted adapter tests. ## Model Used - OpenAI GPT-5 Codex via Paperclip `codex_local` adapter, with shell/git/GitHub CLI tool use. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-05-06 06:06:47 -05:00
model: prepared.requestedModel || null,
Add ACPX local adapter runtime (#4893) ## Thinking Path > - Paperclip orchestrates AI-agent companies through a control plane that can start, supervise, and recover agent runs. > - Local adapters are the bridge between Paperclip issues and concrete agent runtimes such as Claude, Codex, and other ACP-compatible tools. > - The roadmap calls out broader “bring your own agent” and claw-style agent support, and ACPX gives Paperclip one path to normalize multiple ACP agents behind a single adapter. > - The branch needed to become one reviewable PR against current `paperclipai/paperclip:master`, without carrying stale base conflicts or generated lockfile churn. > - This pull request adds an experimental built-in `acpx_local` adapter, integrates it through the server/CLI/UI adapter surfaces, and adds regression coverage for runtime execution, skill sync, stream parsing, diagnostics, and log redaction. > - The benefit is that Paperclip can run Claude/Codex/custom ACP agents through ACPX while keeping operator configuration, skills, logging, and transcript rendering inside the existing adapter model. ## What Changed - Added `@paperclipai/adapter-acpx-local` with server execution, config schema, ACPX session handling, CLI formatting, UI config helpers, and stdout parsing. - Registered `acpx_local` across CLI, server, shared constants, UI adapter metadata, adapter capabilities, and agent creation/editing surfaces. - Added ACPX runtime execution support with persistent sessions, local-agent JWT environment handling, skill snapshots, runtime skill materialization, and isolation/security regressions. - Added ACPX adapter diagnostics and marked the adapter experimental in the UI. - Added command/env secret redaction for resolved command metadata in adapter-utils, server event storage, and the Agent Detail invocation UI. - Added Storybook coverage for ACPX config, transcript rendering, and skill states, plus PR screenshots under `docs/pr-screenshots/pap-2944/`. - Rebased the branch onto current `public-gh/master`; `pnpm-lock.yaml` is intentionally not included and there are no migration/schema changes. ## Verification - `pnpm exec vitest run packages/adapters/acpx-local/src/server/execute.test.ts packages/adapters/acpx-local/src/server/test.test.ts packages/adapters/acpx-local/src/cli/format-event.test.ts packages/adapters/acpx-local/src/ui/parse-stdout.test.ts packages/adapter-utils/src/server-utils.test.ts server/src/__tests__/redaction.test.ts server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/acpx-local-skill-sync.test.ts server/src/__tests__/acpx-local-adapter-environment.test.ts server/src/__tests__/adapter-routes.test.ts server/src/__tests__/agent-skills-routes.test.ts ui/src/adapters/metadata.test.ts` — 12 files, 87 tests passed. - `pnpm --filter @paperclipai/adapter-acpx-local typecheck` — passed. - `pnpm --filter @paperclipai/server typecheck` — passed. - `pnpm --filter @paperclipai/ui typecheck` — passed. - Confirmed PR diff does not include `pnpm-lock.yaml`, database schema files, or migrations. Screenshots: ![ACPX Claude skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-light.png?raw=true) ![ACPX Claude skills dark](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-dark.png?raw=true) ![ACPX custom skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-custom-light.png?raw=true) ## Risks - Medium risk: this introduces a new built-in adapter package and touches runtime execution, adapter registration, agent config, skills, and transcript rendering. - ACPX and ACP agent behavior can vary by installed tool versions; the adapter is marked experimental to set operator expectations. - `pnpm-lock.yaml` is excluded per repository PR policy, so dependency lock refresh must be handled by the repo’s automation or maintainers. - No database migration risk: no schema or migration files changed. > 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 coding agent based on GPT-5, with repository tool use, shell execution, git operations, and local verification. Exact hosted context window was not exposed in this environment. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-30 19:57:05 -05:00
resultJson: { phase: "ensure_session" },
summary: "ACPX did not return a runtime session handle.",
};
}
const sessionHandle = handle;
Improve ACPX adapter configuration (#5290) ## Thinking Path > - Paperclip orchestrates AI agents across several adapter implementations. > - ACPX is a local adapter path that can proxy Claude and Codex-style execution. > - Its configuration needed stronger schema defaults, provider-aware model handling, and better UI support. > - Plugin authors also need clear docs for managed resources. > - This pull request improves ACPX adapter configuration and documents plugin-managed resources. > - The benefit is a more predictable adapter setup path without changing unrelated control-plane behavior. ## What Changed - Improved ACPX config schema, execution config handling, UI build config, and route coverage. - Added ACPX model filtering support and tests. - Updated the agent config form and storybook coverage for ACPX model/provider behavior. - Expanded plugin authoring documentation for managed resources. ## Verification - `pnpm install --frozen-lockfile` - `pnpm exec vitest run server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/adapter-routes.test.ts ui/src/lib/acpx-model-filter.test.ts` ## Risks - Low-to-medium risk: adapter configuration behavior changes can affect ACPX users, but the change is isolated to ACPX/plugin-doc surfaces and covered by targeted adapter tests. ## Model Used - OpenAI GPT-5 Codex via Paperclip `codex_local` adapter, with shell/git/GitHub CLI tool use. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-05-06 06:06:47 -05:00
try {
await applySessionConfigOptions({
runtime,
handle: sessionHandle,
prepared,
onLog: ctx.onLog,
});
} catch (err) {
Make ACPX-Claude adapter work seamlessly (PAPA-388) (#6590) ## Thinking Path > - Paperclip orchestrates AI agents for zero-human companies, so when an adapter fails, the platform must surface enough detail for the next agent (or human reviewer) to act > - The `acpx_local` adapter wraps `claude-agent-acp`, which in turn drives the Claude Code SDK — three layers, three different permission and error-handling models > - A user created a `Claude Local ACPX` agent in PAPA-387 and it failed instantly with the generic `acpx.error / "Internal error"` log, stranding the work and triggering an opaque `stranded_assigned_issue` recovery to the CTO > - Once the diagnostic blackbox was opened, the underlying cause turned out to be two SDK-level mismatches: a model-name allowlist that rejects bare IDs like `claude-opus-4-7`, and a Claude Code permission/Read-sandbox configuration that silently denies every non-allowlisted tool when the user's `~/.claude/settings.json` has `defaultMode: "dontAsk"` > - This pull request fixes both classes of failure in the adapter itself so new ACPX agents work seamlessly without per-host configuration, and widens the diagnostic surface so the *next* failure of any kind is actionable > - The benefit is that ACPX-Claude can join the regular agent roster — verified end to end on PAPA-401, where the agent successfully reached the Paperclip API, opened a worktree, surveyed existing notification PRs, and posted a structured plan ## What Changed - Widen ACPX failure diagnostics (`packages/adapters/acpx-local/src/server/execute.ts`): - Capture `err.name`, ACP code, `cause.message`, retryable flag, and a 5-frame stack preview into `errorMeta`. - Promote phase-specific error codes: `ensure_session → acpx_session_init_failed`, `configure_session → acpx_session_config_failed`, `turn → acpx_turn_failed`, plus mapping for `ACP_BACKEND_MISSING` / `ACP_BACKEND_UNAVAILABLE`. - Set `verbose: true` on the ACPX runtime so its session-event log flows through `ctx.onLog`. - Capture child-process stderr via a wrapper-script tee into `<stateDir>/run-stderr/<runId>.log`, inline the tail into the `acpx.error` payload as `childStderrTail`, and forward it through `ctx.onLog("stderr", …)` so it lands in the heartbeat `stderrExcerpt` column (existing redaction applies). - Set the model via `ANTHROPIC_MODEL` env for the `claude` agent instead of `set_config_option(model, …)`. The ACP server's `set_config_option` handler validates against an internal allowlist and rejects bare IDs like `claude-opus-4-7`. `ANTHROPIC_MODEL` is read during initialization and bypasses that check. - Seed `<worktree>/.claude/settings.local.json` before spawning `claude-agent-acp` (the seamless-API fix). Since `claude-agent-acp` hard-codes `settingSources: ["user", "project", "local"]` and "local" has the highest precedence: - Set `permissions.defaultMode: "default"`, but **only** if the user's value is missing or `"dontAsk"` (the broken case). Other modes like `acceptEdits`/`plan` are preserved. - Pre-allow Paperclip's Bash surface (`Bash(curl:*)`, `Bash(env:*)`, `Bash(<cwd>/scripts/paperclip-issue-update.sh:*)`, `Bash(<cwd>/scripts/paperclip:*)`). - Widen `permissions.additionalDirectories` to include `stateDir`, `agentHome`, and the per-company instance root (`~/.paperclip/instances/<id>/companies/<companyId>`). Scoped to this company only — does not expose other tenants. - Existing user entries are merged, not replaced. The resolved roots are folded into the session fingerprint so warm-session handles invalidate when they change. - Sync the existing server-side integration test (`server/src/__tests__/acpx-local-execute.test.ts`) to assert `acpx_session_init_failed` instead of the now-removed `acpx_protocol_error` for `ACP_SESSION_INIT_FAILED` (a follow-up to commit 1). ## Verification - `pnpm --filter "@paperclipai/adapter-acpx-local" run typecheck` — passes. - `pnpm vitest run` in `packages/adapters/acpx-local` — 35/35 pass, includes 4 new tests covering the settings.local.json write path (claude only, merge with pre-existing content, `dontAsk` override, codex no-op). - `pnpm vitest run src/__tests__/acpx-local-execute.test.ts` in `server/` — 15/15 pass after the test-sync commit. - End-to-end manual verification (PAPA-401): the `Claude Local ACPX` agent that previously hit "restricted environment" now successfully reaches the Paperclip API, opens its worktree, posts structured plan comments, and flips the issue to `in_review` without any external configuration. ## Risks - **Low**, scoped to the `acpx_local` adapter. The settings.local.json write is per-worktree (worktrees live under `.paperclip/worktrees/<issue>/`) and only triggers when `acpxAgent === "claude"`. Existing user content is merged with `[...existing, ...paperclip]` and deduped — nothing is overwritten outright. - The `defaultMode` override is intentionally narrow: it only flips `"dontAsk"` (which silently denies every tool and is the root cause) to `"default"`. Users who explicitly picked `acceptEdits`, `plan`, or any other mode keep their choice. - Stderr capture goes through the existing `log-redaction` pass before persisting, so `PAPERCLIP_API_KEY` and similar secrets in the wrapper env don't leak into heartbeat logs. > 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 4.7 (`claude-opus-4-7`), running in the `claude_local` adapter via Paperclip's harness. Extended thinking enabled, tool use enabled. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [ ] If this change affects the UI, I have included before/after screenshots — N/A (adapter-only) - [ ] I have updated relevant documentation to reflect my changes — no user-facing docs changed; internal commentary in the code change explains the SDK constraints - [x] I have considered and documented any risks above - [ ] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-05-23 13:01:27 -07:00
const { classified, message } = await emitAcpxFailure({
ctx,
prepared,
err,
phase: "configure_session",
});
Improve ACPX adapter configuration (#5290) ## Thinking Path > - Paperclip orchestrates AI agents across several adapter implementations. > - ACPX is a local adapter path that can proxy Claude and Codex-style execution. > - Its configuration needed stronger schema defaults, provider-aware model handling, and better UI support. > - Plugin authors also need clear docs for managed resources. > - This pull request improves ACPX adapter configuration and documents plugin-managed resources. > - The benefit is a more predictable adapter setup path without changing unrelated control-plane behavior. ## What Changed - Improved ACPX config schema, execution config handling, UI build config, and route coverage. - Added ACPX model filtering support and tests. - Updated the agent config form and storybook coverage for ACPX model/provider behavior. - Expanded plugin authoring documentation for managed resources. ## Verification - `pnpm install --frozen-lockfile` - `pnpm exec vitest run server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/adapter-routes.test.ts ui/src/lib/acpx-model-filter.test.ts` ## Risks - Low-to-medium risk: adapter configuration behavior changes can affect ACPX users, but the change is isolated to ACPX/plugin-doc surfaces and covered by targeted adapter tests. ## Model Used - OpenAI GPT-5 Codex via Paperclip `codex_local` adapter, with shell/git/GitHub CLI tool use. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-05-06 06:06:47 -05:00
await runtime.close({
handle: sessionHandle,
reason: "paperclip config cleanup",
discardPersistentState: false,
}).catch(() => {});
const existing = warmHandles.get(prepared.sessionKey);
if (warmHandleMatches(existing, runtime, sessionHandle) && existing) {
clearWarmHandleTimer(existing);
warmHandles.delete(prepared.sessionKey);
}
return {
exitCode: 1,
signal: null,
timedOut: false,
errorMessage: message,
...classified,
provider: "acpx",
model: prepared.requestedModel || null,
clearSession,
resultJson: {
phase: "configure_session",
agent: prepared.acpxAgent,
requestedModel: prepared.requestedModel || null,
requestedThinkingEffort: prepared.requestedThinkingEffort || null,
fastMode: prepared.fastMode,
},
summary: message,
};
}
Add ACPX local adapter runtime (#4893) ## Thinking Path > - Paperclip orchestrates AI-agent companies through a control plane that can start, supervise, and recover agent runs. > - Local adapters are the bridge between Paperclip issues and concrete agent runtimes such as Claude, Codex, and other ACP-compatible tools. > - The roadmap calls out broader “bring your own agent” and claw-style agent support, and ACPX gives Paperclip one path to normalize multiple ACP agents behind a single adapter. > - The branch needed to become one reviewable PR against current `paperclipai/paperclip:master`, without carrying stale base conflicts or generated lockfile churn. > - This pull request adds an experimental built-in `acpx_local` adapter, integrates it through the server/CLI/UI adapter surfaces, and adds regression coverage for runtime execution, skill sync, stream parsing, diagnostics, and log redaction. > - The benefit is that Paperclip can run Claude/Codex/custom ACP agents through ACPX while keeping operator configuration, skills, logging, and transcript rendering inside the existing adapter model. ## What Changed - Added `@paperclipai/adapter-acpx-local` with server execution, config schema, ACPX session handling, CLI formatting, UI config helpers, and stdout parsing. - Registered `acpx_local` across CLI, server, shared constants, UI adapter metadata, adapter capabilities, and agent creation/editing surfaces. - Added ACPX runtime execution support with persistent sessions, local-agent JWT environment handling, skill snapshots, runtime skill materialization, and isolation/security regressions. - Added ACPX adapter diagnostics and marked the adapter experimental in the UI. - Added command/env secret redaction for resolved command metadata in adapter-utils, server event storage, and the Agent Detail invocation UI. - Added Storybook coverage for ACPX config, transcript rendering, and skill states, plus PR screenshots under `docs/pr-screenshots/pap-2944/`. - Rebased the branch onto current `public-gh/master`; `pnpm-lock.yaml` is intentionally not included and there are no migration/schema changes. ## Verification - `pnpm exec vitest run packages/adapters/acpx-local/src/server/execute.test.ts packages/adapters/acpx-local/src/server/test.test.ts packages/adapters/acpx-local/src/cli/format-event.test.ts packages/adapters/acpx-local/src/ui/parse-stdout.test.ts packages/adapter-utils/src/server-utils.test.ts server/src/__tests__/redaction.test.ts server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/acpx-local-skill-sync.test.ts server/src/__tests__/acpx-local-adapter-environment.test.ts server/src/__tests__/adapter-routes.test.ts server/src/__tests__/agent-skills-routes.test.ts ui/src/adapters/metadata.test.ts` — 12 files, 87 tests passed. - `pnpm --filter @paperclipai/adapter-acpx-local typecheck` — passed. - `pnpm --filter @paperclipai/server typecheck` — passed. - `pnpm --filter @paperclipai/ui typecheck` — passed. - Confirmed PR diff does not include `pnpm-lock.yaml`, database schema files, or migrations. Screenshots: ![ACPX Claude skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-light.png?raw=true) ![ACPX Claude skills dark](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-dark.png?raw=true) ![ACPX custom skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-custom-light.png?raw=true) ## Risks - Medium risk: this introduces a new built-in adapter package and touches runtime execution, adapter registration, agent config, skills, and transcript rendering. - ACPX and ACP agent behavior can vary by installed tool versions; the adapter is marked experimental to set operator expectations. - `pnpm-lock.yaml` is excluded per repository PR policy, so dependency lock refresh must be handled by the repo’s automation or maintainers. - No database migration risk: no schema or migration files changed. > 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 coding agent based on GPT-5, with repository tool use, shell execution, git operations, and local verification. Exact hosted context window was not exposed in this environment. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-30 19:57:05 -05:00
const { prompt, promptMetrics, commandNotes } = await buildPrompt(ctx, resumedSession);
const runPrompt = joinPromptSections([prepared.skillPromptInstructions, prompt]);
await emitAcpxLog(ctx, {
type: "acpx.session",
agent: prepared.acpxAgent,
sessionId: sessionHandle.backendSessionId,
acpSessionId: sessionHandle.backendSessionId,
agentSessionId: sessionHandle.agentSessionId,
runtimeSessionName: sessionHandle.runtimeSessionName,
mode: prepared.mode,
permissionMode: prepared.permissionMode,
Improve ACPX adapter configuration (#5290) ## Thinking Path > - Paperclip orchestrates AI agents across several adapter implementations. > - ACPX is a local adapter path that can proxy Claude and Codex-style execution. > - Its configuration needed stronger schema defaults, provider-aware model handling, and better UI support. > - Plugin authors also need clear docs for managed resources. > - This pull request improves ACPX adapter configuration and documents plugin-managed resources. > - The benefit is a more predictable adapter setup path without changing unrelated control-plane behavior. ## What Changed - Improved ACPX config schema, execution config handling, UI build config, and route coverage. - Added ACPX model filtering support and tests. - Updated the agent config form and storybook coverage for ACPX model/provider behavior. - Expanded plugin authoring documentation for managed resources. ## Verification - `pnpm install --frozen-lockfile` - `pnpm exec vitest run server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/adapter-routes.test.ts ui/src/lib/acpx-model-filter.test.ts` ## Risks - Low-to-medium risk: adapter configuration behavior changes can affect ACPX users, but the change is isolated to ACPX/plugin-doc surfaces and covered by targeted adapter tests. ## Model Used - OpenAI GPT-5 Codex via Paperclip `codex_local` adapter, with shell/git/GitHub CLI tool use. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-05-06 06:06:47 -05:00
model: prepared.requestedModel || null,
thinkingEffort: prepared.requestedThinkingEffort || null,
fastMode: prepared.fastMode,
Add ACPX local adapter runtime (#4893) ## Thinking Path > - Paperclip orchestrates AI-agent companies through a control plane that can start, supervise, and recover agent runs. > - Local adapters are the bridge between Paperclip issues and concrete agent runtimes such as Claude, Codex, and other ACP-compatible tools. > - The roadmap calls out broader “bring your own agent” and claw-style agent support, and ACPX gives Paperclip one path to normalize multiple ACP agents behind a single adapter. > - The branch needed to become one reviewable PR against current `paperclipai/paperclip:master`, without carrying stale base conflicts or generated lockfile churn. > - This pull request adds an experimental built-in `acpx_local` adapter, integrates it through the server/CLI/UI adapter surfaces, and adds regression coverage for runtime execution, skill sync, stream parsing, diagnostics, and log redaction. > - The benefit is that Paperclip can run Claude/Codex/custom ACP agents through ACPX while keeping operator configuration, skills, logging, and transcript rendering inside the existing adapter model. ## What Changed - Added `@paperclipai/adapter-acpx-local` with server execution, config schema, ACPX session handling, CLI formatting, UI config helpers, and stdout parsing. - Registered `acpx_local` across CLI, server, shared constants, UI adapter metadata, adapter capabilities, and agent creation/editing surfaces. - Added ACPX runtime execution support with persistent sessions, local-agent JWT environment handling, skill snapshots, runtime skill materialization, and isolation/security regressions. - Added ACPX adapter diagnostics and marked the adapter experimental in the UI. - Added command/env secret redaction for resolved command metadata in adapter-utils, server event storage, and the Agent Detail invocation UI. - Added Storybook coverage for ACPX config, transcript rendering, and skill states, plus PR screenshots under `docs/pr-screenshots/pap-2944/`. - Rebased the branch onto current `public-gh/master`; `pnpm-lock.yaml` is intentionally not included and there are no migration/schema changes. ## Verification - `pnpm exec vitest run packages/adapters/acpx-local/src/server/execute.test.ts packages/adapters/acpx-local/src/server/test.test.ts packages/adapters/acpx-local/src/cli/format-event.test.ts packages/adapters/acpx-local/src/ui/parse-stdout.test.ts packages/adapter-utils/src/server-utils.test.ts server/src/__tests__/redaction.test.ts server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/acpx-local-skill-sync.test.ts server/src/__tests__/acpx-local-adapter-environment.test.ts server/src/__tests__/adapter-routes.test.ts server/src/__tests__/agent-skills-routes.test.ts ui/src/adapters/metadata.test.ts` — 12 files, 87 tests passed. - `pnpm --filter @paperclipai/adapter-acpx-local typecheck` — passed. - `pnpm --filter @paperclipai/server typecheck` — passed. - `pnpm --filter @paperclipai/ui typecheck` — passed. - Confirmed PR diff does not include `pnpm-lock.yaml`, database schema files, or migrations. Screenshots: ![ACPX Claude skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-light.png?raw=true) ![ACPX Claude skills dark](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-dark.png?raw=true) ![ACPX custom skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-custom-light.png?raw=true) ## Risks - Medium risk: this introduces a new built-in adapter package and touches runtime execution, adapter registration, agent config, skills, and transcript rendering. - ACPX and ACP agent behavior can vary by installed tool versions; the adapter is marked experimental to set operator expectations. - `pnpm-lock.yaml` is excluded per repository PR policy, so dependency lock refresh must be handled by the repo’s automation or maintainers. - No database migration risk: no schema or migration files changed. > 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 coding agent based on GPT-5, with repository tool use, shell execution, git operations, and local verification. Exact hosted context window was not exposed in this environment. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-30 19:57:05 -05:00
});
if (ctx.onMeta) {
await ctx.onMeta({
adapterType: "acpx_local",
command: prepared.agentCommand ?? prepared.acpxAgent,
cwd: prepared.cwd,
commandNotes: [
`ACPX runtime embedded in Paperclip with ${prepared.mode} session mode.`,
`Effective ACPX permission mode: ${prepared.permissionMode}.`,
Make ACPX-Claude adapter work seamlessly (PAPA-388) (#6590) ## Thinking Path > - Paperclip orchestrates AI agents for zero-human companies, so when an adapter fails, the platform must surface enough detail for the next agent (or human reviewer) to act > - The `acpx_local` adapter wraps `claude-agent-acp`, which in turn drives the Claude Code SDK — three layers, three different permission and error-handling models > - A user created a `Claude Local ACPX` agent in PAPA-387 and it failed instantly with the generic `acpx.error / "Internal error"` log, stranding the work and triggering an opaque `stranded_assigned_issue` recovery to the CTO > - Once the diagnostic blackbox was opened, the underlying cause turned out to be two SDK-level mismatches: a model-name allowlist that rejects bare IDs like `claude-opus-4-7`, and a Claude Code permission/Read-sandbox configuration that silently denies every non-allowlisted tool when the user's `~/.claude/settings.json` has `defaultMode: "dontAsk"` > - This pull request fixes both classes of failure in the adapter itself so new ACPX agents work seamlessly without per-host configuration, and widens the diagnostic surface so the *next* failure of any kind is actionable > - The benefit is that ACPX-Claude can join the regular agent roster — verified end to end on PAPA-401, where the agent successfully reached the Paperclip API, opened a worktree, surveyed existing notification PRs, and posted a structured plan ## What Changed - Widen ACPX failure diagnostics (`packages/adapters/acpx-local/src/server/execute.ts`): - Capture `err.name`, ACP code, `cause.message`, retryable flag, and a 5-frame stack preview into `errorMeta`. - Promote phase-specific error codes: `ensure_session → acpx_session_init_failed`, `configure_session → acpx_session_config_failed`, `turn → acpx_turn_failed`, plus mapping for `ACP_BACKEND_MISSING` / `ACP_BACKEND_UNAVAILABLE`. - Set `verbose: true` on the ACPX runtime so its session-event log flows through `ctx.onLog`. - Capture child-process stderr via a wrapper-script tee into `<stateDir>/run-stderr/<runId>.log`, inline the tail into the `acpx.error` payload as `childStderrTail`, and forward it through `ctx.onLog("stderr", …)` so it lands in the heartbeat `stderrExcerpt` column (existing redaction applies). - Set the model via `ANTHROPIC_MODEL` env for the `claude` agent instead of `set_config_option(model, …)`. The ACP server's `set_config_option` handler validates against an internal allowlist and rejects bare IDs like `claude-opus-4-7`. `ANTHROPIC_MODEL` is read during initialization and bypasses that check. - Seed `<worktree>/.claude/settings.local.json` before spawning `claude-agent-acp` (the seamless-API fix). Since `claude-agent-acp` hard-codes `settingSources: ["user", "project", "local"]` and "local" has the highest precedence: - Set `permissions.defaultMode: "default"`, but **only** if the user's value is missing or `"dontAsk"` (the broken case). Other modes like `acceptEdits`/`plan` are preserved. - Pre-allow Paperclip's Bash surface (`Bash(curl:*)`, `Bash(env:*)`, `Bash(<cwd>/scripts/paperclip-issue-update.sh:*)`, `Bash(<cwd>/scripts/paperclip:*)`). - Widen `permissions.additionalDirectories` to include `stateDir`, `agentHome`, and the per-company instance root (`~/.paperclip/instances/<id>/companies/<companyId>`). Scoped to this company only — does not expose other tenants. - Existing user entries are merged, not replaced. The resolved roots are folded into the session fingerprint so warm-session handles invalidate when they change. - Sync the existing server-side integration test (`server/src/__tests__/acpx-local-execute.test.ts`) to assert `acpx_session_init_failed` instead of the now-removed `acpx_protocol_error` for `ACP_SESSION_INIT_FAILED` (a follow-up to commit 1). ## Verification - `pnpm --filter "@paperclipai/adapter-acpx-local" run typecheck` — passes. - `pnpm vitest run` in `packages/adapters/acpx-local` — 35/35 pass, includes 4 new tests covering the settings.local.json write path (claude only, merge with pre-existing content, `dontAsk` override, codex no-op). - `pnpm vitest run src/__tests__/acpx-local-execute.test.ts` in `server/` — 15/15 pass after the test-sync commit. - End-to-end manual verification (PAPA-401): the `Claude Local ACPX` agent that previously hit "restricted environment" now successfully reaches the Paperclip API, opens its worktree, posts structured plan comments, and flips the issue to `in_review` without any external configuration. ## Risks - **Low**, scoped to the `acpx_local` adapter. The settings.local.json write is per-worktree (worktrees live under `.paperclip/worktrees/<issue>/`) and only triggers when `acpxAgent === "claude"`. Existing user content is merged with `[...existing, ...paperclip]` and deduped — nothing is overwritten outright. - The `defaultMode` override is intentionally narrow: it only flips `"dontAsk"` (which silently denies every tool and is the root cause) to `"default"`. Users who explicitly picked `acceptEdits`, `plan`, or any other mode keep their choice. - Stderr capture goes through the existing `log-redaction` pass before persisting, so `PAPERCLIP_API_KEY` and similar secrets in the wrapper env don't leak into heartbeat logs. > 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 4.7 (`claude-opus-4-7`), running in the `claude_local` adapter via Paperclip's harness. Extended thinking enabled, tool use enabled. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [ ] If this change affects the UI, I have included before/after screenshots — N/A (adapter-only) - [ ] I have updated relevant documentation to reflect my changes — no user-facing docs changed; internal commentary in the code change explains the SDK constraints - [x] I have considered and documented any risks above - [ ] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-05-23 13:01:27 -07:00
...(prepared.requestedModel
? [
prepared.acpxAgent === "claude"
? `Requested ACPX model: ${prepared.requestedModel} (set via ANTHROPIC_MODEL env at startup).`
: `Requested ACPX model: ${prepared.requestedModel}.`,
]
: []),
Improve ACPX adapter configuration (#5290) ## Thinking Path > - Paperclip orchestrates AI agents across several adapter implementations. > - ACPX is a local adapter path that can proxy Claude and Codex-style execution. > - Its configuration needed stronger schema defaults, provider-aware model handling, and better UI support. > - Plugin authors also need clear docs for managed resources. > - This pull request improves ACPX adapter configuration and documents plugin-managed resources. > - The benefit is a more predictable adapter setup path without changing unrelated control-plane behavior. ## What Changed - Improved ACPX config schema, execution config handling, UI build config, and route coverage. - Added ACPX model filtering support and tests. - Updated the agent config form and storybook coverage for ACPX model/provider behavior. - Expanded plugin authoring documentation for managed resources. ## Verification - `pnpm install --frozen-lockfile` - `pnpm exec vitest run server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/adapter-routes.test.ts ui/src/lib/acpx-model-filter.test.ts` ## Risks - Low-to-medium risk: adapter configuration behavior changes can affect ACPX users, but the change is isolated to ACPX/plugin-doc surfaces and covered by targeted adapter tests. ## Model Used - OpenAI GPT-5 Codex via Paperclip `codex_local` adapter, with shell/git/GitHub CLI tool use. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-05-06 06:06:47 -05:00
...(prepared.requestedThinkingEffort ? [`Requested ACPX thinking effort: ${prepared.requestedThinkingEffort}.`] : []),
...(prepared.fastMode ? ["Requested ACPX Codex fast mode."] : []),
Add ACPX local adapter runtime (#4893) ## Thinking Path > - Paperclip orchestrates AI-agent companies through a control plane that can start, supervise, and recover agent runs. > - Local adapters are the bridge between Paperclip issues and concrete agent runtimes such as Claude, Codex, and other ACP-compatible tools. > - The roadmap calls out broader “bring your own agent” and claw-style agent support, and ACPX gives Paperclip one path to normalize multiple ACP agents behind a single adapter. > - The branch needed to become one reviewable PR against current `paperclipai/paperclip:master`, without carrying stale base conflicts or generated lockfile churn. > - This pull request adds an experimental built-in `acpx_local` adapter, integrates it through the server/CLI/UI adapter surfaces, and adds regression coverage for runtime execution, skill sync, stream parsing, diagnostics, and log redaction. > - The benefit is that Paperclip can run Claude/Codex/custom ACP agents through ACPX while keeping operator configuration, skills, logging, and transcript rendering inside the existing adapter model. ## What Changed - Added `@paperclipai/adapter-acpx-local` with server execution, config schema, ACPX session handling, CLI formatting, UI config helpers, and stdout parsing. - Registered `acpx_local` across CLI, server, shared constants, UI adapter metadata, adapter capabilities, and agent creation/editing surfaces. - Added ACPX runtime execution support with persistent sessions, local-agent JWT environment handling, skill snapshots, runtime skill materialization, and isolation/security regressions. - Added ACPX adapter diagnostics and marked the adapter experimental in the UI. - Added command/env secret redaction for resolved command metadata in adapter-utils, server event storage, and the Agent Detail invocation UI. - Added Storybook coverage for ACPX config, transcript rendering, and skill states, plus PR screenshots under `docs/pr-screenshots/pap-2944/`. - Rebased the branch onto current `public-gh/master`; `pnpm-lock.yaml` is intentionally not included and there are no migration/schema changes. ## Verification - `pnpm exec vitest run packages/adapters/acpx-local/src/server/execute.test.ts packages/adapters/acpx-local/src/server/test.test.ts packages/adapters/acpx-local/src/cli/format-event.test.ts packages/adapters/acpx-local/src/ui/parse-stdout.test.ts packages/adapter-utils/src/server-utils.test.ts server/src/__tests__/redaction.test.ts server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/acpx-local-skill-sync.test.ts server/src/__tests__/acpx-local-adapter-environment.test.ts server/src/__tests__/adapter-routes.test.ts server/src/__tests__/agent-skills-routes.test.ts ui/src/adapters/metadata.test.ts` — 12 files, 87 tests passed. - `pnpm --filter @paperclipai/adapter-acpx-local typecheck` — passed. - `pnpm --filter @paperclipai/server typecheck` — passed. - `pnpm --filter @paperclipai/ui typecheck` — passed. - Confirmed PR diff does not include `pnpm-lock.yaml`, database schema files, or migrations. Screenshots: ![ACPX Claude skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-light.png?raw=true) ![ACPX Claude skills dark](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-dark.png?raw=true) ![ACPX custom skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-custom-light.png?raw=true) ## Risks - Medium risk: this introduces a new built-in adapter package and touches runtime execution, adapter registration, agent config, skills, and transcript rendering. - ACPX and ACP agent behavior can vary by installed tool versions; the adapter is marked experimental to set operator expectations. - `pnpm-lock.yaml` is excluded per repository PR policy, so dependency lock refresh must be handled by the repo’s automation or maintainers. - No database migration risk: no schema or migration files changed. > 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 coding agent based on GPT-5, with repository tool use, shell execution, git operations, and local verification. Exact hosted context window was not exposed in this environment. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-30 19:57:05 -05:00
...(Array.isArray(prepared.skillsIdentity.commandNotes)
? prepared.skillsIdentity.commandNotes.filter((note): note is string => typeof note === "string")
: []),
...commandNotes,
],
env: prepared.loggedEnv,
prompt: runPrompt,
promptMetrics,
context: ctx.context,
});
}
let cancelActiveTurn: ((reason: string) => Promise<void>) | null = null;
let controller: AbortController | null = null;
let timeout: NodeJS.Timeout | null = null;
let timedOut = false;
const textParts: string[] = [];
try {
const timeoutMs = prepared.timeoutSec > 0 ? prepared.timeoutSec * 1000 : undefined;
controller = new AbortController();
if (timeoutMs) {
timeout = setTimeout(() => {
timedOut = true;
controller?.abort();
void cancelActiveTurn?.(`Timed out after ${prepared.timeoutSec}s`).catch(() => {});
}, timeoutMs);
}
const turn = runtime.startTurn({
handle: sessionHandle,
text: runPrompt,
mode: "prompt",
requestId: ctx.runId,
timeoutMs,
signal: controller?.signal,
});
cancelActiveTurn = async (reason: string) => {
await turn.cancel({ reason });
};
for await (const event of turn.events) {
if (event.type === "text_delta") textParts.push(event.text);
await emitRuntimeEvent(ctx, event);
}
const terminal = await turn.result;
if (timeout) clearTimeout(timeout);
if (terminal.status === "failed" || terminal.status === "cancelled" || timedOut) {
Improve ACPX adapter configuration (#5290) ## Thinking Path > - Paperclip orchestrates AI agents across several adapter implementations. > - ACPX is a local adapter path that can proxy Claude and Codex-style execution. > - Its configuration needed stronger schema defaults, provider-aware model handling, and better UI support. > - Plugin authors also need clear docs for managed resources. > - This pull request improves ACPX adapter configuration and documents plugin-managed resources. > - The benefit is a more predictable adapter setup path without changing unrelated control-plane behavior. ## What Changed - Improved ACPX config schema, execution config handling, UI build config, and route coverage. - Added ACPX model filtering support and tests. - Updated the agent config form and storybook coverage for ACPX model/provider behavior. - Expanded plugin authoring documentation for managed resources. ## Verification - `pnpm install --frozen-lockfile` - `pnpm exec vitest run server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/adapter-routes.test.ts ui/src/lib/acpx-model-filter.test.ts` ## Risks - Low-to-medium risk: adapter configuration behavior changes can affect ACPX users, but the change is isolated to ACPX/plugin-doc surfaces and covered by targeted adapter tests. ## Model Used - OpenAI GPT-5 Codex via Paperclip `codex_local` adapter, with shell/git/GitHub CLI tool use. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-05-06 06:06:47 -05:00
const existing = warmHandles.get(prepared.sessionKey);
if (warmHandleMatches(existing, runtime, sessionHandle) && existing) {
await closeWarmHandle({
handles: warmHandles,
key: prepared.sessionKey,
entry: existing,
reason: timedOut ? "paperclip timeout cleanup" : `paperclip turn ${terminal.status}`,
discardPersistentState: terminal.status === "cancelled" || timedOut,
});
} else {
await runtime.close({
handle: sessionHandle,
reason: timedOut ? "paperclip timeout cleanup" : `paperclip turn ${terminal.status}`,
discardPersistentState: terminal.status === "cancelled" || timedOut,
}).catch(() => {});
Add ACPX local adapter runtime (#4893) ## Thinking Path > - Paperclip orchestrates AI-agent companies through a control plane that can start, supervise, and recover agent runs. > - Local adapters are the bridge between Paperclip issues and concrete agent runtimes such as Claude, Codex, and other ACP-compatible tools. > - The roadmap calls out broader “bring your own agent” and claw-style agent support, and ACPX gives Paperclip one path to normalize multiple ACP agents behind a single adapter. > - The branch needed to become one reviewable PR against current `paperclipai/paperclip:master`, without carrying stale base conflicts or generated lockfile churn. > - This pull request adds an experimental built-in `acpx_local` adapter, integrates it through the server/CLI/UI adapter surfaces, and adds regression coverage for runtime execution, skill sync, stream parsing, diagnostics, and log redaction. > - The benefit is that Paperclip can run Claude/Codex/custom ACP agents through ACPX while keeping operator configuration, skills, logging, and transcript rendering inside the existing adapter model. ## What Changed - Added `@paperclipai/adapter-acpx-local` with server execution, config schema, ACPX session handling, CLI formatting, UI config helpers, and stdout parsing. - Registered `acpx_local` across CLI, server, shared constants, UI adapter metadata, adapter capabilities, and agent creation/editing surfaces. - Added ACPX runtime execution support with persistent sessions, local-agent JWT environment handling, skill snapshots, runtime skill materialization, and isolation/security regressions. - Added ACPX adapter diagnostics and marked the adapter experimental in the UI. - Added command/env secret redaction for resolved command metadata in adapter-utils, server event storage, and the Agent Detail invocation UI. - Added Storybook coverage for ACPX config, transcript rendering, and skill states, plus PR screenshots under `docs/pr-screenshots/pap-2944/`. - Rebased the branch onto current `public-gh/master`; `pnpm-lock.yaml` is intentionally not included and there are no migration/schema changes. ## Verification - `pnpm exec vitest run packages/adapters/acpx-local/src/server/execute.test.ts packages/adapters/acpx-local/src/server/test.test.ts packages/adapters/acpx-local/src/cli/format-event.test.ts packages/adapters/acpx-local/src/ui/parse-stdout.test.ts packages/adapter-utils/src/server-utils.test.ts server/src/__tests__/redaction.test.ts server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/acpx-local-skill-sync.test.ts server/src/__tests__/acpx-local-adapter-environment.test.ts server/src/__tests__/adapter-routes.test.ts server/src/__tests__/agent-skills-routes.test.ts ui/src/adapters/metadata.test.ts` — 12 files, 87 tests passed. - `pnpm --filter @paperclipai/adapter-acpx-local typecheck` — passed. - `pnpm --filter @paperclipai/server typecheck` — passed. - `pnpm --filter @paperclipai/ui typecheck` — passed. - Confirmed PR diff does not include `pnpm-lock.yaml`, database schema files, or migrations. Screenshots: ![ACPX Claude skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-light.png?raw=true) ![ACPX Claude skills dark](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-dark.png?raw=true) ![ACPX custom skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-custom-light.png?raw=true) ## Risks - Medium risk: this introduces a new built-in adapter package and touches runtime execution, adapter registration, agent config, skills, and transcript rendering. - ACPX and ACP agent behavior can vary by installed tool versions; the adapter is marked experimental to set operator expectations. - `pnpm-lock.yaml` is excluded per repository PR policy, so dependency lock refresh must be handled by the repo’s automation or maintainers. - No database migration risk: no schema or migration files changed. > 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 coding agent based on GPT-5, with repository tool use, shell execution, git operations, and local verification. Exact hosted context window was not exposed in this environment. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-30 19:57:05 -05:00
}
Improve ACPX adapter configuration (#5290) ## Thinking Path > - Paperclip orchestrates AI agents across several adapter implementations. > - ACPX is a local adapter path that can proxy Claude and Codex-style execution. > - Its configuration needed stronger schema defaults, provider-aware model handling, and better UI support. > - Plugin authors also need clear docs for managed resources. > - This pull request improves ACPX adapter configuration and documents plugin-managed resources. > - The benefit is a more predictable adapter setup path without changing unrelated control-plane behavior. ## What Changed - Improved ACPX config schema, execution config handling, UI build config, and route coverage. - Added ACPX model filtering support and tests. - Updated the agent config form and storybook coverage for ACPX model/provider behavior. - Expanded plugin authoring documentation for managed resources. ## Verification - `pnpm install --frozen-lockfile` - `pnpm exec vitest run server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/adapter-routes.test.ts ui/src/lib/acpx-model-filter.test.ts` ## Risks - Low-to-medium risk: adapter configuration behavior changes can affect ACPX users, but the change is isolated to ACPX/plugin-doc surfaces and covered by targeted adapter tests. ## Model Used - OpenAI GPT-5 Codex via Paperclip `codex_local` adapter, with shell/git/GitHub CLI tool use. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-05-06 06:06:47 -05:00
} else if (prepared.mode === "persistent" && warmIdleMs > 0) {
Add ACPX local adapter runtime (#4893) ## Thinking Path > - Paperclip orchestrates AI-agent companies through a control plane that can start, supervise, and recover agent runs. > - Local adapters are the bridge between Paperclip issues and concrete agent runtimes such as Claude, Codex, and other ACP-compatible tools. > - The roadmap calls out broader “bring your own agent” and claw-style agent support, and ACPX gives Paperclip one path to normalize multiple ACP agents behind a single adapter. > - The branch needed to become one reviewable PR against current `paperclipai/paperclip:master`, without carrying stale base conflicts or generated lockfile churn. > - This pull request adds an experimental built-in `acpx_local` adapter, integrates it through the server/CLI/UI adapter surfaces, and adds regression coverage for runtime execution, skill sync, stream parsing, diagnostics, and log redaction. > - The benefit is that Paperclip can run Claude/Codex/custom ACP agents through ACPX while keeping operator configuration, skills, logging, and transcript rendering inside the existing adapter model. ## What Changed - Added `@paperclipai/adapter-acpx-local` with server execution, config schema, ACPX session handling, CLI formatting, UI config helpers, and stdout parsing. - Registered `acpx_local` across CLI, server, shared constants, UI adapter metadata, adapter capabilities, and agent creation/editing surfaces. - Added ACPX runtime execution support with persistent sessions, local-agent JWT environment handling, skill snapshots, runtime skill materialization, and isolation/security regressions. - Added ACPX adapter diagnostics and marked the adapter experimental in the UI. - Added command/env secret redaction for resolved command metadata in adapter-utils, server event storage, and the Agent Detail invocation UI. - Added Storybook coverage for ACPX config, transcript rendering, and skill states, plus PR screenshots under `docs/pr-screenshots/pap-2944/`. - Rebased the branch onto current `public-gh/master`; `pnpm-lock.yaml` is intentionally not included and there are no migration/schema changes. ## Verification - `pnpm exec vitest run packages/adapters/acpx-local/src/server/execute.test.ts packages/adapters/acpx-local/src/server/test.test.ts packages/adapters/acpx-local/src/cli/format-event.test.ts packages/adapters/acpx-local/src/ui/parse-stdout.test.ts packages/adapter-utils/src/server-utils.test.ts server/src/__tests__/redaction.test.ts server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/acpx-local-skill-sync.test.ts server/src/__tests__/acpx-local-adapter-environment.test.ts server/src/__tests__/adapter-routes.test.ts server/src/__tests__/agent-skills-routes.test.ts ui/src/adapters/metadata.test.ts` — 12 files, 87 tests passed. - `pnpm --filter @paperclipai/adapter-acpx-local typecheck` — passed. - `pnpm --filter @paperclipai/server typecheck` — passed. - `pnpm --filter @paperclipai/ui typecheck` — passed. - Confirmed PR diff does not include `pnpm-lock.yaml`, database schema files, or migrations. Screenshots: ![ACPX Claude skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-light.png?raw=true) ![ACPX Claude skills dark](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-dark.png?raw=true) ![ACPX custom skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-custom-light.png?raw=true) ## Risks - Medium risk: this introduces a new built-in adapter package and touches runtime execution, adapter registration, agent config, skills, and transcript rendering. - ACPX and ACP agent behavior can vary by installed tool versions; the adapter is marked experimental to set operator expectations. - `pnpm-lock.yaml` is excluded per repository PR policy, so dependency lock refresh must be handled by the repo’s automation or maintainers. - No database migration risk: no schema or migration files changed. > 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 coding agent based on GPT-5, with repository tool use, shell execution, git operations, and local verification. Exact hosted context window was not exposed in this environment. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-30 19:57:05 -05:00
const existing = warmHandles.get(prepared.sessionKey);
if (existing && !warmHandleMatches(existing, runtime, sessionHandle)) {
await runtime.close({
handle: sessionHandle,
reason: "paperclip duplicate warm handle cleanup",
discardPersistentState: false,
}).catch(() => {});
} else {
Improve ACPX adapter configuration (#5290) ## Thinking Path > - Paperclip orchestrates AI agents across several adapter implementations. > - ACPX is a local adapter path that can proxy Claude and Codex-style execution. > - Its configuration needed stronger schema defaults, provider-aware model handling, and better UI support. > - Plugin authors also need clear docs for managed resources. > - This pull request improves ACPX adapter configuration and documents plugin-managed resources. > - The benefit is a more predictable adapter setup path without changing unrelated control-plane behavior. ## What Changed - Improved ACPX config schema, execution config handling, UI build config, and route coverage. - Added ACPX model filtering support and tests. - Updated the agent config form and storybook coverage for ACPX model/provider behavior. - Expanded plugin authoring documentation for managed resources. ## Verification - `pnpm install --frozen-lockfile` - `pnpm exec vitest run server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/adapter-routes.test.ts ui/src/lib/acpx-model-filter.test.ts` ## Risks - Low-to-medium risk: adapter configuration behavior changes can affect ACPX users, but the change is isolated to ACPX/plugin-doc surfaces and covered by targeted adapter tests. ## Model Used - OpenAI GPT-5 Codex via Paperclip `codex_local` adapter, with shell/git/GitHub CLI tool use. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-05-06 06:06:47 -05:00
const entry: RuntimeCacheEntry = {
Add ACPX local adapter runtime (#4893) ## Thinking Path > - Paperclip orchestrates AI-agent companies through a control plane that can start, supervise, and recover agent runs. > - Local adapters are the bridge between Paperclip issues and concrete agent runtimes such as Claude, Codex, and other ACP-compatible tools. > - The roadmap calls out broader “bring your own agent” and claw-style agent support, and ACPX gives Paperclip one path to normalize multiple ACP agents behind a single adapter. > - The branch needed to become one reviewable PR against current `paperclipai/paperclip:master`, without carrying stale base conflicts or generated lockfile churn. > - This pull request adds an experimental built-in `acpx_local` adapter, integrates it through the server/CLI/UI adapter surfaces, and adds regression coverage for runtime execution, skill sync, stream parsing, diagnostics, and log redaction. > - The benefit is that Paperclip can run Claude/Codex/custom ACP agents through ACPX while keeping operator configuration, skills, logging, and transcript rendering inside the existing adapter model. ## What Changed - Added `@paperclipai/adapter-acpx-local` with server execution, config schema, ACPX session handling, CLI formatting, UI config helpers, and stdout parsing. - Registered `acpx_local` across CLI, server, shared constants, UI adapter metadata, adapter capabilities, and agent creation/editing surfaces. - Added ACPX runtime execution support with persistent sessions, local-agent JWT environment handling, skill snapshots, runtime skill materialization, and isolation/security regressions. - Added ACPX adapter diagnostics and marked the adapter experimental in the UI. - Added command/env secret redaction for resolved command metadata in adapter-utils, server event storage, and the Agent Detail invocation UI. - Added Storybook coverage for ACPX config, transcript rendering, and skill states, plus PR screenshots under `docs/pr-screenshots/pap-2944/`. - Rebased the branch onto current `public-gh/master`; `pnpm-lock.yaml` is intentionally not included and there are no migration/schema changes. ## Verification - `pnpm exec vitest run packages/adapters/acpx-local/src/server/execute.test.ts packages/adapters/acpx-local/src/server/test.test.ts packages/adapters/acpx-local/src/cli/format-event.test.ts packages/adapters/acpx-local/src/ui/parse-stdout.test.ts packages/adapter-utils/src/server-utils.test.ts server/src/__tests__/redaction.test.ts server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/acpx-local-skill-sync.test.ts server/src/__tests__/acpx-local-adapter-environment.test.ts server/src/__tests__/adapter-routes.test.ts server/src/__tests__/agent-skills-routes.test.ts ui/src/adapters/metadata.test.ts` — 12 files, 87 tests passed. - `pnpm --filter @paperclipai/adapter-acpx-local typecheck` — passed. - `pnpm --filter @paperclipai/server typecheck` — passed. - `pnpm --filter @paperclipai/ui typecheck` — passed. - Confirmed PR diff does not include `pnpm-lock.yaml`, database schema files, or migrations. Screenshots: ![ACPX Claude skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-light.png?raw=true) ![ACPX Claude skills dark](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-dark.png?raw=true) ![ACPX custom skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-custom-light.png?raw=true) ## Risks - Medium risk: this introduces a new built-in adapter package and touches runtime execution, adapter registration, agent config, skills, and transcript rendering. - ACPX and ACP agent behavior can vary by installed tool versions; the adapter is marked experimental to set operator expectations. - `pnpm-lock.yaml` is excluded per repository PR policy, so dependency lock refresh must be handled by the repo’s automation or maintainers. - No database migration risk: no schema or migration files changed. > 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 coding agent based on GPT-5, with repository tool use, shell execution, git operations, and local verification. Exact hosted context window was not exposed in this environment. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-30 19:57:05 -05:00
runtime,
handle: sessionHandle,
fingerprint: prepared.fingerprint,
lastUsedAt: now(),
Improve ACPX adapter configuration (#5290) ## Thinking Path > - Paperclip orchestrates AI agents across several adapter implementations. > - ACPX is a local adapter path that can proxy Claude and Codex-style execution. > - Its configuration needed stronger schema defaults, provider-aware model handling, and better UI support. > - Plugin authors also need clear docs for managed resources. > - This pull request improves ACPX adapter configuration and documents plugin-managed resources. > - The benefit is a more predictable adapter setup path without changing unrelated control-plane behavior. ## What Changed - Improved ACPX config schema, execution config handling, UI build config, and route coverage. - Added ACPX model filtering support and tests. - Updated the agent config form and storybook coverage for ACPX model/provider behavior. - Expanded plugin authoring documentation for managed resources. ## Verification - `pnpm install --frozen-lockfile` - `pnpm exec vitest run server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/adapter-routes.test.ts ui/src/lib/acpx-model-filter.test.ts` ## Risks - Low-to-medium risk: adapter configuration behavior changes can affect ACPX users, but the change is isolated to ACPX/plugin-doc surfaces and covered by targeted adapter tests. ## Model Used - OpenAI GPT-5 Codex via Paperclip `codex_local` adapter, with shell/git/GitHub CLI tool use. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-05-06 06:06:47 -05:00
};
warmHandles.set(prepared.sessionKey, entry);
scheduleIdleHandleCleanup({
handles: warmHandles,
key: prepared.sessionKey,
entry,
idleMs: warmIdleMs,
now,
Add ACPX local adapter runtime (#4893) ## Thinking Path > - Paperclip orchestrates AI-agent companies through a control plane that can start, supervise, and recover agent runs. > - Local adapters are the bridge between Paperclip issues and concrete agent runtimes such as Claude, Codex, and other ACP-compatible tools. > - The roadmap calls out broader “bring your own agent” and claw-style agent support, and ACPX gives Paperclip one path to normalize multiple ACP agents behind a single adapter. > - The branch needed to become one reviewable PR against current `paperclipai/paperclip:master`, without carrying stale base conflicts or generated lockfile churn. > - This pull request adds an experimental built-in `acpx_local` adapter, integrates it through the server/CLI/UI adapter surfaces, and adds regression coverage for runtime execution, skill sync, stream parsing, diagnostics, and log redaction. > - The benefit is that Paperclip can run Claude/Codex/custom ACP agents through ACPX while keeping operator configuration, skills, logging, and transcript rendering inside the existing adapter model. ## What Changed - Added `@paperclipai/adapter-acpx-local` with server execution, config schema, ACPX session handling, CLI formatting, UI config helpers, and stdout parsing. - Registered `acpx_local` across CLI, server, shared constants, UI adapter metadata, adapter capabilities, and agent creation/editing surfaces. - Added ACPX runtime execution support with persistent sessions, local-agent JWT environment handling, skill snapshots, runtime skill materialization, and isolation/security regressions. - Added ACPX adapter diagnostics and marked the adapter experimental in the UI. - Added command/env secret redaction for resolved command metadata in adapter-utils, server event storage, and the Agent Detail invocation UI. - Added Storybook coverage for ACPX config, transcript rendering, and skill states, plus PR screenshots under `docs/pr-screenshots/pap-2944/`. - Rebased the branch onto current `public-gh/master`; `pnpm-lock.yaml` is intentionally not included and there are no migration/schema changes. ## Verification - `pnpm exec vitest run packages/adapters/acpx-local/src/server/execute.test.ts packages/adapters/acpx-local/src/server/test.test.ts packages/adapters/acpx-local/src/cli/format-event.test.ts packages/adapters/acpx-local/src/ui/parse-stdout.test.ts packages/adapter-utils/src/server-utils.test.ts server/src/__tests__/redaction.test.ts server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/acpx-local-skill-sync.test.ts server/src/__tests__/acpx-local-adapter-environment.test.ts server/src/__tests__/adapter-routes.test.ts server/src/__tests__/agent-skills-routes.test.ts ui/src/adapters/metadata.test.ts` — 12 files, 87 tests passed. - `pnpm --filter @paperclipai/adapter-acpx-local typecheck` — passed. - `pnpm --filter @paperclipai/server typecheck` — passed. - `pnpm --filter @paperclipai/ui typecheck` — passed. - Confirmed PR diff does not include `pnpm-lock.yaml`, database schema files, or migrations. Screenshots: ![ACPX Claude skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-light.png?raw=true) ![ACPX Claude skills dark](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-dark.png?raw=true) ![ACPX custom skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-custom-light.png?raw=true) ## Risks - Medium risk: this introduces a new built-in adapter package and touches runtime execution, adapter registration, agent config, skills, and transcript rendering. - ACPX and ACP agent behavior can vary by installed tool versions; the adapter is marked experimental to set operator expectations. - `pnpm-lock.yaml` is excluded per repository PR policy, so dependency lock refresh must be handled by the repo’s automation or maintainers. - No database migration risk: no schema or migration files changed. > 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 coding agent based on GPT-5, with repository tool use, shell execution, git operations, and local verification. Exact hosted context window was not exposed in this environment. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-30 19:57:05 -05:00
});
}
Improve ACPX adapter configuration (#5290) ## Thinking Path > - Paperclip orchestrates AI agents across several adapter implementations. > - ACPX is a local adapter path that can proxy Claude and Codex-style execution. > - Its configuration needed stronger schema defaults, provider-aware model handling, and better UI support. > - Plugin authors also need clear docs for managed resources. > - This pull request improves ACPX adapter configuration and documents plugin-managed resources. > - The benefit is a more predictable adapter setup path without changing unrelated control-plane behavior. ## What Changed - Improved ACPX config schema, execution config handling, UI build config, and route coverage. - Added ACPX model filtering support and tests. - Updated the agent config form and storybook coverage for ACPX model/provider behavior. - Expanded plugin authoring documentation for managed resources. ## Verification - `pnpm install --frozen-lockfile` - `pnpm exec vitest run server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/adapter-routes.test.ts ui/src/lib/acpx-model-filter.test.ts` ## Risks - Low-to-medium risk: adapter configuration behavior changes can affect ACPX users, but the change is isolated to ACPX/plugin-doc surfaces and covered by targeted adapter tests. ## Model Used - OpenAI GPT-5 Codex via Paperclip `codex_local` adapter, with shell/git/GitHub CLI tool use. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-05-06 06:06:47 -05:00
} else {
const existing = warmHandles.get(prepared.sessionKey);
if (warmHandleMatches(existing, runtime, sessionHandle) && existing) {
await closeWarmHandle({
handles: warmHandles,
key: prepared.sessionKey,
entry: existing,
reason: "paperclip completed turn cleanup",
});
} else {
await runtime.close({
handle: sessionHandle,
reason: "paperclip completed turn cleanup",
discardPersistentState: false,
}).catch(() => {});
}
Add ACPX local adapter runtime (#4893) ## Thinking Path > - Paperclip orchestrates AI-agent companies through a control plane that can start, supervise, and recover agent runs. > - Local adapters are the bridge between Paperclip issues and concrete agent runtimes such as Claude, Codex, and other ACP-compatible tools. > - The roadmap calls out broader “bring your own agent” and claw-style agent support, and ACPX gives Paperclip one path to normalize multiple ACP agents behind a single adapter. > - The branch needed to become one reviewable PR against current `paperclipai/paperclip:master`, without carrying stale base conflicts or generated lockfile churn. > - This pull request adds an experimental built-in `acpx_local` adapter, integrates it through the server/CLI/UI adapter surfaces, and adds regression coverage for runtime execution, skill sync, stream parsing, diagnostics, and log redaction. > - The benefit is that Paperclip can run Claude/Codex/custom ACP agents through ACPX while keeping operator configuration, skills, logging, and transcript rendering inside the existing adapter model. ## What Changed - Added `@paperclipai/adapter-acpx-local` with server execution, config schema, ACPX session handling, CLI formatting, UI config helpers, and stdout parsing. - Registered `acpx_local` across CLI, server, shared constants, UI adapter metadata, adapter capabilities, and agent creation/editing surfaces. - Added ACPX runtime execution support with persistent sessions, local-agent JWT environment handling, skill snapshots, runtime skill materialization, and isolation/security regressions. - Added ACPX adapter diagnostics and marked the adapter experimental in the UI. - Added command/env secret redaction for resolved command metadata in adapter-utils, server event storage, and the Agent Detail invocation UI. - Added Storybook coverage for ACPX config, transcript rendering, and skill states, plus PR screenshots under `docs/pr-screenshots/pap-2944/`. - Rebased the branch onto current `public-gh/master`; `pnpm-lock.yaml` is intentionally not included and there are no migration/schema changes. ## Verification - `pnpm exec vitest run packages/adapters/acpx-local/src/server/execute.test.ts packages/adapters/acpx-local/src/server/test.test.ts packages/adapters/acpx-local/src/cli/format-event.test.ts packages/adapters/acpx-local/src/ui/parse-stdout.test.ts packages/adapter-utils/src/server-utils.test.ts server/src/__tests__/redaction.test.ts server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/acpx-local-skill-sync.test.ts server/src/__tests__/acpx-local-adapter-environment.test.ts server/src/__tests__/adapter-routes.test.ts server/src/__tests__/agent-skills-routes.test.ts ui/src/adapters/metadata.test.ts` — 12 files, 87 tests passed. - `pnpm --filter @paperclipai/adapter-acpx-local typecheck` — passed. - `pnpm --filter @paperclipai/server typecheck` — passed. - `pnpm --filter @paperclipai/ui typecheck` — passed. - Confirmed PR diff does not include `pnpm-lock.yaml`, database schema files, or migrations. Screenshots: ![ACPX Claude skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-light.png?raw=true) ![ACPX Claude skills dark](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-dark.png?raw=true) ![ACPX custom skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-custom-light.png?raw=true) ## Risks - Medium risk: this introduces a new built-in adapter package and touches runtime execution, adapter registration, agent config, skills, and transcript rendering. - ACPX and ACP agent behavior can vary by installed tool versions; the adapter is marked experimental to set operator expectations. - `pnpm-lock.yaml` is excluded per repository PR policy, so dependency lock refresh must be handled by the repo’s automation or maintainers. - No database migration risk: no schema or migration files changed. > 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 coding agent based on GPT-5, with repository tool use, shell execution, git operations, and local verification. Exact hosted context window was not exposed in this environment. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-30 19:57:05 -05:00
}
const errorMessage = timedOut
? `Timed out after ${prepared.timeoutSec}s`
: resultErrorMessage(terminal);
const terminalStopReason = terminal.status === "failed" ? terminal.error.message : terminal.stopReason;
await emitAcpxLog(ctx, {
type: terminal.status === "completed" ? "acpx.result" : "acpx.error",
summary: terminal.status,
stopReason: terminalStopReason,
message: errorMessage,
});
return {
exitCode: terminal.status === "completed" ? 0 : 1,
signal: timedOut ? "SIGTERM" : null,
timedOut,
errorMessage,
errorCode: terminal.status === "failed" ? "acpx_turn_failed" : timedOut ? "acpx_timeout" : null,
sessionId: sessionHandle.backendSessionId ?? sessionHandle.runtimeSessionName,
sessionParams: buildSessionParams({ prepared, handle: sessionHandle }),
sessionDisplayId: sessionHandle.agentSessionId ?? sessionHandle.backendSessionId ?? sessionHandle.runtimeSessionName,
provider: "acpx",
Improve ACPX adapter configuration (#5290) ## Thinking Path > - Paperclip orchestrates AI agents across several adapter implementations. > - ACPX is a local adapter path that can proxy Claude and Codex-style execution. > - Its configuration needed stronger schema defaults, provider-aware model handling, and better UI support. > - Plugin authors also need clear docs for managed resources. > - This pull request improves ACPX adapter configuration and documents plugin-managed resources. > - The benefit is a more predictable adapter setup path without changing unrelated control-plane behavior. ## What Changed - Improved ACPX config schema, execution config handling, UI build config, and route coverage. - Added ACPX model filtering support and tests. - Updated the agent config form and storybook coverage for ACPX model/provider behavior. - Expanded plugin authoring documentation for managed resources. ## Verification - `pnpm install --frozen-lockfile` - `pnpm exec vitest run server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/adapter-routes.test.ts ui/src/lib/acpx-model-filter.test.ts` ## Risks - Low-to-medium risk: adapter configuration behavior changes can affect ACPX users, but the change is isolated to ACPX/plugin-doc surfaces and covered by targeted adapter tests. ## Model Used - OpenAI GPT-5 Codex via Paperclip `codex_local` adapter, with shell/git/GitHub CLI tool use. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-05-06 06:06:47 -05:00
model: prepared.requestedModel || null,
Add ACPX local adapter runtime (#4893) ## Thinking Path > - Paperclip orchestrates AI-agent companies through a control plane that can start, supervise, and recover agent runs. > - Local adapters are the bridge between Paperclip issues and concrete agent runtimes such as Claude, Codex, and other ACP-compatible tools. > - The roadmap calls out broader “bring your own agent” and claw-style agent support, and ACPX gives Paperclip one path to normalize multiple ACP agents behind a single adapter. > - The branch needed to become one reviewable PR against current `paperclipai/paperclip:master`, without carrying stale base conflicts or generated lockfile churn. > - This pull request adds an experimental built-in `acpx_local` adapter, integrates it through the server/CLI/UI adapter surfaces, and adds regression coverage for runtime execution, skill sync, stream parsing, diagnostics, and log redaction. > - The benefit is that Paperclip can run Claude/Codex/custom ACP agents through ACPX while keeping operator configuration, skills, logging, and transcript rendering inside the existing adapter model. ## What Changed - Added `@paperclipai/adapter-acpx-local` with server execution, config schema, ACPX session handling, CLI formatting, UI config helpers, and stdout parsing. - Registered `acpx_local` across CLI, server, shared constants, UI adapter metadata, adapter capabilities, and agent creation/editing surfaces. - Added ACPX runtime execution support with persistent sessions, local-agent JWT environment handling, skill snapshots, runtime skill materialization, and isolation/security regressions. - Added ACPX adapter diagnostics and marked the adapter experimental in the UI. - Added command/env secret redaction for resolved command metadata in adapter-utils, server event storage, and the Agent Detail invocation UI. - Added Storybook coverage for ACPX config, transcript rendering, and skill states, plus PR screenshots under `docs/pr-screenshots/pap-2944/`. - Rebased the branch onto current `public-gh/master`; `pnpm-lock.yaml` is intentionally not included and there are no migration/schema changes. ## Verification - `pnpm exec vitest run packages/adapters/acpx-local/src/server/execute.test.ts packages/adapters/acpx-local/src/server/test.test.ts packages/adapters/acpx-local/src/cli/format-event.test.ts packages/adapters/acpx-local/src/ui/parse-stdout.test.ts packages/adapter-utils/src/server-utils.test.ts server/src/__tests__/redaction.test.ts server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/acpx-local-skill-sync.test.ts server/src/__tests__/acpx-local-adapter-environment.test.ts server/src/__tests__/adapter-routes.test.ts server/src/__tests__/agent-skills-routes.test.ts ui/src/adapters/metadata.test.ts` — 12 files, 87 tests passed. - `pnpm --filter @paperclipai/adapter-acpx-local typecheck` — passed. - `pnpm --filter @paperclipai/server typecheck` — passed. - `pnpm --filter @paperclipai/ui typecheck` — passed. - Confirmed PR diff does not include `pnpm-lock.yaml`, database schema files, or migrations. Screenshots: ![ACPX Claude skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-light.png?raw=true) ![ACPX Claude skills dark](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-dark.png?raw=true) ![ACPX custom skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-custom-light.png?raw=true) ## Risks - Medium risk: this introduces a new built-in adapter package and touches runtime execution, adapter registration, agent config, skills, and transcript rendering. - ACPX and ACP agent behavior can vary by installed tool versions; the adapter is marked experimental to set operator expectations. - `pnpm-lock.yaml` is excluded per repository PR policy, so dependency lock refresh must be handled by the repo’s automation or maintainers. - No database migration risk: no schema or migration files changed. > 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 coding agent based on GPT-5, with repository tool use, shell execution, git operations, and local verification. Exact hosted context window was not exposed in this environment. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-30 19:57:05 -05:00
billingType: "unknown",
costUsd: null,
resultJson: {
status: terminal.status,
stopReason: terminalStopReason,
permissionMode: prepared.permissionMode,
mode: prepared.mode,
Improve ACPX adapter configuration (#5290) ## Thinking Path > - Paperclip orchestrates AI agents across several adapter implementations. > - ACPX is a local adapter path that can proxy Claude and Codex-style execution. > - Its configuration needed stronger schema defaults, provider-aware model handling, and better UI support. > - Plugin authors also need clear docs for managed resources. > - This pull request improves ACPX adapter configuration and documents plugin-managed resources. > - The benefit is a more predictable adapter setup path without changing unrelated control-plane behavior. ## What Changed - Improved ACPX config schema, execution config handling, UI build config, and route coverage. - Added ACPX model filtering support and tests. - Updated the agent config form and storybook coverage for ACPX model/provider behavior. - Expanded plugin authoring documentation for managed resources. ## Verification - `pnpm install --frozen-lockfile` - `pnpm exec vitest run server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/adapter-routes.test.ts ui/src/lib/acpx-model-filter.test.ts` ## Risks - Low-to-medium risk: adapter configuration behavior changes can affect ACPX users, but the change is isolated to ACPX/plugin-doc surfaces and covered by targeted adapter tests. ## Model Used - OpenAI GPT-5 Codex via Paperclip `codex_local` adapter, with shell/git/GitHub CLI tool use. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-05-06 06:06:47 -05:00
requestedModel: prepared.requestedModel || null,
requestedThinkingEffort: prepared.requestedThinkingEffort || null,
fastMode: prepared.fastMode,
Add ACPX local adapter runtime (#4893) ## Thinking Path > - Paperclip orchestrates AI-agent companies through a control plane that can start, supervise, and recover agent runs. > - Local adapters are the bridge between Paperclip issues and concrete agent runtimes such as Claude, Codex, and other ACP-compatible tools. > - The roadmap calls out broader “bring your own agent” and claw-style agent support, and ACPX gives Paperclip one path to normalize multiple ACP agents behind a single adapter. > - The branch needed to become one reviewable PR against current `paperclipai/paperclip:master`, without carrying stale base conflicts or generated lockfile churn. > - This pull request adds an experimental built-in `acpx_local` adapter, integrates it through the server/CLI/UI adapter surfaces, and adds regression coverage for runtime execution, skill sync, stream parsing, diagnostics, and log redaction. > - The benefit is that Paperclip can run Claude/Codex/custom ACP agents through ACPX while keeping operator configuration, skills, logging, and transcript rendering inside the existing adapter model. ## What Changed - Added `@paperclipai/adapter-acpx-local` with server execution, config schema, ACPX session handling, CLI formatting, UI config helpers, and stdout parsing. - Registered `acpx_local` across CLI, server, shared constants, UI adapter metadata, adapter capabilities, and agent creation/editing surfaces. - Added ACPX runtime execution support with persistent sessions, local-agent JWT environment handling, skill snapshots, runtime skill materialization, and isolation/security regressions. - Added ACPX adapter diagnostics and marked the adapter experimental in the UI. - Added command/env secret redaction for resolved command metadata in adapter-utils, server event storage, and the Agent Detail invocation UI. - Added Storybook coverage for ACPX config, transcript rendering, and skill states, plus PR screenshots under `docs/pr-screenshots/pap-2944/`. - Rebased the branch onto current `public-gh/master`; `pnpm-lock.yaml` is intentionally not included and there are no migration/schema changes. ## Verification - `pnpm exec vitest run packages/adapters/acpx-local/src/server/execute.test.ts packages/adapters/acpx-local/src/server/test.test.ts packages/adapters/acpx-local/src/cli/format-event.test.ts packages/adapters/acpx-local/src/ui/parse-stdout.test.ts packages/adapter-utils/src/server-utils.test.ts server/src/__tests__/redaction.test.ts server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/acpx-local-skill-sync.test.ts server/src/__tests__/acpx-local-adapter-environment.test.ts server/src/__tests__/adapter-routes.test.ts server/src/__tests__/agent-skills-routes.test.ts ui/src/adapters/metadata.test.ts` — 12 files, 87 tests passed. - `pnpm --filter @paperclipai/adapter-acpx-local typecheck` — passed. - `pnpm --filter @paperclipai/server typecheck` — passed. - `pnpm --filter @paperclipai/ui typecheck` — passed. - Confirmed PR diff does not include `pnpm-lock.yaml`, database schema files, or migrations. Screenshots: ![ACPX Claude skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-light.png?raw=true) ![ACPX Claude skills dark](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-dark.png?raw=true) ![ACPX custom skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-custom-light.png?raw=true) ## Risks - Medium risk: this introduces a new built-in adapter package and touches runtime execution, adapter registration, agent config, skills, and transcript rendering. - ACPX and ACP agent behavior can vary by installed tool versions; the adapter is marked experimental to set operator expectations. - `pnpm-lock.yaml` is excluded per repository PR policy, so dependency lock refresh must be handled by the repo’s automation or maintainers. - No database migration risk: no schema or migration files changed. > 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 coding agent based on GPT-5, with repository tool use, shell execution, git operations, and local verification. Exact hosted context window was not exposed in this environment. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-30 19:57:05 -05:00
},
summary: textParts.join("").trim() || terminalStopReason || terminal.status,
clearSession,
};
} catch (err) {
if (timeout) clearTimeout(timeout);
Make ACPX-Claude adapter work seamlessly (PAPA-388) (#6590) ## Thinking Path > - Paperclip orchestrates AI agents for zero-human companies, so when an adapter fails, the platform must surface enough detail for the next agent (or human reviewer) to act > - The `acpx_local` adapter wraps `claude-agent-acp`, which in turn drives the Claude Code SDK — three layers, three different permission and error-handling models > - A user created a `Claude Local ACPX` agent in PAPA-387 and it failed instantly with the generic `acpx.error / "Internal error"` log, stranding the work and triggering an opaque `stranded_assigned_issue` recovery to the CTO > - Once the diagnostic blackbox was opened, the underlying cause turned out to be two SDK-level mismatches: a model-name allowlist that rejects bare IDs like `claude-opus-4-7`, and a Claude Code permission/Read-sandbox configuration that silently denies every non-allowlisted tool when the user's `~/.claude/settings.json` has `defaultMode: "dontAsk"` > - This pull request fixes both classes of failure in the adapter itself so new ACPX agents work seamlessly without per-host configuration, and widens the diagnostic surface so the *next* failure of any kind is actionable > - The benefit is that ACPX-Claude can join the regular agent roster — verified end to end on PAPA-401, where the agent successfully reached the Paperclip API, opened a worktree, surveyed existing notification PRs, and posted a structured plan ## What Changed - Widen ACPX failure diagnostics (`packages/adapters/acpx-local/src/server/execute.ts`): - Capture `err.name`, ACP code, `cause.message`, retryable flag, and a 5-frame stack preview into `errorMeta`. - Promote phase-specific error codes: `ensure_session → acpx_session_init_failed`, `configure_session → acpx_session_config_failed`, `turn → acpx_turn_failed`, plus mapping for `ACP_BACKEND_MISSING` / `ACP_BACKEND_UNAVAILABLE`. - Set `verbose: true` on the ACPX runtime so its session-event log flows through `ctx.onLog`. - Capture child-process stderr via a wrapper-script tee into `<stateDir>/run-stderr/<runId>.log`, inline the tail into the `acpx.error` payload as `childStderrTail`, and forward it through `ctx.onLog("stderr", …)` so it lands in the heartbeat `stderrExcerpt` column (existing redaction applies). - Set the model via `ANTHROPIC_MODEL` env for the `claude` agent instead of `set_config_option(model, …)`. The ACP server's `set_config_option` handler validates against an internal allowlist and rejects bare IDs like `claude-opus-4-7`. `ANTHROPIC_MODEL` is read during initialization and bypasses that check. - Seed `<worktree>/.claude/settings.local.json` before spawning `claude-agent-acp` (the seamless-API fix). Since `claude-agent-acp` hard-codes `settingSources: ["user", "project", "local"]` and "local" has the highest precedence: - Set `permissions.defaultMode: "default"`, but **only** if the user's value is missing or `"dontAsk"` (the broken case). Other modes like `acceptEdits`/`plan` are preserved. - Pre-allow Paperclip's Bash surface (`Bash(curl:*)`, `Bash(env:*)`, `Bash(<cwd>/scripts/paperclip-issue-update.sh:*)`, `Bash(<cwd>/scripts/paperclip:*)`). - Widen `permissions.additionalDirectories` to include `stateDir`, `agentHome`, and the per-company instance root (`~/.paperclip/instances/<id>/companies/<companyId>`). Scoped to this company only — does not expose other tenants. - Existing user entries are merged, not replaced. The resolved roots are folded into the session fingerprint so warm-session handles invalidate when they change. - Sync the existing server-side integration test (`server/src/__tests__/acpx-local-execute.test.ts`) to assert `acpx_session_init_failed` instead of the now-removed `acpx_protocol_error` for `ACP_SESSION_INIT_FAILED` (a follow-up to commit 1). ## Verification - `pnpm --filter "@paperclipai/adapter-acpx-local" run typecheck` — passes. - `pnpm vitest run` in `packages/adapters/acpx-local` — 35/35 pass, includes 4 new tests covering the settings.local.json write path (claude only, merge with pre-existing content, `dontAsk` override, codex no-op). - `pnpm vitest run src/__tests__/acpx-local-execute.test.ts` in `server/` — 15/15 pass after the test-sync commit. - End-to-end manual verification (PAPA-401): the `Claude Local ACPX` agent that previously hit "restricted environment" now successfully reaches the Paperclip API, opens its worktree, posts structured plan comments, and flips the issue to `in_review` without any external configuration. ## Risks - **Low**, scoped to the `acpx_local` adapter. The settings.local.json write is per-worktree (worktrees live under `.paperclip/worktrees/<issue>/`) and only triggers when `acpxAgent === "claude"`. Existing user content is merged with `[...existing, ...paperclip]` and deduped — nothing is overwritten outright. - The `defaultMode` override is intentionally narrow: it only flips `"dontAsk"` (which silently denies every tool and is the root cause) to `"default"`. Users who explicitly picked `acceptEdits`, `plan`, or any other mode keep their choice. - Stderr capture goes through the existing `log-redaction` pass before persisting, so `PAPERCLIP_API_KEY` and similar secrets in the wrapper env don't leak into heartbeat logs. > 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 4.7 (`claude-opus-4-7`), running in the `claude_local` adapter via Paperclip's harness. Extended thinking enabled, tool use enabled. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [ ] If this change affects the UI, I have included before/after screenshots — N/A (adapter-only) - [ ] I have updated relevant documentation to reflect my changes — no user-facing docs changed; internal commentary in the code change explains the SDK constraints - [x] I have considered and documented any risks above - [ ] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-05-23 13:01:27 -07:00
const messageOverride = timedOut ? `Timed out after ${prepared.timeoutSec}s` : undefined;
Add ACPX local adapter runtime (#4893) ## Thinking Path > - Paperclip orchestrates AI-agent companies through a control plane that can start, supervise, and recover agent runs. > - Local adapters are the bridge between Paperclip issues and concrete agent runtimes such as Claude, Codex, and other ACP-compatible tools. > - The roadmap calls out broader “bring your own agent” and claw-style agent support, and ACPX gives Paperclip one path to normalize multiple ACP agents behind a single adapter. > - The branch needed to become one reviewable PR against current `paperclipai/paperclip:master`, without carrying stale base conflicts or generated lockfile churn. > - This pull request adds an experimental built-in `acpx_local` adapter, integrates it through the server/CLI/UI adapter surfaces, and adds regression coverage for runtime execution, skill sync, stream parsing, diagnostics, and log redaction. > - The benefit is that Paperclip can run Claude/Codex/custom ACP agents through ACPX while keeping operator configuration, skills, logging, and transcript rendering inside the existing adapter model. ## What Changed - Added `@paperclipai/adapter-acpx-local` with server execution, config schema, ACPX session handling, CLI formatting, UI config helpers, and stdout parsing. - Registered `acpx_local` across CLI, server, shared constants, UI adapter metadata, adapter capabilities, and agent creation/editing surfaces. - Added ACPX runtime execution support with persistent sessions, local-agent JWT environment handling, skill snapshots, runtime skill materialization, and isolation/security regressions. - Added ACPX adapter diagnostics and marked the adapter experimental in the UI. - Added command/env secret redaction for resolved command metadata in adapter-utils, server event storage, and the Agent Detail invocation UI. - Added Storybook coverage for ACPX config, transcript rendering, and skill states, plus PR screenshots under `docs/pr-screenshots/pap-2944/`. - Rebased the branch onto current `public-gh/master`; `pnpm-lock.yaml` is intentionally not included and there are no migration/schema changes. ## Verification - `pnpm exec vitest run packages/adapters/acpx-local/src/server/execute.test.ts packages/adapters/acpx-local/src/server/test.test.ts packages/adapters/acpx-local/src/cli/format-event.test.ts packages/adapters/acpx-local/src/ui/parse-stdout.test.ts packages/adapter-utils/src/server-utils.test.ts server/src/__tests__/redaction.test.ts server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/acpx-local-skill-sync.test.ts server/src/__tests__/acpx-local-adapter-environment.test.ts server/src/__tests__/adapter-routes.test.ts server/src/__tests__/agent-skills-routes.test.ts ui/src/adapters/metadata.test.ts` — 12 files, 87 tests passed. - `pnpm --filter @paperclipai/adapter-acpx-local typecheck` — passed. - `pnpm --filter @paperclipai/server typecheck` — passed. - `pnpm --filter @paperclipai/ui typecheck` — passed. - Confirmed PR diff does not include `pnpm-lock.yaml`, database schema files, or migrations. Screenshots: ![ACPX Claude skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-light.png?raw=true) ![ACPX Claude skills dark](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-dark.png?raw=true) ![ACPX custom skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-custom-light.png?raw=true) ## Risks - Medium risk: this introduces a new built-in adapter package and touches runtime execution, adapter registration, agent config, skills, and transcript rendering. - ACPX and ACP agent behavior can vary by installed tool versions; the adapter is marked experimental to set operator expectations. - `pnpm-lock.yaml` is excluded per repository PR policy, so dependency lock refresh must be handled by the repo’s automation or maintainers. - No database migration risk: no schema or migration files changed. > 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 coding agent based on GPT-5, with repository tool use, shell execution, git operations, and local verification. Exact hosted context window was not exposed in this environment. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-30 19:57:05 -05:00
const cancel = cancelActiveTurn as ((reason: string) => Promise<void>) | null;
Make ACPX-Claude adapter work seamlessly (PAPA-388) (#6590) ## Thinking Path > - Paperclip orchestrates AI agents for zero-human companies, so when an adapter fails, the platform must surface enough detail for the next agent (or human reviewer) to act > - The `acpx_local` adapter wraps `claude-agent-acp`, which in turn drives the Claude Code SDK — three layers, three different permission and error-handling models > - A user created a `Claude Local ACPX` agent in PAPA-387 and it failed instantly with the generic `acpx.error / "Internal error"` log, stranding the work and triggering an opaque `stranded_assigned_issue` recovery to the CTO > - Once the diagnostic blackbox was opened, the underlying cause turned out to be two SDK-level mismatches: a model-name allowlist that rejects bare IDs like `claude-opus-4-7`, and a Claude Code permission/Read-sandbox configuration that silently denies every non-allowlisted tool when the user's `~/.claude/settings.json` has `defaultMode: "dontAsk"` > - This pull request fixes both classes of failure in the adapter itself so new ACPX agents work seamlessly without per-host configuration, and widens the diagnostic surface so the *next* failure of any kind is actionable > - The benefit is that ACPX-Claude can join the regular agent roster — verified end to end on PAPA-401, where the agent successfully reached the Paperclip API, opened a worktree, surveyed existing notification PRs, and posted a structured plan ## What Changed - Widen ACPX failure diagnostics (`packages/adapters/acpx-local/src/server/execute.ts`): - Capture `err.name`, ACP code, `cause.message`, retryable flag, and a 5-frame stack preview into `errorMeta`. - Promote phase-specific error codes: `ensure_session → acpx_session_init_failed`, `configure_session → acpx_session_config_failed`, `turn → acpx_turn_failed`, plus mapping for `ACP_BACKEND_MISSING` / `ACP_BACKEND_UNAVAILABLE`. - Set `verbose: true` on the ACPX runtime so its session-event log flows through `ctx.onLog`. - Capture child-process stderr via a wrapper-script tee into `<stateDir>/run-stderr/<runId>.log`, inline the tail into the `acpx.error` payload as `childStderrTail`, and forward it through `ctx.onLog("stderr", …)` so it lands in the heartbeat `stderrExcerpt` column (existing redaction applies). - Set the model via `ANTHROPIC_MODEL` env for the `claude` agent instead of `set_config_option(model, …)`. The ACP server's `set_config_option` handler validates against an internal allowlist and rejects bare IDs like `claude-opus-4-7`. `ANTHROPIC_MODEL` is read during initialization and bypasses that check. - Seed `<worktree>/.claude/settings.local.json` before spawning `claude-agent-acp` (the seamless-API fix). Since `claude-agent-acp` hard-codes `settingSources: ["user", "project", "local"]` and "local" has the highest precedence: - Set `permissions.defaultMode: "default"`, but **only** if the user's value is missing or `"dontAsk"` (the broken case). Other modes like `acceptEdits`/`plan` are preserved. - Pre-allow Paperclip's Bash surface (`Bash(curl:*)`, `Bash(env:*)`, `Bash(<cwd>/scripts/paperclip-issue-update.sh:*)`, `Bash(<cwd>/scripts/paperclip:*)`). - Widen `permissions.additionalDirectories` to include `stateDir`, `agentHome`, and the per-company instance root (`~/.paperclip/instances/<id>/companies/<companyId>`). Scoped to this company only — does not expose other tenants. - Existing user entries are merged, not replaced. The resolved roots are folded into the session fingerprint so warm-session handles invalidate when they change. - Sync the existing server-side integration test (`server/src/__tests__/acpx-local-execute.test.ts`) to assert `acpx_session_init_failed` instead of the now-removed `acpx_protocol_error` for `ACP_SESSION_INIT_FAILED` (a follow-up to commit 1). ## Verification - `pnpm --filter "@paperclipai/adapter-acpx-local" run typecheck` — passes. - `pnpm vitest run` in `packages/adapters/acpx-local` — 35/35 pass, includes 4 new tests covering the settings.local.json write path (claude only, merge with pre-existing content, `dontAsk` override, codex no-op). - `pnpm vitest run src/__tests__/acpx-local-execute.test.ts` in `server/` — 15/15 pass after the test-sync commit. - End-to-end manual verification (PAPA-401): the `Claude Local ACPX` agent that previously hit "restricted environment" now successfully reaches the Paperclip API, opens its worktree, posts structured plan comments, and flips the issue to `in_review` without any external configuration. ## Risks - **Low**, scoped to the `acpx_local` adapter. The settings.local.json write is per-worktree (worktrees live under `.paperclip/worktrees/<issue>/`) and only triggers when `acpxAgent === "claude"`. Existing user content is merged with `[...existing, ...paperclip]` and deduped — nothing is overwritten outright. - The `defaultMode` override is intentionally narrow: it only flips `"dontAsk"` (which silently denies every tool and is the root cause) to `"default"`. Users who explicitly picked `acceptEdits`, `plan`, or any other mode keep their choice. - Stderr capture goes through the existing `log-redaction` pass before persisting, so `PAPERCLIP_API_KEY` and similar secrets in the wrapper env don't leak into heartbeat logs. > 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 4.7 (`claude-opus-4-7`), running in the `claude_local` adapter via Paperclip's harness. Extended thinking enabled, tool use enabled. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [ ] If this change affects the UI, I have included before/after screenshots — N/A (adapter-only) - [ ] I have updated relevant documentation to reflect my changes — no user-facing docs changed; internal commentary in the code change explains the SDK constraints - [x] I have considered and documented any risks above - [ ] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-05-23 13:01:27 -07:00
const preEmitMessage =
messageOverride ?? (err instanceof Error ? err.message : String(err));
if (cancel) await cancel(preEmitMessage).catch(() => {});
Add ACPX local adapter runtime (#4893) ## Thinking Path > - Paperclip orchestrates AI-agent companies through a control plane that can start, supervise, and recover agent runs. > - Local adapters are the bridge between Paperclip issues and concrete agent runtimes such as Claude, Codex, and other ACP-compatible tools. > - The roadmap calls out broader “bring your own agent” and claw-style agent support, and ACPX gives Paperclip one path to normalize multiple ACP agents behind a single adapter. > - The branch needed to become one reviewable PR against current `paperclipai/paperclip:master`, without carrying stale base conflicts or generated lockfile churn. > - This pull request adds an experimental built-in `acpx_local` adapter, integrates it through the server/CLI/UI adapter surfaces, and adds regression coverage for runtime execution, skill sync, stream parsing, diagnostics, and log redaction. > - The benefit is that Paperclip can run Claude/Codex/custom ACP agents through ACPX while keeping operator configuration, skills, logging, and transcript rendering inside the existing adapter model. ## What Changed - Added `@paperclipai/adapter-acpx-local` with server execution, config schema, ACPX session handling, CLI formatting, UI config helpers, and stdout parsing. - Registered `acpx_local` across CLI, server, shared constants, UI adapter metadata, adapter capabilities, and agent creation/editing surfaces. - Added ACPX runtime execution support with persistent sessions, local-agent JWT environment handling, skill snapshots, runtime skill materialization, and isolation/security regressions. - Added ACPX adapter diagnostics and marked the adapter experimental in the UI. - Added command/env secret redaction for resolved command metadata in adapter-utils, server event storage, and the Agent Detail invocation UI. - Added Storybook coverage for ACPX config, transcript rendering, and skill states, plus PR screenshots under `docs/pr-screenshots/pap-2944/`. - Rebased the branch onto current `public-gh/master`; `pnpm-lock.yaml` is intentionally not included and there are no migration/schema changes. ## Verification - `pnpm exec vitest run packages/adapters/acpx-local/src/server/execute.test.ts packages/adapters/acpx-local/src/server/test.test.ts packages/adapters/acpx-local/src/cli/format-event.test.ts packages/adapters/acpx-local/src/ui/parse-stdout.test.ts packages/adapter-utils/src/server-utils.test.ts server/src/__tests__/redaction.test.ts server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/acpx-local-skill-sync.test.ts server/src/__tests__/acpx-local-adapter-environment.test.ts server/src/__tests__/adapter-routes.test.ts server/src/__tests__/agent-skills-routes.test.ts ui/src/adapters/metadata.test.ts` — 12 files, 87 tests passed. - `pnpm --filter @paperclipai/adapter-acpx-local typecheck` — passed. - `pnpm --filter @paperclipai/server typecheck` — passed. - `pnpm --filter @paperclipai/ui typecheck` — passed. - Confirmed PR diff does not include `pnpm-lock.yaml`, database schema files, or migrations. Screenshots: ![ACPX Claude skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-light.png?raw=true) ![ACPX Claude skills dark](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-dark.png?raw=true) ![ACPX custom skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-custom-light.png?raw=true) ## Risks - Medium risk: this introduces a new built-in adapter package and touches runtime execution, adapter registration, agent config, skills, and transcript rendering. - ACPX and ACP agent behavior can vary by installed tool versions; the adapter is marked experimental to set operator expectations. - `pnpm-lock.yaml` is excluded per repository PR policy, so dependency lock refresh must be handled by the repo’s automation or maintainers. - No database migration risk: no schema or migration files changed. > 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 coding agent based on GPT-5, with repository tool use, shell execution, git operations, and local verification. Exact hosted context window was not exposed in this environment. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-30 19:57:05 -05:00
await runtime.close({
handle: sessionHandle,
reason: timedOut ? "paperclip timeout cleanup" : "paperclip error cleanup",
discardPersistentState: timedOut,
}).catch(() => {});
Improve ACPX adapter configuration (#5290) ## Thinking Path > - Paperclip orchestrates AI agents across several adapter implementations. > - ACPX is a local adapter path that can proxy Claude and Codex-style execution. > - Its configuration needed stronger schema defaults, provider-aware model handling, and better UI support. > - Plugin authors also need clear docs for managed resources. > - This pull request improves ACPX adapter configuration and documents plugin-managed resources. > - The benefit is a more predictable adapter setup path without changing unrelated control-plane behavior. ## What Changed - Improved ACPX config schema, execution config handling, UI build config, and route coverage. - Added ACPX model filtering support and tests. - Updated the agent config form and storybook coverage for ACPX model/provider behavior. - Expanded plugin authoring documentation for managed resources. ## Verification - `pnpm install --frozen-lockfile` - `pnpm exec vitest run server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/adapter-routes.test.ts ui/src/lib/acpx-model-filter.test.ts` ## Risks - Low-to-medium risk: adapter configuration behavior changes can affect ACPX users, but the change is isolated to ACPX/plugin-doc surfaces and covered by targeted adapter tests. ## Model Used - OpenAI GPT-5 Codex via Paperclip `codex_local` adapter, with shell/git/GitHub CLI tool use. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-05-06 06:06:47 -05:00
const existing = warmHandles.get(prepared.sessionKey);
if (warmHandleMatches(existing, runtime, sessionHandle) && existing) {
clearWarmHandleTimer(existing);
Add ACPX local adapter runtime (#4893) ## Thinking Path > - Paperclip orchestrates AI-agent companies through a control plane that can start, supervise, and recover agent runs. > - Local adapters are the bridge between Paperclip issues and concrete agent runtimes such as Claude, Codex, and other ACP-compatible tools. > - The roadmap calls out broader “bring your own agent” and claw-style agent support, and ACPX gives Paperclip one path to normalize multiple ACP agents behind a single adapter. > - The branch needed to become one reviewable PR against current `paperclipai/paperclip:master`, without carrying stale base conflicts or generated lockfile churn. > - This pull request adds an experimental built-in `acpx_local` adapter, integrates it through the server/CLI/UI adapter surfaces, and adds regression coverage for runtime execution, skill sync, stream parsing, diagnostics, and log redaction. > - The benefit is that Paperclip can run Claude/Codex/custom ACP agents through ACPX while keeping operator configuration, skills, logging, and transcript rendering inside the existing adapter model. ## What Changed - Added `@paperclipai/adapter-acpx-local` with server execution, config schema, ACPX session handling, CLI formatting, UI config helpers, and stdout parsing. - Registered `acpx_local` across CLI, server, shared constants, UI adapter metadata, adapter capabilities, and agent creation/editing surfaces. - Added ACPX runtime execution support with persistent sessions, local-agent JWT environment handling, skill snapshots, runtime skill materialization, and isolation/security regressions. - Added ACPX adapter diagnostics and marked the adapter experimental in the UI. - Added command/env secret redaction for resolved command metadata in adapter-utils, server event storage, and the Agent Detail invocation UI. - Added Storybook coverage for ACPX config, transcript rendering, and skill states, plus PR screenshots under `docs/pr-screenshots/pap-2944/`. - Rebased the branch onto current `public-gh/master`; `pnpm-lock.yaml` is intentionally not included and there are no migration/schema changes. ## Verification - `pnpm exec vitest run packages/adapters/acpx-local/src/server/execute.test.ts packages/adapters/acpx-local/src/server/test.test.ts packages/adapters/acpx-local/src/cli/format-event.test.ts packages/adapters/acpx-local/src/ui/parse-stdout.test.ts packages/adapter-utils/src/server-utils.test.ts server/src/__tests__/redaction.test.ts server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/acpx-local-skill-sync.test.ts server/src/__tests__/acpx-local-adapter-environment.test.ts server/src/__tests__/adapter-routes.test.ts server/src/__tests__/agent-skills-routes.test.ts ui/src/adapters/metadata.test.ts` — 12 files, 87 tests passed. - `pnpm --filter @paperclipai/adapter-acpx-local typecheck` — passed. - `pnpm --filter @paperclipai/server typecheck` — passed. - `pnpm --filter @paperclipai/ui typecheck` — passed. - Confirmed PR diff does not include `pnpm-lock.yaml`, database schema files, or migrations. Screenshots: ![ACPX Claude skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-light.png?raw=true) ![ACPX Claude skills dark](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-dark.png?raw=true) ![ACPX custom skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-custom-light.png?raw=true) ## Risks - Medium risk: this introduces a new built-in adapter package and touches runtime execution, adapter registration, agent config, skills, and transcript rendering. - ACPX and ACP agent behavior can vary by installed tool versions; the adapter is marked experimental to set operator expectations. - `pnpm-lock.yaml` is excluded per repository PR policy, so dependency lock refresh must be handled by the repo’s automation or maintainers. - No database migration risk: no schema or migration files changed. > 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 coding agent based on GPT-5, with repository tool use, shell execution, git operations, and local verification. Exact hosted context window was not exposed in this environment. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-30 19:57:05 -05:00
warmHandles.delete(prepared.sessionKey);
}
Make ACPX-Claude adapter work seamlessly (PAPA-388) (#6590) ## Thinking Path > - Paperclip orchestrates AI agents for zero-human companies, so when an adapter fails, the platform must surface enough detail for the next agent (or human reviewer) to act > - The `acpx_local` adapter wraps `claude-agent-acp`, which in turn drives the Claude Code SDK — three layers, three different permission and error-handling models > - A user created a `Claude Local ACPX` agent in PAPA-387 and it failed instantly with the generic `acpx.error / "Internal error"` log, stranding the work and triggering an opaque `stranded_assigned_issue` recovery to the CTO > - Once the diagnostic blackbox was opened, the underlying cause turned out to be two SDK-level mismatches: a model-name allowlist that rejects bare IDs like `claude-opus-4-7`, and a Claude Code permission/Read-sandbox configuration that silently denies every non-allowlisted tool when the user's `~/.claude/settings.json` has `defaultMode: "dontAsk"` > - This pull request fixes both classes of failure in the adapter itself so new ACPX agents work seamlessly without per-host configuration, and widens the diagnostic surface so the *next* failure of any kind is actionable > - The benefit is that ACPX-Claude can join the regular agent roster — verified end to end on PAPA-401, where the agent successfully reached the Paperclip API, opened a worktree, surveyed existing notification PRs, and posted a structured plan ## What Changed - Widen ACPX failure diagnostics (`packages/adapters/acpx-local/src/server/execute.ts`): - Capture `err.name`, ACP code, `cause.message`, retryable flag, and a 5-frame stack preview into `errorMeta`. - Promote phase-specific error codes: `ensure_session → acpx_session_init_failed`, `configure_session → acpx_session_config_failed`, `turn → acpx_turn_failed`, plus mapping for `ACP_BACKEND_MISSING` / `ACP_BACKEND_UNAVAILABLE`. - Set `verbose: true` on the ACPX runtime so its session-event log flows through `ctx.onLog`. - Capture child-process stderr via a wrapper-script tee into `<stateDir>/run-stderr/<runId>.log`, inline the tail into the `acpx.error` payload as `childStderrTail`, and forward it through `ctx.onLog("stderr", …)` so it lands in the heartbeat `stderrExcerpt` column (existing redaction applies). - Set the model via `ANTHROPIC_MODEL` env for the `claude` agent instead of `set_config_option(model, …)`. The ACP server's `set_config_option` handler validates against an internal allowlist and rejects bare IDs like `claude-opus-4-7`. `ANTHROPIC_MODEL` is read during initialization and bypasses that check. - Seed `<worktree>/.claude/settings.local.json` before spawning `claude-agent-acp` (the seamless-API fix). Since `claude-agent-acp` hard-codes `settingSources: ["user", "project", "local"]` and "local" has the highest precedence: - Set `permissions.defaultMode: "default"`, but **only** if the user's value is missing or `"dontAsk"` (the broken case). Other modes like `acceptEdits`/`plan` are preserved. - Pre-allow Paperclip's Bash surface (`Bash(curl:*)`, `Bash(env:*)`, `Bash(<cwd>/scripts/paperclip-issue-update.sh:*)`, `Bash(<cwd>/scripts/paperclip:*)`). - Widen `permissions.additionalDirectories` to include `stateDir`, `agentHome`, and the per-company instance root (`~/.paperclip/instances/<id>/companies/<companyId>`). Scoped to this company only — does not expose other tenants. - Existing user entries are merged, not replaced. The resolved roots are folded into the session fingerprint so warm-session handles invalidate when they change. - Sync the existing server-side integration test (`server/src/__tests__/acpx-local-execute.test.ts`) to assert `acpx_session_init_failed` instead of the now-removed `acpx_protocol_error` for `ACP_SESSION_INIT_FAILED` (a follow-up to commit 1). ## Verification - `pnpm --filter "@paperclipai/adapter-acpx-local" run typecheck` — passes. - `pnpm vitest run` in `packages/adapters/acpx-local` — 35/35 pass, includes 4 new tests covering the settings.local.json write path (claude only, merge with pre-existing content, `dontAsk` override, codex no-op). - `pnpm vitest run src/__tests__/acpx-local-execute.test.ts` in `server/` — 15/15 pass after the test-sync commit. - End-to-end manual verification (PAPA-401): the `Claude Local ACPX` agent that previously hit "restricted environment" now successfully reaches the Paperclip API, opens its worktree, posts structured plan comments, and flips the issue to `in_review` without any external configuration. ## Risks - **Low**, scoped to the `acpx_local` adapter. The settings.local.json write is per-worktree (worktrees live under `.paperclip/worktrees/<issue>/`) and only triggers when `acpxAgent === "claude"`. Existing user content is merged with `[...existing, ...paperclip]` and deduped — nothing is overwritten outright. - The `defaultMode` override is intentionally narrow: it only flips `"dontAsk"` (which silently denies every tool and is the root cause) to `"default"`. Users who explicitly picked `acceptEdits`, `plan`, or any other mode keep their choice. - Stderr capture goes through the existing `log-redaction` pass before persisting, so `PAPERCLIP_API_KEY` and similar secrets in the wrapper env don't leak into heartbeat logs. > 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 4.7 (`claude-opus-4-7`), running in the `claude_local` adapter via Paperclip's harness. Extended thinking enabled, tool use enabled. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [ ] If this change affects the UI, I have included before/after screenshots — N/A (adapter-only) - [ ] I have updated relevant documentation to reflect my changes — no user-facing docs changed; internal commentary in the code change explains the SDK constraints - [x] I have considered and documented any risks above - [ ] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-05-23 13:01:27 -07:00
const { classified, message } = await emitAcpxFailure({
ctx,
prepared,
err,
phase: "turn",
messageOverride,
});
Add ACPX local adapter runtime (#4893) ## Thinking Path > - Paperclip orchestrates AI-agent companies through a control plane that can start, supervise, and recover agent runs. > - Local adapters are the bridge between Paperclip issues and concrete agent runtimes such as Claude, Codex, and other ACP-compatible tools. > - The roadmap calls out broader “bring your own agent” and claw-style agent support, and ACPX gives Paperclip one path to normalize multiple ACP agents behind a single adapter. > - The branch needed to become one reviewable PR against current `paperclipai/paperclip:master`, without carrying stale base conflicts or generated lockfile churn. > - This pull request adds an experimental built-in `acpx_local` adapter, integrates it through the server/CLI/UI adapter surfaces, and adds regression coverage for runtime execution, skill sync, stream parsing, diagnostics, and log redaction. > - The benefit is that Paperclip can run Claude/Codex/custom ACP agents through ACPX while keeping operator configuration, skills, logging, and transcript rendering inside the existing adapter model. ## What Changed - Added `@paperclipai/adapter-acpx-local` with server execution, config schema, ACPX session handling, CLI formatting, UI config helpers, and stdout parsing. - Registered `acpx_local` across CLI, server, shared constants, UI adapter metadata, adapter capabilities, and agent creation/editing surfaces. - Added ACPX runtime execution support with persistent sessions, local-agent JWT environment handling, skill snapshots, runtime skill materialization, and isolation/security regressions. - Added ACPX adapter diagnostics and marked the adapter experimental in the UI. - Added command/env secret redaction for resolved command metadata in adapter-utils, server event storage, and the Agent Detail invocation UI. - Added Storybook coverage for ACPX config, transcript rendering, and skill states, plus PR screenshots under `docs/pr-screenshots/pap-2944/`. - Rebased the branch onto current `public-gh/master`; `pnpm-lock.yaml` is intentionally not included and there are no migration/schema changes. ## Verification - `pnpm exec vitest run packages/adapters/acpx-local/src/server/execute.test.ts packages/adapters/acpx-local/src/server/test.test.ts packages/adapters/acpx-local/src/cli/format-event.test.ts packages/adapters/acpx-local/src/ui/parse-stdout.test.ts packages/adapter-utils/src/server-utils.test.ts server/src/__tests__/redaction.test.ts server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/acpx-local-skill-sync.test.ts server/src/__tests__/acpx-local-adapter-environment.test.ts server/src/__tests__/adapter-routes.test.ts server/src/__tests__/agent-skills-routes.test.ts ui/src/adapters/metadata.test.ts` — 12 files, 87 tests passed. - `pnpm --filter @paperclipai/adapter-acpx-local typecheck` — passed. - `pnpm --filter @paperclipai/server typecheck` — passed. - `pnpm --filter @paperclipai/ui typecheck` — passed. - Confirmed PR diff does not include `pnpm-lock.yaml`, database schema files, or migrations. Screenshots: ![ACPX Claude skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-light.png?raw=true) ![ACPX Claude skills dark](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-dark.png?raw=true) ![ACPX custom skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-custom-light.png?raw=true) ## Risks - Medium risk: this introduces a new built-in adapter package and touches runtime execution, adapter registration, agent config, skills, and transcript rendering. - ACPX and ACP agent behavior can vary by installed tool versions; the adapter is marked experimental to set operator expectations. - `pnpm-lock.yaml` is excluded per repository PR policy, so dependency lock refresh must be handled by the repo’s automation or maintainers. - No database migration risk: no schema or migration files changed. > 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 coding agent based on GPT-5, with repository tool use, shell execution, git operations, and local verification. Exact hosted context window was not exposed in this environment. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-30 19:57:05 -05:00
return {
exitCode: 1,
signal: timedOut ? "SIGTERM" : null,
timedOut,
errorMessage: message,
errorCode: timedOut ? "acpx_timeout" : classified.errorCode,
errorMeta: classified.errorMeta,
provider: "acpx",
Improve ACPX adapter configuration (#5290) ## Thinking Path > - Paperclip orchestrates AI agents across several adapter implementations. > - ACPX is a local adapter path that can proxy Claude and Codex-style execution. > - Its configuration needed stronger schema defaults, provider-aware model handling, and better UI support. > - Plugin authors also need clear docs for managed resources. > - This pull request improves ACPX adapter configuration and documents plugin-managed resources. > - The benefit is a more predictable adapter setup path without changing unrelated control-plane behavior. ## What Changed - Improved ACPX config schema, execution config handling, UI build config, and route coverage. - Added ACPX model filtering support and tests. - Updated the agent config form and storybook coverage for ACPX model/provider behavior. - Expanded plugin authoring documentation for managed resources. ## Verification - `pnpm install --frozen-lockfile` - `pnpm exec vitest run server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/adapter-routes.test.ts ui/src/lib/acpx-model-filter.test.ts` ## Risks - Low-to-medium risk: adapter configuration behavior changes can affect ACPX users, but the change is isolated to ACPX/plugin-doc surfaces and covered by targeted adapter tests. ## Model Used - OpenAI GPT-5 Codex via Paperclip `codex_local` adapter, with shell/git/GitHub CLI tool use. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-05-06 06:06:47 -05:00
model: prepared.requestedModel || null,
Add ACPX local adapter runtime (#4893) ## Thinking Path > - Paperclip orchestrates AI-agent companies through a control plane that can start, supervise, and recover agent runs. > - Local adapters are the bridge between Paperclip issues and concrete agent runtimes such as Claude, Codex, and other ACP-compatible tools. > - The roadmap calls out broader “bring your own agent” and claw-style agent support, and ACPX gives Paperclip one path to normalize multiple ACP agents behind a single adapter. > - The branch needed to become one reviewable PR against current `paperclipai/paperclip:master`, without carrying stale base conflicts or generated lockfile churn. > - This pull request adds an experimental built-in `acpx_local` adapter, integrates it through the server/CLI/UI adapter surfaces, and adds regression coverage for runtime execution, skill sync, stream parsing, diagnostics, and log redaction. > - The benefit is that Paperclip can run Claude/Codex/custom ACP agents through ACPX while keeping operator configuration, skills, logging, and transcript rendering inside the existing adapter model. ## What Changed - Added `@paperclipai/adapter-acpx-local` with server execution, config schema, ACPX session handling, CLI formatting, UI config helpers, and stdout parsing. - Registered `acpx_local` across CLI, server, shared constants, UI adapter metadata, adapter capabilities, and agent creation/editing surfaces. - Added ACPX runtime execution support with persistent sessions, local-agent JWT environment handling, skill snapshots, runtime skill materialization, and isolation/security regressions. - Added ACPX adapter diagnostics and marked the adapter experimental in the UI. - Added command/env secret redaction for resolved command metadata in adapter-utils, server event storage, and the Agent Detail invocation UI. - Added Storybook coverage for ACPX config, transcript rendering, and skill states, plus PR screenshots under `docs/pr-screenshots/pap-2944/`. - Rebased the branch onto current `public-gh/master`; `pnpm-lock.yaml` is intentionally not included and there are no migration/schema changes. ## Verification - `pnpm exec vitest run packages/adapters/acpx-local/src/server/execute.test.ts packages/adapters/acpx-local/src/server/test.test.ts packages/adapters/acpx-local/src/cli/format-event.test.ts packages/adapters/acpx-local/src/ui/parse-stdout.test.ts packages/adapter-utils/src/server-utils.test.ts server/src/__tests__/redaction.test.ts server/src/__tests__/acpx-local-execute.test.ts server/src/__tests__/acpx-local-skill-sync.test.ts server/src/__tests__/acpx-local-adapter-environment.test.ts server/src/__tests__/adapter-routes.test.ts server/src/__tests__/agent-skills-routes.test.ts ui/src/adapters/metadata.test.ts` — 12 files, 87 tests passed. - `pnpm --filter @paperclipai/adapter-acpx-local typecheck` — passed. - `pnpm --filter @paperclipai/server typecheck` — passed. - `pnpm --filter @paperclipai/ui typecheck` — passed. - Confirmed PR diff does not include `pnpm-lock.yaml`, database schema files, or migrations. Screenshots: ![ACPX Claude skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-light.png?raw=true) ![ACPX Claude skills dark](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-claude-dark.png?raw=true) ![ACPX custom skills light](https://github.com/cryppadotta/paperclip-1/blob/PAP-2944-acpx-make-a-claude_local-adapter-that-uses-acpx-instead/docs/pr-screenshots/pap-2944/skills-custom-light.png?raw=true) ## Risks - Medium risk: this introduces a new built-in adapter package and touches runtime execution, adapter registration, agent config, skills, and transcript rendering. - ACPX and ACP agent behavior can vary by installed tool versions; the adapter is marked experimental to set operator expectations. - `pnpm-lock.yaml` is excluded per repository PR policy, so dependency lock refresh must be handled by the repo’s automation or maintainers. - No database migration risk: no schema or migration files changed. > 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 coding agent based on GPT-5, with repository tool use, shell execution, git operations, and local verification. Exact hosted context window was not exposed in this environment. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-30 19:57:05 -05:00
clearSession: clearSession || timedOut,
resultJson: { phase: "turn" },
summary: message,
};
}
};
}
export const execute = createAcpxLocalExecutor();