@chorus-aidlc/chorus 0.16.1 → 0.16.2
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 +373 -372
- package/.next/standalone/.next/app-path-routes-manifest.json +41 -41
- package/.next/standalone/.next/build-manifest.json +5 -5
- package/.next/standalone/.next/prerender-manifest.json +42 -42
- 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.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/activity/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/dashboard/[ideaUuid]/page.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/dashboard/[ideaUuid]/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/dashboard/[ideaUuid]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/dashboard/page.js +1 -1
- 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 +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/documents/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/documents/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/graph/page.js +1 -1
- 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.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/tasks/[taskUuid]/page.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/tasks/[taskUuid]/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/tasks/[taskUuid]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/tasks/page.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/tasks/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/tasks/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/page.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/settings/page.js +2 -2
- package/.next/standalone/.next/server/app/(dashboard)/settings/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/settings/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/_not-found.html +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_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 +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 +2 -2
- 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 +1 -1
- 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 +41 -41
- package/.next/standalone/.next/server/chunks/2572.js +1 -1
- package/.next/standalone/.next/server/chunks/2618.js +1 -1
- package/.next/standalone/.next/server/chunks/2961.js +1 -1
- package/.next/standalone/.next/server/chunks/3594.js +1 -1
- package/.next/standalone/.next/server/chunks/{2547.js → 4011.js} +3 -3
- package/.next/standalone/.next/server/chunks/4827.js +1 -1
- package/.next/standalone/.next/server/chunks/5205.js +1 -0
- package/.next/standalone/.next/server/chunks/5245.js +1 -1
- package/.next/standalone/.next/server/chunks/6113.js +1 -1
- package/.next/standalone/.next/server/chunks/6506.js +3 -3
- package/.next/standalone/.next/server/chunks/6515.js +2 -2
- package/.next/standalone/.next/server/chunks/6995.js +1 -1
- package/.next/standalone/.next/server/chunks/7364.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/middleware-build-manifest.js +1 -1
- package/.next/standalone/.next/server/middleware-manifest.json +1 -1
- package/.next/standalone/.next/server/pages/404.html +2 -2
- package/.next/standalone/.next/server/pages/500.html +1 -1
- package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/static/chunks/{11595.1bcd2b65089007ae.js → 11595.b6f8ad33572b32fe.js} +1 -1
- package/.next/standalone/.next/static/chunks/19887-9f459ee9e8d0855f.js +1 -0
- package/.next/standalone/.next/static/chunks/{29108-e171d8b8c680cbb5.js → 29108-b9b232255811ffa8.js} +1 -1
- package/.next/standalone/.next/static/chunks/{31308-bb4a97b3f39c22dd.js → 31308-fda6febfb2882a28.js} +1 -1
- package/.next/standalone/.next/static/chunks/{33456.c98d3e21528b61d8.js → 33456.e8550ad410031e29.js} +1 -1
- package/.next/standalone/.next/static/chunks/35432-ee83da56c49ef6f8.js +1 -0
- package/.next/standalone/.next/static/chunks/{4860.9122a86d33dc6b62.js → 4860.b405fc235b36271b.js} +1 -1
- package/.next/standalone/.next/static/chunks/66980-652990fcf3212c94.js +10 -0
- package/.next/standalone/.next/static/chunks/{94643-90a9ec7b9a9abaf0.js → 94643-6d31df78aa3074b5.js} +1 -1
- package/.next/standalone/.next/static/chunks/96170-75da13decdb6f73f.js +1 -0
- package/.next/standalone/.next/static/chunks/{99373.585230dcb315a068.js → 99373.9dce8f30802824fc.js} +1 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/{layout-3d3b3b9e16c03cda.js → layout-cea0bb3e3a295bea.js} +1 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/dashboard/{page-69d746c98079024d.js → page-007278623926490f.js} +1 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/documents/[documentUuid]/{page-2af705f6c3789131.js → page-b6ecaf52f6b81ec7.js} +1 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/graph/{page-8119df915138a9c3.js → page-f5a351c544ed23d7.js} +1 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/[proposalUuid]/page-3cd46bec9383b191.js +1 -0
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/tasks/[taskUuid]/{page-0789c6589363154c.js → page-7f87113e5d8bcf6e.js} +1 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/tasks/{page-a612f6fc5be0239d.js → page-30ab1573c4bd466f.js} +1 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/settings/{page-5fb9fd3db155d5ca.js → page-b21d4184d9ca0b25.js} +1 -1
- package/.next/standalone/.next/static/chunks/app/onboarding/page-3b6c54f887108635.js +1 -0
- package/.next/standalone/.next/static/chunks/{webpack-dec1f54ebb9bf963.js → webpack-b54e0c78eded76be.js} +1 -1
- package/.next/standalone/.next/static/css/893d99a21153c9b0.css +1 -0
- 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/agents/code-reviewer.md +1 -1
- package/.next/standalone/public/chorus-plugin/agents/proposal-reviewer.md +1 -0
- package/.next/standalone/public/chorus-plugin/agents/task-reviewer.md +2 -0
- package/.next/standalone/public/chorus-plugin/skills/brainstorm/SKILL.md +1 -1
- package/.next/standalone/public/chorus-plugin/skills/chorus/SKILL.md +3 -3
- package/.next/standalone/public/chorus-plugin/skills/develop/SKILL.md +1 -1
- 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 +1 -1
- package/.next/standalone/public/chorus-plugin/skills/proposal/SKILL.md +1 -1
- 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 +1 -1
- 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 +1 -1
- package/.next/standalone/public/kiro-plugin/.kiro/agents/chorus-task-reviewer.json +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-develop/SKILL.md +1 -1
- 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 +1 -1
- package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-proposal/SKILL.md +1 -1
- 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 +1 -1
- package/.next/standalone/public/kiro-plugin/.kiro/steering/chorus.md +2 -2
- package/.next/standalone/public/kiro-plugin/bin/chorus-api.sh +1 -1
- package/.next/standalone/public/skill/chorus/SKILL.md +2 -2
- package/.next/standalone/public/skill/code-reviewer-chorus/SKILL.md +2 -2
- package/.next/standalone/public/skill/proposal-reviewer-chorus/SKILL.md +2 -1
- package/.next/standalone/public/skill/task-reviewer-chorus/SKILL.md +2 -1
- package/README.ja.md +26 -346
- package/README.ko.md +28 -347
- package/README.md +33 -353
- package/README.zh.md +31 -328
- package/cli/control-handler.mjs +13 -3
- package/cli/daemon-rest-client.mjs +11 -3
- package/cli/daemon.mjs +52 -10
- package/cli/event-router.mjs +17 -5
- package/cli/prompts.mjs +116 -1
- package/cli/turn-reporter.mjs +5 -1
- package/cli/wake-queue.mjs +57 -35
- package/cli/waker.mjs +125 -36
- package/package.json +1 -1
- package/prisma/migrations/20260814101500_add_typed_assignment_provenance/migration.sql +2 -0
- package/prisma/schema.prisma +4 -2
- package/.next/standalone/.next/server/chunks/1114.js +0 -1
- package/.next/standalone/.next/static/chunks/19887-4d76db57a7ce4437.js +0 -1
- package/.next/standalone/.next/static/chunks/4340-a33120fb742af57e.js +0 -1
- package/.next/standalone/.next/static/chunks/94426-39b6da238425f9b7.js +0 -10
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/[proposalUuid]/page-f619bd65e1eed8c9.js +0 -1
- package/.next/standalone/.next/static/chunks/app/onboarding/page-e85315278aafc300.js +0 -1
- package/.next/standalone/.next/static/css/67fba0943f494f0e.css +0 -1
- /package/.next/standalone/.next/static/{H92ZuhpmDWcL3WOfYRc-- → YTZwWTfE0BsJnjCDYCEHi}/_buildManifest.js +0 -0
- /package/.next/standalone/.next/static/{H92ZuhpmDWcL3WOfYRc-- → YTZwWTfE0BsJnjCDYCEHi}/_ssgManifest.js +0 -0
package/README.zh.md
CHANGED
|
@@ -2,15 +2,15 @@
|
|
|
2
2
|
<img src="packages/landing/public/images/chorus-slug.png" alt="Chorus" width="240" />
|
|
3
3
|
</p>
|
|
4
4
|
|
|
5
|
-
<p align="center"><strong
|
|
5
|
+
<p align="center"><strong>你的编程 Agent 之上的 Harness:Agent 提议,人类把关,软件交付。</strong></p>
|
|
6
6
|
|
|
7
7
|
<p align="center"><a href="README.md">English</a> · <strong>中文</strong> · <a href="README.ko.md">한국어</a> · <a href="README.ja.md">日本語</a></p>
|
|
8
8
|
|
|
9
|
-
<p align="center"><a href="https://doc.chorus-ai.dev"><strong>📖 文档</strong></a></p>
|
|
9
|
+
<p align="center"><a href="https://doc.chorus-ai.dev/zh/"><strong>📖 文档</strong></a></p>
|
|
10
10
|
|
|
11
|
-
Chorus
|
|
11
|
+
Chorus 是你的编程 Agent 之上的 Harness。编程 Agent 是把模型 harness 起来写代码的那层;Chorus 高它们一层,把多个这样的 Agent 和你收进同一条流水线:Agent 提议,你来验收,想法最终交付成软件,而不只是写代码。在底层,它把这套多 Agent、真人把关的协作稳稳跑起来所需的一切都处理好:会话生命周期、任务状态、子 Agent 编排、可观测性和故障恢复。每个 AI Agent 都有细粒度、可配置的权限。
|
|
12
12
|
|
|
13
|
-
受 **[AI-DLC(AI-Driven Development Lifecycle)](https://aws.amazon.com/blogs/devops/ai-driven-development-life-cycle/)** 方法论启发。核心理念:**Reversed Conversation
|
|
13
|
+
受 **[AI-DLC(AI-Driven Development Lifecycle)](https://aws.amazon.com/blogs/devops/ai-driven-development-life-cycle/)** 方法论启发。核心理念:**Reversed Conversation**:AI 提议,人类验证。
|
|
14
14
|
|
|
15
15
|
---
|
|
16
16
|
|
|
@@ -23,7 +23,7 @@ Idea ──> Proposal ──> [Document + Task DAG] ──> Execute ──> Veri
|
|
|
23
23
|
提出 + 需求澄清 + 起草 PRD/任务 + 报告进度 + 验收 + 关闭
|
|
24
24
|
```
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
每个阶段下方标的是「执行该阶段所需的权限」,可以授予人类、Agent 或两者。没有固定角色,5 × 3 权限矩阵的任意组合都合法。→ [Agent 权限](https://doc.chorus-ai.dev/zh/guides/manage-agents/)
|
|
27
27
|
|
|
28
28
|
---
|
|
29
29
|
|
|
@@ -45,248 +45,58 @@ Idea ──> Proposal ──> [Document + Task DAG] ──> Execute ──> Veri
|
|
|
45
45
|
|
|
46
46
|
## 快速开始
|
|
47
47
|
|
|
48
|
-
|
|
48
|
+
两条命令即可,无需数据库、无需 Docker、无需配置文件。
|
|
49
49
|
|
|
50
50
|
```bash
|
|
51
51
|
npm install -g @chorus-aidlc/chorus
|
|
52
52
|
chorus
|
|
53
53
|
```
|
|
54
54
|
|
|
55
|
-
Chorus 会自动启动内嵌 PostgreSQL (PGlite)、执行数据库迁移,然后在 **http://localhost:8637**
|
|
55
|
+
Chorus 会自动启动内嵌 PostgreSQL (PGlite)、执行数据库迁移,然后在 **http://localhost:8637** 提供服务。默认登录账号:`admin@chorus.local` / `chorus`。
|
|
56
56
|
|
|
57
|
-
>
|
|
57
|
+
> 需要运行多个 agent,或部署到生产环境?可使用外部 PostgreSQL、Docker 或 AWS → **[部署与自托管](https://doc.chorus-ai.dev/zh/guides/deployment-overview/)**。
|
|
58
58
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
### 参数选项
|
|
62
|
-
|
|
63
|
-
```bash
|
|
64
|
-
# 自定义端口
|
|
65
|
-
chorus --port 3000
|
|
66
|
-
|
|
67
|
-
# 自定义数据目录(默认:~/.chorus-data)
|
|
68
|
-
chorus --data-dir /path/to/data
|
|
69
|
-
|
|
70
|
-
# 自定义登录账号
|
|
71
|
-
DEFAULT_USER=me@example.com DEFAULT_PASSWORD=secret chorus
|
|
72
|
-
|
|
73
|
-
# 使用外部 PostgreSQL(跳过内嵌 PGlite)
|
|
74
|
-
DATABASE_URL=postgresql://user:pass@host:5432/chorus chorus
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
### 其他部署方式
|
|
78
|
-
|
|
79
|
-
| 方式 | 命令 |
|
|
80
|
-
|------|------|
|
|
81
|
-
| **npm**(最简单) | `npm i -g @chorus-aidlc/chorus && chorus` |
|
|
82
|
-
| **Docker(单镜像)** | [`docker compose -f docker-compose.local.yml up`](#docker-一键启动推荐) |
|
|
83
|
-
| **Docker(完整版)** | [`docker compose up`](#docker-一键启动推荐)(PostgreSQL + Redis + Chorus) |
|
|
84
|
-
| **AWS CDK** | [部署到 AWS](#部署到-aws) |
|
|
85
|
-
|
|
86
|
-
### `chorus daemon` — 作为 Agent 运行时连接
|
|
87
|
-
|
|
88
|
-
`chorus daemon` 将你的本地机器作为 Agent 运行时连接到远程 Chorus 服务器并执行 Chorus 分配的任务。
|
|
89
|
-
|
|
90
|
-
> **Agent 后端:** 支持 **Claude Code**(默认)和 **Codex**,用 `--agent codex`(或 `CHORUS_AGENT=codex`)切换。对其他 Agent CLI(Copilot 等)的支持计划在未来版本中实现。
|
|
91
|
-
|
|
92
|
-
```bash
|
|
93
|
-
chorus login # 认证(打开浏览器)
|
|
94
|
-
chorus daemon # 前台启动 daemon
|
|
95
|
-
chorus daemon -d # 后台启动 daemon(分离模式)
|
|
96
|
-
chorus daemon install # 安装为开机自启服务(Linux)—— 推荐
|
|
97
|
-
chorus daemon uninstall # 卸载已安装的服务
|
|
98
|
-
chorus daemon stop # 停止 daemon(已安装服务时委派给 systemd)
|
|
99
|
-
chorus daemon stop --force # pid 卡死时强制清理 pidfile
|
|
100
|
-
chorus daemon status # 查看 daemon 状态
|
|
101
|
-
chorus daemon restart # 重启 daemon
|
|
102
|
-
chorus daemon logs # 查看 daemon 日志
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
**主要特性:**
|
|
106
|
-
|
|
107
|
-
- **Claude Code 与 Codex 后端** — 自动检测 PATH 中的 `claude`(或 `codex`)CLI;用 `--agent codex` 选择
|
|
108
|
-
- **后台模式** — 使用 `-d` 标志后台运行;用 `stop/restart/logs` 管理
|
|
109
|
-
- **开机自启服务** — `chorus daemon install` 生成正确的 `systemd --user` unit 并启动(见下文);此后 `status/stop/restart/logs` 会自动委派给 systemd
|
|
110
|
-
- **权限模式** — 默认完全访问(yolo);使用 `--chorus-only` 限制为仅 Chorus MCP 工具
|
|
111
|
-
- **多路径** — 用可重复的 `--cwd` 让单个 daemon 同时服务多个工作目录(见下文)
|
|
112
|
-
- **交互式设置** — 首次启动时如未配置凭证会提示输入
|
|
113
|
-
|
|
114
|
-
daemon 需要先认证。首次使用请先运行 `chorus login`,或者 daemon 会在首次启动时交互式提示输入凭证(如果在终端中运行)。
|
|
115
|
-
|
|
116
|
-
#### 开机 / 登录时自启 —— `chorus daemon install`
|
|
117
|
-
|
|
118
|
-
```bash
|
|
119
|
-
chorus daemon install --cwd ~/work/repo-a --cwd ~/work/repo-b # 立即安装并启动,登录时自启
|
|
120
|
-
chorus daemon uninstall # 停用并移除该服务
|
|
121
|
-
```
|
|
122
|
-
|
|
123
|
-
在 Linux 上,`install` 会生成一个 `systemd --user` unit,让 daemon 以**前台**方式运行(`Type=simple`,不带 `-d`),从而由 systemd 直接接管进程,然后 `daemon-reload` + `enable --now`。它会捕获你传入的 `--cwd`/`--agent`/`--chorus-only` 参数。**不要**手写 `Type=forking` + `chorus daemon -d` 的 unit —— daemon 会自我 daemon 化,systemd 追踪不到,重启时会陷入死循环;交给 `install` 写正确的 unit。在 macOS/Windows 上,`install` 会打印一份可手动安装的正确模板。请先运行 `chorus login`,让 unit 能读到凭证。详见 [docs/DAEMON.md](docs/DAEMON.md)。
|
|
124
|
-
|
|
125
|
-
#### 服务多个工作目录
|
|
126
|
-
|
|
127
|
-
一个 daemon 可以同时服务多个本地工作目录——每个声明的路径会注册为一条独立连接(各自拥有会话与唤起循环),归属同一个 Agent。路径**仅仅**是 daemon 服务的目录,不携带任何项目绑定。
|
|
128
|
-
|
|
129
|
-
```bash
|
|
130
|
-
chorus daemon --cwd ~/work/repo-a --cwd ~/work/repo-b # 可重复传入
|
|
131
|
-
CHORUS_DAEMON_CWDS="~/work/repo-a:~/work/repo-b" chorus daemon # 或用环境变量(`:` 或 `,` 分隔)
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
不传 `--cwd` 时,daemon 只服务它的启动目录这一个路径。
|
|
135
|
-
|
|
136
|
-
#### 配置文件 —— `~/.chorus/daemon.json`
|
|
137
|
-
|
|
138
|
-
`chorus login` 会把凭证写入此文件(权限 `0600`)。你也可以把 daemon 的调优项写进**同一个**文件。所有字段都是可选的;命令行参数和环境变量的优先级始终高于文件。
|
|
139
|
-
|
|
140
|
-
```json
|
|
141
|
-
{
|
|
142
|
-
"url": "https://chorus.example.com",
|
|
143
|
-
"apiKey": "cho_xxxxxxxxxxxxxxxxxxxxxxxx",
|
|
144
|
-
"agentUuid": "00000000-0000-0000-0000-000000000000",
|
|
145
|
-
"agentName": "My Daemon Agent",
|
|
146
|
-
"cwds": ["~/work/repo-a", "~/work/repo-b"],
|
|
147
|
-
"sigintTimeoutMs": 10000
|
|
148
|
-
}
|
|
149
|
-
```
|
|
150
|
-
|
|
151
|
-
| 字段 | 类型 | 写入方 / 用途 | 优先级(从高到低) |
|
|
152
|
-
|------|------|---------------|--------------------|
|
|
153
|
-
| `url` | string | 远程 Chorus 服务器 URL | `--url` 参数 → `CHORUS_URL` → 文件 |
|
|
154
|
-
| `apiKey` | string | Agent API Key(`cho_…`) | `--api-key` 参数 → `CHORUS_API_KEY` → 文件 |
|
|
155
|
-
| `agentUuid` / `agentName` | string | 认证身份(登录时记录) | 由 `chorus login` 写入 |
|
|
156
|
-
| `cwds` | string[] | daemon 服务的工作目录(多路径) | `--cwd` 参数 → `CHORUS_DAEMON_CWDS` → 文件 → 启动目录 |
|
|
157
|
-
| `sigintTimeoutMs` | number | SIGINT 后强制结束前的宽限窗口(毫秒,默认 `10000`) | `--sigint-timeout` 参数 → `CHORUS_DAEMON_SIGINT_TIMEOUT` → 文件 → `10000` |
|
|
158
|
-
| `yoloAckAt` | string | 内部字段——TTY 下 yolo 确认的时间戳(自动管理) | — |
|
|
159
|
-
|
|
160
|
-
daemon 启动时的横幅会打印它**实际读取的 `daemon.json` 路径**(以及该文件是否存在),让你随时清楚该编辑哪个文件。
|
|
59
|
+
想把本地机器变成领取任务的 agent 运行时,运行 `chorus daemon` → **[Daemon 运维](https://doc.chorus-ai.dev/zh/guides/daemon-operations/)** · **[远程控制](https://doc.chorus-ai.dev/zh/guides/remote-control/)**。
|
|
161
60
|
|
|
162
61
|
---
|
|
163
62
|
|
|
164
63
|
## 界面预览
|
|
165
64
|
|
|
166
|
-
### 远程唤醒 Agent
|
|
65
|
+
### 远程唤醒 Agent:派活到指定目录,实时看它跑
|
|
167
66
|
|
|
168
67
|

|
|
169
68
|
|
|
170
69
|
把一条想法派给远程 Agent 的某个目录,打开对话窗口,就能实时看到本地的 Claude Code 接活、开跑,全程不用碰终端,也不用手动 resume。
|
|
171
70
|
|
|
172
|
-
###
|
|
71
|
+
### 项目资源图谱:整个项目一张实时思维导图
|
|
173
72
|
|
|
174
73
|

|
|
175
74
|
|
|
176
|
-
|
|
75
|
+
想法、提案、文档、任务连成一棵树,每张卡片的状态随着 Agent 工作实时更新。
|
|
177
76
|
|
|
178
|
-
### Proposal
|
|
77
|
+
### Proposal:AI Agent 实时生成计划
|
|
179
78
|
|
|
180
79
|

|
|
181
80
|
|
|
182
81
|
PM Agent 分析需求并实时生成包含 PRD 和任务 DAG 的提案,Presence 指示器实时显示 Agent 活动状态。
|
|
183
82
|
|
|
184
|
-
###
|
|
185
|
-
|
|
186
|
-

|
|
187
|
-
|
|
188
|
-
左侧为像素工作室,用像素小人代表每个 Agent 的实时工作状态;右侧为 Agent 终端实时输出。
|
|
189
|
-
|
|
190
|
-
### Kanban——任务状态实时流转
|
|
83
|
+
### Kanban:任务状态实时流转
|
|
191
84
|
|
|
192
85
|

|
|
193
86
|
|
|
194
87
|
Kanban 看板随 Agent 工作进度自动更新,任务卡片在 To Do → In Progress → To Verify 之间实时流转。Presence 指示器高亮显示正在被操作的资源。
|
|
195
88
|
|
|
196
|
-
### 看板 & 任务 DAG
|
|
197
|
-
|
|
198
|
-

|
|
199
|
-
|
|
200
|
-
看板追踪任务状态,DAG 展示依赖关系和并行路径,一目了然。
|
|
201
|
-
|
|
202
|
-
### Idea & 需求细化
|
|
203
|
-
|
|
204
|
-

|
|
205
|
-
|
|
206
|
-
PM Agent 在创建 Proposal 前,通过结构化问答轮次澄清需求。面板展示 Idea 详情及已完成的细化轮次。
|
|
207
|
-
|
|
208
|
-
### 提案审阅
|
|
209
|
-
|
|
210
|
-

|
|
211
|
-
|
|
212
|
-
PM Agent 生成的 Proposal 包含文档草稿和任务 DAG 草稿,Admin 在此面板审阅并决定批准或驳回。
|
|
213
|
-
|
|
214
|
-
### 验收标准——双路验证
|
|
215
|
-
|
|
216
|
-

|
|
217
|
-
|
|
218
|
-
Dev Agent 自检 + Admin 独立审核,每条验收标准都有结构化的通过/失败证据。
|
|
219
|
-
|
|
220
|
-
### Universal Search——Cmd+K 全局搜索
|
|
221
|
-
|
|
222
|
-

|
|
223
|
-
|
|
224
|
-
Cmd+K 命令面板,支持跨 6 种实体类型搜索。支持范围筛选(全局/项目组/单项目)、按类型切换 Tab、键盘导航。Web UI 和 AI Agent(通过 `chorus_search` MCP 工具)共享同一搜索后端。
|
|
225
|
-
|
|
226
89
|
---
|
|
227
90
|
|
|
228
|
-
##
|
|
229
|
-
|
|
230
|
-
- **会话生命周期** — 持久化 Session,心跳检测,自动过期与故障恢复
|
|
231
|
-
- **任务 DAG** — 依赖建模、环检测、交互式可视化
|
|
232
|
-
- **Kanban** — 实时任务流转,Worker 徽标与 Agent Presence
|
|
233
|
-
- **Multi-Agent 协作** — Claude Code Agent Teams (Swarm Mode) 并行执行
|
|
234
|
-
- **细粒度 Agent 权限** — 5 类资源 × 3 个动作组成的权限网格,支持预设 + 自定义组合([详细说明](docs/PERMISSIONS.md) · 英文)
|
|
235
|
-
- **Chorus Plugin** — 生命周期钩子自动管理 Session 创建/关闭、心跳、上下文注入
|
|
236
|
-
- **需求澄清** — Proposal 创建前的结构化问答轮次
|
|
237
|
-
- **Proposal 审批流** — PM 起草,Admin 审批,草稿物化为正式实体
|
|
238
|
-
- **通知系统** — 应用内 + SSE 推送 + Redis Pub/Sub,支持个人偏好设置([设计文档](src/app/api/notifications/README.md))
|
|
239
|
-
- **@Mention** — Tiptap 自动补全、权限隔离搜索、mention 通知([设计文档](src/app/api/mentionables/README.md))
|
|
240
|
-
- **活动流** — 全操作审计 + Session 归因
|
|
241
|
-
- **全局搜索** — Cmd+K 跨 6 种实体类型、3 级范围筛选、片段生成([设计文档](docs/SEARCH.md))
|
|
242
|
-
---
|
|
91
|
+
## 连接 Agent
|
|
243
92
|
|
|
244
|
-
|
|
93
|
+
最快的方式是应用内的 setup 向导:打开 **Settings → Setup Guide**。它会创建 API Key,并给出适配你所用客户端的完整命令,无论是 Claude Code、Codex、Kiro、OpenCode、OpenClaw、Pi,还是任何兼容 MCP 的 agent。
|
|
245
94
|
|
|
246
|
-
|
|
247
|
-
┌──────────────────────────────────────────────────────────────────┐
|
|
248
|
-
│ Chorus — Agent Harness (:8637) │
|
|
249
|
-
│ │
|
|
250
|
-
│ ┌── Harness Capabilities ───────────────────────────────────┐ │
|
|
251
|
-
│ │ Session Lifecycle │ Task State Machine │ Context Inject │ │
|
|
252
|
-
│ │ Sub-Agent Orchestration │ Observability │ Failure Recovery│ │
|
|
253
|
-
│ └───────────────────────────────────────────────────────────┘ │
|
|
254
|
-
│ │
|
|
255
|
-
│ ┌── Chorus Plugin (lifecycle hooks) ────────────────────────┐ │
|
|
256
|
-
│ │ SubagentStart/Stop │ Heartbeat │ Skill & Context Inject │ │
|
|
257
|
-
│ └───────────────────────────────────────────────────────────┘ │
|
|
258
|
-
│ │
|
|
259
|
-
│ ┌── API Layer ──────────────────────────────────────────────┐ │
|
|
260
|
-
│ │ /api/mcp — MCP Streaming (50+ tools, permission-gated) │ │
|
|
261
|
-
│ │ /api/* — REST API (Web UI + SSE push) │ │
|
|
262
|
-
│ └───────────────────────────────────────────────────────────┘ │
|
|
263
|
-
│ │
|
|
264
|
-
│ ┌── Service Layer ──────────────────────────────────────────┐ │
|
|
265
|
-
│ │ AI-DLC Workflow │ UUID-first │ Multi-tenant │ │
|
|
266
|
-
│ └───────────────────────────────────────────────────────────┘ │
|
|
267
|
-
│ │
|
|
268
|
-
│ ┌── Web UI (React 19 + Tailwind + shadcn/ui) ──────────────┐ │
|
|
269
|
-
│ │ Kanban │ Task DAG │ Proposals │ Activity │ Sessions │ │
|
|
270
|
-
│ └───────────────────────────────────────────────────────────┘ │
|
|
271
|
-
└──────────────────────────────────────────────────────────────────┘
|
|
272
|
-
↑ ↑ ↑ ↑
|
|
273
|
-
Agent w/ Agent w/ Agent w/ 人类
|
|
274
|
-
idea+proposal task:write *:admin perms (浏览器)
|
|
275
|
-
:write perms perms (代理人类审批)
|
|
276
|
-
(LLM) (LLM) (LLM)
|
|
277
|
-
│
|
|
278
|
-
┌──────────▼──────────┐ ┌─────────────────────┐
|
|
279
|
-
│ PostgreSQL + Prisma │ │ Redis(可选) │
|
|
280
|
-
└─────────────────────┘ │ Pub/Sub 事件分发 │
|
|
281
|
-
└─────────────────────┘
|
|
282
|
-
```
|
|
95
|
+
按客户端分的完整接入指南 → **[Agent 接入平台](https://doc.chorus-ai.dev/zh/reference/agents/)**。
|
|
283
96
|
|
|
284
|
-
|
|
97
|
+
在 **Settings → Agents → Create API Key** 创建 API Key。Key 以 `cho_` 开头,仅在创建时显示一次。
|
|
285
98
|
|
|
286
|
-
|
|
287
|
-
|---|------|
|
|
288
|
-
| [`packages/openclaw-plugin`](packages/openclaw-plugin) | **OpenClaw 插件** — 通过 SSE 长连接 + MCP 工具桥接 [OpenClaw](https://openclaw.ai) 与 Chorus。 |
|
|
289
|
-
| [`packages/chorus-cdk`](packages/chorus-cdk) | **AWS CDK** — Chorus 的 AWS 基础设施即代码。 |
|
|
99
|
+
---
|
|
290
100
|
|
|
291
101
|
## 技术栈
|
|
292
102
|
|
|
@@ -294,132 +104,25 @@ Cmd+K 命令面板,支持跨 6 种实体类型搜索。支持范围筛选(
|
|
|
294
104
|
|------|------|
|
|
295
105
|
| 框架 | Next.js 15 (App Router, Turbopack) |
|
|
296
106
|
| 语言 | TypeScript 5 (strict mode) |
|
|
297
|
-
| 前端 | React 19, Tailwind CSS 4, shadcn/ui
|
|
298
|
-
|
|
|
299
|
-
|
|
|
300
|
-
| 缓存/消息 | Redis 7 (ioredis) — 可选 |
|
|
301
|
-
| Agent 集成 | MCP SDK 1.26 (HTTP Streamable Transport) |
|
|
107
|
+
| 前端 | React 19, Tailwind CSS 4, shadcn/ui |
|
|
108
|
+
| 数据 | PostgreSQL 16 + Prisma 7, Redis 7(可选) |
|
|
109
|
+
| Agent 集成 | MCP SDK (HTTP Streamable Transport) |
|
|
302
110
|
| 认证 | OIDC + PKCE / API Key / SuperAdmin |
|
|
303
111
|
| i18n | next-intl (en, zh, ko, ja) |
|
|
304
|
-
| 部署 |
|
|
305
|
-
|
|
306
|
-
---
|
|
307
|
-
|
|
308
|
-
## 快速开始
|
|
309
|
-
|
|
310
|
-
### Docker 一键启动(推荐)
|
|
311
|
-
|
|
312
|
-
无需构建工具或外部数据库。镜像内置 [PGlite](https://pglite.dev)(嵌入式 PostgreSQL):
|
|
313
|
-
|
|
314
|
-
```bash
|
|
315
|
-
git clone https://github.com/Chorus-AIDLC/chorus.git
|
|
316
|
-
cd chorus
|
|
317
|
-
|
|
318
|
-
DEFAULT_USER=admin@example.com DEFAULT_PASSWORD=changeme \
|
|
319
|
-
docker compose -f docker-compose.local.yml up -d
|
|
320
|
-
```
|
|
321
|
-
|
|
322
|
-
访问 [http://localhost:8637](http://localhost:8637),用上面设置的账号登录。
|
|
323
|
-
|
|
324
|
-
> 数据持久化在 Docker 卷中。嵌入模式仅支持单实例(无 Redis)。
|
|
325
|
-
|
|
326
|
-
#### 生产部署(PostgreSQL + Redis)
|
|
327
|
-
|
|
328
|
-
多副本生产环境:
|
|
329
|
-
|
|
330
|
-
```bash
|
|
331
|
-
DEFAULT_USER=admin@example.com DEFAULT_PASSWORD=changeme \
|
|
332
|
-
docker compose up -d
|
|
333
|
-
```
|
|
334
|
-
|
|
335
|
-
> 完整环境变量和配置选项见 [Docker 文档](docs/DOCKER.md)。
|
|
336
|
-
|
|
337
|
-
---
|
|
338
|
-
|
|
339
|
-
### 本地开发
|
|
340
|
-
|
|
341
|
-
前置条件:Node.js 22+、pnpm 9+、Docker(用于 PostgreSQL/Redis)
|
|
342
|
-
|
|
343
|
-
```bash
|
|
344
|
-
cp .env.example .env
|
|
345
|
-
pnpm docker:db
|
|
346
|
-
pnpm install
|
|
347
|
-
pnpm db:migrate:dev
|
|
348
|
-
pnpm dev
|
|
349
|
-
# 访问 http://localhost:8637
|
|
350
|
-
```
|
|
351
|
-
|
|
352
|
-
### 本地开发(无需 Docker)
|
|
353
|
-
|
|
354
|
-
前置条件:Node.js 22+、pnpm 9+
|
|
355
|
-
|
|
356
|
-
```bash
|
|
357
|
-
cp .env.example .env
|
|
358
|
-
pnpm install
|
|
359
|
-
pnpm dev:local # 开发服务器 http://localhost:8637
|
|
360
|
-
```
|
|
361
|
-
|
|
362
|
-
PGlite 在端口 5433 运行嵌入式 PostgreSQL。数据存储在 `.pglite/`,删除即可重置。
|
|
363
|
-
|
|
364
|
-
### 部署到 AWS
|
|
365
|
-
|
|
366
|
-
```bash
|
|
367
|
-
./install.sh
|
|
368
|
-
```
|
|
369
|
-
|
|
370
|
-
交互式安装器自动创建 VPC、Aurora Serverless v2、ElastiCache Serverless、ECS Fargate 和 ALB(HTTPS)。配置保存到 `default_deploy.sh` 供后续重新部署。
|
|
371
|
-
|
|
372
|
-
### 连接 AI Agent
|
|
373
|
-
|
|
374
|
-
最快的方式是用应用内的 setup 向导:打开 Web UI,进入 **Settings → Setup Guide → 打开设置向导**,按照向导给出的分步指引接入自己的客户端(Claude Code、Codex、Kiro、OpenCode、OpenClaw 或其他 agent)。向导会帮你创建 API Key、展示完整命令,并引导你验证连接。
|
|
375
|
-
|
|
376
|
-
如果偏好文档:
|
|
377
|
-
|
|
378
|
-
| 客户端 | 接入文档 |
|
|
379
|
-
|--------|---------|
|
|
380
|
-
| Claude Code | [CONNECT_CLAUDE_CODE.zh.md](docs/CONNECT_CLAUDE_CODE.zh.md) |
|
|
381
|
-
| Codex CLI | [CONNECT_CODEX.zh.md](docs/CONNECT_CODEX.zh.md) |
|
|
382
|
-
| Pi coding agent | [CONNECT_PI.md](docs/CONNECT_PI.md) |
|
|
383
|
-
| Kiro CLI | [CONNECT_KIRO.md](docs/CONNECT_KIRO.md) |
|
|
384
|
-
| OpenCode † | [CONNECT_OPENCODE.zh.md](docs/CONNECT_OPENCODE.zh.md) |
|
|
385
|
-
| 其他 MCP agent(Cursor / Continue / 自研等) | [CONNECT_OTHER_AGENTS.zh.md](docs/CONNECT_OTHER_AGENTS.zh.md) |
|
|
386
|
-
|
|
387
|
-
† OpenCode 的接入由社区维护的 [`opencode-chorus`](https://github.com/etnperlong/opencode-chorus) 插件提供(npm: [`opencode-chorus`](https://www.npmjs.com/package/opencode-chorus)),作者 [@etnperlong](https://github.com/etnperlong),特此感谢!
|
|
388
|
-
|
|
389
|
-
在 Web UI 的 **Settings → Agents → Create API Key** 创建 API Key。Key 以 `cho_` 开头,仅在创建时显示一次。
|
|
390
|
-
|
|
391
|
-

|
|
392
|
-
|
|
393
|
-
---
|
|
394
|
-
|
|
395
|
-
## Skill 文档
|
|
396
|
-
|
|
397
|
-
| 方式 | 位置 | 适用场景 |
|
|
398
|
-
|------|------|---------|
|
|
399
|
-
| **Plugin 内嵌(Claude Code)** | `public/chorus-plugin/skills/` | Claude Code + Chorus 插件,Session 自动化与生命周期 hook |
|
|
400
|
-
| **Plugin 内嵌(Codex CLI)** | `plugins/chorus/skills/` | Codex CLI + Chorus 插件,移植版技能(`$` 前缀斜杠命令)|
|
|
401
|
-
| **Package 内嵌(Pi)** | `packages/chorus-pi/skills/` | Pi + Chorus package,Session 自动化与生命周期 hook |
|
|
402
|
-
| **独立分发** | `public/skill/`(`/skill/` 路径静态托管)| 其他 MCP 客户端(Cursor / Continue / 自研),手动 Session 管理 |
|
|
112
|
+
| 部署 | npm / Docker / AWS CDK |
|
|
403
113
|
|
|
404
114
|
---
|
|
405
115
|
|
|
406
116
|
## 文档
|
|
407
117
|
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
| [Search](docs/SEARCH.md) | 全局搜索技术设计 |
|
|
417
|
-
| [AI-DLC Gap Analysis](docs/AIDLC_GAP_ANALYSIS.md) | AI-DLC 方法论差距分析 |
|
|
418
|
-
| [AIG Implementation Plan](docs/CHORUS_AIG_PLAN.md) | Agent 透明度路线图 |
|
|
419
|
-
| [Presence Design](docs/PRESENCE_DESIGN.md) | 实时 Agent Presence 系统 |
|
|
420
|
-
| [Docker](docs/DOCKER.md) | Docker 镜像使用与部署 |
|
|
421
|
-
| [Logging](docs/LOGGING.md) | 结构化日志架构 |
|
|
422
|
-
| [CLAUDE.md](CLAUDE.md) | 项目开发规范 |
|
|
118
|
+
**📖 完整文档:[doc.chorus-ai.dev](https://doc.chorus-ai.dev/zh/)**
|
|
119
|
+
|
|
120
|
+
- [快速上手](https://doc.chorus-ai.dev/zh/guides/getting-started/)
|
|
121
|
+
- [连接 agent](https://doc.chorus-ai.dev/zh/reference/agents/)
|
|
122
|
+
- [AI-DLC 工作流](https://doc.chorus-ai.dev/zh/guides/ai-dlc-workflow/)
|
|
123
|
+
- [插件与命令](https://doc.chorus-ai.dev/zh/guides/plugin-commands/)
|
|
124
|
+
- [MCP 工具参考](https://doc.chorus-ai.dev/zh/reference/mcp-tools/)
|
|
125
|
+
- [部署与自托管](https://doc.chorus-ai.dev/zh/guides/deployment-overview/)
|
|
423
126
|
|
|
424
127
|
---
|
|
425
128
|
|
package/cli/control-handler.mjs
CHANGED
|
@@ -38,7 +38,8 @@ const NOOP_LOGGER = { info() {}, warn() {}, error() {} };
|
|
|
38
38
|
* (null until the SSE handshake reports it).
|
|
39
39
|
* killer?: (child: any, opts: any) => Promise<any>, Injectable; defaults to killProcessTree.
|
|
40
40
|
* sigintTimeoutMs?: number, Layered-resolved escalation window.
|
|
41
|
-
* redispatchResume?: (entityType: string, entityUuid: string, resumeReason?: string
|
|
41
|
+
* redispatchResume?: (entityType: string, entityUuid: string, resumeReason?: string,
|
|
42
|
+
* runtimeCwd?: string, orchestrator?: object|null) => void,
|
|
42
43
|
* Re-run a wake for a resumed entity (子3); injected
|
|
43
44
|
* by the daemon. `resumeReason` ("user" | "crash",
|
|
44
45
|
* add-crash-execution-resume) is the row's prior
|
|
@@ -180,8 +181,17 @@ export function createControlHandler(deps) {
|
|
|
180
181
|
`)`
|
|
181
182
|
);
|
|
182
183
|
try {
|
|
183
|
-
if (
|
|
184
|
-
|
|
184
|
+
if (
|
|
185
|
+
(typeof event.runtimeCwd === "string" && event.runtimeCwd) ||
|
|
186
|
+
event.orchestrator != null
|
|
187
|
+
) {
|
|
188
|
+
redispatchResume?.(
|
|
189
|
+
entityType,
|
|
190
|
+
entityUuid,
|
|
191
|
+
resumeReason,
|
|
192
|
+
typeof event.runtimeCwd === "string" ? event.runtimeCwd : undefined,
|
|
193
|
+
event.orchestrator ?? null,
|
|
194
|
+
);
|
|
185
195
|
} else {
|
|
186
196
|
redispatchResume?.(entityType, entityUuid, resumeReason);
|
|
187
197
|
}
|
|
@@ -7,7 +7,8 @@
|
|
|
7
7
|
// The five operations and their EXACT server payload shapes (verified against
|
|
8
8
|
// src/app/api/daemon/*/route.ts — the server is NOT changed by this work):
|
|
9
9
|
// turnAdvance → POST /api/daemon/turn-advance
|
|
10
|
-
// { connectionUuid, sessionId, status, entityType?, entityUuid
|
|
10
|
+
// { connectionUuid, sessionId, status, entityType?, entityUuid?,
|
|
11
|
+
// coalescedCount? }
|
|
11
12
|
// transcript → POST /api/daemon/transcript
|
|
12
13
|
// { sessionId, messages: [{ role, text }] }
|
|
13
14
|
// executionState → POST /api/daemon/execution-state
|
|
@@ -70,7 +71,7 @@ const NOOP_LOGGER = { info() {}, warn() {}, error() {} };
|
|
|
70
71
|
* logger?: { info(m:string):void, warn(m:string):void, error(m:string):void },
|
|
71
72
|
* }} opts
|
|
72
73
|
* @returns {{
|
|
73
|
-
* turnAdvance: (p: { sessionId: string, backendSessionId?: string|null, status: string, entityType?: string|null, entityUuid?: string|null }) => Promise<DaemonRestResult>,
|
|
74
|
+
* turnAdvance: (p: { sessionId: string, backendSessionId?: string|null, status: string, entityType?: string|null, entityUuid?: string|null, coalescedCount?: number }) => Promise<DaemonRestResult>,
|
|
74
75
|
* transcript: (p: { sessionId: string, messages: Array<{ role: string, text: string }> }) => Promise<DaemonRestResult>,
|
|
75
76
|
* executionState: (p: { executions: Array<Record<string, unknown>> }) => Promise<DaemonRestResult>,
|
|
76
77
|
* reportInterrupt: (p: { entityType: string, entityUuid: string, reason: string }) => Promise<DaemonRestResult>,
|
|
@@ -147,7 +148,7 @@ export function createDaemonRestClient(opts) {
|
|
|
147
148
|
* the turn's usage. Both ride the terminal edge only. Requires the connectionUuid (the
|
|
148
149
|
* server addresses the turn against a connection the agent owns).
|
|
149
150
|
*/
|
|
150
|
-
async turnAdvance({ sessionId, status, entityType, entityUuid, interruptedReason, transcriptRelayError, usage, backendSessionId }) {
|
|
151
|
+
async turnAdvance({ sessionId, status, entityType, entityUuid, interruptedReason, transcriptRelayError, usage, backendSessionId, coalescedCount }) {
|
|
151
152
|
const connectionUuid = getConnectionUuid();
|
|
152
153
|
if (!connectionUuid) {
|
|
153
154
|
const error = `cannot advance turn for session ${sessionId} → ${status} — no connection uuid yet`;
|
|
@@ -173,6 +174,13 @@ export function createDaemonRestClient(opts) {
|
|
|
173
174
|
// The whole normalized TokenUsage object, nested under `usage`, only on a terminal edge.
|
|
174
175
|
...(usage && isTerminal ? { usage } : {}),
|
|
175
176
|
...(backendSessionId && isTerminal ? { backendSessionId } : {}),
|
|
177
|
+
// Coalesced-wake count (add-daemon-wake-coalescing): meaningful ONLY on the → running
|
|
178
|
+
// edge, where the server settles the next (count − 1) same-session pending turns to
|
|
179
|
+
// `merged`. Sent only when a real batch coalesced (> 1); a single wake (default 1)
|
|
180
|
+
// omits it so the wire — and every existing turn-advance test — stays byte-identical.
|
|
181
|
+
...(status === "running" && typeof coalescedCount === "number" && coalescedCount > 1
|
|
182
|
+
? { coalescedCount }
|
|
183
|
+
: {}),
|
|
176
184
|
};
|
|
177
185
|
return post(
|
|
178
186
|
"turn-advance",
|
package/cli/daemon.mjs
CHANGED
|
@@ -8,6 +8,12 @@
|
|
|
8
8
|
// so a human can `claude --resume <idea-uuid>`); new-vs-resume is decided by
|
|
9
9
|
// probing the on-disk transcript — there is no persisted session-id map.
|
|
10
10
|
//
|
|
11
|
+
// Wake coalescing (add-daemon-wake-coalescing): the WakeQueue is PER-CONNECTION
|
|
12
|
+
// and serializes per DIRECT idea (= per session). Wakes that pile up on the same
|
|
13
|
+
// key while a turn runs are drained together and delivered as ONE batch — a
|
|
14
|
+
// single runBatch → waker.wakeBatch → one `claude --resume` turn — so N
|
|
15
|
+
// same-session queued wakes coalesce into one turn, never N sequential turns.
|
|
16
|
+
//
|
|
11
17
|
// Connection / session / transcript reporting to the server is intentionally
|
|
12
18
|
// NOT done here — the no-op UploadHooks reserve those seams for the derived
|
|
13
19
|
// observability idea.
|
|
@@ -147,10 +153,7 @@ export function buildDaemon(creds, deps = {}) {
|
|
|
147
153
|
// passed through so the Codex backend can export the daemon key into the woken
|
|
148
154
|
// process env (the Claude backend ignores creds — it gets its key via --mcp-config).
|
|
149
155
|
const spawner = deps.spawner ?? selectSpawner(agentType, { logger, permissionMode, creds });
|
|
150
|
-
|
|
151
|
-
// path-connections: serialization-per-idea still holds, and maxConcurrency caps the
|
|
152
|
-
// whole process's in-flight wakes rather than per-cwd — the right global budget.
|
|
153
|
-
const queue = new WakeQueue({ maxConcurrency: deps.maxConcurrency ?? 4, logger });
|
|
156
|
+
const maxConcurrency = deps.maxConcurrency ?? 4;
|
|
154
157
|
|
|
155
158
|
// ===== Multi-path: the SET of cwds this daemon serves (T3 — FR-5) =====
|
|
156
159
|
// Each declared path becomes one INDEPENDENT connection (own SSE self-report + own
|
|
@@ -338,6 +341,11 @@ export function buildDaemon(creds, deps = {}) {
|
|
|
338
341
|
selectWaker(notification).markQueued(notification, key, attribution),
|
|
339
342
|
wake: (notification, key, attribution) =>
|
|
340
343
|
selectWaker(notification).wake(notification, key, attribution),
|
|
344
|
+
// Coalesced batch (add-daemon-wake-coalescing): every item shares the key → the same
|
|
345
|
+
// session → the same cwd (a session's cwd is pinned), so route the whole batch to the
|
|
346
|
+
// waker selected by the first item's runtimeCwd.
|
|
347
|
+
wakeBatch: (notifications, key, attribution) =>
|
|
348
|
+
selectWaker(notifications[0]).wakeBatch(notifications, key, attribution),
|
|
341
349
|
markInterrupting(entityType, entityUuid) {
|
|
342
350
|
for (const candidate of runtimeWakers.values()) {
|
|
343
351
|
if (candidate.executions.has(`${entityType}:${entityUuid}`)) {
|
|
@@ -351,6 +359,19 @@ export function buildDaemon(creds, deps = {}) {
|
|
|
351
359
|
buildExecutionSnapshot: () =>
|
|
352
360
|
[...runtimeWakers.values()].flatMap((candidate) => candidate.buildExecutionSnapshot()),
|
|
353
361
|
};
|
|
362
|
+
// The WakeQueue serializes per DIRECT idea (keyFor's key) and coalesces same-key pending
|
|
363
|
+
// wakes into one batch (add-daemon-wake-coalescing §C1/§C4). It is PER-CONNECTION so the
|
|
364
|
+
// batch runs on THIS connection's own waker facade — the runBatch drains the per-key data
|
|
365
|
+
// items { notification, attribution } and hands the whole batch to waker.wakeBatch (all
|
|
366
|
+
// items on one key share the session anchor, so items[0].attribution is the batch
|
|
367
|
+
// attribution). maxConcurrency caps this connection's in-flight batches.
|
|
368
|
+
const queue = new WakeQueue({
|
|
369
|
+
maxConcurrency,
|
|
370
|
+
logger,
|
|
371
|
+
runBatch: (key, items) =>
|
|
372
|
+
waker.wakeBatch(items.map((i) => i.notification), key, items[0].attribution),
|
|
373
|
+
});
|
|
374
|
+
|
|
354
375
|
// The router reads THIS connection's own uuid lazily (same source the control handler
|
|
355
376
|
// uses) to suppress a DIRECTED (pinned) wake stamped for a different connection
|
|
356
377
|
// (fix-pinned-wake-directed-delivery, T2). Null until the SSE handshake assigns it — a
|
|
@@ -370,8 +391,20 @@ export function buildDaemon(creds, deps = {}) {
|
|
|
370
391
|
// all scoped to THIS connection's uuid/router/backfill (see the original wiring
|
|
371
392
|
// comments retained on the shared helpers). The control handler verifies a control
|
|
372
393
|
// event against this connection's own connectionUuid before acting.
|
|
373
|
-
const redispatchResume = (
|
|
374
|
-
|
|
394
|
+
const redispatchResume = (
|
|
395
|
+
entityType,
|
|
396
|
+
entityUuid,
|
|
397
|
+
resumeReason,
|
|
398
|
+
runtimeCwd,
|
|
399
|
+
orchestrator,
|
|
400
|
+
) => {
|
|
401
|
+
router.dispatchResume?.({
|
|
402
|
+
entityType,
|
|
403
|
+
entityUuid,
|
|
404
|
+
resumeReason,
|
|
405
|
+
runtimeCwd,
|
|
406
|
+
orchestrator,
|
|
407
|
+
});
|
|
375
408
|
};
|
|
376
409
|
const deliverTurn = (turnUuid) => backfill?.pendingTurnsOnly?.(turnUuid);
|
|
377
410
|
const onControl = createControlHandler({
|
|
@@ -483,6 +516,7 @@ export function buildDaemon(creds, deps = {}) {
|
|
|
483
516
|
connectionState,
|
|
484
517
|
waker,
|
|
485
518
|
runtimeWakers,
|
|
519
|
+
queue,
|
|
486
520
|
router,
|
|
487
521
|
backfill,
|
|
488
522
|
sseListener,
|
|
@@ -501,9 +535,11 @@ export function buildDaemon(creds, deps = {}) {
|
|
|
501
535
|
mcpClient,
|
|
502
536
|
lineage,
|
|
503
537
|
spawner,
|
|
504
|
-
queue,
|
|
505
538
|
// Back-compat single-connection aliases (the common single-path case). The full
|
|
506
|
-
// set is exposed as `connections` for multi-path inspection/tests.
|
|
539
|
+
// set is exposed as `connections` for multi-path inspection/tests. The WakeQueue is
|
|
540
|
+
// now per-connection (add-daemon-wake-coalescing) so its runBatch can run on the right
|
|
541
|
+
// connection's waker facade; the primary connection's queue is aliased here.
|
|
542
|
+
queue: primary.queue,
|
|
507
543
|
waker: primary.waker,
|
|
508
544
|
router: primary.router,
|
|
509
545
|
sseListener: primary.sseListener,
|
|
@@ -526,8 +562,10 @@ export function buildDaemon(creds, deps = {}) {
|
|
|
526
562
|
// and latch the queue (queued-but-unstarted wakes never spawn).
|
|
527
563
|
for (const c of connections) {
|
|
528
564
|
c.sseListener.disconnect?.();
|
|
565
|
+
// Latch each connection's OWN queue (queues are per-connection now — add-daemon-
|
|
566
|
+
// wake-coalescing) so queued-but-unstarted wakes never spawn.
|
|
567
|
+
c.queue?.stop?.();
|
|
529
568
|
}
|
|
530
|
-
queue.stop();
|
|
531
569
|
// 2. Interrupt every in-flight wake subprocess via the shared kill escalation.
|
|
532
570
|
// Each wake's exit path — seeing shuttingDown — reports its turn
|
|
533
571
|
// interrupted(shutdown) and suppresses the execution crash report.
|
|
@@ -538,7 +576,11 @@ export function buildDaemon(creds, deps = {}) {
|
|
|
538
576
|
// the kill escalation window plus a hard 5s cap for the exit path's REST
|
|
539
577
|
// reports. A wake that outlives this does NOT hang the shutdown — its
|
|
540
578
|
// orphaned turn is the server-side offline reconcile's job (the backstop).
|
|
541
|
-
|
|
579
|
+
// Drain every connection's queue in parallel; `drained` is true only if all did.
|
|
580
|
+
const drainResults = await Promise.all(
|
|
581
|
+
connections.map((c) => c.queue?.drain?.(sigintTimeoutMs + 5_000) ?? true),
|
|
582
|
+
);
|
|
583
|
+
const drained = drainResults.every(Boolean);
|
|
542
584
|
if (!drained) {
|
|
543
585
|
logger.warn(
|
|
544
586
|
"[Chorus] shutdown: in-flight wake(s) did not finish within the bound — exiting anyway (server reconcile will finalize their turns)",
|