@chorus-aidlc/chorus 0.16.3 → 0.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (355) hide show
  1. package/.next/standalone/.next/BUILD_ID +1 -1
  2. package/.next/standalone/.next/app-build-manifest.json +445 -445
  3. package/.next/standalone/.next/app-path-routes-manifest.json +54 -54
  4. package/.next/standalone/.next/build-manifest.json +5 -5
  5. package/.next/standalone/.next/prerender-manifest.json +42 -42
  6. package/.next/standalone/.next/server/app/(dashboard)/project-groups/[uuid]/page.js +1 -1
  7. package/.next/standalone/.next/server/app/(dashboard)/project-groups/[uuid]/page.js.nft.json +1 -1
  8. package/.next/standalone/.next/server/app/(dashboard)/project-groups/[uuid]/page_client-reference-manifest.js +1 -1
  9. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/activity/page.js +1 -1
  10. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/activity/page_client-reference-manifest.js +1 -1
  11. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/dashboard/[ideaUuid]/page.js +1 -1
  12. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/dashboard/[ideaUuid]/page_client-reference-manifest.js +1 -1
  13. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/dashboard/page.js +2 -2
  14. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/dashboard/page.js.nft.json +1 -1
  15. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/dashboard/page_client-reference-manifest.js +1 -1
  16. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/documents/[documentUuid]/page.js +2 -2
  17. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/documents/[documentUuid]/page_client-reference-manifest.js +1 -1
  18. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/documents/page.js +2 -2
  19. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/documents/page_client-reference-manifest.js +1 -1
  20. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/graph/page.js +2 -2
  21. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/graph/page.js.nft.json +1 -1
  22. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/graph/page_client-reference-manifest.js +1 -1
  23. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/[proposalUuid]/page.js +2 -2
  24. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/[proposalUuid]/page.js.nft.json +1 -1
  25. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/[proposalUuid]/page_client-reference-manifest.js +1 -1
  26. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/new/page.js +1 -1
  27. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/new/page_client-reference-manifest.js +1 -1
  28. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/page.js +2 -2
  29. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/page_client-reference-manifest.js +1 -1
  30. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/tasks/[taskUuid]/page.js +1 -1
  31. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/tasks/[taskUuid]/page.js.nft.json +1 -1
  32. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/tasks/[taskUuid]/page_client-reference-manifest.js +1 -1
  33. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/tasks/page.js +1 -1
  34. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/tasks/page.js.nft.json +1 -1
  35. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/tasks/page_client-reference-manifest.js +1 -1
  36. package/.next/standalone/.next/server/app/(dashboard)/projects/page.js +1 -1
  37. package/.next/standalone/.next/server/app/(dashboard)/projects/page.js.nft.json +1 -1
  38. package/.next/standalone/.next/server/app/(dashboard)/projects/page_client-reference-manifest.js +1 -1
  39. package/.next/standalone/.next/server/app/(dashboard)/settings/page.js +2 -2
  40. package/.next/standalone/.next/server/app/(dashboard)/settings/page.js.nft.json +1 -1
  41. package/.next/standalone/.next/server/app/(dashboard)/settings/page_client-reference-manifest.js +1 -1
  42. package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  43. package/.next/standalone/.next/server/app/_not-found.html +2 -2
  44. package/.next/standalone/.next/server/app/_not-found.rsc +1 -1
  45. package/.next/standalone/.next/server/app/admin/companies/[uuid]/page_client-reference-manifest.js +1 -1
  46. package/.next/standalone/.next/server/app/admin/companies/new/page_client-reference-manifest.js +1 -1
  47. package/.next/standalone/.next/server/app/admin/companies/new.html +2 -2
  48. package/.next/standalone/.next/server/app/admin/companies/new.rsc +1 -1
  49. package/.next/standalone/.next/server/app/admin/companies/page_client-reference-manifest.js +1 -1
  50. package/.next/standalone/.next/server/app/admin/companies.html +2 -2
  51. package/.next/standalone/.next/server/app/admin/companies.rsc +1 -1
  52. package/.next/standalone/.next/server/app/admin/page_client-reference-manifest.js +1 -1
  53. package/.next/standalone/.next/server/app/admin.html +2 -2
  54. package/.next/standalone/.next/server/app/admin.rsc +1 -1
  55. package/.next/standalone/.next/server/app/api/admin/companies/[uuid]/route_client-reference-manifest.js +1 -1
  56. package/.next/standalone/.next/server/app/api/admin/companies/route_client-reference-manifest.js +1 -1
  57. package/.next/standalone/.next/server/app/api/admin/login/route_client-reference-manifest.js +1 -1
  58. package/.next/standalone/.next/server/app/api/admin/session/route_client-reference-manifest.js +1 -1
  59. package/.next/standalone/.next/server/app/api/agent-connections/route_client-reference-manifest.js +1 -1
  60. package/.next/standalone/.next/server/app/api/agents/[uuid]/route_client-reference-manifest.js +1 -1
  61. package/.next/standalone/.next/server/app/api/agents/[uuid]/sessions/route_client-reference-manifest.js +1 -1
  62. package/.next/standalone/.next/server/app/api/agents/route_client-reference-manifest.js +1 -1
  63. package/.next/standalone/.next/server/app/api/api-keys/[uuid]/route_client-reference-manifest.js +1 -1
  64. package/.next/standalone/.next/server/app/api/api-keys/route_client-reference-manifest.js +1 -1
  65. package/.next/standalone/.next/server/app/api/auth/callback/route_client-reference-manifest.js +1 -1
  66. package/.next/standalone/.next/server/app/api/auth/check-default/route_client-reference-manifest.js +1 -1
  67. package/.next/standalone/.next/server/app/api/auth/company-oidc/route_client-reference-manifest.js +1 -1
  68. package/.next/standalone/.next/server/app/api/auth/default-login/route_client-reference-manifest.js +1 -1
  69. package/.next/standalone/.next/server/app/api/auth/identify/route_client-reference-manifest.js +1 -1
  70. package/.next/standalone/.next/server/app/api/auth/logout/route_client-reference-manifest.js +1 -1
  71. package/.next/standalone/.next/server/app/api/auth/me/route_client-reference-manifest.js +1 -1
  72. package/.next/standalone/.next/server/app/api/auth/sync-token/route_client-reference-manifest.js +1 -1
  73. package/.next/standalone/.next/server/app/api/comments/route_client-reference-manifest.js +1 -1
  74. package/.next/standalone/.next/server/app/api/daemon/connection-heartbeat/route_client-reference-manifest.js +1 -1
  75. package/.next/standalone/.next/server/app/api/daemon/control/route_client-reference-manifest.js +1 -1
  76. package/.next/standalone/.next/server/app/api/daemon/directory-request/report/route_client-reference-manifest.js +1 -1
  77. package/.next/standalone/.next/server/app/api/daemon/execution-state/route_client-reference-manifest.js +1 -1
  78. package/.next/standalone/.next/server/app/api/daemon/executions/route_client-reference-manifest.js +1 -1
  79. package/.next/standalone/.next/server/app/api/daemon/pending-turns/route_client-reference-manifest.js +1 -1
  80. package/.next/standalone/.next/server/app/api/daemon/report-interrupt/route_client-reference-manifest.js +1 -1
  81. package/.next/standalone/.next/server/app/api/daemon/resume/route_client-reference-manifest.js +1 -1
  82. package/.next/standalone/.next/server/app/api/daemon/transcript/route_client-reference-manifest.js +1 -1
  83. package/.next/standalone/.next/server/app/api/daemon/turn-advance/route.js +1 -1
  84. package/.next/standalone/.next/server/app/api/daemon/turn-advance/route_client-reference-manifest.js +1 -1
  85. package/.next/standalone/.next/server/app/api/daemon-directory-requests/[uuid]/route_client-reference-manifest.js +1 -1
  86. package/.next/standalone/.next/server/app/api/daemon-directory-requests/route_client-reference-manifest.js +1 -1
  87. package/.next/standalone/.next/server/app/api/daemon-sessions/[sessionUuid]/instruction/route_client-reference-manifest.js +1 -1
  88. package/.next/standalone/.next/server/app/api/daemon-sessions/[sessionUuid]/repoint/route_client-reference-manifest.js +1 -1
  89. package/.next/standalone/.next/server/app/api/daemon-sessions/[sessionUuid]/route_client-reference-manifest.js +1 -1
  90. package/.next/standalone/.next/server/app/api/daemon-sessions/ad-hoc/route_client-reference-manifest.js +1 -1
  91. package/.next/standalone/.next/server/app/api/daemon-sessions/route_client-reference-manifest.js +1 -1
  92. package/.next/standalone/.next/server/app/api/documents/[uuid]/route_client-reference-manifest.js +1 -1
  93. package/.next/standalone/.next/server/app/api/entities/[type]/[uuid]/root-idea/route_client-reference-manifest.js +1 -1
  94. package/.next/standalone/.next/server/app/api/events/notifications/route_client-reference-manifest.js +1 -1
  95. package/.next/standalone/.next/server/app/api/events/route_client-reference-manifest.js +1 -1
  96. package/.next/standalone/.next/server/app/api/health/route_client-reference-manifest.js +1 -1
  97. package/.next/standalone/.next/server/app/api/ideas/[uuid]/claim/route_client-reference-manifest.js +1 -1
  98. package/.next/standalone/.next/server/app/api/ideas/[uuid]/move/preview/route_client-reference-manifest.js +1 -1
  99. package/.next/standalone/.next/server/app/api/ideas/[uuid]/move/route_client-reference-manifest.js +1 -1
  100. package/.next/standalone/.next/server/app/api/ideas/[uuid]/parent/route_client-reference-manifest.js +1 -1
  101. package/.next/standalone/.next/server/app/api/ideas/[uuid]/release/route_client-reference-manifest.js +1 -1
  102. package/.next/standalone/.next/server/app/api/ideas/[uuid]/route_client-reference-manifest.js +1 -1
  103. package/.next/standalone/.next/server/app/api/ideas/[uuid]/wake-preview/route_client-reference-manifest.js +1 -1
  104. package/.next/standalone/.next/server/app/api/ideas/conversational/route_client-reference-manifest.js +1 -1
  105. package/.next/standalone/.next/server/app/api/mcp/route.js +3 -3
  106. package/.next/standalone/.next/server/app/api/mcp/route_client-reference-manifest.js +1 -1
  107. package/.next/standalone/.next/server/app/api/me/assignments/route.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/project-visits/pin/route_client-reference-manifest.js +1 -1
  120. package/.next/standalone/.next/server/app/api/project-visits/route_client-reference-manifest.js +1 -1
  121. package/.next/standalone/.next/server/app/api/project-visits/visit/route_client-reference-manifest.js +1 -1
  122. package/.next/standalone/.next/server/app/api/projects/[uuid]/activity/route_client-reference-manifest.js +1 -1
  123. package/.next/standalone/.next/server/app/api/projects/[uuid]/agent-cwds/route_client-reference-manifest.js +1 -1
  124. package/.next/standalone/.next/server/app/api/projects/[uuid]/available/route.js +1 -1
  125. package/.next/standalone/.next/server/app/api/projects/[uuid]/available/route_client-reference-manifest.js +1 -1
  126. package/.next/standalone/.next/server/app/api/projects/[uuid]/documents/route_client-reference-manifest.js +1 -1
  127. package/.next/standalone/.next/server/app/api/projects/[uuid]/group/route_client-reference-manifest.js +1 -1
  128. package/.next/standalone/.next/server/app/api/projects/[uuid]/ideas/route_client-reference-manifest.js +1 -1
  129. package/.next/standalone/.next/server/app/api/projects/[uuid]/ideas/tracker/route_client-reference-manifest.js +1 -1
  130. package/.next/standalone/.next/server/app/api/projects/[uuid]/proposals/[proposalUuid]/validate/route_client-reference-manifest.js +1 -1
  131. package/.next/standalone/.next/server/app/api/projects/[uuid]/proposals/route_client-reference-manifest.js +1 -1
  132. package/.next/standalone/.next/server/app/api/projects/[uuid]/proposals/summary/route_client-reference-manifest.js +1 -1
  133. package/.next/standalone/.next/server/app/api/projects/[uuid]/resource-graph/route_client-reference-manifest.js +1 -1
  134. package/.next/standalone/.next/server/app/api/projects/[uuid]/route_client-reference-manifest.js +1 -1
  135. package/.next/standalone/.next/server/app/api/projects/[uuid]/stats/route_client-reference-manifest.js +1 -1
  136. package/.next/standalone/.next/server/app/api/projects/[uuid]/tasks/dependencies/route_client-reference-manifest.js +1 -1
  137. package/.next/standalone/.next/server/app/api/projects/[uuid]/tasks/route_client-reference-manifest.js +1 -1
  138. package/.next/standalone/.next/server/app/api/projects/agent-cwd-options/route_client-reference-manifest.js +1 -1
  139. package/.next/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  140. package/.next/standalone/.next/server/app/api/proposals/[uuid]/approve/route_client-reference-manifest.js +1 -1
  141. package/.next/standalone/.next/server/app/api/proposals/[uuid]/close/route_client-reference-manifest.js +1 -1
  142. package/.next/standalone/.next/server/app/api/proposals/[uuid]/reject/route_client-reference-manifest.js +1 -1
  143. package/.next/standalone/.next/server/app/api/proposals/[uuid]/revoke/route_client-reference-manifest.js +1 -1
  144. package/.next/standalone/.next/server/app/api/proposals/[uuid]/route_client-reference-manifest.js +1 -1
  145. package/.next/standalone/.next/server/app/api/references/[uuid]/route_client-reference-manifest.js +1 -1
  146. package/.next/standalone/.next/server/app/api/references/route_client-reference-manifest.js +1 -1
  147. package/.next/standalone/.next/server/app/api/search/route_client-reference-manifest.js +1 -1
  148. package/.next/standalone/.next/server/app/api/session/route_client-reference-manifest.js +1 -1
  149. package/.next/standalone/.next/server/app/api/sessions/[uuid]/route_client-reference-manifest.js +1 -1
  150. package/.next/standalone/.next/server/app/api/tasks/[uuid]/claim/route_client-reference-manifest.js +1 -1
  151. package/.next/standalone/.next/server/app/api/tasks/[uuid]/dependencies/[dependsOnUuid]/route_client-reference-manifest.js +1 -1
  152. package/.next/standalone/.next/server/app/api/tasks/[uuid]/dependencies/route_client-reference-manifest.js +1 -1
  153. package/.next/standalone/.next/server/app/api/tasks/[uuid]/release/route_client-reference-manifest.js +1 -1
  154. package/.next/standalone/.next/server/app/api/tasks/[uuid]/route_client-reference-manifest.js +1 -1
  155. package/.next/standalone/.next/server/app/api/tasks/[uuid]/sessions/route_client-reference-manifest.js +1 -1
  156. package/.next/standalone/.next/server/app/index.html +2 -2
  157. package/.next/standalone/.next/server/app/index.rsc +1 -1
  158. package/.next/standalone/.next/server/app/login/admin/page_client-reference-manifest.js +1 -1
  159. package/.next/standalone/.next/server/app/login/admin.html +2 -2
  160. package/.next/standalone/.next/server/app/login/admin.rsc +1 -1
  161. package/.next/standalone/.next/server/app/login/callback/page_client-reference-manifest.js +1 -1
  162. package/.next/standalone/.next/server/app/login/callback.html +2 -2
  163. package/.next/standalone/.next/server/app/login/callback.rsc +1 -1
  164. package/.next/standalone/.next/server/app/login/page_client-reference-manifest.js +1 -1
  165. package/.next/standalone/.next/server/app/login/pick-workspace/page_client-reference-manifest.js +1 -1
  166. package/.next/standalone/.next/server/app/login/pick-workspace.html +2 -2
  167. package/.next/standalone/.next/server/app/login/pick-workspace.rsc +1 -1
  168. package/.next/standalone/.next/server/app/login.html +2 -2
  169. package/.next/standalone/.next/server/app/login.rsc +1 -1
  170. package/.next/standalone/.next/server/app/onboarding/page.js +2 -2
  171. package/.next/standalone/.next/server/app/onboarding/page.js.nft.json +1 -1
  172. package/.next/standalone/.next/server/app/onboarding/page_client-reference-manifest.js +1 -1
  173. package/.next/standalone/.next/server/app/onboarding.html +2 -2
  174. package/.next/standalone/.next/server/app/onboarding.rsc +2 -2
  175. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  176. package/.next/standalone/.next/server/app/projects.html +2 -2
  177. package/.next/standalone/.next/server/app/projects.rsc +2 -2
  178. package/.next/standalone/.next/server/app/settings.html +2 -2
  179. package/.next/standalone/.next/server/app/settings.rsc +3 -3
  180. package/.next/standalone/.next/server/app-paths-manifest.json +54 -54
  181. package/.next/standalone/.next/server/chunks/1114.js +1 -1
  182. package/.next/standalone/.next/server/chunks/1318.js +1 -1
  183. package/.next/standalone/.next/server/chunks/1437.js +1 -0
  184. package/.next/standalone/.next/server/chunks/1559.js +2 -2
  185. package/.next/standalone/.next/server/chunks/2572.js +1 -1
  186. package/.next/standalone/.next/server/chunks/2618.js +1 -1
  187. package/.next/standalone/.next/server/chunks/2961.js +1 -1
  188. package/.next/standalone/.next/server/chunks/{9793.js → 3045.js} +1 -1
  189. package/.next/standalone/.next/server/chunks/3831.js +37 -0
  190. package/.next/standalone/.next/server/chunks/4827.js +1 -1
  191. package/.next/standalone/.next/server/chunks/5245.js +1 -1
  192. package/.next/standalone/.next/server/chunks/{4394.js → 5706.js} +1 -1
  193. package/.next/standalone/.next/server/chunks/6113.js +1 -1
  194. package/.next/standalone/.next/server/chunks/6207.js +1 -1
  195. package/.next/standalone/.next/server/chunks/6506.js +2 -2
  196. package/.next/standalone/.next/server/chunks/6515.js +2 -2
  197. package/.next/standalone/.next/server/chunks/679.js +1 -1
  198. package/.next/standalone/.next/server/chunks/7368.js +1 -1
  199. package/.next/standalone/.next/server/chunks/7530.js +1 -1
  200. package/.next/standalone/.next/server/chunks/8454.js +1 -1
  201. package/.next/standalone/.next/server/chunks/920.js +1 -1
  202. package/.next/standalone/.next/server/chunks/9213.js +1 -1
  203. package/.next/standalone/.next/server/chunks/9378.js +1 -1
  204. package/.next/standalone/.next/server/chunks/9449.js +1 -0
  205. package/.next/standalone/.next/server/chunks/9458.js +1 -0
  206. package/.next/standalone/.next/server/middleware-build-manifest.js +1 -1
  207. package/.next/standalone/.next/server/middleware-manifest.json +5 -5
  208. package/.next/standalone/.next/server/pages/404.html +2 -2
  209. package/.next/standalone/.next/server/pages/500.html +1 -1
  210. package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
  211. package/.next/standalone/.next/server/server-reference-manifest.json +1 -1
  212. package/.next/standalone/.next/static/chunks/{11595.97e534422c57aee1.js → 11595.bbe40924d18958bf.js} +1 -1
  213. package/.next/standalone/.next/static/chunks/18139-e6ef4b5869593f8e.js +1 -0
  214. package/.next/standalone/.next/static/chunks/28856-ef2cb58fbd404ef9.js +1 -0
  215. package/.next/standalone/.next/static/chunks/{31308-fda6febfb2882a28.js → 31308-bb4a97b3f39c22dd.js} +1 -1
  216. package/.next/standalone/.next/static/chunks/{33456.6dc44a6aca1a01fd.js → 33456.5499eb8e892b110a.js} +1 -1
  217. package/.next/standalone/.next/static/chunks/{4860.7873ebc9ba435c8c.js → 4860.be77046fb2b3a2bd.js} +1 -1
  218. package/.next/standalone/.next/static/chunks/66873-e3be53f41b3f2255.js +1 -0
  219. package/.next/standalone/.next/static/chunks/70303-aec3d52ad87602a3.js +1 -0
  220. package/.next/standalone/.next/static/chunks/76201-83b26515f85ce37c.js +1 -0
  221. package/.next/standalone/.next/static/chunks/78917-a8a8dff98857c045.js +1 -0
  222. package/.next/standalone/.next/static/chunks/{94643-01be319472d751b3.js → 94643-ffa140f765c73daf.js} +1 -1
  223. package/.next/standalone/.next/static/chunks/97663-9c3ae4fd60b353db.js +1 -0
  224. package/.next/standalone/.next/static/chunks/{99373.d0e808c18408b8da.js → 99373.111493dc260a2a04.js} +1 -1
  225. package/.next/standalone/.next/static/chunks/app/(dashboard)/{layout-b742c51c0a764daf.js → layout-40fe7d026c5a7c6d.js} +1 -1
  226. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/dashboard/page-87d4d0fe90fca28c.js +1 -0
  227. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/documents/[documentUuid]/page-1206abaee85dc915.js +1 -0
  228. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/documents/{page-425acbe9ade5fa83.js → page-474e494097c8945f.js} +1 -1
  229. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/graph/page-e902b19328092ccf.js +1 -0
  230. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/[proposalUuid]/page-f273288c3530aa0f.js +1 -0
  231. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/new/page-6568a7b08bf9a54b.js +1 -0
  232. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/page-fbd3c27b68666234.js +1 -0
  233. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/tasks/[taskUuid]/{page-58b48aa0a11603c3.js → page-15bb6e1696668512.js} +1 -1
  234. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/tasks/{page-286faced32c6133f.js → page-2bea97214b1595cc.js} +1 -1
  235. package/.next/standalone/.next/static/chunks/app/(dashboard)/settings/page-2bf7ceee62b574c7.js +1 -0
  236. package/.next/standalone/.next/static/chunks/app/onboarding/{page-5c82cf3abd856301.js → page-540da64d7ba16dc7.js} +1 -1
  237. package/.next/standalone/.next/static/chunks/{webpack-fa066d7ff9ab2b29.js → webpack-7cbb3ba6792f1fb3.js} +1 -1
  238. package/.next/standalone/package.json +1 -1
  239. package/.next/standalone/public/chorus-plugin/.claude-plugin/plugin.json +1 -1
  240. package/.next/standalone/public/chorus-plugin/bin/chorus-api.sh +44 -1
  241. package/.next/standalone/public/chorus-plugin/bin/on-session-start.sh +4 -3
  242. package/.next/standalone/public/chorus-plugin/bin/tests/test-mcp-cli-delegation.sh +244 -0
  243. package/.next/standalone/public/chorus-plugin/skills/brainstorm/SKILL.md +1 -1
  244. package/.next/standalone/public/chorus-plugin/skills/chorus/SKILL.md +19 -1
  245. package/.next/standalone/public/chorus-plugin/skills/chorus-cli/SKILL.md +57 -0
  246. package/.next/standalone/public/chorus-plugin/skills/develop/SKILL.md +2 -2
  247. package/.next/standalone/public/chorus-plugin/skills/docs/SKILL.md +1 -1
  248. package/.next/standalone/public/chorus-plugin/skills/idea/SKILL.md +1 -1
  249. package/.next/standalone/public/chorus-plugin/skills/openspec-aware/SKILL.md +85 -42
  250. package/.next/standalone/public/chorus-plugin/skills/orchestrate/SKILL.md +1 -1
  251. package/.next/standalone/public/chorus-plugin/skills/proposal/SKILL.md +2 -2
  252. package/.next/standalone/public/chorus-plugin/skills/quick-dev/SKILL.md +1 -1
  253. package/.next/standalone/public/chorus-plugin/skills/review/SKILL.md +1 -1
  254. package/.next/standalone/public/chorus-plugin/skills/yolo/SKILL.md +3 -3
  255. package/.next/standalone/public/dsh-credentials.sh +30 -0
  256. package/.next/standalone/public/install-codex.sh +21 -406
  257. package/.next/standalone/public/install-kiro.sh +20 -344
  258. package/.next/standalone/public/install-opencode.sh +20 -275
  259. package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-brainstorm/SKILL.md +1 -1
  260. package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-cli/SKILL.md +57 -0
  261. package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-develop/SKILL.md +2 -2
  262. package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-docs/SKILL.md +1 -1
  263. package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-idea/SKILL.md +1 -1
  264. package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-openspec-aware/SKILL.md +85 -42
  265. package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-orchestrate/SKILL.md +1 -1
  266. package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-proposal/SKILL.md +2 -2
  267. package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-quick-dev/SKILL.md +1 -1
  268. package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-review/SKILL.md +1 -1
  269. package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-yolo/SKILL.md +3 -3
  270. package/.next/standalone/public/kiro-plugin/bin/chorus-api.sh +44 -1
  271. package/.next/standalone/public/kiro-plugin/bin/on-agent-spawn.sh +6 -4
  272. package/.next/standalone/public/kiro-plugin/manifest.txt +41 -0
  273. package/.next/standalone/public/skill/brainstorm-chorus/SKILL.md +1 -1
  274. package/.next/standalone/public/skill/chorus/SKILL.md +19 -1
  275. package/.next/standalone/public/skill/code-reviewer-chorus/SKILL.md +1 -1
  276. package/.next/standalone/public/skill/develop-chorus/SKILL.md +1 -1
  277. package/.next/standalone/public/skill/docs-chorus/SKILL.md +1 -1
  278. package/.next/standalone/public/skill/idea-chorus/SKILL.md +1 -1
  279. package/.next/standalone/public/skill/orchestrate-chorus/SKILL.md +1 -1
  280. package/.next/standalone/public/skill/proposal-chorus/SKILL.md +1 -1
  281. package/.next/standalone/public/skill/proposal-reviewer-chorus/SKILL.md +1 -1
  282. package/.next/standalone/public/skill/quick-dev-chorus/SKILL.md +1 -1
  283. package/.next/standalone/public/skill/review-chorus/SKILL.md +1 -1
  284. package/.next/standalone/public/skill/task-reviewer-chorus/SKILL.md +1 -1
  285. package/.next/standalone/public/skill/yolo-chorus/SKILL.md +1 -1
  286. package/.next/standalone/public/test-dsh-credentials.sh +39 -0
  287. package/.next/standalone/public/test-install-codex.sh +31 -79
  288. package/README.ja.md +5 -3
  289. package/README.ko.md +5 -3
  290. package/README.md +5 -3
  291. package/README.zh.md +5 -3
  292. package/chorus.mjs +35 -1
  293. package/cli/agent-backend-prompt.mjs +94 -0
  294. package/cli/agents.mjs +329 -0
  295. package/cli/chorus-client.mjs +69 -0
  296. package/cli/claude-spawner.mjs +4 -0
  297. package/cli/client-args.mjs +11 -5
  298. package/cli/codex-spawner.mjs +11 -6
  299. package/cli/credentials.mjs +185 -3
  300. package/cli/daemon-agent.mjs +30 -5
  301. package/cli/daemon-banner.mjs +3 -3
  302. package/cli/daemon-config.mjs +27 -2
  303. package/cli/daemon-install-config.mjs +21 -14
  304. package/cli/daemon-rest-client.mjs +31 -8
  305. package/cli/daemon-service.mjs +120 -33
  306. package/cli/daemon.mjs +175 -28
  307. package/cli/dsh-managed-config.mjs +407 -0
  308. package/cli/dsh-spawner.mjs +445 -0
  309. package/cli/init/adapters.mjs +137 -0
  310. package/cli/init/agent-type-map.mjs +60 -0
  311. package/cli/init/chorus-plugin-consts.mjs +16 -0
  312. package/cli/init/codex-mcp-config.mjs +183 -0
  313. package/cli/init/contracts.mjs +120 -0
  314. package/cli/init/detect.mjs +97 -0
  315. package/cli/init/file-template.mjs +248 -0
  316. package/cli/init/install-methods.mjs +508 -0
  317. package/cli/init/registry.mjs +74 -0
  318. package/cli/init/run-command.mjs +30 -0
  319. package/cli/init/select.mjs +111 -0
  320. package/cli/init/steps/credential-seed.mjs +751 -0
  321. package/cli/init/steps/daemon-setup.mjs +246 -0
  322. package/cli/init/steps/plugin-install.mjs +37 -0
  323. package/cli/init-args.mjs +137 -0
  324. package/cli/init.mjs +198 -0
  325. package/cli/kiro-spawner.mjs +4 -0
  326. package/cli/login.mjs +26 -4
  327. package/cli/mcp-args.mjs +280 -0
  328. package/cli/mcp.mjs +164 -0
  329. package/cli/spawner-select.mjs +54 -2
  330. package/cli/turn-reporter.mjs +5 -2
  331. package/cli/upload-hooks.mjs +31 -1
  332. package/cli/waker.mjs +49 -6
  333. package/package.json +1 -1
  334. package/prisma/migrations/20260818024700_add_turn_backend_session_id/migration.sql +1 -0
  335. package/prisma/schema.prisma +3 -0
  336. package/.next/standalone/.next/server/chunks/3594.js +0 -1
  337. package/.next/standalone/.next/server/chunks/5351.js +0 -32
  338. package/.next/standalone/.next/server/chunks/6667.js +0 -1
  339. package/.next/standalone/.next/server/chunks/6995.js +0 -1
  340. package/.next/standalone/.next/static/chunks/19887-c0bb297a78a1c7cd.js +0 -1
  341. package/.next/standalone/.next/static/chunks/29108-5a11eea003f4cc11.js +0 -1
  342. package/.next/standalone/.next/static/chunks/53073-a7ed20af6538a178.js +0 -1
  343. package/.next/standalone/.next/static/chunks/6603-e70ddeab6ad09c50.js +0 -1
  344. package/.next/standalone/.next/static/chunks/78917-1b59cbb806b3ecfc.js +0 -1
  345. package/.next/standalone/.next/static/chunks/82751-3e161e1d8dbda3ac.js +0 -1
  346. package/.next/standalone/.next/static/chunks/99366-425e9ef22e60e3e2.js +0 -1
  347. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/dashboard/page-f636e00c28f425ea.js +0 -1
  348. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/documents/[documentUuid]/page-c004f1a194af7fa5.js +0 -1
  349. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/graph/page-fdd617457730a116.js +0 -1
  350. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/[proposalUuid]/page-6b3fb08d53826d02.js +0 -1
  351. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/new/page-d5b222f379b2e8ca.js +0 -1
  352. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/page-0a6c2d0e1b68e0e4.js +0 -1
  353. package/.next/standalone/.next/static/chunks/app/(dashboard)/settings/page-1507a761e67c2aa9.js +0 -1
  354. /package/.next/standalone/.next/static/{K8qIdwvKoIWbwQ_f01mnM → 0spgxl3lP26Fl1otd1D7R}/_buildManifest.js +0 -0
  355. /package/.next/standalone/.next/static/{K8qIdwvKoIWbwQ_f01mnM → 0spgxl3lP26Fl1otd1D7R}/_ssgManifest.js +0 -0
package/cli/login.mjs CHANGED
@@ -9,6 +9,7 @@ import { createInterface } from "node:readline";
9
9
 
10
10
  import { loginFilePath } from "./credentials.mjs";
11
11
  import { validateAndFetchIdentity } from "./chorus-client.mjs";
12
+ import { promptAgentBackend } from "./agent-backend-prompt.mjs";
12
13
 
13
14
  /**
14
15
  * Prompt for a line of input. When `mask` is true, typed characters are not
@@ -219,12 +220,21 @@ export function appendAgentConfig(agentObj, deps = {}) {
219
220
  * single flat credential — so one daemon can serve several agents. On an invalid
220
221
  * key, or a duplicate, nothing is written.
221
222
  *
223
+ * The agent backend (agent type) is captured too: an explicit `--agent` wins,
224
+ * otherwise an interactive menu is offered on a TTY (skipped on a non-TTY so a
225
+ * scripted login never blocks). No choice → nothing is written for the backend
226
+ * (the `--add` entry omits `agentType`; the single-agent config omits the
227
+ * top-level `agent`), so it inherits the daemon default — never a literal
228
+ * `claude-code`. See {@link promptAgentBackend}.
229
+ *
222
230
  * @param {{ url?: string, apiKey?: string, agent?: string, add?: boolean }} flags
223
231
  * @param {{
224
232
  * validate?: typeof validateAndFetchIdentity,
225
233
  * write?: typeof writeLoginFile,
226
234
  * appendAgent?: typeof appendAgentConfig,
227
235
  * prompt?: typeof prompt,
236
+ * promptBackend?: typeof promptAgentBackend,
237
+ * isTTY?: boolean,
228
238
  * log?: (m: string) => void,
229
239
  * errLog?: (m: string) => void,
230
240
  * }} [deps]
@@ -235,6 +245,8 @@ export async function runLogin(flags = {}, deps = {}) {
235
245
  const write = deps.write ?? writeLoginFile;
236
246
  const appendAgent = deps.appendAgent ?? appendAgentConfig;
237
247
  const ask = deps.prompt ?? prompt;
248
+ const promptBackend = deps.promptBackend ?? promptAgentBackend;
249
+ const isTTY = deps.isTTY ?? Boolean(process.stdin.isTTY);
238
250
  const log = deps.log ?? ((m) => process.stdout.write(m + "\n"));
239
251
  const errLog = deps.errLog ?? ((m) => process.stderr.write(m + "\n"));
240
252
 
@@ -259,10 +271,16 @@ export async function runLogin(flags = {}, deps = {}) {
259
271
  return 1;
260
272
  }
261
273
 
274
+ // Which agent backend should this agent use? Explicit --agent wins; otherwise
275
+ // offer the interactive menu on a TTY. `undefined` = no explicit choice → we
276
+ // write NO backend key so it inherits the daemon default (never claude-code).
277
+ let agentType = nonEmpty(flags.agent);
278
+ if (!agentType) agentType = await promptBackend({ ask, log, isTTY });
279
+
262
280
  // --add: append as an additional agent (multi-agent) instead of overwriting.
263
281
  if (flags.add) {
264
282
  const agentObj = { url, apiKey, agentUuid: identity.uuid, agentName: identity.name };
265
- if (nonEmpty(flags.agent)) agentObj.agentType = nonEmpty(flags.agent);
283
+ if (agentType) agentObj.agentType = agentType;
266
284
  const res = appendAgent(agentObj);
267
285
  if (!res.ok) {
268
286
  errLog(
@@ -270,13 +288,17 @@ export async function runLogin(flags = {}, deps = {}) {
270
288
  );
271
289
  return 1;
272
290
  }
273
- log(`Added agent ${identity.name} (${identity.uuid}) as agents[${res.index}] in ${res.path}.`);
291
+ const backendNote = agentType ? ` — backend: ${agentType}` : "";
292
+ log(`Added agent ${identity.name} (${identity.uuid}) as agents[${res.index}] in ${res.path}${backendNote}.`);
274
293
  log(`This daemon now serves ${res.agents.length} agent(s).`);
275
294
  return 0;
276
295
  }
277
296
 
278
- const path = write({ url, apiKey, agentUuid: identity.uuid, agentName: identity.name });
279
- log(`Logged in as ${identity.name} (${identity.uuid}).`);
297
+ const loginData = { url, apiKey, agentUuid: identity.uuid, agentName: identity.name };
298
+ if (agentType) loginData.agent = agentType;
299
+ const path = write(loginData);
300
+ const backendNote = agentType ? ` — backend: ${agentType}` : "";
301
+ log(`Logged in as ${identity.name} (${identity.uuid})${backendNote}.`);
280
302
  log(`Credentials saved to ${path}.`);
281
303
  return 0;
282
304
  }
@@ -0,0 +1,280 @@
1
+ // cli/mcp-args.mjs
2
+ // Pure, dependency-injected argument parser + assembler for the `chorus mcp`
3
+ // command group (call / whoami / list). No direct IO — file/stdin reads are
4
+ // injected so this is fully unit-testable. This is the byte-faithful
5
+ // replacement for the plugin's `json_encode_file` bash helper: a file's raw
6
+ // bytes become a JSON *string* value (equivalent to `jq -Rs '.'`), never
7
+ // re-parsed. See openspec/changes/add-cli-mcp-native-client/design.md.
8
+
9
+ /** Thrown on any structural / usage problem. The command layer maps it to a
10
+ * stderr diagnostic + a non-zero (usage) exit code. */
11
+ export class UsageError extends Error {
12
+ constructor(message) {
13
+ super(message);
14
+ this.name = "UsageError";
15
+ }
16
+ }
17
+
18
+ const ACTIONS = new Set(["call", "whoami", "list"]);
19
+
20
+ /** Flags that consume the following token as their value (or `--flag=value`). */
21
+ const VALUE_FLAGS = new Set(["--arg", "--arg-file", "--args-file", "--agent", "--url", "--api-key"]);
22
+
23
+ /**
24
+ * @typedef {Object} ParsedMcp
25
+ * @property {boolean} help `--help`/`-h` requested (short-circuits).
26
+ * @property {"call"|"whoami"|"list"|null} action
27
+ * @property {string|null} tool Tool name (call only).
28
+ * @property {string|null} positionalJson Base arguments as a JSON string.
29
+ * @property {string|null} argsFile Base arguments from a JSON file (`-`=stdin).
30
+ * @property {Array<{type:"arg"|"arg-file", key:string, raw:string}>} overrides
31
+ * Per-key overrides in command-line order. `type:"arg"` raw is the literal /
32
+ * `@file` value; `type:"arg-file"` raw is the path.
33
+ * @property {{ agent?:string, url?:string, apiKey?:string }} creds
34
+ */
35
+
36
+ /**
37
+ * Parse the argv AFTER the `mcp` subcommand word (i.e. `process.argv.slice(3)`).
38
+ * Structural only — file/stdin reads and JSON parsing happen in assembleArgs.
39
+ * @param {string[]} argv
40
+ * @returns {ParsedMcp}
41
+ * @throws {UsageError}
42
+ */
43
+ export function parseMcpArgs(argv) {
44
+ const out = /** @type {ParsedMcp} */ ({
45
+ help: false,
46
+ action: null,
47
+ tool: null,
48
+ positionalJson: null,
49
+ argsFile: null,
50
+ overrides: [],
51
+ creds: {},
52
+ });
53
+
54
+ // A leading --help/-h (before any action) is a group help request.
55
+ const tokens = [...argv];
56
+ const positionals = [];
57
+
58
+ for (let i = 0; i < tokens.length; i++) {
59
+ const tok = tokens[i];
60
+
61
+ if (tok === "--help" || tok === "-h") {
62
+ out.help = true;
63
+ continue;
64
+ }
65
+
66
+ if (tok.startsWith("--")) {
67
+ // Support both `--flag value` and `--flag=value`.
68
+ let name = tok;
69
+ let inlineValue = null;
70
+ const eq = tok.indexOf("=");
71
+ if (eq !== -1) {
72
+ name = tok.slice(0, eq);
73
+ inlineValue = tok.slice(eq + 1);
74
+ }
75
+
76
+ if (!VALUE_FLAGS.has(name)) {
77
+ throw new UsageError(`Unknown flag: ${name}`);
78
+ }
79
+
80
+ const value = inlineValue !== null ? inlineValue : tokens[++i];
81
+ if (value === undefined) {
82
+ throw new UsageError(`Flag ${name} requires a value`);
83
+ }
84
+
85
+ switch (name) {
86
+ case "--arg": {
87
+ const kv = splitKeyValue(value, "--arg");
88
+ out.overrides.push({ type: "arg", key: kv.key, raw: kv.value });
89
+ break;
90
+ }
91
+ case "--arg-file": {
92
+ const kv = splitKeyValue(value, "--arg-file");
93
+ out.overrides.push({ type: "arg-file", key: kv.key, raw: kv.value });
94
+ break;
95
+ }
96
+ case "--args-file":
97
+ out.argsFile = value;
98
+ break;
99
+ case "--agent":
100
+ out.creds.agent = value;
101
+ break;
102
+ case "--url":
103
+ out.creds.url = value;
104
+ break;
105
+ case "--api-key":
106
+ out.creds.apiKey = value;
107
+ break;
108
+ }
109
+ continue;
110
+ }
111
+
112
+ // Bare positional.
113
+ positionals.push(tok);
114
+ }
115
+
116
+ // First positional = action.
117
+ if (positionals.length === 0) {
118
+ if (out.help) return out; // `chorus mcp --help`
119
+ throw new UsageError("Missing action. Expected: call | whoami | list");
120
+ }
121
+ const action = positionals[0];
122
+ if (!ACTIONS.has(action)) {
123
+ throw new UsageError(`Unknown action "${action}". Expected: call | whoami | list`);
124
+ }
125
+ out.action = /** @type {"call"|"whoami"|"list"} */ (action);
126
+
127
+ if (action === "call") {
128
+ // positionals[1] = tool, positionals[2] = base JSON. No more.
129
+ out.tool = positionals[1] ?? null;
130
+ if (!out.help && !out.tool) throw new UsageError("`chorus mcp call` requires a <tool> name");
131
+ if (positionals.length > 3) {
132
+ throw new UsageError(
133
+ "Too many positional arguments. Usage: chorus mcp call <tool> ['<json>'] [flags]",
134
+ );
135
+ }
136
+ out.positionalJson = positionals[2] ?? null;
137
+ } else {
138
+ // whoami / list take no positional beyond the action.
139
+ if (positionals.length > 1) {
140
+ throw new UsageError(`\`chorus mcp ${action}\` takes no positional arguments`);
141
+ }
142
+ if (out.overrides.length || out.positionalJson || out.argsFile) {
143
+ throw new UsageError(`\`chorus mcp ${action}\` does not accept --arg/--arg-file/--args-file`);
144
+ }
145
+ }
146
+
147
+ return out;
148
+ }
149
+
150
+ /** Split `key=value` on the FIRST `=`. */
151
+ function splitKeyValue(token, flag) {
152
+ const eq = token.indexOf("=");
153
+ if (eq === -1) throw new UsageError(`${flag} expects key=value (got "${token}")`);
154
+ const key = token.slice(0, eq);
155
+ if (!key) throw new UsageError(`${flag} has an empty key (got "${token}")`);
156
+ return { key, value: token.slice(eq + 1) };
157
+ }
158
+
159
+ /**
160
+ * Build the tool `arguments` object from a parsed `call`. Layers sources, later
161
+ * overriding earlier, applied in command-line order:
162
+ * 1. base = positional JSON XOR --args-file (both → error; neither → {}).
163
+ * 2/3/4. --arg literal / --arg-file / @file → per-key overrides (files → string).
164
+ * File-fill sources inject file bytes as a JSON string (never JSON-parsed).
165
+ * At most one source may consume stdin (`-`).
166
+ *
167
+ * @param {ParsedMcp} parsed
168
+ * @param {{ readFile: (path:string)=>string, readStdin: ()=>string }} io
169
+ * @returns {Record<string, unknown>}
170
+ * @throws {UsageError}
171
+ */
172
+ export function assembleArgs(parsed, io) {
173
+ const { readFile, readStdin } = io;
174
+ let stdinUsed = false;
175
+ const consumeStdin = () => {
176
+ if (stdinUsed) throw new UsageError("stdin (-) can only be consumed by one argument");
177
+ stdinUsed = true;
178
+ try {
179
+ return readStdin();
180
+ } catch (e) {
181
+ throw new UsageError(`cannot read stdin: ${/** @type {Error} */ (e).message}`);
182
+ }
183
+ };
184
+ // A file-read failure (missing path, permissions) is a usage error, not a
185
+ // transport/tool error — wrap it as UsageError so the command layer maps it to
186
+ // the usage exit code (2), never the tool-error exit code (1).
187
+ const readPath = (path) => {
188
+ if (path === "-") return consumeStdin();
189
+ try {
190
+ return readFile(path);
191
+ } catch (e) {
192
+ throw new UsageError(`cannot read file "${path}": ${/** @type {Error} */ (e).message}`);
193
+ }
194
+ };
195
+
196
+ // 1. Base object.
197
+ if (parsed.positionalJson !== null && parsed.argsFile !== null) {
198
+ throw new UsageError(
199
+ "Provide the base arguments either as a positional JSON string OR --args-file, not both",
200
+ );
201
+ }
202
+ let args = {};
203
+ const rawBase =
204
+ parsed.positionalJson !== null
205
+ ? parsed.positionalJson
206
+ : parsed.argsFile !== null
207
+ ? readPath(parsed.argsFile)
208
+ : null;
209
+ if (rawBase !== null) {
210
+ let parsedBase;
211
+ try {
212
+ parsedBase = JSON.parse(rawBase);
213
+ } catch (err) {
214
+ const src = parsed.positionalJson !== null ? "positional JSON argument" : `--args-file (${parsed.argsFile})`;
215
+ throw new UsageError(`Invalid JSON in ${src}: ${/** @type {Error} */ (err).message}`);
216
+ }
217
+ if (parsedBase === null || typeof parsedBase !== "object" || Array.isArray(parsedBase)) {
218
+ throw new UsageError("Base arguments must be a JSON object");
219
+ }
220
+ args = parsedBase;
221
+ }
222
+
223
+ // 2/3/4. Per-key overrides in command-line order.
224
+ for (const ov of parsed.overrides) {
225
+ if (ov.type === "arg-file") {
226
+ args[ov.key] = readPath(ov.raw);
227
+ continue;
228
+ }
229
+ // type === "arg": interpret the raw value.
230
+ const raw = ov.raw;
231
+ if (raw.startsWith("@@")) {
232
+ // Escape: `@@rest` → literal `@rest`.
233
+ args[ov.key] = "@" + raw.slice(2);
234
+ } else if (raw.startsWith("@")) {
235
+ // `@path` file sugar (`@-` → stdin).
236
+ args[ov.key] = readPath(raw.slice(1));
237
+ } else {
238
+ args[ov.key] = raw;
239
+ }
240
+ }
241
+
242
+ return args;
243
+ }
244
+
245
+ /** Help text for the `chorus mcp` command group. */
246
+ export function mcpHelpText(version = "") {
247
+ const v = version ? ` v${version}` : "";
248
+ return `\
249
+ Chorus${v} — native MCP client
250
+
251
+ USAGE
252
+ chorus mcp call <tool> ['<json>'] [arg flags] Call an MCP tool as the resolved agent
253
+ chorus mcp whoami Print this agent's own UUID
254
+ chorus mcp list List the tools this agent may call
255
+
256
+ ARGUMENT FLAGS (call)
257
+ <json> Positional JSON object — the base arguments
258
+ --args-file <path> Read the whole arguments object from a JSON file ('-' = stdin)
259
+ --arg key=value Set key to the literal string value
260
+ --arg-file key=<path> Set key to a file's raw bytes as a string ('-' = stdin)
261
+ --arg key=@<path> Shorthand for --arg-file ('@-' = stdin; '@@x' = literal '@x')
262
+ (later --arg/--arg-file override earlier keys, in order)
263
+
264
+ CREDENTIALS (all actions)
265
+ --url <url> Chorus server URL (env: CHORUS_URL)
266
+ --api-key <cho_...> Agent API key (env: CHORUS_API_KEY)
267
+ --agent <name|uuid> Act as an agent from ~/.chorus/daemon.json agents[],
268
+ matched by its agentUuid or agentName (env:
269
+ CHORUS_AGENT_PROFILE). The key is read from daemon.json —
270
+ no need to pass/export CHORUS_API_KEY. A profile is
271
+ preferred over CHORUS_URL/CHORUS_API_KEY; required when
272
+ several agents are configured and no profile/flags/env.
273
+
274
+ OUTPUT
275
+ call prints the tool result's text verbatim on success (drop-in for
276
+ chorus-api.sh mcp-tool); tool/transport errors go to stderr, exit != 0.
277
+ whoami prints the bare agent UUID.
278
+ list prints one 'name — description' line per permitted tool.
279
+ `;
280
+ }
package/cli/mcp.mjs ADDED
@@ -0,0 +1,164 @@
1
+ // cli/mcp.mjs
2
+ // `chorus mcp` command group — the native MCP client surface (call / whoami /
3
+ // list). Thin orchestration over the pure arg engine (cli/mcp-args.mjs), the
4
+ // credential/identity resolver (cli/credentials.mjs), and the MCP client
5
+ // (cli/chorus-client.mjs). All IO + collaborators are injectable so this is
6
+ // unit-testable with fakes. See openspec/changes/add-cli-mcp-native-client/.
7
+
8
+ import { readFileSync } from "node:fs";
9
+ import { parseMcpArgs, assembleArgs, mcpHelpText, UsageError } from "./mcp-args.mjs";
10
+ import { resolveMcpCredentials } from "./credentials.mjs";
11
+ import { ChorusClient, validateAndFetchIdentity } from "./chorus-client.mjs";
12
+
13
+ // Exit codes (design.md "Output & exit-code semantics"):
14
+ const EXIT_OK = 0; // success
15
+ const EXIT_TOOL_ERROR = 1; // tool returned isError
16
+ const EXIT_USAGE = 2; // bad flags / JSON / ambiguity / transport / auth
17
+
18
+ /** First line of a (possibly multi-line) description, for the `list` output. */
19
+ function firstLine(s) {
20
+ const nl = s.indexOf("\n");
21
+ return nl === -1 ? s : s.slice(0, nl);
22
+ }
23
+
24
+ /**
25
+ * Announce the acting agent on stderr for the identity-oriented actions
26
+ * (whoami / list) when a NAMED agent was selected from daemon.json agents[].
27
+ * Never emitted for the flag/env path (label "flag"/"env") and never on
28
+ * `call` (whose stdout must stay a byte-exact tool payload).
29
+ */
30
+ function noticeActingAs(creds, err) {
31
+ if (creds.label && creds.label !== "flag" && creds.label !== "env") {
32
+ err.write(`(acting as agent "${creds.label}")\n`);
33
+ }
34
+ }
35
+
36
+ /**
37
+ * Run `chorus mcp <action> …`. Returns an exit code — never calls
38
+ * `process.exit` (the entry module owns process lifetime).
39
+ *
40
+ * @param {string[]} argv argv AFTER the `mcp` word (process.argv.slice(3)).
41
+ * @param {{
42
+ * version?: string,
43
+ * stdout?: { write(s:string):unknown },
44
+ * stderr?: { write(s:string):unknown },
45
+ * makeClient?: (o:{url:string,apiKey:string}) => any,
46
+ * readFile?: (path:string)=>string,
47
+ * readStdin?: ()=>string,
48
+ * resolveCreds?: (flags:any, deps:any)=>{url:string,apiKey:string,label:string},
49
+ * credsDeps?: any,
50
+ * }} [opts]
51
+ * @returns {Promise<number>}
52
+ */
53
+ export async function runMcp(argv, opts = {}) {
54
+ const version = opts.version ?? "";
55
+ const out = opts.stdout ?? process.stdout;
56
+ const err = opts.stderr ?? process.stderr;
57
+ const makeClient = opts.makeClient ?? ((o) => new ChorusClient(o));
58
+ const readFile = opts.readFile ?? ((p) => readFileSync(p, "utf8"));
59
+ // fd 0 = stdin; readFileSync(0) drains it synchronously (fine for a one-shot CLI).
60
+ const readStdin = opts.readStdin ?? (() => readFileSync(0, "utf8"));
61
+ const resolveCreds = opts.resolveCreds ?? resolveMcpCredentials;
62
+
63
+ // 1. Parse (structural).
64
+ let parsed;
65
+ try {
66
+ parsed = parseMcpArgs(argv);
67
+ } catch (e) {
68
+ if (e instanceof UsageError) {
69
+ err.write(`error: ${e.message}\n\n${mcpHelpText(version)}`);
70
+ return EXIT_USAGE;
71
+ }
72
+ throw e;
73
+ }
74
+
75
+ if (parsed.help || !parsed.action) {
76
+ out.write(mcpHelpText(version));
77
+ return EXIT_OK;
78
+ }
79
+
80
+ // 2. Resolve credentials + acting identity.
81
+ let creds;
82
+ try {
83
+ creds = resolveCreds(parsed.creds, opts.credsDeps ?? {});
84
+ } catch (e) {
85
+ err.write(`error: ${/** @type {Error} */ (e).message}\n`);
86
+ return EXIT_USAGE;
87
+ }
88
+
89
+ // 3. Dispatch the action.
90
+ if (parsed.action === "call") {
91
+ let args;
92
+ try {
93
+ args = assembleArgs(parsed, { readFile, readStdin });
94
+ } catch (e) {
95
+ if (e instanceof UsageError) {
96
+ err.write(`error: ${e.message}\n`);
97
+ return EXIT_USAGE;
98
+ }
99
+ throw e;
100
+ }
101
+ const client = makeClient({ url: creds.url, apiKey: creds.apiKey });
102
+ try {
103
+ const { isError, text } = await client.callToolRaw(parsed.tool, args);
104
+ if (isError) {
105
+ // Tool-level error → stderr, non-zero, stdout stays empty.
106
+ err.write(text.endsWith("\n") ? text : `${text}\n`);
107
+ return EXIT_TOOL_ERROR;
108
+ }
109
+ // Success → verbatim text on stdout, matching `chorus-api.sh mcp-tool`'s
110
+ // `jq -r` (which appends a single trailing newline).
111
+ out.write(`${text}\n`);
112
+ return EXIT_OK;
113
+ } catch (e) {
114
+ err.write(`error: ${/** @type {Error} */ (e).message}\n`);
115
+ return EXIT_USAGE;
116
+ } finally {
117
+ await safeDisconnect(client);
118
+ }
119
+ }
120
+
121
+ if (parsed.action === "whoami") {
122
+ noticeActingAs(creds, err);
123
+ try {
124
+ // Fresh identity via chorus_checkin every call — no on-disk cache.
125
+ const identity = await validateAndFetchIdentity(
126
+ { url: creds.url, apiKey: creds.apiKey },
127
+ { makeClient },
128
+ );
129
+ out.write(`${identity.uuid}\n`);
130
+ return EXIT_OK;
131
+ } catch (e) {
132
+ err.write(`error: ${/** @type {Error} */ (e).message}\n`);
133
+ return EXIT_USAGE;
134
+ }
135
+ }
136
+
137
+ if (parsed.action === "list") {
138
+ noticeActingAs(creds, err);
139
+ const client = makeClient({ url: creds.url, apiKey: creds.apiKey });
140
+ try {
141
+ const tools = await client.listTools();
142
+ for (const t of tools) {
143
+ out.write(t.description ? `${t.name} — ${firstLine(t.description)}\n` : `${t.name}\n`);
144
+ }
145
+ return EXIT_OK;
146
+ } catch (e) {
147
+ err.write(`error: ${/** @type {Error} */ (e).message}\n`);
148
+ return EXIT_USAGE;
149
+ } finally {
150
+ await safeDisconnect(client);
151
+ }
152
+ }
153
+
154
+ return EXIT_USAGE;
155
+ }
156
+
157
+ /** Disconnect without letting a teardown error mask the real result. */
158
+ async function safeDisconnect(client) {
159
+ try {
160
+ if (client && typeof client.disconnect === "function") await client.disconnect();
161
+ } catch {
162
+ // ignore
163
+ }
164
+ }
@@ -6,26 +6,78 @@
6
6
  // injected purely through the shared wake(...) contract.
7
7
  //
8
8
  // The function is TOTAL: resolveAgentType has already rejected unknown values
9
- // before this runs, so an unrecognized type here is not a user error path — we
9
+ // before this runs, so an UNRECOGNIZED type here is not a user error path — we
10
10
  // fall back to the safe default (claude-code) rather than throw.
11
+ //
12
+ // The `offline` type is the ONE known value that must NEVER reach that default:
13
+ // it is a non-wakeable classification (an agent parked in daemon.json only for the
14
+ // `chorus mcp` proxy key), so it gets an explicit branch returning the
15
+ // OfflineSpawner — a fail-closed no-op that logs and never spawns a subprocess.
16
+ // Without this branch, adding `offline` to KNOWN_AGENTS would let it fall through
17
+ // and silently wake Claude — the exact fail-open bug this guards against.
11
18
 
12
19
  import { ClaudeSpawner } from "./claude-spawner.mjs";
13
20
  import { CodexSpawner } from "./codex-spawner.mjs";
21
+ import { DshSpawner } from "./dsh-spawner.mjs";
14
22
  import { KiroSpawner } from "./kiro-spawner.mjs";
15
23
 
24
+ /**
25
+ * A fail-closed spawner for the `offline` agentType. It satisfies the shared
26
+ * wake(...) contract so the daemon's pipeline stays backend-agnostic, but it never
27
+ * spawns a process, never invokes `onChild` (so no server turn advances to
28
+ * running), and never falls through to a real backend. It simply logs that the
29
+ * agent is offline and resolves with a terminal no-op result (exitCode: null —
30
+ * matching the "skipping wake" convention of the real backends when their CLI is
31
+ * absent). An offline agent exists in daemon.json solely so `chorus mcp` can proxy
32
+ * through its key; the daemon must not wake it.
33
+ */
34
+ export class OfflineSpawner {
35
+ /** @param {{ logger?: any }} [opts] */
36
+ constructor({ logger } = {}) {
37
+ this.logger = logger;
38
+ }
39
+
40
+ /**
41
+ * @param {{ sessionId?: string }} [params]
42
+ * @returns {Promise<{ sessionId: string, exitCode: null, isNew: false }>}
43
+ */
44
+ async wake({ sessionId } = {}) {
45
+ this.logger?.warn?.(
46
+ "[Chorus] agent backend is 'offline' — no local agent to wake; dropping this wake " +
47
+ "(offline agents are proxied via `chorus mcp` only, never spawned).",
48
+ );
49
+ return { sessionId: sessionId ?? "", exitCode: null, isNew: false };
50
+ }
51
+ }
52
+
16
53
  /**
17
54
  * Construct the spawner backend for `agentType`.
18
- * @param {string} agentType "claude-code" | "codex" | "kiro" (already validated upstream).
55
+ * @param {string} agentType "claude-code" | "codex" | "kiro" | "dsh" | "offline"
56
+ * (already validated upstream). "offline" → OfflineSpawner (fail-closed no-op).
19
57
  * @param {{ logger?: any, permissionMode?: "chorus"|"yolo", creds?: { url: string, apiKey: string } }} [opts]
20
58
  * @returns {import("./codex-spawner.mjs").Spawner}
21
59
  */
22
60
  export function selectSpawner(agentType, opts = {}) {
23
61
  const { logger, permissionMode, creds } = opts;
62
+ if (agentType === "offline") {
63
+ // Fail-closed: an offline agent has no local backend. Return the no-op spawner
64
+ // explicitly so we NEVER fall through to the claude-code default below and wake
65
+ // Claude for an agent the operator classified as offline.
66
+ return new OfflineSpawner({ logger });
67
+ }
24
68
  if (agentType === "codex") {
25
69
  return new CodexSpawner({ logger, permissionMode, creds });
26
70
  }
27
71
  if (agentType === "kiro") {
28
72
  return new KiroSpawner({ logger, permissionMode, creds });
29
73
  }
74
+ if (agentType === "dsh") {
75
+ return new DshSpawner({
76
+ logger,
77
+ creds,
78
+ bundleVersion: opts.bundleVersion,
79
+ prepareManagedConfigFn: opts.prepareManagedConfigFn,
80
+ });
81
+ }
30
82
  return new ClaudeSpawner({ logger, permissionMode, creds });
31
83
  }
@@ -52,7 +52,7 @@ export const TURN_INTERRUPT_REASONS = new Set([
52
52
  * logger?: { info(m:string):void, warn(m:string):void, error(m:string):void },
53
53
  * fetchImpl?: typeof fetch, Injectable for tests.
54
54
  * }} opts
55
- * @returns {(params: { sessionId: string, status: "running"|"ended"|"interrupted", entityType?: string|null, entityUuid?: string|null, interruptedReason?: "user"|"crash"|"shutdown"|"invalid_path"|null, transcriptRelayError?: string|null, usage?: import("./upload-hooks.mjs").TokenUsage|null, coalescedCount?: number }) => Promise<void>}
55
+ * @returns {(params: { sessionId: string, turnUuid?: string|null, status: "running"|"ended"|"interrupted", entityType?: string|null, entityUuid?: string|null, interruptedReason?: "user"|"crash"|"shutdown"|"invalid_path"|null, transcriptRelayError?: string|null, usage?: import("./upload-hooks.mjs").TokenUsage|null, coalescedCount?: number }) => Promise<import("./daemon-rest-client.mjs").DaemonRestResult|undefined>}
56
56
  */
57
57
  export function createTurnReporter(opts) {
58
58
  const logger = opts.logger ?? NOOP_LOGGER;
@@ -69,6 +69,7 @@ export function createTurnReporter(opts) {
69
69
 
70
70
  return async function advanceTurn({
71
71
  sessionId,
72
+ turnUuid,
72
73
  status,
73
74
  entityType,
74
75
  entityUuid,
@@ -101,8 +102,9 @@ export function createTurnReporter(opts) {
101
102
  // entityType/entityUuid only when both are present, and transcriptRelayError only when
102
103
  // truthy (fix #444 follow-up) — and logs the failure cause on a network error / non-2xx.
103
104
  // We swallow the structured result so a failed report can never crash the wake path.
104
- await client.turnAdvance({
105
+ const result = await client.turnAdvance({
105
106
  sessionId,
107
+ turnUuid,
106
108
  status,
107
109
  entityType,
108
110
  entityUuid,
@@ -116,5 +118,6 @@ export function createTurnReporter(opts) {
116
118
  // client sends it only on the → running edge and only when > 1 (a single wake omits it).
117
119
  coalescedCount,
118
120
  });
121
+ return result;
119
122
  };
120
123
  }