@chorus-aidlc/chorus 0.16.4 → 0.17.0
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 +420 -420
- package/.next/standalone/.next/app-path-routes-manifest.json +53 -53
- package/.next/standalone/.next/build-manifest.json +5 -5
- package/.next/standalone/.next/prerender-manifest.json +45 -45
- package/.next/standalone/.next/server/app/(dashboard)/project-groups/[uuid]/page.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/project-groups/[uuid]/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/project-groups/[uuid]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/activity/page.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/activity/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/dashboard/[ideaUuid]/page.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/dashboard/[ideaUuid]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/dashboard/page.js +2 -2
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/dashboard/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/dashboard/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/documents/[documentUuid]/page.js +2 -2
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/documents/[documentUuid]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/documents/page.js +2 -2
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/documents/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/graph/page.js +2 -2
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/graph/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/graph/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/[proposalUuid]/page.js +2 -2
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/[proposalUuid]/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/[proposalUuid]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/new/page.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/new/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/new/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/page.js +2 -2
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/tasks/[taskUuid]/page.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/tasks/[taskUuid]/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/tasks/[taskUuid]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/tasks/page.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/tasks/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/tasks/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/page.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/settings/page.js +2 -2
- package/.next/standalone/.next/server/app/(dashboard)/settings/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/settings/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/_not-found.html +2 -2
- package/.next/standalone/.next/server/app/_not-found.rsc +1 -1
- package/.next/standalone/.next/server/app/admin/companies/[uuid]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/admin/companies/new/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/admin/companies/new.html +2 -2
- package/.next/standalone/.next/server/app/admin/companies/new.rsc +1 -1
- package/.next/standalone/.next/server/app/admin/companies/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/admin/companies.html +2 -2
- package/.next/standalone/.next/server/app/admin/companies.rsc +1 -1
- package/.next/standalone/.next/server/app/admin/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/admin.html +2 -2
- package/.next/standalone/.next/server/app/admin.rsc +1 -1
- package/.next/standalone/.next/server/app/api/admin/companies/[uuid]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/admin/companies/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/admin/login/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/admin/session/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/agent-connections/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/agent-connections/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/agents/[uuid]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/agents/[uuid]/sessions/route.js +1 -1
- package/.next/standalone/.next/server/app/api/agents/[uuid]/sessions/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/agents/[uuid]/sessions/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/agents/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/api-keys/[uuid]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/api-keys/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/auth/callback/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/auth/check-default/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/auth/company-oidc/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/auth/default-login/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/auth/identify/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/auth/logout/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/auth/me/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/auth/sync-token/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/comments/route.js +1 -1
- package/.next/standalone/.next/server/app/api/comments/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/comments/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon/connection-heartbeat/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/daemon/connection-heartbeat/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon/control/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon/directory-request/report/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/daemon/directory-request/report/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon/execution-state/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/daemon/execution-state/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon/executions/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/daemon/executions/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon/pending-turns/route.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon/pending-turns/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/daemon/pending-turns/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon/report-interrupt/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/daemon/report-interrupt/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon/resume/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/daemon/resume/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon/transcript/route.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon/transcript/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/daemon/transcript/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon/turn-advance/route.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon/turn-advance/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/daemon/turn-advance/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon-directory-requests/[uuid]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/daemon-directory-requests/[uuid]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon-directory-requests/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/daemon-directory-requests/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon-sessions/[sessionUuid]/instruction/route.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon-sessions/[sessionUuid]/instruction/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/daemon-sessions/[sessionUuid]/instruction/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon-sessions/[sessionUuid]/repoint/route.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon-sessions/[sessionUuid]/repoint/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/daemon-sessions/[sessionUuid]/repoint/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon-sessions/[sessionUuid]/route.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon-sessions/[sessionUuid]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/daemon-sessions/[sessionUuid]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon-sessions/ad-hoc/route.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon-sessions/ad-hoc/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/daemon-sessions/ad-hoc/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon-sessions/route.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon-sessions/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/daemon-sessions/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/documents/[uuid]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/entities/[type]/[uuid]/root-idea/route.js +1 -1
- package/.next/standalone/.next/server/app/api/entities/[type]/[uuid]/root-idea/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/entities/[type]/[uuid]/root-idea/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/events/notifications/route.js +1 -1
- package/.next/standalone/.next/server/app/api/events/notifications/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/events/notifications/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/events/route.js +1 -1
- package/.next/standalone/.next/server/app/api/events/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/events/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/health/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/ideas/[uuid]/claim/route.js +1 -1
- package/.next/standalone/.next/server/app/api/ideas/[uuid]/claim/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/ideas/[uuid]/claim/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/ideas/[uuid]/move/preview/route.js +1 -1
- package/.next/standalone/.next/server/app/api/ideas/[uuid]/move/preview/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/ideas/[uuid]/move/preview/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/ideas/[uuid]/move/route.js +1 -1
- package/.next/standalone/.next/server/app/api/ideas/[uuid]/move/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/ideas/[uuid]/move/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/ideas/[uuid]/parent/route.js +1 -1
- package/.next/standalone/.next/server/app/api/ideas/[uuid]/parent/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/ideas/[uuid]/parent/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/ideas/[uuid]/release/route.js +1 -1
- package/.next/standalone/.next/server/app/api/ideas/[uuid]/release/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/ideas/[uuid]/release/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/ideas/[uuid]/route.js +1 -1
- package/.next/standalone/.next/server/app/api/ideas/[uuid]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/ideas/[uuid]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/ideas/[uuid]/wake-preview/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/ideas/[uuid]/wake-preview/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/ideas/conversational/route.js +1 -1
- package/.next/standalone/.next/server/app/api/ideas/conversational/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/ideas/conversational/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/mcp/route.js +4 -4
- package/.next/standalone/.next/server/app/api/mcp/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/mcp/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/me/assignments/route.js +1 -1
- package/.next/standalone/.next/server/app/api/me/assignments/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/me/assignments/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/mentionables/route.js +1 -1
- package/.next/standalone/.next/server/app/api/mentionables/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/mentionables/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/notifications/[uuid]/archive/route.js +1 -1
- package/.next/standalone/.next/server/app/api/notifications/[uuid]/archive/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/notifications/[uuid]/archive/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/notifications/[uuid]/read/route.js +1 -1
- package/.next/standalone/.next/server/app/api/notifications/[uuid]/read/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/notifications/[uuid]/read/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/notifications/preferences/route.js +1 -1
- package/.next/standalone/.next/server/app/api/notifications/preferences/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/notifications/preferences/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/notifications/read-all/route.js +1 -1
- package/.next/standalone/.next/server/app/api/notifications/read-all/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/notifications/read-all/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/notifications/route.js +1 -1
- package/.next/standalone/.next/server/app/api/notifications/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/notifications/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/notifications/unread-count/route.js +1 -1
- package/.next/standalone/.next/server/app/api/notifications/unread-count/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/notifications/unread-count/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/project-groups/[uuid]/dashboard/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/project-groups/[uuid]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/project-groups/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/project-visits/pin/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/project-visits/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/project-visits/visit/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/activity/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/agent-cwds/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/agent-cwds/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/available/route.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/available/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/available/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/documents/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/group/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/ideas/route.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/ideas/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/ideas/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/ideas/tracker/route.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/ideas/tracker/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/ideas/tracker/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/proposals/[proposalUuid]/validate/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/proposals/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/proposals/summary/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/resource-graph/route.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/resource-graph/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/resource-graph/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/stats/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/tasks/dependencies/route.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/tasks/dependencies/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/tasks/dependencies/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/tasks/route.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/tasks/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/tasks/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/agent-cwd-options/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/projects/agent-cwd-options/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/proposals/[uuid]/approve/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/proposals/[uuid]/close/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/proposals/[uuid]/reject/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/proposals/[uuid]/revoke/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/proposals/[uuid]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/references/[uuid]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/references/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/search/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/session/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/sessions/[uuid]/route.js +1 -1
- package/.next/standalone/.next/server/app/api/sessions/[uuid]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/sessions/[uuid]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/tasks/[uuid]/claim/route.js +1 -1
- package/.next/standalone/.next/server/app/api/tasks/[uuid]/claim/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/tasks/[uuid]/claim/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/tasks/[uuid]/dependencies/[dependsOnUuid]/route.js +1 -1
- package/.next/standalone/.next/server/app/api/tasks/[uuid]/dependencies/[dependsOnUuid]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/tasks/[uuid]/dependencies/[dependsOnUuid]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/tasks/[uuid]/dependencies/route.js +1 -1
- package/.next/standalone/.next/server/app/api/tasks/[uuid]/dependencies/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/tasks/[uuid]/dependencies/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/tasks/[uuid]/release/route.js +1 -1
- package/.next/standalone/.next/server/app/api/tasks/[uuid]/release/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/tasks/[uuid]/release/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/tasks/[uuid]/route.js +1 -1
- package/.next/standalone/.next/server/app/api/tasks/[uuid]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/tasks/[uuid]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/tasks/[uuid]/sessions/route.js +1 -1
- package/.next/standalone/.next/server/app/api/tasks/[uuid]/sessions/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/tasks/[uuid]/sessions/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/index.html +2 -2
- package/.next/standalone/.next/server/app/index.rsc +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 +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 +1 -1
- package/.next/standalone/.next/server/app/login/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/login/pick-workspace/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/login/pick-workspace.html +2 -2
- package/.next/standalone/.next/server/app/login/pick-workspace.rsc +1 -1
- package/.next/standalone/.next/server/app/login.html +2 -2
- package/.next/standalone/.next/server/app/login.rsc +1 -1
- 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 +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 +2 -2
- package/.next/standalone/.next/server/app/settings.html +2 -2
- package/.next/standalone/.next/server/app/settings.rsc +3 -3
- package/.next/standalone/.next/server/app-paths-manifest.json +53 -53
- package/.next/standalone/.next/server/chunks/{5205.js → 1114.js} +1 -1
- package/.next/standalone/.next/server/chunks/1318.js +1 -1
- package/.next/standalone/.next/server/chunks/1437.js +1 -0
- package/.next/standalone/.next/server/chunks/1559.js +2 -2
- package/.next/standalone/.next/server/chunks/2572.js +1 -1
- package/.next/standalone/.next/server/chunks/2961.js +1 -1
- package/.next/standalone/.next/server/chunks/{9793.js → 3045.js} +1 -1
- package/.next/standalone/.next/server/chunks/3831.js +37 -0
- package/.next/standalone/.next/server/chunks/4827.js +1 -1
- package/.next/standalone/.next/server/chunks/5245.js +1 -1
- package/.next/standalone/.next/server/chunks/{4394.js → 5706.js} +1 -1
- package/.next/standalone/.next/server/chunks/6113.js +1 -1
- package/.next/standalone/.next/server/chunks/6207.js +1 -1
- package/.next/standalone/.next/server/chunks/6515.js +2 -2
- 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/8454.js +1 -1
- 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/9449.js +1 -0
- package/.next/standalone/.next/server/chunks/9458.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/pages/404.html +2 -2
- package/.next/standalone/.next/server/pages/500.html +1 -1
- package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/static/chunks/{11595.a6268c75ca8a2163.js → 11595.bbe40924d18958bf.js} +1 -1
- package/.next/standalone/.next/static/chunks/18139-e6ef4b5869593f8e.js +1 -0
- package/.next/standalone/.next/static/chunks/28856-ef2cb58fbd404ef9.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.5499eb8e892b110a.js} +1 -1
- package/.next/standalone/.next/static/chunks/{4860.9e06848eb531e667.js → 4860.be77046fb2b3a2bd.js} +1 -1
- package/.next/standalone/.next/static/chunks/66873-e3be53f41b3f2255.js +1 -0
- package/.next/standalone/.next/static/chunks/70303-aec3d52ad87602a3.js +1 -0
- package/.next/standalone/.next/static/chunks/76201-83b26515f85ce37c.js +1 -0
- package/.next/standalone/.next/static/chunks/78917-a8a8dff98857c045.js +1 -0
- package/.next/standalone/.next/static/chunks/97663-9c3ae4fd60b353db.js +1 -0
- package/.next/standalone/.next/static/chunks/{99373.81b79c91858f9099.js → 99373.111493dc260a2a04.js} +1 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/{layout-b742c51c0a764daf.js → layout-40fe7d026c5a7c6d.js} +1 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/dashboard/page-87d4d0fe90fca28c.js +1 -0
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/documents/[documentUuid]/page-1206abaee85dc915.js +1 -0
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/documents/{page-425acbe9ade5fa83.js → page-474e494097c8945f.js} +1 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/graph/page-e902b19328092ccf.js +1 -0
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/[proposalUuid]/page-f273288c3530aa0f.js +1 -0
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/new/page-6568a7b08bf9a54b.js +1 -0
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/page-fbd3c27b68666234.js +1 -0
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/tasks/[taskUuid]/{page-58b48aa0a11603c3.js → page-15bb6e1696668512.js} +1 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/tasks/{page-286faced32c6133f.js → page-2bea97214b1595cc.js} +1 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/settings/page-2bf7ceee62b574c7.js +1 -0
- package/.next/standalone/.next/static/chunks/app/onboarding/{page-5c82cf3abd856301.js → page-540da64d7ba16dc7.js} +1 -1
- package/.next/standalone/.next/static/chunks/{webpack-4d1cc14b13e247b6.js → webpack-7cbb3ba6792f1fb3.js} +1 -1
- package/.next/standalone/package.json +1 -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 +1 -1
- 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 +1 -1
- 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 +41 -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 +1 -1
- 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/README.ja.md +2 -2
- package/README.ko.md +2 -2
- package/README.md +2 -2
- package/README.zh.md +2 -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 +4 -0
- package/cli/codex-spawner.mjs +11 -6
- package/cli/credentials.mjs +185 -3
- 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 +120 -0
- package/cli/init/detect.mjs +97 -0
- package/cli/init/file-template.mjs +248 -0
- package/cli/init/install-methods.mjs +508 -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 +137 -0
- package/cli/init.mjs +198 -0
- package/cli/kiro-spawner.mjs +4 -0
- package/cli/mcp-args.mjs +280 -0
- package/cli/mcp.mjs +164 -0
- package/cli/spawner-select.mjs +45 -2
- package/package.json +1 -1
- package/.next/standalone/.next/server/chunks/3594.js +0 -1
- package/.next/standalone/.next/server/chunks/5351.js +0 -33
- package/.next/standalone/.next/server/chunks/6667.js +0 -1
- package/.next/standalone/.next/server/chunks/6995.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/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/99366-425e9ef22e60e3e2.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]/graph/page-fdd617457730a116.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)/settings/page-1507a761e67c2aa9.js +0 -1
- /package/.next/standalone/.next/static/{6sHDgeKioa0SJR1MAbcYG → 0spgxl3lP26Fl1otd1D7R}/_buildManifest.js +0 -0
- /package/.next/standalone/.next/static/{6sHDgeKioa0SJR1MAbcYG → 0spgxl3lP26Fl1otd1D7R}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
// cli/init/adapters.mjs
|
|
2
|
+
// The per-agent adapters `chorus init` configures. One descriptor per supported
|
|
3
|
+
// coding-agent harness; buildAdapter() turns each into an AgentAdapter
|
|
4
|
+
// (contracts.mjs). Detection is shared (cli/init/detect.mjs); the plugin-install
|
|
5
|
+
// mechanism (descriptor.install) is added by the plugin-install task — until
|
|
6
|
+
// then installPlugin reports "unsupported" rather than guessing a command.
|
|
7
|
+
//
|
|
8
|
+
// LAYOUT PROVENANCE (binary + config dir), so future edits don't drift into
|
|
9
|
+
// LLM-guessed paths (verified against each agent's real CLI / install-*.sh):
|
|
10
|
+
// - claude : bin `claude`; dir ~/.claude (this machine + docs/CONNECT_CLAUDE_CODE.md)
|
|
11
|
+
// - codex : bin `codex`; dir ~/.codex (public/install-codex.sh: CODEX_HOME=$HOME/.codex)
|
|
12
|
+
// - kiro : bin `kiro`; dir ~/.kiro (public/install-kiro.sh: ~/.kiro global)
|
|
13
|
+
// - opencode : bin `opencode`; dir ~/.config/opencode (public/install-opencode.sh: OPENCODE_CONFIG_DIR)
|
|
14
|
+
// - openclaw : bin `openclaw`; dir ~/.openclaw|~/.config/openclaw (NOT independently verified — probe both; see NOTE)
|
|
15
|
+
// - pi : bin `pi`; dir ~/.pi|~/.config/pi (NOT independently verified — probe both; see NOTE)
|
|
16
|
+
// - dsh : bin `dsh`; dir $DSH_HOME|~/.dsh ($DSH_HOME per dsh integration; see NOTE)
|
|
17
|
+
//
|
|
18
|
+
// NOTE: openclaw / pi / dsh config-dir specifics were not verifiable on this
|
|
19
|
+
// build host (their CLIs/config were not all present); the descriptors probe the
|
|
20
|
+
// most likely locations. A wrong config-dir guess only weakens the *config-dir*
|
|
21
|
+
// half of the dual signal (the binary-on-PATH half still detects them) and never
|
|
22
|
+
// blocks selection — undetected agents remain selectable. The plugin-install
|
|
23
|
+
// task must still verify each install command against the real CLI.
|
|
24
|
+
|
|
25
|
+
import { readFileSync } from "node:fs";
|
|
26
|
+
import { homedir } from "node:os";
|
|
27
|
+
import { join } from "node:path";
|
|
28
|
+
import { detectSignals } from "./detect.mjs";
|
|
29
|
+
import { OUTCOME_ACTIONS } from "./contracts.mjs";
|
|
30
|
+
import { CHORUS_PLUGIN_ID, CHORUS_MARKETPLACE_NAME, CHORUS_MARKETPLACE_SOURCE } from "./chorus-plugin-consts.mjs";
|
|
31
|
+
import {
|
|
32
|
+
installClaude,
|
|
33
|
+
installCodex,
|
|
34
|
+
installOpencode,
|
|
35
|
+
installDsh,
|
|
36
|
+
installOpenclaw,
|
|
37
|
+
installKiro,
|
|
38
|
+
readCodexInstallState,
|
|
39
|
+
readOpencodeInstallState,
|
|
40
|
+
readDshInstallState,
|
|
41
|
+
readOpenclawInstallState,
|
|
42
|
+
readKiroInstallState,
|
|
43
|
+
guided,
|
|
44
|
+
GUIDED_MESSAGES,
|
|
45
|
+
} from "./install-methods.mjs";
|
|
46
|
+
|
|
47
|
+
// Re-export the shared marketplace identifiers from their canonical home so
|
|
48
|
+
// existing importers of these names from adapters.mjs keep working.
|
|
49
|
+
export { CHORUS_PLUGIN_ID, CHORUS_MARKETPLACE_NAME, CHORUS_MARKETPLACE_SOURCE };
|
|
50
|
+
|
|
51
|
+
/** Read + JSON-parse a file, or null on any error. Never throws. */
|
|
52
|
+
function readJsonSafe(path) {
|
|
53
|
+
try {
|
|
54
|
+
return JSON.parse(readFileSync(path, "utf8"));
|
|
55
|
+
} catch {
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Claude Code install-state reader (verified against CC 2.1.235 on-disk layout):
|
|
62
|
+
* `~/.claude/plugins/installed_plugins.json` (v2 keyed by `<plugin>@<marketplace>`)
|
|
63
|
+
* and `known_marketplaces.json`. Read-only — never hand-writes these files.
|
|
64
|
+
* @param {{ home?: string, readJson?: (p: string) => any }} [deps]
|
|
65
|
+
* @returns {{ marketplaceRegistered: boolean, pluginInstalled: boolean, version?: string }}
|
|
66
|
+
*/
|
|
67
|
+
export function readClaudeInstallState({ home = homedir(), readJson = readJsonSafe } = {}) {
|
|
68
|
+
const pluginsDir = join(home, ".claude", "plugins");
|
|
69
|
+
const installed = readJson(join(pluginsDir, "installed_plugins.json"));
|
|
70
|
+
const markets = readJson(join(pluginsDir, "known_marketplaces.json"));
|
|
71
|
+
|
|
72
|
+
const marketplaceRegistered = !!(markets && typeof markets === "object" && markets[CHORUS_MARKETPLACE_NAME]);
|
|
73
|
+
|
|
74
|
+
let pluginInstalled = false;
|
|
75
|
+
let version;
|
|
76
|
+
const entries = installed && typeof installed === "object" ? installed.plugins?.[CHORUS_PLUGIN_ID] : null;
|
|
77
|
+
if (Array.isArray(entries) && entries.length > 0) {
|
|
78
|
+
pluginInstalled = true;
|
|
79
|
+
version = entries[0]?.version;
|
|
80
|
+
}
|
|
81
|
+
return { marketplaceRegistered, pluginInstalled, version };
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* The supported-agent descriptors. `install` / `readState` are optional hooks the
|
|
86
|
+
* plugin-install task fills in per agent; absent ⇒ generic behavior.
|
|
87
|
+
* @type {Array<{
|
|
88
|
+
* id: string, displayName: string, binaries: string[], configDirs: string[],
|
|
89
|
+
* readState?: (deps: object) => object, install?: (ctx: object) => object,
|
|
90
|
+
* }>}
|
|
91
|
+
*/
|
|
92
|
+
export const AGENT_DESCRIPTORS = [
|
|
93
|
+
{ id: "claude", displayName: "Claude Code", binaries: ["claude"], configDirs: ["~/.claude"], readState: readClaudeInstallState, install: installClaude },
|
|
94
|
+
{ id: "codex", displayName: "Codex CLI", binaries: ["codex"], configDirs: ["~/.codex"], readState: readCodexInstallState, install: installCodex },
|
|
95
|
+
{ id: "kiro", displayName: "Kiro CLI", binaries: ["kiro"], configDirs: ["~/.kiro"], readState: readKiroInstallState, install: installKiro },
|
|
96
|
+
{ id: "opencode", displayName: "opencode", binaries: ["opencode"], configDirs: ["~/.config/opencode", "~/.opencode"], readState: readOpencodeInstallState, install: installOpencode },
|
|
97
|
+
{ id: "openclaw", displayName: "OpenClaw", binaries: ["openclaw"], configDirs: ["~/.openclaw", "~/.config/openclaw"], readState: readOpenclawInstallState, install: installOpenclaw },
|
|
98
|
+
{ id: "pi", displayName: "Pi", binaries: ["pi"], configDirs: ["~/.pi", "~/.config/pi"], install: guided("pi", GUIDED_MESSAGES.pi) },
|
|
99
|
+
{ id: "dsh", displayName: "DeepSeek Harness (dsh)", binaries: ["dsh"], configDirs: ["$DSH_HOME", "~/.dsh"], readState: readDshInstallState, install: installDsh },
|
|
100
|
+
];
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Build an AgentAdapter from a descriptor.
|
|
104
|
+
* @param {typeof AGENT_DESCRIPTORS[number]} d
|
|
105
|
+
* @returns {import("./contracts.mjs").AgentAdapter}
|
|
106
|
+
*/
|
|
107
|
+
export function buildAdapter(d) {
|
|
108
|
+
return {
|
|
109
|
+
id: d.id,
|
|
110
|
+
displayName: d.displayName,
|
|
111
|
+
detect: (env = process.env) => detectSignals(d, { env }),
|
|
112
|
+
readInstallState: (deps = {}) => {
|
|
113
|
+
const base = typeof d.readState === "function"
|
|
114
|
+
? d.readState(deps)
|
|
115
|
+
: { marketplaceRegistered: false, pluginInstalled: false };
|
|
116
|
+
// `supported` = a REAL automated install path exists for this agent. A
|
|
117
|
+
// `guided()` fallback also returns a function (so `typeof d.install ===
|
|
118
|
+
// "function"` alone would report every fallback agent as supported — the
|
|
119
|
+
// pre-existing latent bug); guided installers are tagged `.guided === true`,
|
|
120
|
+
// so exclude them here. Real installers (claude/codex/opencode + dsh/openclaw/
|
|
121
|
+
// kiro) → true; guided (pi) → false.
|
|
122
|
+
return { supported: typeof d.install === "function" && d.install.guided !== true, ...base };
|
|
123
|
+
},
|
|
124
|
+
installPlugin: (ctx = {}) =>
|
|
125
|
+
typeof d.install === "function"
|
|
126
|
+
? d.install(ctx)
|
|
127
|
+
: {
|
|
128
|
+
stepId: "plugin-install",
|
|
129
|
+
agentId: d.id,
|
|
130
|
+
action: OUTCOME_ACTIONS.UNSUPPORTED,
|
|
131
|
+
detail: `no automated plugin install for ${d.displayName} yet — configure manually`,
|
|
132
|
+
},
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/** All supported adapters, built from the descriptors. */
|
|
137
|
+
export const ADAPTERS = AGENT_DESCRIPTORS.map(buildAdapter);
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
// cli/init/agent-type-map.mjs
|
|
2
|
+
// The single translation between a `chorus init` adapter selection id (see
|
|
3
|
+
// cli/init/adapters.mjs — "claude" | "codex" | "kiro" | "opencode" | "openclaw" |
|
|
4
|
+
// "pi" | "dsh") and the daemon's agentType vocabulary (cli/daemon-agent.mjs
|
|
5
|
+
// KNOWN_AGENTS). It lives in ONE place so the credential-seed step (which writes
|
|
6
|
+
// each selected agent's daemon.json agents[] entry) and the daemon-setup step
|
|
7
|
+
// (which gates auto-start on whether any selected agent is wakeable) can never
|
|
8
|
+
// disagree about how a selection maps to a backend.
|
|
9
|
+
//
|
|
10
|
+
// Two rules the callers rely on:
|
|
11
|
+
// 1. The init id "claude" is NOT the daemon agentType — it renames to
|
|
12
|
+
// "claude-code" EXPLICITLY here. No caller ever passes the raw init id
|
|
13
|
+
// through to daemon.json; every write goes through agentTypeForSelection.
|
|
14
|
+
// 2. Any selection the daemon cannot wake as a first-class backend
|
|
15
|
+
// (opencode / openclaw / pi, and dsh while its harness is dormant/offline)
|
|
16
|
+
// maps to the non-wakeable "offline" classification. Its key is still parked
|
|
17
|
+
// in agents[] for the `chorus mcp` proxy, but the daemon builds no spawner
|
|
18
|
+
// and dispatches no wake (spawner-select.mjs fail-closes on "offline").
|
|
19
|
+
//
|
|
20
|
+
// Fail-closed by default: an unknown / unmapped id maps to "offline" rather than a
|
|
21
|
+
// wakeable backend, so a future adapter added without a mapping is never silently
|
|
22
|
+
// woken as claude-code.
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Selection id → daemon agentType. Only claude/codex/kiro are wakeable backends;
|
|
26
|
+
* everything else is classified offline. `dsh` maps to offline because the dsh
|
|
27
|
+
* harness is de-advertised (offline) — re-map it here to bring it back online.
|
|
28
|
+
* @type {Readonly<Record<string, string>>}
|
|
29
|
+
*/
|
|
30
|
+
export const SELECTION_TO_AGENT_TYPE = Object.freeze({
|
|
31
|
+
claude: "claude-code", // explicit rename — never pass the init id "claude" through verbatim
|
|
32
|
+
codex: "codex",
|
|
33
|
+
kiro: "kiro",
|
|
34
|
+
opencode: "offline",
|
|
35
|
+
openclaw: "offline",
|
|
36
|
+
pi: "offline",
|
|
37
|
+
dsh: "offline",
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Map a `chorus init` selection id to the daemon agentType written into
|
|
42
|
+
* daemon.json `agents[]`. Unknown ids fail closed to "offline" (never a wakeable
|
|
43
|
+
* default), so an agent is only ever woken when its backend is explicitly known.
|
|
44
|
+
* @param {string} selectionId
|
|
45
|
+
* @returns {string} a KNOWN_AGENTS agentType ("claude-code" | "codex" | "kiro" | "offline")
|
|
46
|
+
*/
|
|
47
|
+
export function agentTypeForSelection(selectionId) {
|
|
48
|
+
return SELECTION_TO_AGENT_TYPE[selectionId] ?? "offline";
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Whether a daemon agentType is one the daemon can actually wake. "offline" is the
|
|
53
|
+
* one non-wakeable classification; every other value the init mapping produces
|
|
54
|
+
* (claude-code / codex / kiro) is wakeable.
|
|
55
|
+
* @param {string} agentType
|
|
56
|
+
* @returns {boolean}
|
|
57
|
+
*/
|
|
58
|
+
export function isWakeableAgentType(agentType) {
|
|
59
|
+
return agentType !== "offline";
|
|
60
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// cli/init/chorus-plugin-consts.mjs
|
|
2
|
+
// Canonical Chorus plugin/marketplace identifiers, shared by the adapters and the
|
|
3
|
+
// per-agent install methods. Kept in its own module so adapters.mjs and
|
|
4
|
+
// install-methods.mjs can both import them without a circular dependency.
|
|
5
|
+
|
|
6
|
+
/** Plugin selector used by marketplace-based agents (Claude Code, Codex). */
|
|
7
|
+
export const CHORUS_PLUGIN_ID = "chorus@chorus-plugins";
|
|
8
|
+
/** Marketplace name as it appears in agents' on-disk state. */
|
|
9
|
+
export const CHORUS_MARKETPLACE_NAME = "chorus-plugins";
|
|
10
|
+
/**
|
|
11
|
+
* Remote marketplace source (owner decision: each agent's NATIVE REMOTE
|
|
12
|
+
* marketplace, not a local bundle). Overridable per invocation via
|
|
13
|
+
* CHORUS_MARKETPLACE_SOURCE. Accepted by `claude plugin marketplace add`
|
|
14
|
+
* (URL/path/repo). Codex prefers the `owner/repo` slug — see installCodex.
|
|
15
|
+
*/
|
|
16
|
+
export const CHORUS_MARKETPLACE_SOURCE = "https://github.com/Chorus-AIDLC/Chorus";
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
// cli/init/codex-mcp-config.mjs
|
|
2
|
+
// Writes the Chorus native-MCP server block into ~/.codex/config.toml using a KEYLESS
|
|
3
|
+
// env-var reference — `bearer_token_env_var = "CHORUS_API_KEY"` — instead of a literal
|
|
4
|
+
// `Authorization: Bearer <key>`. Codex loads ~/.codex/.env into its process env at arg0
|
|
5
|
+
// startup and resolves that env var into `Authorization: Bearer <key>` at connect time
|
|
6
|
+
// (config/src/mcp_types.rs StreamableHttp.bearer_token_env_var; codex-mcp resolve_bearer_token),
|
|
7
|
+
// so the API key lives in exactly ONE place (~/.codex/.env). A daemon-woken Codex — whose
|
|
8
|
+
// spawner exports CHORUS_API_KEY into the child env — then also authenticates to native MCP,
|
|
9
|
+
// closing the gap a literal Bearer left (cli/codex-spawner.mjs:16-22).
|
|
10
|
+
//
|
|
11
|
+
// `codex plugin add` does NOT write [mcp_servers.chorus] (its marketplace `authentication:
|
|
12
|
+
// ON_INSTALL` is metadata only — verified codex-cli 0.150.1), so `chorus agents add` writes it
|
|
13
|
+
// here, AFTER the plugin install (authoritative, no race).
|
|
14
|
+
//
|
|
15
|
+
// TARGETED TEXTUAL upsert — no TOML-parser dependency (the repo stays pure-JS / cross-platform),
|
|
16
|
+
// preserving every other section, key, and comment verbatim. The secret is NEVER written here
|
|
17
|
+
// (bearer_token_env_var is a variable NAME, not the key).
|
|
18
|
+
|
|
19
|
+
import { mkdirSync, readFileSync, renameSync, writeFileSync } from "node:fs";
|
|
20
|
+
import { homedir } from "node:os";
|
|
21
|
+
import { dirname, join } from "node:path";
|
|
22
|
+
|
|
23
|
+
const BEARER_ENV_VAR = "CHORUS_API_KEY";
|
|
24
|
+
|
|
25
|
+
/** A non-empty trimmed string, or undefined. */
|
|
26
|
+
function nonEmpty(value) {
|
|
27
|
+
return typeof value === "string" && value.trim() ? value.trim() : undefined;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Resolve the Codex `~/.codex/config.toml` path. Honors `CODEX_HOME`, then `HOME` (so tests
|
|
32
|
+
* can inject a temp home), else the OS home dir — matching cli/codex-spawner.mjs +
|
|
33
|
+
* install-methods.mjs.
|
|
34
|
+
* @param {Record<string, string | undefined>} env
|
|
35
|
+
*/
|
|
36
|
+
export function resolveCodexConfigPath(env) {
|
|
37
|
+
const base = nonEmpty(env.CODEX_HOME) ?? join(nonEmpty(env.HOME) ?? homedir(), ".codex");
|
|
38
|
+
return join(base, "config.toml");
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Normalize a Chorus base URL to the MCP endpoint the same way the hook wrapper
|
|
43
|
+
* (chorus-mcp-call.sh) does: a URL that already has a path segment beyond the host is used
|
|
44
|
+
* as-is; a bare host gains `/api/mcp`. Returns undefined for an empty URL.
|
|
45
|
+
* @param {string | undefined} rawUrl
|
|
46
|
+
*/
|
|
47
|
+
export function codexMcpUrl(rawUrl) {
|
|
48
|
+
const u = nonEmpty(rawUrl);
|
|
49
|
+
if (!u) return undefined;
|
|
50
|
+
const trimmed = u.replace(/\/+$/, "");
|
|
51
|
+
const m = trimmed.match(/^https?:\/\/[^/]+(\/.*)?$/);
|
|
52
|
+
if (m && m[1] && m[1].length > 0) return trimmed; // already a full endpoint
|
|
53
|
+
return `${trimmed}/api/mcp`;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// TOML basic-string value: escape backslash then double-quote. URLs don't contain these, but
|
|
57
|
+
// escape defensively so we never emit invalid TOML.
|
|
58
|
+
const toToml = (v) => `"${String(v).replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`;
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Upsert `[mcp_servers.chorus]` in `~/.codex/config.toml` to
|
|
62
|
+
* url = "<mcp-endpoint>"
|
|
63
|
+
* bearer_token_env_var = "CHORUS_API_KEY"
|
|
64
|
+
* and MIGRATE away any legacy literal auth: a `bearer_token = "..."` line is dropped, and a
|
|
65
|
+
* `[mcp_servers.chorus.http_headers]` `Authorization = "..."` line is removed (dropping the
|
|
66
|
+
* whole http_headers subtable when it becomes empty, preserving any OTHER header). Every other
|
|
67
|
+
* section/key/comment in the file is preserved verbatim.
|
|
68
|
+
*
|
|
69
|
+
* Atomic 0600 temp+rename; idempotent (a re-run with the same url reproduces the file). The API
|
|
70
|
+
* key is NEVER written — only the env-var NAME.
|
|
71
|
+
* @param {{ configPath: string, url: string }} args
|
|
72
|
+
* @param {{
|
|
73
|
+
* read?: (p: string) => string,
|
|
74
|
+
* write?: (p: string, c: string, o: object) => void,
|
|
75
|
+
* mkdir?: (p: string, o: object) => void,
|
|
76
|
+
* rename?: (from: string, to: string) => void,
|
|
77
|
+
* }} [deps]
|
|
78
|
+
* @returns {string} the config.toml path written
|
|
79
|
+
*/
|
|
80
|
+
export function writeCodexMcpServer({ configPath, url }, deps = {}) {
|
|
81
|
+
const read = deps.read ?? ((p) => readFileSync(p, "utf8"));
|
|
82
|
+
const write = deps.write ?? writeFileSync;
|
|
83
|
+
const mkdir = deps.mkdir ?? mkdirSync;
|
|
84
|
+
const rename = deps.rename ?? renameSync;
|
|
85
|
+
|
|
86
|
+
const mcpUrl = codexMcpUrl(url);
|
|
87
|
+
if (!mcpUrl) throw new Error("writeCodexMcpServer requires a url");
|
|
88
|
+
|
|
89
|
+
let existing = "";
|
|
90
|
+
try {
|
|
91
|
+
existing = read(configPath);
|
|
92
|
+
} catch {
|
|
93
|
+
existing = ""; // no file yet — start fresh
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const lines = existing.length ? existing.split(/\r?\n/) : [];
|
|
97
|
+
if (lines.length && lines[lines.length - 1] === "") lines.pop();
|
|
98
|
+
|
|
99
|
+
const isHeader = (s) => /^\s*\[/.test(s);
|
|
100
|
+
const chorusHeaderRe = /^\s*\[mcp_servers\.chorus\]\s*$/;
|
|
101
|
+
const headersHeaderRe = /^\s*\[mcp_servers\.chorus\.http_headers\]\s*$/;
|
|
102
|
+
// A `key = value` line (not a comment or blank) — used to tell whether a subtable still has
|
|
103
|
+
// content after removing Authorization.
|
|
104
|
+
const isKvLine = (s) => /^\s*[^#\s][^=]*=/.test(s);
|
|
105
|
+
|
|
106
|
+
// Split into groups: a preamble (before the first table header) + one group per table header.
|
|
107
|
+
const groups = [];
|
|
108
|
+
let cur = { header: null, body: [] };
|
|
109
|
+
for (const line of lines) {
|
|
110
|
+
if (isHeader(line)) {
|
|
111
|
+
groups.push(cur);
|
|
112
|
+
cur = { header: line, body: [] };
|
|
113
|
+
} else {
|
|
114
|
+
cur.body.push(line);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
groups.push(cur);
|
|
118
|
+
|
|
119
|
+
const outGroups = [];
|
|
120
|
+
let wroteChorus = false;
|
|
121
|
+
for (const g of groups) {
|
|
122
|
+
if (g.header === null) {
|
|
123
|
+
outGroups.push(...g.body); // preamble verbatim
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
if (chorusHeaderRe.test(g.header)) {
|
|
127
|
+
// Normalize the [mcp_servers.chorus] body: set url + bearer_token_env_var in place,
|
|
128
|
+
// drop any literal bearer_token, preserve every other key.
|
|
129
|
+
let seenUrl = false;
|
|
130
|
+
let seenBearerEnv = false;
|
|
131
|
+
const body = [];
|
|
132
|
+
for (const l of g.body) {
|
|
133
|
+
if (/^\s*url\s*=/.test(l)) {
|
|
134
|
+
body.push(`url = ${toToml(mcpUrl)}`);
|
|
135
|
+
seenUrl = true;
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
if (/^\s*bearer_token_env_var\s*=/.test(l)) {
|
|
139
|
+
body.push(`bearer_token_env_var = ${toToml(BEARER_ENV_VAR)}`);
|
|
140
|
+
seenBearerEnv = true;
|
|
141
|
+
continue;
|
|
142
|
+
}
|
|
143
|
+
if (/^\s*bearer_token\s*=/.test(l)) continue; // drop legacy literal bearer_token
|
|
144
|
+
body.push(l);
|
|
145
|
+
}
|
|
146
|
+
const head = [];
|
|
147
|
+
if (!seenUrl) head.push(`url = ${toToml(mcpUrl)}`);
|
|
148
|
+
if (!seenBearerEnv) head.push(`bearer_token_env_var = ${toToml(BEARER_ENV_VAR)}`);
|
|
149
|
+
outGroups.push(g.header, ...head, ...body);
|
|
150
|
+
wroteChorus = true;
|
|
151
|
+
continue;
|
|
152
|
+
}
|
|
153
|
+
if (headersHeaderRe.test(g.header)) {
|
|
154
|
+
// Strip the literal Authorization; drop the whole subtable if nothing else remains.
|
|
155
|
+
const body = g.body.filter((l) => !/^\s*Authorization\s*=/i.test(l));
|
|
156
|
+
if (body.some(isKvLine)) {
|
|
157
|
+
outGroups.push(g.header, ...body);
|
|
158
|
+
}
|
|
159
|
+
// else: drop the emptied subtable entirely
|
|
160
|
+
continue;
|
|
161
|
+
}
|
|
162
|
+
outGroups.push(g.header, ...g.body);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
if (!wroteChorus) {
|
|
166
|
+
if (outGroups.length && outGroups[outGroups.length - 1] !== "") outGroups.push("");
|
|
167
|
+
outGroups.push(
|
|
168
|
+
"[mcp_servers.chorus]",
|
|
169
|
+
`url = ${toToml(mcpUrl)}`,
|
|
170
|
+
`bearer_token_env_var = ${toToml(BEARER_ENV_VAR)}`,
|
|
171
|
+
);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// Trim trailing blank lines so idempotent re-runs never accumulate them.
|
|
175
|
+
while (outGroups.length && outGroups[outGroups.length - 1] === "") outGroups.pop();
|
|
176
|
+
const content = outGroups.join("\n") + "\n";
|
|
177
|
+
|
|
178
|
+
mkdir(dirname(configPath), { recursive: true });
|
|
179
|
+
const tmp = `${configPath}.tmp`;
|
|
180
|
+
write(tmp, content, { mode: 0o600 });
|
|
181
|
+
rename(tmp, configPath);
|
|
182
|
+
return configPath;
|
|
183
|
+
}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
// cli/init/contracts.mjs
|
|
2
|
+
// Shared contracts for `chorus init` (idea c055e285, A1 foundation). Two
|
|
3
|
+
// extension points let sibling ideas grow the command without editing its core:
|
|
4
|
+
//
|
|
5
|
+
// 1. AgentAdapter — one per coding-agent harness (Claude Code, Codex, Kiro,
|
|
6
|
+
// opencode, OpenClaw, Pi, dsh). Adding an agent = adding an adapter to the
|
|
7
|
+
// registry (cli/init/registry.mjs). Detection, install-state read, and the
|
|
8
|
+
// plugin install all live behind this interface.
|
|
9
|
+
//
|
|
10
|
+
// 2. InitStep — one per configuration concern. THIS change ships the
|
|
11
|
+
// credential-seed step (scope "once") and the plugin-install step (scope
|
|
12
|
+
// "per-agent"). Sibling ideas register more steps (MCP proxy cc115e6b,
|
|
13
|
+
// daemon setup a7c2a3e8) into the same ordered registry.
|
|
14
|
+
//
|
|
15
|
+
// Iteration ownership (resolves proposal-review note #3): the ORCHESTRATOR
|
|
16
|
+
// (runInit) owns per-agent iteration. A `per-agent` step's run(ctx) is invoked
|
|
17
|
+
// once per selected agent with ctx.agentId set; a `once` step's run(ctx) is
|
|
18
|
+
// invoked a single time with ctx.agentId undefined. Steps never loop the
|
|
19
|
+
// selection themselves.
|
|
20
|
+
//
|
|
21
|
+
// Plain ESM, zero dependencies — ships verbatim in the npm package. This module
|
|
22
|
+
// is intentionally (mostly) JSDoc typedefs plus a few frozen enums so the shape
|
|
23
|
+
// is one source of truth for the whole cli/init tree and its tests.
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Step scopes. `once` runs a single time per `chorus init` invocation;
|
|
27
|
+
* `per-agent` runs once for each selected agent.
|
|
28
|
+
* @readonly
|
|
29
|
+
*/
|
|
30
|
+
export const STEP_SCOPES = Object.freeze({ ONCE: "once", PER_AGENT: "per-agent" });
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Terminal per-unit outcomes a step reports for the summary table.
|
|
34
|
+
* - installed: a fresh configuration was applied
|
|
35
|
+
* - repaired: an existing but incomplete/broken configuration was fixed
|
|
36
|
+
* - skipped: already configured / nothing to do
|
|
37
|
+
* - seeded: a `once` step persisted shared state (e.g. credentials)
|
|
38
|
+
* - failed: the unit could not be configured (detail carries the reason)
|
|
39
|
+
* - unsupported: the agent has no verified automated mechanism (guided message)
|
|
40
|
+
* @readonly
|
|
41
|
+
*/
|
|
42
|
+
export const OUTCOME_ACTIONS = Object.freeze({
|
|
43
|
+
INSTALLED: "installed",
|
|
44
|
+
REPAIRED: "repaired",
|
|
45
|
+
SKIPPED: "skipped",
|
|
46
|
+
SEEDED: "seeded",
|
|
47
|
+
FAILED: "failed",
|
|
48
|
+
UNSUPPORTED: "unsupported",
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
/** Outcome actions that mean "this unit did not succeed" — drive the exit code. */
|
|
52
|
+
export const FAILURE_ACTIONS = Object.freeze([OUTCOME_ACTIONS.FAILED]);
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* @typedef {Object} AgentDetection
|
|
56
|
+
* @property {string} id Stable adapter id (e.g. "claude").
|
|
57
|
+
* @property {string} displayName Human label (e.g. "Claude Code").
|
|
58
|
+
* @property {boolean} binaryOnPath Whether the agent's CLI resolves on PATH.
|
|
59
|
+
* @property {boolean} configDirPresent Whether the agent's config dir exists.
|
|
60
|
+
* @property {boolean} detected `binaryOnPath || configDirPresent` — drives
|
|
61
|
+
* default pre-selection only, never gates choice.
|
|
62
|
+
*/
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* @typedef {Object} AgentInstallState
|
|
66
|
+
* @property {boolean} supported Whether an automated install is available on
|
|
67
|
+
* this machine (false ⇒ guided message only).
|
|
68
|
+
* @property {boolean} marketplaceRegistered Whether the Chorus marketplace/source
|
|
69
|
+
* is already registered for this agent.
|
|
70
|
+
* @property {boolean} pluginInstalled Whether the Chorus plugin is already installed.
|
|
71
|
+
* @property {string} [version] Installed plugin version, when known.
|
|
72
|
+
* @property {string} [detail] Optional human note (e.g. why unsupported).
|
|
73
|
+
*/
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* @typedef {Object} AgentAdapter
|
|
77
|
+
* @property {string} id
|
|
78
|
+
* @property {string} displayName
|
|
79
|
+
* @property {(env: NodeJS.ProcessEnv) => {binaryOnPath: boolean, configDirPresent: boolean}} detect
|
|
80
|
+
* Pure-ish: may stat the filesystem and look up PATH; MUST NOT mutate anything.
|
|
81
|
+
* @property {(deps: object) => AgentInstallState} readInstallState
|
|
82
|
+
* Read-only idempotency probe (e.g. parse the agent's own state files).
|
|
83
|
+
* @property {(ctx: StepContext) => StepOutcome} installPlugin
|
|
84
|
+
* Register the agent's native remote marketplace and install/enable the Chorus
|
|
85
|
+
* plugin surface. MUST be idempotent, MUST back up before overwrite via
|
|
86
|
+
* ctx.backup(), and MUST NOT write any per-agent MCP/credential config.
|
|
87
|
+
*/
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* @typedef {Object} InitStep
|
|
91
|
+
* @property {string} id Stable step id (e.g. "credential-seed").
|
|
92
|
+
* @property {number} order Ascending run order.
|
|
93
|
+
* @property {("once"|"per-agent")} scope
|
|
94
|
+
* @property {(ctx: StepContext) => (StepOutcome | Promise<StepOutcome>)} run
|
|
95
|
+
*/
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* @typedef {Object} StepOutcome
|
|
99
|
+
* @property {string} stepId
|
|
100
|
+
* @property {string} [agentId] Present for per-agent outcomes.
|
|
101
|
+
* @property {("installed"|"repaired"|"skipped"|"seeded"|"failed"|"unsupported")} action
|
|
102
|
+
* @property {string} detail One-line human explanation for the summary.
|
|
103
|
+
*/
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* @typedef {Object} StepContext
|
|
107
|
+
* @property {string[]} selection Selected agent ids (for `once` steps that need the set).
|
|
108
|
+
* @property {string} [agentId] The current agent id (per-agent steps only).
|
|
109
|
+
* @property {AgentAdapter} [adapter] The current agent's adapter (per-agent steps only).
|
|
110
|
+
* @property {object} flags Parsed init flags (see cli/init-args.mjs).
|
|
111
|
+
* @property {{ log: (m: string) => void, ask: Function, isTTY: boolean }} io
|
|
112
|
+
* @property {(path: string) => (string|null)} backup Copy a file to <path>.chorus-bak
|
|
113
|
+
* once before overwrite; returns the backup path or null if the source is absent.
|
|
114
|
+
* @property {NodeJS.ProcessEnv} env
|
|
115
|
+
*/
|
|
116
|
+
|
|
117
|
+
/** True when an outcome represents a failure (drives the process exit code). */
|
|
118
|
+
export function isFailureOutcome(outcome) {
|
|
119
|
+
return !!outcome && FAILURE_ACTIONS.includes(outcome.action);
|
|
120
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
// cli/init/detect.mjs
|
|
2
|
+
// Cross-platform detection primitives for `chorus init` adapters. Dual signal:
|
|
3
|
+
// a CLI binary resolvable on PATH, and/or an agent config directory present.
|
|
4
|
+
// All IO (env, filesystem, platform, home) is injectable so adapters unit-test
|
|
5
|
+
// without a real machine. Zero runtime dependencies beyond node core.
|
|
6
|
+
|
|
7
|
+
import { existsSync as fsExistsSync } from "node:fs";
|
|
8
|
+
import { homedir } from "node:os";
|
|
9
|
+
import { join, delimiter as pathDelimiter } from "node:path";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Expand a config-dir spec into an absolute path:
|
|
13
|
+
* - a leading `~` → the home directory,
|
|
14
|
+
* - a leading `$VAR` segment → env[VAR] (whole spec dropped if unset),
|
|
15
|
+
* Returns null when the spec cannot be resolved (e.g. `$DSH_HOME` unset).
|
|
16
|
+
* @param {string} spec
|
|
17
|
+
* @param {{ env?: Record<string,string|undefined>, home?: string }} [deps]
|
|
18
|
+
* @returns {string | null}
|
|
19
|
+
*/
|
|
20
|
+
export function expandPath(spec, { env = process.env, home = homedir() } = {}) {
|
|
21
|
+
if (typeof spec !== "string" || !spec) return null;
|
|
22
|
+
if (spec.startsWith("~")) {
|
|
23
|
+
return join(home, spec.slice(1).replace(/^[/\\]/, ""));
|
|
24
|
+
}
|
|
25
|
+
if (spec.startsWith("$")) {
|
|
26
|
+
const slash = spec.search(/[/\\]/);
|
|
27
|
+
const varName = (slash === -1 ? spec.slice(1) : spec.slice(1, slash));
|
|
28
|
+
const value = env[varName];
|
|
29
|
+
if (!value) return null; // unset env var → this candidate does not apply
|
|
30
|
+
const rest = slash === -1 ? "" : spec.slice(slash + 1);
|
|
31
|
+
return rest ? join(value, rest) : value;
|
|
32
|
+
}
|
|
33
|
+
return spec;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* True if any of `names` resolves to an executable on PATH. Scans PATH entries
|
|
38
|
+
* and (on Windows) the PATHEXT extension list. Pure lookup — never executes.
|
|
39
|
+
* @param {string[]} names candidate binary base names (e.g. ["claude"])
|
|
40
|
+
* @param {{
|
|
41
|
+
* env?: Record<string,string|undefined>,
|
|
42
|
+
* existsSync?: (p: string) => boolean,
|
|
43
|
+
* platform?: NodeJS.Platform,
|
|
44
|
+
* }} [deps]
|
|
45
|
+
* @returns {boolean}
|
|
46
|
+
*/
|
|
47
|
+
export function binaryOnPath(names, { env = process.env, existsSync = fsExistsSync, platform = process.platform } = {}) {
|
|
48
|
+
const rawPath = env.PATH ?? env.Path ?? "";
|
|
49
|
+
if (!rawPath) return false;
|
|
50
|
+
const sep = platform === "win32" ? ";" : pathDelimiter;
|
|
51
|
+
const dirs = rawPath.split(sep).filter(Boolean);
|
|
52
|
+
const exts =
|
|
53
|
+
platform === "win32"
|
|
54
|
+
? ["", ...String(env.PATHEXT ?? ".EXE;.CMD;.BAT;.COM").split(";").filter(Boolean)]
|
|
55
|
+
: [""];
|
|
56
|
+
for (const name of names) {
|
|
57
|
+
if (!name) continue;
|
|
58
|
+
for (const dir of dirs) {
|
|
59
|
+
for (const ext of exts) {
|
|
60
|
+
// Windows filesystems are case-insensitive; try the ext as-given.
|
|
61
|
+
if (existsSync(join(dir, name + ext))) return true;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* True if any of the config-dir specs (after expandPath) exists on disk.
|
|
70
|
+
* @param {string[]} specs
|
|
71
|
+
* @param {{
|
|
72
|
+
* env?: Record<string,string|undefined>,
|
|
73
|
+
* existsSync?: (p: string) => boolean,
|
|
74
|
+
* home?: string,
|
|
75
|
+
* }} [deps]
|
|
76
|
+
* @returns {boolean}
|
|
77
|
+
*/
|
|
78
|
+
export function configDirPresent(specs, { env = process.env, existsSync = fsExistsSync, home = homedir() } = {}) {
|
|
79
|
+
for (const spec of specs || []) {
|
|
80
|
+
const resolved = expandPath(spec, { env, home });
|
|
81
|
+
if (resolved && existsSync(resolved)) return true;
|
|
82
|
+
}
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Compute the dual-signal detection for one agent descriptor.
|
|
88
|
+
* @param {{ binaries: string[], configDirs: string[] }} descriptor
|
|
89
|
+
* @param {object} [deps] forwarded to binaryOnPath / configDirPresent
|
|
90
|
+
* @returns {{ binaryOnPath: boolean, configDirPresent: boolean }}
|
|
91
|
+
*/
|
|
92
|
+
export function detectSignals(descriptor, deps = {}) {
|
|
93
|
+
return {
|
|
94
|
+
binaryOnPath: binaryOnPath(descriptor.binaries || [], deps),
|
|
95
|
+
configDirPresent: configDirPresent(descriptor.configDirs || [], deps),
|
|
96
|
+
};
|
|
97
|
+
}
|