@chorus-aidlc/chorus 0.14.2 → 0.14.4
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 +438 -431
- package/.next/standalone/.next/app-path-routes-manifest.json +49 -48
- package/.next/standalone/.next/build-manifest.json +5 -5
- package/.next/standalone/.next/prerender-manifest.json +33 -33
- 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 +2 -2
- 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 +2 -2
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/new/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/new/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/page.js +2 -2
- package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/page.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 +3 -3
- package/.next/standalone/.next/server/app/(dashboard)/projects/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/projects/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/settings/page.js +2 -2
- package/.next/standalone/.next/server/app/(dashboard)/settings/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/(dashboard)/settings/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/_not-found.html +2 -2
- package/.next/standalone/.next/server/app/_not-found.rsc +2 -2
- package/.next/standalone/.next/server/app/admin/companies/[uuid]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/admin/companies/new/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/admin/companies/new.html +2 -2
- package/.next/standalone/.next/server/app/admin/companies/new.rsc +2 -2
- package/.next/standalone/.next/server/app/admin/companies/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/admin/companies.html +2 -2
- package/.next/standalone/.next/server/app/admin/companies.rsc +2 -2
- package/.next/standalone/.next/server/app/admin/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/admin.html +2 -2
- package/.next/standalone/.next/server/app/admin.rsc +2 -2
- package/.next/standalone/.next/server/app/api/admin/companies/[uuid]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/admin/companies/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/admin/login/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/admin/session/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/agent-connections/route_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.js +1 -0
- package/.next/standalone/.next/server/app/api/daemon/connection-heartbeat/route.js.nft.json +1 -0
- package/.next/standalone/.next/server/app/api/daemon/connection-heartbeat/route_client-reference-manifest.js +1 -0
- 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_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.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-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.js +5 -5
- 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]/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/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_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/login/admin.html +2 -2
- package/.next/standalone/.next/server/app/login/admin.rsc +2 -2
- package/.next/standalone/.next/server/app/login/callback/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/login/callback.html +2 -2
- package/.next/standalone/.next/server/app/login/callback.rsc +2 -2
- package/.next/standalone/.next/server/app/login/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/login/pick-workspace/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/login/pick-workspace.html +2 -2
- package/.next/standalone/.next/server/app/login/pick-workspace.rsc +2 -2
- package/.next/standalone/.next/server/app/login.html +2 -2
- package/.next/standalone/.next/server/app/login.rsc +2 -2
- package/.next/standalone/.next/server/app/onboarding/page.js +2 -2
- package/.next/standalone/.next/server/app/onboarding/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/onboarding/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/onboarding.html +2 -2
- package/.next/standalone/.next/server/app/onboarding.rsc +3 -3
- package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/projects.html +2 -2
- package/.next/standalone/.next/server/app/projects.rsc +3 -3
- package/.next/standalone/.next/server/app/settings.html +2 -2
- package/.next/standalone/.next/server/app/settings.rsc +4 -4
- package/.next/standalone/.next/server/app-paths-manifest.json +49 -48
- package/.next/standalone/.next/server/chunks/1114.js +1 -1
- package/.next/standalone/.next/server/chunks/1318.js +1 -1
- package/.next/standalone/.next/server/chunks/1559.js +1 -1
- package/.next/standalone/.next/server/chunks/2004.js +1 -0
- package/.next/standalone/.next/server/chunks/2112.js +1 -0
- package/.next/standalone/.next/server/chunks/{1286.js → 2282.js} +3 -3
- package/.next/standalone/.next/server/chunks/2570.js +2 -2
- package/.next/standalone/.next/server/chunks/2618.js +1 -1
- package/.next/standalone/.next/server/chunks/{6492.js → 2789.js} +2 -2
- 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/4070.js +1 -0
- package/.next/standalone/.next/server/chunks/4827.js +1 -1
- package/.next/standalone/.next/server/chunks/5245.js +1 -1
- package/.next/standalone/.next/server/chunks/6113.js +1 -1
- package/.next/standalone/.next/server/chunks/6207.js +1 -1
- package/.next/standalone/.next/server/chunks/6506.js +2 -2
- package/.next/standalone/.next/server/chunks/679.js +1 -1
- package/.next/standalone/.next/server/chunks/7368.js +1 -1
- package/.next/standalone/.next/server/chunks/7530.js +1 -1
- package/.next/standalone/.next/server/chunks/8540.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/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/WVmgQzimrMNvGtHx6Cqm1/_buildManifest.js +1 -0
- package/.next/standalone/.next/static/chunks/{11595.fbbfc784ff9ee566.js → 11595.c580c5690d176cce.js} +1 -1
- package/.next/standalone/.next/static/chunks/{13867-a95a4555fcb7b13b.js → 14160-7bcee6e9e8bc5233.js} +1 -1
- package/.next/standalone/.next/static/chunks/{32331-87ae9bc7517c7947.js → 18351-2a408c4f57ddb3a7.js} +1 -1
- package/.next/standalone/.next/static/chunks/24870-5b0be64361f5ef70.js +1 -0
- package/.next/standalone/.next/static/chunks/26232-110019cebde19691.js +1 -0
- package/.next/standalone/.next/static/chunks/{33456.b67f1146831e9f2b.js → 33456.c48dc366aa90b234.js} +1 -1
- package/.next/standalone/.next/static/chunks/{37985-e4683195e4ca2519.js → 33806-cb339e86820a87c4.js} +1 -1
- package/.next/standalone/.next/static/chunks/{38526-7ffc4b7351c15bc4.js → 37938-c09acf52d7f85cb4.js} +1 -1
- package/.next/standalone/.next/static/chunks/{4860.3491d748fdde968e.js → 4860.baf6a285246198af.js} +1 -1
- package/.next/standalone/.next/static/chunks/{33277-9926b461045318b3.js → 60178-d6276df1c07d7735.js} +2 -2
- package/.next/standalone/.next/static/chunks/68326-924445654ed47e6f.js +1 -0
- package/.next/standalone/.next/static/chunks/78917-1498676a1ffe5ded.js +1 -0
- package/.next/standalone/.next/static/chunks/94470-1076452151689267.js +1 -0
- package/.next/standalone/.next/static/chunks/94643-7c7f2efab0640658.js +1 -0
- package/.next/standalone/.next/static/chunks/{99373.827383575665ce2f.js → 99373.ad871bd0bbfc5eb7.js} +1 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/{layout-12d81eedb519461c.js → layout-78259279cf6c6919.js} +1 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/dashboard/[ideaUuid]/page-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/dashboard/{page-996b8a87b4b986f1.js → page-59dcf0ba7ce877ec.js} +1 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/documents/[documentUuid]/page-d6c226fd56b5ebb5.js +1 -0
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/documents/{page-c231207c3674aa54.js → page-2c9d3f4c6e0ff807.js} +1 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/graph/{page-c62c7d7cf9833060.js → page-af35d50848f01875.js} +1 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/[proposalUuid]/page-cb6fdf592863833c.js +1 -0
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/new/page-596d97796dd55e2f.js +1 -0
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/{page-7948aa8db4813091.js → page-ed9415921188b4d3.js} +1 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/tasks/[taskUuid]/{page-8eea1e0cea60758f.js → page-ebf4c28014025b7b.js} +1 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/tasks/{page-658f31ac6a28ec82.js → page-bbde7e85e3388813.js} +1 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/settings/page-e60bc39bf2957f77.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/admin/companies/[uuid]/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/admin/companies/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/admin/login/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/admin/session/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/agent-connections/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/agents/[uuid]/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/agents/[uuid]/sessions/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/agents/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/api-keys/[uuid]/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/api-keys/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/auth/callback/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/auth/check-default/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/auth/company-oidc/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/auth/default-login/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/auth/identify/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/auth/logout/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/auth/me/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/auth/sync-token/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/comments/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/daemon/connection-heartbeat/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/daemon/control/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/daemon/execution-state/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/daemon/executions/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/daemon/pending-turns/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/daemon/report-interrupt/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/daemon/resume/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/daemon/transcript/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/daemon/turn-advance/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/daemon-sessions/[sessionUuid]/instruction/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/daemon-sessions/[sessionUuid]/repoint/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/daemon-sessions/[sessionUuid]/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/daemon-sessions/ad-hoc/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/daemon-sessions/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/documents/[uuid]/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/entities/[type]/[uuid]/root-idea/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/events/notifications/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/events/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/health/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/ideas/[uuid]/claim/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/ideas/[uuid]/move/preview/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/ideas/[uuid]/move/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/ideas/[uuid]/parent/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/ideas/[uuid]/release/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/ideas/[uuid]/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/ideas/[uuid]/wake-preview/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/ideas/conversational/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/mcp/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/me/assignments/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/mentionables/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/notifications/[uuid]/archive/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/notifications/[uuid]/read/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/notifications/preferences/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/notifications/read-all/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/notifications/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/notifications/unread-count/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/project-groups/[uuid]/dashboard/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/project-groups/[uuid]/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/project-groups/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/project-visits/pin/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/project-visits/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/project-visits/visit/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/projects/[uuid]/activity/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/projects/[uuid]/available/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/projects/[uuid]/documents/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/projects/[uuid]/group/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/projects/[uuid]/ideas/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/projects/[uuid]/ideas/tracker/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/projects/[uuid]/proposals/[proposalUuid]/validate/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/projects/[uuid]/proposals/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/projects/[uuid]/proposals/summary/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/projects/[uuid]/resource-graph/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/projects/[uuid]/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/projects/[uuid]/stats/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/projects/[uuid]/tasks/dependencies/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/projects/[uuid]/tasks/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/projects/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/proposals/[uuid]/approve/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/proposals/[uuid]/close/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/proposals/[uuid]/reject/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/proposals/[uuid]/revoke/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/proposals/[uuid]/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/references/[uuid]/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/references/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/search/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/session/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/sessions/[uuid]/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/tasks/[uuid]/claim/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/tasks/[uuid]/dependencies/[dependsOnUuid]/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/tasks/[uuid]/dependencies/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/tasks/[uuid]/release/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/tasks/[uuid]/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/api/tasks/[uuid]/sessions/route-8cf720e8efb6ac7d.js +1 -0
- package/.next/standalone/.next/static/chunks/app/onboarding/{page-b178eb3215360d91.js → page-006bf9e9d6a991f1.js} +1 -1
- package/.next/standalone/.next/static/chunks/{webpack-567d9ffe31a0a5ee.js → webpack-af2cb28ef7bbd7c2.js} +1 -1
- package/.next/standalone/.next/static/css/f46eab37c942ff33.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/on-post-verify-task.sh +1 -1
- package/.next/standalone/public/chorus-plugin/bin/verify-document-roundtrip.sh +28 -0
- 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/develop/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 +8 -4
- package/.next/standalone/public/chorus-plugin/skills/proposal/SKILL.md +1 -1
- package/.next/standalone/public/chorus-plugin/skills/quick-dev/SKILL.md +1 -1
- package/.next/standalone/public/chorus-plugin/skills/review/SKILL.md +1 -1
- package/.next/standalone/public/chorus-plugin/skills/yolo/SKILL.md +1 -1
- package/.next/standalone/public/install-kiro.sh +1 -1
- package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-brainstorm/SKILL.md +1 -1
- package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-develop/SKILL.md +1 -1
- package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-idea/SKILL.md +1 -1
- package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-openspec-aware/SKILL.md +8 -4
- package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-proposal/SKILL.md +1 -1
- package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-quick-dev/SKILL.md +1 -1
- package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-review/SKILL.md +1 -1
- package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-yolo/SKILL.md +1 -1
- package/.next/standalone/public/kiro-plugin/bin/chorus-api.sh +1 -1
- package/.next/standalone/public/kiro-plugin/bin/verify-document-roundtrip.sh +28 -0
- package/.next/standalone/public/skill/brainstorm-chorus/SKILL.md +1 -1
- package/.next/standalone/public/skill/chorus/SKILL.md +1 -1
- package/.next/standalone/public/skill/code-reviewer-chorus/SKILL.md +1 -1
- package/.next/standalone/public/skill/develop-chorus/SKILL.md +1 -1
- package/.next/standalone/public/skill/idea-chorus/SKILL.md +1 -1
- package/.next/standalone/public/skill/package.json +1 -1
- package/.next/standalone/public/skill/proposal-chorus/SKILL.md +1 -1
- package/.next/standalone/public/skill/proposal-reviewer-chorus/SKILL.md +1 -1
- package/.next/standalone/public/skill/quick-dev-chorus/SKILL.md +1 -1
- package/.next/standalone/public/skill/review-chorus/SKILL.md +1 -1
- package/.next/standalone/public/skill/task-reviewer-chorus/SKILL.md +1 -1
- package/.next/standalone/public/skill/yolo-chorus/SKILL.md +1 -1
- package/README.md +2 -0
- package/cli/claude-spawner.mjs +4 -0
- package/cli/client-args.mjs +15 -8
- package/cli/codex-spawner.mjs +41 -10
- package/cli/codex-usage-map.mjs +115 -0
- package/cli/daemon-agent.mjs +56 -6
- package/cli/daemon-install-config.mjs +129 -0
- package/cli/daemon-rest-client.mjs +34 -3
- package/cli/daemon.mjs +32 -1
- package/cli/sse-listener.mjs +82 -5
- package/cli/turn-reporter.mjs +17 -5
- package/cli/upload-hooks.mjs +337 -12
- package/cli/waker.mjs +68 -13
- package/package.json +1 -1
- package/prisma/migrations/20260723014810_add_turn_relay_error/migration.sql +2 -0
- package/prisma/migrations/20260724031955_add_turn_token_usage/migration.sql +6 -0
- package/prisma/migrations/20260724082248_add_session_cache_rollup/migration.sql +3 -0
- package/prisma/schema.prisma +27 -0
- package/.next/standalone/.next/server/chunks/1173.js +0 -1
- package/.next/standalone/.next/server/chunks/3407.js +0 -1
- package/.next/standalone/.next/server/chunks/595.js +0 -1
- package/.next/standalone/.next/server/chunks/7762.js +0 -1
- package/.next/standalone/.next/static/XTQkt8fOQEK4mZkZTFQ_E/_buildManifest.js +0 -1
- package/.next/standalone/.next/static/chunks/24537-7d71bf10329d1be1.js +0 -1
- package/.next/standalone/.next/static/chunks/27030-19cd50b9d47b3be6.js +0 -1
- package/.next/standalone/.next/static/chunks/28680-f9c5e04f67982cb6.js +0 -1
- package/.next/standalone/.next/static/chunks/73510-c338cef00ca3cfaf.js +0 -1
- package/.next/standalone/.next/static/chunks/78917-a297b76c6daa9f5d.js +0 -1
- package/.next/standalone/.next/static/chunks/84219-09970ab1b85c61f0.js +0 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/dashboard/[ideaUuid]/page-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/documents/[documentUuid]/page-77771ef395e19922.js +0 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/[proposalUuid]/page-d098269dcaa06de7.js +0 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/new/page-7bcaa11ee24b5754.js +0 -1
- package/.next/standalone/.next/static/chunks/app/(dashboard)/settings/page-7fbf5bc58d3dd5b0.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/admin/companies/[uuid]/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/admin/companies/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/admin/login/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/admin/session/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/agent-connections/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/agents/[uuid]/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/agents/[uuid]/sessions/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/agents/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/api-keys/[uuid]/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/api-keys/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/auth/callback/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/auth/check-default/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/auth/company-oidc/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/auth/default-login/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/auth/identify/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/auth/logout/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/auth/me/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/auth/sync-token/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/comments/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/daemon/control/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/daemon/execution-state/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/daemon/executions/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/daemon/pending-turns/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/daemon/report-interrupt/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/daemon/resume/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/daemon/transcript/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/daemon/turn-advance/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/daemon-sessions/[sessionUuid]/instruction/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/daemon-sessions/[sessionUuid]/repoint/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/daemon-sessions/[sessionUuid]/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/daemon-sessions/ad-hoc/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/daemon-sessions/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/documents/[uuid]/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/entities/[type]/[uuid]/root-idea/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/events/notifications/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/events/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/health/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/ideas/[uuid]/claim/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/ideas/[uuid]/move/preview/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/ideas/[uuid]/move/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/ideas/[uuid]/parent/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/ideas/[uuid]/release/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/ideas/[uuid]/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/ideas/[uuid]/wake-preview/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/ideas/conversational/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/mcp/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/me/assignments/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/mentionables/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/notifications/[uuid]/archive/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/notifications/[uuid]/read/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/notifications/preferences/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/notifications/read-all/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/notifications/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/notifications/unread-count/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/project-groups/[uuid]/dashboard/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/project-groups/[uuid]/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/project-groups/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/project-visits/pin/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/project-visits/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/project-visits/visit/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/projects/[uuid]/activity/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/projects/[uuid]/available/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/projects/[uuid]/documents/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/projects/[uuid]/group/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/projects/[uuid]/ideas/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/projects/[uuid]/ideas/tracker/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/projects/[uuid]/proposals/[proposalUuid]/validate/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/projects/[uuid]/proposals/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/projects/[uuid]/proposals/summary/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/projects/[uuid]/resource-graph/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/projects/[uuid]/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/projects/[uuid]/stats/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/projects/[uuid]/tasks/dependencies/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/projects/[uuid]/tasks/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/projects/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/proposals/[uuid]/approve/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/proposals/[uuid]/close/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/proposals/[uuid]/reject/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/proposals/[uuid]/revoke/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/proposals/[uuid]/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/references/[uuid]/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/references/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/search/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/session/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/sessions/[uuid]/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/tasks/[uuid]/claim/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/tasks/[uuid]/dependencies/[dependsOnUuid]/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/tasks/[uuid]/dependencies/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/tasks/[uuid]/release/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/tasks/[uuid]/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/chunks/app/api/tasks/[uuid]/sessions/route-d1c49cfe592deeb8.js +0 -1
- package/.next/standalone/.next/static/css/617133917710c831.css +0 -1
- /package/.next/standalone/.next/static/{XTQkt8fOQEK4mZkZTFQ_E → WVmgQzimrMNvGtHx6Cqm1}/_ssgManifest.js +0 -0
package/cli/upload-hooks.mjs
CHANGED
|
@@ -42,6 +42,21 @@ const NOOP_LOGGER = { info() {}, warn() {}, error() {} };
|
|
|
42
42
|
* @property {(info: { host: string, agentUuid?: string }) => Promise<void>} onConnect
|
|
43
43
|
* @property {(info: { rootIdeaKey: string, sessionId: string, isNew: boolean }) => Promise<void>} onSessionStart
|
|
44
44
|
* @property {(info: { rootIdeaKey: string, sessionId: string, message: any }) => Promise<void>} onTranscriptMessage
|
|
45
|
+
* @property {(info: { sessionId: string }) => Promise<{ relayError: string|null, usage: TokenUsage|null }>} [onSessionEnd]
|
|
46
|
+
* Fire-and-forget + await-able: the wake's subprocess has exited. FLUSH any buffered
|
|
47
|
+
* (debounced) transcript for the session NOW and await it, so a turn's trailing
|
|
48
|
+
* user/assistant text is persisted BEFORE the waker advances the turn to a terminal
|
|
49
|
+
* status (fix #444 — transcript-relay flush-on-exit). Best-effort + non-throwing.
|
|
50
|
+
* RETURNS `{ relayError, usage }`:
|
|
51
|
+
* • `relayError` — the final terminal upload failure reason for this session (retry
|
|
52
|
+
* exhausted / non-2xx / network) when the reply was produced but never reached
|
|
53
|
+
* Chorus, else `null` (a later success clears it). The waker forwards it onto the
|
|
54
|
+
* exit-path turn-advance so the UI can say "reply couldn't be uploaded (reason)"
|
|
55
|
+
* rather than the misleading "no reply received".
|
|
56
|
+
* • `usage` — the turn's authoritative per-turn {@link TokenUsage} (daemon-token-usage),
|
|
57
|
+
* or `null` when the run emitted no `result` frame. The waker forwards it onto the
|
|
58
|
+
* same terminal turn-advance so the server persists it.
|
|
59
|
+
* No-op (`{ relayError: null, usage: null }`) in the noop hooks and the execution-only hooks.
|
|
45
60
|
* @property {() => void} [onExecutionChange] Fire-and-forget: upload a fresh
|
|
46
61
|
* execution snapshot. The waker calls this on every lifecycle transition
|
|
47
62
|
* (enqueue / wake start / wake finish). No-op in the noop hooks.
|
|
@@ -58,6 +73,9 @@ export function createNoopUploadHooks() {
|
|
|
58
73
|
async onConnect() {},
|
|
59
74
|
async onSessionStart() {},
|
|
60
75
|
async onTranscriptMessage() {},
|
|
76
|
+
async onSessionEnd() {
|
|
77
|
+
return { relayError: null, usage: null };
|
|
78
|
+
},
|
|
61
79
|
onExecutionChange() {},
|
|
62
80
|
};
|
|
63
81
|
}
|
|
@@ -87,6 +105,7 @@ export function mergeUploadHooks(...args) {
|
|
|
87
105
|
typeof a.onConnect === "function" ||
|
|
88
106
|
typeof a.onSessionStart === "function" ||
|
|
89
107
|
typeof a.onTranscriptMessage === "function" ||
|
|
108
|
+
typeof a.onSessionEnd === "function" ||
|
|
90
109
|
typeof a.onExecutionChange === "function";
|
|
91
110
|
if (!looksLikeHooks && a.logger) {
|
|
92
111
|
logger = a.logger;
|
|
@@ -96,23 +115,46 @@ export function mergeUploadHooks(...args) {
|
|
|
96
115
|
}
|
|
97
116
|
|
|
98
117
|
async function fanOutAsync(name, info) {
|
|
99
|
-
await Promise.all(
|
|
118
|
+
const results = await Promise.all(
|
|
100
119
|
sets.map(async (s) => {
|
|
101
120
|
const fn = s[name];
|
|
102
|
-
if (typeof fn !== "function") return;
|
|
121
|
+
if (typeof fn !== "function") return undefined;
|
|
103
122
|
try {
|
|
104
|
-
await fn.call(s, info);
|
|
123
|
+
return await fn.call(s, info);
|
|
105
124
|
} catch (err) {
|
|
106
125
|
logger.warn(`[Chorus] ${name} hook failed: ${err}`);
|
|
126
|
+
return undefined;
|
|
107
127
|
}
|
|
108
128
|
})
|
|
109
129
|
);
|
|
130
|
+
return results;
|
|
110
131
|
}
|
|
111
132
|
|
|
112
133
|
return {
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
134
|
+
// The void-returning hooks discard the internal results array (they resolve to
|
|
135
|
+
// `undefined`, matching the single-hook contract — nothing downstream reads them).
|
|
136
|
+
onConnect: async (info) => {
|
|
137
|
+
await fanOutAsync("onConnect", info);
|
|
138
|
+
},
|
|
139
|
+
onSessionStart: async (info) => {
|
|
140
|
+
await fanOutAsync("onSessionStart", info);
|
|
141
|
+
},
|
|
142
|
+
onTranscriptMessage: async (info) => {
|
|
143
|
+
await fanOutAsync("onTranscriptMessage", info);
|
|
144
|
+
},
|
|
145
|
+
// Fan out to every set, then AGGREGATE the transcript relay outcome + the token usage:
|
|
146
|
+
// the first set that reports a non-null `relayError` wins, and independently the first
|
|
147
|
+
// that reports a non-null `usage` wins (only the transcript hook produces either; others
|
|
148
|
+
// resolve nulls or undefined). The waker forwards BOTH onto the exit-path turn-advance
|
|
149
|
+
// (fix #444 relay drop + daemon-token-usage). Aggregated independently so one being null
|
|
150
|
+
// never suppresses the other.
|
|
151
|
+
onSessionEnd: async (info) => {
|
|
152
|
+
const results = await fanOutAsync("onSessionEnd", info);
|
|
153
|
+
const relayError =
|
|
154
|
+
results.find((r) => r && r.relayError)?.relayError ?? null;
|
|
155
|
+
const usage = results.find((r) => r && r.usage)?.usage ?? null;
|
|
156
|
+
return { relayError, usage };
|
|
157
|
+
},
|
|
116
158
|
onExecutionChange: () => {
|
|
117
159
|
for (const s of sets) {
|
|
118
160
|
if (typeof s.onExecutionChange !== "function") continue;
|
|
@@ -166,6 +208,161 @@ export function mergeUploadHooks(...args) {
|
|
|
166
208
|
/** Top-level stream-json envelope types that carry a conversation message. */
|
|
167
209
|
const CONVERSATION_TYPES = new Set(["user", "assistant"]);
|
|
168
210
|
|
|
211
|
+
// ─── Per-turn token usage capture (daemon-token-usage) ──────────────────────
|
|
212
|
+
//
|
|
213
|
+
// The normalized token-usage shape carried end-to-end — the SINGLE contract every
|
|
214
|
+
// later agent-backend integration (Codex, OpenClaw, Kiro) normalizes toward. All
|
|
215
|
+
// token fields + `model` are NULLABLE (a backend fills only what it can obtain);
|
|
216
|
+
// `source` is always set so partial data is interpretable. Tokens ONLY — no cost
|
|
217
|
+
// field this slice (the elaboration-locked scope decision).
|
|
218
|
+
//
|
|
219
|
+
/**
|
|
220
|
+
* @typedef {Object} TokenUsage
|
|
221
|
+
* @property {number|null} inputTokens New (non-cache) input tokens.
|
|
222
|
+
* @property {number|null} outputTokens Generated tokens.
|
|
223
|
+
* @property {number|null} cacheCreationTokens Cache-WRITE tokens (Claude only; others null).
|
|
224
|
+
* @property {number|null} cacheReadTokens Cache-READ tokens.
|
|
225
|
+
* @property {string|null} model Model id (canonical where known). NOT read from
|
|
226
|
+
* the `usage` object — Anthropic's usage carries no
|
|
227
|
+
* model key (verified against a live CLI stream).
|
|
228
|
+
* @property {string} source Backend id — always set (e.g. "claude_code").
|
|
229
|
+
*/
|
|
230
|
+
|
|
231
|
+
/** The `source` tag stamped on usage captured from a Claude Code stream. */
|
|
232
|
+
export const CLAUDE_CODE_USAGE_SOURCE = "claude_code";
|
|
233
|
+
|
|
234
|
+
/** The `source` tag stamped on usage captured from a Codex stream. MUST equal the
|
|
235
|
+
* daemon's Codex client type (`"codex"`, per cli/daemon-agent.mjs `backendClientType`)
|
|
236
|
+
* so persisted usage is attributable to the right backend / connection. */
|
|
237
|
+
export const CODEX_USAGE_SOURCE = "codex";
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Coerce a value to a non-negative integer token count, or null. Guards against a
|
|
241
|
+
* CLI that ever emits a string / float / negative — a garbled count becomes null
|
|
242
|
+
* (renders no badge) rather than a bogus number. Never throws.
|
|
243
|
+
* @param {unknown} v
|
|
244
|
+
* @returns {number|null}
|
|
245
|
+
*/
|
|
246
|
+
function toTokenInt(v) {
|
|
247
|
+
if (typeof v !== "number" || !Number.isFinite(v) || v < 0) return null;
|
|
248
|
+
return Math.round(v);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Extract the AUTHORITATIVE per-turn token usage from a Claude Code stream object,
|
|
253
|
+
* or null when the object is not a usage-bearing `result` envelope.
|
|
254
|
+
*
|
|
255
|
+
* Source of truth = the `type:"result"` envelope's `.usage` (verified against a live
|
|
256
|
+
* `claude -p --output-format stream-json --verbose` capture, CLI 2.1.x): it carries
|
|
257
|
+
* the cumulative token counts for the WHOLE turn, so we read THAT and never sum the
|
|
258
|
+
* per-message `assistant.message.usage` frames (double-count avoidance — the
|
|
259
|
+
* elaboration-locked decision). The on-disk JSONL is never consulted (its
|
|
260
|
+
* output_tokens is a known upstream placeholder, anthropics/claude-code#25941).
|
|
261
|
+
*
|
|
262
|
+
* Token field names on `.usage` are canonical snake_case: `input_tokens`,
|
|
263
|
+
* `output_tokens`, `cache_creation_input_tokens`, `cache_read_input_tokens`.
|
|
264
|
+
*
|
|
265
|
+
* MODEL LOCATION (verified, non-obvious): `.usage` carries NO model key, and on a
|
|
266
|
+
* Bedrock-backed run the envelope's top-level `.model` is `null`. The model is only
|
|
267
|
+
* reliably present in the `.modelUsage` map (keyed by model id, each entry exposing a
|
|
268
|
+
* clean `canonicalModel`). We therefore source `model` from: top-level `.model` when a
|
|
269
|
+
* non-empty string, else the `canonicalModel` (or the key) of the first `.modelUsage`
|
|
270
|
+
* entry, else null. Never from `.usage`.
|
|
271
|
+
*
|
|
272
|
+
* Returns null for every non-result frame (system/assistant/user), so the existing
|
|
273
|
+
* `extractTranscriptText` path is completely untouched. Never throws — an unrecognized
|
|
274
|
+
* shape yields null (defensive against CLI drift).
|
|
275
|
+
*
|
|
276
|
+
* @param {any} obj One parsed stream NDJSON object.
|
|
277
|
+
* @returns {TokenUsage | null}
|
|
278
|
+
*/
|
|
279
|
+
export function extractTurnUsage(obj) {
|
|
280
|
+
if (!obj || typeof obj !== "object" || obj.type !== "result") return null;
|
|
281
|
+
const usage = obj.usage;
|
|
282
|
+
if (!usage || typeof usage !== "object") return null;
|
|
283
|
+
|
|
284
|
+
// Model: prefer a non-empty top-level string; else the modelUsage map's canonical
|
|
285
|
+
// name (or its key). Never the `usage` object.
|
|
286
|
+
let model = typeof obj.model === "string" && obj.model.trim() ? obj.model : null;
|
|
287
|
+
if (!model && obj.modelUsage && typeof obj.modelUsage === "object") {
|
|
288
|
+
const keys = Object.keys(obj.modelUsage);
|
|
289
|
+
if (keys.length > 0) {
|
|
290
|
+
const first = obj.modelUsage[keys[0]];
|
|
291
|
+
const canonical =
|
|
292
|
+
first && typeof first === "object" && typeof first.canonicalModel === "string"
|
|
293
|
+
? first.canonicalModel
|
|
294
|
+
: null;
|
|
295
|
+
model = canonical || keys[0] || null;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
return {
|
|
300
|
+
inputTokens: toTokenInt(usage.input_tokens),
|
|
301
|
+
outputTokens: toTokenInt(usage.output_tokens),
|
|
302
|
+
cacheCreationTokens: toTokenInt(usage.cache_creation_input_tokens),
|
|
303
|
+
cacheReadTokens: toTokenInt(usage.cache_read_input_tokens),
|
|
304
|
+
model,
|
|
305
|
+
source: CLAUDE_CODE_USAGE_SOURCE,
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
/**
|
|
310
|
+
* Extract the per-turn token usage from a Codex `codex exec --json` stream object,
|
|
311
|
+
* or null when the object is not a usage-bearing `turn.completed` event. The Codex
|
|
312
|
+
* counterpart to {@link extractTurnUsage} — the two are discriminated purely by the
|
|
313
|
+
* top-level event type (`turn.completed` vs `result`), which are disjoint, so no
|
|
314
|
+
* backend flag is needed (same as `extractTranscriptText`'s dual dialect).
|
|
315
|
+
*
|
|
316
|
+
* Source of truth = the `turn.completed` event's `.usage` (verified against a live
|
|
317
|
+
* `codex exec --json` run on codex-cli 0.145.0 and ../codex/codex-rs/exec/src/exec_events.rs
|
|
318
|
+
* `Usage`). Field names are snake_case: `input_tokens`, `cached_input_tokens`,
|
|
319
|
+
* `cache_write_input_tokens`, `output_tokens`, `reasoning_output_tokens`.
|
|
320
|
+
*
|
|
321
|
+
* Mapping into the shared TokenUsage shape:
|
|
322
|
+
* • inputTokens ← input_tokens
|
|
323
|
+
* • outputTokens ← output_tokens (ALONE — see below; matches Claude, whose
|
|
324
|
+
* output already folds thinking.)
|
|
325
|
+
* • cacheReadTokens ← cached_input_tokens
|
|
326
|
+
* • cacheCreationTokens ← cache_write_input_tokens
|
|
327
|
+
* • model ← null (the Codex --json stream carries no model id on ANY event)
|
|
328
|
+
* • source ← CODEX_USAGE_SOURCE
|
|
329
|
+
*
|
|
330
|
+
* `reasoning_output_tokens` is deliberately NOT added to `output_tokens`: in Codex /
|
|
331
|
+
* the OpenAI Responses API it is a SUBDIVISION *inside* `output_tokens`
|
|
332
|
+
* (`output_tokens_details.reasoning_tokens`), not a separate bucket — adding it would
|
|
333
|
+
* double-count. Verified against ../codex/codex-rs/codex-api/src/sse/responses.rs
|
|
334
|
+
* (`From<ResponseCompletedUsage>` sources reasoning_output_tokens from the output
|
|
335
|
+
* details; its test asserts input:100 + output:10 = total:110 with reasoning:5 inside
|
|
336
|
+
* output) and protocol.rs `blended_total()` = non_cached_input + output_tokens (reasoning
|
|
337
|
+
* is shown only as a parenthetical, never summed).
|
|
338
|
+
*
|
|
339
|
+
* An older codex-cli that omits `cache_write_input_tokens` degrades gracefully (reads
|
|
340
|
+
* null) — no version pin. Every numeric field is `toTokenInt`-guarded (garble → null).
|
|
341
|
+
* Returns null for every non-`turn.completed` frame (item.completed/thread.started/
|
|
342
|
+
* turn.started AND Claude's `result`), so the transcript-text path and the Claude usage
|
|
343
|
+
* path are both untouched. Never throws — an unrecognized shape yields null (defensive
|
|
344
|
+
* against CLI drift).
|
|
345
|
+
*
|
|
346
|
+
* @param {any} obj One parsed stream NDJSON object.
|
|
347
|
+
* @returns {TokenUsage | null}
|
|
348
|
+
*/
|
|
349
|
+
export function extractCodexTurnUsage(obj) {
|
|
350
|
+
if (!obj || typeof obj !== "object" || obj.type !== "turn.completed") return null;
|
|
351
|
+
const usage = obj.usage;
|
|
352
|
+
if (!usage || typeof usage !== "object") return null;
|
|
353
|
+
|
|
354
|
+
return {
|
|
355
|
+
inputTokens: toTokenInt(usage.input_tokens),
|
|
356
|
+
// output_tokens ALREADY includes reasoning_output_tokens (a subdivision, not a
|
|
357
|
+
// separate bucket) — do NOT add reasoning or it double-counts.
|
|
358
|
+
outputTokens: toTokenInt(usage.output_tokens),
|
|
359
|
+
cacheCreationTokens: toTokenInt(usage.cache_write_input_tokens),
|
|
360
|
+
cacheReadTokens: toTokenInt(usage.cached_input_tokens),
|
|
361
|
+
model: null, // Codex stream carries no model id on any event
|
|
362
|
+
source: CODEX_USAGE_SOURCE,
|
|
363
|
+
};
|
|
364
|
+
}
|
|
365
|
+
|
|
169
366
|
/**
|
|
170
367
|
* Remove `<system-reminder>…</system-reminder>` spans from a retained text block
|
|
171
368
|
* (defense-in-depth for harness-injected reminders that ride inside a kept text
|
|
@@ -286,6 +483,15 @@ export function extractTranscriptText(obj) {
|
|
|
286
483
|
* (default 50ms). 0 → flush on the next microtask.
|
|
287
484
|
* setTimeoutImpl?: typeof setTimeout, Injectable timer for tests.
|
|
288
485
|
* clearTimeoutImpl?: typeof clearTimeout,
|
|
486
|
+
* maxUploadAttempts?: number, Bounded retry for a failed transcript POST (transient
|
|
487
|
+
* network error / non-2xx). Total attempts including the
|
|
488
|
+
* first (default 3). ≤1 disables retry. fix #444 — a
|
|
489
|
+
* transient Docker-proxy 502 must not silently drop a turn's
|
|
490
|
+
* transcript.
|
|
491
|
+
* retryBackoffMs?: number, Base backoff between attempts (default 200ms); the Nth
|
|
492
|
+
* retry waits `retryBackoffMs * N`.
|
|
493
|
+
* sleepImpl?: (ms: number) => Promise<void>, Injectable backoff sleep for tests (default
|
|
494
|
+
* a real setTimeout-based delay).
|
|
289
495
|
* }} opts
|
|
290
496
|
* @returns {UploadHooks}
|
|
291
497
|
*/
|
|
@@ -294,6 +500,13 @@ export function createTranscriptUploadHooks(opts) {
|
|
|
294
500
|
const batchDelayMs = opts.batchDelayMs ?? 50;
|
|
295
501
|
const setTimeoutImpl = opts.setTimeoutImpl ?? setTimeout;
|
|
296
502
|
const clearTimeoutImpl = opts.clearTimeoutImpl ?? clearTimeout;
|
|
503
|
+
// Bounded retry for a failed transcript POST (fix #444 — no more silent drops on a
|
|
504
|
+
// transient non-2xx / network blip). Retry lives HERE, in the host-side hook, NOT in
|
|
505
|
+
// the shared daemon-rest-client (which stays a single-shot transport by contract).
|
|
506
|
+
const maxUploadAttempts = Math.max(1, opts.maxUploadAttempts ?? 3);
|
|
507
|
+
const retryBackoffMs = opts.retryBackoffMs ?? 200;
|
|
508
|
+
const sleepImpl =
|
|
509
|
+
opts.sleepImpl ?? ((ms) => new Promise((resolve) => setTimeoutImpl(resolve, ms)));
|
|
297
510
|
// Transport via the shared client (transcript has no connectionUuid concern — the agent
|
|
298
511
|
// key + sessionId resolve the turn server-side, so getConnectionUuid is unused here).
|
|
299
512
|
const client = createDaemonRestClient({
|
|
@@ -303,6 +516,16 @@ export function createTranscriptUploadHooks(opts) {
|
|
|
303
516
|
logger,
|
|
304
517
|
});
|
|
305
518
|
|
|
519
|
+
// NOTE ON SCOPE: this instance's `currentSessionId` / `pending` / `chain` /
|
|
520
|
+
// `lastRelayError` are per-hook-instance, and the daemon builds ONE transcript-hook
|
|
521
|
+
// instance per connection (per cwd) — see daemon.mjs. The per-(agent,session) WakeQueue
|
|
522
|
+
// serializes wakes of the SAME session, but different sessions (root-idea keys) on the
|
|
523
|
+
// same cwd can run concurrently (maxConcurrency). This single-session-batching state
|
|
524
|
+
// therefore assumes at most one ACTIVE session producing transcript at a time on a given
|
|
525
|
+
// cwd, which holds for today's usage (one dispatched conversation per cwd at a time); it
|
|
526
|
+
// is NOT a general guarantee. `lastRelayError` inherits exactly this scope — no stronger,
|
|
527
|
+
// no weaker — so it is only as isolated as the batching state it rides alongside.
|
|
528
|
+
//
|
|
306
529
|
// The session this batch belongs to (set by onSessionStart, and re-affirmed by each
|
|
307
530
|
// message's observed session id from the stream). Messages queued for one session
|
|
308
531
|
// are flushed before the session changes, so they always target the right turn.
|
|
@@ -312,15 +535,59 @@ export function createTranscriptUploadHooks(opts) {
|
|
|
312
535
|
let timer = null;
|
|
313
536
|
// Serialize POSTs so an earlier batch can never land after a later one on the wire.
|
|
314
537
|
let chain = Promise.resolve();
|
|
538
|
+
// The final upload failure reason for the current session's most recent batch, or null
|
|
539
|
+
// when the last upload succeeded/was skipped (fix #444 follow-up). `onSessionEnd`
|
|
540
|
+
// returns this so the waker can annotate the terminal turn with WHY its transcript is
|
|
541
|
+
// missing. Reset in `onSessionStart`; set only when a batch exhausts its retry budget
|
|
542
|
+
// (a transient failure that a later batch recovers is NOT surfaced). Its isolation is
|
|
543
|
+
// exactly the single-active-session scope described above.
|
|
544
|
+
let lastRelayError = null;
|
|
545
|
+
// The most recent per-turn token usage seen on THIS session's stream (daemon-token-usage).
|
|
546
|
+
// Captured from the authoritative `result` envelope in `onTranscriptMessage`; the LAST one
|
|
547
|
+
// wins (a turn emits exactly one result frame, but last-wins is safe either way). Returned
|
|
548
|
+
// by `onSessionEnd` so the waker forwards it onto the terminal turn-advance. Shares EXACTLY
|
|
549
|
+
// the single-active-session scope of `lastRelayError` above — no stronger, no weaker. Reset
|
|
550
|
+
// in `onSessionStart` so a new wake never inherits the prior turn's usage.
|
|
551
|
+
/** @type {TokenUsage|null} */
|
|
552
|
+
let lastUsage = null;
|
|
315
553
|
|
|
316
|
-
/**
|
|
554
|
+
/**
|
|
555
|
+
* POST one batch for a session via the shared client, with bounded retry. Never throws.
|
|
556
|
+
*
|
|
557
|
+
* The client POSTs `{ sessionId, messages }` to /api/daemon/transcript with Bearer auth
|
|
558
|
+
* and returns a structured `{ ok }` result (it logs its own request-failed / non-2xx /
|
|
559
|
+
* success lines). A transient failure (`ok === false`) is retried up to
|
|
560
|
+
* `maxUploadAttempts` total with an increasing backoff; on the final failure the batch
|
|
561
|
+
* is dropped with ONE loud warn naming the lost message count (fix #444 — a Docker-proxy
|
|
562
|
+
* 502 previously dropped the turn's transcript silently on the first try). A `skipped`
|
|
563
|
+
* result (empty batch / no session) is a success no-op, never retried.
|
|
564
|
+
*/
|
|
317
565
|
async function upload(sessionId, messages) {
|
|
318
566
|
if (!sessionId || messages.length === 0) return;
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
567
|
+
for (let attempt = 1; attempt <= maxUploadAttempts; attempt += 1) {
|
|
568
|
+
const result = await client.transcript({ sessionId, messages });
|
|
569
|
+
// ok (2xx) or an intentional skip → done. A success CLEARS any prior relay error
|
|
570
|
+
// (a transient failure that a later batch recovered must not be surfaced as a drop).
|
|
571
|
+
if (!result || result.ok || result.skipped) {
|
|
572
|
+
lastRelayError = null;
|
|
573
|
+
return;
|
|
574
|
+
}
|
|
575
|
+
if (attempt < maxUploadAttempts) {
|
|
576
|
+
// Wait then retry — the client already logged the failure cause for this attempt.
|
|
577
|
+
await sleepImpl(retryBackoffMs * attempt);
|
|
578
|
+
continue;
|
|
579
|
+
}
|
|
580
|
+
// Exhausted the budget: drop LOUDLY (no silent errors), naming what was lost, AND
|
|
581
|
+
// record the reason so `onSessionEnd` can surface it on the turn (fix #444 follow-up).
|
|
582
|
+
// Prefer the client's structured `error` (e.g. "transcript upload returned 502");
|
|
583
|
+
// fall back to a generic phrasing so the field is never an empty string.
|
|
584
|
+
lastRelayError =
|
|
585
|
+
result.error ?? `transcript upload failed for session ${sessionId}`;
|
|
586
|
+
logger.warn(
|
|
587
|
+
`[Chorus] transcript upload gave up after ${maxUploadAttempts} attempt(s) — ` +
|
|
588
|
+
`dropping ${messages.length} message(s) for session ${sessionId}`,
|
|
589
|
+
);
|
|
590
|
+
}
|
|
324
591
|
}
|
|
325
592
|
|
|
326
593
|
/** Drain `pending` for `currentSessionId` into a serialized fire-and-forget POST. */
|
|
@@ -366,6 +633,14 @@ export function createTranscriptUploadHooks(opts) {
|
|
|
366
633
|
// so its messages don't get re-tagged to the new session.
|
|
367
634
|
if (currentSessionId && currentSessionId !== sessionId) flush();
|
|
368
635
|
currentSessionId = sessionId || currentSessionId || null;
|
|
636
|
+
// A new wake starts → clear the previous wake's relay error so a stale drop from an
|
|
637
|
+
// earlier turn isn't re-reported here (fix #444 follow-up). This is sequential-reuse
|
|
638
|
+
// hygiene; it does NOT defend against two sessions overlapping on one hook instance
|
|
639
|
+
// (see the scope note where `lastRelayError` is declared).
|
|
640
|
+
lastRelayError = null;
|
|
641
|
+
// Same hygiene for token usage (daemon-token-usage): a new wake must not inherit the
|
|
642
|
+
// prior turn's usage. Cleared here so a turn that emits NO result frame reports null.
|
|
643
|
+
lastUsage = null;
|
|
369
644
|
},
|
|
370
645
|
/**
|
|
371
646
|
* One stream-json object. Keep only user/assistant text; queue it for a batched
|
|
@@ -376,6 +651,19 @@ export function createTranscriptUploadHooks(opts) {
|
|
|
376
651
|
// The stream stamps the authoritative session id on every line; prefer it so a
|
|
377
652
|
// session resolved only from the stream (not onSessionStart) is still attributed.
|
|
378
653
|
if (sessionId) currentSessionId = sessionId;
|
|
654
|
+
// Capture per-turn token usage from EITHER backend's authoritative usage frame
|
|
655
|
+
// (daemon-token-usage): the Claude Code `result` envelope or the Codex
|
|
656
|
+
// `turn.completed` event. The two extractors are discriminated purely by top-level
|
|
657
|
+
// event type (disjoint), so at most one returns non-null — same dual-dialect pattern
|
|
658
|
+
// as extractTranscriptText. Returns null for every other frame, so this is a cheap
|
|
659
|
+
// no-op on the vast majority of lines and never touches the transcript path. Guarded
|
|
660
|
+
// so a malformed frame can never break transcript relay (no-silent: warn).
|
|
661
|
+
try {
|
|
662
|
+
const usage = extractTurnUsage(message) ?? extractCodexTurnUsage(message);
|
|
663
|
+
if (usage) lastUsage = usage;
|
|
664
|
+
} catch (err) {
|
|
665
|
+
logger.warn(`[Chorus] token usage extract failed: ${err}`);
|
|
666
|
+
}
|
|
379
667
|
let extracted;
|
|
380
668
|
try {
|
|
381
669
|
extracted = extractTranscriptText(message);
|
|
@@ -387,6 +675,43 @@ export function createTranscriptUploadHooks(opts) {
|
|
|
387
675
|
pending.push(extracted);
|
|
388
676
|
scheduleFlush();
|
|
389
677
|
},
|
|
678
|
+
/**
|
|
679
|
+
* The wake's subprocess has exited (fix #444 — flush-on-exit). Cancel the debounce
|
|
680
|
+
* timer, drain the buffered batch onto the serialized chain NOW, and AWAIT the chain
|
|
681
|
+
* so the trailing transcript is persisted BEFORE the waker advances the turn to a
|
|
682
|
+
* terminal status. Awaiting matters: the server attaches transcript to the session's
|
|
683
|
+
* `running` turn, so the flush must land while the turn is still `running`. Best-effort
|
|
684
|
+
* + non-throwing — a flush failure is already logged inside `upload`, and we swallow
|
|
685
|
+
* anything else so a flush error never crashes the wake exit path.
|
|
686
|
+
*
|
|
687
|
+
* `sessionId` (from the caller — the waker's session anchor) re-affirms the batch's
|
|
688
|
+
* attribution in case no stream line ever set `currentSessionId` (e.g. a run that
|
|
689
|
+
* produced only a trailing message right before exit).
|
|
690
|
+
*
|
|
691
|
+
* Returns `{ relayError, usage }`: `relayError` is the final terminal upload failure
|
|
692
|
+
* reason (retry exhausted) after the flush settles, or null when every batch landed
|
|
693
|
+
* (the waker forwards it so a KNOWN relay drop is surfaced rather than misread as "no
|
|
694
|
+
* reply received", fix #444 follow-up). `usage` is the turn's authoritative per-turn
|
|
695
|
+
* token usage captured from the `result` frame, or null when none was seen
|
|
696
|
+
* (daemon-token-usage) — the waker forwards it onto the same terminal turn-advance.
|
|
697
|
+
* @param {{ sessionId?: string }} info
|
|
698
|
+
* @returns {Promise<{ relayError: string|null, usage: TokenUsage|null }>}
|
|
699
|
+
*/
|
|
700
|
+
async onSessionEnd({ sessionId } = {}) {
|
|
701
|
+
if (sessionId) currentSessionId = sessionId;
|
|
702
|
+
try {
|
|
703
|
+
flush();
|
|
704
|
+
// Await the serialized chain so all queued POSTs (this batch + any still in flight)
|
|
705
|
+
// settle before we return. `chain` never rejects (upload swallows), but guard anyway.
|
|
706
|
+
await chain;
|
|
707
|
+
} catch (err) {
|
|
708
|
+
logger.warn(`[Chorus] transcript flush on session end failed: ${err}`);
|
|
709
|
+
}
|
|
710
|
+
// `lastRelayError` reflects the outcome of the FINAL batch's upload (set on retry
|
|
711
|
+
// exhaustion, cleared on success) — read it AFTER the chain settles. `lastUsage` is
|
|
712
|
+
// the turn's authoritative token usage (null if the run emitted no result frame).
|
|
713
|
+
return { relayError: lastRelayError, usage: lastUsage };
|
|
714
|
+
},
|
|
390
715
|
onExecutionChange() {},
|
|
391
716
|
};
|
|
392
717
|
}
|
package/cli/waker.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// cli/waker.mjs
|
|
2
2
|
// Executes a single wake: resolve the event to its idea attribution, derive the
|
|
3
3
|
// deterministic session id (= the DIRECT idea uuid), build the --mcp-config, spawn
|
|
4
|
-
//
|
|
4
|
+
// the configured headless agent, and
|
|
5
5
|
// fire the (no-op) upload hooks. The WakeQueue schedules these per DIRECT idea so
|
|
6
6
|
// two wakes for the same idea never run concurrently against the same session.
|
|
7
7
|
//
|
|
@@ -38,7 +38,7 @@ export class Waker {
|
|
|
38
38
|
* Injectable interrupt reporter (子3). Called when a wake's subprocess exits in
|
|
39
39
|
* an interrupted (user) or crashed (non-zero, no interrupt flag) state. Defaults
|
|
40
40
|
* to a no-op that logs — the daemon wires the REST reporter (interrupt-reporter.mjs).
|
|
41
|
-
* advanceTurn?: (params: { sessionId: string, status: "running"|"ended"|"interrupted", entityType?: string|null, entityUuid?: string|null, interruptedReason?: "user"|"crash"|"shutdown" }) => Promise<void>,
|
|
41
|
+
* advanceTurn?: (params: { sessionId: string, status: "running"|"ended"|"interrupted", entityType?: string|null, entityUuid?: string|null, interruptedReason?: "user"|"crash"|"shutdown", transcriptRelayError?: string|null, usage?: import("./upload-hooks.mjs").TokenUsage|null }) => Promise<void>,
|
|
42
42
|
* Injectable turn-lifecycle reporter (子1 — daemon-session-conversation). Called
|
|
43
43
|
* on spawn (→ running) and on subprocess exit (→ ended on a clean exit, or
|
|
44
44
|
* → interrupted with the classified reason otherwise) to advance the server-side
|
|
@@ -56,7 +56,7 @@ export class Waker {
|
|
|
56
56
|
this.lineage = opts.lineage;
|
|
57
57
|
this.spawner = opts.spawner;
|
|
58
58
|
// Verbose per-wake logging (daemon-startup-output). Default: one compact
|
|
59
|
-
// line per lifecycle event (arrival /
|
|
59
|
+
// line per lifecycle event (arrival / session decision / completion).
|
|
60
60
|
// When true, additional detail is emitted alongside those lines.
|
|
61
61
|
this.verbose = opts.verbose ?? false;
|
|
62
62
|
// The connection/session-bound working directory this Waker serves (T3 — 单
|
|
@@ -385,13 +385,20 @@ export class Waker {
|
|
|
385
385
|
const cwd = this.resolveCwd();
|
|
386
386
|
const isNew = sessionId ? this.isNewSessionFn(sessionId, cwd) : true;
|
|
387
387
|
|
|
388
|
-
//
|
|
389
|
-
//
|
|
390
|
-
//
|
|
391
|
-
this.
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
388
|
+
// Spawners declare whether the shared transcript probe is authoritative
|
|
389
|
+
// for their session decision. Missing metadata preserves the established
|
|
390
|
+
// Claude-compatible logging contract for injected/third-party spawners.
|
|
391
|
+
const sessionDecision = this.spawner.sessionDecision;
|
|
392
|
+
const probeIsAuthoritative = sessionDecision?.probeIsAuthoritative !== false;
|
|
393
|
+
if (probeIsAuthoritative) {
|
|
394
|
+
const takeoverCommand = sessionDecision?.takeoverCommand ?? "claude --resume";
|
|
395
|
+
this.logger.info(
|
|
396
|
+
`[Chorus] ${isNew ? "spawning new" : "resuming"} session ${sessionId ?? "(none)"}` +
|
|
397
|
+
(sessionId && takeoverCommand ? ` — take over with: ${takeoverCommand} ${sessionId}` : "")
|
|
398
|
+
);
|
|
399
|
+
} else {
|
|
400
|
+
this.logger.info(`[Chorus] dispatching session ${sessionId ?? "(none)"}`);
|
|
401
|
+
}
|
|
395
402
|
if (this.verbose) {
|
|
396
403
|
this.logger.info(`[Chorus] cwd=${cwd} action=${notification.action} root=${rootIdeaUuid ?? "(none)"}`);
|
|
397
404
|
}
|
|
@@ -448,6 +455,12 @@ export class Waker {
|
|
|
448
455
|
},
|
|
449
456
|
});
|
|
450
457
|
|
|
458
|
+
if (result && !probeIsAuthoritative) {
|
|
459
|
+
this.logger.info(
|
|
460
|
+
`[Chorus] backend ${result.isNew ? "started new" : "resumed"} session ${result.sessionId ?? sessionId ?? "(none)"}`
|
|
461
|
+
);
|
|
462
|
+
}
|
|
463
|
+
|
|
451
464
|
// No session map to persist anymore — the id is deterministic (= direct idea
|
|
452
465
|
// uuid) and the next wake re-derives new-vs-resume from disk. Just log a
|
|
453
466
|
// non-zero exit visibly (no-silent-errors).
|
|
@@ -469,6 +482,36 @@ export class Waker {
|
|
|
469
482
|
const wasInterrupting = entity && execKey ? this.interrupting.has(execKey) : false;
|
|
470
483
|
const cleanExit = result && result.exitCode === 0;
|
|
471
484
|
|
|
485
|
+
// Transcript flush-on-exit (fix #444): the subprocess has exited, but the transcript
|
|
486
|
+
// hook batches user/assistant text on a short debounce — the LAST batch may still be
|
|
487
|
+
// buffered right now. Flush it and AWAIT it BEFORE advancing the turn to a terminal
|
|
488
|
+
// status, so the trailing reply is persisted while the turn is still `running` (the
|
|
489
|
+
// server attaches transcript to the running turn). Without this, a clean-exiting wake
|
|
490
|
+
// advanced straight to `ended` and the buffered reply was dropped → the "该回合没有
|
|
491
|
+
// 保留对话记录" empty turn in #444. Guarded + non-throwing (onSessionEnd swallows its
|
|
492
|
+
// own failures; this try is belt-and-braces) so a flush error never crashes the wake.
|
|
493
|
+
// `onSessionEnd` returns `{ relayError }` — the final transcript-upload failure
|
|
494
|
+
// reason (retry exhausted / non-2xx / network) when the reply was produced but never
|
|
495
|
+
// reached Chorus, else null. Forwarded onto the terminal turn-advance below so the UI
|
|
496
|
+
// can say "reply couldn't be uploaded (reason)" rather than the misleading "no reply
|
|
497
|
+
// received" (fix #444 follow-up). Guarded — a hook failure never crashes the exit path
|
|
498
|
+
// and simply leaves the annotation absent.
|
|
499
|
+
let transcriptRelayError = null;
|
|
500
|
+
// The turn's authoritative per-turn token usage (daemon-token-usage), captured from
|
|
501
|
+
// the Claude Code `result` frame by the transcript hook and returned alongside
|
|
502
|
+
// relayError from the SAME onSessionEnd call. Forwarded onto the terminal turn-advance
|
|
503
|
+
// below so the server persists it. Null when the run emitted no result frame.
|
|
504
|
+
let turnUsage = null;
|
|
505
|
+
if (sessionId) {
|
|
506
|
+
try {
|
|
507
|
+
const outcome = await this.hooks?.onSessionEnd?.({ sessionId });
|
|
508
|
+
transcriptRelayError = outcome?.relayError ?? null;
|
|
509
|
+
turnUsage = outcome?.usage ?? null;
|
|
510
|
+
} catch (err) {
|
|
511
|
+
this.logger.warn(`[Chorus] onSessionEnd flush failed for ${key}: ${err}`);
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
|
|
472
515
|
// Turn lifecycle: the subprocess has exited — advance the server turn from
|
|
473
516
|
// `running` to its OUTCOME-AWARE terminal state (fix-daemon-exit-orphan-running-
|
|
474
517
|
// turn): `ended` on a clean exit, `interrupted` with the classified reason
|
|
@@ -478,10 +521,13 @@ export class Waker {
|
|
|
478
521
|
// rejected server-side as invalid_transition). Swallow-safe; never throws.
|
|
479
522
|
if (sessionId && turnAdvancedToRunning) {
|
|
480
523
|
if (cleanExit) {
|
|
481
|
-
|
|
524
|
+
// A clean exit with a KNOWN relay drop is the exact #444 signature: the reply
|
|
525
|
+
// ran but its transcript never landed. Annotate the (still-clean) `ended` turn.
|
|
526
|
+
// `turnUsage` rides the same terminal advance (daemon-token-usage).
|
|
527
|
+
await this.#advanceTurn(sessionId, "ended", entity, null, transcriptRelayError, turnUsage);
|
|
482
528
|
} else {
|
|
483
529
|
const reason = wasInterrupting ? "user" : this.shuttingDown ? "shutdown" : "crash";
|
|
484
|
-
await this.#advanceTurn(sessionId, "interrupted", entity, reason);
|
|
530
|
+
await this.#advanceTurn(sessionId, "interrupted", entity, reason, transcriptRelayError, turnUsage);
|
|
485
531
|
}
|
|
486
532
|
}
|
|
487
533
|
|
|
@@ -565,11 +611,18 @@ export class Waker {
|
|
|
565
611
|
* its classified `interruptedReason` (user/crash/shutdown). Never throws into the
|
|
566
612
|
* wake path — a reporter failure is logged and swallowed (the REST reporter
|
|
567
613
|
* already swallows; this is belt-and-braces, matching #report).
|
|
614
|
+
*
|
|
615
|
+
* `transcriptRelayError` (fix #444 follow-up) annotates a terminal turn whose transcript
|
|
616
|
+
* upload finally failed — the reply was produced but never reached Chorus. Forwarded only
|
|
617
|
+
* when set (a clean relay leaves it null so the field stays absent from the payload).
|
|
568
618
|
* @param {string} sessionId @param {"running"|"ended"|"interrupted"} status
|
|
569
619
|
* @param {{ entityType: string, entityUuid: string }|null} entity
|
|
570
620
|
* @param {"user"|"crash"|"shutdown"|null} [interruptedReason]
|
|
621
|
+
* @param {string|null} [transcriptRelayError]
|
|
622
|
+
* @param {import("./upload-hooks.mjs").TokenUsage|null} [usage] Per-turn token usage
|
|
623
|
+
* (daemon-token-usage); forwarded only on a terminal edge, mirroring transcriptRelayError.
|
|
571
624
|
*/
|
|
572
|
-
async #advanceTurn(sessionId, status, entity, interruptedReason = null) {
|
|
625
|
+
async #advanceTurn(sessionId, status, entity, interruptedReason = null, transcriptRelayError = null, usage = null) {
|
|
573
626
|
try {
|
|
574
627
|
await this.advanceTurn({
|
|
575
628
|
sessionId,
|
|
@@ -577,6 +630,8 @@ export class Waker {
|
|
|
577
630
|
entityType: entity?.entityType ?? null,
|
|
578
631
|
entityUuid: entity?.entityUuid ?? null,
|
|
579
632
|
...(status === "interrupted" && interruptedReason ? { interruptedReason } : {}),
|
|
633
|
+
...(transcriptRelayError ? { transcriptRelayError } : {}),
|
|
634
|
+
...(usage ? { usage } : {}),
|
|
580
635
|
});
|
|
581
636
|
} catch (err) {
|
|
582
637
|
this.logger.warn(
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@chorus-aidlc/chorus",
|
|
3
|
-
"version": "0.14.
|
|
3
|
+
"version": "0.14.4",
|
|
4
4
|
"description": "The Agent Harness for AI-Human Collaboration — session lifecycle, task state, sub-agent orchestration, observability, and failure recovery",
|
|
5
5
|
"homepage": "https://github.com/Chorus-AIDLC/Chorus",
|
|
6
6
|
"repository": {
|