@chorus-aidlc/chorus 0.12.0 → 0.12.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (263) hide show
  1. package/.next/standalone/.next/BUILD_ID +1 -1
  2. package/.next/standalone/.next/app-build-manifest.json +364 -363
  3. package/.next/standalone/.next/app-path-routes-manifest.json +43 -43
  4. package/.next/standalone/.next/build-manifest.json +5 -5
  5. package/.next/standalone/.next/prerender-manifest.json +43 -43
  6. package/.next/standalone/.next/react-loadable-manifest.json +3 -3
  7. package/.next/standalone/.next/server/app/(dashboard)/project-groups/[uuid]/page.js +1 -1
  8. package/.next/standalone/.next/server/app/(dashboard)/project-groups/[uuid]/page.js.nft.json +1 -1
  9. package/.next/standalone/.next/server/app/(dashboard)/project-groups/[uuid]/page_client-reference-manifest.js +1 -1
  10. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/activity/page.js +2 -2
  11. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/activity/page.js.nft.json +1 -1
  12. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/activity/page_client-reference-manifest.js +1 -1
  13. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/dashboard/[ideaUuid]/page.js +2 -2
  14. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/dashboard/[ideaUuid]/page.js.nft.json +1 -1
  15. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/dashboard/[ideaUuid]/page_client-reference-manifest.js +1 -1
  16. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/dashboard/page.js +2 -2
  17. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/dashboard/page.js.nft.json +1 -1
  18. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/dashboard/page_client-reference-manifest.js +1 -1
  19. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/documents/[documentUuid]/page.js +2 -2
  20. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/documents/[documentUuid]/page.js.nft.json +1 -1
  21. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/documents/[documentUuid]/page_client-reference-manifest.js +1 -1
  22. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/documents/page.js +2 -2
  23. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/documents/page.js.nft.json +1 -1
  24. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/documents/page_client-reference-manifest.js +1 -1
  25. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/[proposalUuid]/page.js +2 -2
  26. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/[proposalUuid]/page.js.nft.json +1 -1
  27. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/[proposalUuid]/page_client-reference-manifest.js +1 -1
  28. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/new/page.js +2 -2
  29. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/new/page.js.nft.json +1 -1
  30. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/new/page_client-reference-manifest.js +1 -1
  31. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/page.js +2 -2
  32. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/page.js.nft.json +1 -1
  33. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/page_client-reference-manifest.js +1 -1
  34. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/tasks/[taskUuid]/page.js +1 -1
  35. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/tasks/[taskUuid]/page.js.nft.json +1 -1
  36. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/tasks/[taskUuid]/page_client-reference-manifest.js +1 -1
  37. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/tasks/page.js +1 -1
  38. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/tasks/page.js.nft.json +1 -1
  39. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/tasks/page_client-reference-manifest.js +1 -1
  40. package/.next/standalone/.next/server/app/(dashboard)/projects/page.js +1 -1
  41. package/.next/standalone/.next/server/app/(dashboard)/projects/page.js.nft.json +1 -1
  42. package/.next/standalone/.next/server/app/(dashboard)/projects/page_client-reference-manifest.js +1 -1
  43. package/.next/standalone/.next/server/app/(dashboard)/settings/page.js +2 -2
  44. package/.next/standalone/.next/server/app/(dashboard)/settings/page.js.nft.json +1 -1
  45. package/.next/standalone/.next/server/app/(dashboard)/settings/page_client-reference-manifest.js +1 -1
  46. package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  47. package/.next/standalone/.next/server/app/_not-found.html +1 -1
  48. package/.next/standalone/.next/server/app/_not-found.rsc +1 -1
  49. package/.next/standalone/.next/server/app/admin/companies/[uuid]/page_client-reference-manifest.js +1 -1
  50. package/.next/standalone/.next/server/app/admin/companies/new/page_client-reference-manifest.js +1 -1
  51. package/.next/standalone/.next/server/app/admin/companies/new.html +1 -1
  52. package/.next/standalone/.next/server/app/admin/companies/new.rsc +1 -1
  53. package/.next/standalone/.next/server/app/admin/companies/page_client-reference-manifest.js +1 -1
  54. package/.next/standalone/.next/server/app/admin/companies.html +1 -1
  55. package/.next/standalone/.next/server/app/admin/companies.rsc +1 -1
  56. package/.next/standalone/.next/server/app/admin/page_client-reference-manifest.js +1 -1
  57. package/.next/standalone/.next/server/app/admin.html +1 -1
  58. package/.next/standalone/.next/server/app/admin.rsc +1 -1
  59. package/.next/standalone/.next/server/app/api/admin/companies/[uuid]/route_client-reference-manifest.js +1 -1
  60. package/.next/standalone/.next/server/app/api/admin/companies/route_client-reference-manifest.js +1 -1
  61. package/.next/standalone/.next/server/app/api/admin/login/route_client-reference-manifest.js +1 -1
  62. package/.next/standalone/.next/server/app/api/admin/session/route_client-reference-manifest.js +1 -1
  63. package/.next/standalone/.next/server/app/api/agent-connections/route_client-reference-manifest.js +1 -1
  64. package/.next/standalone/.next/server/app/api/agents/[uuid]/route_client-reference-manifest.js +1 -1
  65. package/.next/standalone/.next/server/app/api/agents/[uuid]/sessions/route_client-reference-manifest.js +1 -1
  66. package/.next/standalone/.next/server/app/api/agents/route_client-reference-manifest.js +1 -1
  67. package/.next/standalone/.next/server/app/api/api-keys/[uuid]/route_client-reference-manifest.js +1 -1
  68. package/.next/standalone/.next/server/app/api/api-keys/route_client-reference-manifest.js +1 -1
  69. package/.next/standalone/.next/server/app/api/auth/callback/route_client-reference-manifest.js +1 -1
  70. package/.next/standalone/.next/server/app/api/auth/check-default/route_client-reference-manifest.js +1 -1
  71. package/.next/standalone/.next/server/app/api/auth/company-oidc/route_client-reference-manifest.js +1 -1
  72. package/.next/standalone/.next/server/app/api/auth/default-login/route_client-reference-manifest.js +1 -1
  73. package/.next/standalone/.next/server/app/api/auth/identify/route_client-reference-manifest.js +1 -1
  74. package/.next/standalone/.next/server/app/api/auth/logout/route_client-reference-manifest.js +1 -1
  75. package/.next/standalone/.next/server/app/api/auth/me/route_client-reference-manifest.js +1 -1
  76. package/.next/standalone/.next/server/app/api/auth/refresh/route_client-reference-manifest.js +1 -1
  77. package/.next/standalone/.next/server/app/api/auth/session/route_client-reference-manifest.js +1 -1
  78. package/.next/standalone/.next/server/app/api/auth/sync-token/route_client-reference-manifest.js +1 -1
  79. package/.next/standalone/.next/server/app/api/comments/route_client-reference-manifest.js +1 -1
  80. package/.next/standalone/.next/server/app/api/daemon/control/route_client-reference-manifest.js +1 -1
  81. package/.next/standalone/.next/server/app/api/daemon/execution-state/route_client-reference-manifest.js +1 -1
  82. package/.next/standalone/.next/server/app/api/daemon/executions/route_client-reference-manifest.js +1 -1
  83. package/.next/standalone/.next/server/app/api/daemon/pending-turns/route_client-reference-manifest.js +1 -1
  84. package/.next/standalone/.next/server/app/api/daemon/report-interrupt/route_client-reference-manifest.js +1 -1
  85. package/.next/standalone/.next/server/app/api/daemon/resume/route_client-reference-manifest.js +1 -1
  86. package/.next/standalone/.next/server/app/api/daemon/transcript/route_client-reference-manifest.js +1 -1
  87. package/.next/standalone/.next/server/app/api/daemon/turn-advance/route_client-reference-manifest.js +1 -1
  88. package/.next/standalone/.next/server/app/api/daemon-sessions/[sessionUuid]/instruction/route_client-reference-manifest.js +1 -1
  89. package/.next/standalone/.next/server/app/api/daemon-sessions/[sessionUuid]/repoint/route_client-reference-manifest.js +1 -1
  90. package/.next/standalone/.next/server/app/api/daemon-sessions/[sessionUuid]/route_client-reference-manifest.js +1 -1
  91. package/.next/standalone/.next/server/app/api/daemon-sessions/ad-hoc/route_client-reference-manifest.js +1 -1
  92. package/.next/standalone/.next/server/app/api/daemon-sessions/route_client-reference-manifest.js +1 -1
  93. package/.next/standalone/.next/server/app/api/documents/[uuid]/route_client-reference-manifest.js +1 -1
  94. package/.next/standalone/.next/server/app/api/entities/[type]/[uuid]/root-idea/route_client-reference-manifest.js +1 -1
  95. package/.next/standalone/.next/server/app/api/events/notifications/route.js +6 -4
  96. package/.next/standalone/.next/server/app/api/events/notifications/route_client-reference-manifest.js +1 -1
  97. package/.next/standalone/.next/server/app/api/events/route.js +7 -5
  98. package/.next/standalone/.next/server/app/api/events/route_client-reference-manifest.js +1 -1
  99. package/.next/standalone/.next/server/app/api/health/route_client-reference-manifest.js +1 -1
  100. package/.next/standalone/.next/server/app/api/ideas/[uuid]/claim/route_client-reference-manifest.js +1 -1
  101. package/.next/standalone/.next/server/app/api/ideas/[uuid]/move/preview/route_client-reference-manifest.js +1 -1
  102. package/.next/standalone/.next/server/app/api/ideas/[uuid]/move/route_client-reference-manifest.js +1 -1
  103. package/.next/standalone/.next/server/app/api/ideas/[uuid]/parent/route_client-reference-manifest.js +1 -1
  104. package/.next/standalone/.next/server/app/api/ideas/[uuid]/release/route_client-reference-manifest.js +1 -1
  105. package/.next/standalone/.next/server/app/api/ideas/[uuid]/route_client-reference-manifest.js +1 -1
  106. package/.next/standalone/.next/server/app/api/keepalive/route_client-reference-manifest.js +1 -1
  107. package/.next/standalone/.next/server/app/api/mcp/route_client-reference-manifest.js +1 -1
  108. package/.next/standalone/.next/server/app/api/me/assignments/route_client-reference-manifest.js +1 -1
  109. package/.next/standalone/.next/server/app/api/mentionables/route_client-reference-manifest.js +1 -1
  110. package/.next/standalone/.next/server/app/api/notifications/[uuid]/archive/route_client-reference-manifest.js +1 -1
  111. package/.next/standalone/.next/server/app/api/notifications/[uuid]/read/route_client-reference-manifest.js +1 -1
  112. package/.next/standalone/.next/server/app/api/notifications/preferences/route_client-reference-manifest.js +1 -1
  113. package/.next/standalone/.next/server/app/api/notifications/read-all/route_client-reference-manifest.js +1 -1
  114. package/.next/standalone/.next/server/app/api/notifications/route_client-reference-manifest.js +1 -1
  115. package/.next/standalone/.next/server/app/api/notifications/unread-count/route_client-reference-manifest.js +1 -1
  116. package/.next/standalone/.next/server/app/api/project-groups/[uuid]/dashboard/route_client-reference-manifest.js +1 -1
  117. package/.next/standalone/.next/server/app/api/project-groups/[uuid]/route_client-reference-manifest.js +1 -1
  118. package/.next/standalone/.next/server/app/api/project-groups/route_client-reference-manifest.js +1 -1
  119. package/.next/standalone/.next/server/app/api/projects/[uuid]/activity/route_client-reference-manifest.js +1 -1
  120. package/.next/standalone/.next/server/app/api/projects/[uuid]/available/route_client-reference-manifest.js +1 -1
  121. package/.next/standalone/.next/server/app/api/projects/[uuid]/documents/route_client-reference-manifest.js +1 -1
  122. package/.next/standalone/.next/server/app/api/projects/[uuid]/group/route_client-reference-manifest.js +1 -1
  123. package/.next/standalone/.next/server/app/api/projects/[uuid]/ideas/route_client-reference-manifest.js +1 -1
  124. package/.next/standalone/.next/server/app/api/projects/[uuid]/ideas/tracker/route_client-reference-manifest.js +1 -1
  125. package/.next/standalone/.next/server/app/api/projects/[uuid]/proposals/[proposalUuid]/validate/route_client-reference-manifest.js +1 -1
  126. package/.next/standalone/.next/server/app/api/projects/[uuid]/proposals/route_client-reference-manifest.js +1 -1
  127. package/.next/standalone/.next/server/app/api/projects/[uuid]/proposals/summary/route_client-reference-manifest.js +1 -1
  128. package/.next/standalone/.next/server/app/api/projects/[uuid]/route_client-reference-manifest.js +1 -1
  129. package/.next/standalone/.next/server/app/api/projects/[uuid]/stats/route_client-reference-manifest.js +1 -1
  130. package/.next/standalone/.next/server/app/api/projects/[uuid]/tasks/dependencies/route_client-reference-manifest.js +1 -1
  131. package/.next/standalone/.next/server/app/api/projects/[uuid]/tasks/route_client-reference-manifest.js +1 -1
  132. package/.next/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  133. package/.next/standalone/.next/server/app/api/proposals/[uuid]/approve/route_client-reference-manifest.js +1 -1
  134. package/.next/standalone/.next/server/app/api/proposals/[uuid]/close/route_client-reference-manifest.js +1 -1
  135. package/.next/standalone/.next/server/app/api/proposals/[uuid]/reject/route_client-reference-manifest.js +1 -1
  136. package/.next/standalone/.next/server/app/api/proposals/[uuid]/revoke/route_client-reference-manifest.js +1 -1
  137. package/.next/standalone/.next/server/app/api/proposals/[uuid]/route_client-reference-manifest.js +1 -1
  138. package/.next/standalone/.next/server/app/api/search/route_client-reference-manifest.js +1 -1
  139. package/.next/standalone/.next/server/app/api/sessions/[uuid]/route_client-reference-manifest.js +1 -1
  140. package/.next/standalone/.next/server/app/api/tasks/[uuid]/claim/route_client-reference-manifest.js +1 -1
  141. package/.next/standalone/.next/server/app/api/tasks/[uuid]/dependencies/[dependsOnUuid]/route_client-reference-manifest.js +1 -1
  142. package/.next/standalone/.next/server/app/api/tasks/[uuid]/dependencies/route_client-reference-manifest.js +1 -1
  143. package/.next/standalone/.next/server/app/api/tasks/[uuid]/release/route_client-reference-manifest.js +1 -1
  144. package/.next/standalone/.next/server/app/api/tasks/[uuid]/route_client-reference-manifest.js +1 -1
  145. package/.next/standalone/.next/server/app/api/tasks/[uuid]/sessions/route_client-reference-manifest.js +1 -1
  146. package/.next/standalone/.next/server/app/index.html +1 -1
  147. package/.next/standalone/.next/server/app/index.rsc +2 -2
  148. package/.next/standalone/.next/server/app/login/admin/page.js +2 -2
  149. package/.next/standalone/.next/server/app/login/admin/page.js.nft.json +1 -1
  150. package/.next/standalone/.next/server/app/login/admin/page_client-reference-manifest.js +1 -1
  151. package/.next/standalone/.next/server/app/login/admin.html +1 -1
  152. package/.next/standalone/.next/server/app/login/admin.rsc +1 -1
  153. package/.next/standalone/.next/server/app/login/callback/page.js +2 -2
  154. package/.next/standalone/.next/server/app/login/callback/page.js.nft.json +1 -1
  155. package/.next/standalone/.next/server/app/login/callback/page_client-reference-manifest.js +1 -1
  156. package/.next/standalone/.next/server/app/login/callback.html +1 -1
  157. package/.next/standalone/.next/server/app/login/callback.rsc +1 -1
  158. package/.next/standalone/.next/server/app/login/page.js +2 -2
  159. package/.next/standalone/.next/server/app/login/page.js.nft.json +1 -1
  160. package/.next/standalone/.next/server/app/login/page_client-reference-manifest.js +1 -1
  161. package/.next/standalone/.next/server/app/login/pick-workspace/page_client-reference-manifest.js +1 -1
  162. package/.next/standalone/.next/server/app/login/pick-workspace.html +1 -1
  163. package/.next/standalone/.next/server/app/login/pick-workspace.rsc +1 -1
  164. package/.next/standalone/.next/server/app/login/silent-refresh/page_client-reference-manifest.js +1 -1
  165. package/.next/standalone/.next/server/app/login/silent-refresh.html +1 -1
  166. package/.next/standalone/.next/server/app/login/silent-refresh.rsc +1 -1
  167. package/.next/standalone/.next/server/app/login.html +1 -1
  168. package/.next/standalone/.next/server/app/login.rsc +2 -2
  169. package/.next/standalone/.next/server/app/onboarding/page.js +2 -2
  170. package/.next/standalone/.next/server/app/onboarding/page.js.nft.json +1 -1
  171. package/.next/standalone/.next/server/app/onboarding/page_client-reference-manifest.js +1 -1
  172. package/.next/standalone/.next/server/app/onboarding.html +1 -1
  173. package/.next/standalone/.next/server/app/onboarding.rsc +2 -2
  174. package/.next/standalone/.next/server/app/page.js +2 -2
  175. package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
  176. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  177. package/.next/standalone/.next/server/app/projects.html +1 -1
  178. package/.next/standalone/.next/server/app/projects.rsc +2 -2
  179. package/.next/standalone/.next/server/app/settings.html +1 -1
  180. package/.next/standalone/.next/server/app/settings.rsc +3 -3
  181. package/.next/standalone/.next/server/app-paths-manifest.json +43 -43
  182. package/.next/standalone/.next/server/chunks/1596.js +2 -2
  183. package/.next/standalone/.next/server/chunks/2779.js +31 -0
  184. package/.next/standalone/.next/server/chunks/2961.js +1 -1
  185. package/.next/standalone/.next/server/chunks/3219.js +1 -1
  186. package/.next/standalone/.next/server/chunks/4292.js +1 -0
  187. package/.next/standalone/.next/server/chunks/4872.js +1 -1
  188. package/.next/standalone/.next/server/chunks/5538.js +1 -0
  189. package/.next/standalone/.next/server/chunks/6113.js +1 -1
  190. package/.next/standalone/.next/server/chunks/6207.js +1 -1
  191. package/.next/standalone/.next/server/chunks/7063.js +2 -2
  192. package/.next/standalone/.next/server/chunks/7160.js +1 -1
  193. package/.next/standalone/.next/server/chunks/7368.js +1 -1
  194. package/.next/standalone/.next/server/chunks/7515.js +1 -1
  195. package/.next/standalone/.next/server/chunks/8732.js +1 -0
  196. package/.next/standalone/.next/server/chunks/920.js +1 -1
  197. package/.next/standalone/.next/server/chunks/9273.js +1 -0
  198. package/.next/standalone/.next/server/chunks/937.js +1 -1
  199. package/.next/standalone/.next/server/middleware-build-manifest.js +1 -1
  200. package/.next/standalone/.next/server/middleware-manifest.json +5 -5
  201. package/.next/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  202. package/.next/standalone/.next/server/pages/404.html +1 -1
  203. package/.next/standalone/.next/server/pages/500.html +1 -1
  204. package/.next/standalone/.next/server/pages-manifest.json +1 -1
  205. package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
  206. package/.next/standalone/.next/server/server-reference-manifest.json +1 -1
  207. package/.next/standalone/.next/static/chunks/10344-2e9a9d767e2e8ed1.js +1 -0
  208. package/.next/standalone/.next/static/chunks/{33187.13c12f5c0821ac57.js → 33187.1328c15b9dab78a8.js} +1 -1
  209. package/.next/standalone/.next/static/chunks/{40867-04cc0d00205eaf9b.js → 46983-8bf90f1ffeb55957.js} +1 -1
  210. package/.next/standalone/.next/static/chunks/{32497-886aa4d3d7bf4967.js → 46999-f53da8f53fe1b8a9.js} +1 -1
  211. package/.next/standalone/.next/static/chunks/{4860.f4242c493fcf182d.js → 4860.e3d0dd79a4d37626.js} +1 -1
  212. package/.next/standalone/.next/static/chunks/{78917-2b959ab0a7f610b4.js → 78917-aa5bbff9248799a4.js} +1 -1
  213. package/.next/standalone/.next/static/chunks/85573-fb4d2cbd67612d47.js +1 -0
  214. package/.next/standalone/.next/static/chunks/{97784-7b90a17294840e32.js → 97784-42081b75f8cc6da8.js} +1 -1
  215. package/.next/standalone/.next/static/chunks/97868-55f18a05fe483d85.js +1 -0
  216. package/.next/standalone/.next/static/chunks/{99373.880b43de1fa6411f.js → 99373.cc6319fa4cf36081.js} +1 -1
  217. package/.next/standalone/.next/static/chunks/app/(dashboard)/layout-b3a497ba5eb08036.js +1 -0
  218. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/dashboard/page-d786f0c18a9c4f06.js +1 -0
  219. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/documents/[documentUuid]/page-c68f1eda3779b448.js +1 -0
  220. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/documents/{page-6620b9d7a2cc766f.js → page-e0935445535c28cb.js} +1 -1
  221. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/[proposalUuid]/page-f824632ff61a9fa7.js +1 -0
  222. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/new/page-dbcb6e50fc4816c6.js +1 -0
  223. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/page-1295bc505e727383.js +1 -0
  224. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/tasks/[taskUuid]/{page-d5c3dde34d6291a8.js → page-ceeec49af0396432.js} +1 -1
  225. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/tasks/{page-0da08d8b425acb6a.js → page-1286afe43c086d6a.js} +1 -1
  226. package/.next/standalone/.next/static/chunks/app/(dashboard)/settings/{page-44014947a679f91c.js → page-0fb1d51016f6bd56.js} +1 -1
  227. package/.next/standalone/.next/static/chunks/app/login/page-d2513f477211dd6f.js +1 -0
  228. package/.next/standalone/.next/static/chunks/app/onboarding/{page-9a41067d4c5d29d7.js → page-2936274fb252329e.js} +1 -1
  229. package/.next/standalone/.next/static/chunks/app/page-075afd218994d377.js +1 -0
  230. package/.next/standalone/.next/static/chunks/{webpack-1556cfd11f7e90d1.js → webpack-ed3555ea61243391.js} +1 -1
  231. package/.next/standalone/package.json +1 -1
  232. package/README.md +2 -2
  233. package/README.zh.md +2 -2
  234. package/cli/client-args.mjs +1 -1
  235. package/cli/codex-session-map.mjs +117 -0
  236. package/cli/codex-spawner.mjs +312 -0
  237. package/cli/daemon-agent.mjs +32 -6
  238. package/cli/daemon-banner.mjs +43 -5
  239. package/cli/daemon.mjs +133 -14
  240. package/cli/login.mjs +77 -34
  241. package/cli/spawner-select.mjs +30 -0
  242. package/cli/sse-listener.mjs +29 -1
  243. package/cli/upload-hooks.mjs +73 -8
  244. package/package.json +1 -1
  245. package/.next/standalone/.next/server/chunks/3371.js +0 -1
  246. package/.next/standalone/.next/server/chunks/345.js +0 -1
  247. package/.next/standalone/.next/server/chunks/4958.js +0 -1
  248. package/.next/standalone/.next/server/chunks/5581.js +0 -1
  249. package/.next/standalone/.next/server/chunks/7897.js +0 -1
  250. package/.next/standalone/.next/server/chunks/8245.js +0 -31
  251. package/.next/standalone/.next/static/chunks/42111-1935df3b0dab2095.js +0 -1
  252. package/.next/standalone/.next/static/chunks/6239-d78e6f830ce0a7f8.js +0 -1
  253. package/.next/standalone/.next/static/chunks/97868-9406a4014b667c2d.js +0 -1
  254. package/.next/standalone/.next/static/chunks/app/(dashboard)/layout-f04d5fa070f15acd.js +0 -1
  255. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/dashboard/page-c4271886ef004611.js +0 -1
  256. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/documents/[documentUuid]/page-7a8b60de97bfbd29.js +0 -1
  257. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/[proposalUuid]/page-0a55289b2bc510c2.js +0 -1
  258. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/new/page-99639479cc98965f.js +0 -1
  259. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/page-5d09141beb5d6aee.js +0 -1
  260. package/.next/standalone/.next/static/chunks/app/login/page-e7493d55573a52f1.js +0 -1
  261. package/.next/standalone/.next/static/chunks/app/page-8b4baa950c78ffe7.js +0 -1
  262. /package/.next/standalone/.next/static/{v1yRpXkt1wNBkZMTE3tiz → GmBblfxcDziUENBiEap4B}/_buildManifest.js +0 -0
  263. /package/.next/standalone/.next/static/{v1yRpXkt1wNBkZMTE3tiz → GmBblfxcDziUENBiEap4B}/_ssgManifest.js +0 -0
@@ -0,0 +1,312 @@
1
+ // cli/codex-spawner.mjs
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`: MCP comes from the user's ~/.codex/config.toml; the daemon
17
+ // key reaches it via the configured bearer_token_env_var (default
18
+ // CHORUS_API_KEY) exported into the child ENV — never argv.
19
+ // • Permission is a SANDBOX mode, not a tool allowlist.
20
+ //
21
+ // Reuses claude-spawner's platform-neutral helpers: parseNdjsonChunk (NDJSON
22
+ // stream parse) and the PATH-walk shape of resolveClaudePath.
23
+
24
+ import { spawn } from "node:child_process";
25
+ import { statSync } from "node:fs";
26
+ import { win32 as pathWin32, posix as pathPosix } from "node:path";
27
+ import { parseNdjsonChunk } from "./claude-spawner.mjs";
28
+ import { getThreadId as defaultGetThreadId, setThreadId as defaultSetThreadId } from "./codex-session-map.mjs";
29
+
30
+ const NOOP_LOGGER = { info() {}, warn() {}, error() {} };
31
+
32
+ /**
33
+ * @typedef {Object} Spawner
34
+ * @property {(params: {
35
+ * prompt: string, sessionId: string|null, isNew: boolean,
36
+ * mcpConfigPath?: string, cwd?: string,
37
+ * onMessage?: (obj: any) => void,
38
+ * onChild?: (child: import("node:child_process").ChildProcess) => void
39
+ * }) => Promise<{ sessionId: string, exitCode: number|null, isNew: boolean }>} wake
40
+ * The backend-agnostic wake contract. ClaudeSpawner and CodexSpawner both
41
+ * implement it; the daemon injects one based on the resolved agent type.
42
+ */
43
+
44
+ /**
45
+ * Map the daemon's backend-agnostic permission mode to a Codex sandbox posture.
46
+ * The expression is SUBCOMMAND-AWARE because the two surfaces differ (verified
47
+ * against codex 0.142.3): the top-level `codex exec` accepts `--sandbox <mode>`,
48
+ * but `codex exec resume` does NOT — passing `--sandbox` there errors with exit 2.
49
+ * yolo → --dangerously-bypass-approvals-and-sandbox (valid on BOTH exec and
50
+ * resume; full autonomy)
51
+ * chorus → exec: --sandbox read-only
52
+ * resume: -c sandbox_mode="read-only" (the `-c` config override is how
53
+ * `codex exec resume` accepts a sandbox mode; `sandbox_mode` is a real
54
+ * config key, value spelled `read-only` per protocol/src/config_types.rs,
55
+ * confirmed via `--strict-config`).
56
+ * Anything other than yolo falls back to the restricted read-only posture.
57
+ * @param {"yolo"|"chorus"|undefined} permissionMode
58
+ * @param {{ resume?: boolean }} [opts] resume:true selects the `codex exec resume` surface.
59
+ * @returns {string[]}
60
+ */
61
+ export function sandboxFlags(permissionMode, opts = {}) {
62
+ if (permissionMode === "yolo") return ["--dangerously-bypass-approvals-and-sandbox"];
63
+ // restricted read-only posture, expressed per subcommand:
64
+ return opts.resume ? ["-c", 'sandbox_mode="read-only"'] : ["--sandbox", "read-only"];
65
+ }
66
+
67
+ /**
68
+ * Build the argv for a headless codex run. Prompt is NEVER here — it goes over
69
+ * stdin. `--skip-git-repo-check` lets a non-repo cwd still run.
70
+ * @param {{ isNew: boolean, threadId?: string|null, permissionMode?: "yolo"|"chorus" }} o
71
+ * @returns {string[]}
72
+ */
73
+ export function buildCodexArgs({ isNew, threadId, permissionMode }) {
74
+ if (!isNew && threadId) {
75
+ const sandbox = sandboxFlags(permissionMode, { resume: true });
76
+ return ["exec", "resume", threadId, "--json", ...sandbox, "--skip-git-repo-check"];
77
+ }
78
+ const sandbox = sandboxFlags(permissionMode);
79
+ return ["exec", "--json", ...sandbox, "--skip-git-repo-check"];
80
+ }
81
+
82
+ /**
83
+ * Extract the Codex thread id from a stream event, or null. Accepts the live
84
+ * `thread.started` shape (authoritative) and the on-disk rollout `session_meta`
85
+ * shape as a defensive fallback.
86
+ * @param {any} obj
87
+ * @returns {string|null}
88
+ */
89
+ export function extractThreadId(obj) {
90
+ if (!obj || typeof obj !== "object") return null;
91
+ if (obj.type === "thread.started" && typeof obj.thread_id === "string") return obj.thread_id;
92
+ if (obj.type === "session_meta" && obj.payload && typeof obj.payload.id === "string") {
93
+ return obj.payload.id;
94
+ }
95
+ return null;
96
+ }
97
+
98
+ /**
99
+ * Resolve the real `codex` executable WITHOUT a shell — same approach as
100
+ * resolveClaudePath. On Windows the bin may be `codex.cmd` (npm shim), which
101
+ * `spawn` can't exec directly without shell:true; we walk PATH for the platform
102
+ * candidates. `CHORUS_CODEX_PATH` overrides.
103
+ * @param {{ env?: NodeJS.ProcessEnv, platform?: NodeJS.Platform, isFile?: (p: string) => boolean }} [deps]
104
+ * @returns {string | null}
105
+ */
106
+ export function resolveCodexPath(deps = {}) {
107
+ const env = deps.env ?? process.env;
108
+ const platform = deps.platform ?? process.platform;
109
+ const isFile =
110
+ deps.isFile ??
111
+ ((p) => {
112
+ try {
113
+ return statSync(p).isFile();
114
+ } catch {
115
+ return false;
116
+ }
117
+ });
118
+
119
+ if (env.CHORUS_CODEX_PATH && isFile(env.CHORUS_CODEX_PATH)) {
120
+ return env.CHORUS_CODEX_PATH;
121
+ }
122
+
123
+ const isWin = platform === "win32";
124
+ const p = isWin ? pathWin32 : pathPosix;
125
+ const names = isWin ? ["codex.cmd", "codex.exe", "codex"] : ["codex"];
126
+ const pathVar = env.PATH || env.Path || "";
127
+ const dirs = pathVar.split(p.delimiter).filter(Boolean);
128
+ for (const dir of dirs) {
129
+ for (const name of names) {
130
+ const candidate = p.join(dir, name);
131
+ if (isFile(candidate)) return candidate;
132
+ }
133
+ }
134
+ return null;
135
+ }
136
+
137
+ /**
138
+ * Resolve the actual command + argv to spawn. On Windows a `.cmd`/`.bat` shim is
139
+ * not a PE executable, so it must run via `cmd.exe /d /s /c <path> ...args`; we
140
+ * keep shell:false and pass argv as an array (no shell word-splitting/injection).
141
+ * @param {string} codexPath @param {string[]} args
142
+ * @param {NodeJS.Platform} [platform] @param {NodeJS.ProcessEnv} [env]
143
+ * @returns {{ command: string, argv: string[] }}
144
+ */
145
+ export function resolveSpawnCommand(codexPath, args, platform = process.platform, env = process.env) {
146
+ const isWin = platform === "win32";
147
+ const lower = codexPath.toLowerCase();
148
+ if (isWin && (lower.endsWith(".cmd") || lower.endsWith(".bat"))) {
149
+ const comspec = env.ComSpec || env.COMSPEC || "cmd.exe";
150
+ return { command: comspec, argv: ["/d", "/s", "/c", codexPath, ...args] };
151
+ }
152
+ return { command: codexPath, argv: args };
153
+ }
154
+
155
+ /**
156
+ * @typedef {Object} CodexSpawnerOptions
157
+ * @property {string} [codexPath] Resolved codex path (resolved lazily if omitted).
158
+ * @property {(o: object) => any} [spawnImpl] Injectable spawn (tests).
159
+ * @property {{info(m:string):void,warn(m:string):void,error(m:string):void}} [logger]
160
+ * @property {"chorus"|"yolo"} [permissionMode] Maps to a Codex sandbox posture.
161
+ * @property {{ url: string, apiKey: string }} [creds] Daemon creds — apiKey is exported
162
+ * into the child env under the user config's bearer_token_env_var (default CHORUS_API_KEY).
163
+ * @property {NodeJS.Platform} [platform] Injectable for tests; gates POSIX `detached`.
164
+ * @property {(anchor: string) => string|null} [getThreadIdFn] Injectable session-map read.
165
+ * @property {(anchor: string, threadId: string) => void} [setThreadIdFn] Injectable session-map write.
166
+ */
167
+
168
+ export class CodexSpawner {
169
+ /** @param {CodexSpawnerOptions} [opts] */
170
+ constructor(opts = {}) {
171
+ this.codexPath = opts.codexPath ?? null;
172
+ this.spawnImpl = opts.spawnImpl ?? spawn;
173
+ this.logger = opts.logger ?? NOOP_LOGGER;
174
+ this.permissionMode = opts.permissionMode ?? "chorus";
175
+ this.creds = opts.creds ?? null;
176
+ this.platform = opts.platform ?? process.platform;
177
+ this.getThreadIdFn = opts.getThreadIdFn ?? defaultGetThreadId;
178
+ this.setThreadIdFn = opts.setThreadIdFn ?? defaultSetThreadId;
179
+ this.resolveCodexPathFn = opts.resolveCodexPathFn ?? resolveCodexPath;
180
+ }
181
+
182
+ /**
183
+ * Spawn a headless Codex run. Resolves when the subprocess exits. The prompt is
184
+ * written to stdin (never argv). `sessionId` is the Chorus anchor (direct idea
185
+ * uuid, or entity uuid). Codex owns its session id, so we IGNORE the passed
186
+ * `isNew`/`mcpConfigPath` and decide new-vs-resume from the persisted
187
+ * anchor→thread_id map: a recorded thread id → `resume`, otherwise a fresh run.
188
+ *
189
+ * @param {{ prompt: string, sessionId: string|null, isNew?: boolean, mcpConfigPath?: string,
190
+ * cwd?: string, onMessage?: (obj: any) => void,
191
+ * onChild?: (child: import("node:child_process").ChildProcess) => void }} params
192
+ * @returns {Promise<{ sessionId: string, exitCode: number|null, isNew: boolean }>}
193
+ */
194
+ async wake({ prompt, sessionId, cwd, onMessage, onChild }) {
195
+ const anchor = typeof sessionId === "string" ? sessionId : "";
196
+
197
+ // new-vs-resume is OWNED by this backend (Codex session model), not the
198
+ // waker's Claude transcript probe: a recorded thread id means resume.
199
+ const knownThreadId = anchor ? this.getThreadIdFn(anchor) : null;
200
+ const isNew = !knownThreadId;
201
+
202
+ const codexPath = this.codexPath ?? this.resolveCodexPathFn();
203
+ if (!codexPath) {
204
+ // No crash — surface visibly and resolve with a failure result.
205
+ this.logger.error("[Chorus] cannot locate the `codex` executable on PATH; skipping wake");
206
+ return { sessionId: anchor, exitCode: null, isNew };
207
+ }
208
+
209
+ const args = buildCodexArgs({ isNew, threadId: knownThreadId, permissionMode: this.permissionMode });
210
+ const { command, argv } = resolveSpawnCommand(codexPath, args, this.platform);
211
+
212
+ // POSIX: detached process group so the interrupt path can group-kill the tree
213
+ // (codex exec forks child shells for tools). Windows uses taskkill /T. stdio
214
+ // stays piped — prompt over stdin + NDJSON stdout parse are unaffected.
215
+ const detached = this.platform !== "win32";
216
+
217
+ // Daemon key via ENV under the var the user's [mcp_servers.chorus] references
218
+ // (bearer_token_env_var, default CHORUS_API_KEY) — NEVER argv. Merged over the
219
+ // inherited env so PATH / model auth (Bedrock profile) / CODEX_HOME survive.
220
+ const childEnv = { ...process.env, CHORUS_DAEMON_HEADLESS: "1" };
221
+ if (this.creds && this.creds.apiKey) childEnv.CHORUS_API_KEY = this.creds.apiKey;
222
+
223
+ return new Promise((resolve) => {
224
+ let child;
225
+ try {
226
+ child = this.spawnImpl(command, argv, {
227
+ cwd: cwd ?? process.cwd(),
228
+ stdio: ["pipe", "pipe", "pipe"],
229
+ env: childEnv,
230
+ shell: false,
231
+ detached,
232
+ windowsHide: true,
233
+ });
234
+ } catch (err) {
235
+ this.logger.error(`[Chorus] failed to spawn codex: ${err}`);
236
+ resolve({ sessionId: anchor, exitCode: null, isNew });
237
+ return;
238
+ }
239
+
240
+ // Hand the live child to the caller (interrupt registry) before resolving.
241
+ // Never let a throwing callback escape into the spawn path.
242
+ if (onChild) {
243
+ try {
244
+ onChild(child);
245
+ } catch (err) {
246
+ this.logger.warn(`[Chorus] onChild handler threw: ${err}`);
247
+ }
248
+ }
249
+
250
+ let stdoutBuf = "";
251
+ let observedThreadId = knownThreadId || null;
252
+
253
+ child.stdout?.setEncoding?.("utf8");
254
+ child.stdout?.on("data", (chunk) => {
255
+ stdoutBuf = parseNdjsonChunk(
256
+ stdoutBuf,
257
+ String(chunk),
258
+ (obj) => {
259
+ const tid = extractThreadId(obj);
260
+ if (tid) observedThreadId = tid;
261
+ if (onMessage) {
262
+ try {
263
+ onMessage(obj);
264
+ } catch (err) {
265
+ this.logger.warn(`[Chorus] onMessage handler threw: ${err}`);
266
+ }
267
+ }
268
+ },
269
+ (msg) => this.logger.warn(`[Chorus] ${msg}`)
270
+ );
271
+ });
272
+
273
+ child.stderr?.setEncoding?.("utf8");
274
+ child.stderr?.on("data", (chunk) => {
275
+ const text = String(chunk).trim();
276
+ if (text) this.logger.warn(`[Chorus] codex stderr: ${text}`);
277
+ });
278
+
279
+ child.on("error", (err) => {
280
+ this.logger.error(`[Chorus] codex process error: ${err}`);
281
+ resolve({ sessionId: observedThreadId || anchor, exitCode: null, isNew });
282
+ });
283
+
284
+ child.on("close", (code) => {
285
+ if (code !== 0) {
286
+ this.logger.warn(`[Chorus] codex exited with code ${code}`);
287
+ }
288
+ // Persist anchor→thread_id only on a fresh, successful run that produced a
289
+ // new id — so a later wake for this anchor resumes it. Best-effort; the
290
+ // session map swallows its own IO errors.
291
+ if (code === 0 && isNew && anchor && observedThreadId) {
292
+ this.setThreadIdFn(anchor, observedThreadId);
293
+ }
294
+ resolve({ sessionId: observedThreadId || anchor, exitCode: code, isNew });
295
+ });
296
+
297
+ // Guard against an ASYNC stdin error (EPIPE) so it never becomes an
298
+ // uncaughtException that kills the daemon.
299
+ child.stdin?.on?.("error", (err) => {
300
+ this.logger.warn(`[Chorus] codex stdin error (ignored): ${err}`);
301
+ });
302
+
303
+ // Feed the prompt over stdin, then close it so the model runs.
304
+ try {
305
+ child.stdin?.write(prompt);
306
+ child.stdin?.end();
307
+ } catch (err) {
308
+ this.logger.warn(`[Chorus] failed writing prompt to codex stdin: ${err}`);
309
+ }
310
+ });
311
+ }
312
+ }
@@ -1,15 +1,41 @@
1
1
  // cli/daemon-agent.mjs
2
- // Pure resolution + validation of the daemon's `--agent <type>` selection. The
3
- // flag/env exist to RESERVE the extension point for future agent backends
4
- // (e.g. codex); only `claude-code` is implemented in this change. Resolving an
2
+ // Pure resolution + validation of the daemon's `--agent <type>` selection.
3
+ // `claude-code` (the default) and `codex` are both implemented backends
4
+ // (add-daemon-codex-backend cashed in the reserved `codex` slot). Resolving an
5
5
  // unknown value is a hard error (no silent fallback). Zero dependencies.
6
6
 
7
- /** The agent backends the daemon recognizes. Only `claude-code` is implemented. */
8
- export const KNOWN_AGENTS = ["claude-code"];
7
+ /** The agent backends the daemon recognizes. Both are implemented (claude-code
8
+ * via ClaudeSpawner, codex via CodexSpawner — see spawner-select.mjs). */
9
+ export const KNOWN_AGENTS = ["claude-code", "codex"];
9
10
 
10
11
  /** The default agent backend when neither --agent nor CHORUS_AGENT is set. */
11
12
  export const DEFAULT_AGENT = "claude-code";
12
13
 
14
+ /**
15
+ * Per-backend CLI descriptor: the executable name the daemon resolves/spawns and
16
+ * the env var that overrides its path. Drives the startup banner's "CLI" row and
17
+ * the not-found warning so they name the SELECTED backend (not always `claude`).
18
+ * Unknown / undefined falls back to the default (claude-code) descriptor.
19
+ * @param {string} agentType
20
+ * @returns {{ name: string, envVar: string }}
21
+ */
22
+ export function backendCli(agentType) {
23
+ if (agentType === "codex") return { name: "codex", envVar: "CHORUS_CODEX_PATH" };
24
+ return { name: "claude", envVar: "CHORUS_CLAUDE_PATH" };
25
+ }
26
+
27
+ /**
28
+ * Map the resolved agent backend to the `clientType` the daemon self-reports to
29
+ * the server (and that the connection registry + presence UI display). The server
30
+ * gates this against DAEMON_CLIENT_TYPES, so the values MUST match: `codex` →
31
+ * `codex`, `claude-code` → `claude_code`. Anything else falls back to claude_code.
32
+ * @param {string} agentType
33
+ * @returns {string}
34
+ */
35
+ export function backendClientType(agentType) {
36
+ return agentType === "codex" ? "codex" : "claude_code";
37
+ }
38
+
13
39
  /**
14
40
  * Resolve the agent type from flag → env → default, and validate it.
15
41
  * Precedence: explicit `--agent` flag > CHORUS_AGENT env > DEFAULT_AGENT.
@@ -31,7 +57,7 @@ export function resolveAgentType(flags, env) {
31
57
  value: raw,
32
58
  error:
33
59
  `Unknown --agent "${raw}". Accepted: ${KNOWN_AGENTS.join(", ")}. ` +
34
- `(Only ${DEFAULT_AGENT} is implemented; the flag reserves the slot for future agents.)`,
60
+ `(Default is ${DEFAULT_AGENT}.)`,
35
61
  };
36
62
  }
37
63
  return { ok: true, agent: raw };
@@ -6,7 +6,10 @@
6
6
  //
7
7
  // SECURITY: the banner shows the credential SOURCE, never the raw API key
8
8
  // (owner decision: no masking needed because the key is simply not displayed).
9
- // Zero dependencies — ships in the npm package alongside chorus.mjs.
9
+ // Zero dependencies (beyond the pure backendCli descriptor) — ships in the npm
10
+ // package alongside chorus.mjs.
11
+
12
+ import { backendCli } from "./daemon-agent.mjs";
10
13
 
11
14
  /**
12
15
  * @typedef {Object} BannerInfo
@@ -16,8 +19,8 @@
16
19
  * @property {string} agentUuid authenticated agent uuid.
17
20
  * @property {"yolo"|"chorus"} permissionMode
18
21
  * @property {string} credentialSource resolved credential source (flag/env/login-file/…).
19
- * @property {string} agentType local agent backend (e.g. claude-code).
20
- * @property {string|null} claudePath resolved claude path, or null when not found.
22
+ * @property {string} agentType local agent backend (claude-code | codex) — drives the CLI row label.
23
+ * @property {string|null} cliPath resolved path of the SELECTED backend's CLI, or null when not found.
21
24
  * @property {string} [connection] connection state line (default "connecting…").
22
25
  * @property {string} [configPath] absolute path to the daemon.json the CLI reads.
23
26
  * @property {boolean} [configExists] whether that daemon.json exists on disk.
@@ -39,7 +42,12 @@ export function bannerRows(info) {
39
42
  info.permissionMode === "yolo"
40
43
  ? "YOLO ⚠ (full autonomy — Bash/write/any command)"
41
44
  : "chorus-only (Chorus MCP tools only)";
42
- const claude = info.claudePath ? `found: ${info.claudePath}` : "NOT FOUND — install `claude` or set CHORUS_CLAUDE_PATH";
45
+ // The CLI row names the SELECTED backend (claude-code "claude", codex
46
+ // "codex") so a `--agent codex` run never mislabels itself as claude.
47
+ const cli = backendCli(info.agentType);
48
+ const cliValue = info.cliPath
49
+ ? `found: ${info.cliPath}`
50
+ : `NOT FOUND — install \`${cli.name}\` or set ${cli.envVar}`;
43
51
  const rows = [
44
52
  ["Version", `chorus v${info.version}`],
45
53
  ["Server", info.url],
@@ -48,7 +56,7 @@ export function bannerRows(info) {
48
56
  ["Permission", permission],
49
57
  ["Credentials", `source: ${info.credentialSource}`],
50
58
  ["Connection", info.connection ?? "connecting…"],
51
- ["claude CLI", claude],
59
+ [`${cli.name} CLI`, cliValue],
52
60
  ];
53
61
  // Config file row — shown only when the path is known. Tells the operator
54
62
  // exactly which daemon.json the CLI read (and whether it exists), so a
@@ -60,6 +68,36 @@ export function bannerRows(info) {
60
68
  return rows;
61
69
  }
62
70
 
71
+ /**
72
+ * The prominent warning shown at startup when the SELECTED backend's executable
73
+ * cannot be resolved. Mirrors `yoloWarningLine()`'s loud single-line style so a
74
+ * missing binary is visible in an unattended / systemd journal immediately,
75
+ * rather than only when a wake later fails. The daemon stays non-fatal — it still
76
+ * subscribes. Names the backend's own binary + override env var (claude /
77
+ * CHORUS_CLAUDE_PATH, or codex / CHORUS_CODEX_PATH).
78
+ * @param {string} agentType
79
+ * @returns {string}
80
+ */
81
+ export function agentNotFoundWarningLine(agentType) {
82
+ const { name, envVar } = backendCli(agentType);
83
+ return (
84
+ `⚠ ${name} CLI NOT FOUND on PATH — wakes will FAIL until you install \`${name}\` ` +
85
+ `or set ${envVar}. For a systemd/boot service, ensure the unit's PATH ` +
86
+ "includes the directory holding the binary (e.g. ~/.local/bin). The daemon will " +
87
+ "still subscribe, but every task dispatch errors until this is fixed."
88
+ );
89
+ }
90
+
91
+ /**
92
+ * Back-compat alias — the original claude-only warning. Delegates to
93
+ * {@link agentNotFoundWarningLine} for the default claude-code backend so older
94
+ * imports keep working.
95
+ * @returns {string}
96
+ */
97
+ export function claudeNotFoundWarningLine() {
98
+ return agentNotFoundWarningLine("claude-code");
99
+ }
100
+
63
101
  /**
64
102
  * Format the startup banner. On a TTY, draws a Unicode box; otherwise emits
65
103
  * plain `label: value` lines (no box-drawing chars, no width math) so piped