@chorus-aidlc/chorus 0.17.3 → 0.18.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.next/standalone/.next/BUILD_ID +1 -1
- package/.next/standalone/.next/app-build-manifest.json +345 -341
- package/.next/standalone/.next/app-path-routes-manifest.json +35 -35
- package/.next/standalone/.next/build-manifest.json +5 -5
- package/.next/standalone/.next/prerender-manifest.json +27 -27
- package/.next/standalone/.next/server/app/(dashboard)/project-groups/[uuid]/page.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/project-groups/[uuid]/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/project-groups/[uuid]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/activity/page.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/activity/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/dashboard/[ideaUuid]/page.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/dashboard/[ideaUuid]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/dashboard/page.js +2 -2
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/dashboard/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/dashboard/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/documents/[documentUuid]/page.js +2 -2
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/documents/[documentUuid]/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/documents/[documentUuid]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/documents/page.js +2 -2
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/documents/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/graph/page.js +2 -2
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/graph/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/graph/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/[proposalUuid]/page.js +2 -2
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/[proposalUuid]/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/[proposalUuid]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/new/page.js +2 -2
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/new/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/new/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/page.js +2 -2
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/tasks/[taskUuid]/page.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/tasks/[taskUuid]/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/tasks/[taskUuid]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/tasks/page.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/tasks/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/tasks/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/page.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/settings/page.js +2 -2
- package/.next/standalone/.next/server/app/(dashboard)/settings/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/settings/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/_not-found.html +2 -2
- package/.next/standalone/.next/server/app/_not-found.rsc +2 -2
- package/.next/standalone/.next/server/app/admin/companies/[uuid]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/admin/companies/new/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/admin/companies/new.html +2 -2
- package/.next/standalone/.next/server/app/admin/companies/new.rsc +2 -2
- package/.next/standalone/.next/server/app/admin/companies/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/admin/companies.html +2 -2
- package/.next/standalone/.next/server/app/admin/companies.rsc +2 -2
- package/.next/standalone/.next/server/app/admin/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/admin.html +2 -2
- package/.next/standalone/.next/server/app/admin.rsc +2 -2
- package/.next/standalone/.next/server/app/api/admin/companies/[uuid]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/admin/companies/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/admin/login/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/admin/session/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/agent-connections/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/agent-connections/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/agents/[uuid]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/agents/[uuid]/sessions/route.js +1 -1
- package/.next/standalone/.next/server/app/api/agents/[uuid]/sessions/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/agents/[uuid]/sessions/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/agents/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/api-keys/[uuid]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/api-keys/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/auth/callback/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/auth/check-default/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/auth/company-oidc/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/auth/default-login/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/auth/identify/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/auth/logout/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/auth/me/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/auth/sync-token/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/comments/route.js +1 -1
- package/.next/standalone/.next/server/app/api/comments/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/comments/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon/connection-heartbeat/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/daemon/connection-heartbeat/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon/control/route.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon/control/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/daemon/control/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon/directory-request/report/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/daemon/directory-request/report/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon/execution-state/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/daemon/execution-state/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon/executions/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/daemon/executions/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon/pending-turns/route.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon/pending-turns/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/daemon/pending-turns/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon/report-interrupt/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/daemon/report-interrupt/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon/resume/route.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon/resume/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/daemon/resume/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon/transcript/route.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon/transcript/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/daemon/transcript/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon/turn-advance/route.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon/turn-advance/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/daemon/turn-advance/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon-directory-requests/[uuid]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/daemon-directory-requests/[uuid]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon-directory-requests/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/daemon-directory-requests/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon-sessions/[sessionUuid]/instruction/route.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon-sessions/[sessionUuid]/instruction/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/daemon-sessions/[sessionUuid]/instruction/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon-sessions/[sessionUuid]/repoint/route.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon-sessions/[sessionUuid]/repoint/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/daemon-sessions/[sessionUuid]/repoint/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon-sessions/[sessionUuid]/route.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon-sessions/[sessionUuid]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/daemon-sessions/[sessionUuid]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon-sessions/ad-hoc/route.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon-sessions/ad-hoc/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/daemon-sessions/ad-hoc/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon-sessions/route.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon-sessions/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/daemon-sessions/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/documents/[uuid]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/entities/[type]/[uuid]/root-idea/route.js +1 -1
- package/.next/standalone/.next/server/app/api/entities/[type]/[uuid]/root-idea/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/entities/[type]/[uuid]/root-idea/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/events/notifications/route.js +1 -1
- package/.next/standalone/.next/server/app/api/events/notifications/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/events/notifications/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/events/route.js +1 -1
- package/.next/standalone/.next/server/app/api/events/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/events/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/health/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/ideas/[uuid]/claim/route.js +1 -1
- package/.next/standalone/.next/server/app/api/ideas/[uuid]/claim/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/ideas/[uuid]/claim/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/ideas/[uuid]/move/preview/route.js +1 -1
- package/.next/standalone/.next/server/app/api/ideas/[uuid]/move/preview/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/ideas/[uuid]/move/preview/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/ideas/[uuid]/move/route.js +1 -1
- package/.next/standalone/.next/server/app/api/ideas/[uuid]/move/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/ideas/[uuid]/move/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/ideas/[uuid]/parent/route.js +1 -1
- package/.next/standalone/.next/server/app/api/ideas/[uuid]/parent/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/ideas/[uuid]/parent/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/ideas/[uuid]/release/route.js +1 -1
- package/.next/standalone/.next/server/app/api/ideas/[uuid]/release/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/ideas/[uuid]/release/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/ideas/[uuid]/route.js +1 -1
- package/.next/standalone/.next/server/app/api/ideas/[uuid]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/ideas/[uuid]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/ideas/[uuid]/wake-preview/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/ideas/[uuid]/wake-preview/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/ideas/conversational/route.js +1 -1
- package/.next/standalone/.next/server/app/api/ideas/conversational/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/ideas/conversational/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/mcp/route.js +1 -1
- package/.next/standalone/.next/server/app/api/mcp/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/mcp/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/me/assignments/route.js +1 -1
- package/.next/standalone/.next/server/app/api/me/assignments/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/me/assignments/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/mentionables/route.js +1 -1
- package/.next/standalone/.next/server/app/api/mentionables/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/mentionables/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/notifications/[uuid]/archive/route.js +1 -1
- package/.next/standalone/.next/server/app/api/notifications/[uuid]/archive/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/notifications/[uuid]/archive/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/notifications/[uuid]/read/route.js +1 -1
- package/.next/standalone/.next/server/app/api/notifications/[uuid]/read/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/notifications/[uuid]/read/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/notifications/preferences/route.js +1 -1
- package/.next/standalone/.next/server/app/api/notifications/preferences/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/notifications/preferences/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/notifications/read-all/route.js +1 -1
- package/.next/standalone/.next/server/app/api/notifications/read-all/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/notifications/read-all/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/notifications/route.js +1 -1
- package/.next/standalone/.next/server/app/api/notifications/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/notifications/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/notifications/unread-count/route.js +1 -1
- package/.next/standalone/.next/server/app/api/notifications/unread-count/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/notifications/unread-count/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/project-groups/[uuid]/dashboard/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/project-groups/[uuid]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/project-groups/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/project-visits/pin/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/project-visits/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/project-visits/visit/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/activity/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/agent-cwds/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/agent-cwds/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/available/route.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/available/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/available/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/documents/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/group/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/ideas/route.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/ideas/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/ideas/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/ideas/tracker/route.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/ideas/tracker/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/ideas/tracker/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/proposals/[proposalUuid]/validate/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/proposals/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/proposals/summary/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/resource-graph/route.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/resource-graph/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/resource-graph/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/stats/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/tasks/dependencies/route.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/tasks/dependencies/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/tasks/dependencies/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/tasks/route.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/tasks/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/tasks/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/agent-cwd-options/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/projects/agent-cwd-options/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/proposals/[uuid]/approve/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/proposals/[uuid]/close/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/proposals/[uuid]/reject/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/proposals/[uuid]/revoke/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/proposals/[uuid]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/references/[uuid]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/references/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/search/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/session/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/sessions/[uuid]/route.js +1 -1
- package/.next/standalone/.next/server/app/api/sessions/[uuid]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/sessions/[uuid]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/tasks/[uuid]/claim/route.js +1 -1
- package/.next/standalone/.next/server/app/api/tasks/[uuid]/claim/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/tasks/[uuid]/claim/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/tasks/[uuid]/dependencies/[dependsOnUuid]/route.js +1 -1
- package/.next/standalone/.next/server/app/api/tasks/[uuid]/dependencies/[dependsOnUuid]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/tasks/[uuid]/dependencies/[dependsOnUuid]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/tasks/[uuid]/dependencies/route.js +1 -1
- package/.next/standalone/.next/server/app/api/tasks/[uuid]/dependencies/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/tasks/[uuid]/dependencies/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/tasks/[uuid]/release/route.js +1 -1
- package/.next/standalone/.next/server/app/api/tasks/[uuid]/release/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/tasks/[uuid]/release/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/tasks/[uuid]/route.js +1 -1
- package/.next/standalone/.next/server/app/api/tasks/[uuid]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/tasks/[uuid]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/tasks/[uuid]/sessions/route.js +1 -1
- package/.next/standalone/.next/server/app/api/tasks/[uuid]/sessions/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/tasks/[uuid]/sessions/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/index.html +2 -2
- package/.next/standalone/.next/server/app/index.rsc +2 -2
- package/.next/standalone/.next/server/app/login/admin/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/login/admin.html +2 -2
- package/.next/standalone/.next/server/app/login/admin.rsc +2 -2
- package/.next/standalone/.next/server/app/login/callback/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/login/callback.html +2 -2
- package/.next/standalone/.next/server/app/login/callback.rsc +2 -2
- package/.next/standalone/.next/server/app/login/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/login/pick-workspace/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/login/pick-workspace.html +2 -2
- package/.next/standalone/.next/server/app/login/pick-workspace.rsc +2 -2
- package/.next/standalone/.next/server/app/login.html +2 -2
- package/.next/standalone/.next/server/app/login.rsc +2 -2
- package/.next/standalone/.next/server/app/onboarding/page.js +2 -2
- package/.next/standalone/.next/server/app/onboarding/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/onboarding/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/onboarding.html +2 -2
- package/.next/standalone/.next/server/app/onboarding.rsc +3 -3
- package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/projects.html +2 -2
- package/.next/standalone/.next/server/app/projects.rsc +3 -3
- package/.next/standalone/.next/server/app/settings.html +2 -2
- package/.next/standalone/.next/server/app/settings.rsc +4 -4
- package/.next/standalone/.next/server/app-paths-manifest.json +35 -35
- package/.next/standalone/.next/server/chunks/1318.js +1 -1
- package/.next/standalone/.next/server/chunks/{5201.js → 1416.js} +2 -2
- package/.next/standalone/.next/server/chunks/1559.js +2 -2
- package/.next/standalone/.next/server/chunks/{3630.js → 2195.js} +1 -1
- package/.next/standalone/.next/server/chunks/2460.js +1 -0
- package/.next/standalone/.next/server/chunks/2572.js +2 -2
- package/.next/standalone/.next/server/chunks/2758.js +1 -0
- package/.next/standalone/.next/server/chunks/2961.js +1 -1
- package/.next/standalone/.next/server/chunks/3419.js +1 -1
- package/.next/standalone/.next/server/chunks/4066.js +1 -0
- package/.next/standalone/.next/server/chunks/4827.js +1 -1
- package/.next/standalone/.next/server/chunks/5245.js +1 -1
- package/.next/standalone/.next/server/chunks/5453.js +1 -1
- package/.next/standalone/.next/server/chunks/5489.js +1 -1
- package/.next/standalone/.next/server/chunks/6113.js +1 -1
- package/.next/standalone/.next/server/chunks/6506.js +2 -2
- package/.next/standalone/.next/server/chunks/6737.js +1 -0
- package/.next/standalone/.next/server/chunks/679.js +1 -1
- package/.next/standalone/.next/server/chunks/7368.js +1 -1
- package/.next/standalone/.next/server/chunks/7530.js +1 -1
- package/.next/standalone/.next/server/chunks/7578.js +2 -2
- package/.next/standalone/.next/server/chunks/7675.js +1 -0
- package/.next/standalone/.next/server/chunks/7789.js +1 -0
- package/.next/standalone/.next/server/chunks/{1201.js → 8030.js} +2 -2
- package/.next/standalone/.next/server/chunks/920.js +1 -1
- package/.next/standalone/.next/server/chunks/9213.js +1 -1
- package/.next/standalone/.next/server/chunks/9378.js +1 -1
- package/.next/standalone/.next/server/chunks/9931.js +1 -1
- package/.next/standalone/.next/server/instrumentation.js +1 -1
- package/.next/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/.next/standalone/.next/server/middleware-manifest.json +5 -5
- package/.next/standalone/.next/server/pages/404.html +2 -2
- package/.next/standalone/.next/server/pages/500.html +1 -1
- package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/static/chunks/11595.f080a1d100972212.js +1 -0
- package/.next/standalone/.next/static/chunks/14628-283d3983d1fb36c9.js +1 -0
- package/.next/standalone/.next/static/chunks/{29305-f587e7e81bc0b200.js → 17562-56f932146e9e6c94.js} +4 -4
- package/.next/standalone/.next/static/chunks/25080-25ad29e64c855338.js +1 -0
- package/.next/standalone/.next/static/chunks/28698-7fb271ffc6e63a26.js +1 -0
- package/.next/standalone/.next/static/chunks/{95225-96b44da3ebd6ddad.js → 32736-aeaaa1e4c4d5529b.js} +1 -1
- package/.next/standalone/.next/static/chunks/33456.20313bd67a5c41cc.js +1 -0
- package/.next/standalone/.next/static/chunks/4860.3b555a398cdffb19.js +1 -0
- package/.next/standalone/.next/static/chunks/75257-99c0ce24b436847b.js +1 -0
- package/.next/standalone/.next/static/chunks/79919-0c6dcda1dd8646f0.js +1 -0
- package/.next/standalone/.next/static/chunks/91328-f501e3c3ca519a92.js +1 -0
- package/.next/standalone/.next/static/chunks/94643-e54eff17e941a93b.js +1 -0
- package/.next/standalone/.next/static/chunks/99373.b8a95d1bec5ad4e7.js +1 -0
- package/.next/standalone/.next/static/chunks/app/(dashboard)/layout-f3c6431432d42c7c.js +1 -0
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/dashboard/{page-77b175e52a85f3cb.js → page-5d723f974bdad33b.js} +1 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/documents/[documentUuid]/page-8d3b1f4d8b76d66c.js +1 -0
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/documents/page-57c698dea2fa6e29.js +1 -0
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/graph/{page-69d3162667f85677.js → page-d2bb622855e746f1.js} +1 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/[proposalUuid]/page-fc255dc3612032b9.js +1 -0
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/new/{page-a3f83031dfbafc81.js → page-f032ee8a80d1f56a.js} +1 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/page-46a0ddfd0421b0a8.js +1 -0
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/tasks/[taskUuid]/{page-3c7ff3a40a4615ac.js → page-3a83748ce0ae1c4f.js} +1 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/tasks/{page-7b8e11fdc5b596d0.js → page-8af9bb9f96ab0258.js} +1 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/settings/page-b02939820affdae5.js +1 -0
- package/.next/standalone/.next/static/chunks/app/onboarding/page-d2c0c7951114e763.js +1 -0
- package/.next/standalone/.next/static/chunks/{webpack-dffb97a4feb8faba.js → webpack-de8a36d232a91d6b.js} +1 -1
- package/.next/standalone/.next/static/css/44f13b43a3de716d.css +1 -0
- package/.next/standalone/package.json +1 -1
- package/.next/standalone/public/chorus-plugin/.claude-plugin/plugin.json +2 -2
- package/.next/standalone/public/chorus-plugin/agents/code-reviewer.md +1 -0
- package/.next/standalone/public/chorus-plugin/agents/proposal-reviewer.md +12 -3
- package/.next/standalone/public/chorus-plugin/agents/task-reviewer.md +4 -0
- package/.next/standalone/public/chorus-plugin/bin/chorus-api.sh +1 -1
- package/.next/standalone/public/chorus-plugin/bin/on-post-submit-for-verify.sh +3 -3
- package/.next/standalone/public/chorus-plugin/bin/on-post-submit-proposal.sh +3 -3
- package/.next/standalone/public/chorus-plugin/bin/on-post-verify-task.sh +2 -2
- package/.next/standalone/public/chorus-plugin/bin/on-pre-spawn-agent.sh +22 -9
- package/.next/standalone/public/chorus-plugin/bin/on-session-start.sh +39 -64
- package/.next/standalone/public/chorus-plugin/bin/on-subagent-start.sh +44 -29
- package/.next/standalone/public/chorus-plugin/bin/on-subagent-stop.sh +100 -29
- package/.next/standalone/public/chorus-plugin/bin/resolve-spec-mode.sh +107 -0
- package/.next/standalone/public/chorus-plugin/bin/test-syntax.sh +6 -2
- package/.next/standalone/public/chorus-plugin/bin/tests/test-resolver-drift.sh +46 -0
- package/.next/standalone/public/chorus-plugin/bin/tests/test-skill-harness-fidelity-negative.sh +328 -0
- package/.next/standalone/public/chorus-plugin/bin/tests/test-skill-harness-fidelity.sh +372 -0
- package/.next/standalone/public/chorus-plugin/bin/tests/test-spec-mode-resolution.sh +83 -0
- package/.next/standalone/public/chorus-plugin/bin/tests/test-subagent-session-name.sh +599 -0
- package/.next/standalone/public/chorus-plugin/skills/brainstorm/SKILL.md +1 -1
- package/.next/standalone/public/chorus-plugin/skills/chorus/SKILL.md +11 -6
- package/.next/standalone/public/chorus-plugin/skills/chorus-cli/SKILL.md +1 -1
- package/.next/standalone/public/chorus-plugin/skills/develop/SKILL.md +14 -9
- package/.next/standalone/public/chorus-plugin/skills/docs/SKILL.md +1 -1
- package/.next/standalone/public/chorus-plugin/skills/idea/SKILL.md +1 -1
- package/.next/standalone/public/chorus-plugin/skills/openspec-aware/SKILL.md +27 -31
- package/.next/standalone/public/chorus-plugin/skills/orchestrate/SKILL.md +11 -1
- package/.next/standalone/public/chorus-plugin/skills/proposal/SKILL.md +14 -7
- package/.next/standalone/public/chorus-plugin/skills/quick-dev/SKILL.md +6 -4
- package/.next/standalone/public/chorus-plugin/skills/review/SKILL.md +10 -8
- package/.next/standalone/public/chorus-plugin/skills/spec-lite/SKILL.md +147 -0
- package/.next/standalone/public/chorus-plugin/skills/yolo/SKILL.md +49 -34
- package/.next/standalone/public/kiro-plugin/.kiro/agents/chorus-code-reviewer.json +1 -1
- package/.next/standalone/public/kiro-plugin/.kiro/agents/chorus-proposal-reviewer.json +2 -1
- package/.next/standalone/public/kiro-plugin/.kiro/agents/chorus-task-reviewer.json +1 -1
- package/.next/standalone/public/kiro-plugin/.kiro/agents/chorus.md +1 -1
- package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-brainstorm/SKILL.md +1 -1
- package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-cli/SKILL.md +1 -1
- package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-develop/SKILL.md +9 -7
- package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-docs/SKILL.md +1 -1
- package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-idea/SKILL.md +1 -1
- package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-openspec-aware/SKILL.md +35 -27
- package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-orchestrate/SKILL.md +9 -1
- package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-proposal/SKILL.md +14 -7
- package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-quick-dev/SKILL.md +2 -2
- package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-review/SKILL.md +8 -8
- package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-spec-lite/SKILL.md +147 -0
- package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-yolo/SKILL.md +39 -25
- package/.next/standalone/public/kiro-plugin/.kiro/steering/chorus.md +11 -6
- package/.next/standalone/public/kiro-plugin/bin/chorus-api.sh +1 -1
- package/.next/standalone/public/kiro-plugin/bin/on-agent-spawn.sh +41 -0
- package/.next/standalone/public/kiro-plugin/bin/on-post-submit-for-verify.sh +3 -3
- package/.next/standalone/public/kiro-plugin/bin/on-post-submit-proposal.sh +3 -3
- package/.next/standalone/public/kiro-plugin/bin/on-post-verify-task.sh +2 -2
- package/.next/standalone/public/kiro-plugin/bin/resolve-spec-mode.sh +107 -0
- package/.next/standalone/public/kiro-plugin/manifest.txt +2 -0
- package/.next/standalone/public/skill/chorus/SKILL.md +11 -1
- package/.next/standalone/public/skill/code-reviewer-chorus/SKILL.md +1 -0
- package/.next/standalone/public/skill/develop-chorus/SKILL.md +1 -1
- package/.next/standalone/public/skill/orchestrate-chorus/SKILL.md +11 -1
- package/.next/standalone/public/skill/proposal-reviewer-chorus/SKILL.md +5 -2
- package/.next/standalone/public/skill/quick-dev-chorus/SKILL.md +1 -1
- package/.next/standalone/public/skill/review-chorus/SKILL.md +5 -3
- package/.next/standalone/public/skill/task-reviewer-chorus/SKILL.md +4 -0
- package/.next/standalone/public/skill/yolo-chorus/SKILL.md +23 -7
- package/README.ja.md +3 -3
- package/README.ko.md +3 -3
- package/README.md +3 -3
- package/README.zh.md +3 -3
- package/chorus.mjs +30 -2
- package/cli/agent-cli-config.mjs +323 -0
- package/cli/agent-launcher.mjs +44 -16
- package/cli/child-exit.mjs +77 -0
- package/cli/claude-spawner.mjs +26 -14
- package/cli/codex-spawner.mjs +27 -16
- package/cli/control-handler.mjs +104 -6
- package/cli/credentials.mjs +7 -0
- package/cli/daemon-config.mjs +14 -0
- package/cli/daemon-rest-client.mjs +98 -29
- package/cli/daemon.mjs +37 -7
- package/cli/dsh-managed-config.mjs +26 -28
- package/cli/dsh-spawner.mjs +27 -16
- package/cli/init/steps/credential-seed.mjs +1 -1
- package/cli/kiro-spawner.mjs +26 -16
- package/cli/launch-diagnostics.mjs +67 -0
- package/cli/login.mjs +17 -1
- package/cli/pi-spawner.mjs +23 -13
- package/cli/prompts.mjs +52 -2
- package/cli/spawner-select.mjs +6 -11
- package/package.json +1 -1
- package/.next/standalone/.next/server/chunks/1114.js +0 -1
- package/.next/standalone/.next/server/chunks/1155.js +0 -1
- package/.next/standalone/.next/server/chunks/6465.js +0 -1
- package/.next/standalone/.next/server/chunks/8105.js +0 -1
- package/.next/standalone/.next/server/chunks/8232.js +0 -1
- package/.next/standalone/.next/static/chunks/11595.f7c3ef5cd7fc8feb.js +0 -1
- package/.next/standalone/.next/static/chunks/33456.c81079032acc2966.js +0 -1
- package/.next/standalone/.next/static/chunks/45262-38b332523f00a223.js +0 -1
- package/.next/standalone/.next/static/chunks/46021-f5d072b0cbcb7fac.js +0 -1
- package/.next/standalone/.next/static/chunks/4860.f0cfb1201191ae88.js +0 -1
- package/.next/standalone/.next/static/chunks/66609-64a01d5cb415465b.js +0 -1
- package/.next/standalone/.next/static/chunks/79919-c5a2a3fd8f5f9204.js +0 -1
- package/.next/standalone/.next/static/chunks/94394-38194b81b489275c.js +0 -1
- package/.next/standalone/.next/static/chunks/94643-f1bdf37fb3bb6adb.js +0 -1
- package/.next/standalone/.next/static/chunks/96482-2b3bdb2544d72e5a.js +0 -1
- package/.next/standalone/.next/static/chunks/99373.3c23ac2efbd4db02.js +0 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/layout-66328332f62c7371.js +0 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/documents/[documentUuid]/page-87ceae13c4950fc9.js +0 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/documents/page-45e95154e546460e.js +0 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/[proposalUuid]/page-b7b2017e5be69564.js +0 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/page-8b06834ca0f663bb.js +0 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/settings/page-efe5326c47aca9ca.js +0 -1
- package/.next/standalone/.next/static/chunks/app/onboarding/page-0ce33b9327fe3d8c.js +0 -1
- package/.next/standalone/.next/static/css/1d9cf83f50b6db00.css +0 -1
- /package/.next/standalone/.next/static/{wuqYN129vOIGymh_NEdZe → dot63ILT878Tloqi7Czj_}/_buildManifest.js +0 -0
- /package/.next/standalone/.next/static/{wuqYN129vOIGymh_NEdZe → dot63ILT878Tloqi7Czj_}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
// Per-profile literal argv/env. No IO, interpolation, defaults shared across agents,
|
|
2
|
+
// or attempt to sandbox an operator who controls their executable/config files.
|
|
3
|
+
const canonicalType = (type) => type === "claude" ? "claude-code" : type;
|
|
4
|
+
|
|
5
|
+
// Known controls owned by the headless adapters (also protected in persistent
|
|
6
|
+
// foreground config). Short options match attached values and clusters as well.
|
|
7
|
+
const PROTECTED = {
|
|
8
|
+
"claude-code": {
|
|
9
|
+
long: "print output-format input-format verbose session-id resume continue fork-session no-session-persistence mcp-config strict-mcp-config permission-mode permission-prompts permission-prompt-tool dangerously-skip-permissions allow-dangerously-skip-permissions allowedTools allowed-tools disallowedTools disallowed-tools tools add-dir cwd system-prompt system-prompt-file append-system-prompt append-system-prompt-file settings setting-sources agent agents worktree teleport from-pr remote-control remote-control-session-name-prefix background bg cloud environment bare json-schema include-partial-messages replay-user-messages restricted safe-mode system-prompt-snapshot tmux include-hook-events forward-subagent-text prompt-suggestions",
|
|
10
|
+
short: "prcwv",
|
|
11
|
+
},
|
|
12
|
+
codex: {
|
|
13
|
+
long: "json experimental-json output-schema output-last-message color sandbox ask-for-approval full-auto approve-for-me not-so-yolo yolo dangerously-bypass-approvals-and-sandbox dangerously-bypass-hook-trust cd add-dir skip-git-repo-check ephemeral last all session resume fork profile remote remote-auth-token-env thread-source ignore-user-config ignore-rules",
|
|
14
|
+
short: "soaCp",
|
|
15
|
+
},
|
|
16
|
+
kiro: {
|
|
17
|
+
long: "no-interactive resume resume-id resume-picker agent trust-all-tools trust-tools list-sessions delete-session session-source format agent-engine v3 mode cwd tui legacy-ui classic list-models verbose",
|
|
18
|
+
short: "raldfv",
|
|
19
|
+
},
|
|
20
|
+
pi: {
|
|
21
|
+
long: "print mode continue resume session session-id session-dir no-session fork name cwd system-prompt append-system-prompt export list-models",
|
|
22
|
+
short: "pcrn",
|
|
23
|
+
},
|
|
24
|
+
dsh: {
|
|
25
|
+
long: "profile patch dump-config dump-default-config resume session session-id cwd rpc mode prompt",
|
|
26
|
+
short: "",
|
|
27
|
+
},
|
|
28
|
+
opencode: {
|
|
29
|
+
long: "continue session fork prompt agent port hostname mdns mdns-domain cors",
|
|
30
|
+
short: "cs",
|
|
31
|
+
},
|
|
32
|
+
openclaw: {
|
|
33
|
+
long: "session session-key session-id message agent local json gateway port profile dev to",
|
|
34
|
+
short: "mt",
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
// Arity is separate from protection and singleton precedence. This is NOT a
|
|
39
|
+
// generic third-party parser: unknown flags pass through, but we never guess
|
|
40
|
+
// whether their next token is a value. Sources/limitations: docs/DAEMON.md.
|
|
41
|
+
// Each entry is zero, one required value, optional value, or variadic values.
|
|
42
|
+
const ARITIES = {
|
|
43
|
+
"claude-code": {
|
|
44
|
+
zero: "print continue verbose fork-session no-session-persistence strict-mcp-config dangerously-skip-permissions allow-dangerously-skip-permissions bg background bare brief chrome no-chrome disable-slash-commands ide ax-screen-reader exclude-dynamic-system-prompt-sections include-hook-events include-partial-messages forward-subagent-text replay-user-messages restricted safe-mode",
|
|
45
|
+
one: "model effort autocompact debug-file fallback-model max-budget-usd plugin-dir plugin-url name agent agents append-system-prompt append-system-prompt-file system-prompt system-prompt-file input-format output-format json-schema permission-mode permission-prompts permission-prompt-tool session-id settings setting-sources environment remote-control-session-name-prefix system-prompt-snapshot",
|
|
46
|
+
optional: "debug resume worktree cloud from-pr remote-control teleport prompt-suggestions tmux",
|
|
47
|
+
many: "add-dir allowedTools allowed-tools disallowedTools disallowed-tools tools mcp-config betas file",
|
|
48
|
+
aliases: { "-p": "--print", "-c": "--continue", "-d": "--debug", "-n": "--name", "-r": "--resume", "-w": "--worktree" },
|
|
49
|
+
},
|
|
50
|
+
codex: {
|
|
51
|
+
zero: "strict-config oss search no-alt-screen json experimental-json full-auto approve-for-me not-so-yolo yolo dangerously-bypass-approvals-and-sandbox dangerously-bypass-hook-trust skip-git-repo-check ephemeral last all ignore-user-config ignore-rules",
|
|
52
|
+
one: "model config enable disable image local-provider profile sandbox ask-for-approval cd add-dir remote remote-auth-token-env thread-source output-schema output-last-message color",
|
|
53
|
+
aliases: { "-m": "--model", "-c": "--config", "-i": "--image", "-p": "--profile", "-s": "--sandbox", "-a": "--ask-for-approval", "-C": "--cd", "-o": "--output-last-message" },
|
|
54
|
+
},
|
|
55
|
+
kiro: {
|
|
56
|
+
zero: "resume resume-picker trust-all-tools no-interactive list-sessions list-models require-mcp-startup verbose tui legacy-ui classic v3",
|
|
57
|
+
one: "model effort resume-id agent trust-tools format delete-session session-source wrap agent-engine mode",
|
|
58
|
+
aliases: { "-r": "--resume", "-a": "--trust-all-tools", "-l": "--list-sessions", "-f": "--format", "-d": "--delete-session", "-w": "--wrap", "-v": "--verbose" },
|
|
59
|
+
},
|
|
60
|
+
pi: {
|
|
61
|
+
zero: "continue resume no-session no-tools no-builtin-tools no-extensions no-skills no-prompt-templates no-themes no-context-files verbose approve no-approve offline",
|
|
62
|
+
one: "provider model api-key system-prompt append-system-prompt mode session session-id fork session-dir name models tools exclude-tools thinking extension skill prompt-template theme use-theme export tui-mode",
|
|
63
|
+
optional: "print list-models",
|
|
64
|
+
aliases: { "-p": "--print", "-c": "--continue", "-r": "--resume", "-n": "--name", "-nt": "--no-tools", "-nbt": "--no-builtin-tools", "-t": "--tools", "-xt": "--exclude-tools", "-e": "--extension", "-ne": "--no-extensions", "-ns": "--no-skills", "-np": "--no-prompt-templates", "-nc": "--no-context-files", "-a": "--approve", "-na": "--no-approve" },
|
|
65
|
+
},
|
|
66
|
+
dsh: { zero: "dump-config dump-default-config", one: "profile patch" },
|
|
67
|
+
opencode: {
|
|
68
|
+
zero: "print-logs pure continue fork mdns",
|
|
69
|
+
one: "log-level model session prompt agent port hostname mdns-domain",
|
|
70
|
+
many: "cors",
|
|
71
|
+
aliases: { "-m": "--model", "-c": "--continue", "-s": "--session" },
|
|
72
|
+
},
|
|
73
|
+
openclaw: {
|
|
74
|
+
zero: "local json deliver dry-run best-effort-deliver dev no-color",
|
|
75
|
+
one: "model thinking message to session-id agent channel reply-to reply-channel reply-account timeout verbose profile log-level",
|
|
76
|
+
aliases: { "-m": "--message", "-t": "--to" },
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
const OPTION_ARITIES = Object.fromEntries(Object.entries(ARITIES).map(([type, spec]) => {
|
|
80
|
+
const flags = { "--help": "zero", "--version": "zero" };
|
|
81
|
+
for (const arity of ["zero", "one", "optional", "many"])
|
|
82
|
+
for (const name of (spec[arity] ?? "").split(" ").filter(Boolean)) flags[`--${name}`] = arity;
|
|
83
|
+
return [type, { flags, aliases: { "-h": "--help", "-V": "--version", "-v": "--version", ...spec.aliases } }];
|
|
84
|
+
}));
|
|
85
|
+
|
|
86
|
+
function optionAt(type, args, i) {
|
|
87
|
+
const spec = OPTION_ARITIES[type];
|
|
88
|
+
const token = args[i];
|
|
89
|
+
let flag = token.split("=", 1)[0];
|
|
90
|
+
let attached = token.includes("=");
|
|
91
|
+
// Pi has exact multi-character aliases (-nt, -xt, ...), not short clusters.
|
|
92
|
+
if (type !== "pi" && /^-[^-].+/.test(token) && !spec?.aliases[flag]) {
|
|
93
|
+
const short = token.slice(0, 2);
|
|
94
|
+
if (spec?.flags[spec.aliases[short]] === "one" || spec?.flags[spec.aliases[short]] === "optional") {
|
|
95
|
+
flag = short;
|
|
96
|
+
attached = true;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
flag = spec?.aliases[flag] ?? flag;
|
|
100
|
+
const arity = spec?.flags[flag];
|
|
101
|
+
if (!arity) return null;
|
|
102
|
+
let size = 1;
|
|
103
|
+
const next = args[i + 1];
|
|
104
|
+
// Clap/yargs keep -- as a boundary; Pi and Commander consume it literally
|
|
105
|
+
// as a required value. Persistent configuration rejects sentinels either way.
|
|
106
|
+
const literalSentinel = ["pi", "claude-code", "dsh", "openclaw"].includes(type);
|
|
107
|
+
const piNonOptionValue = type === "pi" && ["--use-theme", "--tui-mode"].includes(flag);
|
|
108
|
+
const hasNext = next !== undefined && (next !== "--" || literalSentinel) &&
|
|
109
|
+
!(piNonOptionValue && next.startsWith("-"));
|
|
110
|
+
if (!attached && hasNext) {
|
|
111
|
+
if (arity === "one" || arity === "many") size++;
|
|
112
|
+
else if (arity === "optional" && !next.startsWith("-")) size++;
|
|
113
|
+
}
|
|
114
|
+
if (arity === "many") {
|
|
115
|
+
while (i + size < args.length && !args[i + size].startsWith("-")) size++;
|
|
116
|
+
}
|
|
117
|
+
return { flag, arity, size, missing: !attached && ["one", "many"].includes(arity) && size === 1 };
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function invalid(label, field, reason) {
|
|
121
|
+
// Never include the token, env name, or value: even malformed keys can be secrets.
|
|
122
|
+
throw new Error(`Agent ${label}: ${field} ${reason}.`);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export function rejectSharedCliConfig(file) {
|
|
126
|
+
if (Array.isArray(file?.agents) && file.agents.length &&
|
|
127
|
+
(Object.hasOwn(file, "args") || Object.hasOwn(file, "env"))) {
|
|
128
|
+
throw new Error("daemon.json: top-level args/env cannot be shared with agents[]; move them into each agent entry.");
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Codex -c is repeatable by TOML key, not a singleton flag. Parse only a simple
|
|
133
|
+
// dotted/quoted key; reject ambiguous keys in persistent config rather than risk
|
|
134
|
+
// allowing quoted protected controls to bypass the guard.
|
|
135
|
+
function codexConfigAt(args, i) {
|
|
136
|
+
const tok = args[i];
|
|
137
|
+
let value;
|
|
138
|
+
let size = 1;
|
|
139
|
+
if (tok === "-c" || tok === "--config") { value = args[i + 1]; size = value === "--" || value === undefined ? 1 : 2; }
|
|
140
|
+
else if (tok.startsWith("--config=")) value = tok.slice(9);
|
|
141
|
+
else if (tok.startsWith("-c") && !tok.startsWith("--")) value = tok.slice(2).replace(/^=/, "");
|
|
142
|
+
else return null;
|
|
143
|
+
const raw = typeof value === "string" ? value.split("=", 1)[0].trim() : "";
|
|
144
|
+
const key = raw.replace(/["']/g, "").replace(/\s*\.\s*/g, ".");
|
|
145
|
+
return { key, size, valid: typeof value === "string" && value.includes("=") && /^[A-Za-z_][A-Za-z0-9_.]*$/.test(key) };
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
export function validateAgentCliConfig(config = {}, type, label = "agent") {
|
|
149
|
+
const args = config.args === undefined ? [] : config.args;
|
|
150
|
+
const env = config.env === undefined ? {} : config.env;
|
|
151
|
+
if (!Array.isArray(args)) invalid(label, "args", "must be an array of strings");
|
|
152
|
+
for (let i = 0; i < args.length; i++) {
|
|
153
|
+
if (typeof args[i] !== "string" || args[i].includes("\0"))
|
|
154
|
+
invalid(label, `args[${i}]`, "must be a string without NUL");
|
|
155
|
+
}
|
|
156
|
+
if (!env || typeof env !== "object" || Array.isArray(env) ||
|
|
157
|
+
![Object.prototype, null].includes(Object.getPrototypeOf(env)))
|
|
158
|
+
invalid(label, "env", "must be a string-to-string object");
|
|
159
|
+
for (const [i, [key, value]] of Object.entries(env).entries()) {
|
|
160
|
+
if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(key)) invalid(label, `env entry[${i}]`, "has an invalid variable name");
|
|
161
|
+
if (/^CHORUS_/i.test(key)) invalid(label, `env entry[${i}]`, "cannot override managed CHORUS_* variables");
|
|
162
|
+
if (/^(CLAUDECODE|CLAUDE_CODE_ENTRYPOINT)$/i.test(key))
|
|
163
|
+
invalid(label, `env entry[${i}]`, "cannot override managed nested-Claude context variables");
|
|
164
|
+
if (typeof value !== "string" || value.includes("\0")) invalid(label, `env entry[${i}]`, "must have a string value without NUL");
|
|
165
|
+
}
|
|
166
|
+
const backend = canonicalType(type);
|
|
167
|
+
const controls = PROTECTED[backend];
|
|
168
|
+
const longs = new Set([...(controls?.long.split(" ") ?? []), "help", "version"]);
|
|
169
|
+
for (let i = 0; i < args.length; i++) {
|
|
170
|
+
if (args[i] === "--" || args[i] === "-") invalid(label, `args[${i}]`, "cannot contain an argument terminator or stdin prompt marker");
|
|
171
|
+
}
|
|
172
|
+
for (let i = 0; i < args.length; i++) {
|
|
173
|
+
const tok = args[i];
|
|
174
|
+
const option = optionAt(backend, args, i);
|
|
175
|
+
if (controls && !tok.startsWith("-"))
|
|
176
|
+
invalid(label, `args[${i}]`, "cannot supply a positional prompt or ambiguous value; unknown options require inline --option=value syntax (if supported by the CLI)");
|
|
177
|
+
if ((longs.has((option?.flag ?? tok.split("=", 1)[0]).replace(/^--/, ""))) ||
|
|
178
|
+
(!option && /^-[^-]/.test(tok) && `${controls?.short ?? ""}hVv`.includes(tok[1])))
|
|
179
|
+
invalid(label, `args[${i}]`, "conflicts with managed backend controls; use the dedicated Chorus settings or explicit foreground passthrough");
|
|
180
|
+
if (backend === "codex") {
|
|
181
|
+
const c = codexConfigAt(args, i);
|
|
182
|
+
if (c) {
|
|
183
|
+
if (!c.valid || /^(mcp_servers|sandbox[^.]*|approval_policy|approvals_reviewer|cwd|permissions|developer_instructions|model_instructions_file|experimental_instructions_file|base_instructions)(\.|$)/.test(c.key))
|
|
184
|
+
invalid(label, `args[${i}]`, "has an invalid or managed Codex config key");
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
if (option?.missing) invalid(label, `args[${i}]`, "requires a value before managed launch arguments");
|
|
188
|
+
i += (option?.size ?? 1) - 1;
|
|
189
|
+
}
|
|
190
|
+
return { args: [...args], env: { ...env } };
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// Windows child environments are case-insensitive, unlike an ordinary JS object
|
|
194
|
+
// (including injected test envs). Match Node's sorted-key selection if an inherited
|
|
195
|
+
// object contains duplicates; overlayAgentEnv removes collisions for overrides.
|
|
196
|
+
export function getAgentEnv(env, name, platform = process.platform) {
|
|
197
|
+
if (platform !== "win32") return env[name];
|
|
198
|
+
const key = Object.keys(env).sort().find((key) => key.toUpperCase() === name.toUpperCase());
|
|
199
|
+
return key === undefined ? undefined : env[key];
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
export function overlayAgentEnv(base, overrides = {}, platform = process.platform) {
|
|
203
|
+
const result = { ...base };
|
|
204
|
+
if (platform === "win32") {
|
|
205
|
+
for (const key of Object.keys(result)) {
|
|
206
|
+
if (/^CHORUS_/i.test(key) && key !== key.toUpperCase()) {
|
|
207
|
+
result[key.toUpperCase()] = result[key];
|
|
208
|
+
delete result[key];
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
for (const [key, value] of Object.entries(overrides)) {
|
|
213
|
+
if (platform === "win32") {
|
|
214
|
+
for (const old of Object.keys(result)) if (old.toLowerCase() === key.toLowerCase()) delete result[old];
|
|
215
|
+
}
|
|
216
|
+
// Canonical PATH spelling also makes the existing binary resolvers consistent.
|
|
217
|
+
const name = platform === "win32" && key.toUpperCase() === "PATH" ? "PATH" : key;
|
|
218
|
+
Object.defineProperty(result, name, { value, enumerable: true, writable: true, configurable: true });
|
|
219
|
+
}
|
|
220
|
+
return result;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// Deliberately small registry. See docs/DAEMON.md for verified CLI sources/forms.
|
|
224
|
+
const SINGLETONS = {
|
|
225
|
+
"claude-code": { "--model": "model", "--effort": "effort" },
|
|
226
|
+
codex: { "--model": "model", "-m": "model" },
|
|
227
|
+
kiro: { "--model": "model", "--effort": "effort" },
|
|
228
|
+
pi: { "--model": "model", "--thinking": "thinking", "--provider": "provider" },
|
|
229
|
+
opencode: { "--model": "model", "-m": "model" },
|
|
230
|
+
openclaw: { "--model": "model", "--thinking": "thinking" },
|
|
231
|
+
};
|
|
232
|
+
function singletonAt(type, args, i) {
|
|
233
|
+
if (type === "codex") {
|
|
234
|
+
const c = codexConfigAt(args, i);
|
|
235
|
+
if (c?.valid && ["model", "model_reasoning_effort"].includes(c.key)) return { key: c.key, size: c.size };
|
|
236
|
+
}
|
|
237
|
+
for (const [flag, key] of Object.entries(SINGLETONS[type] ?? {})) {
|
|
238
|
+
if (args[i] === flag) return { key, size: args[i + 1] === undefined || args[i + 1] === "--" ? 1 : 2 };
|
|
239
|
+
if (args[i].startsWith(`${flag}=`) || flag.length === 2 && args[i].startsWith(flag)) return { key, size: 1 };
|
|
240
|
+
}
|
|
241
|
+
return null;
|
|
242
|
+
}
|
|
243
|
+
// Only these command paths have a supported insertion scope. Walk known option
|
|
244
|
+
// arities, never token-search: a value named "exec"/"resume" is not a command.
|
|
245
|
+
const SUBCOMMANDS = {
|
|
246
|
+
codex: { exec: { resume: {} }, resume: {} },
|
|
247
|
+
kiro: { chat: {} },
|
|
248
|
+
openclaw: { agent: {} },
|
|
249
|
+
};
|
|
250
|
+
function foregroundScope(type, explicit) {
|
|
251
|
+
let commands = SUBCOMMANDS[type];
|
|
252
|
+
let start = 0;
|
|
253
|
+
if (!commands) return start;
|
|
254
|
+
for (let i = 0; i < explicit.length;) {
|
|
255
|
+
const token = explicit[i];
|
|
256
|
+
if (Object.hasOwn(commands, token)) {
|
|
257
|
+
start = ++i;
|
|
258
|
+
commands = commands[token];
|
|
259
|
+
if (!Object.keys(commands).length) break;
|
|
260
|
+
continue;
|
|
261
|
+
}
|
|
262
|
+
const option = optionAt(type, explicit, i);
|
|
263
|
+
if (option) {
|
|
264
|
+
if (option.missing) break;
|
|
265
|
+
i += option.size;
|
|
266
|
+
} else if (token.startsWith("--") && token.includes("=")) {
|
|
267
|
+
i++; // self-contained unknown option; no arity guess
|
|
268
|
+
} else break; // positional prompt/unknown command/ambiguous option
|
|
269
|
+
}
|
|
270
|
+
return start;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
export function planAgentArgs(type, configured, explicit = []) {
|
|
274
|
+
type = canonicalType(type);
|
|
275
|
+
// Chorus analysis ALWAYS ends at the first bare --, even for backends that
|
|
276
|
+
// might consume it as an option value. Forward the original tokens unchanged.
|
|
277
|
+
const terminator = explicit.indexOf("--");
|
|
278
|
+
const scan = explicit.slice(0, terminator < 0 ? explicit.length : terminator);
|
|
279
|
+
const start = foregroundScope(type, scan);
|
|
280
|
+
const supplied = new Set();
|
|
281
|
+
for (let i = 0; i < scan.length; i++) {
|
|
282
|
+
const boundary = optionAt(type, scan, i);
|
|
283
|
+
// Unknown separated options may consume ANY following token. Do not infer
|
|
284
|
+
// overrides beyond this point; still forward the entire explicit argv.
|
|
285
|
+
if (!boundary && scan[i].startsWith("-") &&
|
|
286
|
+
!(scan[i].startsWith("--") && scan[i].includes("="))) break;
|
|
287
|
+
const option = singletonAt(type, scan, i);
|
|
288
|
+
// Local root/parent options do not override options of the selected child
|
|
289
|
+
// command. Codex --config/-c is global and applies across command scopes.
|
|
290
|
+
const globalConfig = type === "codex" && boundary?.flag === "--config";
|
|
291
|
+
if (option && (i >= start || globalConfig)) supplied.add(option.key);
|
|
292
|
+
i += (boundary?.size ?? 1) - 1;
|
|
293
|
+
}
|
|
294
|
+
const kept = [];
|
|
295
|
+
for (let i = 0; i < configured.length; i++) {
|
|
296
|
+
const boundary = optionAt(type, configured, i);
|
|
297
|
+
const option = singletonAt(type, configured, i);
|
|
298
|
+
const size = boundary?.size ?? 1;
|
|
299
|
+
if (!option || !supplied.has(option.key)) kept.push(...configured.slice(i, i + size));
|
|
300
|
+
i += size - 1;
|
|
301
|
+
}
|
|
302
|
+
return {
|
|
303
|
+
args: [...explicit.slice(0, start), ...kept, ...explicit.slice(start)],
|
|
304
|
+
configuredArgs: kept,
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
export function mergeAgentArgs(type, configured, explicit = []) {
|
|
309
|
+
return planAgentArgs(type, configured, explicit).args;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
// cmd.exe parses even with shell:false. Until a fully tested cmd encoder exists,
|
|
313
|
+
// only simple configured tokens are supported with .cmd/.bat shims. Native exe
|
|
314
|
+
// and POSIX paths retain ALL literal tokens. Explicit foreground argv is unchanged.
|
|
315
|
+
export function assertConfiguredShimArgs(binPath, args, platform = process.platform, label = "agent") {
|
|
316
|
+
if (platform !== "win32" || !/\.(cmd|bat)$/i.test(binPath)) return;
|
|
317
|
+
if (/["%!^&|<>()\r\n]/.test(binPath))
|
|
318
|
+
invalid(label, "executable path", "cannot be passed literally through a Windows command shim; use a native executable");
|
|
319
|
+
for (let i = 0; i < args.length; i++) {
|
|
320
|
+
if (!args[i] || /[\s"'%!^&|<>()]/.test(args[i]))
|
|
321
|
+
invalid(label, `args[${i}]`, "cannot be passed literally through a Windows command shim; use a native executable");
|
|
322
|
+
}
|
|
323
|
+
}
|
package/cli/agent-launcher.mjs
CHANGED
|
@@ -15,9 +15,11 @@
|
|
|
15
15
|
// name/UUID and the resolved binary, nothing else.
|
|
16
16
|
|
|
17
17
|
import { spawn } from "node:child_process";
|
|
18
|
+
import { safeSpawnError } from "./launch-diagnostics.mjs";
|
|
18
19
|
import { statSync } from "node:fs";
|
|
19
20
|
import { win32 as pathWin32, posix as pathPosix } from "node:path";
|
|
20
21
|
import { resolveLaunchAgent } from "./credentials.mjs";
|
|
22
|
+
import { validateAgentCliConfig, overlayAgentEnv, getAgentEnv, planAgentArgs, assertConfiguredShimArgs } from "./agent-cli-config.mjs";
|
|
21
23
|
|
|
22
24
|
/**
|
|
23
25
|
* Launch agent-type → executable base name. Launch is a SUPERSET of daemon wake:
|
|
@@ -173,7 +175,7 @@ export function resolveBinaryPath(binName, deps = {}) {
|
|
|
173
175
|
const isWin = platform === "win32";
|
|
174
176
|
const p = isWin ? pathWin32 : pathPosix;
|
|
175
177
|
const names = isWin ? [`${binName}.cmd`, `${binName}.exe`, binName] : [binName];
|
|
176
|
-
const pathVar = env
|
|
178
|
+
const pathVar = getAgentEnv(env, "PATH", platform) || env.Path || "";
|
|
177
179
|
const dirs = pathVar.split(p.delimiter).filter(Boolean);
|
|
178
180
|
for (const dir of dirs) {
|
|
179
181
|
for (const name of names) {
|
|
@@ -197,7 +199,7 @@ export function resolveSpawnCommand(binPath, args, platform = process.platform,
|
|
|
197
199
|
const isWin = platform === "win32";
|
|
198
200
|
const lower = binPath.toLowerCase();
|
|
199
201
|
if (isWin && (lower.endsWith(".cmd") || lower.endsWith(".bat"))) {
|
|
200
|
-
const comspec = env
|
|
202
|
+
const comspec = getAgentEnv(env, "COMSPEC", platform) || "cmd.exe";
|
|
201
203
|
return { command: comspec, argv: ["/d", "/s", "/c", binPath, ...args] };
|
|
202
204
|
}
|
|
203
205
|
return { command: binPath, argv: args };
|
|
@@ -212,13 +214,20 @@ export function resolveSpawnCommand(binPath, args, platform = process.platform,
|
|
|
212
214
|
* @param {NodeJS.ProcessEnv} [baseEnv]
|
|
213
215
|
* @returns {NodeJS.ProcessEnv}
|
|
214
216
|
*/
|
|
215
|
-
export function buildChildEnv(agent, baseEnv = process.env) {
|
|
216
|
-
const childEnv =
|
|
217
|
+
export function buildChildEnv(agent, baseEnv = process.env, platform = process.platform) {
|
|
218
|
+
const childEnv = overlayAgentEnv(baseEnv, agent.env, platform);
|
|
217
219
|
if (agent.url) childEnv.CHORUS_URL = agent.url;
|
|
218
220
|
if (agent.apiKey) childEnv.CHORUS_API_KEY = agent.apiKey;
|
|
219
221
|
const profile = agent.agentUuid || agent.agentName;
|
|
220
222
|
if (profile) childEnv.CHORUS_AGENT_PROFILE = profile;
|
|
221
|
-
|
|
223
|
+
for (const key of Object.keys(childEnv)) {
|
|
224
|
+
if (key.toUpperCase() === "CHORUS_DAEMON_HEADLESS") delete childEnv[key];
|
|
225
|
+
}
|
|
226
|
+
if (agent.agentType === "claude-code" || agent.agentType === "claude") {
|
|
227
|
+
for (const key of Object.keys(childEnv)) {
|
|
228
|
+
if (["CLAUDECODE", "CLAUDE_CODE_ENTRYPOINT"].includes(key.toUpperCase())) delete childEnv[key];
|
|
229
|
+
}
|
|
230
|
+
}
|
|
222
231
|
return childEnv;
|
|
223
232
|
}
|
|
224
233
|
|
|
@@ -233,8 +242,11 @@ USAGE
|
|
|
233
242
|
|
|
234
243
|
Launches the agent's binary in the FOREGROUND with this agent's Chorus connection
|
|
235
244
|
injected into the child (CHORUS_URL / CHORUS_API_KEY / CHORUS_AGENT_PROFILE).
|
|
236
|
-
Everything after \`--\` is passed to the agent verbatim
|
|
237
|
-
|
|
245
|
+
Everything after \`--\` is passed to the agent verbatim. Recognized explicit model/
|
|
246
|
+
reasoning options suppress configured equivalents in the selected command scope.
|
|
247
|
+
Configured args precede explicit options after known commands (Codex exec, exec
|
|
248
|
+
resume, resume; Kiro chat; OpenClaw agent), otherwise they go first. Unknown
|
|
249
|
+
command grammars are not inferred. Analysis stops at the first bare \`--\`.
|
|
238
250
|
|
|
239
251
|
FLAGS
|
|
240
252
|
--name <name|uuid> Which configured agent to launch (default: the only one).
|
|
@@ -295,8 +307,18 @@ export async function runAgentLaunch(argv = [], opts = {}) {
|
|
|
295
307
|
return 1;
|
|
296
308
|
}
|
|
297
309
|
|
|
298
|
-
//
|
|
299
|
-
|
|
310
|
+
// Validate before binary discovery or spawn, against the effective --type.
|
|
311
|
+
let config;
|
|
312
|
+
try {
|
|
313
|
+
config = validateAgentCliConfig(agent, typeRes.type, agent.label);
|
|
314
|
+
} catch (e) {
|
|
315
|
+
err.write(`error: ${e.message}\n`);
|
|
316
|
+
return 1;
|
|
317
|
+
}
|
|
318
|
+
const childEnv = buildChildEnv({ ...agent, agentType: typeRes.type, env: config.env }, env, platform);
|
|
319
|
+
|
|
320
|
+
// 3. Locate the binary using this profile's effective PATH.
|
|
321
|
+
const binPath = resolveBinaryPath(typeRes.binary, { env: childEnv, platform, isFile: opts.isFile });
|
|
300
322
|
if (!binPath) {
|
|
301
323
|
err.write(
|
|
302
324
|
`error: could not find the \`${typeRes.binary}\` executable on PATH ` +
|
|
@@ -305,9 +327,15 @@ export async function runAgentLaunch(argv = [], opts = {}) {
|
|
|
305
327
|
return 1;
|
|
306
328
|
}
|
|
307
329
|
|
|
308
|
-
// 4.
|
|
309
|
-
const
|
|
310
|
-
|
|
330
|
+
// 4. Filter only configured recognized duplicates; explicit argv stays untouched.
|
|
331
|
+
const { args, configuredArgs } = planAgentArgs(typeRes.type, config.args, parsed.passthrough);
|
|
332
|
+
try {
|
|
333
|
+
assertConfiguredShimArgs(binPath, configuredArgs, platform, agent.label);
|
|
334
|
+
} catch (e) {
|
|
335
|
+
err.write(`error: ${e.message}\n`);
|
|
336
|
+
return 1;
|
|
337
|
+
}
|
|
338
|
+
const { command, argv: spawnArgv } = resolveSpawnCommand(binPath, args, platform, childEnv);
|
|
311
339
|
|
|
312
340
|
// Diagnostic — agent name/uuid + binary ONLY. Never the key or url userinfo.
|
|
313
341
|
out.write(`Launching ${agent.label} (${agent.agentUuid ?? "no uuid"}) → ${typeRes.binary}\n`);
|
|
@@ -321,13 +349,13 @@ export async function runAgentLaunch(argv = [], opts = {}) {
|
|
|
321
349
|
env: childEnv,
|
|
322
350
|
shell: false,
|
|
323
351
|
});
|
|
324
|
-
} catch (
|
|
325
|
-
err.write(`error: failed to launch ${typeRes.binary}: ${
|
|
352
|
+
} catch (error) {
|
|
353
|
+
err.write(`error: failed to launch ${typeRes.binary}: ${safeSpawnError(error)}\n`);
|
|
326
354
|
resolve(1);
|
|
327
355
|
return;
|
|
328
356
|
}
|
|
329
|
-
child.on("error", (
|
|
330
|
-
err.write(`error: ${typeRes.binary} failed to start: ${
|
|
357
|
+
child.on("error", (error) => {
|
|
358
|
+
err.write(`error: ${typeRes.binary} failed to start: ${safeSpawnError(error)}\n`);
|
|
331
359
|
resolve(1);
|
|
332
360
|
});
|
|
333
361
|
child.on("close", (code, signal) => {
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
// cli/child-exit.mjs
|
|
2
|
+
// One shared settlement path for every spawner's child process, so the five
|
|
3
|
+
// backends (pi / claude / codex / kiro / dsh) cannot drift on "when is the wake
|
|
4
|
+
// over?".
|
|
5
|
+
//
|
|
6
|
+
// WHY THIS EXISTS — `close` is not the same event as "the agent finished".
|
|
7
|
+
// Node emits `exit` when the child process itself is reaped, but `close` only
|
|
8
|
+
// once every stdio stream the child was given has been closed. A child that
|
|
9
|
+
// leaves a DETACHED DESCENDANT behind (a backgrounded server, a `nohup`'d
|
|
10
|
+
// helper) hands that descendant the SAME inherited pipes, so the pipes stay
|
|
11
|
+
// open after the child is long gone and `close` may never fire. A spawner that
|
|
12
|
+
// waits only for `close` therefore keeps reporting a finished wake as still
|
|
13
|
+
// `running` — the phantom `running` turn. Settling on `exit` fixes that.
|
|
14
|
+
//
|
|
15
|
+
// !!! THE GRACE IS NOT A WAKE TIMEOUT AND NOT A WATCHDOG !!!
|
|
16
|
+
// `stdioGraceMs` only starts counting AFTER the child process has ALREADY
|
|
17
|
+
// EXITED, and it bounds one thing only: how long we wait for that dead
|
|
18
|
+
// process's pipes to drain so a final stdout chunk is still parsed. It places
|
|
19
|
+
// no limit whatsoever on how long an agent may run — a wake that runs for
|
|
20
|
+
// hours is never interrupted, cancelled or "timed out" by this module. No
|
|
21
|
+
// wake-duration limit is introduced anywhere here; do not repurpose this timer
|
|
22
|
+
// into one.
|
|
23
|
+
|
|
24
|
+
/** Grace for an already-exited process's pipes to drain. NOT a wake timeout. */
|
|
25
|
+
export const DEFAULT_STDIO_GRACE_MS = 2000;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Resolve once with the child's exit code as soon as the process is KNOWN to be gone.
|
|
29
|
+
*
|
|
30
|
+
* • `close` first → resolve immediately (today's behaviour, zero regression).
|
|
31
|
+
* • `exit` first → wait up to `stdioGraceMs` for `close` (so a last stdout chunk
|
|
32
|
+
* is still parsed), then resolve with the exit code anyway.
|
|
33
|
+
*
|
|
34
|
+
* Settles exactly once and NEVER rejects. The grace timer is `unref`'d so it can
|
|
35
|
+
* never hold the daemon's event loop open.
|
|
36
|
+
*
|
|
37
|
+
* @param {import("node:child_process").ChildProcess} child
|
|
38
|
+
* @param {{ stdioGraceMs?: number, logger?: { warn?: (msg: string) => void }, label?: string }} [options]
|
|
39
|
+
* @returns {Promise<number | null>} the exit code (`null` when the child was signalled)
|
|
40
|
+
*/
|
|
41
|
+
export function awaitChildSettled(child, options = {}) {
|
|
42
|
+
const { stdioGraceMs = DEFAULT_STDIO_GRACE_MS, logger, label = "child" } = options;
|
|
43
|
+
|
|
44
|
+
return new Promise((resolve) => {
|
|
45
|
+
let settled = false;
|
|
46
|
+
let timer = null;
|
|
47
|
+
|
|
48
|
+
const settle = (code) => {
|
|
49
|
+
if (settled) return;
|
|
50
|
+
settled = true;
|
|
51
|
+
if (timer) {
|
|
52
|
+
clearTimeout(timer);
|
|
53
|
+
timer = null;
|
|
54
|
+
}
|
|
55
|
+
resolve(code ?? null);
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
child.on?.("close", (code) => settle(code));
|
|
59
|
+
|
|
60
|
+
child.on?.("exit", (code) => {
|
|
61
|
+
if (settled || timer) return;
|
|
62
|
+
// The process is gone; give its (possibly descendant-held) pipes a bounded
|
|
63
|
+
// moment to drain, then settle regardless. See the header: not a timeout.
|
|
64
|
+
timer = setTimeout(() => {
|
|
65
|
+
timer = null;
|
|
66
|
+
if (settled) return;
|
|
67
|
+
logger?.warn?.(
|
|
68
|
+
`[Chorus] ${label} exited (code ${code ?? null}) but stdio stayed open for ` +
|
|
69
|
+
`${stdioGraceMs}ms; settling on exit`
|
|
70
|
+
);
|
|
71
|
+
settle(code);
|
|
72
|
+
}, stdioGraceMs);
|
|
73
|
+
// Never keep the daemon's event loop alive for a dead process's pipes.
|
|
74
|
+
timer?.unref?.();
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
}
|
package/cli/claude-spawner.mjs
CHANGED
|
@@ -23,9 +23,12 @@
|
|
|
23
23
|
// carried per-turn by the wake-prompt preamble in prompts.mjs, not at the system level.
|
|
24
24
|
|
|
25
25
|
import { spawn } from "node:child_process";
|
|
26
|
+
import { safeSpawnError } from "./launch-diagnostics.mjs";
|
|
27
|
+
import { validateAgentCliConfig, overlayAgentEnv, getAgentEnv, assertConfiguredShimArgs } from "./agent-cli-config.mjs";
|
|
26
28
|
import { existsSync, statSync } from "node:fs";
|
|
27
29
|
import { homedir } from "node:os";
|
|
28
30
|
import { win32 as pathWin32, posix as pathPosix, join as pathJoin } from "node:path";
|
|
31
|
+
import { awaitChildSettled } from "./child-exit.mjs";
|
|
29
32
|
|
|
30
33
|
const NOOP_LOGGER = { info() {}, warn() {}, error() {} };
|
|
31
34
|
|
|
@@ -102,7 +105,7 @@ export function escapeCwd(cwd, platform = process.platform) {
|
|
|
102
105
|
export function transcriptPath(sessionId, cwd, deps = {}) {
|
|
103
106
|
const env = deps.env ?? process.env;
|
|
104
107
|
const platform = deps.platform ?? process.platform;
|
|
105
|
-
const configDir = env
|
|
108
|
+
const configDir = getAgentEnv(env, "CLAUDE_CONFIG_DIR", platform) || pathJoin(deps.home ?? getAgentEnv(env, "HOME", platform) ?? getAgentEnv(env, "USERPROFILE", platform) ?? homedir(), ".claude");
|
|
106
109
|
return pathJoin(configDir, "projects", escapeCwd(cwd, platform), `${sessionId}.jsonl`);
|
|
107
110
|
}
|
|
108
111
|
|
|
@@ -146,8 +149,9 @@ export function resolveClaudePath(deps = {}) {
|
|
|
146
149
|
});
|
|
147
150
|
|
|
148
151
|
// An explicit override always wins (set by the daemon if the user configured it).
|
|
149
|
-
|
|
150
|
-
|
|
152
|
+
const override = getAgentEnv(env, "CHORUS_CLAUDE_PATH", platform);
|
|
153
|
+
if (override && isFile(override)) {
|
|
154
|
+
return override;
|
|
151
155
|
}
|
|
152
156
|
|
|
153
157
|
// Use platform-correct path semantics so the resolver is testable for
|
|
@@ -155,7 +159,7 @@ export function resolveClaudePath(deps = {}) {
|
|
|
155
159
|
const isWin = platform === "win32";
|
|
156
160
|
const p = isWin ? pathWin32 : pathPosix;
|
|
157
161
|
const names = isWin ? ["claude.cmd", "claude.exe", "claude"] : ["claude"];
|
|
158
|
-
const pathVar = env
|
|
162
|
+
const pathVar = getAgentEnv(env, "PATH", platform) || env.Path || "";
|
|
159
163
|
const dirs = pathVar.split(p.delimiter).filter(Boolean);
|
|
160
164
|
for (const dir of dirs) {
|
|
161
165
|
for (const name of names) {
|
|
@@ -228,7 +232,7 @@ export function resolveSpawnCommand(claudePath, args, platform = process.platfor
|
|
|
228
232
|
const isWin = platform === "win32";
|
|
229
233
|
const lower = claudePath.toLowerCase();
|
|
230
234
|
if (isWin && (lower.endsWith(".cmd") || lower.endsWith(".bat"))) {
|
|
231
|
-
const comspec = env
|
|
235
|
+
const comspec = getAgentEnv(env, "COMSPEC", platform) || "cmd.exe";
|
|
232
236
|
// /d skip AutoRun, /s treat everything after /c literally, /c run then exit.
|
|
233
237
|
return { command: comspec, argv: ["/d", "/s", "/c", claudePath, ...args] };
|
|
234
238
|
}
|
|
@@ -289,6 +293,8 @@ export class ClaudeSpawner {
|
|
|
289
293
|
// can group-kill the tree; Windows does not. Injectable so a POSIX test host
|
|
290
294
|
// can exercise the Windows branch and vice versa.
|
|
291
295
|
this.platform = opts.platform ?? process.platform;
|
|
296
|
+
this.cliConfig = validateAgentCliConfig(opts.cliConfig, "claude-code", opts.label);
|
|
297
|
+
this.env = overlayAgentEnv(opts.env ?? process.env, this.cliConfig.env, this.platform);
|
|
292
298
|
}
|
|
293
299
|
|
|
294
300
|
/**
|
|
@@ -330,18 +336,19 @@ export class ClaudeSpawner {
|
|
|
330
336
|
return { sessionId: typeof id === "string" ? id : "", backendSessionId: null, exitCode: null, isNew: Boolean(isNew) };
|
|
331
337
|
}
|
|
332
338
|
|
|
333
|
-
const claudePath = this.claudePath ?? resolveClaudePath();
|
|
339
|
+
const claudePath = this.claudePath ?? resolveClaudePath({ env: this.env, platform: this.platform });
|
|
334
340
|
if (!claudePath) {
|
|
335
341
|
// No crash — surface visibly and resolve with a failure result.
|
|
336
342
|
this.logger.error("[Chorus] cannot locate the `claude` executable on PATH; skipping wake");
|
|
337
343
|
return { sessionId: id, backendSessionId: null, exitCode: null, isNew };
|
|
338
344
|
}
|
|
339
345
|
|
|
340
|
-
|
|
346
|
+
assertConfiguredShimArgs(claudePath, this.cliConfig.args, this.platform);
|
|
347
|
+
const args = [...buildArgs({ sessionId: id, isNew, mcpConfigPath, permissionMode: this.permissionMode }), ...this.cliConfig.args];
|
|
341
348
|
// On Windows, a .cmd/.bat shim must be run via cmd.exe /c (CreateProcess
|
|
342
349
|
// can't exec a script directly). resolveSpawnCommand keeps shell:false and
|
|
343
350
|
// passes argv as an array — no shell injection surface either way.
|
|
344
|
-
const { command, argv } = resolveSpawnCommand(claudePath, args);
|
|
351
|
+
const { command, argv } = resolveSpawnCommand(claudePath, args, this.platform, this.env);
|
|
345
352
|
|
|
346
353
|
// POSIX: spawn `detached: true` so the child becomes a PROCESS GROUP LEADER
|
|
347
354
|
// (its pgid === its pid). The interrupt path then signals the whole group via
|
|
@@ -353,7 +360,10 @@ export class ClaudeSpawner {
|
|
|
353
360
|
// stream and observe the exit. On Windows `detached` is NOT used: taskkill /T
|
|
354
361
|
// walks the tree by pid, and detached there only spawns a new console window.
|
|
355
362
|
const detached = (this.platform ?? process.platform) !== "win32";
|
|
356
|
-
const childEnv = { ...
|
|
363
|
+
const childEnv = { ...this.env, CHORUS_DAEMON_HEADLESS: "1" };
|
|
364
|
+
for (const key of Object.keys(childEnv)) {
|
|
365
|
+
if (["CLAUDECODE", "CLAUDE_CODE_ENTRYPOINT"].includes(key.toUpperCase())) delete childEnv[key];
|
|
366
|
+
}
|
|
357
367
|
if (this.creds) {
|
|
358
368
|
if (this.creds.url) childEnv.CHORUS_URL = this.creds.url;
|
|
359
369
|
if (this.creds.apiKey) childEnv.CHORUS_API_KEY = this.creds.apiKey;
|
|
@@ -379,8 +389,8 @@ export class ClaudeSpawner {
|
|
|
379
389
|
detached,
|
|
380
390
|
windowsHide: true,
|
|
381
391
|
});
|
|
382
|
-
} catch (
|
|
383
|
-
this.logger.error(`[Chorus] failed to spawn claude: ${
|
|
392
|
+
} catch (error) {
|
|
393
|
+
this.logger.error(`[Chorus] failed to spawn claude: ${safeSpawnError(error)}`);
|
|
384
394
|
resolve({ sessionId: id, backendSessionId: null, exitCode: null, isNew });
|
|
385
395
|
return;
|
|
386
396
|
}
|
|
@@ -429,16 +439,18 @@ export class ClaudeSpawner {
|
|
|
429
439
|
if (text) this.logger.warn(`[Chorus] claude stderr: ${text}`);
|
|
430
440
|
});
|
|
431
441
|
|
|
432
|
-
child.on("error", (
|
|
442
|
+
child.on("error", (error) => {
|
|
433
443
|
// e.g. ENOENT if the resolved path vanished — log, don't throw.
|
|
434
|
-
this.logger.error(`[Chorus] claude process error: ${
|
|
444
|
+
this.logger.error(`[Chorus] claude process error: ${safeSpawnError(error)}`);
|
|
435
445
|
// backendSessionId is the `--resume` anchor (`id`), NOT observedSessionId:
|
|
436
446
|
// a fork-on-resume claude can emit a new stream session_id, but the daemon
|
|
437
447
|
// resumes and files the transcript under `id`, so `id` is the resumable value.
|
|
438
448
|
resolve({ sessionId: observedSessionId, backendSessionId: id, exitCode: null, isNew });
|
|
439
449
|
});
|
|
440
450
|
|
|
441
|
-
|
|
451
|
+
// Settle on process exit, not only on stdio close: a detached descendant can
|
|
452
|
+
// inherit the pipes and keep `close` from ever firing (see cli/child-exit.mjs).
|
|
453
|
+
awaitChildSettled(child, { logger: this.logger, label: "claude" }).then((code) => {
|
|
442
454
|
if (code !== 0) {
|
|
443
455
|
this.logger.warn(`[Chorus] claude exited with code ${code}`);
|
|
444
456
|
}
|