@chorus-aidlc/chorus 0.12.0 → 0.12.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 +364 -363
- package/.next/standalone/.next/app-path-routes-manifest.json +43 -43
- package/.next/standalone/.next/build-manifest.json +5 -5
- package/.next/standalone/.next/prerender-manifest.json +43 -43
- package/.next/standalone/.next/react-loadable-manifest.json +3 -3
- 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 +2 -2
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/activity/page.js.nft.json +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 +2 -2
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/dashboard/[ideaUuid]/page.js.nft.json +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.js.nft.json +1 -1
- 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]/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.js.nft.json +1 -1
- 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 +1 -1
- package/.next/standalone/.next/server/app/_not-found.rsc +1 -1
- 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 +1 -1
- package/.next/standalone/.next/server/app/admin/companies/new.rsc +1 -1
- package/.next/standalone/.next/server/app/admin/companies/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/admin/companies.html +1 -1
- package/.next/standalone/.next/server/app/admin/companies.rsc +1 -1
- package/.next/standalone/.next/server/app/admin/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/admin.html +1 -1
- package/.next/standalone/.next/server/app/admin.rsc +1 -1
- 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_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_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/refresh/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/auth/session/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_client-reference-manifest.js +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/execution-state/route_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/events/notifications/route.js +6 -4
- 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 +7 -5
- 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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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/keepalive/route_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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/projects/[uuid]/activity/route_client-reference-manifest.js +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_client-reference-manifest.js +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]/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_client-reference-manifest.js +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/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/search/route_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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 +1 -1
- package/.next/standalone/.next/server/app/index.rsc +2 -2
- package/.next/standalone/.next/server/app/login/admin/page.js +2 -2
- package/.next/standalone/.next/server/app/login/admin/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/login/admin/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/login/admin.html +1 -1
- package/.next/standalone/.next/server/app/login/admin.rsc +1 -1
- package/.next/standalone/.next/server/app/login/callback/page.js +2 -2
- package/.next/standalone/.next/server/app/login/callback/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/login/callback/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/login/callback.html +1 -1
- package/.next/standalone/.next/server/app/login/callback.rsc +1 -1
- package/.next/standalone/.next/server/app/login/page.js +2 -2
- package/.next/standalone/.next/server/app/login/page.js.nft.json +1 -1
- 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 +1 -1
- package/.next/standalone/.next/server/app/login/pick-workspace.rsc +1 -1
- package/.next/standalone/.next/server/app/login/silent-refresh/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/login/silent-refresh.html +1 -1
- package/.next/standalone/.next/server/app/login/silent-refresh.rsc +1 -1
- package/.next/standalone/.next/server/app/login.html +1 -1
- 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 +1 -1
- package/.next/standalone/.next/server/app/onboarding.rsc +2 -2
- package/.next/standalone/.next/server/app/page.js +2 -2
- package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/projects.html +1 -1
- package/.next/standalone/.next/server/app/projects.rsc +2 -2
- package/.next/standalone/.next/server/app/settings.html +1 -1
- package/.next/standalone/.next/server/app/settings.rsc +3 -3
- package/.next/standalone/.next/server/app-paths-manifest.json +43 -43
- package/.next/standalone/.next/server/chunks/1596.js +2 -2
- package/.next/standalone/.next/server/chunks/2779.js +31 -0
- package/.next/standalone/.next/server/chunks/2961.js +1 -1
- package/.next/standalone/.next/server/chunks/3219.js +1 -1
- package/.next/standalone/.next/server/chunks/4292.js +1 -0
- package/.next/standalone/.next/server/chunks/4872.js +1 -1
- package/.next/standalone/.next/server/chunks/5538.js +1 -0
- package/.next/standalone/.next/server/chunks/6113.js +1 -1
- package/.next/standalone/.next/server/chunks/6207.js +1 -1
- package/.next/standalone/.next/server/chunks/7063.js +2 -2
- package/.next/standalone/.next/server/chunks/7160.js +1 -1
- package/.next/standalone/.next/server/chunks/7368.js +1 -1
- package/.next/standalone/.next/server/chunks/7515.js +1 -1
- package/.next/standalone/.next/server/chunks/8732.js +1 -0
- package/.next/standalone/.next/server/chunks/920.js +1 -1
- package/.next/standalone/.next/server/chunks/9273.js +1 -0
- package/.next/standalone/.next/server/chunks/937.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/middleware-react-loadable-manifest.js +1 -1
- package/.next/standalone/.next/server/pages/404.html +1 -1
- package/.next/standalone/.next/server/pages/500.html +1 -1
- package/.next/standalone/.next/server/pages-manifest.json +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/10344-2e9a9d767e2e8ed1.js +1 -0
- package/.next/standalone/.next/static/chunks/{33187.13c12f5c0821ac57.js → 33187.1328c15b9dab78a8.js} +1 -1
- package/.next/standalone/.next/static/chunks/{40867-04cc0d00205eaf9b.js → 46983-8bf90f1ffeb55957.js} +1 -1
- package/.next/standalone/.next/static/chunks/{32497-886aa4d3d7bf4967.js → 46999-f53da8f53fe1b8a9.js} +1 -1
- package/.next/standalone/.next/static/chunks/{4860.f4242c493fcf182d.js → 4860.e3d0dd79a4d37626.js} +1 -1
- package/.next/standalone/.next/static/chunks/{78917-2b959ab0a7f610b4.js → 78917-aa5bbff9248799a4.js} +1 -1
- package/.next/standalone/.next/static/chunks/85573-fb4d2cbd67612d47.js +1 -0
- package/.next/standalone/.next/static/chunks/{97784-7b90a17294840e32.js → 97784-42081b75f8cc6da8.js} +1 -1
- package/.next/standalone/.next/static/chunks/97868-55f18a05fe483d85.js +1 -0
- package/.next/standalone/.next/static/chunks/{99373.880b43de1fa6411f.js → 99373.cc6319fa4cf36081.js} +1 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/layout-b3a497ba5eb08036.js +1 -0
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/dashboard/page-d786f0c18a9c4f06.js +1 -0
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/documents/[documentUuid]/page-c68f1eda3779b448.js +1 -0
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/documents/{page-6620b9d7a2cc766f.js → page-e0935445535c28cb.js} +1 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/[proposalUuid]/page-f824632ff61a9fa7.js +1 -0
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/new/page-dbcb6e50fc4816c6.js +1 -0
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/page-1295bc505e727383.js +1 -0
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/tasks/[taskUuid]/{page-d5c3dde34d6291a8.js → page-ceeec49af0396432.js} +1 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/tasks/{page-0da08d8b425acb6a.js → page-1286afe43c086d6a.js} +1 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/settings/{page-44014947a679f91c.js → page-0fb1d51016f6bd56.js} +1 -1
- package/.next/standalone/.next/static/chunks/app/login/page-d2513f477211dd6f.js +1 -0
- package/.next/standalone/.next/static/chunks/app/onboarding/{page-9a41067d4c5d29d7.js → page-2936274fb252329e.js} +1 -1
- package/.next/standalone/.next/static/chunks/app/page-075afd218994d377.js +1 -0
- package/.next/standalone/.next/static/chunks/{webpack-1556cfd11f7e90d1.js → webpack-ed3555ea61243391.js} +1 -1
- package/.next/standalone/package.json +1 -1
- package/README.md +2 -2
- package/README.zh.md +2 -2
- package/cli/client-args.mjs +1 -1
- package/cli/codex-session-map.mjs +117 -0
- package/cli/codex-spawner.mjs +312 -0
- package/cli/daemon-agent.mjs +32 -6
- package/cli/daemon-banner.mjs +43 -5
- package/cli/daemon.mjs +133 -14
- package/cli/login.mjs +77 -34
- package/cli/spawner-select.mjs +30 -0
- package/cli/sse-listener.mjs +29 -1
- package/cli/upload-hooks.mjs +73 -8
- package/package.json +1 -1
- package/.next/standalone/.next/server/chunks/3371.js +0 -1
- package/.next/standalone/.next/server/chunks/345.js +0 -1
- package/.next/standalone/.next/server/chunks/4958.js +0 -1
- package/.next/standalone/.next/server/chunks/5581.js +0 -1
- package/.next/standalone/.next/server/chunks/7897.js +0 -1
- package/.next/standalone/.next/server/chunks/8245.js +0 -31
- package/.next/standalone/.next/static/chunks/42111-1935df3b0dab2095.js +0 -1
- package/.next/standalone/.next/static/chunks/6239-d78e6f830ce0a7f8.js +0 -1
- package/.next/standalone/.next/static/chunks/97868-9406a4014b667c2d.js +0 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/layout-f04d5fa070f15acd.js +0 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/dashboard/page-c4271886ef004611.js +0 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/documents/[documentUuid]/page-7a8b60de97bfbd29.js +0 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/[proposalUuid]/page-0a55289b2bc510c2.js +0 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/new/page-99639479cc98965f.js +0 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/page-5d09141beb5d6aee.js +0 -1
- package/.next/standalone/.next/static/chunks/app/login/page-e7493d55573a52f1.js +0 -1
- package/.next/standalone/.next/static/chunks/app/page-8b4baa950c78ffe7.js +0 -1
- /package/.next/standalone/.next/static/{v1yRpXkt1wNBkZMTE3tiz → GmBblfxcDziUENBiEap4B}/_buildManifest.js +0 -0
- /package/.next/standalone/.next/static/{v1yRpXkt1wNBkZMTE3tiz → GmBblfxcDziUENBiEap4B}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
// cli/codex-spawner.mjs
|
|
2
|
+
// Cross-platform headless Codex spawner — the `codex` counterpart to
|
|
3
|
+
// ClaudeSpawner, satisfying the SAME backend-agnostic Spawner.wake(...) contract
|
|
4
|
+
// so the daemon's wake pipeline (queue, waker, directed delivery, headless guard,
|
|
5
|
+
// reporters) stays backend-neutral.
|
|
6
|
+
//
|
|
7
|
+
// Codex diverges structurally from Claude (verified against codex-cli 0.142.3 +
|
|
8
|
+
// the ../codex source + a live `codex exec --json` run):
|
|
9
|
+
// • `codex exec --json` emits JSONL (one event per line); the prompt is read
|
|
10
|
+
// from STDIN (never argv). `codex exec resume <id> --json` continues a run.
|
|
11
|
+
// • The FIRST event is `{"type":"thread.started","thread_id":"<uuid>"}` — Codex
|
|
12
|
+
// GENERATES its own id (it does NOT accept a client `--session-id`). We capture
|
|
13
|
+
// it and persist anchor→thread_id (codex-session-map.mjs) so a later wake can
|
|
14
|
+
// `resume <thread_id>`. (serde: ThreadEvent tag="type", rename="thread.started";
|
|
15
|
+
// ThreadStartedEvent.thread_id: String — codex-rs/exec/src/exec_events.rs.)
|
|
16
|
+
// • No `--mcp-config`: MCP comes from the user's ~/.codex/config.toml; the daemon
|
|
17
|
+
// key reaches it via the configured bearer_token_env_var (default
|
|
18
|
+
// CHORUS_API_KEY) exported into the child ENV — never argv.
|
|
19
|
+
// • Permission is a SANDBOX mode, not a tool allowlist.
|
|
20
|
+
//
|
|
21
|
+
// Reuses claude-spawner's platform-neutral helpers: parseNdjsonChunk (NDJSON
|
|
22
|
+
// stream parse) and the PATH-walk shape of resolveClaudePath.
|
|
23
|
+
|
|
24
|
+
import { spawn } from "node:child_process";
|
|
25
|
+
import { statSync } from "node:fs";
|
|
26
|
+
import { win32 as pathWin32, posix as pathPosix } from "node:path";
|
|
27
|
+
import { parseNdjsonChunk } from "./claude-spawner.mjs";
|
|
28
|
+
import { getThreadId as defaultGetThreadId, setThreadId as defaultSetThreadId } from "./codex-session-map.mjs";
|
|
29
|
+
|
|
30
|
+
const NOOP_LOGGER = { info() {}, warn() {}, error() {} };
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* @typedef {Object} Spawner
|
|
34
|
+
* @property {(params: {
|
|
35
|
+
* prompt: string, sessionId: string|null, isNew: boolean,
|
|
36
|
+
* mcpConfigPath?: string, cwd?: string,
|
|
37
|
+
* onMessage?: (obj: any) => void,
|
|
38
|
+
* onChild?: (child: import("node:child_process").ChildProcess) => void
|
|
39
|
+
* }) => Promise<{ sessionId: string, exitCode: number|null, isNew: boolean }>} wake
|
|
40
|
+
* The backend-agnostic wake contract. ClaudeSpawner and CodexSpawner both
|
|
41
|
+
* implement it; the daemon injects one based on the resolved agent type.
|
|
42
|
+
*/
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Map the daemon's backend-agnostic permission mode to a Codex sandbox posture.
|
|
46
|
+
* The expression is SUBCOMMAND-AWARE because the two surfaces differ (verified
|
|
47
|
+
* against codex 0.142.3): the top-level `codex exec` accepts `--sandbox <mode>`,
|
|
48
|
+
* but `codex exec resume` does NOT — passing `--sandbox` there errors with exit 2.
|
|
49
|
+
* yolo → --dangerously-bypass-approvals-and-sandbox (valid on BOTH exec and
|
|
50
|
+
* resume; full autonomy)
|
|
51
|
+
* chorus → exec: --sandbox read-only
|
|
52
|
+
* resume: -c sandbox_mode="read-only" (the `-c` config override is how
|
|
53
|
+
* `codex exec resume` accepts a sandbox mode; `sandbox_mode` is a real
|
|
54
|
+
* config key, value spelled `read-only` per protocol/src/config_types.rs,
|
|
55
|
+
* confirmed via `--strict-config`).
|
|
56
|
+
* Anything other than yolo falls back to the restricted read-only posture.
|
|
57
|
+
* @param {"yolo"|"chorus"|undefined} permissionMode
|
|
58
|
+
* @param {{ resume?: boolean }} [opts] resume:true selects the `codex exec resume` surface.
|
|
59
|
+
* @returns {string[]}
|
|
60
|
+
*/
|
|
61
|
+
export function sandboxFlags(permissionMode, opts = {}) {
|
|
62
|
+
if (permissionMode === "yolo") return ["--dangerously-bypass-approvals-and-sandbox"];
|
|
63
|
+
// restricted read-only posture, expressed per subcommand:
|
|
64
|
+
return opts.resume ? ["-c", 'sandbox_mode="read-only"'] : ["--sandbox", "read-only"];
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Build the argv for a headless codex run. Prompt is NEVER here — it goes over
|
|
69
|
+
* stdin. `--skip-git-repo-check` lets a non-repo cwd still run.
|
|
70
|
+
* @param {{ isNew: boolean, threadId?: string|null, permissionMode?: "yolo"|"chorus" }} o
|
|
71
|
+
* @returns {string[]}
|
|
72
|
+
*/
|
|
73
|
+
export function buildCodexArgs({ isNew, threadId, permissionMode }) {
|
|
74
|
+
if (!isNew && threadId) {
|
|
75
|
+
const sandbox = sandboxFlags(permissionMode, { resume: true });
|
|
76
|
+
return ["exec", "resume", threadId, "--json", ...sandbox, "--skip-git-repo-check"];
|
|
77
|
+
}
|
|
78
|
+
const sandbox = sandboxFlags(permissionMode);
|
|
79
|
+
return ["exec", "--json", ...sandbox, "--skip-git-repo-check"];
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Extract the Codex thread id from a stream event, or null. Accepts the live
|
|
84
|
+
* `thread.started` shape (authoritative) and the on-disk rollout `session_meta`
|
|
85
|
+
* shape as a defensive fallback.
|
|
86
|
+
* @param {any} obj
|
|
87
|
+
* @returns {string|null}
|
|
88
|
+
*/
|
|
89
|
+
export function extractThreadId(obj) {
|
|
90
|
+
if (!obj || typeof obj !== "object") return null;
|
|
91
|
+
if (obj.type === "thread.started" && typeof obj.thread_id === "string") return obj.thread_id;
|
|
92
|
+
if (obj.type === "session_meta" && obj.payload && typeof obj.payload.id === "string") {
|
|
93
|
+
return obj.payload.id;
|
|
94
|
+
}
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Resolve the real `codex` executable WITHOUT a shell — same approach as
|
|
100
|
+
* resolveClaudePath. On Windows the bin may be `codex.cmd` (npm shim), which
|
|
101
|
+
* `spawn` can't exec directly without shell:true; we walk PATH for the platform
|
|
102
|
+
* candidates. `CHORUS_CODEX_PATH` overrides.
|
|
103
|
+
* @param {{ env?: NodeJS.ProcessEnv, platform?: NodeJS.Platform, isFile?: (p: string) => boolean }} [deps]
|
|
104
|
+
* @returns {string | null}
|
|
105
|
+
*/
|
|
106
|
+
export function resolveCodexPath(deps = {}) {
|
|
107
|
+
const env = deps.env ?? process.env;
|
|
108
|
+
const platform = deps.platform ?? process.platform;
|
|
109
|
+
const isFile =
|
|
110
|
+
deps.isFile ??
|
|
111
|
+
((p) => {
|
|
112
|
+
try {
|
|
113
|
+
return statSync(p).isFile();
|
|
114
|
+
} catch {
|
|
115
|
+
return false;
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
if (env.CHORUS_CODEX_PATH && isFile(env.CHORUS_CODEX_PATH)) {
|
|
120
|
+
return env.CHORUS_CODEX_PATH;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const isWin = platform === "win32";
|
|
124
|
+
const p = isWin ? pathWin32 : pathPosix;
|
|
125
|
+
const names = isWin ? ["codex.cmd", "codex.exe", "codex"] : ["codex"];
|
|
126
|
+
const pathVar = env.PATH || env.Path || "";
|
|
127
|
+
const dirs = pathVar.split(p.delimiter).filter(Boolean);
|
|
128
|
+
for (const dir of dirs) {
|
|
129
|
+
for (const name of names) {
|
|
130
|
+
const candidate = p.join(dir, name);
|
|
131
|
+
if (isFile(candidate)) return candidate;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return null;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Resolve the actual command + argv to spawn. On Windows a `.cmd`/`.bat` shim is
|
|
139
|
+
* not a PE executable, so it must run via `cmd.exe /d /s /c <path> ...args`; we
|
|
140
|
+
* keep shell:false and pass argv as an array (no shell word-splitting/injection).
|
|
141
|
+
* @param {string} codexPath @param {string[]} args
|
|
142
|
+
* @param {NodeJS.Platform} [platform] @param {NodeJS.ProcessEnv} [env]
|
|
143
|
+
* @returns {{ command: string, argv: string[] }}
|
|
144
|
+
*/
|
|
145
|
+
export function resolveSpawnCommand(codexPath, args, platform = process.platform, env = process.env) {
|
|
146
|
+
const isWin = platform === "win32";
|
|
147
|
+
const lower = codexPath.toLowerCase();
|
|
148
|
+
if (isWin && (lower.endsWith(".cmd") || lower.endsWith(".bat"))) {
|
|
149
|
+
const comspec = env.ComSpec || env.COMSPEC || "cmd.exe";
|
|
150
|
+
return { command: comspec, argv: ["/d", "/s", "/c", codexPath, ...args] };
|
|
151
|
+
}
|
|
152
|
+
return { command: codexPath, argv: args };
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* @typedef {Object} CodexSpawnerOptions
|
|
157
|
+
* @property {string} [codexPath] Resolved codex path (resolved lazily if omitted).
|
|
158
|
+
* @property {(o: object) => any} [spawnImpl] Injectable spawn (tests).
|
|
159
|
+
* @property {{info(m:string):void,warn(m:string):void,error(m:string):void}} [logger]
|
|
160
|
+
* @property {"chorus"|"yolo"} [permissionMode] Maps to a Codex sandbox posture.
|
|
161
|
+
* @property {{ url: string, apiKey: string }} [creds] Daemon creds — apiKey is exported
|
|
162
|
+
* into the child env under the user config's bearer_token_env_var (default CHORUS_API_KEY).
|
|
163
|
+
* @property {NodeJS.Platform} [platform] Injectable for tests; gates POSIX `detached`.
|
|
164
|
+
* @property {(anchor: string) => string|null} [getThreadIdFn] Injectable session-map read.
|
|
165
|
+
* @property {(anchor: string, threadId: string) => void} [setThreadIdFn] Injectable session-map write.
|
|
166
|
+
*/
|
|
167
|
+
|
|
168
|
+
export class CodexSpawner {
|
|
169
|
+
/** @param {CodexSpawnerOptions} [opts] */
|
|
170
|
+
constructor(opts = {}) {
|
|
171
|
+
this.codexPath = opts.codexPath ?? null;
|
|
172
|
+
this.spawnImpl = opts.spawnImpl ?? spawn;
|
|
173
|
+
this.logger = opts.logger ?? NOOP_LOGGER;
|
|
174
|
+
this.permissionMode = opts.permissionMode ?? "chorus";
|
|
175
|
+
this.creds = opts.creds ?? null;
|
|
176
|
+
this.platform = opts.platform ?? process.platform;
|
|
177
|
+
this.getThreadIdFn = opts.getThreadIdFn ?? defaultGetThreadId;
|
|
178
|
+
this.setThreadIdFn = opts.setThreadIdFn ?? defaultSetThreadId;
|
|
179
|
+
this.resolveCodexPathFn = opts.resolveCodexPathFn ?? resolveCodexPath;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Spawn a headless Codex run. Resolves when the subprocess exits. The prompt is
|
|
184
|
+
* written to stdin (never argv). `sessionId` is the Chorus anchor (direct idea
|
|
185
|
+
* uuid, or entity uuid). Codex owns its session id, so we IGNORE the passed
|
|
186
|
+
* `isNew`/`mcpConfigPath` and decide new-vs-resume from the persisted
|
|
187
|
+
* anchor→thread_id map: a recorded thread id → `resume`, otherwise a fresh run.
|
|
188
|
+
*
|
|
189
|
+
* @param {{ prompt: string, sessionId: string|null, isNew?: boolean, mcpConfigPath?: string,
|
|
190
|
+
* cwd?: string, onMessage?: (obj: any) => void,
|
|
191
|
+
* onChild?: (child: import("node:child_process").ChildProcess) => void }} params
|
|
192
|
+
* @returns {Promise<{ sessionId: string, exitCode: number|null, isNew: boolean }>}
|
|
193
|
+
*/
|
|
194
|
+
async wake({ prompt, sessionId, cwd, onMessage, onChild }) {
|
|
195
|
+
const anchor = typeof sessionId === "string" ? sessionId : "";
|
|
196
|
+
|
|
197
|
+
// new-vs-resume is OWNED by this backend (Codex session model), not the
|
|
198
|
+
// waker's Claude transcript probe: a recorded thread id means resume.
|
|
199
|
+
const knownThreadId = anchor ? this.getThreadIdFn(anchor) : null;
|
|
200
|
+
const isNew = !knownThreadId;
|
|
201
|
+
|
|
202
|
+
const codexPath = this.codexPath ?? this.resolveCodexPathFn();
|
|
203
|
+
if (!codexPath) {
|
|
204
|
+
// No crash — surface visibly and resolve with a failure result.
|
|
205
|
+
this.logger.error("[Chorus] cannot locate the `codex` executable on PATH; skipping wake");
|
|
206
|
+
return { sessionId: anchor, exitCode: null, isNew };
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
const args = buildCodexArgs({ isNew, threadId: knownThreadId, permissionMode: this.permissionMode });
|
|
210
|
+
const { command, argv } = resolveSpawnCommand(codexPath, args, this.platform);
|
|
211
|
+
|
|
212
|
+
// POSIX: detached process group so the interrupt path can group-kill the tree
|
|
213
|
+
// (codex exec forks child shells for tools). Windows uses taskkill /T. stdio
|
|
214
|
+
// stays piped — prompt over stdin + NDJSON stdout parse are unaffected.
|
|
215
|
+
const detached = this.platform !== "win32";
|
|
216
|
+
|
|
217
|
+
// Daemon key via ENV under the var the user's [mcp_servers.chorus] references
|
|
218
|
+
// (bearer_token_env_var, default CHORUS_API_KEY) — NEVER argv. Merged over the
|
|
219
|
+
// inherited env so PATH / model auth (Bedrock profile) / CODEX_HOME survive.
|
|
220
|
+
const childEnv = { ...process.env, CHORUS_DAEMON_HEADLESS: "1" };
|
|
221
|
+
if (this.creds && this.creds.apiKey) childEnv.CHORUS_API_KEY = this.creds.apiKey;
|
|
222
|
+
|
|
223
|
+
return new Promise((resolve) => {
|
|
224
|
+
let child;
|
|
225
|
+
try {
|
|
226
|
+
child = this.spawnImpl(command, argv, {
|
|
227
|
+
cwd: cwd ?? process.cwd(),
|
|
228
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
229
|
+
env: childEnv,
|
|
230
|
+
shell: false,
|
|
231
|
+
detached,
|
|
232
|
+
windowsHide: true,
|
|
233
|
+
});
|
|
234
|
+
} catch (err) {
|
|
235
|
+
this.logger.error(`[Chorus] failed to spawn codex: ${err}`);
|
|
236
|
+
resolve({ sessionId: anchor, exitCode: null, isNew });
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// Hand the live child to the caller (interrupt registry) before resolving.
|
|
241
|
+
// Never let a throwing callback escape into the spawn path.
|
|
242
|
+
if (onChild) {
|
|
243
|
+
try {
|
|
244
|
+
onChild(child);
|
|
245
|
+
} catch (err) {
|
|
246
|
+
this.logger.warn(`[Chorus] onChild handler threw: ${err}`);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
let stdoutBuf = "";
|
|
251
|
+
let observedThreadId = knownThreadId || null;
|
|
252
|
+
|
|
253
|
+
child.stdout?.setEncoding?.("utf8");
|
|
254
|
+
child.stdout?.on("data", (chunk) => {
|
|
255
|
+
stdoutBuf = parseNdjsonChunk(
|
|
256
|
+
stdoutBuf,
|
|
257
|
+
String(chunk),
|
|
258
|
+
(obj) => {
|
|
259
|
+
const tid = extractThreadId(obj);
|
|
260
|
+
if (tid) observedThreadId = tid;
|
|
261
|
+
if (onMessage) {
|
|
262
|
+
try {
|
|
263
|
+
onMessage(obj);
|
|
264
|
+
} catch (err) {
|
|
265
|
+
this.logger.warn(`[Chorus] onMessage handler threw: ${err}`);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
},
|
|
269
|
+
(msg) => this.logger.warn(`[Chorus] ${msg}`)
|
|
270
|
+
);
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
child.stderr?.setEncoding?.("utf8");
|
|
274
|
+
child.stderr?.on("data", (chunk) => {
|
|
275
|
+
const text = String(chunk).trim();
|
|
276
|
+
if (text) this.logger.warn(`[Chorus] codex stderr: ${text}`);
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
child.on("error", (err) => {
|
|
280
|
+
this.logger.error(`[Chorus] codex process error: ${err}`);
|
|
281
|
+
resolve({ sessionId: observedThreadId || anchor, exitCode: null, isNew });
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
child.on("close", (code) => {
|
|
285
|
+
if (code !== 0) {
|
|
286
|
+
this.logger.warn(`[Chorus] codex exited with code ${code}`);
|
|
287
|
+
}
|
|
288
|
+
// Persist anchor→thread_id only on a fresh, successful run that produced a
|
|
289
|
+
// new id — so a later wake for this anchor resumes it. Best-effort; the
|
|
290
|
+
// session map swallows its own IO errors.
|
|
291
|
+
if (code === 0 && isNew && anchor && observedThreadId) {
|
|
292
|
+
this.setThreadIdFn(anchor, observedThreadId);
|
|
293
|
+
}
|
|
294
|
+
resolve({ sessionId: observedThreadId || anchor, exitCode: code, isNew });
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
// Guard against an ASYNC stdin error (EPIPE) so it never becomes an
|
|
298
|
+
// uncaughtException that kills the daemon.
|
|
299
|
+
child.stdin?.on?.("error", (err) => {
|
|
300
|
+
this.logger.warn(`[Chorus] codex stdin error (ignored): ${err}`);
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
// Feed the prompt over stdin, then close it so the model runs.
|
|
304
|
+
try {
|
|
305
|
+
child.stdin?.write(prompt);
|
|
306
|
+
child.stdin?.end();
|
|
307
|
+
} catch (err) {
|
|
308
|
+
this.logger.warn(`[Chorus] failed writing prompt to codex stdin: ${err}`);
|
|
309
|
+
}
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
}
|
package/cli/daemon-agent.mjs
CHANGED
|
@@ -1,15 +1,41 @@
|
|
|
1
1
|
// cli/daemon-agent.mjs
|
|
2
|
-
// Pure resolution + validation of the daemon's `--agent <type>` selection.
|
|
3
|
-
//
|
|
4
|
-
// (
|
|
2
|
+
// Pure resolution + validation of the daemon's `--agent <type>` selection.
|
|
3
|
+
// `claude-code` (the default) and `codex` are both implemented backends
|
|
4
|
+
// (add-daemon-codex-backend cashed in the reserved `codex` slot). Resolving an
|
|
5
5
|
// unknown value is a hard error (no silent fallback). Zero dependencies.
|
|
6
6
|
|
|
7
|
-
/** The agent backends the daemon recognizes.
|
|
8
|
-
|
|
7
|
+
/** The agent backends the daemon recognizes. Both are implemented (claude-code
|
|
8
|
+
* via ClaudeSpawner, codex via CodexSpawner — see spawner-select.mjs). */
|
|
9
|
+
export const KNOWN_AGENTS = ["claude-code", "codex"];
|
|
9
10
|
|
|
10
11
|
/** The default agent backend when neither --agent nor CHORUS_AGENT is set. */
|
|
11
12
|
export const DEFAULT_AGENT = "claude-code";
|
|
12
13
|
|
|
14
|
+
/**
|
|
15
|
+
* Per-backend CLI descriptor: the executable name the daemon resolves/spawns and
|
|
16
|
+
* the env var that overrides its path. Drives the startup banner's "CLI" row and
|
|
17
|
+
* the not-found warning so they name the SELECTED backend (not always `claude`).
|
|
18
|
+
* Unknown / undefined falls back to the default (claude-code) descriptor.
|
|
19
|
+
* @param {string} agentType
|
|
20
|
+
* @returns {{ name: string, envVar: string }}
|
|
21
|
+
*/
|
|
22
|
+
export function backendCli(agentType) {
|
|
23
|
+
if (agentType === "codex") return { name: "codex", envVar: "CHORUS_CODEX_PATH" };
|
|
24
|
+
return { name: "claude", envVar: "CHORUS_CLAUDE_PATH" };
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Map the resolved agent backend to the `clientType` the daemon self-reports to
|
|
29
|
+
* the server (and that the connection registry + presence UI display). The server
|
|
30
|
+
* gates this against DAEMON_CLIENT_TYPES, so the values MUST match: `codex` →
|
|
31
|
+
* `codex`, `claude-code` → `claude_code`. Anything else falls back to claude_code.
|
|
32
|
+
* @param {string} agentType
|
|
33
|
+
* @returns {string}
|
|
34
|
+
*/
|
|
35
|
+
export function backendClientType(agentType) {
|
|
36
|
+
return agentType === "codex" ? "codex" : "claude_code";
|
|
37
|
+
}
|
|
38
|
+
|
|
13
39
|
/**
|
|
14
40
|
* Resolve the agent type from flag → env → default, and validate it.
|
|
15
41
|
* Precedence: explicit `--agent` flag > CHORUS_AGENT env > DEFAULT_AGENT.
|
|
@@ -31,7 +57,7 @@ export function resolveAgentType(flags, env) {
|
|
|
31
57
|
value: raw,
|
|
32
58
|
error:
|
|
33
59
|
`Unknown --agent "${raw}". Accepted: ${KNOWN_AGENTS.join(", ")}. ` +
|
|
34
|
-
`(
|
|
60
|
+
`(Default is ${DEFAULT_AGENT}.)`,
|
|
35
61
|
};
|
|
36
62
|
}
|
|
37
63
|
return { ok: true, agent: raw };
|
package/cli/daemon-banner.mjs
CHANGED
|
@@ -6,7 +6,10 @@
|
|
|
6
6
|
//
|
|
7
7
|
// SECURITY: the banner shows the credential SOURCE, never the raw API key
|
|
8
8
|
// (owner decision: no masking needed because the key is simply not displayed).
|
|
9
|
-
// Zero dependencies — ships in the npm
|
|
9
|
+
// Zero dependencies (beyond the pure backendCli descriptor) — ships in the npm
|
|
10
|
+
// package alongside chorus.mjs.
|
|
11
|
+
|
|
12
|
+
import { backendCli } from "./daemon-agent.mjs";
|
|
10
13
|
|
|
11
14
|
/**
|
|
12
15
|
* @typedef {Object} BannerInfo
|
|
@@ -16,8 +19,8 @@
|
|
|
16
19
|
* @property {string} agentUuid authenticated agent uuid.
|
|
17
20
|
* @property {"yolo"|"chorus"} permissionMode
|
|
18
21
|
* @property {string} credentialSource resolved credential source (flag/env/login-file/…).
|
|
19
|
-
* @property {string} agentType local agent backend (
|
|
20
|
-
* @property {string|null}
|
|
22
|
+
* @property {string} agentType local agent backend (claude-code | codex) — drives the CLI row label.
|
|
23
|
+
* @property {string|null} cliPath resolved path of the SELECTED backend's CLI, or null when not found.
|
|
21
24
|
* @property {string} [connection] connection state line (default "connecting…").
|
|
22
25
|
* @property {string} [configPath] absolute path to the daemon.json the CLI reads.
|
|
23
26
|
* @property {boolean} [configExists] whether that daemon.json exists on disk.
|
|
@@ -39,7 +42,12 @@ export function bannerRows(info) {
|
|
|
39
42
|
info.permissionMode === "yolo"
|
|
40
43
|
? "YOLO ⚠ (full autonomy — Bash/write/any command)"
|
|
41
44
|
: "chorus-only (Chorus MCP tools only)";
|
|
42
|
-
|
|
45
|
+
// The CLI row names the SELECTED backend (claude-code → "claude", codex →
|
|
46
|
+
// "codex") so a `--agent codex` run never mislabels itself as claude.
|
|
47
|
+
const cli = backendCli(info.agentType);
|
|
48
|
+
const cliValue = info.cliPath
|
|
49
|
+
? `found: ${info.cliPath}`
|
|
50
|
+
: `NOT FOUND — install \`${cli.name}\` or set ${cli.envVar}`;
|
|
43
51
|
const rows = [
|
|
44
52
|
["Version", `chorus v${info.version}`],
|
|
45
53
|
["Server", info.url],
|
|
@@ -48,7 +56,7 @@ export function bannerRows(info) {
|
|
|
48
56
|
["Permission", permission],
|
|
49
57
|
["Credentials", `source: ${info.credentialSource}`],
|
|
50
58
|
["Connection", info.connection ?? "connecting…"],
|
|
51
|
-
[
|
|
59
|
+
[`${cli.name} CLI`, cliValue],
|
|
52
60
|
];
|
|
53
61
|
// Config file row — shown only when the path is known. Tells the operator
|
|
54
62
|
// exactly which daemon.json the CLI read (and whether it exists), so a
|
|
@@ -60,6 +68,36 @@ export function bannerRows(info) {
|
|
|
60
68
|
return rows;
|
|
61
69
|
}
|
|
62
70
|
|
|
71
|
+
/**
|
|
72
|
+
* The prominent warning shown at startup when the SELECTED backend's executable
|
|
73
|
+
* cannot be resolved. Mirrors `yoloWarningLine()`'s loud single-line style so a
|
|
74
|
+
* missing binary is visible in an unattended / systemd journal immediately,
|
|
75
|
+
* rather than only when a wake later fails. The daemon stays non-fatal — it still
|
|
76
|
+
* subscribes. Names the backend's own binary + override env var (claude /
|
|
77
|
+
* CHORUS_CLAUDE_PATH, or codex / CHORUS_CODEX_PATH).
|
|
78
|
+
* @param {string} agentType
|
|
79
|
+
* @returns {string}
|
|
80
|
+
*/
|
|
81
|
+
export function agentNotFoundWarningLine(agentType) {
|
|
82
|
+
const { name, envVar } = backendCli(agentType);
|
|
83
|
+
return (
|
|
84
|
+
`⚠ ${name} CLI NOT FOUND on PATH — wakes will FAIL until you install \`${name}\` ` +
|
|
85
|
+
`or set ${envVar}. For a systemd/boot service, ensure the unit's PATH ` +
|
|
86
|
+
"includes the directory holding the binary (e.g. ~/.local/bin). The daemon will " +
|
|
87
|
+
"still subscribe, but every task dispatch errors until this is fixed."
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Back-compat alias — the original claude-only warning. Delegates to
|
|
93
|
+
* {@link agentNotFoundWarningLine} for the default claude-code backend so older
|
|
94
|
+
* imports keep working.
|
|
95
|
+
* @returns {string}
|
|
96
|
+
*/
|
|
97
|
+
export function claudeNotFoundWarningLine() {
|
|
98
|
+
return agentNotFoundWarningLine("claude-code");
|
|
99
|
+
}
|
|
100
|
+
|
|
63
101
|
/**
|
|
64
102
|
* Format the startup banner. On a TTY, draws a Unicode box; otherwise emits
|
|
65
103
|
* plain `label: value` lines (no box-drawing chars, no width math) so piped
|