@chorus-aidlc/chorus 0.19.1 → 0.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.next/standalone/.next/BUILD_ID +1 -1
- package/.next/standalone/.next/app-build-manifest.json +349 -349
- package/.next/standalone/.next/app-path-routes-manifest.json +38 -38
- package/.next/standalone/.next/build-manifest.json +5 -5
- package/.next/standalone/.next/prerender-manifest.json +18 -18
- package/.next/standalone/.next/server/app/(dashboard)/project-groups/[uuid]/page.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/project-groups/[uuid]/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/project-groups/[uuid]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/activity/page.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/activity/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/dashboard/[ideaUuid]/page.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/dashboard/[ideaUuid]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/dashboard/page.js +2 -2
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/dashboard/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/dashboard/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/documents/[documentUuid]/page.js +2 -2
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/documents/[documentUuid]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/documents/page.js +2 -2
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/documents/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/graph/page.js +2 -2
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/graph/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/graph/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/[proposalUuid]/page.js +2 -2
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/[proposalUuid]/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/[proposalUuid]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/new/page.js +2 -2
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/new/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/page.js +2 -2
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/tasks/[taskUuid]/page.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/tasks/[taskUuid]/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/tasks/[taskUuid]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/tasks/page.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/tasks/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/tasks/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/page.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/settings/page.js +2 -2
- package/.next/standalone/.next/server/app/(dashboard)/settings/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/settings/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/_not-found.html +2 -2
- package/.next/standalone/.next/server/app/_not-found.rsc +2 -2
- package/.next/standalone/.next/server/app/admin/companies/[uuid]/page.js +1 -1
- package/.next/standalone/.next/server/app/admin/companies/[uuid]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/admin/companies/new/page.js +1 -1
- package/.next/standalone/.next/server/app/admin/companies/new/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/admin/companies/new.html +2 -2
- package/.next/standalone/.next/server/app/admin/companies/new.rsc +3 -3
- package/.next/standalone/.next/server/app/admin/companies/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/admin/companies.html +2 -2
- package/.next/standalone/.next/server/app/admin/companies.rsc +2 -2
- package/.next/standalone/.next/server/app/admin/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/admin.html +2 -2
- package/.next/standalone/.next/server/app/admin.rsc +2 -2
- package/.next/standalone/.next/server/app/api/admin/companies/[uuid]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/admin/companies/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/admin/login/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/admin/session/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/agent-connections/route_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_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/agents/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/api-keys/[uuid]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/api-keys/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/auth/callback/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/auth/check-default/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/auth/company-oidc/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/auth/default-login/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/auth/identify/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/auth/logout/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/auth/me/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/auth/sync-token/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/comments/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon/connection-heartbeat/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon/control/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon/directory-request/report/route_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon/turn-advance/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon-directory-requests/[uuid]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon-directory-requests/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/daemon-sessions/[sessionUuid]/instruction/route_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/documents/[uuid]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/entities/[type]/[uuid]/root-idea/route_client-reference-manifest.js +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_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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/ideas/[uuid]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/ideas/[uuid]/wake-preview/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/ideas/conversational/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/mcp/route_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/project-groups/[uuid]/dashboard/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/project-groups/[uuid]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/project-groups/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/project-visits/pin/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/project-visits/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/project-visits/visit/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/activity/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/agent-cwds/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/available/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/documents/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/group/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/ideas/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/ideas/tracker/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/proposals/[proposalUuid]/validate/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/proposals/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/proposals/summary/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/resource-graph/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/stats/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/tasks/dependencies/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/[uuid]/tasks/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/projects/agent-cwd-options/route_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_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/proposals/[uuid]/close/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/proposals/[uuid]/reject/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/proposals/[uuid]/revoke/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/proposals/[uuid]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/references/[uuid]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/references/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/search/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/session/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/sessions/[uuid]/route_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/index.html +2 -2
- package/.next/standalone/.next/server/app/index.rsc +2 -2
- package/.next/standalone/.next/server/app/login/admin/page.js +1 -1
- package/.next/standalone/.next/server/app/login/admin/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/login/admin.html +2 -2
- package/.next/standalone/.next/server/app/login/admin.rsc +3 -3
- package/.next/standalone/.next/server/app/login/callback/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/login/callback.html +2 -2
- package/.next/standalone/.next/server/app/login/callback.rsc +2 -2
- package/.next/standalone/.next/server/app/login/page.js +1 -1
- package/.next/standalone/.next/server/app/login/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/login/pick-workspace/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/login/pick-workspace.html +2 -2
- package/.next/standalone/.next/server/app/login/pick-workspace.rsc +2 -2
- package/.next/standalone/.next/server/app/login.html +2 -2
- 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 +2 -2
- package/.next/standalone/.next/server/app/onboarding.rsc +3 -3
- package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/projects.html +2 -2
- package/.next/standalone/.next/server/app/projects.rsc +4 -4
- package/.next/standalone/.next/server/app/settings.html +2 -2
- package/.next/standalone/.next/server/app/settings.rsc +4 -4
- package/.next/standalone/.next/server/app-paths-manifest.json +38 -38
- package/.next/standalone/.next/server/chunks/1559.js +2 -2
- package/.next/standalone/.next/server/chunks/{657.js → 186.js} +1 -1
- package/.next/standalone/.next/server/chunks/2572.js +1 -1
- package/.next/standalone/.next/server/chunks/2961.js +1 -1
- package/.next/standalone/.next/server/chunks/3371.js +1 -0
- package/.next/standalone/.next/server/chunks/4131.js +39 -0
- package/.next/standalone/.next/server/chunks/4672.js +2 -2
- package/.next/standalone/.next/server/chunks/5245.js +1 -1
- package/.next/standalone/.next/server/chunks/5577.js +1 -0
- package/.next/standalone/.next/server/chunks/5728.js +1 -0
- package/.next/standalone/.next/server/chunks/6113.js +1 -1
- package/.next/standalone/.next/server/chunks/6515.js +2 -2
- package/.next/standalone/.next/server/chunks/6753.js +4 -4
- package/.next/standalone/.next/server/chunks/679.js +1 -1
- package/.next/standalone/.next/server/chunks/7368.js +1 -1
- package/.next/standalone/.next/server/chunks/7530.js +1 -1
- package/.next/standalone/.next/server/chunks/8017.js +1 -1
- package/.next/standalone/.next/server/chunks/8177.js +1 -0
- package/.next/standalone/.next/server/chunks/920.js +1 -1
- package/.next/standalone/.next/server/chunks/9213.js +1 -1
- package/.next/standalone/.next/server/chunks/9378.js +1 -1
- package/.next/standalone/.next/server/chunks/9931.js +1 -1
- package/.next/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/.next/standalone/.next/server/middleware-manifest.json +5 -5
- package/.next/standalone/.next/server/pages/404.html +2 -2
- package/.next/standalone/.next/server/pages/500.html +1 -1
- package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/static/chunks/{11595.b2b74d1d1d0ae9d9.js → 11595.4cebcf7499ef6a78.js} +1 -1
- package/.next/standalone/.next/static/chunks/27370-0d04028ec8a339f0.js +1 -0
- package/.next/standalone/.next/static/chunks/27787-3566e3dd0506e241.js +1 -0
- package/.next/standalone/.next/static/chunks/{33456.978e5f47d1c8eb93.js → 33456.a5a9acba61ca3665.js} +1 -1
- package/.next/standalone/.next/static/chunks/{4860.79d6eefc2861716f.js → 4860.61dfcdf8c4c5c703.js} +1 -1
- package/.next/standalone/.next/static/chunks/53504-3a0f6dee12a39d5d.js +1 -0
- package/.next/standalone/.next/static/chunks/63819-c52b5bc9ee32ca9b.js +1 -0
- package/.next/standalone/.next/static/chunks/76103-5d656aebd9cd5e7f.js +1 -0
- package/.next/standalone/.next/static/chunks/78847-9f65efbac984cf70.js +1 -0
- package/.next/standalone/.next/static/chunks/79919-32af2c1abfc92a30.js +1 -0
- package/.next/standalone/.next/static/chunks/91997-3592827b5a069beb.js +1 -0
- package/.next/standalone/.next/static/chunks/{99373.e659954ff5148796.js → 99373.747e181e4c952509.js} +1 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/layout-6135300353d6c6ad.js +1 -0
- package/.next/standalone/.next/static/chunks/app/(dashboard)/project-groups/[uuid]/page-bb9f26c107a6b113.js +1 -0
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/dashboard/page-31dd9042ee36b8e5.js +1 -0
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/documents/[documentUuid]/page-a6bfa3b6b6893bc4.js +1 -0
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/documents/page-01e81333c9beee2d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/graph/{page-487d071317ae5e6d.js → page-795b161eb0694092.js} +1 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/[proposalUuid]/page-e20e65b5df817433.js +1 -0
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/new/page-fc2d02d552bbdbf0.js +1 -0
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/page-0cfa38d2de9fa9d9.js +1 -0
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/tasks/[taskUuid]/{page-7cb8a91f6ca34ba8.js → page-529dec4c3bcd5ba9.js} +1 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/tasks/{page-6466141ca355d9a4.js → page-b211c29669eaa3e4.js} +1 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/settings/page-0606d1497512e155.js +1 -0
- package/.next/standalone/.next/static/chunks/app/admin/companies/[uuid]/page-47e49c331996193b.js +1 -0
- package/.next/standalone/.next/static/chunks/app/admin/companies/new/page-c1e28205503002de.js +1 -0
- package/.next/standalone/.next/static/chunks/app/login/admin/page-b0d0ea2fa4102ff7.js +1 -0
- package/.next/standalone/.next/static/chunks/app/login/page-ee63e900cb54148c.js +1 -0
- package/.next/standalone/.next/static/chunks/app/onboarding/{page-323e1d93218758c5.js → page-1f3ab167cab58610.js} +1 -1
- package/.next/standalone/.next/static/chunks/{webpack-ec441a05567c82b0.js → webpack-6151d196b2fab7e8.js} +1 -1
- package/.next/standalone/.next/static/css/09ac5931fe977492.css +1 -0
- package/.next/standalone/package.json +1 -1
- package/.next/standalone/public/chorus-plugin/.claude-plugin/plugin.json +1 -1
- package/.next/standalone/public/chorus-plugin/bin/chorus-api.sh +1 -1
- package/.next/standalone/public/chorus-plugin/skills/brainstorm/SKILL.md +1 -1
- package/.next/standalone/public/chorus-plugin/skills/chorus/SKILL.md +1 -1
- package/.next/standalone/public/chorus-plugin/skills/chorus-cli/SKILL.md +1 -1
- package/.next/standalone/public/chorus-plugin/skills/develop/SKILL.md +1 -1
- package/.next/standalone/public/chorus-plugin/skills/docs/SKILL.md +1 -1
- package/.next/standalone/public/chorus-plugin/skills/idea/SKILL.md +1 -1
- package/.next/standalone/public/chorus-plugin/skills/openspec-aware/SKILL.md +1 -1
- package/.next/standalone/public/chorus-plugin/skills/orchestrate/SKILL.md +1 -1
- package/.next/standalone/public/chorus-plugin/skills/proposal/SKILL.md +1 -1
- package/.next/standalone/public/chorus-plugin/skills/quick-dev/SKILL.md +1 -1
- package/.next/standalone/public/chorus-plugin/skills/research/SKILL.md +1 -1
- package/.next/standalone/public/chorus-plugin/skills/review/SKILL.md +1 -1
- package/.next/standalone/public/chorus-plugin/skills/spec-lite/SKILL.md +1 -1
- package/.next/standalone/public/chorus-plugin/skills/yolo/SKILL.md +1 -1
- package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-brainstorm/SKILL.md +1 -1
- package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-cli/SKILL.md +1 -1
- package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-develop/SKILL.md +1 -1
- package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-docs/SKILL.md +1 -1
- package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-idea/SKILL.md +1 -1
- package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-openspec-aware/SKILL.md +1 -1
- package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-orchestrate/SKILL.md +1 -1
- package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-proposal/SKILL.md +1 -1
- package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-quick-dev/SKILL.md +1 -1
- package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-research/SKILL.md +1 -1
- package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-review/SKILL.md +1 -1
- package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-spec-lite/SKILL.md +1 -1
- package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-yolo/SKILL.md +1 -1
- package/.next/standalone/public/kiro-plugin/bin/chorus-api.sh +1 -1
- package/README.ja.md +3 -1
- package/README.ko.md +3 -1
- package/README.md +18 -1
- package/README.zh.md +18 -1
- package/chorus.mjs +7 -1
- package/cli/agent-cli-config.mjs +28 -2
- package/cli/claude-spawner.mjs +330 -18
- package/cli/codex-app-server-client.mjs +402 -0
- package/cli/codex-app-server-events.mjs +176 -0
- package/cli/codex-session-map.mjs +1 -1
- package/cli/codex-spawner.mjs +247 -241
- package/cli/init/adapters.mjs +2 -2
- package/cli/init/file-template.mjs +11 -4
- package/cli/init/install-methods.mjs +3 -1
- package/cli/pi-spawner.mjs +472 -78
- package/cli/process-killer.mjs +138 -13
- package/cli/process-stop-hooks.mjs +13 -0
- package/cli/upgrade-plugins.mjs +202 -0
- package/cli/upgrade-process.mjs +159 -0
- package/cli/upgrade.mjs +125 -0
- package/cli/upload-hooks.mjs +2 -2
- package/cli/windows-process-tree.mjs +154 -0
- package/package.json +1 -1
- package/.next/standalone/.next/server/chunks/3420.js +0 -1
- package/.next/standalone/.next/server/chunks/38.js +0 -39
- package/.next/standalone/.next/server/chunks/5576.js +0 -1
- package/.next/standalone/.next/server/chunks/6125.js +0 -1
- package/.next/standalone/.next/server/chunks/6509.js +0 -1
- package/.next/standalone/.next/static/chunks/17081-63e2cad8c15da2fb.js +0 -1
- package/.next/standalone/.next/static/chunks/27370-f998ed24dd4fa975.js +0 -1
- package/.next/standalone/.next/static/chunks/46437-88abf056c31c7e4e.js +0 -1
- package/.next/standalone/.next/static/chunks/48365-13b8e43016ba16a4.js +0 -1
- package/.next/standalone/.next/static/chunks/71522-de2b2a9d8e5059e1.js +0 -1
- package/.next/standalone/.next/static/chunks/79919-d423af700ae83862.js +0 -1
- package/.next/standalone/.next/static/chunks/91796-d235607f577fbaeb.js +0 -1
- package/.next/standalone/.next/static/chunks/99540-99af558190f96511.js +0 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/layout-adf9dbdf339e9038.js +0 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/project-groups/[uuid]/page-cf8ff072a8bc7409.js +0 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/dashboard/page-00d18e26961cee2f.js +0 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/documents/[documentUuid]/page-9ed4d7d4f5897de0.js +0 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/documents/page-9d6d86299f2fadd9.js +0 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/[proposalUuid]/page-b18a2aba2c4f4f1c.js +0 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/new/page-32149a823e7abf42.js +0 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/page-0ac33f9146fc53c5.js +0 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/settings/page-ba19aec7fde5086c.js +0 -1
- package/.next/standalone/.next/static/chunks/app/admin/companies/[uuid]/page-56118c51122ad639.js +0 -1
- package/.next/standalone/.next/static/chunks/app/admin/companies/new/page-4e20deb41357171c.js +0 -1
- package/.next/standalone/.next/static/chunks/app/login/admin/page-c8e40259e5d3d9e0.js +0 -1
- package/.next/standalone/.next/static/chunks/app/login/page-0a16a64855b771ef.js +0 -1
- package/.next/standalone/.next/static/css/652fcc1f1ab231c8.css +0 -1
- /package/.next/standalone/.next/static/{AWk31w7ryFKaxOnUlIeo2 → kDppeym4sfPwXjGFspZG8}/_buildManifest.js +0 -0
- /package/.next/standalone/.next/static/{AWk31w7ryFKaxOnUlIeo2 → kDppeym4sfPwXjGFspZG8}/_ssgManifest.js +0 -0
package/cli/codex-spawner.mjs
CHANGED
|
@@ -1,47 +1,23 @@
|
|
|
1
|
-
//
|
|
2
|
-
// Cross-platform headless Codex spawner — the `codex` counterpart to
|
|
3
|
-
// ClaudeSpawner, satisfying the SAME backend-agnostic Spawner.wake(...) contract
|
|
4
|
-
// so the daemon's wake pipeline (queue, waker, directed delivery, headless guard,
|
|
5
|
-
// reporters) stays backend-neutral.
|
|
6
|
-
//
|
|
7
|
-
// Codex diverges structurally from Claude (verified against codex-cli 0.142.3 +
|
|
8
|
-
// the ../codex source + a live `codex exec --json` run):
|
|
9
|
-
// • `codex exec --json` emits JSONL (one event per line); the prompt is read
|
|
10
|
-
// from STDIN (never argv). `codex exec resume <id> --json` continues a run.
|
|
11
|
-
// • The FIRST event is `{"type":"thread.started","thread_id":"<uuid>"}` — Codex
|
|
12
|
-
// GENERATES its own id (it does NOT accept a client `--session-id`). We capture
|
|
13
|
-
// it and persist anchor→thread_id (codex-session-map.mjs) so a later wake can
|
|
14
|
-
// `resume <thread_id>`. (serde: ThreadEvent tag="type", rename="thread.started";
|
|
15
|
-
// ThreadStartedEvent.thread_id: String — codex-rs/exec/src/exec_events.rs.)
|
|
16
|
-
// • No `--mcp-config`: Codex reads MCP servers from the user's ~/.codex/config.toml.
|
|
17
|
-
// `chorus agents add` writes [mcp_servers.chorus] with bearer_token_env_var =
|
|
18
|
-
// "CHORUS_API_KEY" — a KEYLESS reference (no literal key in config.toml), and Codex
|
|
19
|
-
// resolves that env var into `Authorization: Bearer <key>` at connect. So the
|
|
20
|
-
// CHORUS_API_KEY the daemon exports into the child env below DOES reach Codex's MCP
|
|
21
|
-
// auth (as well as the plugin's shell tooling — chorus-api.sh / SessionStart hooks);
|
|
22
|
-
// never argv. (Multi-agent: two Codex agents with different keys each need their own
|
|
23
|
-
// CODEX_HOME so their config.toml + ~/.codex/.env don't collide.)
|
|
24
|
-
// • Permission is a SANDBOX mode, not a tool allowlist.
|
|
25
|
-
//
|
|
26
|
-
// Reuses claude-spawner's platform-neutral helpers: parseNdjsonChunk (NDJSON
|
|
27
|
-
// stream parse) and the PATH-walk shape of resolveClaudePath.
|
|
28
|
-
|
|
1
|
+
// One isolated Codex App Server stdio connection per daemon wake.
|
|
29
2
|
import { spawn } from "node:child_process";
|
|
30
3
|
import { safeSpawnError } from "./launch-diagnostics.mjs";
|
|
31
|
-
import { validateAgentCliConfig, overlayAgentEnv, getAgentEnv, assertConfiguredShimArgs } from "./agent-cli-config.mjs";
|
|
4
|
+
import { validateAgentCliConfig, codexAppServerArgs, overlayAgentEnv, getAgentEnv, assertConfiguredShimArgs } from "./agent-cli-config.mjs";
|
|
32
5
|
import { readFileSync, statSync } from "node:fs";
|
|
33
6
|
import { homedir } from "node:os";
|
|
34
7
|
import { join, win32 as pathWin32, posix as pathPosix } from "node:path";
|
|
35
|
-
import {
|
|
8
|
+
import { CodexAppServerClient, CodexAppServerError, isHistoryUnavailableError } from "./codex-app-server-client.mjs";
|
|
9
|
+
import { CodexAppServerEvents } from "./codex-app-server-events.mjs";
|
|
10
|
+
import { registerProcessStopHook } from "./process-stop-hooks.mjs";
|
|
11
|
+
import { killProcessTree } from "./process-killer.mjs";
|
|
36
12
|
import { awaitChildSettled } from "./child-exit.mjs";
|
|
37
13
|
import { getThreadId as defaultGetThreadId, setThreadId as defaultSetThreadId } from "./codex-session-map.mjs";
|
|
38
14
|
import {
|
|
39
15
|
getCodexUsageSnapshot as defaultGetUsageSnapshot,
|
|
40
|
-
normalizeCodexUsageEvent,
|
|
41
16
|
setCodexUsageSnapshot as defaultSetUsageSnapshot,
|
|
42
17
|
} from "./codex-usage-map.mjs";
|
|
43
18
|
|
|
44
19
|
const NOOP_LOGGER = { info() {}, warn() {}, error() {} };
|
|
20
|
+
const CLIENT_VERSION = JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf8")).version;
|
|
45
21
|
|
|
46
22
|
/**
|
|
47
23
|
* Check whether the user's Codex config declares the Chorus MCP server.
|
|
@@ -75,60 +51,9 @@ export function hasChorusMcpServer(deps = {}) {
|
|
|
75
51
|
* implement it; the daemon injects one based on the resolved agent type.
|
|
76
52
|
*/
|
|
77
53
|
|
|
78
|
-
/**
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
* against codex 0.142.3): the top-level `codex exec` accepts `--sandbox <mode>`,
|
|
82
|
-
* but `codex exec resume` does NOT — passing `--sandbox` there errors with exit 2.
|
|
83
|
-
* yolo → --dangerously-bypass-approvals-and-sandbox (valid on BOTH exec and
|
|
84
|
-
* resume; full autonomy)
|
|
85
|
-
* chorus → exec: --sandbox read-only
|
|
86
|
-
* resume: -c sandbox_mode="read-only" (the `-c` config override is how
|
|
87
|
-
* `codex exec resume` accepts a sandbox mode; `sandbox_mode` is a real
|
|
88
|
-
* config key, value spelled `read-only` per protocol/src/config_types.rs,
|
|
89
|
-
* confirmed via `--strict-config`).
|
|
90
|
-
* Anything other than yolo falls back to the restricted read-only posture.
|
|
91
|
-
* @param {"yolo"|"chorus"|undefined} permissionMode
|
|
92
|
-
* @param {{ resume?: boolean }} [opts] resume:true selects the `codex exec resume` surface.
|
|
93
|
-
* @returns {string[]}
|
|
94
|
-
*/
|
|
95
|
-
export function sandboxFlags(permissionMode, opts = {}) {
|
|
96
|
-
if (permissionMode === "yolo") return ["--dangerously-bypass-approvals-and-sandbox"];
|
|
97
|
-
// restricted read-only posture, expressed per subcommand:
|
|
98
|
-
return opts.resume ? ["-c", 'sandbox_mode="read-only"'] : ["--sandbox", "read-only"];
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
* Build the argv for a headless codex run. Prompt is NEVER here — it goes over
|
|
103
|
-
* stdin. `--skip-git-repo-check` lets a non-repo cwd still run.
|
|
104
|
-
* @param {{ isNew: boolean, threadId?: string|null, permissionMode?: "yolo"|"chorus" }} o
|
|
105
|
-
* @returns {string[]}
|
|
106
|
-
*/
|
|
107
|
-
export function buildCodexArgs({ isNew, threadId, permissionMode }) {
|
|
108
|
-
if (!isNew && threadId) {
|
|
109
|
-
const sandbox = sandboxFlags(permissionMode, { resume: true });
|
|
110
|
-
return ["exec", "resume", threadId, "--json", ...sandbox, "--skip-git-repo-check"];
|
|
111
|
-
}
|
|
112
|
-
const sandbox = sandboxFlags(permissionMode);
|
|
113
|
-
return ["exec", "--json", ...sandbox, "--skip-git-repo-check"];
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
/**
|
|
117
|
-
* Extract the Codex thread id from a stream event, or null. Accepts the live
|
|
118
|
-
* `thread.started` shape (authoritative) and the on-disk rollout `session_meta`
|
|
119
|
-
* shape as a defensive fallback.
|
|
120
|
-
* @param {any} obj
|
|
121
|
-
* @returns {string|null}
|
|
122
|
-
*/
|
|
123
|
-
export function extractThreadId(obj) {
|
|
124
|
-
if (!obj || typeof obj !== "object") return null;
|
|
125
|
-
if (obj.type === "thread.started" && typeof obj.thread_id === "string") {
|
|
126
|
-
return obj.thread_id.trim() || null;
|
|
127
|
-
}
|
|
128
|
-
if (obj.type === "session_meta" && obj.payload && typeof obj.payload.id === "string") {
|
|
129
|
-
return obj.payload.id.trim() || null;
|
|
130
|
-
}
|
|
131
|
-
return null;
|
|
54
|
+
/** App Server transport is daemon-owned; policy is applied by RPC. */
|
|
55
|
+
export function buildCodexArgs({ args = [] } = {}) {
|
|
56
|
+
return ["app-server", "--listen", "stdio://", ...codexAppServerArgs(args)];
|
|
132
57
|
}
|
|
133
58
|
|
|
134
59
|
/**
|
|
@@ -217,182 +142,263 @@ export class CodexSpawner {
|
|
|
217
142
|
this.platform = opts.platform ?? process.platform;
|
|
218
143
|
this.cliConfig = validateAgentCliConfig(opts.cliConfig, "codex", opts.label);
|
|
219
144
|
this.env = overlayAgentEnv(opts.env ?? process.env, this.cliConfig.env, this.platform);
|
|
220
|
-
|
|
221
|
-
this.
|
|
222
|
-
this.
|
|
223
|
-
this.
|
|
145
|
+
const storeLogger = { warn: () => { throw new CodexAppServerError("STORE_IO_ERROR", "Codex local storage failed"); } };
|
|
146
|
+
this.getThreadIdFn = opts.getThreadIdFn ?? ((anchor) => defaultGetThreadId(anchor, { logger: storeLogger }));
|
|
147
|
+
this.setThreadIdFn = opts.setThreadIdFn ?? ((anchor, id) => defaultSetThreadId(anchor, id, { logger: storeLogger }));
|
|
148
|
+
this.getUsageSnapshotFn = opts.getUsageSnapshotFn ?? ((anchor, id) => defaultGetUsageSnapshot(anchor, id, { logger: storeLogger }));
|
|
149
|
+
this.setUsageSnapshotFn = opts.setUsageSnapshotFn ?? ((anchor, id, usage) => defaultSetUsageSnapshot(anchor, id, usage, { logger: storeLogger }));
|
|
224
150
|
this.resolveCodexPathFn = opts.resolveCodexPathFn ?? resolveCodexPath;
|
|
225
151
|
this.hasChorusMcpServerFn = opts.hasChorusMcpServerFn ?? hasChorusMcpServer;
|
|
226
152
|
this.mcpConfigChecked = false;
|
|
153
|
+
this.rpcLimits = opts.rpcLimits;
|
|
154
|
+
this.cleanupTimeoutMs = opts.cleanupTimeoutMs ?? 10_000;
|
|
155
|
+
this.stdioGraceMs = opts.stdioGraceMs ?? 2_000;
|
|
156
|
+
this.maxBufferedBytes = opts.maxBufferedBytes;
|
|
157
|
+
this.killProcessTreeFn = opts.killProcessTreeFn ?? killProcessTree;
|
|
158
|
+
this.killOptions = opts.killOptions ?? {};
|
|
227
159
|
}
|
|
228
160
|
|
|
229
|
-
/**
|
|
230
|
-
|
|
231
|
-
* written to stdin (never argv). `sessionId` is the Chorus anchor (direct idea
|
|
232
|
-
* uuid, or entity uuid). Codex owns its session id, so we IGNORE the passed
|
|
233
|
-
* `isNew`/`mcpConfigPath` and decide new-vs-resume from the persisted
|
|
234
|
-
* anchor→thread_id map: a recorded thread id → `resume`, otherwise a fresh run.
|
|
235
|
-
*
|
|
236
|
-
* @param {{ prompt: string, sessionId: string|null, isNew?: boolean, mcpConfigPath?: string,
|
|
237
|
-
* cwd?: string, onMessage?: (obj: any) => void,
|
|
238
|
-
* onChild?: (child: import("node:child_process").ChildProcess) => void }} params
|
|
239
|
-
* @returns {Promise<{ sessionId: string, backendSessionId: string|null, exitCode: number|null, isNew: boolean }>}
|
|
240
|
-
*/
|
|
241
|
-
async wake({ prompt, sessionId, cwd, onMessage, onChild }) {
|
|
161
|
+
/** One real stdio child and one authoritative turn per wake. */
|
|
162
|
+
async wake({ prompt, sessionId, cwd = process.cwd(), onMessage, onChild }) {
|
|
242
163
|
const anchor = typeof sessionId === "string" ? sessionId : "";
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
let
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
const
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
164
|
+
let threadId = null;
|
|
165
|
+
let isNew = true;
|
|
166
|
+
let child, client, adapter, unsubscribe, unregister, onProcessError;
|
|
167
|
+
let cancelled = false;
|
|
168
|
+
let stopWork;
|
|
169
|
+
let stopDeadline;
|
|
170
|
+
let rawSettled;
|
|
171
|
+
let rawDone = false;
|
|
172
|
+
let rawCode = null;
|
|
173
|
+
let wakeFault = null;
|
|
174
|
+
const fault = (code) => new CodexAppServerError(code, `Codex App Server: ${code}`);
|
|
175
|
+
// Diagnostic text is fixed, never provider errors, callbacks, paths or values.
|
|
176
|
+
const log = (level, text) => { try { this.logger[level]?.(text); } catch {} };
|
|
177
|
+
const result = (exitCode) => ({ sessionId: anchor, backendSessionId: threadId, exitCode, isNew });
|
|
178
|
+
const ensureRunning = () => {
|
|
179
|
+
if (cancelled) throw fault("CANCELLED");
|
|
180
|
+
if (client?.closed) throw client.error;
|
|
181
|
+
};
|
|
182
|
+
try {
|
|
183
|
+
try { threadId = anchor ? this.getThreadIdFn(anchor) : null; }
|
|
184
|
+
catch {
|
|
185
|
+
threadId = null;
|
|
186
|
+
log("warn", "[Chorus] Codex session mapping could not be read; starting a fresh thread with Chorus context.");
|
|
187
|
+
}
|
|
188
|
+
isNew = !threadId;
|
|
189
|
+
const previousThreadId = threadId;
|
|
190
|
+
const previousUsage = threadId ? this.getUsageSnapshotFn(anchor, threadId) : null;
|
|
191
|
+
let activeSetup = null;
|
|
192
|
+
const captureThread = (id) => {
|
|
193
|
+
activeSetup.observedId = id;
|
|
194
|
+
isNew = activeSetup.method === "thread/start";
|
|
195
|
+
// Latch before best-effort IO so duplicate notifications/responses never
|
|
196
|
+
// retry a failed write or lose the in-memory identity on interruption.
|
|
197
|
+
if (threadId === id) return;
|
|
198
|
+
threadId = id;
|
|
199
|
+
if (anchor) {
|
|
200
|
+
try { this.setThreadIdFn(anchor, id); }
|
|
201
|
+
catch {
|
|
202
|
+
log("warn", "[Chorus] Codex session mapping could not be saved; continuing this thread, but future wake continuity may be reduced.");
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
};
|
|
206
|
+
const establishThread = async (method, params) => {
|
|
207
|
+
activeSetup = { method, expectedId: params.threadId, observedId: null };
|
|
208
|
+
try {
|
|
209
|
+
const established = await client.request(method, params);
|
|
210
|
+
const id = established?.thread?.id;
|
|
211
|
+
if (typeof id !== "string" || !id.trim()) throw fault("INVALID_THREAD_ID");
|
|
212
|
+
if (activeSetup.expectedId && id !== activeSetup.expectedId) throw fault("MISMATCHED_THREAD_ID");
|
|
213
|
+
if (activeSetup.observedId && activeSetup.observedId !== id) throw fault("MISMATCHED_THREAD_ID");
|
|
214
|
+
// Keep a response already received even if cancellation won this await.
|
|
215
|
+
captureThread(id);
|
|
216
|
+
} finally { activeSetup = null; }
|
|
217
|
+
};
|
|
218
|
+
const codexPath = this.codexPath ?? this.resolveCodexPathFn({ env: this.env, platform: this.platform });
|
|
219
|
+
if (!codexPath) throw fault("EXECUTABLE_MISSING");
|
|
220
|
+
if (!this.mcpConfigChecked) {
|
|
221
|
+
this.mcpConfigChecked = true;
|
|
222
|
+
if (!this.hasChorusMcpServerFn({ env: this.env, platform: this.platform }))
|
|
223
|
+
log("warn", "[Chorus] Codex config has no [mcp_servers.chorus] entry; wake will continue without Chorus MCP tools");
|
|
224
|
+
}
|
|
225
|
+
try { assertConfiguredShimArgs(codexPath, this.cliConfig.args, this.platform); }
|
|
226
|
+
catch {
|
|
227
|
+
log("error", "[Chorus] Codex Windows shim cannot safely carry configured arguments; configure a native executable.");
|
|
228
|
+
throw fault("UNSAFE_WINDOWS_SHIM_ARGS");
|
|
229
|
+
}
|
|
230
|
+
let args;
|
|
231
|
+
try { args = buildCodexArgs({ args: this.cliConfig.args }); }
|
|
232
|
+
catch { throw fault("UNSUPPORTED_DAEMON_ARGS"); }
|
|
233
|
+
const { command, argv } = resolveSpawnCommand(codexPath, args, this.platform, this.env);
|
|
234
|
+
const childEnv = { ...this.env, CHORUS_DAEMON_HEADLESS: "1" };
|
|
235
|
+
if (this.creds) {
|
|
236
|
+
if (this.creds.url) childEnv.CHORUS_URL = this.creds.url;
|
|
237
|
+
if (this.creds.apiKey) childEnv.CHORUS_API_KEY = this.creds.apiKey;
|
|
238
|
+
if (this.creds.agentUuid || this.creds.agentName)
|
|
239
|
+
childEnv.CHORUS_AGENT_PROFILE = this.creds.agentUuid || this.creds.agentName;
|
|
269
240
|
}
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
assertConfiguredShimArgs(codexPath, this.cliConfig.args, this.platform);
|
|
273
|
-
const args = [...buildCodexArgs({ isNew, threadId: knownThreadId, permissionMode: this.permissionMode }), ...this.cliConfig.args,
|
|
274
|
-
...(this.cliConfig.args.length ? ["-"] : [])];
|
|
275
|
-
const { command, argv } = resolveSpawnCommand(codexPath, args, this.platform, this.env);
|
|
276
|
-
|
|
277
|
-
// POSIX: detached process group so the interrupt path can group-kill the tree
|
|
278
|
-
// (codex exec forks child shells for tools). Windows uses taskkill /T. stdio
|
|
279
|
-
// stays piped — prompt over stdin + NDJSON stdout parse are unaffected.
|
|
280
|
-
const detached = this.platform !== "win32";
|
|
281
|
-
|
|
282
|
-
// Export the daemon's resolved connection pair for both Codex MCP auth and
|
|
283
|
-
// SessionStart hooks. Explicitly overwrite inherited values so the hook and
|
|
284
|
-
// daemon cannot disagree about which Chorus instance this wake belongs to.
|
|
285
|
-
const childEnv = { ...this.env, CHORUS_DAEMON_HEADLESS: "1" };
|
|
286
|
-
if (this.creds) {
|
|
287
|
-
if (this.creds.url) childEnv.CHORUS_URL = this.creds.url;
|
|
288
|
-
if (this.creds.apiKey) childEnv.CHORUS_API_KEY = this.creds.apiKey;
|
|
289
|
-
// Identity profile for the woken session — its hooks/skills pass this to
|
|
290
|
-
// `chorus mcp --agent`, which resolves the key from ~/.chorus/daemon.json.
|
|
291
|
-
if (this.creds.agentUuid || this.creds.agentName)
|
|
292
|
-
childEnv.CHORUS_AGENT_PROFILE = this.creds.agentUuid || this.creds.agentName;
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
return new Promise((resolve) => {
|
|
296
|
-
let child;
|
|
297
241
|
try {
|
|
298
242
|
child = this.spawnImpl(command, argv, {
|
|
299
|
-
cwd:
|
|
300
|
-
|
|
301
|
-
env: childEnv,
|
|
302
|
-
shell: false,
|
|
303
|
-
detached,
|
|
304
|
-
windowsHide: true,
|
|
243
|
+
cwd, stdio: ["pipe", "pipe", "pipe"], env: childEnv,
|
|
244
|
+
shell: false, detached: this.platform !== "win32", windowsHide: true,
|
|
305
245
|
});
|
|
306
246
|
} catch (error) {
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
return;
|
|
247
|
+
log("error", `[Chorus] Codex startup: ${safeSpawnError(error)}`);
|
|
248
|
+
throw fault("SPAWN_FAILED");
|
|
310
249
|
}
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
250
|
+
onProcessError = (error) => log("error", `[Chorus] Codex process: ${safeSpawnError(error)}`);
|
|
251
|
+
child.on("error", onProcessError);
|
|
252
|
+
rawSettled = awaitChildSettled(child, { logger: this.logger, label: "codex", stdioGraceMs: this.stdioGraceMs })
|
|
253
|
+
.then((code) => { rawDone = true; rawCode = code; return code; });
|
|
254
|
+
client = new CodexAppServerClient(child, {
|
|
255
|
+
limits: this.rpcLimits,
|
|
256
|
+
// CLOSED is emitted only by our explicit close(), including normal
|
|
257
|
+
// completion. Keep real transport faults visible at warning severity.
|
|
258
|
+
onDiagnostic: (text) => log(text === "Codex App Server: CLOSED" ? "info" : "warn", `[Chorus] ${text}`),
|
|
259
|
+
});
|
|
260
|
+
// Subscribe before setup, but don't feed setup/history snapshots to T3.
|
|
261
|
+
unsubscribe = client.subscribe((message) => {
|
|
262
|
+
if (activeSetup && !cancelled && message.method === "thread/started" && !Object.hasOwn(message, "id")) {
|
|
263
|
+
const id = message.params?.thread?.id;
|
|
264
|
+
// This process has only one setup request at a time. A fresh start's
|
|
265
|
+
// first ID is authoritative; resume must match its requested ID, and
|
|
266
|
+
// fallback must not accept a late notification for the old thread.
|
|
267
|
+
if (typeof id === "string" && id.trim()
|
|
268
|
+
&& (!activeSetup.expectedId || id === activeSetup.expectedId)
|
|
269
|
+
&& (activeSetup.method !== "thread/start" || id !== previousThreadId)
|
|
270
|
+
&& (!activeSetup.observedId || id === activeSetup.observedId)) captureThread(id);
|
|
319
271
|
}
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
this.setThreadIdFn(anchor, tid);
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
let delivered = obj;
|
|
341
|
-
if (obj?.type === "turn.completed" && obj.usage) {
|
|
342
|
-
delivered = needsUsageSeed
|
|
343
|
-
? { ...obj, usage: null }
|
|
344
|
-
: normalizeCodexUsageEvent(obj, previousUsage);
|
|
345
|
-
if (anchor && observedThreadId) {
|
|
346
|
-
this.setUsageSnapshotFn(anchor, observedThreadId, obj.usage);
|
|
347
|
-
}
|
|
348
|
-
previousUsage = obj.usage;
|
|
349
|
-
needsUsageSeed = false;
|
|
350
|
-
}
|
|
351
|
-
if (onMessage) {
|
|
272
|
+
adapter?.accept(message);
|
|
273
|
+
});
|
|
274
|
+
unregister = registerProcessStopHook(child, ({ deadline, protocolDeadline = deadline, reason, beforeClose }) => {
|
|
275
|
+
stopDeadline = Math.min(stopDeadline ?? Infinity, deadline);
|
|
276
|
+
if (reason !== "cleanup") cancelled = true;
|
|
277
|
+
if (reason === "cleanup") {
|
|
278
|
+
return (async () => { try { await beforeClose?.(); } finally { client.close(); } })();
|
|
279
|
+
}
|
|
280
|
+
if (stopWork) return stopWork;
|
|
281
|
+
stopWork = (async () => {
|
|
282
|
+
try {
|
|
283
|
+
const turnId = adapter?.turnId ?? adapter?.observedTurnId;
|
|
284
|
+
if (turnId && !adapter.outcome && !client.closed) {
|
|
285
|
+
await client.request("turn/interrupt", { threadId, turnId }, {
|
|
286
|
+
timeoutMs: Math.max(1, protocolDeadline - Date.now()),
|
|
287
|
+
});
|
|
288
|
+
let timer;
|
|
352
289
|
try {
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
290
|
+
await Promise.race([
|
|
291
|
+
adapter.completion, client.failure,
|
|
292
|
+
new Promise((resolve) => { timer = setTimeout(resolve, Math.max(0, protocolDeadline - Date.now())); }),
|
|
293
|
+
]);
|
|
294
|
+
} finally { clearTimeout(timer); }
|
|
357
295
|
}
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
|
|
296
|
+
} finally {
|
|
297
|
+
try { await beforeClose?.(); } finally { client.close(); }
|
|
298
|
+
}
|
|
299
|
+
})();
|
|
300
|
+
return stopWork;
|
|
361
301
|
});
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
if (text) this.logger.warn(`[Chorus] codex stderr: ${text}`);
|
|
302
|
+
try { onChild?.(child); } catch { log("warn", "[Chorus] Codex onChild callback failed"); }
|
|
303
|
+
ensureRunning();
|
|
304
|
+
await client.request("initialize", {
|
|
305
|
+
clientInfo: { name: "chorus", version: CLIENT_VERSION }, capabilities: { experimentalApi: false },
|
|
367
306
|
});
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
307
|
+
ensureRunning();
|
|
308
|
+
await client.notify("initialized");
|
|
309
|
+
ensureRunning();
|
|
310
|
+
const fullAccess = this.permissionMode === "yolo";
|
|
311
|
+
const setup = { cwd, approvalPolicy: "never", sandbox: fullAccess ? "danger-full-access" : "read-only" };
|
|
312
|
+
let fallback = false;
|
|
313
|
+
if (threadId) {
|
|
314
|
+
try {
|
|
315
|
+
await establishThread("thread/resume", { ...setup, threadId, excludeTurns: true });
|
|
316
|
+
} catch (error) {
|
|
317
|
+
ensureRunning();
|
|
318
|
+
if (!isHistoryUnavailableError(error, threadId)) throw error;
|
|
319
|
+
fallback = true;
|
|
320
|
+
await establishThread("thread/start", setup);
|
|
379
321
|
}
|
|
380
|
-
|
|
322
|
+
} else await establishThread("thread/start", setup);
|
|
323
|
+
ensureRunning();
|
|
324
|
+
adapter = new CodexAppServerEvents({
|
|
325
|
+
threadId, isNew, previousUsage: threadId === previousThreadId ? previousUsage : null,
|
|
326
|
+
maxBufferedBytes: this.maxBufferedBytes,
|
|
327
|
+
onMessage: (message) => {
|
|
328
|
+
try { onMessage?.(message); } catch { log("warn", "[Chorus] Codex onMessage callback failed"); }
|
|
329
|
+
},
|
|
330
|
+
onUsageSnapshot: (snapshot) => {
|
|
331
|
+
if (anchor) this.setUsageSnapshotFn(anchor, threadId, snapshot);
|
|
332
|
+
},
|
|
381
333
|
});
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
334
|
+
if (fallback) {
|
|
335
|
+
const notice = "Previous Codex history could not be restored; continuing in a new thread with Chorus context.";
|
|
336
|
+
// Native IDs are UUIDs. Do not echo arbitrary provider-controlled strings.
|
|
337
|
+
const displayId = (id) => /^[0-9a-f]{8}(?:-[0-9a-f]{4}){3}-[0-9a-f]{12}$/i.test(id)
|
|
338
|
+
? id : "(unavailable)";
|
|
339
|
+
log("warn", `[Chorus] ${notice} Old thread: ${displayId(previousThreadId)}; new thread: ${displayId(threadId)}.`);
|
|
340
|
+
adapter.notice(notice);
|
|
341
|
+
}
|
|
342
|
+
ensureRunning();
|
|
343
|
+
const started = await client.request("turn/start", {
|
|
344
|
+
threadId, cwd, approvalPolicy: "never",
|
|
345
|
+
sandboxPolicy: fullAccess ? { type: "dangerFullAccess" } : { type: "readOnly", networkAccess: false },
|
|
346
|
+
input: [{ type: "text", text: prompt, text_elements: [] }],
|
|
387
347
|
});
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
348
|
+
adapter.confirmTurn(started?.turn?.id);
|
|
349
|
+
await Promise.race([
|
|
350
|
+
adapter.completion,
|
|
351
|
+
client.failure.then((error) => {
|
|
352
|
+
if (adapter.outcome && ["CLOSED", "EOF"].includes(error.code)) return;
|
|
353
|
+
throw error;
|
|
354
|
+
}),
|
|
355
|
+
rawSettled.then(() => { if (!adapter.outcome) throw fault("MISSING_TERMINAL"); }),
|
|
356
|
+
]);
|
|
357
|
+
} catch (error) {
|
|
358
|
+
wakeFault = error;
|
|
359
|
+
const code = error instanceof CodexAppServerError ? error.code : "SETUP_OR_STORE_ERROR";
|
|
360
|
+
log("error", `[Chorus] Codex App Server wake failed (${code}); check Codex 0.157.1+ installation, login, model/config and local session storage. Unsupported args must use model or permitted -c settings.`);
|
|
361
|
+
} finally {
|
|
362
|
+
try { adapter?.finish(); } catch {
|
|
363
|
+
wakeFault ??= fault("USAGE_STORE_ERROR");
|
|
364
|
+
log("error", "[Chorus] Codex usage persistence failed; check local session storage.");
|
|
395
365
|
}
|
|
396
|
-
|
|
366
|
+
if (child) {
|
|
367
|
+
// Normal close never marks a user interrupt. Concurrent authorized stops
|
|
368
|
+
// still invoke the registered hook and latch cancellation synchronously.
|
|
369
|
+
const deadline = stopDeadline ?? Date.now() + this.cleanupTimeoutMs;
|
|
370
|
+
try {
|
|
371
|
+
const cleanup = await this.killProcessTreeFn(child, {
|
|
372
|
+
...this.killOptions, platform: this.platform, logger: this.logger,
|
|
373
|
+
sigintTimeoutMs: Math.max(0, deadline - Date.now()), reason: "cleanup",
|
|
374
|
+
});
|
|
375
|
+
if (cleanup?.cleanupFailed) throw fault("CLEANUP_ERROR");
|
|
376
|
+
if (!rawDone && rawSettled) {
|
|
377
|
+
let timer;
|
|
378
|
+
try {
|
|
379
|
+
await Promise.race([rawSettled, new Promise((resolve) => {
|
|
380
|
+
timer = setTimeout(resolve, Math.max(0, deadline - Date.now()));
|
|
381
|
+
})]);
|
|
382
|
+
} finally { clearTimeout(timer); }
|
|
383
|
+
}
|
|
384
|
+
} catch {
|
|
385
|
+
wakeFault ??= fault("CLEANUP_ERROR");
|
|
386
|
+
log("error", "[Chorus] Codex process-tree cleanup failed; check process termination permissions.");
|
|
387
|
+
}
|
|
388
|
+
client?.close();
|
|
389
|
+
// Release descendant-held pipes after the bounded shared drain/cleanup.
|
|
390
|
+
for (const stream of [child.stdin, child.stdout, child.stderr]) stream?.destroy?.();
|
|
391
|
+
}
|
|
392
|
+
unsubscribe?.();
|
|
393
|
+
unregister?.();
|
|
394
|
+
if (onProcessError) child?.removeListener("error", onProcessError);
|
|
395
|
+
}
|
|
396
|
+
// CLOSED/EOF is expected only after a confirmed valid terminal. All other
|
|
397
|
+
// protocol faults stay failures even if completion arrived in the same chunk.
|
|
398
|
+
const transportFault = client?.error && !["CLOSED", "EOF"].includes(client.error.code);
|
|
399
|
+
if (cancelled) return result(130);
|
|
400
|
+
if (wakeFault || transportFault || !adapter?.outcome) return result(null);
|
|
401
|
+
if (adapter.outcome.status !== "completed") return result(1);
|
|
402
|
+
return result(rawDone && rawCode === 0 ? 0 : null);
|
|
397
403
|
}
|
|
398
404
|
}
|
package/cli/init/adapters.mjs
CHANGED
|
@@ -64,8 +64,8 @@ function readJsonSafe(path) {
|
|
|
64
64
|
* @param {{ home?: string, readJson?: (p: string) => any }} [deps]
|
|
65
65
|
* @returns {{ marketplaceRegistered: boolean, pluginInstalled: boolean, version?: string }}
|
|
66
66
|
*/
|
|
67
|
-
export function readClaudeInstallState({ home = homedir(), readJson = readJsonSafe } = {}) {
|
|
68
|
-
const pluginsDir = join(home, ".claude", "plugins");
|
|
67
|
+
export function readClaudeInstallState({ env = process.env, home = env.HOME || env.USERPROFILE || homedir(), readJson = readJsonSafe } = {}) {
|
|
68
|
+
const pluginsDir = join(env.CLAUDE_CONFIG_DIR || join(home, ".claude"), "plugins");
|
|
69
69
|
const installed = readJson(join(pluginsDir, "installed_plugins.json"));
|
|
70
70
|
const markets = readJson(join(pluginsDir, "known_marketplaces.json"));
|
|
71
71
|
|
|
@@ -136,6 +136,7 @@ export function mergeChorusServer(existingText, serverObj) {
|
|
|
136
136
|
* backup?: (path: string) => (string|null),
|
|
137
137
|
* platform?: NodeJS.Platform,
|
|
138
138
|
* log?: (m: string) => void,
|
|
139
|
+
* preserveExistingChorus?: boolean,
|
|
139
140
|
* }} opts
|
|
140
141
|
* @returns {Promise<{ skills: number, reviewerAgents: number, hookScripts: number, kiroDir: string, chorusBinAbs: string }>}
|
|
141
142
|
*/
|
|
@@ -146,6 +147,7 @@ export async function installFileTemplate({
|
|
|
146
147
|
backup,
|
|
147
148
|
platform = process.platform,
|
|
148
149
|
log,
|
|
150
|
+
preserveExistingChorus = false,
|
|
149
151
|
} = {}) {
|
|
150
152
|
const assetBase = normalizeAssetBase(chorusUrl); // throws on bad/empty URL
|
|
151
153
|
const doFetch = fetchImpl ?? globalThis.fetch;
|
|
@@ -216,6 +218,14 @@ export async function installFileTemplate({
|
|
|
216
218
|
}
|
|
217
219
|
serverObj.url = `${assetBase}/api/mcp`;
|
|
218
220
|
|
|
221
|
+
// Validate the destination before dropping any assets. Upgrade preserves an
|
|
222
|
+
// existing Chorus connection too; changing credentials is an agents-add action.
|
|
223
|
+
const mcpJsonPath = join(kiroDir, "settings", "mcp.json");
|
|
224
|
+
const existed = existsSync(mcpJsonPath);
|
|
225
|
+
const existingText = existed ? readFileSync(mcpJsonPath, "utf8") : "";
|
|
226
|
+
const existingServer = existingText.trim() ? JSON.parse(existingText)?.mcpServers?.chorus : undefined;
|
|
227
|
+
const merged = mergeChorusServer(existingText, preserveExistingChorus && existingServer ? existingServer : serverObj);
|
|
228
|
+
|
|
219
229
|
// ---- phase 2: write to disk (every fetch already verified) ----
|
|
220
230
|
for (const [dest, { text, exec }] of files) {
|
|
221
231
|
mkdirSync(dirname(dest), { recursive: true });
|
|
@@ -230,12 +240,9 @@ export async function installFileTemplate({
|
|
|
230
240
|
}
|
|
231
241
|
|
|
232
242
|
// ---- merge the `chorus` MCP server into settings/mcp.json (back up first) ----
|
|
233
|
-
const mcpJsonPath = join(kiroDir, "settings", "mcp.json");
|
|
234
243
|
mkdirSync(dirname(mcpJsonPath), { recursive: true });
|
|
235
|
-
const existed = existsSync(mcpJsonPath);
|
|
236
244
|
if (existed && typeof backup === "function") backup(mcpJsonPath);
|
|
237
|
-
|
|
238
|
-
writeFileSync(mcpJsonPath, mergeChorusServer(existingText, serverObj));
|
|
245
|
+
writeFileSync(mcpJsonPath, merged);
|
|
239
246
|
|
|
240
247
|
log?.(`[chorus agents add] kiro: wrote .kiro/ template into ${kiroDir}`);
|
|
241
248
|
return {
|
|
@@ -135,7 +135,7 @@ export function installCodex(ctx) {
|
|
|
135
135
|
// (agents[0]) — that covers the interactive path where the operator typed the URL at a
|
|
136
136
|
// prompt (credential-seed, order 10, already wrote it there before this step runs).
|
|
137
137
|
let chorusUrl = nonEmpty(ctx.flags?.url) ?? nonEmpty(env.CHORUS_URL);
|
|
138
|
-
if (!chorusUrl) {
|
|
138
|
+
if (!chorusUrl && !ctx.flags?.pluginOnly) {
|
|
139
139
|
try {
|
|
140
140
|
chorusUrl = nonEmpty(resolveCreds(ctx.flags ?? {}, { env }).url);
|
|
141
141
|
} catch {
|
|
@@ -147,6 +147,7 @@ export function installCodex(ctx) {
|
|
|
147
147
|
// form. Idempotent; runs on both fresh install and re-run. Never writes a secret. A missing
|
|
148
148
|
// URL is a non-fatal skip (the plugin surface is still installed). Returns a note suffix.
|
|
149
149
|
const ensureMcp = () => {
|
|
150
|
+
if (ctx.flags?.pluginOnly) return ""; // Upgrade preserves existing connection settings.
|
|
150
151
|
if (!chorusUrl) {
|
|
151
152
|
return " (skipped [mcp_servers.chorus]: no Chorus URL — pass --url or set CHORUS_URL)";
|
|
152
153
|
}
|
|
@@ -648,6 +649,7 @@ export async function installKiro(ctx) {
|
|
|
648
649
|
backup: ctx.backup,
|
|
649
650
|
platform: ctx.platform,
|
|
650
651
|
log: ctx.io?.log,
|
|
652
|
+
preserveExistingChorus: ctx.flags?.pluginOnly === true,
|
|
651
653
|
});
|
|
652
654
|
return out(
|
|
653
655
|
"kiro",
|