@chorus-aidlc/chorus 0.17.3 → 0.18.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.next/standalone/.next/BUILD_ID +1 -1
- package/.next/standalone/.next/app-build-manifest.json +345 -341
- package/.next/standalone/.next/app-path-routes-manifest.json +35 -35
- package/.next/standalone/.next/build-manifest.json +5 -5
- package/.next/standalone/.next/prerender-manifest.json +27 -27
- package/.next/standalone/.next/server/app/(dashboard)/project-groups/[uuid]/page.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/project-groups/[uuid]/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/project-groups/[uuid]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/activity/page.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/activity/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/dashboard/[ideaUuid]/page.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/dashboard/[ideaUuid]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/dashboard/page.js +2 -2
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/dashboard/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/dashboard/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/documents/[documentUuid]/page.js +2 -2
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/documents/[documentUuid]/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/documents/[documentUuid]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/documents/page.js +2 -2
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/documents/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/graph/page.js +2 -2
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/graph/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/graph/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/[proposalUuid]/page.js +2 -2
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/[proposalUuid]/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/[proposalUuid]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/new/page.js +2 -2
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/new/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/new/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/page.js +2 -2
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/tasks/[taskUuid]/page.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/tasks/[taskUuid]/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/tasks/[taskUuid]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/tasks/page.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/tasks/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/tasks/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/page.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/settings/page.js +2 -2
- package/.next/standalone/.next/server/app/(dashboard)/settings/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/settings/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/_not-found.html +2 -2
- package/.next/standalone/.next/server/app/_not-found.rsc +2 -2
- package/.next/standalone/.next/server/app/admin/companies/[uuid]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/admin/companies/new/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/admin/companies/new.html +2 -2
- package/.next/standalone/.next/server/app/admin/companies/new.rsc +2 -2
- package/.next/standalone/.next/server/app/admin/companies/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/admin/companies.html +2 -2
- package/.next/standalone/.next/server/app/admin/companies.rsc +2 -2
- package/.next/standalone/.next/server/app/admin/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/admin.html +2 -2
- package/.next/standalone/.next/server/app/admin.rsc +2 -2
- package/.next/standalone/.next/server/app/api/admin/companies/[uuid]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/admin/companies/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/admin/login/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/admin/session/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/agent-connections/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/agent-connections/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/agents/[uuid]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/agents/[uuid]/sessions/route.js +1 -1
- package/.next/standalone/.next/server/app/api/agents/[uuid]/sessions/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/agents/[uuid]/sessions/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/agents/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/api-keys/[uuid]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/api-keys/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/auth/callback/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/auth/check-default/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/auth/company-oidc/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/auth/default-login/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/auth/identify/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/auth/logout/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/auth/me/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/auth/sync-token/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/comments/route.js +1 -1
- package/.next/standalone/.next/server/app/api/comments/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/comments/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon/connection-heartbeat/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/daemon/connection-heartbeat/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon/control/route.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon/control/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/daemon/control/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon/directory-request/report/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/daemon/directory-request/report/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon/execution-state/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/daemon/execution-state/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon/executions/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/daemon/executions/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon/pending-turns/route.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon/pending-turns/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/daemon/pending-turns/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon/report-interrupt/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/daemon/report-interrupt/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon/resume/route.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon/resume/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/daemon/resume/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon/transcript/route.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon/transcript/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/daemon/transcript/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon/turn-advance/route.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon/turn-advance/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/daemon/turn-advance/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon-directory-requests/[uuid]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/daemon-directory-requests/[uuid]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon-directory-requests/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/daemon-directory-requests/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon-sessions/[sessionUuid]/instruction/route.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon-sessions/[sessionUuid]/instruction/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/daemon-sessions/[sessionUuid]/instruction/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon-sessions/[sessionUuid]/repoint/route.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon-sessions/[sessionUuid]/repoint/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/daemon-sessions/[sessionUuid]/repoint/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon-sessions/[sessionUuid]/route.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon-sessions/[sessionUuid]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/daemon-sessions/[sessionUuid]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon-sessions/ad-hoc/route.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon-sessions/ad-hoc/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/daemon-sessions/ad-hoc/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon-sessions/route.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon-sessions/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/daemon-sessions/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/documents/[uuid]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/entities/[type]/[uuid]/root-idea/route.js +1 -1
- package/.next/standalone/.next/server/app/api/entities/[type]/[uuid]/root-idea/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/entities/[type]/[uuid]/root-idea/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/events/notifications/route.js +1 -1
- package/.next/standalone/.next/server/app/api/events/notifications/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/events/notifications/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/events/route.js +1 -1
- package/.next/standalone/.next/server/app/api/events/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/events/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/health/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/ideas/[uuid]/claim/route.js +1 -1
- package/.next/standalone/.next/server/app/api/ideas/[uuid]/claim/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/ideas/[uuid]/claim/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/ideas/[uuid]/move/preview/route.js +1 -1
- package/.next/standalone/.next/server/app/api/ideas/[uuid]/move/preview/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/ideas/[uuid]/move/preview/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/ideas/[uuid]/move/route.js +1 -1
- package/.next/standalone/.next/server/app/api/ideas/[uuid]/move/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/ideas/[uuid]/move/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/ideas/[uuid]/parent/route.js +1 -1
- package/.next/standalone/.next/server/app/api/ideas/[uuid]/parent/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/ideas/[uuid]/parent/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/ideas/[uuid]/release/route.js +1 -1
- package/.next/standalone/.next/server/app/api/ideas/[uuid]/release/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/ideas/[uuid]/release/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/ideas/[uuid]/route.js +1 -1
- package/.next/standalone/.next/server/app/api/ideas/[uuid]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/ideas/[uuid]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/ideas/[uuid]/wake-preview/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/ideas/[uuid]/wake-preview/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/ideas/conversational/route.js +1 -1
- package/.next/standalone/.next/server/app/api/ideas/conversational/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/ideas/conversational/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/mcp/route.js +1 -1
- package/.next/standalone/.next/server/app/api/mcp/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/mcp/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/me/assignments/route.js +1 -1
- package/.next/standalone/.next/server/app/api/me/assignments/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/me/assignments/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/mentionables/route.js +1 -1
- package/.next/standalone/.next/server/app/api/mentionables/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/mentionables/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/notifications/[uuid]/archive/route.js +1 -1
- package/.next/standalone/.next/server/app/api/notifications/[uuid]/archive/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/notifications/[uuid]/archive/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/notifications/[uuid]/read/route.js +1 -1
- package/.next/standalone/.next/server/app/api/notifications/[uuid]/read/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/notifications/[uuid]/read/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/notifications/preferences/route.js +1 -1
- package/.next/standalone/.next/server/app/api/notifications/preferences/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/notifications/preferences/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/notifications/read-all/route.js +1 -1
- package/.next/standalone/.next/server/app/api/notifications/read-all/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/notifications/read-all/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/notifications/route.js +1 -1
- package/.next/standalone/.next/server/app/api/notifications/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/notifications/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/notifications/unread-count/route.js +1 -1
- package/.next/standalone/.next/server/app/api/notifications/unread-count/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/notifications/unread-count/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/project-groups/[uuid]/dashboard/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/project-groups/[uuid]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/project-groups/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/project-visits/pin/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/project-visits/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/project-visits/visit/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/activity/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/agent-cwds/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/agent-cwds/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/available/route.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/available/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/available/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/documents/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/group/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/ideas/route.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/ideas/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/ideas/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/ideas/tracker/route.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/ideas/tracker/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/ideas/tracker/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/proposals/[proposalUuid]/validate/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/proposals/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/proposals/summary/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/resource-graph/route.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/resource-graph/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/resource-graph/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/stats/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/tasks/dependencies/route.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/tasks/dependencies/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/tasks/dependencies/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/tasks/route.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/tasks/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/tasks/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/agent-cwd-options/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/projects/agent-cwd-options/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/proposals/[uuid]/approve/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/proposals/[uuid]/close/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/proposals/[uuid]/reject/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/proposals/[uuid]/revoke/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/proposals/[uuid]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/references/[uuid]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/references/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/search/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/session/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/sessions/[uuid]/route.js +1 -1
- package/.next/standalone/.next/server/app/api/sessions/[uuid]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/sessions/[uuid]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/tasks/[uuid]/claim/route.js +1 -1
- package/.next/standalone/.next/server/app/api/tasks/[uuid]/claim/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/tasks/[uuid]/claim/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/tasks/[uuid]/dependencies/[dependsOnUuid]/route.js +1 -1
- package/.next/standalone/.next/server/app/api/tasks/[uuid]/dependencies/[dependsOnUuid]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/tasks/[uuid]/dependencies/[dependsOnUuid]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/tasks/[uuid]/dependencies/route.js +1 -1
- package/.next/standalone/.next/server/app/api/tasks/[uuid]/dependencies/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/tasks/[uuid]/dependencies/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/tasks/[uuid]/release/route.js +1 -1
- package/.next/standalone/.next/server/app/api/tasks/[uuid]/release/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/tasks/[uuid]/release/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/tasks/[uuid]/route.js +1 -1
- package/.next/standalone/.next/server/app/api/tasks/[uuid]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/tasks/[uuid]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/tasks/[uuid]/sessions/route.js +1 -1
- package/.next/standalone/.next/server/app/api/tasks/[uuid]/sessions/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/tasks/[uuid]/sessions/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/index.html +2 -2
- package/.next/standalone/.next/server/app/index.rsc +2 -2
- package/.next/standalone/.next/server/app/login/admin/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/login/admin.html +2 -2
- package/.next/standalone/.next/server/app/login/admin.rsc +2 -2
- package/.next/standalone/.next/server/app/login/callback/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/login/callback.html +2 -2
- package/.next/standalone/.next/server/app/login/callback.rsc +2 -2
- package/.next/standalone/.next/server/app/login/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/login/pick-workspace/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/login/pick-workspace.html +2 -2
- package/.next/standalone/.next/server/app/login/pick-workspace.rsc +2 -2
- package/.next/standalone/.next/server/app/login.html +2 -2
- package/.next/standalone/.next/server/app/login.rsc +2 -2
- package/.next/standalone/.next/server/app/onboarding/page.js +2 -2
- package/.next/standalone/.next/server/app/onboarding/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/onboarding/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/onboarding.html +2 -2
- package/.next/standalone/.next/server/app/onboarding.rsc +3 -3
- package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/projects.html +2 -2
- package/.next/standalone/.next/server/app/projects.rsc +3 -3
- package/.next/standalone/.next/server/app/settings.html +2 -2
- package/.next/standalone/.next/server/app/settings.rsc +4 -4
- package/.next/standalone/.next/server/app-paths-manifest.json +35 -35
- package/.next/standalone/.next/server/chunks/1318.js +1 -1
- package/.next/standalone/.next/server/chunks/{5201.js → 1416.js} +2 -2
- package/.next/standalone/.next/server/chunks/1559.js +2 -2
- package/.next/standalone/.next/server/chunks/{3630.js → 2195.js} +1 -1
- package/.next/standalone/.next/server/chunks/2460.js +1 -0
- package/.next/standalone/.next/server/chunks/2572.js +2 -2
- package/.next/standalone/.next/server/chunks/2758.js +1 -0
- package/.next/standalone/.next/server/chunks/2961.js +1 -1
- package/.next/standalone/.next/server/chunks/3419.js +1 -1
- package/.next/standalone/.next/server/chunks/4066.js +1 -0
- package/.next/standalone/.next/server/chunks/4827.js +1 -1
- package/.next/standalone/.next/server/chunks/5245.js +1 -1
- package/.next/standalone/.next/server/chunks/5453.js +1 -1
- package/.next/standalone/.next/server/chunks/5489.js +1 -1
- package/.next/standalone/.next/server/chunks/6113.js +1 -1
- package/.next/standalone/.next/server/chunks/6506.js +2 -2
- package/.next/standalone/.next/server/chunks/6737.js +1 -0
- package/.next/standalone/.next/server/chunks/679.js +1 -1
- package/.next/standalone/.next/server/chunks/7368.js +1 -1
- package/.next/standalone/.next/server/chunks/7530.js +1 -1
- package/.next/standalone/.next/server/chunks/7578.js +2 -2
- package/.next/standalone/.next/server/chunks/7675.js +1 -0
- package/.next/standalone/.next/server/chunks/7789.js +1 -0
- package/.next/standalone/.next/server/chunks/{1201.js → 8030.js} +2 -2
- package/.next/standalone/.next/server/chunks/920.js +1 -1
- package/.next/standalone/.next/server/chunks/9213.js +1 -1
- package/.next/standalone/.next/server/chunks/9378.js +1 -1
- package/.next/standalone/.next/server/chunks/9931.js +1 -1
- package/.next/standalone/.next/server/instrumentation.js +1 -1
- package/.next/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/.next/standalone/.next/server/middleware-manifest.json +5 -5
- package/.next/standalone/.next/server/pages/404.html +2 -2
- package/.next/standalone/.next/server/pages/500.html +1 -1
- package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/static/chunks/11595.f080a1d100972212.js +1 -0
- package/.next/standalone/.next/static/chunks/14628-283d3983d1fb36c9.js +1 -0
- package/.next/standalone/.next/static/chunks/{29305-f587e7e81bc0b200.js → 17562-56f932146e9e6c94.js} +4 -4
- package/.next/standalone/.next/static/chunks/25080-25ad29e64c855338.js +1 -0
- package/.next/standalone/.next/static/chunks/28698-7fb271ffc6e63a26.js +1 -0
- package/.next/standalone/.next/static/chunks/{95225-96b44da3ebd6ddad.js → 32736-aeaaa1e4c4d5529b.js} +1 -1
- package/.next/standalone/.next/static/chunks/33456.20313bd67a5c41cc.js +1 -0
- package/.next/standalone/.next/static/chunks/4860.3b555a398cdffb19.js +1 -0
- package/.next/standalone/.next/static/chunks/75257-99c0ce24b436847b.js +1 -0
- package/.next/standalone/.next/static/chunks/79919-0c6dcda1dd8646f0.js +1 -0
- package/.next/standalone/.next/static/chunks/91328-f501e3c3ca519a92.js +1 -0
- package/.next/standalone/.next/static/chunks/94643-e54eff17e941a93b.js +1 -0
- package/.next/standalone/.next/static/chunks/99373.b8a95d1bec5ad4e7.js +1 -0
- package/.next/standalone/.next/static/chunks/app/(dashboard)/layout-f3c6431432d42c7c.js +1 -0
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/dashboard/{page-77b175e52a85f3cb.js → page-5d723f974bdad33b.js} +1 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/documents/[documentUuid]/page-8d3b1f4d8b76d66c.js +1 -0
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/documents/page-57c698dea2fa6e29.js +1 -0
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/graph/{page-69d3162667f85677.js → page-d2bb622855e746f1.js} +1 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/[proposalUuid]/page-fc255dc3612032b9.js +1 -0
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/new/{page-a3f83031dfbafc81.js → page-f032ee8a80d1f56a.js} +1 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/page-46a0ddfd0421b0a8.js +1 -0
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/tasks/[taskUuid]/{page-3c7ff3a40a4615ac.js → page-3a83748ce0ae1c4f.js} +1 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/tasks/{page-7b8e11fdc5b596d0.js → page-8af9bb9f96ab0258.js} +1 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/settings/page-b02939820affdae5.js +1 -0
- package/.next/standalone/.next/static/chunks/app/onboarding/page-d2c0c7951114e763.js +1 -0
- package/.next/standalone/.next/static/chunks/{webpack-dffb97a4feb8faba.js → webpack-de8a36d232a91d6b.js} +1 -1
- package/.next/standalone/.next/static/css/44f13b43a3de716d.css +1 -0
- package/.next/standalone/package.json +1 -1
- package/.next/standalone/public/chorus-plugin/.claude-plugin/plugin.json +2 -2
- package/.next/standalone/public/chorus-plugin/agents/code-reviewer.md +1 -0
- package/.next/standalone/public/chorus-plugin/agents/proposal-reviewer.md +12 -3
- package/.next/standalone/public/chorus-plugin/agents/task-reviewer.md +4 -0
- package/.next/standalone/public/chorus-plugin/bin/chorus-api.sh +1 -1
- package/.next/standalone/public/chorus-plugin/bin/on-post-submit-for-verify.sh +3 -3
- package/.next/standalone/public/chorus-plugin/bin/on-post-submit-proposal.sh +3 -3
- package/.next/standalone/public/chorus-plugin/bin/on-post-verify-task.sh +2 -2
- package/.next/standalone/public/chorus-plugin/bin/on-pre-spawn-agent.sh +22 -9
- package/.next/standalone/public/chorus-plugin/bin/on-session-start.sh +39 -64
- package/.next/standalone/public/chorus-plugin/bin/on-subagent-start.sh +44 -29
- package/.next/standalone/public/chorus-plugin/bin/on-subagent-stop.sh +100 -29
- package/.next/standalone/public/chorus-plugin/bin/resolve-spec-mode.sh +107 -0
- package/.next/standalone/public/chorus-plugin/bin/test-syntax.sh +6 -2
- package/.next/standalone/public/chorus-plugin/bin/tests/test-resolver-drift.sh +46 -0
- package/.next/standalone/public/chorus-plugin/bin/tests/test-skill-harness-fidelity-negative.sh +328 -0
- package/.next/standalone/public/chorus-plugin/bin/tests/test-skill-harness-fidelity.sh +372 -0
- package/.next/standalone/public/chorus-plugin/bin/tests/test-spec-mode-resolution.sh +83 -0
- package/.next/standalone/public/chorus-plugin/bin/tests/test-subagent-session-name.sh +599 -0
- package/.next/standalone/public/chorus-plugin/skills/brainstorm/SKILL.md +1 -1
- package/.next/standalone/public/chorus-plugin/skills/chorus/SKILL.md +11 -6
- package/.next/standalone/public/chorus-plugin/skills/chorus-cli/SKILL.md +1 -1
- package/.next/standalone/public/chorus-plugin/skills/develop/SKILL.md +14 -9
- package/.next/standalone/public/chorus-plugin/skills/docs/SKILL.md +1 -1
- package/.next/standalone/public/chorus-plugin/skills/idea/SKILL.md +1 -1
- package/.next/standalone/public/chorus-plugin/skills/openspec-aware/SKILL.md +27 -31
- package/.next/standalone/public/chorus-plugin/skills/orchestrate/SKILL.md +11 -1
- package/.next/standalone/public/chorus-plugin/skills/proposal/SKILL.md +14 -7
- package/.next/standalone/public/chorus-plugin/skills/quick-dev/SKILL.md +6 -4
- package/.next/standalone/public/chorus-plugin/skills/review/SKILL.md +10 -8
- package/.next/standalone/public/chorus-plugin/skills/spec-lite/SKILL.md +147 -0
- package/.next/standalone/public/chorus-plugin/skills/yolo/SKILL.md +49 -34
- package/.next/standalone/public/kiro-plugin/.kiro/agents/chorus-code-reviewer.json +1 -1
- package/.next/standalone/public/kiro-plugin/.kiro/agents/chorus-proposal-reviewer.json +2 -1
- package/.next/standalone/public/kiro-plugin/.kiro/agents/chorus-task-reviewer.json +1 -1
- package/.next/standalone/public/kiro-plugin/.kiro/agents/chorus.md +1 -1
- package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-brainstorm/SKILL.md +1 -1
- package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-cli/SKILL.md +1 -1
- package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-develop/SKILL.md +9 -7
- package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-docs/SKILL.md +1 -1
- package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-idea/SKILL.md +1 -1
- package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-openspec-aware/SKILL.md +35 -27
- package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-orchestrate/SKILL.md +9 -1
- package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-proposal/SKILL.md +14 -7
- package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-quick-dev/SKILL.md +2 -2
- package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-review/SKILL.md +8 -8
- package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-spec-lite/SKILL.md +147 -0
- package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-yolo/SKILL.md +39 -25
- package/.next/standalone/public/kiro-plugin/.kiro/steering/chorus.md +11 -6
- package/.next/standalone/public/kiro-plugin/bin/chorus-api.sh +1 -1
- package/.next/standalone/public/kiro-plugin/bin/on-agent-spawn.sh +41 -0
- package/.next/standalone/public/kiro-plugin/bin/on-post-submit-for-verify.sh +3 -3
- package/.next/standalone/public/kiro-plugin/bin/on-post-submit-proposal.sh +3 -3
- package/.next/standalone/public/kiro-plugin/bin/on-post-verify-task.sh +2 -2
- package/.next/standalone/public/kiro-plugin/bin/resolve-spec-mode.sh +107 -0
- package/.next/standalone/public/kiro-plugin/manifest.txt +2 -0
- package/.next/standalone/public/skill/chorus/SKILL.md +11 -1
- package/.next/standalone/public/skill/code-reviewer-chorus/SKILL.md +1 -0
- package/.next/standalone/public/skill/develop-chorus/SKILL.md +1 -1
- package/.next/standalone/public/skill/orchestrate-chorus/SKILL.md +11 -1
- package/.next/standalone/public/skill/proposal-reviewer-chorus/SKILL.md +5 -2
- package/.next/standalone/public/skill/quick-dev-chorus/SKILL.md +1 -1
- package/.next/standalone/public/skill/review-chorus/SKILL.md +5 -3
- package/.next/standalone/public/skill/task-reviewer-chorus/SKILL.md +4 -0
- package/.next/standalone/public/skill/yolo-chorus/SKILL.md +23 -7
- package/README.ja.md +3 -3
- package/README.ko.md +3 -3
- package/README.md +3 -3
- package/README.zh.md +3 -3
- package/chorus.mjs +30 -2
- package/cli/agent-cli-config.mjs +323 -0
- package/cli/agent-launcher.mjs +44 -16
- package/cli/child-exit.mjs +77 -0
- package/cli/claude-spawner.mjs +26 -14
- package/cli/codex-spawner.mjs +27 -16
- package/cli/control-handler.mjs +104 -6
- package/cli/credentials.mjs +7 -0
- package/cli/daemon-config.mjs +14 -0
- package/cli/daemon-rest-client.mjs +98 -29
- package/cli/daemon.mjs +37 -7
- package/cli/dsh-managed-config.mjs +26 -28
- package/cli/dsh-spawner.mjs +27 -16
- package/cli/init/steps/credential-seed.mjs +1 -1
- package/cli/kiro-spawner.mjs +26 -16
- package/cli/launch-diagnostics.mjs +67 -0
- package/cli/login.mjs +17 -1
- package/cli/pi-spawner.mjs +23 -13
- package/cli/prompts.mjs +52 -2
- package/cli/spawner-select.mjs +6 -11
- package/package.json +1 -1
- package/.next/standalone/.next/server/chunks/1114.js +0 -1
- package/.next/standalone/.next/server/chunks/1155.js +0 -1
- package/.next/standalone/.next/server/chunks/6465.js +0 -1
- package/.next/standalone/.next/server/chunks/8105.js +0 -1
- package/.next/standalone/.next/server/chunks/8232.js +0 -1
- package/.next/standalone/.next/static/chunks/11595.f7c3ef5cd7fc8feb.js +0 -1
- package/.next/standalone/.next/static/chunks/33456.c81079032acc2966.js +0 -1
- package/.next/standalone/.next/static/chunks/45262-38b332523f00a223.js +0 -1
- package/.next/standalone/.next/static/chunks/46021-f5d072b0cbcb7fac.js +0 -1
- package/.next/standalone/.next/static/chunks/4860.f0cfb1201191ae88.js +0 -1
- package/.next/standalone/.next/static/chunks/66609-64a01d5cb415465b.js +0 -1
- package/.next/standalone/.next/static/chunks/79919-c5a2a3fd8f5f9204.js +0 -1
- package/.next/standalone/.next/static/chunks/94394-38194b81b489275c.js +0 -1
- package/.next/standalone/.next/static/chunks/94643-f1bdf37fb3bb6adb.js +0 -1
- package/.next/standalone/.next/static/chunks/96482-2b3bdb2544d72e5a.js +0 -1
- package/.next/standalone/.next/static/chunks/99373.3c23ac2efbd4db02.js +0 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/layout-66328332f62c7371.js +0 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/documents/[documentUuid]/page-87ceae13c4950fc9.js +0 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/documents/page-45e95154e546460e.js +0 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/[proposalUuid]/page-b7b2017e5be69564.js +0 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/page-8b06834ca0f663bb.js +0 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/settings/page-efe5326c47aca9ca.js +0 -1
- package/.next/standalone/.next/static/chunks/app/onboarding/page-0ce33b9327fe3d8c.js +0 -1
- package/.next/standalone/.next/static/css/1d9cf83f50b6db00.css +0 -1
- /package/.next/standalone/.next/static/{wuqYN129vOIGymh_NEdZe → dot63ILT878Tloqi7Czj_}/_buildManifest.js +0 -0
- /package/.next/standalone/.next/static/{wuqYN129vOIGymh_NEdZe → dot63ILT878Tloqi7Czj_}/_ssgManifest.js +0 -0
|
@@ -317,8 +317,8 @@ All tasks of idea-rooted proposal ${PROPOSAL_UUID} are now done. This is the fin
|
|
|
317
317
|
|
|
318
318
|
ACTION REQUESTED: spawn code-reviewer for this idea — an independent, read-only review of the idea's AGGREGATE code change (the whole feature across all its tasks), not a single task.
|
|
319
319
|
|
|
320
|
-
1. Spawn the code-reviewer
|
|
321
|
-
2. Read
|
|
320
|
+
1. Spawn the code-reviewer and wait for its completion notification, passing it ideaUuid="${idea_uuid}" and the review round number (read prior code-review verdict comments on the idea to determine it). It reviews cross-task integration, architecture/convention consistency, security, regression/performance, feature-level test coverage, and overall code soundness, then posts ONE VERDICT comment on the idea.
|
|
321
|
+
2. Read THIS round's VERDICT on the idea (chorus_get_comments targetType="idea") — the comment posted after your dispatch, not an earlier round's. The launch result is not the verdict; do not declare the feature shippable before you have read that comment. If it is missing, check what the reviewer did post: a comment reporting the round limit was reached, or any other explicit refusal to review, is a deliberate escalation — STOP: do not respawn, do not self-review, do not post a VERDICT of your own; leave it pending the human's decision. If it posted nothing at all, respawn once and apply this same check again to what the retry posts — an explicit refusal still means STOP; only a second true silence lets you review the idea's aggregate change yourself as a read-only pass and post the VERDICT. Absence is never a PASS.
|
|
322
322
|
3. PASS / PASS WITH NOTES -> the feature may ship.
|
|
323
323
|
4. FAIL -> the orchestrator invokes Quick Dev to create new tasks on the original approved proposal; never reopen completed tasks or apply untracked fixes. Group related small BLOCKERs by default and split only materially large or independently testable fixes.
|
|
324
324
|
5. Re-run only after every fix task passes AC self-check, independent task review, and admin verification to done. A failed or cancelled fix stops the loop and escalates. Keep maxCodeReviewRounds authoritative.
|
|
@@ -28,27 +28,35 @@ fi
|
|
|
28
28
|
CHORUS_SESSION_ID=$(printf '%s' "$EVENT" | jq -r '.session_id // .sessionId // empty' 2>/dev/null) || true
|
|
29
29
|
export CHORUS_SESSION_ID
|
|
30
30
|
|
|
31
|
-
# Try to extract subagent_type and name from the tool input
|
|
31
|
+
# Try to extract subagent_type and name from the tool input.
|
|
32
|
+
# `tool_input.name` does not exist on CC's Task tool today — it is read for
|
|
33
|
+
# forward-compatibility and falls back to subagent_type, which is the value the
|
|
34
|
+
# SubagentStart hook also receives as agent_type (and uses as the session name).
|
|
32
35
|
AGENT_TYPE=""
|
|
33
36
|
AGENT_NAME=""
|
|
34
37
|
if [ -n "$EVENT" ]; then
|
|
35
38
|
AGENT_TYPE=$(echo "$EVENT" | jq -r '.tool_input.subagent_type // .input.subagent_type // empty' 2>/dev/null) || true
|
|
36
39
|
AGENT_NAME=$(echo "$EVENT" | jq -r '.tool_input.name // .input.name // empty' 2>/dev/null) || true
|
|
37
40
|
fi
|
|
41
|
+
AGENT_NAME="${AGENT_NAME:-$AGENT_TYPE}"
|
|
38
42
|
|
|
39
|
-
# Skip non-worker types — no need to remind for Explore/Plan agents
|
|
43
|
+
# Skip non-worker types — no need to remind for Explore/Plan agents.
|
|
44
|
+
# This list MUST stay identical to the skip list in on-subagent-start.sh:
|
|
45
|
+
# a type skipped by only one hook leaves an orphan pending file that a later
|
|
46
|
+
# internal/cleanup agent could FIFO-claim, defeating the spawn gate.
|
|
40
47
|
case "$(printf '%s' "$AGENT_TYPE" | tr '[:upper:]' '[:lower:]')" in
|
|
41
|
-
explore|plan|haiku|claude-code-guide|statusline-setup)
|
|
48
|
+
explore|plan|haiku|claude-code-guide|statusline-setup|chorus:proposal-reviewer|chorus:task-reviewer)
|
|
42
49
|
exit 0
|
|
43
50
|
;;
|
|
44
51
|
esac
|
|
45
52
|
|
|
46
53
|
# Write a per-agent pending file for SubagentStart to claim.
|
|
47
|
-
#
|
|
48
|
-
#
|
|
54
|
+
#
|
|
55
|
+
# The pending file is a SPAWN GATE, not a name channel: its presence proves a
|
|
56
|
+
# SubagentStart came from a real Task spawn. The session name is derived by
|
|
57
|
+
# on-subagent-start.sh from the event's own agent_type, never from this file.
|
|
49
58
|
#
|
|
50
59
|
# Each spawn gets its own file — no shared state, no concurrency issues.
|
|
51
|
-
# File name is the agent name (or a unique fallback if name is empty).
|
|
52
60
|
# SubagentStart claims by mv (atomic on same filesystem).
|
|
53
61
|
#
|
|
54
62
|
# CC may internally spawn cleanup agents that bypass PreToolUse:Task —
|
|
@@ -59,10 +67,15 @@ esac
|
|
|
59
67
|
PENDING_DIR="${CHORUS_STATE_DIR:-${CLAUDE_PROJECT_DIR:-.}/.chorus}/pending"
|
|
60
68
|
mkdir -p "$PENDING_DIR" 2>/dev/null || true
|
|
61
69
|
|
|
62
|
-
#
|
|
63
|
-
|
|
70
|
+
# Filename stem: sanitized subagent_type (":" and "/" in namespaced types such as
|
|
71
|
+
# chorus:code-reviewer become "_"), plus epoch seconds and the PID for uniqueness.
|
|
72
|
+
# $$ is required: BSD date (macOS) has no %N, so two same-second spawns of the same
|
|
73
|
+
# type would otherwise collide on a single filename and one would be lost.
|
|
74
|
+
PENDING_STEM=$(printf '%s' "${AGENT_TYPE:-worker}" | tr -c '[:alnum:]._-' '_')
|
|
75
|
+
[ -z "$PENDING_STEM" ] && PENDING_STEM="worker"
|
|
76
|
+
PENDING_NAME="${PENDING_STEM}__$(date +%s)-$$"
|
|
64
77
|
printf '{"name":"%s","type":"%s","ts":"%s"}\n' \
|
|
65
|
-
"${AGENT_NAME:-}" "${AGENT_TYPE:-}" "$(date -u +%Y-%m-%dT%H:%M:%
|
|
78
|
+
"${AGENT_NAME:-}" "${AGENT_TYPE:-}" "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
|
|
66
79
|
> "${PENDING_DIR}/${PENDING_NAME}"
|
|
67
80
|
|
|
68
81
|
CONTEXT="[Chorus Plugin — Sub-agent Spawn]
|
|
@@ -67,45 +67,17 @@ if command -v jq >/dev/null 2>&1; then
|
|
|
67
67
|
|
|
68
68
|
fi
|
|
69
69
|
|
|
70
|
-
#
|
|
71
|
-
#
|
|
72
|
-
#
|
|
73
|
-
#
|
|
74
|
-
# Overrides (precedence high -> low, first match wins):
|
|
75
|
-
# 1. enableOpenSpec userConfig toggle (default true) — UI-level switch.
|
|
76
|
-
# 2. CHORUS_OPENSPEC_MODE=off env var — env-level explicit opt-out.
|
|
77
|
-
# When the folder is present but the CLI is missing, surface that as a
|
|
78
|
-
# specific reason so the user-visible toast can hint at the install step
|
|
79
|
-
# instead of silently falling back.
|
|
70
|
+
# Resolve the active spec mode for this repo, once per session. The resolution
|
|
71
|
+
# logic lives in resolve-spec-mode.sh (pure: env + filesystem only) so it can be
|
|
72
|
+
# unit-tested — see bin/tests/test-spec-mode-resolution.sh. It sets SPEC_MODE,
|
|
73
|
+
# SPEC_REASON, SPEC_FAIL, OPENSPEC_USABLE_REASON, OPENSPEC_HINT, CHORUS_OPENSPEC_ACTIVE.
|
|
80
74
|
#
|
|
81
|
-
#
|
|
82
|
-
#
|
|
83
|
-
#
|
|
84
|
-
#
|
|
85
|
-
# without the CLI). Point the user at `/chorus enable openspec`, which walks
|
|
86
|
-
# the actual install/init steps — the banner stays a one-liner.
|
|
75
|
+
# Summary: an explicit CHORUS_SPEC_MODE (lite|openspec|off) wins; when UNSET,
|
|
76
|
+
# OpenSpec stays the default whenever it is usable (openspec/ dir + CLI, not
|
|
77
|
+
# disabled) and lite is the fallback only when OpenSpec is absent or disabled.
|
|
78
|
+
# Legacy CHORUS_OPENSPEC_MODE=off still forces not-openspec (→ lite when unset).
|
|
87
79
|
PROJECT_ROOT="${CLAUDE_PROJECT_DIR:-$PWD}"
|
|
88
|
-
|
|
89
|
-
OPENSPEC_OPTOUT=0
|
|
90
|
-
if [ "${CLAUDE_PLUGIN_OPTION_ENABLEOPENSPEC:-true}" != "true" ]; then
|
|
91
|
-
CHORUS_OPENSPEC_ACTIVE=0
|
|
92
|
-
OPENSPEC_OPTOUT=1
|
|
93
|
-
OPENSPEC_REASON="enableOpenSpec userConfig=false (plugin-level opt-out)"
|
|
94
|
-
elif [ "${CHORUS_OPENSPEC_MODE:-}" = "off" ]; then
|
|
95
|
-
CHORUS_OPENSPEC_ACTIVE=0
|
|
96
|
-
OPENSPEC_OPTOUT=1
|
|
97
|
-
OPENSPEC_REASON="CHORUS_OPENSPEC_MODE=off (explicit opt-out)"
|
|
98
|
-
elif [ ! -d "${PROJECT_ROOT}/openspec" ]; then
|
|
99
|
-
CHORUS_OPENSPEC_ACTIVE=0
|
|
100
|
-
OPENSPEC_REASON="no openspec/ directory at ${PROJECT_ROOT}/openspec"
|
|
101
|
-
elif ! command -v openspec >/dev/null 2>&1; then
|
|
102
|
-
CHORUS_OPENSPEC_ACTIVE=0
|
|
103
|
-
OPENSPEC_REASON="openspec/ directory present but \`openspec\` CLI not on PATH"
|
|
104
|
-
OPENSPEC_HINT="install with: npm i -g @fission-ai/openspec"
|
|
105
|
-
else
|
|
106
|
-
CHORUS_OPENSPEC_ACTIVE=1
|
|
107
|
-
OPENSPEC_REASON="openspec/ directory + openspec CLI both present"
|
|
108
|
-
fi
|
|
80
|
+
. "${SCRIPT_DIR}/resolve-spec-mode.sh"
|
|
109
81
|
|
|
110
82
|
# Build context for Claude (additionalContext)
|
|
111
83
|
CONTEXT="# Chorus Plugin — Active
|
|
@@ -116,33 +88,33 @@ Chorus is connected at ${CHORUS_URL}. Session lifecycle hooks are enabled.
|
|
|
116
88
|
|
|
117
89
|
${CHECKIN_RESULT}
|
|
118
90
|
|
|
119
|
-
##
|
|
91
|
+
## Spec Mode
|
|
120
92
|
|
|
121
|
-
|
|
93
|
+
CHORUS_SPEC_MODE=${SPEC_MODE} (${SPEC_REASON})"
|
|
122
94
|
|
|
123
|
-
if [ "$
|
|
95
|
+
if [ "$SPEC_MODE" = "lite" ]; then
|
|
124
96
|
CONTEXT="${CONTEXT}
|
|
125
97
|
|
|
126
|
-
|
|
98
|
+
Routing: lite → follow the spec-lite skill (\`skills/spec-lite/SKILL.md\`). Author a Chorus-native change folder \`.chorus/specs/<slug>/\` (\`prd.md\` required; \`tech_design.md\` / \`adr.md\` / \`spec.md\` / \`guide.md\` optional) and mirror each \`<type>.md\` 1:1 into a Chorus Document of that type via \`chorus mcp call … --arg-file content=<file>\`. Do NOT scaffold \`openspec/changes/\` or add an \`OpenSpec change slug:\` line."
|
|
99
|
+
elif [ "$SPEC_MODE" = "off" ]; then
|
|
100
|
+
CONTEXT="${CONTEXT}
|
|
127
101
|
|
|
128
|
-
|
|
129
|
-
|
|
102
|
+
Routing: off → free-form, no spec artifact. Do NOT create \`.chorus/specs/\` or \`openspec/changes/\` files; author document drafts inline via direct MCP."
|
|
103
|
+
elif [ -n "$SPEC_FAIL" ]; then
|
|
130
104
|
CONTEXT="${CONTEXT}
|
|
131
105
|
|
|
132
|
-
|
|
133
|
-
if [ "$
|
|
134
|
-
CONTEXT="${CONTEXT}
|
|
106
|
+
Routing: openspec → **cannot be honored** — ${SPEC_FAIL}. The proposal / yolo skill MUST halt after resolving the mode; do NOT silently fall back to lite/free-form. Surface this to the user."
|
|
107
|
+
if [ -n "$OPENSPEC_HINT" ]; then
|
|
108
|
+
CONTEXT="${CONTEXT} Install hint: ${OPENSPEC_HINT}."
|
|
109
|
+
fi
|
|
110
|
+
else
|
|
111
|
+
CONTEXT="${CONTEXT}
|
|
135
112
|
|
|
136
|
-
|
|
137
|
-
elif [ -n "$OPENSPEC_HINT" ]; then
|
|
138
|
-
CONTEXT="${CONTEXT}
|
|
113
|
+
CHORUS_OPENSPEC_ACTIVE=1 (${OPENSPEC_USABLE_REASON})
|
|
139
114
|
|
|
140
|
-
|
|
141
|
-
else
|
|
142
|
-
CONTEXT="${CONTEXT}
|
|
115
|
+
Routing: openspec → load the openspec-aware skill at \`.claude/skills/openspec-aware/SKILL.md\` and follow §3 (OpenSpec authoring) — do NOT re-run the §1 detection block, the answer is already known.
|
|
143
116
|
|
|
144
|
-
|
|
145
|
-
fi
|
|
117
|
+
Critical rule (openspec-aware §2 Rule 1): document mirror calls (\`chorus_pm_add_document_draft\` / \`chorus_pm_update_document_draft\` / \`chorus_pm_update_document\`) MUST fill \`content\` from the local file — prefer \`chorus mcp call <tool> '<json>' --arg-file content=<file>\`, falling back to \`chorus-api.sh mcp-tool\` with \`json_encode_file\` when \`chorus\` is not on PATH. Do NOT invoke these MCP tools directly with hand-typed \`content\` in OpenSpec mode."
|
|
146
118
|
fi
|
|
147
119
|
|
|
148
120
|
CONTEXT="${CONTEXT}
|
|
@@ -164,18 +136,21 @@ Resuming with existing Chorus session: ${MAIN_SESSION}"
|
|
|
164
136
|
"$API" mcp-tool "chorus_session_heartbeat" "$(printf '{"sessionUuid":"%s"}' "$MAIN_SESSION")" >/dev/null 2>&1 || true
|
|
165
137
|
fi
|
|
166
138
|
|
|
167
|
-
# Build user-visible message.
|
|
168
|
-
#
|
|
169
|
-
#
|
|
170
|
-
#
|
|
171
|
-
#
|
|
139
|
+
# Build user-visible message. Always states the active spec mode (lite is the
|
|
140
|
+
# default); an explicit openspec that can't be honored is flagged as not usable.
|
|
141
|
+
# lite -> (Spec: lite)
|
|
142
|
+
# off -> (Spec: off)
|
|
143
|
+
# openspec (usable) -> (Spec: openspec)
|
|
144
|
+
# openspec (broken) -> (Spec: openspec — not usable)
|
|
172
145
|
USER_MSG="Chorus connected at ${CHORUS_URL}"
|
|
173
|
-
if [ "$
|
|
174
|
-
USER_MSG="${USER_MSG} (
|
|
175
|
-
elif [ "$
|
|
176
|
-
USER_MSG="${USER_MSG} (
|
|
146
|
+
if [ "$SPEC_MODE" = "lite" ]; then
|
|
147
|
+
USER_MSG="${USER_MSG} (Spec: lite)"
|
|
148
|
+
elif [ "$SPEC_MODE" = "off" ]; then
|
|
149
|
+
USER_MSG="${USER_MSG} (Spec: off)"
|
|
150
|
+
elif [ -n "$SPEC_FAIL" ]; then
|
|
151
|
+
USER_MSG="${USER_MSG} (Spec: openspec — not usable)"
|
|
177
152
|
else
|
|
178
|
-
USER_MSG="${USER_MSG} (
|
|
153
|
+
USER_MSG="${USER_MSG} (Spec: openspec)"
|
|
179
154
|
fi
|
|
180
155
|
if [ -n "$MAIN_SESSION" ]; then
|
|
181
156
|
USER_MSG="${USER_MSG} (resumed session)"
|
|
@@ -2,8 +2,12 @@
|
|
|
2
2
|
# on-subagent-start.sh — SubagentStart hook
|
|
3
3
|
# Triggered SYNCHRONOUSLY when a sub-agent (teammate) is spawned.
|
|
4
4
|
#
|
|
5
|
-
# Name resolution:
|
|
6
|
-
#
|
|
5
|
+
# Name resolution: the session name is the event's own agent_type (the value the
|
|
6
|
+
# spawning Task call passed as subagent_type), falling back to worker-<agentId8>.
|
|
7
|
+
#
|
|
8
|
+
# Spawn gate: claims a per-spawn pending file written by PreToolUse:Task using
|
|
9
|
+
# atomic mv (only one process can successfully mv a given file). The file only
|
|
10
|
+
# proves the spawn was a real Task call — it never carries the name.
|
|
7
11
|
#
|
|
8
12
|
# Session reuse logic:
|
|
9
13
|
# 1. List existing sessions via MCP
|
|
@@ -45,14 +49,14 @@ export CHORUS_SESSION_ID
|
|
|
45
49
|
[ -f "${SCRIPT_DIR}/chorus-paths.sh" ] && { . "${SCRIPT_DIR}/chorus-paths.sh" 2>/dev/null || true; }
|
|
46
50
|
CHORUS_STATE_DIR="${CHORUS_STATE_DIR:-${CLAUDE_PROJECT_DIR:-.}/.chorus}"
|
|
47
51
|
|
|
48
|
-
# Extract agent info from event
|
|
49
|
-
#
|
|
50
|
-
#
|
|
51
|
-
# (PreToolUse:Task) and stored as a per-agent file in .chorus/pending/.
|
|
52
|
+
# Extract agent info from event.
|
|
53
|
+
# agent_type is the same value the spawning Task call passed as subagent_type,
|
|
54
|
+
# so it is the session name source (see SESSION_NAME below).
|
|
52
55
|
AGENT_ID=$(echo "$EVENT" | jq -r '.agent_id // .agentId // empty' 2>/dev/null) || true
|
|
53
56
|
AGENT_TYPE=$(echo "$EVENT" | jq -r '.agent_type // .agentType // empty' 2>/dev/null) || true
|
|
54
57
|
|
|
55
|
-
# Skip non-worker agent types (read-only agents don't need sessions)
|
|
58
|
+
# Skip non-worker agent types (read-only agents don't need sessions).
|
|
59
|
+
# This list MUST stay identical to the skip list in on-pre-spawn-agent.sh.
|
|
56
60
|
case "$(printf '%s' "$AGENT_TYPE" | tr '[:upper:]' '[:lower:]')" in
|
|
57
61
|
explore|plan|haiku|claude-code-guide|statusline-setup|chorus:proposal-reviewer|chorus:task-reviewer)
|
|
58
62
|
exit 0
|
|
@@ -66,35 +70,24 @@ fi
|
|
|
66
70
|
# Claim a pending file written by PreToolUse:Task (on-pre-spawn-agent.sh).
|
|
67
71
|
# Each pending file represents one expected sub-agent spawn.
|
|
68
72
|
#
|
|
69
|
-
#
|
|
70
|
-
#
|
|
71
|
-
#
|
|
72
|
-
#
|
|
73
|
+
# The pending file is a SPAWN GATE, not a name channel: it only proves this
|
|
74
|
+
# SubagentStart corresponds to a real Task spawn. Neither its filename nor its
|
|
75
|
+
# contents influence the session name, so plain FIFO claiming is safe even when a
|
|
76
|
+
# mixed parallel batch pairs this agent with another spawn's file.
|
|
73
77
|
#
|
|
74
|
-
#
|
|
75
|
-
|
|
78
|
+
# Claim strategy: FIFO by modification time, atomic mv (only one process can
|
|
79
|
+
# succeed per file). If no pending file can be claimed, this is one of Claude
|
|
80
|
+
# Code's internal/cleanup agents (they bypass PreToolUse:Task) → skip.
|
|
76
81
|
PENDING_DIR="${CHORUS_STATE_DIR}/pending"
|
|
77
82
|
CLAIMED_DIR="${CHORUS_STATE_DIR}/claimed"
|
|
78
83
|
mkdir -p "$CLAIMED_DIR" 2>/dev/null || true
|
|
79
84
|
|
|
80
85
|
CLAIMED_FILE=""
|
|
81
86
|
|
|
82
|
-
|
|
83
|
-
if [ -f "${PENDING_DIR}/${AGENT_TYPE}" ]; then
|
|
84
|
-
if mv "${PENDING_DIR}/${AGENT_TYPE}" "${CLAIMED_DIR}/${AGENT_ID}" 2>/dev/null; then
|
|
85
|
-
CLAIMED_FILE="${CLAIMED_DIR}/${AGENT_ID}"
|
|
86
|
-
AGENT_NAME="$AGENT_TYPE"
|
|
87
|
-
fi
|
|
88
|
-
fi
|
|
89
|
-
|
|
90
|
-
# Strategy 2: FIFO — claim oldest pending file
|
|
91
|
-
if [ -z "$CLAIMED_FILE" ] && [ -d "$PENDING_DIR" ]; then
|
|
87
|
+
if [ -d "$PENDING_DIR" ]; then
|
|
92
88
|
for candidate in $(ls -tr "$PENDING_DIR" 2>/dev/null); do
|
|
93
89
|
if mv "${PENDING_DIR}/${candidate}" "${CLAIMED_DIR}/${AGENT_ID}" 2>/dev/null; then
|
|
94
90
|
CLAIMED_FILE="${CLAIMED_DIR}/${AGENT_ID}"
|
|
95
|
-
# Read name from file content if available
|
|
96
|
-
FILE_NAME=$(jq -r '.name // empty' "$CLAIMED_FILE" 2>/dev/null) || true
|
|
97
|
-
AGENT_NAME="${FILE_NAME:-$candidate}"
|
|
98
91
|
break
|
|
99
92
|
fi
|
|
100
93
|
# mv failed → another process claimed it first, try next
|
|
@@ -106,8 +99,17 @@ if [ -z "$CLAIMED_FILE" ]; then
|
|
|
106
99
|
exit 0
|
|
107
100
|
fi
|
|
108
101
|
|
|
109
|
-
#
|
|
110
|
-
|
|
102
|
+
# Session name comes from this event's own agent_type (the same value the Task
|
|
103
|
+
# call passed as subagent_type). Falls back to an agent-id-derived name only when
|
|
104
|
+
# agent_type is empty — never a placeholder like "unknown-<digits>".
|
|
105
|
+
SESSION_NAME="${AGENT_TYPE:-worker-${AGENT_ID:0:8}}"
|
|
106
|
+
|
|
107
|
+
# Sanitized form for on-disk filenames only. Namespaced types such as
|
|
108
|
+
# chorus:code-reviewer are not skipped, so they reach this path and must not put
|
|
109
|
+
# a ":" or "/" into a path. The name sent to Chorus, the state keys and the
|
|
110
|
+
# injected workflow text all keep the raw agent_type.
|
|
111
|
+
SESSION_NAME_FILE=$(printf '%s' "$SESSION_NAME" | tr -c '[:alnum:]._-' '_')
|
|
112
|
+
[ -z "$SESSION_NAME_FILE" ] && SESSION_NAME_FILE="worker-${AGENT_ID:0:8}"
|
|
111
113
|
|
|
112
114
|
# === Session reuse: list existing sessions, find by name ===
|
|
113
115
|
SESSION_UUID=""
|
|
@@ -187,11 +189,24 @@ fi
|
|
|
187
189
|
"$API" state-set "session_${SESSION_NAME}" "$SESSION_UUID"
|
|
188
190
|
"$API" state-set "name_for_agent_${AGENT_ID}" "$SESSION_NAME"
|
|
189
191
|
|
|
192
|
+
# === Holder refcount: register this agent as a holder of the session NAME ===
|
|
193
|
+
# Because the name is the repeating agent_type, two parallel sub-agents of the
|
|
194
|
+
# same type converge on ONE session (reuse-by-name above). on-subagent-stop.sh
|
|
195
|
+
# removes its own entry here and only tears the shared session down when no other
|
|
196
|
+
# holder remains — otherwise the first sibling to exit would close the session,
|
|
197
|
+
# check the other sibling's task out and delete state its sibling still reads.
|
|
198
|
+
# Registered on every path (created / reused / reopened). The directory component
|
|
199
|
+
# uses the SAME sanitization as the sessions/<name>.json filename — a namespaced
|
|
200
|
+
# type such as chorus:code-reviewer must never put a ":" or "/" into a path.
|
|
201
|
+
HOLDERS_DIR="${CHORUS_STATE_DIR}/holders/${SESSION_NAME_FILE}"
|
|
202
|
+
mkdir -p "$HOLDERS_DIR" 2>/dev/null || true
|
|
203
|
+
: > "${HOLDERS_DIR}/${AGENT_ID}" 2>/dev/null || true
|
|
204
|
+
|
|
190
205
|
# === Session file: minimal metadata for other hooks (TeammateIdle, SubagentStop) ===
|
|
191
206
|
SESSIONS_DIR="${CHORUS_STATE_DIR}/sessions"
|
|
192
207
|
mkdir -p "$SESSIONS_DIR" 2>/dev/null || true
|
|
193
208
|
|
|
194
|
-
cat > "${SESSIONS_DIR}/${
|
|
209
|
+
cat > "${SESSIONS_DIR}/${SESSION_NAME_FILE}.json" <<SESSIONEOF
|
|
195
210
|
{
|
|
196
211
|
"sessionUuid": "${SESSION_UUID}",
|
|
197
212
|
"agentId": "${AGENT_ID}",
|
|
@@ -4,6 +4,12 @@
|
|
|
4
4
|
# Auto-checkout from all checked-in tasks, close the Chorus session,
|
|
5
5
|
# clean up state files, and auto-verify if admin AC all passed.
|
|
6
6
|
#
|
|
7
|
+
# Holder-aware: session names are the repeating agent_type, so parallel same-type
|
|
8
|
+
# sub-agents SHARE one session. Teardown (checkout / close / name-keyed state /
|
|
9
|
+
# sessions file / auto-verify) only happens for the LAST holder of the name — see
|
|
10
|
+
# the holder refcount block below. Non-last stops clean up only their own
|
|
11
|
+
# id-keyed state and leave the session running for their siblings.
|
|
12
|
+
#
|
|
7
13
|
# NOTE: SubagentStop does NOT support additionalContext in Claude Code's
|
|
8
14
|
# hookSpecificOutput schema, and systemMessage only reaches the UI —
|
|
9
15
|
# not the main agent's LLM context. All agent-facing reminders must go
|
|
@@ -54,47 +60,104 @@ if [ -z "$SESSION_UUID" ]; then
|
|
|
54
60
|
exit 0
|
|
55
61
|
fi
|
|
56
62
|
|
|
57
|
-
#
|
|
63
|
+
# Sanitized form of the name for on-disk paths (same tr sanitization as
|
|
64
|
+
# on-subagent-start.sh uses for sessions/<name>.json and holders/<name>/) —
|
|
65
|
+
# namespaced types such as chorus:code-reviewer must not put a ":" into a path.
|
|
66
|
+
# The state keys keep the raw name.
|
|
67
|
+
AGENT_NAME_FILE=""
|
|
68
|
+
if [ -n "$AGENT_NAME" ]; then
|
|
69
|
+
AGENT_NAME_FILE=$(printf '%s' "$AGENT_NAME" | tr -c '[:alnum:]._-' '_')
|
|
70
|
+
fi
|
|
71
|
+
|
|
72
|
+
# === Holder refcount: is this the LAST agent holding the session name? ===
|
|
73
|
+
# Session names are the repeating agent_type, so two parallel sub-agents of the
|
|
74
|
+
# same type share ONE session (reuse-by-name in on-subagent-start.sh). Remove our
|
|
75
|
+
# OWN holder entry first, then count what remains: only the last holder may close
|
|
76
|
+
# the session, auto-checkout, auto-verify or delete the name-keyed state that
|
|
77
|
+
# siblings (and on-teammate-idle.sh) still read.
|
|
78
|
+
#
|
|
79
|
+
# Races are benign and must stay benign: if a sibling's start has not registered
|
|
80
|
+
# its holder yet we may see 0 holders and close the session; that sibling's start
|
|
81
|
+
# then finds a closed/inactive row and reopens it via the existing reopen path.
|
|
82
|
+
# Deliberately no locking.
|
|
83
|
+
#
|
|
84
|
+
# With no name in state we cannot refcount — fall back to the legacy
|
|
85
|
+
# single-agent behaviour (treat this stop as the last holder).
|
|
86
|
+
HOLDERS_DIR=""
|
|
87
|
+
HOLDERS_REMAINING=0
|
|
88
|
+
if [ -n "$AGENT_NAME_FILE" ]; then
|
|
89
|
+
HOLDERS_DIR="${CHORUS_STATE_DIR}/holders/${AGENT_NAME_FILE}"
|
|
90
|
+
rm -f "${HOLDERS_DIR}/${AGENT_ID}" 2>/dev/null || true
|
|
91
|
+
if [ -d "$HOLDERS_DIR" ]; then
|
|
92
|
+
HOLDERS_REMAINING=$(ls -1 "$HOLDERS_DIR" 2>/dev/null | grep -c . || true)
|
|
93
|
+
fi
|
|
94
|
+
fi
|
|
95
|
+
[ -n "$HOLDERS_REMAINING" ] || HOLDERS_REMAINING=0
|
|
96
|
+
|
|
97
|
+
IS_LAST_HOLDER=true
|
|
98
|
+
if [ "$HOLDERS_REMAINING" -gt 0 ]; then
|
|
99
|
+
IS_LAST_HOLDER=false
|
|
100
|
+
fi
|
|
101
|
+
|
|
102
|
+
# === Auto-checkout from all checked-in tasks (last holder only) ===
|
|
103
|
+
# Open checkins on a shared session may belong to a still-running sibling, so a
|
|
104
|
+
# non-last stop must not check them out — each sub-agent checks its own task out
|
|
105
|
+
# per the workflow injected by on-subagent-start.sh.
|
|
58
106
|
CHECKOUT_COUNT=0
|
|
59
|
-
SESSION_DETAIL
|
|
107
|
+
SESSION_DETAIL=""
|
|
108
|
+
CLOSE_OK=true
|
|
60
109
|
|
|
61
|
-
if [
|
|
62
|
-
|
|
63
|
-
.checkins[]? | select(.checkoutAt == null) | .taskUuid // empty
|
|
64
|
-
' 2>/dev/null) || true
|
|
110
|
+
if [ "$IS_LAST_HOLDER" = true ]; then
|
|
111
|
+
SESSION_DETAIL=$("$API" mcp-tool "chorus_get_session" "$(printf '{"sessionUuid":"%s"}' "$SESSION_UUID")" 2>/dev/null) || true
|
|
65
112
|
|
|
66
|
-
if [ -
|
|
113
|
+
if [ -n "$SESSION_DETAIL" ]; then
|
|
67
114
|
TASK_UUIDS=$(echo "$SESSION_DETAIL" | jq -r '
|
|
68
|
-
.
|
|
115
|
+
.checkins[]? | select(.checkoutAt == null) | .taskUuid // empty
|
|
69
116
|
' 2>/dev/null) || true
|
|
70
|
-
fi
|
|
71
117
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
>/dev/null 2>&1 || true
|
|
77
|
-
CHECKOUT_COUNT=$((CHECKOUT_COUNT + 1))
|
|
118
|
+
if [ -z "$TASK_UUIDS" ]; then
|
|
119
|
+
TASK_UUIDS=$(echo "$SESSION_DETAIL" | jq -r '
|
|
120
|
+
.sessionTaskCheckins[]? | select(.checkoutAt == null) | .taskUuid // empty
|
|
121
|
+
' 2>/dev/null) || true
|
|
78
122
|
fi
|
|
79
|
-
done
|
|
80
|
-
fi
|
|
81
123
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
"$API" mcp-tool "
|
|
124
|
+
for TASK_UUID in $TASK_UUIDS; do
|
|
125
|
+
if [ -n "$TASK_UUID" ]; then
|
|
126
|
+
"$API" mcp-tool "chorus_session_checkout_task" \
|
|
127
|
+
"$(printf '{"sessionUuid":"%s","taskUuid":"%s"}' "$SESSION_UUID" "$TASK_UUID")" \
|
|
128
|
+
>/dev/null 2>&1 || true
|
|
129
|
+
CHECKOUT_COUNT=$((CHECKOUT_COUNT + 1))
|
|
130
|
+
fi
|
|
131
|
+
done
|
|
132
|
+
fi
|
|
85
133
|
|
|
86
|
-
#
|
|
134
|
+
# Close the Chorus session via MCP
|
|
135
|
+
"$API" mcp-tool "chorus_close_session" "$(printf '{"sessionUuid":"%s"}' "$SESSION_UUID")" >/dev/null 2>&1 || CLOSE_OK=false
|
|
136
|
+
fi
|
|
137
|
+
|
|
138
|
+
# Clean up state.
|
|
139
|
+
# The id-keyed keys are this agent's own and always go. The name-keyed mapping and
|
|
140
|
+
# the reverse map agent_for_session_<uuid> (single-valued — siblings overwrite it)
|
|
141
|
+
# are shared, so they only go on the last-holder path.
|
|
87
142
|
"$API" state-delete "session_${AGENT_ID}" 2>/dev/null || true
|
|
88
|
-
"$API" state-delete "agent_for_session_${SESSION_UUID}" 2>/dev/null || true
|
|
89
143
|
"$API" state-delete "name_for_agent_${AGENT_ID}" 2>/dev/null || true
|
|
90
|
-
if [
|
|
91
|
-
"$API" state-delete "
|
|
144
|
+
if [ "$IS_LAST_HOLDER" = true ]; then
|
|
145
|
+
"$API" state-delete "agent_for_session_${SESSION_UUID}" 2>/dev/null || true
|
|
146
|
+
if [ -n "$AGENT_NAME" ]; then
|
|
147
|
+
"$API" state-delete "session_${AGENT_NAME}" 2>/dev/null || true
|
|
148
|
+
fi
|
|
92
149
|
fi
|
|
93
150
|
|
|
94
|
-
# Clean up session file
|
|
151
|
+
# Clean up session file + holder dir (last holder only — siblings still read
|
|
152
|
+
# sessions/<name>.json, see on-teammate-idle.sh).
|
|
95
153
|
SESSIONS_DIR="${CHORUS_STATE_DIR}/sessions"
|
|
96
|
-
if [
|
|
97
|
-
|
|
154
|
+
if [ "$IS_LAST_HOLDER" = true ]; then
|
|
155
|
+
if [ -n "$AGENT_NAME_FILE" ] && [ -f "${SESSIONS_DIR}/${AGENT_NAME_FILE}.json" ]; then
|
|
156
|
+
rm -f "${SESSIONS_DIR}/${AGENT_NAME_FILE}.json"
|
|
157
|
+
fi
|
|
158
|
+
if [ -n "$HOLDERS_DIR" ] && [ -d "$HOLDERS_DIR" ]; then
|
|
159
|
+
rmdir "$HOLDERS_DIR" 2>/dev/null || true
|
|
160
|
+
fi
|
|
98
161
|
fi
|
|
99
162
|
|
|
100
163
|
# Clean up claimed file (written by SubagentStart)
|
|
@@ -104,7 +167,9 @@ if [ -n "$AGENT_ID" ] && [ -f "${CLAIMED_DIR}/${AGENT_ID}" ]; then
|
|
|
104
167
|
fi
|
|
105
168
|
|
|
106
169
|
# === Auto-verify: if admin marked all AC, verify the task automatically ===
|
|
107
|
-
|
|
170
|
+
# Last holder only: on a shared session the first checkin may belong to a sibling,
|
|
171
|
+
# so a non-last stop must never auto-verify another agent's task.
|
|
172
|
+
if [ "$IS_LAST_HOLDER" = true ] && [ "$CLOSE_OK" = true ] && [ -n "$SESSION_DETAIL" ]; then
|
|
108
173
|
FIRST_TASK_UUID=$(echo "$SESSION_DETAIL" | jq -r '
|
|
109
174
|
(.checkins // .sessionTaskCheckins // [])[] | .taskUuid // empty
|
|
110
175
|
' 2>/dev/null | head -1) || true
|
|
@@ -144,7 +209,13 @@ fi
|
|
|
144
209
|
|
|
145
210
|
# === Output (UI-only, not visible to main agent LLM) ===
|
|
146
211
|
DISPLAY_NAME="${AGENT_NAME:-${AGENT_ID:0:8}}"
|
|
147
|
-
if [ "$
|
|
212
|
+
if [ "$IS_LAST_HOLDER" != true ]; then
|
|
213
|
+
# Shared session still has live holders — do not claim it was closed.
|
|
214
|
+
"$API" hook-output \
|
|
215
|
+
"Chorus session '${DISPLAY_NAME}' kept open (${HOLDERS_REMAINING} other agent(s) still using it)" \
|
|
216
|
+
"" \
|
|
217
|
+
"SubagentStop"
|
|
218
|
+
elif [ "$CLOSE_OK" = true ]; then
|
|
148
219
|
USER_MSG="Chorus session closed: '${DISPLAY_NAME}'"
|
|
149
220
|
if [ "$CHECKOUT_COUNT" -gt 0 ]; then
|
|
150
221
|
USER_MSG="${USER_MSG} (auto-checkout ${CHECKOUT_COUNT} task(s))"
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# resolve-spec-mode.sh — resolve the active Chorus spec mode for a repo.
|
|
3
|
+
#
|
|
4
|
+
# Pure (env + filesystem only; no network). Sourced by on-session-start.sh and
|
|
5
|
+
# driven directly by tests/test-spec-mode-resolution.sh. Bash 3.2 compatible.
|
|
6
|
+
#
|
|
7
|
+
# Inputs (env):
|
|
8
|
+
# CHORUS_SPEC_MODE explicit override: lite | openspec | off (else unset)
|
|
9
|
+
# CHORUS_OPENSPEC_MODE legacy opt-out: "off" disables OpenSpec
|
|
10
|
+
# CLAUDE_PLUGIN_OPTION_ENABLEOPENSPEC plugin toggle: "false" disables OpenSpec (default "true")
|
|
11
|
+
# PROJECT_ROOT repo root to probe for openspec/ (defaults to $PWD)
|
|
12
|
+
# command -v openspec OpenSpec CLI presence on PATH
|
|
13
|
+
#
|
|
14
|
+
# Outputs (vars set in the caller's shell when sourced):
|
|
15
|
+
# SPEC_MODE lite | openspec | off (value surfaced to Claude)
|
|
16
|
+
# SPEC_REASON human-readable one-liner
|
|
17
|
+
# SPEC_FAIL non-empty => stage skill MUST halt (unsatisfiable explicit openspec)
|
|
18
|
+
# OPENSPEC_USABLE 1 | 0
|
|
19
|
+
# OPENSPEC_USABLE_REASON human-readable
|
|
20
|
+
# OPENSPEC_HINT install hint when OpenSpec is merely missing (else empty)
|
|
21
|
+
# CHORUS_OPENSPEC_ACTIVE 1 only when the resolved mode is a USABLE openspec
|
|
22
|
+
#
|
|
23
|
+
# Resolution (per owner): an explicit CHORUS_SPEC_MODE wins; when UNSET, OpenSpec
|
|
24
|
+
# stays the default whenever it is usable (openspec/ dir + CLI, not disabled), and
|
|
25
|
+
# lite is the fallback only when OpenSpec is absent or disabled.
|
|
26
|
+
|
|
27
|
+
: "${PROJECT_ROOT:=$PWD}"
|
|
28
|
+
|
|
29
|
+
# --- Is OpenSpec usable? (needs openspec/ dir + CLI on PATH + not disabled) ---
|
|
30
|
+
OPENSPEC_DISABLED=0
|
|
31
|
+
OPENSPEC_DISABLED_REASON=""
|
|
32
|
+
if [ "${CLAUDE_PLUGIN_OPTION_ENABLEOPENSPEC:-true}" != "true" ]; then
|
|
33
|
+
OPENSPEC_DISABLED=1
|
|
34
|
+
OPENSPEC_DISABLED_REASON="enableOpenSpec userConfig=false (plugin-level opt-out)"
|
|
35
|
+
elif [ "${CHORUS_OPENSPEC_MODE:-}" = "off" ]; then
|
|
36
|
+
OPENSPEC_DISABLED=1
|
|
37
|
+
OPENSPEC_DISABLED_REASON="CHORUS_OPENSPEC_MODE=off (legacy opt-out)"
|
|
38
|
+
fi
|
|
39
|
+
|
|
40
|
+
OPENSPEC_USABLE=0
|
|
41
|
+
OPENSPEC_USABLE_REASON=""
|
|
42
|
+
OPENSPEC_HINT=""
|
|
43
|
+
if [ "$OPENSPEC_DISABLED" = "1" ]; then
|
|
44
|
+
OPENSPEC_USABLE_REASON="$OPENSPEC_DISABLED_REASON"
|
|
45
|
+
elif [ ! -d "${PROJECT_ROOT}/openspec" ]; then
|
|
46
|
+
OPENSPEC_USABLE_REASON="no openspec/ directory at ${PROJECT_ROOT}/openspec"
|
|
47
|
+
OPENSPEC_HINT="npm i -g @fission-ai/openspec && openspec init"
|
|
48
|
+
elif ! command -v openspec >/dev/null 2>&1; then
|
|
49
|
+
OPENSPEC_USABLE_REASON="openspec/ directory present but \`openspec\` CLI not on PATH"
|
|
50
|
+
OPENSPEC_HINT="npm i -g @fission-ai/openspec"
|
|
51
|
+
else
|
|
52
|
+
OPENSPEC_USABLE=1
|
|
53
|
+
OPENSPEC_USABLE_REASON="openspec/ directory + openspec CLI both present"
|
|
54
|
+
fi
|
|
55
|
+
|
|
56
|
+
# --- Resolve CHORUS_SPEC_MODE ---
|
|
57
|
+
SPEC_FAIL=""
|
|
58
|
+
case "${CHORUS_SPEC_MODE:-}" in
|
|
59
|
+
lite)
|
|
60
|
+
SPEC_MODE="lite"
|
|
61
|
+
SPEC_REASON="explicit — Chorus-native lightweight specs in .chorus/specs/<slug>/"
|
|
62
|
+
;;
|
|
63
|
+
off)
|
|
64
|
+
SPEC_MODE="off"
|
|
65
|
+
SPEC_REASON="explicit — free-form, no spec artifact"
|
|
66
|
+
;;
|
|
67
|
+
openspec)
|
|
68
|
+
SPEC_MODE="openspec"
|
|
69
|
+
if [ "$OPENSPEC_USABLE" = "1" ]; then
|
|
70
|
+
SPEC_REASON="explicit; ${OPENSPEC_USABLE_REASON}"
|
|
71
|
+
elif [ "$OPENSPEC_DISABLED" = "1" ]; then
|
|
72
|
+
SPEC_REASON="explicit, but OpenSpec is disabled: ${OPENSPEC_USABLE_REASON}"
|
|
73
|
+
SPEC_FAIL="config conflict — CHORUS_SPEC_MODE=openspec vs OpenSpec disabled (${OPENSPEC_USABLE_REASON}); re-enable OpenSpec or set CHORUS_SPEC_MODE=lite"
|
|
74
|
+
else
|
|
75
|
+
SPEC_REASON="explicit, but OpenSpec is not installed: ${OPENSPEC_USABLE_REASON}"
|
|
76
|
+
SPEC_FAIL="OpenSpec not usable (${OPENSPEC_USABLE_REASON})"
|
|
77
|
+
fi
|
|
78
|
+
;;
|
|
79
|
+
"")
|
|
80
|
+
# Unset: OpenSpec is the default when usable; lite is the fallback otherwise.
|
|
81
|
+
if [ "$OPENSPEC_USABLE" = "1" ]; then
|
|
82
|
+
SPEC_MODE="openspec"
|
|
83
|
+
SPEC_REASON="default — ${OPENSPEC_USABLE_REASON}; set CHORUS_SPEC_MODE=lite for Chorus-native specs, =off to disable"
|
|
84
|
+
else
|
|
85
|
+
SPEC_MODE="lite"
|
|
86
|
+
SPEC_REASON="default — OpenSpec not usable (${OPENSPEC_USABLE_REASON}); using Chorus-native lightweight specs in .chorus/specs/<slug>/"
|
|
87
|
+
fi
|
|
88
|
+
;;
|
|
89
|
+
*)
|
|
90
|
+
# Unrecognized value: treat like unset (OpenSpec-if-usable, else lite).
|
|
91
|
+
if [ "$OPENSPEC_USABLE" = "1" ]; then
|
|
92
|
+
SPEC_MODE="openspec"
|
|
93
|
+
SPEC_REASON="CHORUS_SPEC_MODE='${CHORUS_SPEC_MODE}' unrecognized; falling back to default (${OPENSPEC_USABLE_REASON})"
|
|
94
|
+
else
|
|
95
|
+
SPEC_MODE="lite"
|
|
96
|
+
SPEC_REASON="CHORUS_SPEC_MODE='${CHORUS_SPEC_MODE}' unrecognized; OpenSpec not usable, defaulting to lite"
|
|
97
|
+
fi
|
|
98
|
+
;;
|
|
99
|
+
esac
|
|
100
|
+
|
|
101
|
+
# Back-compat flag for the openspec-aware skill: active only when the resolved
|
|
102
|
+
# mode is a USABLE openspec.
|
|
103
|
+
if [ "$SPEC_MODE" = "openspec" ] && [ -z "$SPEC_FAIL" ]; then
|
|
104
|
+
CHORUS_OPENSPEC_ACTIVE=1
|
|
105
|
+
else
|
|
106
|
+
CHORUS_OPENSPEC_ACTIVE=0
|
|
107
|
+
fi
|