@chorus-aidlc/chorus 0.13.0 → 0.13.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 +410 -425
- package/.next/standalone/.next/app-path-routes-manifest.json +39 -41
- package/.next/standalone/.next/build-manifest.json +5 -5
- package/.next/standalone/.next/prerender-manifest.json +33 -57
- package/.next/standalone/.next/routes-manifest.json +0 -6
- 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 +2 -2
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/activity/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/activity/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/dashboard/[ideaUuid]/page.js +2 -2
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/dashboard/[ideaUuid]/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/dashboard/[ideaUuid]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/dashboard/page.js +2 -2
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/dashboard/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/dashboard/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/documents/[documentUuid]/page.js +2 -2
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/documents/[documentUuid]/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/documents/[documentUuid]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/documents/page.js +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 +2 -2
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/graph/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/graph/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/[proposalUuid]/page.js +2 -2
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/[proposalUuid]/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/[proposalUuid]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/new/page.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/new/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/new/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/page.js +2 -2
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/page.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 +1 -1
- 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 +1 -1
- 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 +1 -1
- 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 +1 -1
- 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 +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.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.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.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/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/execution-state/route.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon/execution-state/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/daemon/execution-state/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon/executions/route.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon/executions/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/daemon/executions/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon/pending-turns/route.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon/pending-turns/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/daemon/pending-turns/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon/report-interrupt/route.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon/report-interrupt/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/daemon/report-interrupt/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon/resume/route.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon/resume/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/daemon/resume/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon/transcript/route.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon/transcript/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/daemon/transcript/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon/turn-advance/route.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon/turn-advance/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/daemon/turn-advance/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon-sessions/[sessionUuid]/instruction/route.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon-sessions/[sessionUuid]/instruction/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/daemon-sessions/[sessionUuid]/instruction/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon-sessions/[sessionUuid]/repoint/route.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon-sessions/[sessionUuid]/repoint/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/daemon-sessions/[sessionUuid]/repoint/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon-sessions/[sessionUuid]/route.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon-sessions/[sessionUuid]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/daemon-sessions/[sessionUuid]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon-sessions/ad-hoc/route.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon-sessions/ad-hoc/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/daemon-sessions/ad-hoc/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon-sessions/route.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon-sessions/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/daemon-sessions/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/documents/[uuid]/route.js +1 -1
- package/.next/standalone/.next/server/app/api/documents/[uuid]/route.js.nft.json +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 +4 -4
- 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 +6 -6
- 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/conversational/route.js +1 -0
- package/.next/standalone/.next/server/app/api/{auth/refresh → ideas/conversational}/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/ideas/conversational/route_client-reference-manifest.js +1 -0
- 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.js +1 -1
- package/.next/standalone/.next/server/app/api/project-groups/[uuid]/dashboard/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/project-groups/[uuid]/dashboard/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/project-groups/[uuid]/route.js +1 -1
- package/.next/standalone/.next/server/app/api/project-groups/[uuid]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/project-groups/[uuid]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/project-groups/route.js +1 -1
- package/.next/standalone/.next/server/app/api/project-groups/route.js.nft.json +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/projects/[uuid]/activity/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/available/route.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/available/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/available/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/documents/route.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/documents/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/documents/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/group/route.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/group/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/group/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/ideas/route.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/ideas/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/ideas/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/ideas/tracker/route.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/ideas/tracker/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/ideas/tracker/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/proposals/[proposalUuid]/validate/route.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/proposals/[proposalUuid]/validate/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/proposals/[proposalUuid]/validate/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/proposals/route.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/proposals/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/proposals/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/proposals/summary/route.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/proposals/summary/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/proposals/summary/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/resource-graph/route.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/resource-graph/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/resource-graph/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/route.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/stats/route.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/stats/route.js.nft.json +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/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/proposals/[uuid]/approve/route.js +1 -1
- package/.next/standalone/.next/server/app/api/proposals/[uuid]/approve/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/proposals/[uuid]/approve/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/proposals/[uuid]/close/route.js +1 -1
- package/.next/standalone/.next/server/app/api/proposals/[uuid]/close/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/proposals/[uuid]/close/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/proposals/[uuid]/reject/route.js +1 -1
- package/.next/standalone/.next/server/app/api/proposals/[uuid]/reject/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/proposals/[uuid]/reject/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/proposals/[uuid]/revoke/route.js +1 -1
- package/.next/standalone/.next/server/app/api/proposals/[uuid]/revoke/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/proposals/[uuid]/revoke/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/proposals/[uuid]/route.js +1 -1
- package/.next/standalone/.next/server/app/api/proposals/[uuid]/route.js.nft.json +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/search/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/session/route.js +1 -0
- package/.next/standalone/.next/server/app/api/session/route.js.nft.json +1 -0
- package/.next/standalone/.next/server/app/api/session/route_client-reference-manifest.js +1 -0
- 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 +1 -1
- package/.next/standalone/.next/server/app/index.rsc +3 -3
- package/.next/standalone/.next/server/app/login/admin/page.js +2 -2
- package/.next/standalone/.next/server/app/login/admin/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/login/admin/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/login/admin.html +1 -1
- package/.next/standalone/.next/server/app/login/admin.rsc +2 -2
- package/.next/standalone/.next/server/app/login/callback/page.js +2 -2
- package/.next/standalone/.next/server/app/login/callback/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/login/callback/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/login/callback.html +1 -1
- package/.next/standalone/.next/server/app/login/callback.rsc +3 -3
- package/.next/standalone/.next/server/app/login/page.js +2 -2
- package/.next/standalone/.next/server/app/login/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/login/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/login/pick-workspace/page.js +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 +1 -1
- package/.next/standalone/.next/server/app/login/pick-workspace.rsc +3 -3
- package/.next/standalone/.next/server/app/login.html +1 -1
- package/.next/standalone/.next/server/app/login.rsc +3 -3
- 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 +1 -1
- package/.next/standalone/.next/server/app/onboarding.rsc +3 -3
- package/.next/standalone/.next/server/app/page.js +2 -2
- package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/projects.html +1 -1
- package/.next/standalone/.next/server/app/projects.rsc +4 -4
- package/.next/standalone/.next/server/app/settings.html +1 -1
- package/.next/standalone/.next/server/app/settings.rsc +4 -4
- package/.next/standalone/.next/server/app-paths-manifest.json +39 -41
- package/.next/standalone/.next/server/chunks/1114.js +1 -0
- package/.next/standalone/.next/server/chunks/1559.js +2 -2
- package/.next/standalone/.next/server/chunks/{7258.js → 2516.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/3219.js +1 -1
- package/.next/standalone/.next/server/chunks/3371.js +1 -0
- package/.next/standalone/.next/server/chunks/3373.js +1 -1
- package/.next/standalone/.next/server/chunks/3419.js +1 -1
- package/.next/standalone/.next/server/chunks/4827.js +1 -0
- package/.next/standalone/.next/server/chunks/4958.js +1 -0
- package/.next/standalone/.next/server/chunks/{9855.js → 5095.js} +2 -2
- package/.next/standalone/.next/server/chunks/5300.js +1 -1
- package/.next/standalone/.next/server/chunks/6113.js +1 -1
- package/.next/standalone/.next/server/chunks/6207.js +1 -1
- package/.next/standalone/.next/server/chunks/6496.js +1 -0
- package/.next/standalone/.next/server/chunks/679.js +1 -1
- package/.next/standalone/.next/server/chunks/6817.js +1 -0
- package/.next/standalone/.next/server/chunks/{178.js → 704.js} +3 -3
- package/.next/standalone/.next/server/chunks/7160.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/8448.js +1 -0
- package/.next/standalone/.next/server/chunks/{8267.js → 8481.js} +1 -1
- package/.next/standalone/.next/server/chunks/8497.js +1 -0
- package/.next/standalone/.next/server/chunks/8577.js +153 -0
- package/.next/standalone/.next/server/chunks/8895.js +1 -0
- package/.next/standalone/.next/server/chunks/920.js +1 -1
- package/.next/standalone/.next/server/chunks/9726.js +1 -0
- 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 +1 -1
- package/.next/standalone/.next/server/pages/500.html +1 -1
- package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/src/middleware.js +5 -5
- package/.next/standalone/.next/static/chunks/15653-31c406c41bf58048.js +1 -0
- package/.next/standalone/.next/static/chunks/1892-9c03d4d3560ff572.js +1 -0
- package/.next/standalone/.next/static/chunks/225-8a41a800021f3d11.js +1 -0
- package/.next/standalone/.next/static/chunks/24459-3bc9657d71c77b47.js +1 -0
- package/.next/standalone/.next/static/chunks/38296-316ba18af72385fb.js +1 -0
- package/.next/standalone/.next/static/chunks/46055-f786ace4b994dc40.js +1 -0
- package/.next/standalone/.next/static/chunks/{4860.c3c83713d1f163a5.js → 4860.7844c573cb3914f3.js} +1 -1
- package/.next/standalone/.next/static/chunks/{49965-fa11628d5ac8fbbe.js → 52064-74d81c8d682deb6b.js} +1 -1
- package/.next/standalone/.next/static/chunks/57362-9ece5cc290dab705.js +1 -0
- package/.next/standalone/.next/static/chunks/{14655-4f3bc7f3044c42c1.js → 58037-55d7422c6b808356.js} +1 -1
- package/.next/standalone/.next/static/chunks/58262-395c00e04f610a32.js +1 -0
- package/.next/standalone/.next/static/chunks/68255-05c42a26602c6b37.js +1 -0
- package/.next/standalone/.next/static/chunks/75752-cc8fafe132943baa.js +1 -0
- package/.next/standalone/.next/static/chunks/80350-8ac8d602965bb4df.js +1 -0
- package/.next/standalone/.next/static/chunks/84169-71a87d06871ec9df.js +1 -0
- package/.next/standalone/.next/static/chunks/94528-ed3f03485480f5e5.js +1 -0
- package/.next/standalone/.next/static/chunks/94743-aff8a51a7f7970a9.js +1 -0
- package/.next/standalone/.next/static/chunks/{36493-5326c14a7240edc8.js → 97306-8834e12cdbeed920.js} +1 -1
- package/.next/standalone/.next/static/chunks/{99373.2b68fce200cc323e.js → 99373.6f0ec031fb759d88.js} +1 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/layout-a3747bde1ddaba52.js +1 -0
- package/.next/standalone/.next/static/chunks/app/(dashboard)/project-groups/[uuid]/page-87b79c98e46fbd04.js +1 -0
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/dashboard/[ideaUuid]/page-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/dashboard/page-f72f17eb58614d2b.js +1 -0
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/documents/[documentUuid]/page-0467d744b84aa2c2.js +1 -0
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/documents/{page-7ebb779f0db4c58b.js → page-7abff55f9bfebab3.js} +1 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/graph/page-3238e0b5474c60f6.js +1 -0
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/[proposalUuid]/page-9f0ebba7e855b2f9.js +1 -0
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/new/page-6dbfbe5d97855e42.js +1 -0
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/page-b8fbcac7224342db.js +1 -0
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/tasks/[taskUuid]/page-0a04a31e1b383094.js +1 -0
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/tasks/page-e2a69b645ec9ae13.js +1 -0
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/{page-0bc22273214e522f.js → page-b760877bfcd12dff.js} +1 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/settings/page-111aed4d3319d64b.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/admin/companies/[uuid]/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/admin/companies/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/admin/login/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/admin/session/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/agent-connections/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/agents/[uuid]/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/agents/[uuid]/sessions/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/agents/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/api-keys/[uuid]/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/api-keys/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/auth/callback/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/auth/check-default/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/auth/company-oidc/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/auth/default-login/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/auth/identify/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/auth/logout/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/auth/me/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/auth/sync-token/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/comments/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/daemon/control/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/daemon/execution-state/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/daemon/executions/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/daemon/pending-turns/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/daemon/report-interrupt/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/daemon/resume/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/daemon/transcript/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/daemon/turn-advance/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/daemon-sessions/[sessionUuid]/instruction/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/daemon-sessions/[sessionUuid]/repoint/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/daemon-sessions/[sessionUuid]/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/daemon-sessions/ad-hoc/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/daemon-sessions/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/documents/[uuid]/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/entities/[type]/[uuid]/root-idea/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/events/notifications/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/events/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/health/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/ideas/[uuid]/claim/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/ideas/[uuid]/move/preview/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/ideas/[uuid]/move/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/ideas/[uuid]/parent/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/ideas/[uuid]/release/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/ideas/[uuid]/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/ideas/conversational/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/mcp/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/me/assignments/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/mentionables/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/notifications/[uuid]/archive/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/notifications/[uuid]/read/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/notifications/preferences/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/notifications/read-all/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/notifications/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/notifications/unread-count/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/project-groups/[uuid]/dashboard/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/project-groups/[uuid]/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/project-groups/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/projects/[uuid]/activity/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/projects/[uuid]/available/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/projects/[uuid]/documents/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/projects/[uuid]/group/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/projects/[uuid]/ideas/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/projects/[uuid]/ideas/tracker/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/projects/[uuid]/proposals/[proposalUuid]/validate/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/projects/[uuid]/proposals/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/projects/[uuid]/proposals/summary/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/projects/[uuid]/resource-graph/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/projects/[uuid]/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/projects/[uuid]/stats/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/projects/[uuid]/tasks/dependencies/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/projects/[uuid]/tasks/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/projects/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/proposals/[uuid]/approve/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/proposals/[uuid]/close/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/proposals/[uuid]/reject/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/proposals/[uuid]/revoke/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/proposals/[uuid]/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/search/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/session/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/sessions/[uuid]/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/tasks/[uuid]/claim/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/tasks/[uuid]/dependencies/[dependsOnUuid]/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/tasks/[uuid]/dependencies/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/tasks/[uuid]/release/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/tasks/[uuid]/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/tasks/[uuid]/sessions/route-47e1d397c5fcef9e.js +1 -0
- package/.next/standalone/.next/static/chunks/app/login/callback/page-39a43f6d0245f8ca.js +1 -0
- package/.next/standalone/.next/static/chunks/app/login/page-acda3a31dc6a8280.js +1 -0
- package/.next/standalone/.next/static/chunks/app/login/pick-workspace/page-10683852baf17426.js +1 -0
- package/.next/standalone/.next/static/chunks/app/onboarding/{page-500aded75bf11ed6.js → page-8e20c8aa8ff90326.js} +1 -1
- package/.next/standalone/.next/static/chunks/app/page-000b1349c8d5b652.js +1 -0
- package/.next/standalone/.next/static/chunks/{webpack-7483083a976ed3d7.js → webpack-fe12dfe2e0d0e4f3.js} +1 -1
- package/.next/standalone/.next/static/css/3f3ae2bdc9e55259.css +1 -0
- package/.next/standalone/.next/static/eORNzMShbzkJbNfQT8MbW/_buildManifest.js +1 -0
- package/.next/standalone/package.json +1 -1
- package/.next/standalone/public/chorus-plugin/skills/develop/SKILL.md +2 -0
- package/.next/standalone/public/chorus-plugin/skills/idea/SKILL.md +2 -0
- package/.next/standalone/public/skill/develop-chorus/SKILL.md +2 -0
- package/.next/standalone/public/skill/idea-chorus/SKILL.md +2 -0
- package/README.md +15 -2
- package/README.zh.md +15 -2
- package/cli/client-args.mjs +31 -9
- package/cli/control-handler.mjs +22 -5
- package/cli/daemon-lifecycle.mjs +192 -25
- package/cli/daemon-rest-client.mjs +6 -2
- package/cli/daemon-service.mjs +422 -0
- package/cli/daemon.mjs +181 -13
- package/cli/event-router.mjs +29 -10
- package/cli/prompts.mjs +61 -0
- package/cli/turn-reporter.mjs +26 -5
- package/cli/wake-queue.mjs +30 -0
- package/cli/waker.mjs +91 -22
- package/package.json +1 -1
- package/prisma/migrations/20260704023331_add_turn_interrupted_state/migration.sql +2 -0
- package/prisma/schema.prisma +9 -2
- package/.next/standalone/.next/server/app/api/auth/refresh/route.js +0 -1
- package/.next/standalone/.next/server/app/api/auth/refresh/route_client-reference-manifest.js +0 -1
- package/.next/standalone/.next/server/app/api/auth/session/route.js +0 -1
- package/.next/standalone/.next/server/app/api/auth/session/route.js.nft.json +0 -1
- package/.next/standalone/.next/server/app/api/auth/session/route_client-reference-manifest.js +0 -1
- package/.next/standalone/.next/server/app/api/keepalive/route.js +0 -1
- package/.next/standalone/.next/server/app/api/keepalive/route.js.nft.json +0 -1
- package/.next/standalone/.next/server/app/api/keepalive/route_client-reference-manifest.js +0 -1
- package/.next/standalone/.next/server/app/login/silent-refresh/page.js +0 -2
- package/.next/standalone/.next/server/app/login/silent-refresh/page.js.nft.json +0 -1
- package/.next/standalone/.next/server/app/login/silent-refresh/page_client-reference-manifest.js +0 -1
- package/.next/standalone/.next/server/app/login/silent-refresh.html +0 -1
- package/.next/standalone/.next/server/app/login/silent-refresh.meta +0 -7
- package/.next/standalone/.next/server/app/login/silent-refresh.rsc +0 -24
- package/.next/standalone/.next/server/chunks/1463.js +0 -1
- package/.next/standalone/.next/server/chunks/298.js +0 -1
- package/.next/standalone/.next/server/chunks/5011.js +0 -1
- package/.next/standalone/.next/server/chunks/6813.js +0 -1
- package/.next/standalone/.next/server/chunks/7421.js +0 -1
- package/.next/standalone/.next/server/chunks/7515.js +0 -1
- package/.next/standalone/.next/server/chunks/7912.js +0 -1
- package/.next/standalone/.next/server/chunks/8821.js +0 -1
- package/.next/standalone/.next/server/chunks/9273.js +0 -1
- package/.next/standalone/.next/server/chunks/937.js +0 -153
- package/.next/standalone/.next/static/W3KEB0tOAICVtfAUfR_M9/_buildManifest.js +0 -1
- package/.next/standalone/.next/static/chunks/10919-7f63b2801a92b8c6.js +0 -1
- package/.next/standalone/.next/static/chunks/1891-d4a9e756fefba3a9.js +0 -1
- package/.next/standalone/.next/static/chunks/20081-a2bf5c9f24d5d589.js +0 -1
- package/.next/standalone/.next/static/chunks/26394-4af487a51dd62832.js +0 -1
- package/.next/standalone/.next/static/chunks/2987-c15f09093b821b24.js +0 -1
- package/.next/standalone/.next/static/chunks/37784-95dee37276b1067b.js +0 -1
- package/.next/standalone/.next/static/chunks/43741-aeea04ab873ac4e9.js +0 -1
- package/.next/standalone/.next/static/chunks/49852-5337f139a2f87c46.js +0 -1
- package/.next/standalone/.next/static/chunks/56812-a6fe5225adc0b2ff.js +0 -1
- package/.next/standalone/.next/static/chunks/64894-71b047ae8ef2f3d8.js +0 -1
- package/.next/standalone/.next/static/chunks/8796-69e708cb8603d8b4.js +0 -1
- package/.next/standalone/.next/static/chunks/91666-3fd4f3512a53ff20.js +0 -1
- package/.next/standalone/.next/static/chunks/97263-018d631416efa5cd.js +0 -1
- package/.next/standalone/.next/static/chunks/97868-55f18a05fe483d85.js +0 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/layout-6061b60d52262d3c.js +0 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/project-groups/[uuid]/page-78ab05c72bcd04fd.js +0 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/dashboard/[ideaUuid]/page-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/dashboard/page-478cce81afbfc145.js +0 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/documents/[documentUuid]/page-494b80e61b485870.js +0 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/graph/page-bfbfc5005de2be13.js +0 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/[proposalUuid]/page-fbb4dd4124525f97.js +0 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/new/page-164fe175720b24a1.js +0 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/page-2742c745a90f843f.js +0 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/tasks/[taskUuid]/page-f2313bf05387b39b.js +0 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/tasks/page-955e8fd8d7b0b7c8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/settings/page-960ab78b5055780c.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/admin/companies/[uuid]/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/admin/companies/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/admin/login/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/admin/session/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/agent-connections/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/agents/[uuid]/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/agents/[uuid]/sessions/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/agents/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/api-keys/[uuid]/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/api-keys/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/auth/callback/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/auth/check-default/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/auth/company-oidc/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/auth/default-login/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/auth/identify/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/auth/logout/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/auth/me/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/auth/refresh/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/auth/session/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/auth/sync-token/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/comments/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/daemon/control/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/daemon/execution-state/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/daemon/executions/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/daemon/pending-turns/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/daemon/report-interrupt/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/daemon/resume/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/daemon/transcript/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/daemon/turn-advance/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/daemon-sessions/[sessionUuid]/instruction/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/daemon-sessions/[sessionUuid]/repoint/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/daemon-sessions/[sessionUuid]/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/daemon-sessions/ad-hoc/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/daemon-sessions/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/documents/[uuid]/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/entities/[type]/[uuid]/root-idea/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/events/notifications/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/events/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/health/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/ideas/[uuid]/claim/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/ideas/[uuid]/move/preview/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/ideas/[uuid]/move/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/ideas/[uuid]/parent/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/ideas/[uuid]/release/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/ideas/[uuid]/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/keepalive/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/mcp/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/me/assignments/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/mentionables/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/notifications/[uuid]/archive/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/notifications/[uuid]/read/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/notifications/preferences/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/notifications/read-all/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/notifications/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/notifications/unread-count/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/project-groups/[uuid]/dashboard/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/project-groups/[uuid]/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/project-groups/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/projects/[uuid]/activity/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/projects/[uuid]/available/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/projects/[uuid]/documents/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/projects/[uuid]/group/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/projects/[uuid]/ideas/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/projects/[uuid]/ideas/tracker/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/projects/[uuid]/proposals/[proposalUuid]/validate/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/projects/[uuid]/proposals/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/projects/[uuid]/proposals/summary/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/projects/[uuid]/resource-graph/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/projects/[uuid]/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/projects/[uuid]/stats/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/projects/[uuid]/tasks/dependencies/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/projects/[uuid]/tasks/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/projects/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/proposals/[uuid]/approve/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/proposals/[uuid]/close/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/proposals/[uuid]/reject/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/proposals/[uuid]/revoke/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/proposals/[uuid]/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/search/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/sessions/[uuid]/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/tasks/[uuid]/claim/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/tasks/[uuid]/dependencies/[dependsOnUuid]/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/tasks/[uuid]/dependencies/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/tasks/[uuid]/release/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/tasks/[uuid]/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/tasks/[uuid]/sessions/route-31ae6abada6e6a64.js +0 -1
- package/.next/standalone/.next/static/chunks/app/login/callback/page-6cad93f5c610b047.js +0 -1
- package/.next/standalone/.next/static/chunks/app/login/page-d2513f477211dd6f.js +0 -1
- package/.next/standalone/.next/static/chunks/app/login/pick-workspace/page-597e0f3377f18d29.js +0 -1
- package/.next/standalone/.next/static/chunks/app/login/silent-refresh/page-a26d1af61578c96e.js +0 -1
- package/.next/standalone/.next/static/chunks/app/page-075afd218994d377.js +0 -1
- package/.next/standalone/.next/static/css/ed6baccd62b81c4e.css +0 -1
- /package/.next/standalone/.next/static/{W3KEB0tOAICVtfAUfR_M9 → eORNzMShbzkJbNfQT8MbW}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,422 @@
|
|
|
1
|
+
// cli/daemon-service.mjs
|
|
2
|
+
// `chorus daemon install` / `uninstall` — generate and install a CORRECT
|
|
3
|
+
// supervisor unit for the long-lived daemon, and detect one so the lifecycle
|
|
4
|
+
// subcommands (status/stop/restart/logs) can transparently delegate to it.
|
|
5
|
+
//
|
|
6
|
+
// WHY THIS EXISTS (root fix for the boot restart storm, idea e55ae33a follow-up):
|
|
7
|
+
// operators hand-wrote a systemd unit as `Type=forking` + `ExecStart=… -d`.
|
|
8
|
+
// `chorus daemon -d` SELF-daemonizes (detached + unref child + a JSON pidfile
|
|
9
|
+
// systemd cannot parse), so systemd never adopts the forked child as MainPID,
|
|
10
|
+
// treats the service as failed, and `Restart=on-failure` retries every few
|
|
11
|
+
// seconds — each retry's `-d` preflight then finds the previous orphan alive
|
|
12
|
+
// via the pidfile and refuses ("a daemon is already running"), an infinite
|
|
13
|
+
// loop that also pins the server-side connection rows ("all declared paths
|
|
14
|
+
// already served"). The correct model is a FOREGROUND `Type=simple` service:
|
|
15
|
+
// systemd owns the process directly, `systemctl stop` delivers SIGTERM to the
|
|
16
|
+
// daemon's existing graceful-shutdown handler, no pidfile is involved, and
|
|
17
|
+
// there is nothing to double-start.
|
|
18
|
+
//
|
|
19
|
+
// Design (add-daemon-install-supervisor):
|
|
20
|
+
// - Linux: fully generate + install a `systemd --user` unit, daemon-reload,
|
|
21
|
+
// enable --now.
|
|
22
|
+
// - macOS (launchd) / Windows: PRINT a correct template + manual steps and
|
|
23
|
+
// exit 0 without writing (no auto-install off Linux — YAGNI + no native
|
|
24
|
+
// deps / platform service-manager coupling).
|
|
25
|
+
// - Rendering is PURE (no IO) so the correctness-critical unit text is unit
|
|
26
|
+
// testable; install / detect / delegate are thin injected-IO shells,
|
|
27
|
+
// mirroring the seam in daemon-lifecycle.mjs (all IO overridable per call).
|
|
28
|
+
|
|
29
|
+
import { spawnSync } from "node:child_process";
|
|
30
|
+
import { existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from "node:fs";
|
|
31
|
+
import { homedir } from "node:os";
|
|
32
|
+
import { dirname, join } from "node:path";
|
|
33
|
+
import { fileURLToPath } from "node:url";
|
|
34
|
+
|
|
35
|
+
/** The systemd --user unit name (also the launchd label stem). */
|
|
36
|
+
export const SERVICE_NAME = "chorus-daemon";
|
|
37
|
+
|
|
38
|
+
/** Default IO bundle — overridable per-call for tests (no real disk/process). */
|
|
39
|
+
function defaultIO() {
|
|
40
|
+
return {
|
|
41
|
+
existsSync,
|
|
42
|
+
mkdirSync,
|
|
43
|
+
readFileSync,
|
|
44
|
+
unlinkSync,
|
|
45
|
+
writeFileSync,
|
|
46
|
+
spawnSync,
|
|
47
|
+
platform: process.platform,
|
|
48
|
+
home: homedir(),
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** ~/.config/systemd/user/chorus-daemon.service */
|
|
53
|
+
export function systemdUnitPath(io = defaultIO()) {
|
|
54
|
+
return join(io.home ?? homedir(), ".config", "systemd", "user", `${SERVICE_NAME}.service`);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** ~/Library/LaunchAgents/com.chorus.daemon.plist */
|
|
58
|
+
export function launchdPlistPath(io = defaultIO()) {
|
|
59
|
+
return join(io.home ?? homedir(), "Library", "LaunchAgents", "com.chorus.daemon.plist");
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Resolve the absolute path to this CLI's `chorus.mjs` entrypoint (one level up
|
|
64
|
+
* from cli/). Absolute so the generated unit does not depend on the operator's
|
|
65
|
+
* cwd or PATH at boot.
|
|
66
|
+
*/
|
|
67
|
+
export function resolveScriptPath() {
|
|
68
|
+
return join(dirname(dirname(fileURLToPath(import.meta.url))), "chorus.mjs");
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Build the argv the SUPERVISED daemon runs — the normal long-lived daemon
|
|
73
|
+
* (NO `-d`: the supervisor owns the foreground process). Reflects the flags the
|
|
74
|
+
* operator passed to `install` so the boot-time daemon serves the same paths /
|
|
75
|
+
* agent / permission posture. Pure.
|
|
76
|
+
* @param {{ cwds?: string[], agent?: string, chorusOnly?: boolean, scriptPath: string }} spec
|
|
77
|
+
* @returns {string[]} e.g. ["/x/chorus.mjs","daemon","--cwd","/a","--cwd","/b"]
|
|
78
|
+
*/
|
|
79
|
+
export function buildServiceArgs(spec) {
|
|
80
|
+
const args = [spec.scriptPath, "daemon"];
|
|
81
|
+
for (const cwd of spec.cwds ?? []) {
|
|
82
|
+
if (typeof cwd === "string" && cwd) args.push("--cwd", cwd);
|
|
83
|
+
}
|
|
84
|
+
if (spec.agent) args.push("--agent", spec.agent);
|
|
85
|
+
if (spec.chorusOnly) args.push("--chorus-only");
|
|
86
|
+
return args;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Render a `systemd --user` unit for the FOREGROUND daemon. Pure.
|
|
91
|
+
*
|
|
92
|
+
* Key correctness properties (the whole point of this module):
|
|
93
|
+
* - Type=simple + ExecStart WITHOUT `-d` → systemd owns the node process as
|
|
94
|
+
* MainPID; no self-fork, no pidfile.
|
|
95
|
+
* - NO ExecStop → default stop is SIGTERM to the unit cgroup, which the
|
|
96
|
+
* daemon already handles gracefully. A pidfile-based `ExecStop=chorus
|
|
97
|
+
* daemon stop` would be a no-op here (foreground writes no pidfile).
|
|
98
|
+
* - TimeoutStopSec gives graceful shutdown room before SIGKILL.
|
|
99
|
+
* - PATH is captured so `node`/`claude`/`codex` resolve at boot the same way
|
|
100
|
+
* they did in the operator's shell.
|
|
101
|
+
*
|
|
102
|
+
* @param {{
|
|
103
|
+
* nodePath: string, scriptPath: string, cwds?: string[], agent?: string,
|
|
104
|
+
* chorusOnly?: boolean, workingDir: string, home: string, path: string,
|
|
105
|
+
* restartSec?: number, timeoutStopSec?: number,
|
|
106
|
+
* }} spec
|
|
107
|
+
* @returns {string}
|
|
108
|
+
*/
|
|
109
|
+
export function renderSystemdUnit(spec) {
|
|
110
|
+
const args = buildServiceArgs({
|
|
111
|
+
cwds: spec.cwds,
|
|
112
|
+
agent: spec.agent,
|
|
113
|
+
chorusOnly: spec.chorusOnly,
|
|
114
|
+
scriptPath: spec.scriptPath,
|
|
115
|
+
});
|
|
116
|
+
// systemd's ExecStart tokenizer splits on UNQUOTED whitespace, so a token
|
|
117
|
+
// with a space (an operator's `--cwd "/home/u/My Projects/repo"`, or a node/
|
|
118
|
+
// script path under such a dir) would be mis-split and the daemon would serve
|
|
119
|
+
// the wrong path silently. Quote every token so spaces survive.
|
|
120
|
+
const execStart = [spec.nodePath, ...args].map(systemdQuoteArg).join(" ");
|
|
121
|
+
const restartSec = spec.restartSec ?? 10;
|
|
122
|
+
const timeoutStopSec = spec.timeoutStopSec ?? 30;
|
|
123
|
+
return `[Unit]
|
|
124
|
+
Description=Chorus Daemon (multi-cwd)
|
|
125
|
+
After=network-online.target
|
|
126
|
+
Wants=network-online.target
|
|
127
|
+
|
|
128
|
+
[Service]
|
|
129
|
+
# Type=simple: the daemon runs in the FOREGROUND (no -d). systemd owns this
|
|
130
|
+
# process directly as MainPID, so 'systemctl stop' delivers SIGTERM straight to
|
|
131
|
+
# the daemon's graceful-shutdown handler — no self-forked orphan, no pidfile
|
|
132
|
+
# race, no restart storm. Do NOT add -d here: -d self-daemonizes and writes a
|
|
133
|
+
# JSON pidfile systemd cannot parse (that was the boot-loop root cause).
|
|
134
|
+
Type=simple
|
|
135
|
+
WorkingDirectory=${spec.workingDir}
|
|
136
|
+
ExecStart=${execStart}
|
|
137
|
+
Restart=on-failure
|
|
138
|
+
RestartSec=${restartSec}
|
|
139
|
+
# Room for in-flight wakes to drain on SIGTERM before SIGKILL.
|
|
140
|
+
TimeoutStopSec=${timeoutStopSec}
|
|
141
|
+
StandardOutput=journal
|
|
142
|
+
StandardError=journal
|
|
143
|
+
SyslogIdentifier=${SERVICE_NAME}
|
|
144
|
+
Environment=HOME=${spec.home}
|
|
145
|
+
Environment=PATH=${spec.path}
|
|
146
|
+
|
|
147
|
+
[Install]
|
|
148
|
+
WantedBy=default.target
|
|
149
|
+
`;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Render a macOS launchd LaunchAgent plist for the FOREGROUND daemon. Pure.
|
|
154
|
+
* RunAtLoad + KeepAlive make launchd start it at login and restart on crash;
|
|
155
|
+
* ProgramArguments carries node + the daemon argv WITHOUT `-d` (launchd, like
|
|
156
|
+
* systemd, must own the foreground process). We print this for the operator to
|
|
157
|
+
* install manually (no auto-write off Linux).
|
|
158
|
+
* @param {{
|
|
159
|
+
* nodePath: string, scriptPath: string, cwds?: string[], agent?: string,
|
|
160
|
+
* chorusOnly?: boolean, workingDir: string, home: string, path: string,
|
|
161
|
+
* logPath: string,
|
|
162
|
+
* }} spec
|
|
163
|
+
* @returns {string}
|
|
164
|
+
*/
|
|
165
|
+
export function renderLaunchdPlist(spec) {
|
|
166
|
+
const args = buildServiceArgs({
|
|
167
|
+
cwds: spec.cwds,
|
|
168
|
+
agent: spec.agent,
|
|
169
|
+
chorusOnly: spec.chorusOnly,
|
|
170
|
+
scriptPath: spec.scriptPath,
|
|
171
|
+
});
|
|
172
|
+
const programArgs = [spec.nodePath, ...args]
|
|
173
|
+
.map((a) => ` <string>${xmlEscape(a)}</string>`)
|
|
174
|
+
.join("\n");
|
|
175
|
+
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
176
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
177
|
+
<plist version="1.0">
|
|
178
|
+
<dict>
|
|
179
|
+
<key>Label</key>
|
|
180
|
+
<string>com.chorus.daemon</string>
|
|
181
|
+
<key>ProgramArguments</key>
|
|
182
|
+
<array>
|
|
183
|
+
${programArgs}
|
|
184
|
+
</array>
|
|
185
|
+
<key>WorkingDirectory</key>
|
|
186
|
+
<string>${xmlEscape(spec.workingDir)}</string>
|
|
187
|
+
<key>EnvironmentVariables</key>
|
|
188
|
+
<dict>
|
|
189
|
+
<key>HOME</key>
|
|
190
|
+
<string>${xmlEscape(spec.home)}</string>
|
|
191
|
+
<key>PATH</key>
|
|
192
|
+
<string>${xmlEscape(spec.path)}</string>
|
|
193
|
+
</dict>
|
|
194
|
+
<key>RunAtLoad</key>
|
|
195
|
+
<true/>
|
|
196
|
+
<key>KeepAlive</key>
|
|
197
|
+
<true/>
|
|
198
|
+
<key>StandardOutPath</key>
|
|
199
|
+
<string>${xmlEscape(spec.logPath)}</string>
|
|
200
|
+
<key>StandardErrorPath</key>
|
|
201
|
+
<string>${xmlEscape(spec.logPath)}</string>
|
|
202
|
+
</dict>
|
|
203
|
+
</plist>
|
|
204
|
+
`;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/** Minimal XML text escaping for plist string values. */
|
|
208
|
+
function xmlEscape(s) {
|
|
209
|
+
return String(s)
|
|
210
|
+
.replace(/&/g, "&")
|
|
211
|
+
.replace(/</g, "<")
|
|
212
|
+
.replace(/>/g, ">");
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Quote a single token for a systemd `ExecStart=` line. systemd splits the line
|
|
217
|
+
* on unquoted whitespace and supports C-escaped double-quoted strings, so a
|
|
218
|
+
* token containing whitespace (or a quote/backslash) must be wrapped in `"…"`
|
|
219
|
+
* with `\` and `"` escaped. Tokens without whitespace are left bare to keep the
|
|
220
|
+
* common unit readable.
|
|
221
|
+
*/
|
|
222
|
+
function systemdQuoteArg(token) {
|
|
223
|
+
const s = String(token);
|
|
224
|
+
if (!/[\s"\\]/.test(s)) return s;
|
|
225
|
+
return `"${s.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Detect whether a supervisor already manages the chorus daemon on this host.
|
|
230
|
+
* Linux only (systemd --user); everything else reports `{ kind: "none" }`.
|
|
231
|
+
* - kind: "systemd" with installed (unit file present, `is-enabled` not
|
|
232
|
+
* "not-found") and active (`is-active` == "active").
|
|
233
|
+
* - kind: "none" otherwise (or when systemctl is unavailable).
|
|
234
|
+
* Used by the lifecycle subcommands to decide whether to delegate.
|
|
235
|
+
* @param {object} [io]
|
|
236
|
+
* @returns {{ kind: "systemd", installed: boolean, active: boolean, unitPath: string } | { kind: "none" }}
|
|
237
|
+
*/
|
|
238
|
+
export function detectSupervisor(io = defaultIO()) {
|
|
239
|
+
if (io.platform !== "linux") return { kind: "none" };
|
|
240
|
+
const unitPath = systemdUnitPath(io);
|
|
241
|
+
const installed = safeExists(unitPath, io);
|
|
242
|
+
// `is-active` is authoritative for "running under systemd right now". Query it
|
|
243
|
+
// even when the unit file is absent: a transient/unit-less path still returns
|
|
244
|
+
// non-active, and we never want to throw here.
|
|
245
|
+
const activeRes = systemctlUser(["is-active", `${SERVICE_NAME}.service`], io);
|
|
246
|
+
const active = (activeRes.stdout ?? "").trim() === "active";
|
|
247
|
+
if (!installed && !active) return { kind: "none" };
|
|
248
|
+
return { kind: "systemd", installed, active, unitPath };
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
function safeExists(path, io) {
|
|
252
|
+
try {
|
|
253
|
+
return io.existsSync(path);
|
|
254
|
+
} catch {
|
|
255
|
+
return false;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/** Run `systemctl --user <args>`, capturing output. Never throws. */
|
|
260
|
+
export function systemctlUser(args, io = defaultIO()) {
|
|
261
|
+
try {
|
|
262
|
+
const r = io.spawnSync("systemctl", ["--user", ...args], { encoding: "utf8" });
|
|
263
|
+
return { status: r?.status ?? null, stdout: r?.stdout ?? "", stderr: r?.stderr ?? "" };
|
|
264
|
+
} catch (err) {
|
|
265
|
+
return { status: null, stdout: "", stderr: err instanceof Error ? err.message : String(err) };
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
/** Run `journalctl --user <args>`, capturing output. Never throws. */
|
|
270
|
+
export function journalctlUser(args, io = defaultIO()) {
|
|
271
|
+
try {
|
|
272
|
+
const r = io.spawnSync("journalctl", ["--user", ...args], { encoding: "utf8" });
|
|
273
|
+
return { status: r?.status ?? null, stdout: r?.stdout ?? "", stderr: r?.stderr ?? "" };
|
|
274
|
+
} catch (err) {
|
|
275
|
+
return { status: null, stdout: "", stderr: err instanceof Error ? err.message : String(err) };
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* Install the systemd --user unit (Linux) or return the template to print
|
|
281
|
+
* (macOS/Windows). On Linux: write the unit, `daemon-reload`, `enable --now`.
|
|
282
|
+
* All IO injected. Never throws — errors surface in the return shape.
|
|
283
|
+
* @param {{
|
|
284
|
+
* nodePath: string, scriptPath: string, cwds?: string[], agent?: string,
|
|
285
|
+
* chorusOnly?: boolean, workingDir: string, path: string,
|
|
286
|
+
* }} spec
|
|
287
|
+
* @param {object} [io]
|
|
288
|
+
* @returns {{
|
|
289
|
+
* platform: "linux"|"darwin"|"other",
|
|
290
|
+
* installed: boolean,
|
|
291
|
+
* unitPath?: string,
|
|
292
|
+
* unitText: string,
|
|
293
|
+
* steps: string[],
|
|
294
|
+
* error?: string,
|
|
295
|
+
* }}
|
|
296
|
+
*/
|
|
297
|
+
export function installService(spec, io = defaultIO()) {
|
|
298
|
+
const home = io.home ?? homedir();
|
|
299
|
+
if (io.platform === "linux") {
|
|
300
|
+
const unitPath = systemdUnitPath(io);
|
|
301
|
+
const unitText = renderSystemdUnit({ ...spec, home });
|
|
302
|
+
const steps = [];
|
|
303
|
+
try {
|
|
304
|
+
io.mkdirSync(dirname(unitPath), { recursive: true });
|
|
305
|
+
io.writeFileSync(unitPath, unitText, { mode: 0o644 });
|
|
306
|
+
steps.push(`wrote ${unitPath}`);
|
|
307
|
+
const reload = systemctlUser(["daemon-reload"], io);
|
|
308
|
+
if (reload.status !== 0) {
|
|
309
|
+
return { platform: "linux", installed: false, unitPath, unitText, steps, error: `systemctl --user daemon-reload failed: ${reload.stderr.trim() || `exit ${reload.status}`}` };
|
|
310
|
+
}
|
|
311
|
+
steps.push("systemctl --user daemon-reload");
|
|
312
|
+
const enable = systemctlUser(["enable", "--now", `${SERVICE_NAME}.service`], io);
|
|
313
|
+
if (enable.status !== 0) {
|
|
314
|
+
return { platform: "linux", installed: false, unitPath, unitText, steps, error: `systemctl --user enable --now failed: ${enable.stderr.trim() || `exit ${enable.status}`}` };
|
|
315
|
+
}
|
|
316
|
+
steps.push(`systemctl --user enable --now ${SERVICE_NAME}.service`);
|
|
317
|
+
// enable --now only STARTS an inactive service; on a re-install over an
|
|
318
|
+
// already-running daemon it is a no-op, leaving the old process on the old
|
|
319
|
+
// --cwd/--agent flags. Restart so a re-install always applies the new unit.
|
|
320
|
+
// Best-effort: a restart failure must not fail an otherwise-good install.
|
|
321
|
+
const restart = systemctlUser(["restart", `${SERVICE_NAME}.service`], io);
|
|
322
|
+
if (restart.status === 0) steps.push(`systemctl --user restart ${SERVICE_NAME}.service`);
|
|
323
|
+
return { platform: "linux", installed: true, unitPath, unitText, steps };
|
|
324
|
+
} catch (err) {
|
|
325
|
+
return { platform: "linux", installed: false, unitPath, unitText, steps, error: err instanceof Error ? err.message : String(err) };
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
if (io.platform === "darwin") {
|
|
329
|
+
const plistPath = launchdPlistPath(io);
|
|
330
|
+
const unitText = renderLaunchdPlist({ ...spec, home, logPath: join(home, ".chorus", "daemon.log") });
|
|
331
|
+
return {
|
|
332
|
+
platform: "darwin",
|
|
333
|
+
installed: false,
|
|
334
|
+
unitPath: plistPath,
|
|
335
|
+
unitText,
|
|
336
|
+
steps: [
|
|
337
|
+
`Save the plist below to ${plistPath}`,
|
|
338
|
+
`launchctl load -w ${plistPath}`,
|
|
339
|
+
`Check: launchctl list | grep com.chorus.daemon`,
|
|
340
|
+
],
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
// Windows / other: no first-class service model without native deps. Print the
|
|
344
|
+
// foreground command an operator can wrap in their supervisor of choice.
|
|
345
|
+
// Quote whitespace-bearing tokens so a copy-pasted path with a space survives.
|
|
346
|
+
const cmd = [spec.nodePath, ...buildServiceArgs(spec)]
|
|
347
|
+
.map((a) => (/\s/.test(String(a)) ? `"${a}"` : a))
|
|
348
|
+
.join(" ");
|
|
349
|
+
return {
|
|
350
|
+
platform: "other",
|
|
351
|
+
installed: false,
|
|
352
|
+
unitText: cmd,
|
|
353
|
+
steps: [
|
|
354
|
+
"Automatic service install is only supported on Linux (systemd).",
|
|
355
|
+
"Run the daemon in the FOREGROUND under your supervisor of choice (NSSM, Task Scheduler, etc.) — do NOT use -d, let the supervisor own the process:",
|
|
356
|
+
` ${cmd}`,
|
|
357
|
+
],
|
|
358
|
+
};
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
/**
|
|
362
|
+
* Uninstall the systemd --user unit (Linux): `disable --now`, remove the unit
|
|
363
|
+
* file, `daemon-reload`. macOS/Windows: return manual removal steps. All IO
|
|
364
|
+
* injected. Never throws.
|
|
365
|
+
* @param {object} [io]
|
|
366
|
+
* @returns {{
|
|
367
|
+
* platform: "linux"|"darwin"|"other",
|
|
368
|
+
* removed: boolean,
|
|
369
|
+
* unitPath?: string,
|
|
370
|
+
* steps: string[],
|
|
371
|
+
* error?: string,
|
|
372
|
+
* }}
|
|
373
|
+
*/
|
|
374
|
+
export function uninstallService(io = defaultIO()) {
|
|
375
|
+
if (io.platform === "linux") {
|
|
376
|
+
const unitPath = systemdUnitPath(io);
|
|
377
|
+
const steps = [];
|
|
378
|
+
const existed = safeExists(unitPath, io);
|
|
379
|
+
// disable --now stops + removes the autostart symlink; tolerate a missing
|
|
380
|
+
// unit (already gone) so uninstall is idempotent.
|
|
381
|
+
const disable = systemctlUser(["disable", "--now", `${SERVICE_NAME}.service`], io);
|
|
382
|
+
if (disable.status === 0) steps.push(`systemctl --user disable --now ${SERVICE_NAME}.service`);
|
|
383
|
+
try {
|
|
384
|
+
if (existed) {
|
|
385
|
+
io.unlinkSync(unitPath);
|
|
386
|
+
steps.push(`removed ${unitPath}`);
|
|
387
|
+
}
|
|
388
|
+
} catch (err) {
|
|
389
|
+
return { platform: "linux", removed: false, unitPath, steps, error: err instanceof Error ? err.message : String(err) };
|
|
390
|
+
}
|
|
391
|
+
systemctlUser(["daemon-reload"], io);
|
|
392
|
+
steps.push("systemctl --user daemon-reload");
|
|
393
|
+
return { platform: "linux", removed: existed || disable.status === 0, unitPath, steps };
|
|
394
|
+
}
|
|
395
|
+
if (io.platform === "darwin") {
|
|
396
|
+
const plistPath = launchdPlistPath(io);
|
|
397
|
+
return {
|
|
398
|
+
platform: "darwin",
|
|
399
|
+
removed: false,
|
|
400
|
+
unitPath: plistPath,
|
|
401
|
+
steps: [`launchctl unload -w ${plistPath}`, `rm ${plistPath}`],
|
|
402
|
+
};
|
|
403
|
+
}
|
|
404
|
+
return {
|
|
405
|
+
platform: "other",
|
|
406
|
+
removed: false,
|
|
407
|
+
steps: ["Automatic service uninstall is only supported on Linux (systemd). Remove the daemon from your supervisor manually."],
|
|
408
|
+
};
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
/**
|
|
412
|
+
* The absolute node + script paths for a freshly-rendered unit, derived from the
|
|
413
|
+
* running CLI. Kept here so callers don't reach into process internals.
|
|
414
|
+
* @returns {{ nodePath: string, scriptPath: string, path: string }}
|
|
415
|
+
*/
|
|
416
|
+
export function resolveServicePaths(env = process.env, execPath = process.execPath) {
|
|
417
|
+
return {
|
|
418
|
+
nodePath: execPath,
|
|
419
|
+
scriptPath: resolveScriptPath(),
|
|
420
|
+
path: env.PATH ?? "/usr/local/bin:/usr/bin:/bin",
|
|
421
|
+
};
|
|
422
|
+
}
|
package/cli/daemon.mjs
CHANGED
|
@@ -46,6 +46,15 @@ import {
|
|
|
46
46
|
isRunning,
|
|
47
47
|
readLog,
|
|
48
48
|
} from "./daemon-lifecycle.mjs";
|
|
49
|
+
import {
|
|
50
|
+
detectSupervisor,
|
|
51
|
+
installService,
|
|
52
|
+
uninstallService,
|
|
53
|
+
systemctlUser,
|
|
54
|
+
journalctlUser,
|
|
55
|
+
resolveServicePaths,
|
|
56
|
+
SERVICE_NAME,
|
|
57
|
+
} from "./daemon-service.mjs";
|
|
49
58
|
import { readFileSync, existsSync } from "node:fs";
|
|
50
59
|
import { dirname, join } from "node:path";
|
|
51
60
|
import { fileURLToPath } from "node:url";
|
|
@@ -254,7 +263,20 @@ export function buildDaemon(creds, deps = {}) {
|
|
|
254
263
|
// transcript (new-vs-resume) and to spawn, so they never diverge (Module Contract
|
|
255
264
|
// 1 — resolveCwd is the single source). `cwd` is `undefined` for the single-path /
|
|
256
265
|
// old-daemon default, which the Waker degrades to process.cwd() (HARD-1).
|
|
257
|
-
waker = new Waker({
|
|
266
|
+
waker = new Waker({
|
|
267
|
+
creds,
|
|
268
|
+
lineage,
|
|
269
|
+
spawner,
|
|
270
|
+
cwd,
|
|
271
|
+
hooks,
|
|
272
|
+
logger,
|
|
273
|
+
reportInterrupt,
|
|
274
|
+
advanceTurn,
|
|
275
|
+
verbose,
|
|
276
|
+
// Graceful-shutdown kill escalation (fix-daemon-exit-orphan-running-turn):
|
|
277
|
+
// interruptAll() reuses the SAME window the interrupt control handler uses.
|
|
278
|
+
sigintTimeoutMs,
|
|
279
|
+
});
|
|
258
280
|
// The router reads THIS connection's own uuid lazily (same source the control handler
|
|
259
281
|
// uses) to suppress a DIRECTED (pinned) wake stamped for a different connection
|
|
260
282
|
// (fix-pinned-wake-directed-delivery, T2). Null until the SSE handshake assigns it — a
|
|
@@ -274,8 +296,8 @@ export function buildDaemon(creds, deps = {}) {
|
|
|
274
296
|
// all scoped to THIS connection's uuid/router/backfill (see the original wiring
|
|
275
297
|
// comments retained on the shared helpers). The control handler verifies a control
|
|
276
298
|
// event against this connection's own connectionUuid before acting.
|
|
277
|
-
const redispatchResume = (entityType, entityUuid) => {
|
|
278
|
-
router.dispatchResume?.({ entityType, entityUuid });
|
|
299
|
+
const redispatchResume = (entityType, entityUuid, resumeReason) => {
|
|
300
|
+
router.dispatchResume?.({ entityType, entityUuid, resumeReason });
|
|
279
301
|
};
|
|
280
302
|
const deliverTurn = (turnUuid) => backfill?.pendingTurnsOnly?.(turnUuid);
|
|
281
303
|
const onControl = createControlHandler({
|
|
@@ -399,10 +421,30 @@ export function buildDaemon(creds, deps = {}) {
|
|
|
399
421
|
}
|
|
400
422
|
},
|
|
401
423
|
async stop() {
|
|
424
|
+
// Graceful shutdown ordering (fix-daemon-exit-orphan-running-turn):
|
|
425
|
+
// 1. Stop taking new work: disconnect the SSE listeners (no new notifications)
|
|
426
|
+
// and latch the queue (queued-but-unstarted wakes never spawn).
|
|
402
427
|
for (const c of connections) {
|
|
403
428
|
c.sseListener.disconnect?.();
|
|
404
429
|
}
|
|
405
|
-
|
|
430
|
+
queue.stop();
|
|
431
|
+
// 2. Interrupt every in-flight wake subprocess via the shared kill escalation.
|
|
432
|
+
// Each wake's exit path — seeing shuttingDown — reports its turn
|
|
433
|
+
// interrupted(shutdown) and suppresses the execution crash report.
|
|
434
|
+
for (const c of connections) {
|
|
435
|
+
c.waker?.interruptAll?.();
|
|
436
|
+
}
|
|
437
|
+
// 3. Await the in-flight wakes so those turn-advance reports flush, BOUNDED:
|
|
438
|
+
// the kill escalation window plus a hard 5s cap for the exit path's REST
|
|
439
|
+
// reports. A wake that outlives this does NOT hang the shutdown — its
|
|
440
|
+
// orphaned turn is the server-side offline reconcile's job (the backstop).
|
|
441
|
+
const drained = await queue.drain(sigintTimeoutMs + 5_000);
|
|
442
|
+
if (!drained) {
|
|
443
|
+
logger.warn(
|
|
444
|
+
"[Chorus] shutdown: in-flight wake(s) did not finish within the bound — exiting anyway (server reconcile will finalize their turns)",
|
|
445
|
+
);
|
|
446
|
+
}
|
|
447
|
+
// 4. The MCP client is process-wide (shared) — disconnect it once.
|
|
406
448
|
await mcpClient.disconnect?.();
|
|
407
449
|
},
|
|
408
450
|
};
|
|
@@ -456,7 +498,25 @@ export async function runDaemon(flags = {}, deps = {}) {
|
|
|
456
498
|
// Lifecycle subcommands (stop/status/restart/logs) operate on the pidfile/logfile
|
|
457
499
|
// managed by the `-d` path — they never start the long-lived foreground daemon.
|
|
458
500
|
// `run` falls through to the normal startup below. Injectable lifecycle for tests.
|
|
459
|
-
|
|
501
|
+
// stopDaemon's real signature is (io, opts); the bundle exposes (opts) with the
|
|
502
|
+
// default io so handleLifecycleAction can pass { force } directly.
|
|
503
|
+
const lifecycle = deps.lifecycle ?? {
|
|
504
|
+
startBackground,
|
|
505
|
+
stopDaemon: (opts) => stopDaemon(undefined, opts),
|
|
506
|
+
isRunning,
|
|
507
|
+
readLog,
|
|
508
|
+
};
|
|
509
|
+
// Supervisor (systemd --user) seam — install/uninstall the boot service and
|
|
510
|
+
// detect/delegate to it from the lifecycle subcommands. Injectable for tests
|
|
511
|
+
// (no real systemctl / disk). Defaults to the real daemon-service module.
|
|
512
|
+
const service = deps.service ?? {
|
|
513
|
+
detectSupervisor,
|
|
514
|
+
installService,
|
|
515
|
+
uninstallService,
|
|
516
|
+
systemctlUser,
|
|
517
|
+
journalctlUser,
|
|
518
|
+
resolveServicePaths: () => resolveServicePaths(env),
|
|
519
|
+
};
|
|
460
520
|
// The preflight dep bundle — built from the same seams runDaemon resolved, so
|
|
461
521
|
// the detach/restart paths run the SAME (injectable) preflight, not the real
|
|
462
522
|
// implementations. Threaded into startDetached so tests can drive it offline.
|
|
@@ -464,7 +524,7 @@ export async function runDaemon(flags = {}, deps = {}) {
|
|
|
464
524
|
|
|
465
525
|
const action = flags.action ?? "run";
|
|
466
526
|
if (action !== "run") {
|
|
467
|
-
return handleLifecycleAction(action, { log, errLog, lifecycle, pfDeps });
|
|
527
|
+
return handleLifecycleAction(action, { log, errLog, lifecycle, service, pfDeps });
|
|
468
528
|
}
|
|
469
529
|
|
|
470
530
|
// `-d` / --detach: complete any interactive preflight in THIS foreground process
|
|
@@ -665,13 +725,87 @@ export async function preflight(ctx) {
|
|
|
665
725
|
}
|
|
666
726
|
|
|
667
727
|
/**
|
|
668
|
-
* Dispatch a daemon lifecycle subcommand
|
|
669
|
-
*
|
|
670
|
-
*
|
|
728
|
+
* Dispatch a daemon lifecycle subcommand. Two families:
|
|
729
|
+
* - install / uninstall — manage the boot-autostart supervisor service
|
|
730
|
+
* (systemd --user on Linux; a printed template on macOS/Windows).
|
|
731
|
+
* - status / stop / restart / logs — when a supervisor unit is installed and
|
|
732
|
+
* active, DELEGATE to it (systemctl / journalctl) so a supervised daemon is
|
|
733
|
+
* never misreported as "not running"; otherwise operate on the
|
|
734
|
+
* pidfile/logfile-managed `-d` background daemon exactly as before.
|
|
735
|
+
* Each reports clearly (no silent failure). `restart` performs
|
|
736
|
+
* stop-then-detached-start on the pidfile path.
|
|
671
737
|
* @returns {Promise<number>} exit code
|
|
672
738
|
*/
|
|
673
|
-
export async function handleLifecycleAction(action, { log, errLog, lifecycle, pfDeps }) {
|
|
739
|
+
export async function handleLifecycleAction(action, { log, errLog, lifecycle, service, pfDeps }) {
|
|
740
|
+
// The supervisor seam is optional (older test bundles inject only lifecycle);
|
|
741
|
+
// a no-op fallback keeps those callers on the pure pidfile path.
|
|
742
|
+
const svc = service ?? { detectSupervisor: () => ({ kind: "none" }) };
|
|
743
|
+
|
|
744
|
+
if (action === "install") {
|
|
745
|
+
const spec = {
|
|
746
|
+
...svc.resolveServicePaths(),
|
|
747
|
+
cwds: pfDeps?.flags?.cwd ?? [],
|
|
748
|
+
agent: pfDeps?.flags?.agent,
|
|
749
|
+
chorusOnly: pfDeps?.flags?.chorusOnly === true,
|
|
750
|
+
workingDir: process.cwd(),
|
|
751
|
+
};
|
|
752
|
+
const r = svc.installService(spec);
|
|
753
|
+
if (r.installed) {
|
|
754
|
+
log(`[Chorus] installed and started the daemon service:`);
|
|
755
|
+
for (const s of r.steps) log(`[Chorus] ${s}`);
|
|
756
|
+
log(`[Chorus] it will now start automatically at login. Manage it with:`);
|
|
757
|
+
log(`[Chorus] chorus daemon status | stop | restart | logs`);
|
|
758
|
+
// A --user service only survives logout with lingering enabled; and a
|
|
759
|
+
// separately-started `chorus daemon -d` would hold the same paths and make
|
|
760
|
+
// this service exit-and-retry. Surface both so neither is a silent gotcha.
|
|
761
|
+
log(`[Chorus] to keep it running after you log out: loginctl enable-linger "$USER"`);
|
|
762
|
+
log(`[Chorus] if you previously ran 'chorus daemon -d', stop it first ('chorus daemon stop') so it doesn't hold the same paths.`);
|
|
763
|
+
return 0;
|
|
764
|
+
}
|
|
765
|
+
if (r.platform === "linux") {
|
|
766
|
+
// Linux install actually failed (write / systemctl error) — surface it.
|
|
767
|
+
errLog(`[Chorus] service install failed: ${r.error}`);
|
|
768
|
+
for (const s of r.steps) errLog(`[Chorus] (did: ${s})`);
|
|
769
|
+
return 1;
|
|
770
|
+
}
|
|
771
|
+
// macOS / Windows: not auto-installed by design — print the template + steps.
|
|
772
|
+
log(`[Chorus] automatic install is Linux-only. To run the daemon as a service on this platform:`);
|
|
773
|
+
for (const s of r.steps) log(`[Chorus] ${s}`);
|
|
774
|
+
log("");
|
|
775
|
+
log(r.unitText);
|
|
776
|
+
return 0;
|
|
777
|
+
}
|
|
778
|
+
if (action === "uninstall") {
|
|
779
|
+
const r = svc.uninstallService();
|
|
780
|
+
if (r.platform === "linux") {
|
|
781
|
+
if (r.error) {
|
|
782
|
+
errLog(`[Chorus] service uninstall failed: ${r.error}`);
|
|
783
|
+
return 1;
|
|
784
|
+
}
|
|
785
|
+
if (r.removed) {
|
|
786
|
+
log(`[Chorus] removed the daemon service:`);
|
|
787
|
+
for (const s of r.steps) log(`[Chorus] ${s}`);
|
|
788
|
+
} else {
|
|
789
|
+
log(`[Chorus] no installed daemon service found (nothing to remove).`);
|
|
790
|
+
}
|
|
791
|
+
return 0;
|
|
792
|
+
}
|
|
793
|
+
log(`[Chorus] automatic uninstall is Linux-only. To remove the service on this platform:`);
|
|
794
|
+
for (const s of r.steps) log(`[Chorus] ${s}`);
|
|
795
|
+
return 0;
|
|
796
|
+
}
|
|
797
|
+
|
|
798
|
+
// For the control verbs, prefer a live supervisor unit over the pidfile.
|
|
799
|
+
const sup = svc.detectSupervisor();
|
|
800
|
+
const supervised = sup.kind === "systemd" && sup.installed;
|
|
801
|
+
|
|
674
802
|
if (action === "status") {
|
|
803
|
+
if (supervised) {
|
|
804
|
+
log(`[Chorus] daemon is managed by systemd (${SERVICE_NAME}.service) — ${sup.active ? "active" : "installed but NOT active"}.`);
|
|
805
|
+
const r = svc.systemctlUser(["status", "--no-pager", `${SERVICE_NAME}.service`]);
|
|
806
|
+
if (r.stdout) log(r.stdout.trimEnd());
|
|
807
|
+
return sup.active ? 0 : 1;
|
|
808
|
+
}
|
|
675
809
|
const s = lifecycle.isRunning();
|
|
676
810
|
if (s.running) log(`[Chorus] daemon is running (pid ${s.pid}).`);
|
|
677
811
|
else if (s.stale) log(`[Chorus] daemon is NOT running (stale pidfile for pid ${s.pid}).`);
|
|
@@ -679,6 +813,15 @@ export async function handleLifecycleAction(action, { log, errLog, lifecycle, pf
|
|
|
679
813
|
return 0;
|
|
680
814
|
}
|
|
681
815
|
if (action === "logs") {
|
|
816
|
+
if (supervised) {
|
|
817
|
+
const r = svc.journalctlUser(["-u", `${SERVICE_NAME}.service`, "--no-pager", "-n", "200"]);
|
|
818
|
+
if (r.status !== 0 && !r.stdout) {
|
|
819
|
+
errLog(`[Chorus] could not read the service journal: ${r.stderr.trim() || `exit ${r.status}`}`);
|
|
820
|
+
return 1;
|
|
821
|
+
}
|
|
822
|
+
log(r.stdout.trimEnd());
|
|
823
|
+
return 0;
|
|
824
|
+
}
|
|
682
825
|
const r = lifecycle.readLog();
|
|
683
826
|
if (!r.ok) {
|
|
684
827
|
errLog(`[Chorus] ${r.message}`);
|
|
@@ -688,11 +831,36 @@ export async function handleLifecycleAction(action, { log, errLog, lifecycle, pf
|
|
|
688
831
|
return 0;
|
|
689
832
|
}
|
|
690
833
|
if (action === "stop") {
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
834
|
+
if (supervised) {
|
|
835
|
+
const r = svc.systemctlUser(["stop", `${SERVICE_NAME}.service`]);
|
|
836
|
+
if (r.status === 0) {
|
|
837
|
+
log(`[Chorus] stopped the daemon service (systemctl --user stop ${SERVICE_NAME}.service).`);
|
|
838
|
+
log(`[Chorus] note: it is still enabled and will start again at next login. To disable: chorus daemon uninstall`);
|
|
839
|
+
return 0;
|
|
840
|
+
}
|
|
841
|
+
errLog(`[Chorus] failed to stop the service: ${r.stderr.trim() || `exit ${r.status}`}`);
|
|
842
|
+
return 1;
|
|
843
|
+
}
|
|
844
|
+
// --force: unconditional pidfile cleanup for stuck states the identity
|
|
845
|
+
// probe cannot resolve. Threaded from the parsed client flags.
|
|
846
|
+
const r = lifecycle.stopDaemon({ force: pfDeps?.flags?.force === true });
|
|
847
|
+
// Exit 0 whenever the end state is "no daemon, no pidfile" (stopped /
|
|
848
|
+
// stale-cleared / forced) so `chorus daemon stop && …` chains survive a
|
|
849
|
+
// self-heal; 1 for not-running and signal errors.
|
|
850
|
+
const ok = r.reason === "stopped" || r.reason === "stale-cleared" || r.reason === "forced";
|
|
851
|
+
(ok ? log : errLog)(`[Chorus] ${r.message}`);
|
|
852
|
+
return ok ? 0 : 1;
|
|
694
853
|
}
|
|
695
854
|
if (action === "restart") {
|
|
855
|
+
if (supervised) {
|
|
856
|
+
const r = svc.systemctlUser(["restart", `${SERVICE_NAME}.service`]);
|
|
857
|
+
if (r.status === 0) {
|
|
858
|
+
log(`[Chorus] restarted the daemon service (systemctl --user restart ${SERVICE_NAME}.service).`);
|
|
859
|
+
return 0;
|
|
860
|
+
}
|
|
861
|
+
errLog(`[Chorus] failed to restart the service: ${r.stderr.trim() || `exit ${r.status}`}`);
|
|
862
|
+
return 1;
|
|
863
|
+
}
|
|
696
864
|
const r = lifecycle.stopDaemon();
|
|
697
865
|
log(`[Chorus] ${r.message}`);
|
|
698
866
|
// Start a fresh detached instance regardless of whether one was running.
|