@chorus-aidlc/chorus 0.16.4 → 0.17.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 +511 -511
- package/.next/standalone/.next/app-path-routes-manifest.json +47 -47
- package/.next/standalone/.next/build-manifest.json +6 -6
- package/.next/standalone/.next/prerender-manifest.json +42 -42
- package/.next/standalone/.next/react-loadable-manifest.json +1 -1
- package/.next/standalone/.next/required-server-files.json +4 -4
- package/.next/standalone/.next/server/app/(dashboard)/project-groups/[uuid]/page.js +2 -2
- 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]/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.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 +2 -2
- 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 +2 -2
- 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 +3 -3
- 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.js +2 -2
- 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 +5 -5
- package/.next/standalone/.next/server/app/admin/companies/[uuid]/page.js +2 -2
- package/.next/standalone/.next/server/app/admin/companies/[uuid]/page.js.nft.json +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.js +2 -2
- package/.next/standalone/.next/server/app/admin/companies/new/page.js.nft.json +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 +7 -7
- package/.next/standalone/.next/server/app/admin/companies/page.js +2 -2
- package/.next/standalone/.next/server/app/admin/companies/page.js.nft.json +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 +2 -2
- package/.next/standalone/.next/server/app/admin/companies.rsc +7 -7
- package/.next/standalone/.next/server/app/admin/page.js +2 -2
- package/.next/standalone/.next/server/app/admin/page.js.nft.json +1 -1
- 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 +7 -7
- package/.next/standalone/.next/server/app/api/admin/companies/[uuid]/route.js +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.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.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.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 +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.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.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.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.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.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.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.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.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.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.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.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.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 +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_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon/directory-request/report/route.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 +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 +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 +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 +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 +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.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 +9 -3
- 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.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 +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 +5 -5
- 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.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.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.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.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.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.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.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 +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.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.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.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.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.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.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.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 +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 +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.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.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.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.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.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.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.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.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.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/favicon.ico/route.js +1 -1
- package/.next/standalone/.next/server/app/index.html +2 -2
- package/.next/standalone/.next/server/app/index.rsc +6 -6
- 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 +2 -2
- package/.next/standalone/.next/server/app/login/admin.rsc +6 -6
- 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 +2 -2
- package/.next/standalone/.next/server/app/login/callback.rsc +6 -6
- 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.js +2 -2
- package/.next/standalone/.next/server/app/login/pick-workspace/page.js.nft.json +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 +6 -6
- package/.next/standalone/.next/server/app/login.html +2 -2
- package/.next/standalone/.next/server/app/login.rsc +6 -6
- 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 +6 -6
- package/.next/standalone/.next/server/app/page.js +2 -2
- 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 +7 -7
- package/.next/standalone/.next/server/app/settings.html +2 -2
- package/.next/standalone/.next/server/app/settings.rsc +7 -7
- package/.next/standalone/.next/server/app-paths-manifest.json +47 -47
- package/.next/standalone/.next/server/chunks/1073.js +1 -0
- package/.next/standalone/.next/server/chunks/1114.js +1 -0
- package/.next/standalone/.next/server/chunks/1267.js +1 -0
- package/.next/standalone/.next/server/chunks/1318.js +1 -1
- package/.next/standalone/.next/server/chunks/1559.js +2 -2
- package/.next/standalone/.next/server/chunks/2570.js +2 -2
- package/.next/standalone/.next/server/chunks/2572.js +1 -1
- package/.next/standalone/.next/server/chunks/2940.js +1 -1
- package/.next/standalone/.next/server/chunks/2961.js +1 -1
- package/.next/standalone/.next/server/chunks/3197.js +1 -1
- package/.next/standalone/.next/server/chunks/378.js +4 -4
- 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/{5351.js → 5737.js} +13 -9
- package/.next/standalone/.next/server/chunks/6113.js +1 -1
- package/.next/standalone/.next/server/chunks/6145.js +1 -0
- package/.next/standalone/.next/server/chunks/6487.js +1 -0
- package/.next/standalone/.next/server/chunks/6506.js +1 -1
- package/.next/standalone/.next/server/chunks/6515.js +2 -2
- package/.next/standalone/.next/server/chunks/6753.js +3 -3
- 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/7770.js +1 -0
- package/.next/standalone/.next/server/chunks/{4394.js → 7822.js} +1 -1
- package/.next/standalone/.next/server/chunks/8454.js +1 -1
- package/.next/standalone/.next/server/chunks/8586.js +1 -0
- 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 -0
- 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/next-font-manifest.js +1 -1
- package/.next/standalone/.next/server/next-font-manifest.json +1 -1
- 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/server/src/middleware.js +2 -2
- package/.next/standalone/.next/static/chunks/{11595.a6268c75ca8a2163.js → 11595.32f7dedc4fd7e3e1.js} +1 -1
- package/.next/standalone/.next/static/chunks/11998-27dcf858173fc015.js +1 -0
- package/.next/standalone/.next/static/chunks/12070-426bb88f5179812b.js +1 -0
- package/.next/standalone/.next/static/chunks/17409-67dbc0a3f4cbc207.js +1 -0
- package/.next/standalone/.next/static/chunks/26494-5a04e150431b0233.js +1 -0
- package/.next/standalone/.next/static/chunks/{31308-fda6febfb2882a28.js → 31308-bb4a97b3f39c22dd.js} +1 -1
- package/.next/standalone/.next/static/chunks/{33456.16ff7edf00137539.js → 33456.87f86ce6041405e0.js} +1 -1
- package/.next/standalone/.next/static/chunks/38366.fb931fab9c756890.js +1 -0
- package/.next/standalone/.next/static/chunks/4166-85352630c29e2c2b.js +1 -0
- package/.next/standalone/.next/static/chunks/{4860.9e06848eb531e667.js → 4860.9457e021394e9399.js} +1 -1
- package/.next/standalone/.next/static/chunks/{65096-f756aac39efad7a3.js → 65096-8295f53f97c40d47.js} +1 -1
- package/.next/standalone/.next/static/chunks/65807-086d83649f593a5a.js +1 -0
- package/.next/standalone/.next/static/chunks/79919-56796c262f51fa82.js +1 -0
- package/.next/standalone/.next/static/chunks/94643-87ee1ede6d955937.js +1 -0
- package/.next/standalone/.next/static/chunks/{99373.81b79c91858f9099.js → 99373.aed267aa48c5bdd0.js} +1 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/layout-9219c4de1012f0fb.js +1 -0
- package/.next/standalone/.next/static/chunks/app/(dashboard)/project-groups/[uuid]/{page-974781e4886529f8.js → page-82e90e222d6bc547.js} +1 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/activity/page-f1eccb50d38d8982.js +1 -0
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/dashboard/page-f4810f1b9f39d1ae.js +1 -0
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/documents/[documentUuid]/page-721d2152f1a28c88.js +1 -0
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/documents/page-9bcff40805f39b25.js +1 -0
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/graph/{page-fdd617457730a116.js → page-f31ad2eebe257628.js} +1 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/[proposalUuid]/page-a4fb04068539c4ce.js +1 -0
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/new/page-b1d2af10e9bc7e09.js +1 -0
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/page-2cb245b0602a3c85.js +1 -0
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/tasks/[taskUuid]/{page-58b48aa0a11603c3.js → page-53ce4468844cc84f.js} +1 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/tasks/{page-286faced32c6133f.js → page-1c374d19e8046d9a.js} +1 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/page-31d6f8e82c7f5366.js +1 -0
- package/.next/standalone/.next/static/chunks/app/(dashboard)/settings/page-32bff791b19a0a58.js +1 -0
- package/.next/standalone/.next/static/chunks/app/_not-found/{page-166b410da84336d4.js → page-b9d672df79b35e87.js} +1 -1
- package/.next/standalone/.next/static/chunks/app/admin/companies/[uuid]/{page-b2458ed001dc8177.js → page-56118c51122ad639.js} +1 -1
- package/.next/standalone/.next/static/chunks/app/admin/companies/new/page-4e20deb41357171c.js +1 -0
- package/.next/standalone/.next/static/chunks/app/admin/companies/page-0632f245bf9c1c27.js +1 -0
- package/.next/standalone/.next/static/chunks/app/admin/layout-725ab2331c642f36.js +1 -0
- package/.next/standalone/.next/static/chunks/app/admin/{page-0cc8cf246db43e5d.js → page-5a0271dd2b8b36fd.js} +1 -1
- package/.next/standalone/.next/static/chunks/app/{layout-985054e973f66999.js → layout-098288cec4490c5d.js} +1 -1
- package/.next/standalone/.next/static/chunks/app/login/admin/page-c8e40259e5d3d9e0.js +1 -0
- package/.next/standalone/.next/static/chunks/app/login/callback/page-527652f6c1a39274.js +1 -0
- package/.next/standalone/.next/static/chunks/app/login/{page-9b34375d1b5579d7.js → page-0a16a64855b771ef.js} +1 -1
- package/.next/standalone/.next/static/chunks/app/login/pick-workspace/page-47375a86e2375202.js +1 -0
- package/.next/standalone/.next/static/chunks/app/onboarding/{page-5c82cf3abd856301.js → page-d082f9b60ad03057.js} +1 -1
- package/.next/standalone/.next/static/chunks/app/{page-79e2d32e69788bd2.js → page-91dbf7dfd85f805f.js} +1 -1
- package/.next/standalone/.next/static/chunks/main-app-1a7cacecc8900a4d.js +1 -0
- package/.next/standalone/.next/static/chunks/{webpack-4d1cc14b13e247b6.js → webpack-e2e0ef50652d5791.js} +1 -1
- package/.next/standalone/.next/static/css/1d9cf83f50b6db00.css +1 -0
- package/.next/standalone/package.json +2 -1
- package/.next/standalone/public/chorus-plugin/.claude-plugin/plugin.json +1 -1
- package/.next/standalone/public/chorus-plugin/bin/chorus-api.sh +44 -1
- package/.next/standalone/public/chorus-plugin/bin/on-session-start.sh +4 -3
- package/.next/standalone/public/chorus-plugin/bin/tests/test-mcp-cli-delegation.sh +244 -0
- package/.next/standalone/public/chorus-plugin/skills/brainstorm/SKILL.md +1 -1
- package/.next/standalone/public/chorus-plugin/skills/chorus/SKILL.md +19 -1
- package/.next/standalone/public/chorus-plugin/skills/chorus-cli/SKILL.md +57 -0
- package/.next/standalone/public/chorus-plugin/skills/develop/SKILL.md +2 -2
- package/.next/standalone/public/chorus-plugin/skills/docs/SKILL.md +1 -1
- package/.next/standalone/public/chorus-plugin/skills/idea/SKILL.md +2 -2
- package/.next/standalone/public/chorus-plugin/skills/openspec-aware/SKILL.md +85 -42
- package/.next/standalone/public/chorus-plugin/skills/orchestrate/SKILL.md +1 -1
- package/.next/standalone/public/chorus-plugin/skills/proposal/SKILL.md +2 -2
- package/.next/standalone/public/chorus-plugin/skills/quick-dev/SKILL.md +1 -1
- package/.next/standalone/public/chorus-plugin/skills/review/SKILL.md +1 -1
- package/.next/standalone/public/chorus-plugin/skills/yolo/SKILL.md +3 -3
- package/.next/standalone/public/dsh-credentials.sh +20 -127
- package/.next/standalone/public/install-codex.sh +21 -406
- package/.next/standalone/public/install-kiro.sh +20 -344
- package/.next/standalone/public/install-opencode.sh +20 -275
- 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 +57 -0
- package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-develop/SKILL.md +2 -2
- 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 +2 -2
- package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-openspec-aware/SKILL.md +85 -42
- package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-orchestrate/SKILL.md +1 -1
- package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-proposal/SKILL.md +2 -2
- package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-quick-dev/SKILL.md +1 -1
- package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-review/SKILL.md +1 -1
- package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-yolo/SKILL.md +3 -3
- package/.next/standalone/public/kiro-plugin/bin/chorus-api.sh +44 -1
- package/.next/standalone/public/kiro-plugin/bin/on-agent-spawn.sh +6 -4
- package/.next/standalone/public/kiro-plugin/manifest.txt +42 -0
- package/.next/standalone/public/skill/brainstorm-chorus/SKILL.md +1 -1
- package/.next/standalone/public/skill/chorus/SKILL.md +19 -1
- package/.next/standalone/public/skill/code-reviewer-chorus/SKILL.md +1 -1
- package/.next/standalone/public/skill/develop-chorus/SKILL.md +1 -1
- package/.next/standalone/public/skill/docs-chorus/SKILL.md +1 -1
- package/.next/standalone/public/skill/idea-chorus/SKILL.md +2 -2
- package/.next/standalone/public/skill/orchestrate-chorus/SKILL.md +1 -1
- package/.next/standalone/public/skill/proposal-chorus/SKILL.md +1 -1
- package/.next/standalone/public/skill/proposal-reviewer-chorus/SKILL.md +1 -1
- package/.next/standalone/public/skill/quick-dev-chorus/SKILL.md +1 -1
- package/.next/standalone/public/skill/review-chorus/SKILL.md +1 -1
- package/.next/standalone/public/skill/task-reviewer-chorus/SKILL.md +1 -1
- package/.next/standalone/public/skill/yolo-chorus/SKILL.md +1 -1
- package/.next/standalone/public/test-dsh-credentials.sh +22 -38
- package/.next/standalone/public/test-install-codex.sh +31 -79
- package/.next/standalone/server.js +1 -1
- package/README.ja.md +4 -2
- package/README.ko.md +4 -2
- package/README.md +4 -2
- package/README.zh.md +4 -2
- package/chorus.mjs +35 -1
- package/cli/agent-backend-prompt.mjs +3 -2
- package/cli/agents.mjs +329 -0
- package/cli/chorus-client.mjs +69 -0
- package/cli/claude-spawner.mjs +56 -15
- package/cli/codex-spawner.mjs +11 -6
- package/cli/credentials.mjs +190 -4
- package/cli/daemon-agent.mjs +26 -2
- package/cli/daemon-config.mjs +27 -2
- package/cli/daemon-service.mjs +120 -33
- package/cli/daemon.mjs +128 -22
- package/cli/dsh-spawner.mjs +7 -0
- package/cli/init/adapters.mjs +137 -0
- package/cli/init/agent-type-map.mjs +60 -0
- package/cli/init/chorus-plugin-consts.mjs +16 -0
- package/cli/init/codex-mcp-config.mjs +183 -0
- package/cli/init/contracts.mjs +122 -0
- package/cli/init/detect.mjs +97 -0
- package/cli/init/file-template.mjs +248 -0
- package/cli/init/install-methods.mjs +569 -0
- package/cli/init/registry.mjs +74 -0
- package/cli/init/run-command.mjs +30 -0
- package/cli/init/select.mjs +111 -0
- package/cli/init/steps/credential-seed.mjs +751 -0
- package/cli/init/steps/daemon-setup.mjs +246 -0
- package/cli/init/steps/plugin-install.mjs +37 -0
- package/cli/init-args.mjs +140 -0
- package/cli/init.mjs +243 -0
- package/cli/kiro-spawner.mjs +5 -0
- package/cli/mcp-args.mjs +280 -0
- package/cli/mcp.mjs +164 -0
- package/cli/spawner-select.mjs +45 -2
- package/cli/waker.mjs +89 -38
- package/package.json +2 -1
- package/.next/standalone/.env +0 -18
- package/.next/standalone/.next/server/chunks/3594.js +0 -1
- package/.next/standalone/.next/server/chunks/4545.js +0 -1
- package/.next/standalone/.next/server/chunks/5205.js +0 -1
- package/.next/standalone/.next/server/chunks/6207.js +0 -1
- package/.next/standalone/.next/server/chunks/6667.js +0 -1
- package/.next/standalone/.next/server/chunks/6995.js +0 -1
- package/.next/standalone/.next/server/chunks/7091.js +0 -1
- package/.next/standalone/.next/server/chunks/9793.js +0 -1
- package/.next/standalone/.next/static/chunks/19887-b805e1dcee8c367b.js +0 -1
- package/.next/standalone/.next/static/chunks/29108-5a11eea003f4cc11.js +0 -1
- package/.next/standalone/.next/static/chunks/38366.e6e0132b8ba873d6.js +0 -1
- package/.next/standalone/.next/static/chunks/53073-a7ed20af6538a178.js +0 -1
- package/.next/standalone/.next/static/chunks/6603-e70ddeab6ad09c50.js +0 -1
- package/.next/standalone/.next/static/chunks/78917-1b59cbb806b3ecfc.js +0 -1
- package/.next/standalone/.next/static/chunks/82751-3e161e1d8dbda3ac.js +0 -1
- package/.next/standalone/.next/static/chunks/94643-ffa140f765c73daf.js +0 -1
- package/.next/standalone/.next/static/chunks/99366-425e9ef22e60e3e2.js +0 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/layout-b742c51c0a764daf.js +0 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/activity/page-20632dbec5a6dbc0.js +0 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/dashboard/page-f636e00c28f425ea.js +0 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/documents/[documentUuid]/page-c004f1a194af7fa5.js +0 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/documents/page-425acbe9ade5fa83.js +0 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/[proposalUuid]/page-b9eb4e0692996657.js +0 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/new/page-d5b222f379b2e8ca.js +0 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/page-0a6c2d0e1b68e0e4.js +0 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/page-9d79e285b6fd2f8d.js +0 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/settings/page-1507a761e67c2aa9.js +0 -1
- package/.next/standalone/.next/static/chunks/app/admin/companies/new/page-e35dce890d6dfd8d.js +0 -1
- package/.next/standalone/.next/static/chunks/app/admin/companies/page-ef720c2b0856166c.js +0 -1
- package/.next/standalone/.next/static/chunks/app/admin/layout-c66ce38cbd88982a.js +0 -1
- package/.next/standalone/.next/static/chunks/app/login/admin/page-f032b6db3bd20a2c.js +0 -1
- package/.next/standalone/.next/static/chunks/app/login/callback/page-ec23211506e688ee.js +0 -1
- package/.next/standalone/.next/static/chunks/app/login/pick-workspace/page-7e4664af2c787d08.js +0 -1
- package/.next/standalone/.next/static/chunks/main-app-ec87f2c9ef083ff1.js +0 -1
- package/.next/standalone/.next/static/css/5f52bd39b284ccdf.css +0 -1
- /package/.next/standalone/.next/static/{6sHDgeKioa0SJR1MAbcYG → _s4RZW3efB1g0lrKgLiZ7}/_buildManifest.js +0 -0
- /package/.next/standalone/.next/static/{6sHDgeKioa0SJR1MAbcYG → _s4RZW3efB1g0lrKgLiZ7}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,751 @@
|
|
|
1
|
+
// cli/init/steps/credential-seed.mjs
|
|
2
|
+
// The `once`-scoped step that captures Chorus credentials for `chorus init` and
|
|
3
|
+
// seeds them into the centralized daemon config (~/.chorus/daemon.json). It loops
|
|
4
|
+
// the init SELECTION (ctx.selection) and captures ONE Chorus key per selected
|
|
5
|
+
// agent, writing each as its own `agents[]` entry tagged with the daemon agentType
|
|
6
|
+
// its adapter maps to (cli/init/agent-type-map.mjs — claude→claude-code, codex,
|
|
7
|
+
// kiro, everything else→offline). This is how one `chorus init` run wires several
|
|
8
|
+
// agents into a single daemon at once (daemon-multi-agent).
|
|
9
|
+
//
|
|
10
|
+
// It reuses the existing, tested credential plumbing:
|
|
11
|
+
// - validateAndFetchIdentity (cli/chorus-client.mjs) to validate each key
|
|
12
|
+
// - appendAgentConfig (cli/login.mjs) to APPEND each validated agent to
|
|
13
|
+
// `agents[]` without disturbing any other agent (migration + dedup handled
|
|
14
|
+
// there), all through the MERGE-SAFE updateDaemonConfig writer that preserves
|
|
15
|
+
// yoloAckAt / cwds / sigintTimeoutMs.
|
|
16
|
+
//
|
|
17
|
+
// It writes credentials ONLY into `agents[]` — the flat top-level url/apiKey
|
|
18
|
+
// (+ identity) agent config is DEPRECATED and is no longer written here (writing
|
|
19
|
+
// both duplicated the first agent: once flat, once in agents[]). Single-credential
|
|
20
|
+
// consumers still resolve fine: `resolveCredentials` (cli/credentials.mjs) falls
|
|
21
|
+
// back to `agents[0]` when the flat pair is absent, and the multi-agent resolver
|
|
22
|
+
// reads `agents[]` directly.
|
|
23
|
+
//
|
|
24
|
+
// dsh EXCEPTION — a SECOND credential sink: when a selected agent is DeepSeek
|
|
25
|
+
// Harness (`dsh`), this step ALSO seeds CHORUS_URL + CHORUS_API_KEY +
|
|
26
|
+
// CHORUS_AGENT_PROFILE into `$DSH_HOME/.env` (see writeDshCredentialsEnv). That
|
|
27
|
+
// file is dsh's ESTABLISHED
|
|
28
|
+
// credential channel (formerly written by the now-retired public/dsh-credentials.sh):
|
|
29
|
+
// dsh scrubs credential-shaped env from tool subprocesses, so the dsh doc-mirror
|
|
30
|
+
// wrapper (packages/chorus-dsh/bin/chorus-mcp-call.mjs) reads it via node:util
|
|
31
|
+
// parseEnv when the `chorus` CLI is absent from PATH. daemon.json alone does NOT
|
|
32
|
+
// reach that wrapper, hence the dual write. It is dsh-ONLY — no other agent gets
|
|
33
|
+
// a .env — and is NOT a general per-agent secret mechanism.
|
|
34
|
+
//
|
|
35
|
+
// Key handling: keys are validated then written 0600 (via updateDaemonConfig) and
|
|
36
|
+
// never echoed. A subsequent selected agent is NEVER given the first agent's key —
|
|
37
|
+
// on a non-TTY where its key can't be captured, the agent is REPORTED as still
|
|
38
|
+
// needing one rather than silently reusing an identity.
|
|
39
|
+
//
|
|
40
|
+
// Runs BEFORE plugin-install (order 10 < 20) so a machine is authenticated before
|
|
41
|
+
// its agents are wired.
|
|
42
|
+
|
|
43
|
+
import { mkdirSync, readFileSync, renameSync, writeFileSync } from "node:fs";
|
|
44
|
+
import { homedir } from "node:os";
|
|
45
|
+
import { dirname, join } from "node:path";
|
|
46
|
+
import { parseEnv } from "node:util";
|
|
47
|
+
|
|
48
|
+
import { STEP_SCOPES, OUTCOME_ACTIONS } from "../contracts.mjs";
|
|
49
|
+
import {
|
|
50
|
+
prompt as defaultPrompt,
|
|
51
|
+
appendAgentConfig as defaultAppendAgentConfig,
|
|
52
|
+
} from "../../login.mjs";
|
|
53
|
+
import { resolveInstallCwds as defaultResolveInstallCwds } from "../../daemon-install-config.mjs";
|
|
54
|
+
import { validateAndFetchIdentity } from "../../chorus-client.mjs";
|
|
55
|
+
import { agentTypeForSelection, isWakeableAgentType } from "../agent-type-map.mjs";
|
|
56
|
+
|
|
57
|
+
const STEP_ID = "credential-seed";
|
|
58
|
+
const { SEEDED, SKIPPED, FAILED } = OUTCOME_ACTIONS;
|
|
59
|
+
const out = (action, detail, extra) => ({ stepId: STEP_ID, action, detail, ...(extra ?? {}) });
|
|
60
|
+
|
|
61
|
+
/** A non-empty trimmed string, or undefined. */
|
|
62
|
+
function nonEmpty(value) {
|
|
63
|
+
return typeof value === "string" && value.trim() ? value.trim() : undefined;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Whether an init selection id is the DeepSeek Harness (dsh). dsh needs a SECOND
|
|
68
|
+
* credential sink beyond ~/.chorus/daemon.json — see {@link writeDshCredentialsEnv}.
|
|
69
|
+
* We gate on the selection id, NOT the daemon agentType: dsh maps to the shared
|
|
70
|
+
* "offline" agentType (agent-type-map.mjs) alongside opencode/openclaw/pi, so the
|
|
71
|
+
* agentType cannot single dsh out. The id can.
|
|
72
|
+
* @param {string} id
|
|
73
|
+
*/
|
|
74
|
+
function isDshSelection(id) {
|
|
75
|
+
return id === "dsh";
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Resolve $DSH_HOME the same way dsh (and the retired public/dsh-credentials.sh)
|
|
80
|
+
* did: `env.DSH_HOME` trimmed if set, else `~/.dsh`.
|
|
81
|
+
* @param {Record<string, string | undefined>} env
|
|
82
|
+
*/
|
|
83
|
+
function resolveDshHome(env) {
|
|
84
|
+
return nonEmpty(env.DSH_HOME) ?? join(homedir(), ".dsh");
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Merge-preserving upsert of CHORUS_URL + CHORUS_API_KEY into `$DSH_HOME/.env`,
|
|
89
|
+
* faithfully taking over what the RETIRED public/dsh-credentials.sh used to write.
|
|
90
|
+
*
|
|
91
|
+
* This is dsh's ESTABLISHED credential channel — NOT a new general per-agent
|
|
92
|
+
* secret write. dsh scrubs credential-shaped variables from tool subprocesses, so
|
|
93
|
+
* its doc-mirror wrapper (packages/chorus-dsh/bin/chorus-mcp-call.mjs) reads the
|
|
94
|
+
* credential keys (CHORUS_URL / CHORUS_API_KEY) from `$DSH_HOME/.env` via node:util
|
|
95
|
+
* `parseEnv` whenever the `chorus` CLI is absent from PATH (e.g. invoked via `npx`
|
|
96
|
+
* rather than the documented `npm install -g @chorus-aidlc/chorus@0.17.0`
|
|
97
|
+
* global-install path). Only a `dsh` selection ever reaches this writer; every
|
|
98
|
+
* other agent gets no .env.
|
|
99
|
+
*
|
|
100
|
+
* CHORUS_AGENT_PROFILE (the agent's UUID) is written here too, but for a DIFFERENT
|
|
101
|
+
* reason than the credentials: it is NOT credential-shaped, so dsh does NOT scrub
|
|
102
|
+
* it — dsh loads `$DSH_HOME/.env` into the session, and the profile reaches tools
|
|
103
|
+
* (including the wrapper) directly on `process.env`. Persisting it here is what lets
|
|
104
|
+
* `chorus agents add` skip the manual `export CHORUS_AGENT_PROFILE=…` hint for dsh
|
|
105
|
+
* (init.mjs profileExportHint), and pins WHICH agent dsh acts as when several are
|
|
106
|
+
* configured (the wrapper then delegates `chorus mcp call --agent <profile>`).
|
|
107
|
+
*
|
|
108
|
+
* Behavior (mirrors the old shell writer):
|
|
109
|
+
* - Preserves every unrelated line verbatim.
|
|
110
|
+
* - Upserts CHORUS_URL / CHORUS_API_KEY, plus CHORUS_AGENT_PROFILE when provided
|
|
111
|
+
* (replacing an existing line in place — with or without an `export ` prefix,
|
|
112
|
+
* and collapsing any duplicates — else appending). Idempotent: a re-run with
|
|
113
|
+
* the same values reproduces the file.
|
|
114
|
+
* - Creates `$DSH_HOME` + the file if absent. Atomic write (temp + rename) at
|
|
115
|
+
* mode 0600.
|
|
116
|
+
*
|
|
117
|
+
* The secret is only ever written into the 0600 file — never argv, never a log.
|
|
118
|
+
* (The profile is a UUID, not a secret.)
|
|
119
|
+
*
|
|
120
|
+
* @param {{ dshHome: string, url: string, apiKey: string, agentProfile?: string }} args
|
|
121
|
+
* @param {{
|
|
122
|
+
* read?: (p: string) => string,
|
|
123
|
+
* write?: (p: string, c: string, o: object) => void,
|
|
124
|
+
* mkdir?: (p: string, o: object) => void,
|
|
125
|
+
* rename?: (from: string, to: string) => void,
|
|
126
|
+
* }} [deps]
|
|
127
|
+
* @returns {string} the .env path written
|
|
128
|
+
*/
|
|
129
|
+
export function writeDshCredentialsEnv({ dshHome, url, apiKey, agentProfile }, deps = {}) {
|
|
130
|
+
// Managed keys: the two credential keys always; CHORUS_AGENT_PROFILE (the agent's
|
|
131
|
+
// UUID) when one was resolved. Only managed keys are rewritten — any other line
|
|
132
|
+
// (including a stale CHORUS_AGENT_PROFILE when none is provided this run) is kept
|
|
133
|
+
// verbatim by the shared upsert, so the unrelated-line contract holds.
|
|
134
|
+
const managed = { CHORUS_URL: url, CHORUS_API_KEY: apiKey };
|
|
135
|
+
if (nonEmpty(agentProfile)) managed.CHORUS_AGENT_PROFILE = agentProfile.trim();
|
|
136
|
+
return upsertDotenvFile({ path: join(dshHome, ".env"), managed }, deps);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Merge-preserving upsert of a set of managed `KEY=value` pairs into a dotenv file — the
|
|
141
|
+
* shared core of {@link writeDshCredentialsEnv} and {@link writeCodexEnvFile}. Replaces each
|
|
142
|
+
* managed key IN PLACE at its first occurrence (dropping any later duplicate, tolerating an
|
|
143
|
+
* `export ` prefix), preserves every unrelated line verbatim, and appends any managed key not
|
|
144
|
+
* already present in stable `Object.keys(managed)` order. Atomic write: temp file (0600) in
|
|
145
|
+
* the same dir, then rename over the target; the parent dir is created if absent. Idempotent:
|
|
146
|
+
* a re-run with the same `managed` reproduces byte-identical content.
|
|
147
|
+
*
|
|
148
|
+
* Values are written verbatim (dotenv `KEY=value`, no quoting) — a secret only ever lands in
|
|
149
|
+
* the 0600 file, never argv/logs; the CALLER must not echo them.
|
|
150
|
+
* @param {{ path: string, managed: Record<string, string> }} args
|
|
151
|
+
* @param {{
|
|
152
|
+
* read?: (p: string) => string,
|
|
153
|
+
* write?: (p: string, c: string, o: object) => void,
|
|
154
|
+
* mkdir?: (p: string, o: object) => void,
|
|
155
|
+
* rename?: (from: string, to: string) => void,
|
|
156
|
+
* }} [deps]
|
|
157
|
+
* @returns {string} the dotenv path written
|
|
158
|
+
*/
|
|
159
|
+
export function upsertDotenvFile({ path: envPath, managed }, deps = {}) {
|
|
160
|
+
const read = deps.read ?? ((p) => readFileSync(p, "utf8"));
|
|
161
|
+
const write = deps.write ?? writeFileSync;
|
|
162
|
+
const mkdir = deps.mkdir ?? mkdirSync;
|
|
163
|
+
const rename = deps.rename ?? renameSync;
|
|
164
|
+
|
|
165
|
+
const managedKeys = Object.keys(managed);
|
|
166
|
+
const keyLine = new RegExp(`^\\s*(?:export\\s+)?(${managedKeys.join("|")})\\s*=`);
|
|
167
|
+
const seen = new Set();
|
|
168
|
+
|
|
169
|
+
let existing = "";
|
|
170
|
+
try {
|
|
171
|
+
existing = read(envPath);
|
|
172
|
+
} catch {
|
|
173
|
+
existing = ""; // no file yet — start fresh
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
const lines = existing.length ? existing.split(/\r?\n/) : [];
|
|
177
|
+
// Drop a single trailing empty element from a final newline so idempotent re-runs never
|
|
178
|
+
// accumulate blank lines.
|
|
179
|
+
if (lines.length && lines[lines.length - 1] === "") lines.pop();
|
|
180
|
+
|
|
181
|
+
const outLines = [];
|
|
182
|
+
for (const line of lines) {
|
|
183
|
+
const m = line.match(keyLine);
|
|
184
|
+
if (m) {
|
|
185
|
+
const key = m[1];
|
|
186
|
+
if (!seen.has(key)) {
|
|
187
|
+
outLines.push(`${key}=${managed[key]}`); // replace in place
|
|
188
|
+
seen.add(key);
|
|
189
|
+
}
|
|
190
|
+
continue; // drop this (and any later duplicate) managed line
|
|
191
|
+
}
|
|
192
|
+
outLines.push(line); // preserve unrelated line verbatim
|
|
193
|
+
}
|
|
194
|
+
// Append any managed key not already present (stable order).
|
|
195
|
+
for (const key of managedKeys) {
|
|
196
|
+
if (!seen.has(key)) outLines.push(`${key}=${managed[key]}`);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
const content = outLines.join("\n") + "\n";
|
|
200
|
+
|
|
201
|
+
mkdir(dirname(envPath), { recursive: true });
|
|
202
|
+
// Atomic write: temp file (0600) in the same dir, then rename over target.
|
|
203
|
+
const tmp = `${envPath}.tmp`;
|
|
204
|
+
write(tmp, content, { mode: 0o600 });
|
|
205
|
+
rename(tmp, envPath);
|
|
206
|
+
return envPath;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Whether an init selection id is Claude Code (`claude`). Claude Code gets a SECOND
|
|
211
|
+
* credential sink beyond ~/.chorus/daemon.json — its user-global ~/.claude/settings.json
|
|
212
|
+
* `env` block — so INTERACTIVE Claude Code authenticates with no manual export (the plugin
|
|
213
|
+
* `.mcp.json` interpolates `${CHORUS_URL}`/`${CHORUS_API_KEY}` from that env at session
|
|
214
|
+
* start). We gate on the selection id, NOT the mapped daemon agentType (`claude` →
|
|
215
|
+
* "claude-code"). Mirrors {@link isDshSelection}.
|
|
216
|
+
* @param {string} id
|
|
217
|
+
*/
|
|
218
|
+
function isClaudeSelection(id) {
|
|
219
|
+
return id === "claude";
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Resolve the USER-GLOBAL Claude Code settings.json path. Honors `CLAUDE_CONFIG_DIR` (which
|
|
224
|
+
* replaces ~/.claude wholesale per Claude Code docs), then `HOME` (so tests can inject a
|
|
225
|
+
* temp home), else the OS home dir. ALWAYS the user-global file — NEVER a project-level
|
|
226
|
+
* `.claude/settings.json` (git-tracked; would leak the `cho_` key) or `.claude/settings.local.json`.
|
|
227
|
+
* @param {Record<string, string | undefined>} env
|
|
228
|
+
*/
|
|
229
|
+
function resolveClaudeSettingsPath(env) {
|
|
230
|
+
const base = nonEmpty(env.CLAUDE_CONFIG_DIR) ?? join(nonEmpty(env.HOME) ?? homedir(), ".claude");
|
|
231
|
+
return join(base, "settings.json");
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Read the `CHORUS_AGENT_PROFILE` currently recorded in a Claude Code settings.json `env`
|
|
236
|
+
* block, for cross-run REPOINT detection. Returns undefined on a missing / unreadable /
|
|
237
|
+
* malformed file or when no such key exists — callers treat undefined as "no prior
|
|
238
|
+
* identity" (safe to write). Never throws.
|
|
239
|
+
* @param {string} settingsPath
|
|
240
|
+
* @param {{ read?: (p: string) => string }} [deps]
|
|
241
|
+
* @returns {string | undefined}
|
|
242
|
+
*/
|
|
243
|
+
export function readClaudeSettingsProfile(settingsPath, deps = {}) {
|
|
244
|
+
const read = deps.read ?? ((p) => readFileSync(p, "utf8"));
|
|
245
|
+
try {
|
|
246
|
+
const parsed = JSON.parse(read(settingsPath));
|
|
247
|
+
const env = parsed && typeof parsed === "object" ? parsed.env : undefined;
|
|
248
|
+
return env && typeof env === "object" && !Array.isArray(env) ? nonEmpty(env.CHORUS_AGENT_PROFILE) : undefined;
|
|
249
|
+
} catch {
|
|
250
|
+
return undefined;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Merge-preserving upsert of CHORUS_URL + CHORUS_API_KEY (+ CHORUS_AGENT_PROFILE) into the
|
|
256
|
+
* `env` block of the user-global ~/.claude/settings.json. The Claude Code analogue of
|
|
257
|
+
* {@link writeDshCredentialsEnv}: same invariants (idempotent, 0600, atomic temp+rename,
|
|
258
|
+
* key never echoed), but the target is a JSON object rather than a dotenv file.
|
|
259
|
+
*
|
|
260
|
+
* settings.json `env` is injected at session start BEFORE the MCP client connects and is
|
|
261
|
+
* inherited by hook + Bash/CLI subprocesses, so this one write satisfies native MCP auth
|
|
262
|
+
* (`.mcp.json` `${VAR}` interpolation), the plugin hooks, AND the skill `chorus` CLI — no
|
|
263
|
+
* manual export. (Verified against Claude Code docs mcp.md / env-vars.md.)
|
|
264
|
+
*
|
|
265
|
+
* Behavior:
|
|
266
|
+
* - Missing file → start from `{}` (create the config dir if absent).
|
|
267
|
+
* - Existing but UNPARSEABLE JSON, a non-object root, or a present-but-non-object `env`
|
|
268
|
+
* → THROW (never clobber a file we cannot safely merge; the caller treats a throw as a
|
|
269
|
+
* write failure and keeps the export hint).
|
|
270
|
+
* - Upserts ONLY the three managed keys into `parsed.env`; every other env key and every
|
|
271
|
+
* other top-level field is preserved verbatim.
|
|
272
|
+
* - Atomic write: temp file (0600) in the same dir, then rename over the target.
|
|
273
|
+
* - Idempotent: a re-run with the same values reproduces the file.
|
|
274
|
+
*
|
|
275
|
+
* The API key is only ever written into the 0600 file — never argv, never a log.
|
|
276
|
+
* @param {{ settingsPath: string, url: string, apiKey: string, agentProfile?: string }} args
|
|
277
|
+
* @param {{
|
|
278
|
+
* read?: (p: string) => string,
|
|
279
|
+
* write?: (p: string, c: string, o: object) => void,
|
|
280
|
+
* mkdir?: (p: string, o: object) => void,
|
|
281
|
+
* rename?: (from: string, to: string) => void,
|
|
282
|
+
* }} [deps]
|
|
283
|
+
* @returns {string} the settings.json path written
|
|
284
|
+
*/
|
|
285
|
+
export function writeClaudeSettingsEnv({ settingsPath, url, apiKey, agentProfile }, deps = {}) {
|
|
286
|
+
const read = deps.read ?? ((p) => readFileSync(p, "utf8"));
|
|
287
|
+
const write = deps.write ?? writeFileSync;
|
|
288
|
+
const mkdir = deps.mkdir ?? mkdirSync;
|
|
289
|
+
const rename = deps.rename ?? renameSync;
|
|
290
|
+
|
|
291
|
+
let raw;
|
|
292
|
+
try {
|
|
293
|
+
raw = read(settingsPath);
|
|
294
|
+
} catch {
|
|
295
|
+
raw = undefined; // no file yet — start fresh
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
let parsed = {};
|
|
299
|
+
if (typeof raw === "string" && raw.trim()) {
|
|
300
|
+
try {
|
|
301
|
+
parsed = JSON.parse(raw);
|
|
302
|
+
} catch (err) {
|
|
303
|
+
throw new Error(`existing ${settingsPath} is not valid JSON (${err?.message ?? err}) — refusing to overwrite`);
|
|
304
|
+
}
|
|
305
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
306
|
+
throw new Error(`existing ${settingsPath} is not a JSON object — refusing to overwrite`);
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
// Preserve an existing `env` object; a present-but-non-object `env` is unsafe to merge.
|
|
311
|
+
let envBlock = parsed.env;
|
|
312
|
+
if (envBlock === undefined || envBlock === null) {
|
|
313
|
+
envBlock = {};
|
|
314
|
+
} else if (typeof envBlock !== "object" || Array.isArray(envBlock)) {
|
|
315
|
+
throw new Error(`existing ${settingsPath} has a non-object "env" block — refusing to overwrite`);
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
const merged = { ...envBlock, CHORUS_URL: url, CHORUS_API_KEY: apiKey };
|
|
319
|
+
if (nonEmpty(agentProfile)) merged.CHORUS_AGENT_PROFILE = agentProfile.trim();
|
|
320
|
+
parsed.env = merged;
|
|
321
|
+
|
|
322
|
+
const content = `${JSON.stringify(parsed, null, 2)}\n`;
|
|
323
|
+
|
|
324
|
+
mkdir(dirname(settingsPath), { recursive: true });
|
|
325
|
+
// Atomic write: temp file (0600) in the same dir, then rename over target.
|
|
326
|
+
const tmp = `${settingsPath}.tmp`;
|
|
327
|
+
write(tmp, content, { mode: 0o600 });
|
|
328
|
+
rename(tmp, settingsPath);
|
|
329
|
+
return settingsPath;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
/**
|
|
333
|
+
* Whether an init selection id is Codex (`codex`). Codex gets a SECOND credential sink
|
|
334
|
+
* beyond ~/.chorus/daemon.json — its own `~/.codex/.env` dotenv file — so INTERACTIVE
|
|
335
|
+
* Codex's plugin lifecycle hooks (SessionStart check-in / PostToolUse) AND its shell-tool
|
|
336
|
+
* `chorus` calls resolve identity with no manual export. Codex loads `~/.codex/.env` into
|
|
337
|
+
* its own process env at arg0 startup (filtering only `CODEX_*` keys), and that env is
|
|
338
|
+
* snapshotted into every hook subprocess and inherited by the shell tool — so a single
|
|
339
|
+
* dotenv write covers both surfaces (unlike `[shell_environment_policy].set`, which reaches
|
|
340
|
+
* the shell tool but NOT the hooks). Native MCP is already export-free via the literal
|
|
341
|
+
* Bearer `codex plugin add` bakes into config.toml (left untouched here). We gate on the
|
|
342
|
+
* selection id, NOT the mapped daemon agentType (`codex` → "codex"). Mirrors
|
|
343
|
+
* {@link isDshSelection} / {@link isClaudeSelection}.
|
|
344
|
+
* @param {string} id
|
|
345
|
+
*/
|
|
346
|
+
function isCodexSelection(id) {
|
|
347
|
+
return id === "codex";
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
/**
|
|
351
|
+
* Resolve the Codex `~/.codex/.env` dotenv path. Honors `CODEX_HOME` (Codex's own override,
|
|
352
|
+
* same as cli/codex-spawner.mjs + install-methods.mjs), then `HOME` (so tests can inject a
|
|
353
|
+
* temp home), else the OS home dir — matching how the Codex install/spawn code already
|
|
354
|
+
* resolves `~/.codex`. This is the file Codex's arg0 loader reads into its process env; the
|
|
355
|
+
* literal `[mcp_servers.chorus]` Bearer lives separately in `config.toml` and is untouched.
|
|
356
|
+
* @param {Record<string, string | undefined>} env
|
|
357
|
+
*/
|
|
358
|
+
function resolveCodexEnvPath(env) {
|
|
359
|
+
const base = nonEmpty(env.CODEX_HOME) ?? join(nonEmpty(env.HOME) ?? homedir(), ".codex");
|
|
360
|
+
return join(base, ".env");
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
/**
|
|
364
|
+
* Merge-preserving upsert of CHORUS_URL + CHORUS_API_KEY + CHORUS_AGENT_PROFILE into the
|
|
365
|
+
* Codex `~/.codex/.env` dotenv file. The Codex analogue of {@link writeClaudeSettingsEnv} /
|
|
366
|
+
* {@link writeDshCredentialsEnv}, and — like dsh — a thin wrapper over the shared
|
|
367
|
+
* {@link upsertDotenvFile} (same invariants: idempotent, 0600, atomic temp+rename,
|
|
368
|
+
* merge-preserving, key never echoed).
|
|
369
|
+
*
|
|
370
|
+
* Codex loads `~/.codex/.env` into its OWN process env at arg0 startup (dotenvy, filtering
|
|
371
|
+
* only `CODEX_*` keys). That process env is snapshotted into every plugin hook subprocess
|
|
372
|
+
* (SessionStart check-in / PostToolUse) AND inherited by the exec/shell tool — so this single
|
|
373
|
+
* dotenv write makes interactive Codex export-free on BOTH surfaces. Contrast the prior
|
|
374
|
+
* `config.toml [shell_environment_policy].set`, which reached the shell tool but NOT the
|
|
375
|
+
* hooks. All three vars are REQUIRED (unlike dsh's optional profile), because the Codex hooks
|
|
376
|
+
* never make a bare auto-single MCP call and the profile pins WHICH agent to act as.
|
|
377
|
+
*
|
|
378
|
+
* The literal `[mcp_servers.chorus]` Bearer (native MCP auth) lives separately in
|
|
379
|
+
* `config.toml` and is never touched here.
|
|
380
|
+
*
|
|
381
|
+
* The API key is only ever written into the 0600 file — never argv, never a log.
|
|
382
|
+
* @param {{ envPath: string, url: string, apiKey: string, agentProfile: string }} args
|
|
383
|
+
* @param {{
|
|
384
|
+
* read?: (p: string) => string,
|
|
385
|
+
* write?: (p: string, c: string, o: object) => void,
|
|
386
|
+
* mkdir?: (p: string, o: object) => void,
|
|
387
|
+
* rename?: (from: string, to: string) => void,
|
|
388
|
+
* }} [deps]
|
|
389
|
+
* @returns {string} the `~/.codex/.env` path written
|
|
390
|
+
*/
|
|
391
|
+
export function writeCodexEnvFile({ envPath, url, apiKey, agentProfile }, deps = {}) {
|
|
392
|
+
const u = nonEmpty(url);
|
|
393
|
+
const k = nonEmpty(apiKey);
|
|
394
|
+
const prof = nonEmpty(agentProfile);
|
|
395
|
+
if (!u || !k || !prof) {
|
|
396
|
+
throw new Error("writeCodexEnvFile requires url, apiKey, and agentProfile");
|
|
397
|
+
}
|
|
398
|
+
return upsertDotenvFile(
|
|
399
|
+
{ path: envPath, managed: { CHORUS_URL: u, CHORUS_API_KEY: k, CHORUS_AGENT_PROFILE: prof } },
|
|
400
|
+
deps,
|
|
401
|
+
);
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
/**
|
|
405
|
+
* Read the `CHORUS_AGENT_PROFILE` currently recorded in a Codex `~/.codex/.env`, for cross-run
|
|
406
|
+
* REPOINT detection (the Codex analogue of {@link readClaudeSettingsProfile}). Parses the
|
|
407
|
+
* dotenv with `node:util` `parseEnv` (matching how the dsh tests read the same channel).
|
|
408
|
+
* Returns undefined on a missing / unreadable / malformed file or when no such key exists —
|
|
409
|
+
* callers treat undefined as "no prior identity" (safe to write). Never throws.
|
|
410
|
+
* @param {string} envPath
|
|
411
|
+
* @param {{ read?: (p: string) => string }} [deps]
|
|
412
|
+
* @returns {string | undefined}
|
|
413
|
+
*/
|
|
414
|
+
export function readCodexEnvProfile(envPath, deps = {}) {
|
|
415
|
+
const read = deps.read ?? ((p) => readFileSync(p, "utf8"));
|
|
416
|
+
try {
|
|
417
|
+
const parsed = parseEnv(read(envPath));
|
|
418
|
+
return parsed && typeof parsed === "object" ? nonEmpty(parsed.CHORUS_AGENT_PROFILE) : undefined;
|
|
419
|
+
} catch {
|
|
420
|
+
return undefined;
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
/**
|
|
425
|
+
* @param {import("../contracts.mjs").StepContext & {
|
|
426
|
+
* validateCredentials?: Function, appendAgent?: Function, writeLogin?: Function,
|
|
427
|
+
* promptFn?: Function,
|
|
428
|
+
* }} ctx
|
|
429
|
+
* @returns {Promise<import("../contracts.mjs").StepOutcome | import("../contracts.mjs").StepOutcome[]>}
|
|
430
|
+
*/
|
|
431
|
+
export async function seedCredentials(ctx) {
|
|
432
|
+
const env = ctx.env ?? process.env;
|
|
433
|
+
const io = ctx.io ?? {};
|
|
434
|
+
const isTTY = !!io.isTTY;
|
|
435
|
+
const flags = ctx.flags ?? {};
|
|
436
|
+
const validate = ctx.validateCredentials ?? validateAndFetchIdentity;
|
|
437
|
+
const append = ctx.appendAgent ?? defaultAppendAgentConfig;
|
|
438
|
+
const resolveCwds = ctx.resolveInstallCwds ?? defaultResolveInstallCwds;
|
|
439
|
+
const ask = ctx.promptFn ?? defaultPrompt;
|
|
440
|
+
const writeDshEnv = ctx.writeDshEnv ?? writeDshCredentialsEnv;
|
|
441
|
+
const writeClaudeSettings = ctx.writeClaudeSettings ?? writeClaudeSettingsEnv;
|
|
442
|
+
const readSettingsProfile = ctx.readClaudeSettingsProfile ?? readClaudeSettingsProfile;
|
|
443
|
+
const writeCodexEnv = ctx.writeCodexEnv ?? writeCodexEnvFile;
|
|
444
|
+
const readCodexProfile = ctx.readCodexEnvProfile ?? readCodexEnvProfile;
|
|
445
|
+
|
|
446
|
+
const selection = Array.isArray(ctx.selection) ? ctx.selection.filter((id) => nonEmpty(id)) : [];
|
|
447
|
+
if (selection.length === 0) {
|
|
448
|
+
return out(SKIPPED, "no agents selected — no credentials to seed");
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
// The Chorus server URL is shared across all selected agents (one Chorus
|
|
452
|
+
// instance). Resolve it once from flags/env, prompting a single time on a TTY.
|
|
453
|
+
let url = nonEmpty(flags.url) ?? nonEmpty(env.CHORUS_URL);
|
|
454
|
+
if (!url && isTTY && typeof ask === "function") {
|
|
455
|
+
url = nonEmpty(await ask("Chorus URL: "));
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
// Resolve the served working-directory SET once and stamp it PER-AGENT into each
|
|
459
|
+
// agents[] entry below. The daemon reads cwds per agent (cfg.cwds is authoritative);
|
|
460
|
+
// the flat top-level `cwds` is a deprecated single-agent leftover — writeConfig is a
|
|
461
|
+
// no-op here so we take only the resolved value, never a top-level write (daemon-setup
|
|
462
|
+
// no longer writes it either). Failure degrades to no cwds (daemon defaults to cwd).
|
|
463
|
+
let cwds = [];
|
|
464
|
+
try {
|
|
465
|
+
const resolved = await resolveCwds(flags, {
|
|
466
|
+
isTTY,
|
|
467
|
+
skip: !isTTY || flags.yes === true,
|
|
468
|
+
writeConfig: () => {},
|
|
469
|
+
readJson: ctx.readJson,
|
|
470
|
+
loginPath: ctx.loginPath,
|
|
471
|
+
prompt: ask,
|
|
472
|
+
log: typeof io.log === "function" ? io.log : () => {},
|
|
473
|
+
});
|
|
474
|
+
cwds = Array.isArray(resolved?.cwds) ? resolved.cwds : [];
|
|
475
|
+
} catch {
|
|
476
|
+
cwds = [];
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
/** @type {import("../contracts.mjs").StepOutcome[]} */
|
|
480
|
+
const outcomes = [];
|
|
481
|
+
|
|
482
|
+
for (let i = 0; i < selection.length; i += 1) {
|
|
483
|
+
const id = selection[i];
|
|
484
|
+
const agentType = agentTypeForSelection(id);
|
|
485
|
+
|
|
486
|
+
// Key capture: the FIRST agent pre-fills from --api-key / CHORUS_API_KEY; every
|
|
487
|
+
// agent prompts on a TTY. A later agent is NEVER handed an earlier agent's key.
|
|
488
|
+
let apiKey = i === 0 ? nonEmpty(flags.apiKey) ?? nonEmpty(env.CHORUS_API_KEY) : undefined;
|
|
489
|
+
if (!apiKey && isTTY && typeof ask === "function") {
|
|
490
|
+
apiKey = nonEmpty(await ask(`Chorus API key for ${id} (cho_...): `, { mask: true }));
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
if (!url || !apiKey) {
|
|
494
|
+
// Cannot capture this agent's own key (non-TTY, nothing pre-filled). Report it
|
|
495
|
+
// — never silently reuse another identity's key across agents.
|
|
496
|
+
const missing = !url ? "URL + API key" : "API key";
|
|
497
|
+
outcomes.push(
|
|
498
|
+
out(
|
|
499
|
+
FAILED,
|
|
500
|
+
`${id}: missing Chorus ${missing} — pass --url/--api-key (first agent) or run interactively; ` +
|
|
501
|
+
`this agent still needs its own key`,
|
|
502
|
+
),
|
|
503
|
+
);
|
|
504
|
+
continue;
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
let identity;
|
|
508
|
+
try {
|
|
509
|
+
identity = await validate({ url, apiKey });
|
|
510
|
+
} catch (err) {
|
|
511
|
+
outcomes.push(out(FAILED, `${id}: credential validation failed: ${err?.message ?? String(err)}`));
|
|
512
|
+
continue;
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
// daemon-wake opt-in (only for a daemon-wakeable backend; offline agents can never
|
|
516
|
+
// be woken, so they get NO daemonWake field). DEFAULT off: an added agent is parked
|
|
517
|
+
// (its key serves `chorus mcp`) but not woken until the operator opts in — via
|
|
518
|
+
// `--daemon-wake <ids>` / `--daemon-wake-all`, or a per-agent prompt on a TTY.
|
|
519
|
+
let daemonWake;
|
|
520
|
+
if (isWakeableAgentType(agentType)) {
|
|
521
|
+
const flaggedAll = flags.daemonWakeAll === true;
|
|
522
|
+
const flaggedThis = Array.isArray(flags.daemonWake) && flags.daemonWake.includes(id);
|
|
523
|
+
if (flaggedAll || flaggedThis) {
|
|
524
|
+
daemonWake = true;
|
|
525
|
+
} else if (isTTY && typeof ask === "function") {
|
|
526
|
+
const ans = String(
|
|
527
|
+
(await ask(`Enable daemon waking for ${identity.name} (${agentType})? [y/N]: `)) ?? "",
|
|
528
|
+
).trim();
|
|
529
|
+
daemonWake = /^y(es)?$/i.test(ans);
|
|
530
|
+
} else {
|
|
531
|
+
daemonWake = false; // non-TTY default: not woken
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
// Append as its own agents[] entry, tagged with the mapped daemon agentType
|
|
536
|
+
// (offline when the backend isn't daemon-wakeable), its OWN cwds, and the resolved
|
|
537
|
+
// daemonWake (explicit boolean for wakeable backends; omitted for offline).
|
|
538
|
+
// Merge-safe; dedups on key; only touches the newly-added entry.
|
|
539
|
+
const res = append({
|
|
540
|
+
url,
|
|
541
|
+
apiKey,
|
|
542
|
+
agentType,
|
|
543
|
+
agentUuid: identity.uuid,
|
|
544
|
+
agentName: identity.name,
|
|
545
|
+
...(cwds.length ? { cwds } : {}),
|
|
546
|
+
...(daemonWake !== undefined ? { daemonWake } : {}),
|
|
547
|
+
});
|
|
548
|
+
|
|
549
|
+
// dsh-only: ALSO restore the retired dsh-credentials.sh channel by seeding
|
|
550
|
+
// $DSH_HOME/.env, so the doc-mirror wrapper resolves creds when `chorus` is
|
|
551
|
+
// off PATH (the npx init path). Runs regardless of the daemon.json dedup
|
|
552
|
+
// result (an idempotent re-run still repairs a missing/stale .env). Only the
|
|
553
|
+
// path is ever surfaced — never the key.
|
|
554
|
+
let dshNote = "";
|
|
555
|
+
// When the profile is persisted in $DSH_HOME/.env, dsh loads it into the session
|
|
556
|
+
// env for free — so init.mjs SKIPS the manual `export CHORUS_AGENT_PROFILE=…`
|
|
557
|
+
// hint for this agent (every non-dsh agent still gets the hint). Only set on a
|
|
558
|
+
// successful .env write; if it failed, the hint is still shown as a fallback.
|
|
559
|
+
let profileInEnv = false;
|
|
560
|
+
if (isDshSelection(id)) {
|
|
561
|
+
try {
|
|
562
|
+
const envPath = writeDshEnv({ dshHome: resolveDshHome(env), url, apiKey, agentProfile: identity.uuid });
|
|
563
|
+
dshNote = `; seeded CHORUS_URL/CHORUS_API_KEY/CHORUS_AGENT_PROFILE into ${envPath} (0600)`;
|
|
564
|
+
profileInEnv = true;
|
|
565
|
+
} catch (err) {
|
|
566
|
+
dshNote = `; WARNING: could not seed $DSH_HOME/.env: ${err?.message ?? String(err)}`;
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
// claude-only: ALSO write the user-global ~/.claude/settings.json `env` block so
|
|
571
|
+
// INTERACTIVE Claude Code authenticates with no manual export. On a SUCCESSFUL write we
|
|
572
|
+
// set settingsEnvWritten so init.mjs suppresses the manual export hint (like dsh's
|
|
573
|
+
// profileInEnv). Runs regardless of the daemon.json dedup result (an idempotent re-run
|
|
574
|
+
// repairs a missing/stale settings.json). The key is only written into the 0600 file.
|
|
575
|
+
let claudeNote = "";
|
|
576
|
+
let settingsEnvWritten = false;
|
|
577
|
+
if (isClaudeSelection(id)) {
|
|
578
|
+
const settingsPath = resolveClaudeSettingsPath(env);
|
|
579
|
+
const newProfile = identity.uuid;
|
|
580
|
+
// Cross-run REPOINT detection: the user-global env block holds ONE identity, and a
|
|
581
|
+
// single run configures `claude` at most once (resolveSelection dedups ids). So a
|
|
582
|
+
// DIFFERENT existing profile is a PRIOR run's identity — never overwrite it silently
|
|
583
|
+
// (prompt on a TTY; WARN on non-TTY). Absent/equal → write (equal is idempotent).
|
|
584
|
+
const existingProfile = readSettingsProfile(settingsPath);
|
|
585
|
+
const isRepoint = existingProfile !== undefined && existingProfile !== newProfile;
|
|
586
|
+
let doWrite = true;
|
|
587
|
+
let declined = false;
|
|
588
|
+
let repointWarn = "";
|
|
589
|
+
if (isRepoint) {
|
|
590
|
+
if (isTTY && typeof ask === "function") {
|
|
591
|
+
const ans = String(
|
|
592
|
+
(await ask(
|
|
593
|
+
`Interactive Claude Code is currently configured as ${existingProfile}; ` +
|
|
594
|
+
`repoint it to ${identity.name} (${newProfile})? [y/N]: `,
|
|
595
|
+
)) ?? "",
|
|
596
|
+
).trim();
|
|
597
|
+
if (!/^y(es)?$/i.test(ans)) {
|
|
598
|
+
doWrite = false;
|
|
599
|
+
declined = true;
|
|
600
|
+
}
|
|
601
|
+
} else {
|
|
602
|
+
repointWarn = ` (WARNING: repointed interactive Claude Code from ${existingProfile} to ${newProfile})`;
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
if (doWrite) {
|
|
606
|
+
try {
|
|
607
|
+
const p = writeClaudeSettings({ settingsPath, url, apiKey, agentProfile: newProfile });
|
|
608
|
+
settingsEnvWritten = true;
|
|
609
|
+
claudeNote = `; wrote CHORUS_URL/CHORUS_API_KEY/CHORUS_AGENT_PROFILE into ${p} (0600)${repointWarn}`;
|
|
610
|
+
} catch (err) {
|
|
611
|
+
// B1: profileExportHint prints only CHORUS_AGENT_PROFILE and CANNOT fix native MCP
|
|
612
|
+
// (it interpolates ${CHORUS_URL}/${CHORUS_API_KEY}), and printing the key would
|
|
613
|
+
// break never-echo. So emit an actionable, non-secret WARNING; the export hint is
|
|
614
|
+
// still shown (settingsEnvWritten stays false) as a partial fallback.
|
|
615
|
+
claudeNote =
|
|
616
|
+
`; WARNING: could not write ${settingsPath} (${err?.message ?? String(err)}). ` +
|
|
617
|
+
"Interactive Claude Code MCP will not connect until CHORUS_URL, CHORUS_API_KEY and " +
|
|
618
|
+
`CHORUS_AGENT_PROFILE are in its env block — add them to ${settingsPath} (or export them). ` +
|
|
619
|
+
"Your cho_ key is not shown here.";
|
|
620
|
+
}
|
|
621
|
+
} else if (declined) {
|
|
622
|
+
// Declined repoint: the EXISTING settings.json identity remains, and since
|
|
623
|
+
// settings.json env OVERRIDES the shell, a shell export would be ignored — so
|
|
624
|
+
// direct the operator to the FILE, do not suggest exporting.
|
|
625
|
+
claudeNote =
|
|
626
|
+
`; left interactive Claude Code as ${existingProfile} — edit ${settingsPath} to change it ` +
|
|
627
|
+
"(a shell export would be overridden by settings.json env).";
|
|
628
|
+
}
|
|
629
|
+
// Ambient-shell conflict heads-up: settings.json env OVERRIDES the shell, so if the
|
|
630
|
+
// shell already exports a DIFFERENT identity, note it. Non-secret: compare the profile
|
|
631
|
+
// UUID (primary) and the key IN MEMORY (never printed).
|
|
632
|
+
const shellProfile = nonEmpty(env.CHORUS_AGENT_PROFILE);
|
|
633
|
+
const shellKey = nonEmpty(env.CHORUS_API_KEY);
|
|
634
|
+
if ((shellProfile && shellProfile !== newProfile) || (shellKey && shellKey !== apiKey)) {
|
|
635
|
+
claudeNote +=
|
|
636
|
+
"; note: your shell exports a different CHORUS_* identity — settings.json env " +
|
|
637
|
+
"overrides it for interactive Claude Code";
|
|
638
|
+
}
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
// codex-only: ALSO write ~/.codex/.env (dotenv) so INTERACTIVE Codex's plugin lifecycle
|
|
642
|
+
// hooks (SessionStart check-in / PostToolUse) AND its shell-tool `chorus` calls resolve
|
|
643
|
+
// identity with NO manual export — Codex loads ~/.codex/.env into its process env at arg0
|
|
644
|
+
// startup, which the hooks snapshot and the shell tool inherits. UNGATED — every codex agent
|
|
645
|
+
// (single- and multi-agent alike), because the Codex hooks never auto-single. Native MCP
|
|
646
|
+
// stays export-free via the literal [mcp_servers.chorus] Bearer this write never touches. On
|
|
647
|
+
// a SUCCESSFUL write set codexEnvWritten so init.mjs suppresses the export hint (like dsh's
|
|
648
|
+
// profileInEnv / Claude Code's settingsEnvWritten). The key is only written into the 0600 file.
|
|
649
|
+
let codexNote = "";
|
|
650
|
+
let codexEnvWritten = false;
|
|
651
|
+
if (isCodexSelection(id)) {
|
|
652
|
+
const envPath = resolveCodexEnvPath(env);
|
|
653
|
+
const newProfile = identity.uuid;
|
|
654
|
+
// Cross-run REPOINT detection (mirrors Claude Code): ~/.codex/.env carries ONE identity and
|
|
655
|
+
// a single run configures `codex` at most once, so a DIFFERENT existing profile is a PRIOR
|
|
656
|
+
// run's identity — never overwrite it silently (prompt on a TTY; WARN on non-TTY).
|
|
657
|
+
// Absent/equal → write (equal is idempotent). Because Codex's dotenv loader OVERRIDES the
|
|
658
|
+
// shell, a declined repoint directs the operator to EDIT the file, not export. Compare by
|
|
659
|
+
// the profile UUID, never the key.
|
|
660
|
+
const existingProfile = readCodexProfile(envPath);
|
|
661
|
+
const isRepoint = existingProfile !== undefined && existingProfile !== newProfile;
|
|
662
|
+
let doWrite = true;
|
|
663
|
+
let declined = false;
|
|
664
|
+
let repointWarn = "";
|
|
665
|
+
if (isRepoint) {
|
|
666
|
+
if (isTTY && typeof ask === "function") {
|
|
667
|
+
const ans = String(
|
|
668
|
+
(await ask(
|
|
669
|
+
`Interactive Codex is currently configured as ${existingProfile}; ` +
|
|
670
|
+
`repoint it to ${identity.name} (${newProfile})? [y/N]: `,
|
|
671
|
+
)) ?? "",
|
|
672
|
+
).trim();
|
|
673
|
+
if (!/^y(es)?$/i.test(ans)) {
|
|
674
|
+
doWrite = false;
|
|
675
|
+
declined = true;
|
|
676
|
+
}
|
|
677
|
+
} else {
|
|
678
|
+
repointWarn = ` (WARNING: repointed interactive Codex from ${existingProfile} to ${newProfile})`;
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
if (doWrite) {
|
|
682
|
+
try {
|
|
683
|
+
const p = writeCodexEnv({ envPath, url, apiKey, agentProfile: newProfile });
|
|
684
|
+
codexEnvWritten = true;
|
|
685
|
+
// Export-free: ~/.codex/.env reaches BOTH the plugin hooks (SessionStart check-in /
|
|
686
|
+
// PostToolUse, via Codex's process-env snapshot) AND the shell tool — no residual, no
|
|
687
|
+
// "start codex from an exporting shell", no wrapper. Key never echoed.
|
|
688
|
+
codexNote =
|
|
689
|
+
`; wrote CHORUS_URL/CHORUS_API_KEY/CHORUS_AGENT_PROFILE into ${p} (0600)${repointWarn} — ` +
|
|
690
|
+
"interactive Codex (plugin hooks: SessionStart check-in / PostToolUse, AND shell-tool " +
|
|
691
|
+
"`chorus` calls) authenticates with no manual export. Your cho_ key is not shown here.";
|
|
692
|
+
} catch (err) {
|
|
693
|
+
// Write failed (locked/unwritable). Emit an actionable, non-secret WARNING; the export
|
|
694
|
+
// hint is still shown (codexEnvWritten stays false). No launcher wrapper.
|
|
695
|
+
codexNote =
|
|
696
|
+
`; WARNING: could not write ${envPath} (${err?.message ?? String(err)}). ` +
|
|
697
|
+
"Interactive Codex will not reach Chorus until CHORUS_URL, CHORUS_API_KEY and " +
|
|
698
|
+
`CHORUS_AGENT_PROFILE are in ~/.codex/.env — add them there (or export them). ` +
|
|
699
|
+
"Your cho_ key is not shown here.";
|
|
700
|
+
}
|
|
701
|
+
} else if (declined) {
|
|
702
|
+
// Declined repoint: the EXISTING ~/.codex/.env identity remains, and since Codex's dotenv
|
|
703
|
+
// loader OVERRIDES the shell, a shell export would be ignored — direct the operator to the
|
|
704
|
+
// FILE, do not suggest exporting.
|
|
705
|
+
codexNote =
|
|
706
|
+
`; left interactive Codex as ${existingProfile} — edit ${envPath} to change it ` +
|
|
707
|
+
"(a shell export would be overridden by Codex's ~/.codex/.env loader).";
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
// Combined side-file note + hint-suppression flags (dsh, claude, and codex are mutually
|
|
712
|
+
// exclusive selection ids, so at most one note/flag is set per iteration).
|
|
713
|
+
const sideNote = `${dshNote}${claudeNote}${codexNote}`;
|
|
714
|
+
const hintFlags = {
|
|
715
|
+
...(profileInEnv ? { profileInEnv: true } : {}),
|
|
716
|
+
...(settingsEnvWritten ? { settingsEnvWritten: true } : {}),
|
|
717
|
+
...(codexEnvWritten ? { codexEnvWritten: true } : {}),
|
|
718
|
+
};
|
|
719
|
+
|
|
720
|
+
if (!res.ok) {
|
|
721
|
+
outcomes.push(
|
|
722
|
+
out(
|
|
723
|
+
SKIPPED,
|
|
724
|
+
`${id}: ${identity.name} (${identity.uuid}) already configured (same key) — left unchanged${sideNote}`,
|
|
725
|
+
// Carry the identity so the orchestrator can print a CHORUS_AGENT_PROFILE
|
|
726
|
+
// export hint even on an idempotent re-run (the agent is still configured).
|
|
727
|
+
{ agentUuid: identity.uuid, agentName: identity.name, ...hintFlags },
|
|
728
|
+
),
|
|
729
|
+
);
|
|
730
|
+
continue;
|
|
731
|
+
}
|
|
732
|
+
outcomes.push(
|
|
733
|
+
out(
|
|
734
|
+
SEEDED,
|
|
735
|
+
`${id}: seeded ${identity.name} (${identity.uuid}) as ${agentType} → agents[${res.index}] in ~/.chorus/daemon.json${sideNote}`,
|
|
736
|
+
// Structured identity for the completion profile-export hint (init.mjs).
|
|
737
|
+
{ agentUuid: identity.uuid, agentName: identity.name, ...hintFlags },
|
|
738
|
+
),
|
|
739
|
+
);
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
return outcomes;
|
|
743
|
+
}
|
|
744
|
+
|
|
745
|
+
/** @type {import("../contracts.mjs").InitStep} */
|
|
746
|
+
export const credentialSeedStep = {
|
|
747
|
+
id: STEP_ID,
|
|
748
|
+
order: 10, // before plugin-install (order 20)
|
|
749
|
+
scope: STEP_SCOPES.ONCE,
|
|
750
|
+
run: seedCredentials,
|
|
751
|
+
};
|