Skip to content

feat(acp): configurable per-agent working directory (cwd) for remote-acp#975

Draft
aatchison wants to merge 1 commit into
mainfrom
remote-acp-configurable-cwd
Draft

feat(acp): configurable per-agent working directory (cwd) for remote-acp#975
aatchison wants to merge 1 commit into
mainfrom
remote-acp-configurable-cwd

Conversation

@aatchison

Copy link
Copy Markdown
Collaborator

Draft. Authored by the Thunderbird self-hosted coding-agent effort. Posting for review — see the deployment note below (two-PR synced-table process) and the /thunderpush caveat at the end.

Problem

The ACP adapter hardcodes the session cwd to '/' (src/acp/acp-adapter.ts). For a remote-acp agent with a real filesystem (e.g. a containerized Cline/Codex), that's invalid: the agent derives a workspace "hint" (name) from the cwd basename, and '/' → empty string, so the agent rejects the session:

-32602  data.path: ["workspaces","/","hint"]  code: too_small  ("expected string to have >=1 characters")

The WebSocket connects and chat/inference work, but every filesystem/tool action fails (the model declines: "I can't create files, do it yourself"). Confirmed against a real remote Cline over wss://: with cwd:/workspace the same prompt works; with '/' it errors.

Change — optional per-agent cwd, end to end

  • Schema: nullable cwd column on the agents table — backend Postgres (backend/src/db/powersync-schema.ts) + client SQLite (src/db/tables.ts), Drizzle migration 0019_smart_genesis. Sync rules use SELECT *, so the column auto-syncs (no sync-rule edit).
  • Types/DAL: Agent.cwd, CreateAgentInput.cwd, UpdateAgentPatch, row mappers.
  • UI: add-custom-agent dialog gains an optional "Working Directory" field (placeholder /).
  • Adapter: session/new + session/load use agent.cwd ?? '/' — the hardcoded value becomes the fallback. Browser / built-in / managed agents that don't set it are unchanged.

Backwards compatible: cwd unset ⇒ prior '/' behavior.

Tests / checks

  • bun run type-check clean; lint, format-check, license:check pass.
  • New: createAgent persists/defaults cwd (DAL); dialog passes cwd in payload. 497 tests pass across the touched dirs (acp/chats/components/dal). Many existing Agent-literal fixtures updated for the new required field.

⚠️ Deployment (two-PR synced-table process)

Per CLAUDE.md, a synced-column add must land backend-first: run migration 0019 (+ confirm PowerSync Cloud rules) before the frontend writes the column, or older clients silently fail to sync it. This branch contains both halves for review — please split/stage into the backend-then-frontend order on merge (or advise and I'll split it).

Notes

  • Companion context: shipped an agent-side shim workaround (SESSION_CWD rewrite) so this works today without waiting on a Thunderbolt deploy — thunderbird/thunderbolt-coding-agent#75. This PR is the proper upstream fix; also benefits managed-acp (feat(coding-agent): managed-acp provider + per-user GitHub token provisioning (draft) #967).
  • /thunderpush wasn't available in my environment, so this was committed directly via git (pre-commit hooks ran: license-headers + make format). Flagging in case the team wants it re-pushed through the standard flow.

The ACP adapter hardcoded the session cwd to '/' (src/acp/acp-adapter.ts).
That's invalid for a remote-acp agent with a real filesystem (e.g. a
containerized Cline): the agent derives a workspace "hint" from the cwd
basename, and '/' yields an empty string, so the agent rejects the session
(`-32602 "workspaces"/"/"/"hint": too small`). Connection + chat work, but
every filesystem/tool action fails.

Adds an optional `cwd` to remote-acp/managed-acp agents, end to end:
- agents table: nullable `cwd` column (backend Postgres + client SQLite),
  Drizzle migration 0019. Sync rules use SELECT * so the column auto-syncs.
- Agent type + DAL (CreateAgentInput, mappers, UpdateAgentPatch).
- Add-custom-agent dialog: optional "Working Directory" field (default '/').
- acp-adapter: session/new + session/load use `agent.cwd ?? '/'` (the
  hardcoded value becomes the fallback; browser/built-in/managed agents that
  don't set it are unchanged).

Backwards compatible: cwd unset => previous '/' behavior.

NOTE (deployment): per the two-PR synced-table process, the backend
migration must run before the frontend writes the column — this branch
contains both halves for review; split/stage on merge. Authored without
/thunderpush (unavailable in this environment) — committed directly.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant