@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,508 @@
|
|
|
1
|
+
// cli/init/install-methods.mjs
|
|
2
|
+
// Per-agent plugin-surface install functions (descriptor.install hooks). Each
|
|
3
|
+
// takes a StepContext and returns a StepOutcome. Every command shape below was
|
|
4
|
+
// verified against the agent's REAL CLI `--help` (not LLM memory) — see the
|
|
5
|
+
// per-function VERIFIED notes. Agents whose install cannot be verified ship a
|
|
6
|
+
// guided message via `guided()` rather than a guessed command.
|
|
7
|
+
//
|
|
8
|
+
// All shell-outs go through ctx.run (default cli/init/run-command.mjs) so this
|
|
9
|
+
// unit-tests without executing anything. These functions write the plugin surface
|
|
10
|
+
// (and, per agent, the MCP-server config that references credentials by env-var —
|
|
11
|
+
// e.g. Codex's keyless [mcp_servers.chorus] bearer_token_env_var, Kiro's ${env:...}
|
|
12
|
+
// mcp.json) — but NEVER a literal API key/secret (those live in the credential sinks).
|
|
13
|
+
|
|
14
|
+
import { readFileSync, existsSync, readdirSync } from "node:fs";
|
|
15
|
+
import { homedir } from "node:os";
|
|
16
|
+
import { join } from "node:path";
|
|
17
|
+
import { fileURLToPath } from "node:url";
|
|
18
|
+
import { runCommand } from "./run-command.mjs";
|
|
19
|
+
import { binaryOnPath } from "./detect.mjs";
|
|
20
|
+
import { installFileTemplate } from "./file-template.mjs";
|
|
21
|
+
import { OUTCOME_ACTIONS } from "./contracts.mjs";
|
|
22
|
+
import { CHORUS_PLUGIN_ID, CHORUS_MARKETPLACE_NAME, CHORUS_MARKETPLACE_SOURCE } from "./chorus-plugin-consts.mjs";
|
|
23
|
+
import { writeCodexMcpServer } from "./codex-mcp-config.mjs";
|
|
24
|
+
import { resolveCredentials } from "../credentials.mjs";
|
|
25
|
+
|
|
26
|
+
const STEP_ID = "plugin-install";
|
|
27
|
+
const { INSTALLED, REPAIRED, SKIPPED, FAILED, UNSUPPORTED } = OUTCOME_ACTIONS;
|
|
28
|
+
|
|
29
|
+
const out = (agentId, action, detail) => ({ stepId: STEP_ID, agentId, action, detail });
|
|
30
|
+
|
|
31
|
+
/** First non-empty line of a command result's stderr/stdout, trimmed short. */
|
|
32
|
+
function errText(r) {
|
|
33
|
+
const t = (r?.stderr || r?.error || r?.stdout || "").trim().split("\n")[0] || "unknown error";
|
|
34
|
+
return t.length > 160 ? `${t.slice(0, 157)}…` : t;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** Read the adapter's install state defensively. `extra` carries per-agent deps
|
|
38
|
+
* the state reader needs beyond `env` (e.g. dsh's chosen `profile`). */
|
|
39
|
+
function safeState(ctx, extra = {}) {
|
|
40
|
+
try {
|
|
41
|
+
return ctx.adapter?.readInstallState?.({ env: ctx.env, ...extra }) ?? {};
|
|
42
|
+
} catch {
|
|
43
|
+
return {};
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** A non-empty trimmed string, or undefined. */
|
|
48
|
+
function nonEmpty(value) {
|
|
49
|
+
return typeof value === "string" && value.trim() ? value.trim() : undefined;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function readTextSafe(path) {
|
|
53
|
+
try {
|
|
54
|
+
return readFileSync(path, "utf8");
|
|
55
|
+
} catch {
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function readJsonSafe(path) {
|
|
61
|
+
try {
|
|
62
|
+
return JSON.parse(readFileSync(path, "utf8"));
|
|
63
|
+
} catch {
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// ---------------------------------------------------------------------------
|
|
69
|
+
// Claude Code — VERIFIED against Claude Code 2.1.235:
|
|
70
|
+
// `claude plugin marketplace add <url|path|repo>`
|
|
71
|
+
// `claude plugin install <plugin@marketplace> -y` (-y required when non-TTY)
|
|
72
|
+
// State is read from ~/.claude/plugins/installed_plugins.json (read-only).
|
|
73
|
+
// ---------------------------------------------------------------------------
|
|
74
|
+
export function installClaude(ctx) {
|
|
75
|
+
const run = ctx.run ?? runCommand;
|
|
76
|
+
const env = ctx.env ?? process.env;
|
|
77
|
+
const source = env.CHORUS_MARKETPLACE_SOURCE || CHORUS_MARKETPLACE_SOURCE;
|
|
78
|
+
const state = safeState(ctx);
|
|
79
|
+
if (state.pluginInstalled) {
|
|
80
|
+
return out("claude", SKIPPED, `already installed${state.version ? ` (v${state.version})` : ""}`);
|
|
81
|
+
}
|
|
82
|
+
if (!state.marketplaceRegistered) {
|
|
83
|
+
const r = run("claude", ["plugin", "marketplace", "add", source], { env });
|
|
84
|
+
if (!r.ok) return out("claude", FAILED, `claude plugin marketplace add failed: ${errText(r)}`);
|
|
85
|
+
}
|
|
86
|
+
const r2 = run("claude", ["plugin", "install", CHORUS_PLUGIN_ID, "-y"], { env });
|
|
87
|
+
if (!r2.ok) return out("claude", FAILED, `claude plugin install failed: ${errText(r2)}`);
|
|
88
|
+
return out("claude", state.marketplaceRegistered ? REPAIRED : INSTALLED, `installed ${CHORUS_PLUGIN_ID} via claude plugin CLI`);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// ---------------------------------------------------------------------------
|
|
92
|
+
// Codex — VERIFIED against codex-cli 0.146.1 / 0.150.1:
|
|
93
|
+
// `codex plugin marketplace add <SOURCE>` (SOURCE = local path | owner/repo[@ref] | Git URL)
|
|
94
|
+
// `codex plugin add <PLUGIN@MARKETPLACE> --json`
|
|
95
|
+
// config.toml is backed up before the CLI mutates it.
|
|
96
|
+
//
|
|
97
|
+
// Codex is the ONE exception to this file's "plugin surface only" rule: `codex plugin add`
|
|
98
|
+
// does NOT write the native-MCP block (its marketplace `authentication: ON_INSTALL` is
|
|
99
|
+
// metadata only — verified codex-cli 0.150.1), so after the plugin install we write
|
|
100
|
+
// `[mcp_servers.chorus]` ourselves with a KEYLESS `bearer_token_env_var = "CHORUS_API_KEY"`
|
|
101
|
+
// (writeCodexMcpServer). Codex resolves that env var — which ~/.codex/.env populates — into
|
|
102
|
+
// the Authorization header at connect time, so the API key stays only in ~/.codex/.env and a
|
|
103
|
+
// daemon-woken Codex authenticates too. No secret is written into config.toml.
|
|
104
|
+
// ---------------------------------------------------------------------------
|
|
105
|
+
export function readCodexInstallState({ env = process.env } = {}) {
|
|
106
|
+
const home = env.HOME || homedir();
|
|
107
|
+
const codexHome = env.CODEX_HOME || join(home, ".codex");
|
|
108
|
+
const toml = readTextSafe(join(codexHome, "config.toml")) || "";
|
|
109
|
+
return {
|
|
110
|
+
marketplaceRegistered: toml.includes(`[marketplaces.${CHORUS_MARKETPLACE_NAME}]`),
|
|
111
|
+
pluginInstalled: toml.includes(`[plugins."${CHORUS_PLUGIN_ID}"]`),
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export function installCodex(ctx) {
|
|
116
|
+
const run = ctx.run ?? runCommand;
|
|
117
|
+
const env = ctx.env ?? process.env;
|
|
118
|
+
const home = env.HOME || homedir();
|
|
119
|
+
const codexHome = env.CODEX_HOME || join(home, ".codex");
|
|
120
|
+
const configPath = join(codexHome, "config.toml");
|
|
121
|
+
// Codex accepts owner/repo; allow an override, else the canonical repo slug.
|
|
122
|
+
const source = env.CHORUS_MARKETPLACE_SOURCE_CODEX || "Chorus-AIDLC/Chorus";
|
|
123
|
+
const state = safeState(ctx);
|
|
124
|
+
const writeMcp = ctx.writeCodexMcpServer ?? writeCodexMcpServer;
|
|
125
|
+
const resolveCreds = ctx.resolveCredentials ?? resolveCredentials;
|
|
126
|
+
// URL for the [mcp_servers.chorus] block. Prefer the explicit flag/env; otherwise fall
|
|
127
|
+
// back to the credential resolver, which reads the URL from ~/.chorus/daemon.json
|
|
128
|
+
// (agents[0]) — that covers the interactive path where the operator typed the URL at a
|
|
129
|
+
// prompt (credential-seed, order 10, already wrote it there before this step runs).
|
|
130
|
+
let chorusUrl = nonEmpty(ctx.flags?.url) ?? nonEmpty(env.CHORUS_URL);
|
|
131
|
+
if (!chorusUrl) {
|
|
132
|
+
try {
|
|
133
|
+
chorusUrl = nonEmpty(resolveCreds(ctx.flags ?? {}, { env }).url);
|
|
134
|
+
} catch {
|
|
135
|
+
chorusUrl = undefined; // no complete credentials resolved — ensureMcp() skips with a note
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// Ensure the native-MCP block is present + normalized to the keyless bearer_token_env_var
|
|
140
|
+
// form. Idempotent; runs on both fresh install and re-run. Never writes a secret. A missing
|
|
141
|
+
// URL is a non-fatal skip (the plugin surface is still installed). Returns a note suffix.
|
|
142
|
+
const ensureMcp = () => {
|
|
143
|
+
if (!chorusUrl) {
|
|
144
|
+
return " (skipped [mcp_servers.chorus]: no Chorus URL — pass --url or set CHORUS_URL)";
|
|
145
|
+
}
|
|
146
|
+
try {
|
|
147
|
+
writeMcp({ configPath, url: chorusUrl });
|
|
148
|
+
return ' and wrote [mcp_servers.chorus] (bearer_token_env_var="CHORUS_API_KEY")';
|
|
149
|
+
} catch (err) {
|
|
150
|
+
return ` (WARNING: could not write [mcp_servers.chorus]: ${errText({ error: err?.message ?? String(err) })})`;
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
if (state.pluginInstalled) {
|
|
155
|
+
ctx.backup?.(configPath); // back up before we normalize the MCP block
|
|
156
|
+
return out("codex", SKIPPED, `already installed (config.toml)${ensureMcp()}`);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
ctx.backup?.(configPath); // back up before the CLI edits it
|
|
160
|
+
if (!state.marketplaceRegistered) {
|
|
161
|
+
const r = run("codex", ["plugin", "marketplace", "add", source], { env });
|
|
162
|
+
if (!r.ok) return out("codex", FAILED, `codex plugin marketplace add failed: ${errText(r)}`);
|
|
163
|
+
}
|
|
164
|
+
const r2 = run("codex", ["plugin", "add", CHORUS_PLUGIN_ID, "--json"], { env });
|
|
165
|
+
if (!r2.ok) return out("codex", FAILED, `codex plugin add failed: ${errText(r2)}`);
|
|
166
|
+
return out(
|
|
167
|
+
"codex",
|
|
168
|
+
state.marketplaceRegistered ? REPAIRED : INSTALLED,
|
|
169
|
+
`installed ${CHORUS_PLUGIN_ID} via codex plugin CLI${ensureMcp()}`,
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// ---------------------------------------------------------------------------
|
|
174
|
+
// opencode — VERIFIED against opencode 1.14.33:
|
|
175
|
+
// `opencode plugin <module>` ("install plugin and update config")
|
|
176
|
+
// module name "opencode-chorus" from public/install-opencode.sh. opencode.json
|
|
177
|
+
// is backed up before the CLI mutates it.
|
|
178
|
+
// ---------------------------------------------------------------------------
|
|
179
|
+
const OPENCODE_PLUGIN_MODULE = "opencode-chorus";
|
|
180
|
+
|
|
181
|
+
export function readOpencodeInstallState({ env = process.env } = {}) {
|
|
182
|
+
const home = env.HOME || homedir();
|
|
183
|
+
const dir = env.OPENCODE_CONFIG_DIR || join(home, ".config", "opencode");
|
|
184
|
+
const cfg = readJsonSafe(join(dir, "opencode.json"));
|
|
185
|
+
const plugins = Array.isArray(cfg?.plugin) ? cfg.plugin : [];
|
|
186
|
+
return {
|
|
187
|
+
marketplaceRegistered: false, // opencode has no marketplace concept
|
|
188
|
+
pluginInstalled: plugins.some((p) => typeof p === "string" && p.includes(OPENCODE_PLUGIN_MODULE)),
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
export function installOpencode(ctx) {
|
|
193
|
+
const run = ctx.run ?? runCommand;
|
|
194
|
+
const env = ctx.env ?? process.env;
|
|
195
|
+
const home = env.HOME || homedir();
|
|
196
|
+
const dir = env.OPENCODE_CONFIG_DIR || join(home, ".config", "opencode");
|
|
197
|
+
const state = safeState(ctx);
|
|
198
|
+
if (state.pluginInstalled) return out("opencode", SKIPPED, "already in opencode.json plugin list");
|
|
199
|
+
|
|
200
|
+
ctx.backup?.(join(dir, "opencode.json")); // back up before the CLI edits it
|
|
201
|
+
// `-g` writes the GLOBAL ~/.config/opencode/opencode.json (the same file
|
|
202
|
+
// readOpencodeInstallState checks); without it opencode installs project-local
|
|
203
|
+
// (cwd), which would defeat idempotency for a machine-wide `chorus init`.
|
|
204
|
+
const r = run("opencode", ["plugin", OPENCODE_PLUGIN_MODULE, "-g"], { env });
|
|
205
|
+
if (!r.ok) return out("opencode", FAILED, `opencode plugin install failed: ${errText(r)}`);
|
|
206
|
+
return out("opencode", INSTALLED, `installed ${OPENCODE_PLUGIN_MODULE} via opencode plugin -g`);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// ---------------------------------------------------------------------------
|
|
210
|
+
// dsh (DeepSeek Harness) — VERIFIED against docs/CONNECT_DSH.md (dsh 0.1.0-rc.7):
|
|
211
|
+
// `dsh plugin --profile <name> add @chorus-aidlc/chorus-dsh -w` (-w MANDATORY:
|
|
212
|
+
// a dsh profile is a pnpm workspace root; pnpm refuses to add a dependency to a
|
|
213
|
+
// workspace root without it).
|
|
214
|
+
// Prereq: `pnpm` on PATH — dsh delegates package management to pnpm. This configures
|
|
215
|
+
// only the INTERACTIVE dsh profile; it NEVER touches the daemon-managed composition
|
|
216
|
+
// (cli/dsh-spawner.mjs). The `--profile <name>` is resolved from an explicit flag/env
|
|
217
|
+
// or a TTY prompt — NEVER guessed. dsh's profile-store enumeration is NOT verifiable
|
|
218
|
+
// on this build host (no dsh CLI present), so we DEGRADE to prompt-for-name rather
|
|
219
|
+
// than hardcode a guessed `dsh profile list` subcommand; wire the real enumeration
|
|
220
|
+
// once a dsh CLI is available. Credentials are handled elsewhere ($DSH_HOME/.env via
|
|
221
|
+
// the credential flow) — this installer writes no secret.
|
|
222
|
+
// ---------------------------------------------------------------------------
|
|
223
|
+
const DSH_BUNDLE = "@chorus-aidlc/chorus-dsh";
|
|
224
|
+
|
|
225
|
+
export function readDshInstallState({ env = process.env, profile } = {}) {
|
|
226
|
+
// Best-effort, per-profile idempotency probe. A dsh profile is a pnpm workspace
|
|
227
|
+
// root under $DSH_HOME (docs/CONNECT_DSH.md); a profile that has added the bundle
|
|
228
|
+
// records it in that root's package.json. The exact layout is NOT verifiable here,
|
|
229
|
+
// so this degrades to "not installed" if it differs (dsh's own `add` is idempotent)
|
|
230
|
+
// — never a false positive, never a throw. Called with no `profile` (registry-level
|
|
231
|
+
// detection, which does not know the user's pick) it reports not-installed.
|
|
232
|
+
if (!profile) return { marketplaceRegistered: false, pluginInstalled: false };
|
|
233
|
+
const home = env.HOME || homedir();
|
|
234
|
+
const dshHome = env.DSH_HOME || join(home, ".dsh");
|
|
235
|
+
const pkg = readJsonSafe(join(dshHome, profile, "package.json"));
|
|
236
|
+
const deps = { ...(pkg?.dependencies ?? {}), ...(pkg?.devDependencies ?? {}) };
|
|
237
|
+
return {
|
|
238
|
+
marketplaceRegistered: false, // dsh has no marketplace concept
|
|
239
|
+
pluginInstalled: Object.prototype.hasOwnProperty.call(deps, DSH_BUNDLE),
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/** Resolve the dsh profile: explicit flag/env pre-fill, else a TTY name prompt.
|
|
244
|
+
* Returns the profile name, or null when none can be resolved without guessing. */
|
|
245
|
+
async function resolveDshProfile(ctx) {
|
|
246
|
+
const env = ctx.env ?? process.env;
|
|
247
|
+
const flags = ctx.flags ?? {};
|
|
248
|
+
const io = ctx.io ?? {};
|
|
249
|
+
// 1. Explicit: --dsh-profile flag or CHORUS_DSH_PROFILE env pre-fill.
|
|
250
|
+
const explicit = nonEmpty(flags.dshProfile) ?? nonEmpty(env.CHORUS_DSH_PROFILE);
|
|
251
|
+
if (explicit) return explicit;
|
|
252
|
+
// 2. Interactive: prompt for the profile NAME on a TTY (no enumeration — see header).
|
|
253
|
+
if (io.isTTY && typeof io.ask === "function") {
|
|
254
|
+
return nonEmpty(await io.ask("dsh profile to add the Chorus bundle to (name): ")) ?? null;
|
|
255
|
+
}
|
|
256
|
+
// 3. No explicit profile and no TTY to ask → caller fails (never guess a profile).
|
|
257
|
+
return null;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
export async function installDsh(ctx) {
|
|
261
|
+
const run = ctx.run ?? runCommand;
|
|
262
|
+
const env = ctx.env ?? process.env;
|
|
263
|
+
|
|
264
|
+
// Precheck: pnpm on PATH. Probe via PATH (NOT `run`) so a missing pnpm returns
|
|
265
|
+
// FAILED with ZERO commands executed. Injectable for unit tests.
|
|
266
|
+
const hasBinary = ctx.binaryOnPath ?? binaryOnPath;
|
|
267
|
+
if (!hasBinary(["pnpm"], { env })) {
|
|
268
|
+
return out("dsh", FAILED, "pnpm not found on PATH — dsh delegates package management to pnpm; install pnpm and re-run");
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
// Profile resolution — NEVER guess (a wrong profile mutates the wrong workspace).
|
|
272
|
+
const profile = await resolveDshProfile(ctx);
|
|
273
|
+
if (!profile) {
|
|
274
|
+
return out("dsh", FAILED, "no dsh profile resolved — pass --dsh-profile <name> or set CHORUS_DSH_PROFILE (a TTY prompts); never a guessed profile");
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
// Idempotency: skip when the chosen profile already carries the bundle.
|
|
278
|
+
const state = safeState(ctx, { profile });
|
|
279
|
+
if (state.pluginInstalled) return out("dsh", SKIPPED, `already installed in dsh profile '${profile}'`);
|
|
280
|
+
|
|
281
|
+
const r = run("dsh", ["plugin", "--profile", profile, "add", DSH_BUNDLE, "-w"], { env });
|
|
282
|
+
if (!r.ok) return out("dsh", FAILED, `dsh plugin add failed: ${errText(r)}`);
|
|
283
|
+
return out("dsh", INSTALLED, `installed ${DSH_BUNDLE} into dsh profile '${profile}'`);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
// ---------------------------------------------------------------------------
|
|
287
|
+
// OpenClaw — VERIFIED against packages/openclaw-plugin/README.md (Installation §,
|
|
288
|
+
// lines 32-35) + package.json `openclaw.install`:
|
|
289
|
+
// `openclaw plugins install npm:@chorus-aidlc/chorus-openclaw-plugin`
|
|
290
|
+
// `openclaw plugins enable chorus-openclaw-plugin`
|
|
291
|
+
// The install SOURCE carries the `npm:` prefix; the enable/disable/uninstall ARG
|
|
292
|
+
// is the bare plugin id `chorus-openclaw-plugin` (README line 60). OpenClaw
|
|
293
|
+
// installs from npm — there is NO marketplace step (unlike claude/codex).
|
|
294
|
+
//
|
|
295
|
+
// Host-version guard: the npm install path ships COMPILED runtimeExtensions
|
|
296
|
+
// (dist/index.js) that bind to OpenClaw SDK APIs added in a specific host
|
|
297
|
+
// version (`activation.onStartup`, 2026.4.27); a below-floor host cannot load the
|
|
298
|
+
// plugin. The floor is READ from the plugin package's `openclaw.install.minHostVersion`
|
|
299
|
+
// (openclawMinHostVersion) — never hardcoded here — and enforced BEFORE any
|
|
300
|
+
// install/enable, so an old host gets a precise "upgrade" message and ZERO mutation.
|
|
301
|
+
//
|
|
302
|
+
// VERIFIED-gap: the openclaw CLI is NOT present on this build host, so (a) the exact
|
|
303
|
+
// `openclaw --version` output shape is not confirmed — parseOpenclawVersion extracts
|
|
304
|
+
// the first dotted-numeric token defensively rather than assuming a fixed format; and
|
|
305
|
+
// (b) plugin state is read from ~/.openclaw/openclaw.json under
|
|
306
|
+
// `plugins.entries.chorus-openclaw-plugin` (README "Where config lives", lines 66-72),
|
|
307
|
+
// degrading to "not installed" if absent — never a false positive. `openclaw --version`
|
|
308
|
+
// is the task-directed probe.
|
|
309
|
+
// ---------------------------------------------------------------------------
|
|
310
|
+
const OPENCLAW_PLUGIN_ID = "chorus-openclaw-plugin";
|
|
311
|
+
const OPENCLAW_NPM_SPEC = "npm:@chorus-aidlc/chorus-openclaw-plugin";
|
|
312
|
+
|
|
313
|
+
// The chorus CLI is published (root package.json `files`) WITHOUT packages/, so
|
|
314
|
+
// this file is not co-located in a published npm layout — openclawMinHostVersion
|
|
315
|
+
// degrades to this documented mirror of packages/openclaw-plugin/package.json →
|
|
316
|
+
// openclaw.install.minHostVersion. In the repo/dev tree the package block itself
|
|
317
|
+
// is the source of truth (read below); keep this in sync with it.
|
|
318
|
+
const OPENCLAW_MIN_HOST_VERSION_FALLBACK = "2026.4.27";
|
|
319
|
+
const OPENCLAW_PACKAGE_JSON_URL = new URL("../../packages/openclaw-plugin/package.json", import.meta.url);
|
|
320
|
+
|
|
321
|
+
/** The OpenClaw host-version floor, READ from the plugin package's
|
|
322
|
+
* `openclaw.install.minHostVersion` (NOT hardcoded). Strips a leading range
|
|
323
|
+
* operator (`>=`) to a bare dotted version. Degrades to the documented mirror
|
|
324
|
+
* only when the package.json cannot be read (stripped npm layout). `pkgUrl` is
|
|
325
|
+
* injectable for tests. */
|
|
326
|
+
export function openclawMinHostVersion({ pkgUrl = OPENCLAW_PACKAGE_JSON_URL } = {}) {
|
|
327
|
+
let raw;
|
|
328
|
+
try {
|
|
329
|
+
const pkg = JSON.parse(readFileSync(fileURLToPath(pkgUrl), "utf8"));
|
|
330
|
+
raw = pkg?.openclaw?.install?.minHostVersion;
|
|
331
|
+
} catch {
|
|
332
|
+
raw = undefined;
|
|
333
|
+
}
|
|
334
|
+
const cleaned = typeof raw === "string" ? raw.replace(/[^\d.]/g, "").trim() : "";
|
|
335
|
+
return cleaned || OPENCLAW_MIN_HOST_VERSION_FALLBACK;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
/** First dotted-numeric token in `openclaw --version` output, or null. Tolerant
|
|
339
|
+
* of `openclaw 2026.4.27`, `v2026.4.27`, `2026.4.27-rc.1`, etc. */
|
|
340
|
+
function parseOpenclawVersion(text) {
|
|
341
|
+
const m = String(text ?? "").match(/\d+(?:\.\d+)+/);
|
|
342
|
+
return m ? m[0] : null;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
/** Compare two dotted-numeric versions → -1 / 0 / 1 (a<b / a==b / a>b).
|
|
346
|
+
* Zero-dependency; covers OpenClaw CalVer (`2026.4.27`) and plain semver. */
|
|
347
|
+
function compareVersions(a, b) {
|
|
348
|
+
const pa = String(a).split(".");
|
|
349
|
+
const pb = String(b).split(".");
|
|
350
|
+
const len = Math.max(pa.length, pb.length);
|
|
351
|
+
for (let i = 0; i < len; i++) {
|
|
352
|
+
const na = parseInt(pa[i] ?? "0", 10) || 0;
|
|
353
|
+
const nb = parseInt(pb[i] ?? "0", 10) || 0;
|
|
354
|
+
if (na !== nb) return na < nb ? -1 : 1;
|
|
355
|
+
}
|
|
356
|
+
return 0;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
export function readOpenclawInstallState({ env = process.env } = {}) {
|
|
360
|
+
const home = env.HOME || homedir();
|
|
361
|
+
const dir = env.OPENCLAW_CONFIG_DIR || join(home, ".openclaw");
|
|
362
|
+
const cfg = readJsonSafe(join(dir, "openclaw.json"));
|
|
363
|
+
const entry = cfg?.plugins?.entries?.[OPENCLAW_PLUGIN_ID];
|
|
364
|
+
const pluginInstalled = !!entry && typeof entry === "object";
|
|
365
|
+
return {
|
|
366
|
+
marketplaceRegistered: false, // openclaw installs from npm — no marketplace concept
|
|
367
|
+
pluginInstalled,
|
|
368
|
+
// `enabled` is an explicit boolean in the config; absent/false ⇒ installed-but-disabled.
|
|
369
|
+
pluginEnabled: pluginInstalled && entry.enabled === true,
|
|
370
|
+
};
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
export function installOpenclaw(ctx) {
|
|
374
|
+
const run = ctx.run ?? runCommand;
|
|
375
|
+
const env = ctx.env ?? process.env;
|
|
376
|
+
const state = safeState(ctx);
|
|
377
|
+
|
|
378
|
+
// Already installed AND enabled → nothing to do. No version probe needed: an
|
|
379
|
+
// enabled-and-loaded plugin necessarily already satisfied the host floor.
|
|
380
|
+
if (state.pluginInstalled && state.pluginEnabled) {
|
|
381
|
+
return out("openclaw", SKIPPED, "already installed and enabled");
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
// Host-version guard BEFORE any mutation (install OR enable). A below-floor host
|
|
385
|
+
// cannot load the compiled plugin, so refuse with a precise upgrade message and
|
|
386
|
+
// run NOTHING rather than leave an "enabled"-but-nonloading plugin.
|
|
387
|
+
const minVersion = ctx.minHostVersion ?? openclawMinHostVersion();
|
|
388
|
+
const vr = run("openclaw", ["--version"], { env });
|
|
389
|
+
const hostVersion = parseOpenclawVersion(`${vr?.stdout ?? ""}\n${vr?.stderr ?? ""}`);
|
|
390
|
+
if (!vr?.ok || !hostVersion) {
|
|
391
|
+
return out("openclaw", FAILED, `could not determine openclaw version (need >=${minVersion}): ${errText(vr)}`);
|
|
392
|
+
}
|
|
393
|
+
if (compareVersions(hostVersion, minVersion) < 0) {
|
|
394
|
+
return out("openclaw", UNSUPPORTED, `openclaw ${hostVersion} is below the required >=${minVersion} for the Chorus plugin — upgrade openclaw and re-run (no install attempted)`);
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
// Installed-but-disabled → enable only (repair).
|
|
398
|
+
if (state.pluginInstalled) {
|
|
399
|
+
const re = run("openclaw", ["plugins", "enable", OPENCLAW_PLUGIN_ID], { env });
|
|
400
|
+
if (!re.ok) return out("openclaw", FAILED, `openclaw plugins enable failed: ${errText(re)}`);
|
|
401
|
+
return out("openclaw", REPAIRED, `enabled ${OPENCLAW_PLUGIN_ID} (was installed but disabled)`);
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
// Fresh → install from npm, then enable.
|
|
405
|
+
const ri = run("openclaw", ["plugins", "install", OPENCLAW_NPM_SPEC], { env });
|
|
406
|
+
if (!ri.ok) return out("openclaw", FAILED, `openclaw plugins install failed: ${errText(ri)}`);
|
|
407
|
+
const re = run("openclaw", ["plugins", "enable", OPENCLAW_PLUGIN_ID], { env });
|
|
408
|
+
if (!re.ok) return out("openclaw", FAILED, `openclaw plugins enable failed: ${errText(re)}`);
|
|
409
|
+
return out("openclaw", INSTALLED, `installed ${OPENCLAW_NPM_SPEC} and enabled ${OPENCLAW_PLUGIN_ID}`);
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
// ---------------------------------------------------------------------------
|
|
413
|
+
// Kiro — NATIVE FILE-TEMPLATE install (Kiro has NO plugin CLI). Its "plugin" is a
|
|
414
|
+
// set of loose files under .kiro/ (what public/install-kiro.sh drops). We
|
|
415
|
+
// re-implement that drop cross-platform in pure JS (no bash/curl), downloading
|
|
416
|
+
// the assets from the connected Chorus instance via file-template.mjs.
|
|
417
|
+
//
|
|
418
|
+
// The .kiro/ layout is mirrored verbatim from install-kiro.sh (the VERIFIED
|
|
419
|
+
// reference): KIRO_DIR = ~/.kiro (global) unless env.KIRO_DIR overrides it;
|
|
420
|
+
// skills/agents/steering/hooks + __CHORUS_BIN__ substitution + a `chorus` server
|
|
421
|
+
// merged (non-destructively) into settings/mcp.json with the key kept as a
|
|
422
|
+
// ${env:...} reference. "Installed" = skills + agents/chorus.json + the chorus
|
|
423
|
+
// mcp server all present; a re-run repairs only the missing delta.
|
|
424
|
+
// ---------------------------------------------------------------------------
|
|
425
|
+
/** True when <skillsDir> holds at least one <name>/SKILL.md (manifest-agnostic so
|
|
426
|
+
* it stays correct in the stripped npm package where the manifest isn't bundled). */
|
|
427
|
+
function kiroSkillsPopulated(skillsDir) {
|
|
428
|
+
try {
|
|
429
|
+
return readdirSync(skillsDir).some((name) => existsSync(join(skillsDir, name, "SKILL.md")));
|
|
430
|
+
} catch {
|
|
431
|
+
return false;
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
export function readKiroInstallState({ env = process.env } = {}) {
|
|
436
|
+
const home = env.HOME || homedir();
|
|
437
|
+
const kiroDir = env.KIRO_DIR || join(home, ".kiro");
|
|
438
|
+
const agentPresent = existsSync(join(kiroDir, "agents", "chorus.json"));
|
|
439
|
+
const mcp = readJsonSafe(join(kiroDir, "settings", "mcp.json"));
|
|
440
|
+
const mcpServerPresent = !!(mcp && typeof mcp === "object" && mcp.mcpServers && mcp.mcpServers.chorus);
|
|
441
|
+
const skillsPresent = kiroSkillsPopulated(join(kiroDir, "skills"));
|
|
442
|
+
return {
|
|
443
|
+
marketplaceRegistered: false, // kiro has no marketplace concept — it's a file drop
|
|
444
|
+
pluginInstalled: skillsPresent && agentPresent && mcpServerPresent,
|
|
445
|
+
skillsPresent,
|
|
446
|
+
agentPresent,
|
|
447
|
+
mcpServerPresent,
|
|
448
|
+
};
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
export async function installKiro(ctx) {
|
|
452
|
+
const env = ctx.env ?? process.env;
|
|
453
|
+
const home = env.HOME || homedir();
|
|
454
|
+
const kiroDir = env.KIRO_DIR || join(home, ".kiro");
|
|
455
|
+
// chorus init already holds the connection URL (flag/env); the .kiro/ template
|
|
456
|
+
// is downloaded from that instance, so a missing URL is a hard failure.
|
|
457
|
+
const chorusUrl = nonEmpty(ctx.flags?.url) ?? nonEmpty(env.CHORUS_URL);
|
|
458
|
+
|
|
459
|
+
const state = safeState(ctx);
|
|
460
|
+
if (state.pluginInstalled) return out("kiro", SKIPPED, `already installed (${kiroDir})`);
|
|
461
|
+
|
|
462
|
+
if (!chorusUrl) {
|
|
463
|
+
return out("kiro", FAILED, "no Chorus URL — pass --url or set CHORUS_URL so the .kiro/ template can be downloaded from the connected instance");
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
// Any chorus-* asset already present ⇒ this is a delta repair, not a fresh drop.
|
|
467
|
+
const repairing = !!(state.skillsPresent || state.agentPresent || state.mcpServerPresent);
|
|
468
|
+
try {
|
|
469
|
+
const res = await installFileTemplate({
|
|
470
|
+
chorusUrl,
|
|
471
|
+
kiroDir,
|
|
472
|
+
fetchImpl: ctx.fetch,
|
|
473
|
+
backup: ctx.backup,
|
|
474
|
+
platform: ctx.platform,
|
|
475
|
+
log: ctx.io?.log,
|
|
476
|
+
});
|
|
477
|
+
return out(
|
|
478
|
+
"kiro",
|
|
479
|
+
repairing ? REPAIRED : INSTALLED,
|
|
480
|
+
`${repairing ? "repaired" : "installed"} the .kiro/ template (${res.skills} skills, ${res.reviewerAgents} reviewer agents, ${res.hookScripts} hooks) → ${kiroDir}; merged the chorus server into settings/mcp.json`,
|
|
481
|
+
);
|
|
482
|
+
} catch (err) {
|
|
483
|
+
return out("kiro", FAILED, err?.message ?? String(err));
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
// ---------------------------------------------------------------------------
|
|
488
|
+
// Guided (not automated). These agents have no verified native install path, so
|
|
489
|
+
// — per the "no guessed command" rule — we surface a precise next step instead
|
|
490
|
+
// of running an unverified command.
|
|
491
|
+
// ---------------------------------------------------------------------------
|
|
492
|
+
export function guided(agentId, detail) {
|
|
493
|
+
// Tag the returned function so adapters.mjs can tell a GUIDED (unsupported)
|
|
494
|
+
// install apart from a real automated one — both are `typeof === "function"`,
|
|
495
|
+
// but only a real installer sets `supported: true`. Without this marker every
|
|
496
|
+
// guided agent would report supported:true (the pre-existing latent bug).
|
|
497
|
+
const fn = () => out(agentId, UNSUPPORTED, detail);
|
|
498
|
+
fn.guided = true;
|
|
499
|
+
return fn;
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
export const GUIDED_MESSAGES = {
|
|
503
|
+
// Pi HAS an extension surface (`pi install <source>`) — this message must NOT
|
|
504
|
+
// claim otherwise. What's missing is a published Chorus Pi extension for
|
|
505
|
+
// `chorus agents add` to install automatically, so the accurate guidance is the real
|
|
506
|
+
// manual command against that source once it's available.
|
|
507
|
+
pi: "Pi installs extensions with `pi install <source>`; Chorus does not yet publish a Pi extension for `chorus agents add` to automate, so install it manually with `pi install <source>` when a Chorus Pi source is available.",
|
|
508
|
+
};
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
// cli/init/registry.mjs
|
|
2
|
+
// The two seams `chorus init` runs against:
|
|
3
|
+
//
|
|
4
|
+
// AGENT_REGISTRY — the supported coding-agent adapters. This array is the
|
|
5
|
+
// single source of the supported-agent set. Task "Agent detection + per-agent
|
|
6
|
+
// adapter registry" populates it; adding a new agent later = pushing one more
|
|
7
|
+
// adapter here, with no change to the command core.
|
|
8
|
+
//
|
|
9
|
+
// STEP_REGISTRY — the ordered configuration steps. This change registers the
|
|
10
|
+
// credential-seed step (once) and the plugin-install step (per-agent). Sibling
|
|
11
|
+
// ideas (MCP proxy cc115e6b, daemon setup a7c2a3e8) push their steps here.
|
|
12
|
+
//
|
|
13
|
+
// Both start empty and are filled by the downstream tasks; the accessor
|
|
14
|
+
// functions below are the stable interface runInit (cli/init.mjs) depends on,
|
|
15
|
+
// so the command is importable and testable at every step of the build.
|
|
16
|
+
|
|
17
|
+
import { ADAPTERS } from "./adapters.mjs";
|
|
18
|
+
import { credentialSeedStep } from "./steps/credential-seed.mjs";
|
|
19
|
+
import { pluginInstallStep } from "./steps/plugin-install.mjs";
|
|
20
|
+
import { daemonSetupStep } from "./steps/daemon-setup.mjs";
|
|
21
|
+
|
|
22
|
+
/** @typedef {import("./contracts.mjs").AgentAdapter} AgentAdapter */
|
|
23
|
+
/** @typedef {import("./contracts.mjs").InitStep} InitStep */
|
|
24
|
+
/** @typedef {import("./contracts.mjs").AgentDetection} AgentDetection */
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Supported coding-agent adapters — the single source of the supported set.
|
|
28
|
+
* Built from cli/init/adapters.mjs; add a new agent = add a descriptor there.
|
|
29
|
+
* @type {AgentAdapter[]}
|
|
30
|
+
*/
|
|
31
|
+
export const AGENT_REGISTRY = [...ADAPTERS];
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Configuration steps, run in ascending `order`: credential-seed (10),
|
|
35
|
+
* plugin-install (20), daemon-setup (30). Sibling ideas push their steps too.
|
|
36
|
+
* @type {InitStep[]}
|
|
37
|
+
*/
|
|
38
|
+
export const STEP_REGISTRY = [credentialSeedStep, pluginInstallStep, daemonSetupStep];
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Run every adapter's detection and return one AgentDetection per supported agent.
|
|
42
|
+
* @param {NodeJS.ProcessEnv} [env]
|
|
43
|
+
* @returns {AgentDetection[]}
|
|
44
|
+
*/
|
|
45
|
+
export function detectAgents(env = process.env) {
|
|
46
|
+
return AGENT_REGISTRY.map((adapter) => {
|
|
47
|
+
let signals = { binaryOnPath: false, configDirPresent: false };
|
|
48
|
+
try {
|
|
49
|
+
signals = adapter.detect(env) || signals;
|
|
50
|
+
} catch {
|
|
51
|
+
// A misbehaving adapter must not break detection of the others.
|
|
52
|
+
}
|
|
53
|
+
return {
|
|
54
|
+
id: adapter.id,
|
|
55
|
+
displayName: adapter.displayName,
|
|
56
|
+
binaryOnPath: !!signals.binaryOnPath,
|
|
57
|
+
configDirPresent: !!signals.configDirPresent,
|
|
58
|
+
detected: !!signals.binaryOnPath || !!signals.configDirPresent,
|
|
59
|
+
};
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/** @param {string} id @returns {AgentAdapter | undefined} */
|
|
64
|
+
export function getAdapter(id) {
|
|
65
|
+
return AGENT_REGISTRY.find((a) => a.id === id);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* The steps to run, sorted ascending by `order` (stable for equal orders).
|
|
70
|
+
* @returns {InitStep[]}
|
|
71
|
+
*/
|
|
72
|
+
export function orderedSteps() {
|
|
73
|
+
return STEP_REGISTRY.slice().sort((a, b) => a.order - b.order);
|
|
74
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// cli/init/run-command.mjs
|
|
2
|
+
// Minimal synchronous command runner for `chorus init` plugin-install steps.
|
|
3
|
+
// Injectable (steps take `ctx.run`) so install logic unit-tests without ever
|
|
4
|
+
// shelling out. Returns a plain result — never throws.
|
|
5
|
+
|
|
6
|
+
import { spawnSync } from "node:child_process";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Run a command synchronously.
|
|
10
|
+
* @param {string} cmd
|
|
11
|
+
* @param {string[]} args
|
|
12
|
+
* @param {{ env?: NodeJS.ProcessEnv, timeoutMs?: number, cwd?: string }} [opts]
|
|
13
|
+
* @returns {{ ok: boolean, code: number|null, stdout: string, stderr: string, error?: string }}
|
|
14
|
+
*/
|
|
15
|
+
export function runCommand(cmd, args = [], opts = {}) {
|
|
16
|
+
try {
|
|
17
|
+
const r = spawnSync(cmd, args, {
|
|
18
|
+
env: opts.env ?? process.env,
|
|
19
|
+
cwd: opts.cwd,
|
|
20
|
+
timeout: opts.timeoutMs ?? 120_000,
|
|
21
|
+
encoding: "utf8",
|
|
22
|
+
});
|
|
23
|
+
if (r.error) {
|
|
24
|
+
return { ok: false, code: null, stdout: r.stdout ?? "", stderr: r.stderr ?? "", error: r.error.message };
|
|
25
|
+
}
|
|
26
|
+
return { ok: r.status === 0, code: r.status, stdout: r.stdout ?? "", stderr: r.stderr ?? "" };
|
|
27
|
+
} catch (err) {
|
|
28
|
+
return { ok: false, code: null, stdout: "", stderr: "", error: err?.message ?? String(err) };
|
|
29
|
+
}
|
|
30
|
+
}
|