@chorus-aidlc/chorus 0.16.4 → 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 (435) hide show
  1. package/.next/standalone/.next/BUILD_ID +1 -1
  2. package/.next/standalone/.next/app-build-manifest.json +420 -420
  3. package/.next/standalone/.next/app-path-routes-manifest.json +53 -53
  4. package/.next/standalone/.next/build-manifest.json +5 -5
  5. package/.next/standalone/.next/prerender-manifest.json +45 -45
  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.js.nft.json +1 -1
  28. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/new/page_client-reference-manifest.js +1 -1
  29. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/page.js +2 -2
  30. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/page_client-reference-manifest.js +1 -1
  31. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/tasks/[taskUuid]/page.js +1 -1
  32. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/tasks/[taskUuid]/page.js.nft.json +1 -1
  33. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/tasks/[taskUuid]/page_client-reference-manifest.js +1 -1
  34. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/tasks/page.js +1 -1
  35. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/tasks/page.js.nft.json +1 -1
  36. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/tasks/page_client-reference-manifest.js +1 -1
  37. package/.next/standalone/.next/server/app/(dashboard)/projects/page.js +1 -1
  38. package/.next/standalone/.next/server/app/(dashboard)/projects/page.js.nft.json +1 -1
  39. package/.next/standalone/.next/server/app/(dashboard)/projects/page_client-reference-manifest.js +1 -1
  40. package/.next/standalone/.next/server/app/(dashboard)/settings/page.js +2 -2
  41. package/.next/standalone/.next/server/app/(dashboard)/settings/page.js.nft.json +1 -1
  42. package/.next/standalone/.next/server/app/(dashboard)/settings/page_client-reference-manifest.js +1 -1
  43. package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  44. package/.next/standalone/.next/server/app/_not-found.html +2 -2
  45. package/.next/standalone/.next/server/app/_not-found.rsc +1 -1
  46. package/.next/standalone/.next/server/app/admin/companies/[uuid]/page_client-reference-manifest.js +1 -1
  47. package/.next/standalone/.next/server/app/admin/companies/new/page_client-reference-manifest.js +1 -1
  48. package/.next/standalone/.next/server/app/admin/companies/new.html +2 -2
  49. package/.next/standalone/.next/server/app/admin/companies/new.rsc +1 -1
  50. package/.next/standalone/.next/server/app/admin/companies/page_client-reference-manifest.js +1 -1
  51. package/.next/standalone/.next/server/app/admin/companies.html +2 -2
  52. package/.next/standalone/.next/server/app/admin/companies.rsc +1 -1
  53. package/.next/standalone/.next/server/app/admin/page_client-reference-manifest.js +1 -1
  54. package/.next/standalone/.next/server/app/admin.html +2 -2
  55. package/.next/standalone/.next/server/app/admin.rsc +1 -1
  56. package/.next/standalone/.next/server/app/api/admin/companies/[uuid]/route_client-reference-manifest.js +1 -1
  57. package/.next/standalone/.next/server/app/api/admin/companies/route_client-reference-manifest.js +1 -1
  58. package/.next/standalone/.next/server/app/api/admin/login/route_client-reference-manifest.js +1 -1
  59. package/.next/standalone/.next/server/app/api/admin/session/route_client-reference-manifest.js +1 -1
  60. package/.next/standalone/.next/server/app/api/agent-connections/route.js.nft.json +1 -1
  61. package/.next/standalone/.next/server/app/api/agent-connections/route_client-reference-manifest.js +1 -1
  62. package/.next/standalone/.next/server/app/api/agents/[uuid]/route_client-reference-manifest.js +1 -1
  63. package/.next/standalone/.next/server/app/api/agents/[uuid]/sessions/route.js +1 -1
  64. package/.next/standalone/.next/server/app/api/agents/[uuid]/sessions/route.js.nft.json +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/sync-token/route_client-reference-manifest.js +1 -1
  77. package/.next/standalone/.next/server/app/api/comments/route.js +1 -1
  78. package/.next/standalone/.next/server/app/api/comments/route.js.nft.json +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/connection-heartbeat/route.js.nft.json +1 -1
  81. package/.next/standalone/.next/server/app/api/daemon/connection-heartbeat/route_client-reference-manifest.js +1 -1
  82. package/.next/standalone/.next/server/app/api/daemon/control/route_client-reference-manifest.js +1 -1
  83. package/.next/standalone/.next/server/app/api/daemon/directory-request/report/route.js.nft.json +1 -1
  84. package/.next/standalone/.next/server/app/api/daemon/directory-request/report/route_client-reference-manifest.js +1 -1
  85. package/.next/standalone/.next/server/app/api/daemon/execution-state/route.js.nft.json +1 -1
  86. package/.next/standalone/.next/server/app/api/daemon/execution-state/route_client-reference-manifest.js +1 -1
  87. package/.next/standalone/.next/server/app/api/daemon/executions/route.js.nft.json +1 -1
  88. package/.next/standalone/.next/server/app/api/daemon/executions/route_client-reference-manifest.js +1 -1
  89. package/.next/standalone/.next/server/app/api/daemon/pending-turns/route.js +1 -1
  90. package/.next/standalone/.next/server/app/api/daemon/pending-turns/route.js.nft.json +1 -1
  91. package/.next/standalone/.next/server/app/api/daemon/pending-turns/route_client-reference-manifest.js +1 -1
  92. package/.next/standalone/.next/server/app/api/daemon/report-interrupt/route.js.nft.json +1 -1
  93. package/.next/standalone/.next/server/app/api/daemon/report-interrupt/route_client-reference-manifest.js +1 -1
  94. package/.next/standalone/.next/server/app/api/daemon/resume/route.js.nft.json +1 -1
  95. package/.next/standalone/.next/server/app/api/daemon/resume/route_client-reference-manifest.js +1 -1
  96. package/.next/standalone/.next/server/app/api/daemon/transcript/route.js +1 -1
  97. package/.next/standalone/.next/server/app/api/daemon/transcript/route.js.nft.json +1 -1
  98. package/.next/standalone/.next/server/app/api/daemon/transcript/route_client-reference-manifest.js +1 -1
  99. package/.next/standalone/.next/server/app/api/daemon/turn-advance/route.js +1 -1
  100. package/.next/standalone/.next/server/app/api/daemon/turn-advance/route.js.nft.json +1 -1
  101. package/.next/standalone/.next/server/app/api/daemon/turn-advance/route_client-reference-manifest.js +1 -1
  102. package/.next/standalone/.next/server/app/api/daemon-directory-requests/[uuid]/route.js.nft.json +1 -1
  103. package/.next/standalone/.next/server/app/api/daemon-directory-requests/[uuid]/route_client-reference-manifest.js +1 -1
  104. package/.next/standalone/.next/server/app/api/daemon-directory-requests/route.js.nft.json +1 -1
  105. package/.next/standalone/.next/server/app/api/daemon-directory-requests/route_client-reference-manifest.js +1 -1
  106. package/.next/standalone/.next/server/app/api/daemon-sessions/[sessionUuid]/instruction/route.js +1 -1
  107. package/.next/standalone/.next/server/app/api/daemon-sessions/[sessionUuid]/instruction/route.js.nft.json +1 -1
  108. package/.next/standalone/.next/server/app/api/daemon-sessions/[sessionUuid]/instruction/route_client-reference-manifest.js +1 -1
  109. package/.next/standalone/.next/server/app/api/daemon-sessions/[sessionUuid]/repoint/route.js +1 -1
  110. package/.next/standalone/.next/server/app/api/daemon-sessions/[sessionUuid]/repoint/route.js.nft.json +1 -1
  111. package/.next/standalone/.next/server/app/api/daemon-sessions/[sessionUuid]/repoint/route_client-reference-manifest.js +1 -1
  112. package/.next/standalone/.next/server/app/api/daemon-sessions/[sessionUuid]/route.js +1 -1
  113. package/.next/standalone/.next/server/app/api/daemon-sessions/[sessionUuid]/route.js.nft.json +1 -1
  114. package/.next/standalone/.next/server/app/api/daemon-sessions/[sessionUuid]/route_client-reference-manifest.js +1 -1
  115. package/.next/standalone/.next/server/app/api/daemon-sessions/ad-hoc/route.js +1 -1
  116. package/.next/standalone/.next/server/app/api/daemon-sessions/ad-hoc/route.js.nft.json +1 -1
  117. package/.next/standalone/.next/server/app/api/daemon-sessions/ad-hoc/route_client-reference-manifest.js +1 -1
  118. package/.next/standalone/.next/server/app/api/daemon-sessions/route.js +1 -1
  119. package/.next/standalone/.next/server/app/api/daemon-sessions/route.js.nft.json +1 -1
  120. package/.next/standalone/.next/server/app/api/daemon-sessions/route_client-reference-manifest.js +1 -1
  121. package/.next/standalone/.next/server/app/api/documents/[uuid]/route_client-reference-manifest.js +1 -1
  122. package/.next/standalone/.next/server/app/api/entities/[type]/[uuid]/root-idea/route.js +1 -1
  123. package/.next/standalone/.next/server/app/api/entities/[type]/[uuid]/root-idea/route.js.nft.json +1 -1
  124. package/.next/standalone/.next/server/app/api/entities/[type]/[uuid]/root-idea/route_client-reference-manifest.js +1 -1
  125. package/.next/standalone/.next/server/app/api/events/notifications/route.js +1 -1
  126. package/.next/standalone/.next/server/app/api/events/notifications/route.js.nft.json +1 -1
  127. package/.next/standalone/.next/server/app/api/events/notifications/route_client-reference-manifest.js +1 -1
  128. package/.next/standalone/.next/server/app/api/events/route.js +1 -1
  129. package/.next/standalone/.next/server/app/api/events/route.js.nft.json +1 -1
  130. package/.next/standalone/.next/server/app/api/events/route_client-reference-manifest.js +1 -1
  131. package/.next/standalone/.next/server/app/api/health/route_client-reference-manifest.js +1 -1
  132. package/.next/standalone/.next/server/app/api/ideas/[uuid]/claim/route.js +1 -1
  133. package/.next/standalone/.next/server/app/api/ideas/[uuid]/claim/route.js.nft.json +1 -1
  134. package/.next/standalone/.next/server/app/api/ideas/[uuid]/claim/route_client-reference-manifest.js +1 -1
  135. package/.next/standalone/.next/server/app/api/ideas/[uuid]/move/preview/route.js +1 -1
  136. package/.next/standalone/.next/server/app/api/ideas/[uuid]/move/preview/route.js.nft.json +1 -1
  137. package/.next/standalone/.next/server/app/api/ideas/[uuid]/move/preview/route_client-reference-manifest.js +1 -1
  138. package/.next/standalone/.next/server/app/api/ideas/[uuid]/move/route.js +1 -1
  139. package/.next/standalone/.next/server/app/api/ideas/[uuid]/move/route.js.nft.json +1 -1
  140. package/.next/standalone/.next/server/app/api/ideas/[uuid]/move/route_client-reference-manifest.js +1 -1
  141. package/.next/standalone/.next/server/app/api/ideas/[uuid]/parent/route.js +1 -1
  142. package/.next/standalone/.next/server/app/api/ideas/[uuid]/parent/route.js.nft.json +1 -1
  143. package/.next/standalone/.next/server/app/api/ideas/[uuid]/parent/route_client-reference-manifest.js +1 -1
  144. package/.next/standalone/.next/server/app/api/ideas/[uuid]/release/route.js +1 -1
  145. package/.next/standalone/.next/server/app/api/ideas/[uuid]/release/route.js.nft.json +1 -1
  146. package/.next/standalone/.next/server/app/api/ideas/[uuid]/release/route_client-reference-manifest.js +1 -1
  147. package/.next/standalone/.next/server/app/api/ideas/[uuid]/route.js +1 -1
  148. package/.next/standalone/.next/server/app/api/ideas/[uuid]/route.js.nft.json +1 -1
  149. package/.next/standalone/.next/server/app/api/ideas/[uuid]/route_client-reference-manifest.js +1 -1
  150. package/.next/standalone/.next/server/app/api/ideas/[uuid]/wake-preview/route.js.nft.json +1 -1
  151. package/.next/standalone/.next/server/app/api/ideas/[uuid]/wake-preview/route_client-reference-manifest.js +1 -1
  152. package/.next/standalone/.next/server/app/api/ideas/conversational/route.js +1 -1
  153. package/.next/standalone/.next/server/app/api/ideas/conversational/route.js.nft.json +1 -1
  154. package/.next/standalone/.next/server/app/api/ideas/conversational/route_client-reference-manifest.js +1 -1
  155. package/.next/standalone/.next/server/app/api/mcp/route.js +4 -4
  156. package/.next/standalone/.next/server/app/api/mcp/route.js.nft.json +1 -1
  157. package/.next/standalone/.next/server/app/api/mcp/route_client-reference-manifest.js +1 -1
  158. package/.next/standalone/.next/server/app/api/me/assignments/route.js +1 -1
  159. package/.next/standalone/.next/server/app/api/me/assignments/route.js.nft.json +1 -1
  160. package/.next/standalone/.next/server/app/api/me/assignments/route_client-reference-manifest.js +1 -1
  161. package/.next/standalone/.next/server/app/api/mentionables/route.js +1 -1
  162. package/.next/standalone/.next/server/app/api/mentionables/route.js.nft.json +1 -1
  163. package/.next/standalone/.next/server/app/api/mentionables/route_client-reference-manifest.js +1 -1
  164. package/.next/standalone/.next/server/app/api/notifications/[uuid]/archive/route.js +1 -1
  165. package/.next/standalone/.next/server/app/api/notifications/[uuid]/archive/route.js.nft.json +1 -1
  166. package/.next/standalone/.next/server/app/api/notifications/[uuid]/archive/route_client-reference-manifest.js +1 -1
  167. package/.next/standalone/.next/server/app/api/notifications/[uuid]/read/route.js +1 -1
  168. package/.next/standalone/.next/server/app/api/notifications/[uuid]/read/route.js.nft.json +1 -1
  169. package/.next/standalone/.next/server/app/api/notifications/[uuid]/read/route_client-reference-manifest.js +1 -1
  170. package/.next/standalone/.next/server/app/api/notifications/preferences/route.js +1 -1
  171. package/.next/standalone/.next/server/app/api/notifications/preferences/route.js.nft.json +1 -1
  172. package/.next/standalone/.next/server/app/api/notifications/preferences/route_client-reference-manifest.js +1 -1
  173. package/.next/standalone/.next/server/app/api/notifications/read-all/route.js +1 -1
  174. package/.next/standalone/.next/server/app/api/notifications/read-all/route.js.nft.json +1 -1
  175. package/.next/standalone/.next/server/app/api/notifications/read-all/route_client-reference-manifest.js +1 -1
  176. package/.next/standalone/.next/server/app/api/notifications/route.js +1 -1
  177. package/.next/standalone/.next/server/app/api/notifications/route.js.nft.json +1 -1
  178. package/.next/standalone/.next/server/app/api/notifications/route_client-reference-manifest.js +1 -1
  179. package/.next/standalone/.next/server/app/api/notifications/unread-count/route.js +1 -1
  180. package/.next/standalone/.next/server/app/api/notifications/unread-count/route.js.nft.json +1 -1
  181. package/.next/standalone/.next/server/app/api/notifications/unread-count/route_client-reference-manifest.js +1 -1
  182. package/.next/standalone/.next/server/app/api/project-groups/[uuid]/dashboard/route_client-reference-manifest.js +1 -1
  183. package/.next/standalone/.next/server/app/api/project-groups/[uuid]/route_client-reference-manifest.js +1 -1
  184. package/.next/standalone/.next/server/app/api/project-groups/route_client-reference-manifest.js +1 -1
  185. package/.next/standalone/.next/server/app/api/project-visits/pin/route_client-reference-manifest.js +1 -1
  186. package/.next/standalone/.next/server/app/api/project-visits/route_client-reference-manifest.js +1 -1
  187. package/.next/standalone/.next/server/app/api/project-visits/visit/route_client-reference-manifest.js +1 -1
  188. package/.next/standalone/.next/server/app/api/projects/[uuid]/activity/route_client-reference-manifest.js +1 -1
  189. package/.next/standalone/.next/server/app/api/projects/[uuid]/agent-cwds/route.js.nft.json +1 -1
  190. package/.next/standalone/.next/server/app/api/projects/[uuid]/agent-cwds/route_client-reference-manifest.js +1 -1
  191. package/.next/standalone/.next/server/app/api/projects/[uuid]/available/route.js +1 -1
  192. package/.next/standalone/.next/server/app/api/projects/[uuid]/available/route.js.nft.json +1 -1
  193. package/.next/standalone/.next/server/app/api/projects/[uuid]/available/route_client-reference-manifest.js +1 -1
  194. package/.next/standalone/.next/server/app/api/projects/[uuid]/documents/route_client-reference-manifest.js +1 -1
  195. package/.next/standalone/.next/server/app/api/projects/[uuid]/group/route_client-reference-manifest.js +1 -1
  196. package/.next/standalone/.next/server/app/api/projects/[uuid]/ideas/route.js +1 -1
  197. package/.next/standalone/.next/server/app/api/projects/[uuid]/ideas/route.js.nft.json +1 -1
  198. package/.next/standalone/.next/server/app/api/projects/[uuid]/ideas/route_client-reference-manifest.js +1 -1
  199. package/.next/standalone/.next/server/app/api/projects/[uuid]/ideas/tracker/route.js +1 -1
  200. package/.next/standalone/.next/server/app/api/projects/[uuid]/ideas/tracker/route.js.nft.json +1 -1
  201. package/.next/standalone/.next/server/app/api/projects/[uuid]/ideas/tracker/route_client-reference-manifest.js +1 -1
  202. package/.next/standalone/.next/server/app/api/projects/[uuid]/proposals/[proposalUuid]/validate/route_client-reference-manifest.js +1 -1
  203. package/.next/standalone/.next/server/app/api/projects/[uuid]/proposals/route_client-reference-manifest.js +1 -1
  204. package/.next/standalone/.next/server/app/api/projects/[uuid]/proposals/summary/route_client-reference-manifest.js +1 -1
  205. package/.next/standalone/.next/server/app/api/projects/[uuid]/resource-graph/route.js +1 -1
  206. package/.next/standalone/.next/server/app/api/projects/[uuid]/resource-graph/route.js.nft.json +1 -1
  207. package/.next/standalone/.next/server/app/api/projects/[uuid]/resource-graph/route_client-reference-manifest.js +1 -1
  208. package/.next/standalone/.next/server/app/api/projects/[uuid]/route_client-reference-manifest.js +1 -1
  209. package/.next/standalone/.next/server/app/api/projects/[uuid]/stats/route_client-reference-manifest.js +1 -1
  210. package/.next/standalone/.next/server/app/api/projects/[uuid]/tasks/dependencies/route.js +1 -1
  211. package/.next/standalone/.next/server/app/api/projects/[uuid]/tasks/dependencies/route.js.nft.json +1 -1
  212. package/.next/standalone/.next/server/app/api/projects/[uuid]/tasks/dependencies/route_client-reference-manifest.js +1 -1
  213. package/.next/standalone/.next/server/app/api/projects/[uuid]/tasks/route.js +1 -1
  214. package/.next/standalone/.next/server/app/api/projects/[uuid]/tasks/route.js.nft.json +1 -1
  215. package/.next/standalone/.next/server/app/api/projects/[uuid]/tasks/route_client-reference-manifest.js +1 -1
  216. package/.next/standalone/.next/server/app/api/projects/agent-cwd-options/route.js.nft.json +1 -1
  217. package/.next/standalone/.next/server/app/api/projects/agent-cwd-options/route_client-reference-manifest.js +1 -1
  218. package/.next/standalone/.next/server/app/api/projects/route.js.nft.json +1 -1
  219. package/.next/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  220. package/.next/standalone/.next/server/app/api/proposals/[uuid]/approve/route_client-reference-manifest.js +1 -1
  221. package/.next/standalone/.next/server/app/api/proposals/[uuid]/close/route_client-reference-manifest.js +1 -1
  222. package/.next/standalone/.next/server/app/api/proposals/[uuid]/reject/route_client-reference-manifest.js +1 -1
  223. package/.next/standalone/.next/server/app/api/proposals/[uuid]/revoke/route_client-reference-manifest.js +1 -1
  224. package/.next/standalone/.next/server/app/api/proposals/[uuid]/route_client-reference-manifest.js +1 -1
  225. package/.next/standalone/.next/server/app/api/references/[uuid]/route_client-reference-manifest.js +1 -1
  226. package/.next/standalone/.next/server/app/api/references/route_client-reference-manifest.js +1 -1
  227. package/.next/standalone/.next/server/app/api/search/route_client-reference-manifest.js +1 -1
  228. package/.next/standalone/.next/server/app/api/session/route_client-reference-manifest.js +1 -1
  229. package/.next/standalone/.next/server/app/api/sessions/[uuid]/route.js +1 -1
  230. package/.next/standalone/.next/server/app/api/sessions/[uuid]/route.js.nft.json +1 -1
  231. package/.next/standalone/.next/server/app/api/sessions/[uuid]/route_client-reference-manifest.js +1 -1
  232. package/.next/standalone/.next/server/app/api/tasks/[uuid]/claim/route.js +1 -1
  233. package/.next/standalone/.next/server/app/api/tasks/[uuid]/claim/route.js.nft.json +1 -1
  234. package/.next/standalone/.next/server/app/api/tasks/[uuid]/claim/route_client-reference-manifest.js +1 -1
  235. package/.next/standalone/.next/server/app/api/tasks/[uuid]/dependencies/[dependsOnUuid]/route.js +1 -1
  236. package/.next/standalone/.next/server/app/api/tasks/[uuid]/dependencies/[dependsOnUuid]/route.js.nft.json +1 -1
  237. package/.next/standalone/.next/server/app/api/tasks/[uuid]/dependencies/[dependsOnUuid]/route_client-reference-manifest.js +1 -1
  238. package/.next/standalone/.next/server/app/api/tasks/[uuid]/dependencies/route.js +1 -1
  239. package/.next/standalone/.next/server/app/api/tasks/[uuid]/dependencies/route.js.nft.json +1 -1
  240. package/.next/standalone/.next/server/app/api/tasks/[uuid]/dependencies/route_client-reference-manifest.js +1 -1
  241. package/.next/standalone/.next/server/app/api/tasks/[uuid]/release/route.js +1 -1
  242. package/.next/standalone/.next/server/app/api/tasks/[uuid]/release/route.js.nft.json +1 -1
  243. package/.next/standalone/.next/server/app/api/tasks/[uuid]/release/route_client-reference-manifest.js +1 -1
  244. package/.next/standalone/.next/server/app/api/tasks/[uuid]/route.js +1 -1
  245. package/.next/standalone/.next/server/app/api/tasks/[uuid]/route.js.nft.json +1 -1
  246. package/.next/standalone/.next/server/app/api/tasks/[uuid]/route_client-reference-manifest.js +1 -1
  247. package/.next/standalone/.next/server/app/api/tasks/[uuid]/sessions/route.js +1 -1
  248. package/.next/standalone/.next/server/app/api/tasks/[uuid]/sessions/route.js.nft.json +1 -1
  249. package/.next/standalone/.next/server/app/api/tasks/[uuid]/sessions/route_client-reference-manifest.js +1 -1
  250. package/.next/standalone/.next/server/app/index.html +2 -2
  251. package/.next/standalone/.next/server/app/index.rsc +1 -1
  252. package/.next/standalone/.next/server/app/login/admin/page_client-reference-manifest.js +1 -1
  253. package/.next/standalone/.next/server/app/login/admin.html +2 -2
  254. package/.next/standalone/.next/server/app/login/admin.rsc +1 -1
  255. package/.next/standalone/.next/server/app/login/callback/page_client-reference-manifest.js +1 -1
  256. package/.next/standalone/.next/server/app/login/callback.html +2 -2
  257. package/.next/standalone/.next/server/app/login/callback.rsc +1 -1
  258. package/.next/standalone/.next/server/app/login/page_client-reference-manifest.js +1 -1
  259. package/.next/standalone/.next/server/app/login/pick-workspace/page_client-reference-manifest.js +1 -1
  260. package/.next/standalone/.next/server/app/login/pick-workspace.html +2 -2
  261. package/.next/standalone/.next/server/app/login/pick-workspace.rsc +1 -1
  262. package/.next/standalone/.next/server/app/login.html +2 -2
  263. package/.next/standalone/.next/server/app/login.rsc +1 -1
  264. package/.next/standalone/.next/server/app/onboarding/page.js +2 -2
  265. package/.next/standalone/.next/server/app/onboarding/page.js.nft.json +1 -1
  266. package/.next/standalone/.next/server/app/onboarding/page_client-reference-manifest.js +1 -1
  267. package/.next/standalone/.next/server/app/onboarding.html +2 -2
  268. package/.next/standalone/.next/server/app/onboarding.rsc +2 -2
  269. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  270. package/.next/standalone/.next/server/app/projects.html +2 -2
  271. package/.next/standalone/.next/server/app/projects.rsc +2 -2
  272. package/.next/standalone/.next/server/app/settings.html +2 -2
  273. package/.next/standalone/.next/server/app/settings.rsc +3 -3
  274. package/.next/standalone/.next/server/app-paths-manifest.json +53 -53
  275. package/.next/standalone/.next/server/chunks/{5205.js → 1114.js} +1 -1
  276. package/.next/standalone/.next/server/chunks/1318.js +1 -1
  277. package/.next/standalone/.next/server/chunks/1437.js +1 -0
  278. package/.next/standalone/.next/server/chunks/1559.js +2 -2
  279. package/.next/standalone/.next/server/chunks/2572.js +1 -1
  280. package/.next/standalone/.next/server/chunks/2961.js +1 -1
  281. package/.next/standalone/.next/server/chunks/{9793.js → 3045.js} +1 -1
  282. package/.next/standalone/.next/server/chunks/3831.js +37 -0
  283. package/.next/standalone/.next/server/chunks/4827.js +1 -1
  284. package/.next/standalone/.next/server/chunks/5245.js +1 -1
  285. package/.next/standalone/.next/server/chunks/{4394.js → 5706.js} +1 -1
  286. package/.next/standalone/.next/server/chunks/6113.js +1 -1
  287. package/.next/standalone/.next/server/chunks/6207.js +1 -1
  288. package/.next/standalone/.next/server/chunks/6515.js +2 -2
  289. package/.next/standalone/.next/server/chunks/679.js +1 -1
  290. package/.next/standalone/.next/server/chunks/7368.js +1 -1
  291. package/.next/standalone/.next/server/chunks/7530.js +1 -1
  292. package/.next/standalone/.next/server/chunks/8454.js +1 -1
  293. package/.next/standalone/.next/server/chunks/920.js +1 -1
  294. package/.next/standalone/.next/server/chunks/9213.js +1 -1
  295. package/.next/standalone/.next/server/chunks/9378.js +1 -1
  296. package/.next/standalone/.next/server/chunks/9449.js +1 -0
  297. package/.next/standalone/.next/server/chunks/9458.js +1 -0
  298. package/.next/standalone/.next/server/middleware-build-manifest.js +1 -1
  299. package/.next/standalone/.next/server/middleware-manifest.json +5 -5
  300. package/.next/standalone/.next/server/pages/404.html +2 -2
  301. package/.next/standalone/.next/server/pages/500.html +1 -1
  302. package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
  303. package/.next/standalone/.next/server/server-reference-manifest.json +1 -1
  304. package/.next/standalone/.next/static/chunks/{11595.a6268c75ca8a2163.js → 11595.bbe40924d18958bf.js} +1 -1
  305. package/.next/standalone/.next/static/chunks/18139-e6ef4b5869593f8e.js +1 -0
  306. package/.next/standalone/.next/static/chunks/28856-ef2cb58fbd404ef9.js +1 -0
  307. package/.next/standalone/.next/static/chunks/{31308-fda6febfb2882a28.js → 31308-bb4a97b3f39c22dd.js} +1 -1
  308. package/.next/standalone/.next/static/chunks/{33456.16ff7edf00137539.js → 33456.5499eb8e892b110a.js} +1 -1
  309. package/.next/standalone/.next/static/chunks/{4860.9e06848eb531e667.js → 4860.be77046fb2b3a2bd.js} +1 -1
  310. package/.next/standalone/.next/static/chunks/66873-e3be53f41b3f2255.js +1 -0
  311. package/.next/standalone/.next/static/chunks/70303-aec3d52ad87602a3.js +1 -0
  312. package/.next/standalone/.next/static/chunks/76201-83b26515f85ce37c.js +1 -0
  313. package/.next/standalone/.next/static/chunks/78917-a8a8dff98857c045.js +1 -0
  314. package/.next/standalone/.next/static/chunks/97663-9c3ae4fd60b353db.js +1 -0
  315. package/.next/standalone/.next/static/chunks/{99373.81b79c91858f9099.js → 99373.111493dc260a2a04.js} +1 -1
  316. package/.next/standalone/.next/static/chunks/app/(dashboard)/{layout-b742c51c0a764daf.js → layout-40fe7d026c5a7c6d.js} +1 -1
  317. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/dashboard/page-87d4d0fe90fca28c.js +1 -0
  318. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/documents/[documentUuid]/page-1206abaee85dc915.js +1 -0
  319. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/documents/{page-425acbe9ade5fa83.js → page-474e494097c8945f.js} +1 -1
  320. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/graph/page-e902b19328092ccf.js +1 -0
  321. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/[proposalUuid]/page-f273288c3530aa0f.js +1 -0
  322. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/new/page-6568a7b08bf9a54b.js +1 -0
  323. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/page-fbd3c27b68666234.js +1 -0
  324. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/tasks/[taskUuid]/{page-58b48aa0a11603c3.js → page-15bb6e1696668512.js} +1 -1
  325. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/tasks/{page-286faced32c6133f.js → page-2bea97214b1595cc.js} +1 -1
  326. package/.next/standalone/.next/static/chunks/app/(dashboard)/settings/page-2bf7ceee62b574c7.js +1 -0
  327. package/.next/standalone/.next/static/chunks/app/onboarding/{page-5c82cf3abd856301.js → page-540da64d7ba16dc7.js} +1 -1
  328. package/.next/standalone/.next/static/chunks/{webpack-4d1cc14b13e247b6.js → webpack-7cbb3ba6792f1fb3.js} +1 -1
  329. package/.next/standalone/package.json +1 -1
  330. package/.next/standalone/public/chorus-plugin/.claude-plugin/plugin.json +1 -1
  331. package/.next/standalone/public/chorus-plugin/bin/chorus-api.sh +44 -1
  332. package/.next/standalone/public/chorus-plugin/bin/on-session-start.sh +4 -3
  333. package/.next/standalone/public/chorus-plugin/bin/tests/test-mcp-cli-delegation.sh +244 -0
  334. package/.next/standalone/public/chorus-plugin/skills/brainstorm/SKILL.md +1 -1
  335. package/.next/standalone/public/chorus-plugin/skills/chorus/SKILL.md +19 -1
  336. package/.next/standalone/public/chorus-plugin/skills/chorus-cli/SKILL.md +57 -0
  337. package/.next/standalone/public/chorus-plugin/skills/develop/SKILL.md +2 -2
  338. package/.next/standalone/public/chorus-plugin/skills/docs/SKILL.md +1 -1
  339. package/.next/standalone/public/chorus-plugin/skills/idea/SKILL.md +1 -1
  340. package/.next/standalone/public/chorus-plugin/skills/openspec-aware/SKILL.md +85 -42
  341. package/.next/standalone/public/chorus-plugin/skills/orchestrate/SKILL.md +1 -1
  342. package/.next/standalone/public/chorus-plugin/skills/proposal/SKILL.md +2 -2
  343. package/.next/standalone/public/chorus-plugin/skills/quick-dev/SKILL.md +1 -1
  344. package/.next/standalone/public/chorus-plugin/skills/review/SKILL.md +1 -1
  345. package/.next/standalone/public/chorus-plugin/skills/yolo/SKILL.md +3 -3
  346. package/.next/standalone/public/dsh-credentials.sh +20 -127
  347. package/.next/standalone/public/install-codex.sh +21 -406
  348. package/.next/standalone/public/install-kiro.sh +20 -344
  349. package/.next/standalone/public/install-opencode.sh +20 -275
  350. package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-brainstorm/SKILL.md +1 -1
  351. package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-cli/SKILL.md +57 -0
  352. package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-develop/SKILL.md +2 -2
  353. package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-docs/SKILL.md +1 -1
  354. package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-idea/SKILL.md +1 -1
  355. package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-openspec-aware/SKILL.md +85 -42
  356. package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-orchestrate/SKILL.md +1 -1
  357. package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-proposal/SKILL.md +2 -2
  358. package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-quick-dev/SKILL.md +1 -1
  359. package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-review/SKILL.md +1 -1
  360. package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-yolo/SKILL.md +3 -3
  361. package/.next/standalone/public/kiro-plugin/bin/chorus-api.sh +44 -1
  362. package/.next/standalone/public/kiro-plugin/bin/on-agent-spawn.sh +6 -4
  363. package/.next/standalone/public/kiro-plugin/manifest.txt +41 -0
  364. package/.next/standalone/public/skill/brainstorm-chorus/SKILL.md +1 -1
  365. package/.next/standalone/public/skill/chorus/SKILL.md +19 -1
  366. package/.next/standalone/public/skill/code-reviewer-chorus/SKILL.md +1 -1
  367. package/.next/standalone/public/skill/develop-chorus/SKILL.md +1 -1
  368. package/.next/standalone/public/skill/docs-chorus/SKILL.md +1 -1
  369. package/.next/standalone/public/skill/idea-chorus/SKILL.md +1 -1
  370. package/.next/standalone/public/skill/orchestrate-chorus/SKILL.md +1 -1
  371. package/.next/standalone/public/skill/proposal-chorus/SKILL.md +1 -1
  372. package/.next/standalone/public/skill/proposal-reviewer-chorus/SKILL.md +1 -1
  373. package/.next/standalone/public/skill/quick-dev-chorus/SKILL.md +1 -1
  374. package/.next/standalone/public/skill/review-chorus/SKILL.md +1 -1
  375. package/.next/standalone/public/skill/task-reviewer-chorus/SKILL.md +1 -1
  376. package/.next/standalone/public/skill/yolo-chorus/SKILL.md +1 -1
  377. package/.next/standalone/public/test-dsh-credentials.sh +22 -38
  378. package/.next/standalone/public/test-install-codex.sh +31 -79
  379. package/README.ja.md +2 -2
  380. package/README.ko.md +2 -2
  381. package/README.md +2 -2
  382. package/README.zh.md +2 -2
  383. package/chorus.mjs +35 -1
  384. package/cli/agent-backend-prompt.mjs +3 -2
  385. package/cli/agents.mjs +329 -0
  386. package/cli/chorus-client.mjs +69 -0
  387. package/cli/claude-spawner.mjs +4 -0
  388. package/cli/codex-spawner.mjs +11 -6
  389. package/cli/credentials.mjs +185 -3
  390. package/cli/daemon-agent.mjs +26 -2
  391. package/cli/daemon-config.mjs +27 -2
  392. package/cli/daemon-service.mjs +120 -33
  393. package/cli/daemon.mjs +128 -22
  394. package/cli/dsh-spawner.mjs +7 -0
  395. package/cli/init/adapters.mjs +137 -0
  396. package/cli/init/agent-type-map.mjs +60 -0
  397. package/cli/init/chorus-plugin-consts.mjs +16 -0
  398. package/cli/init/codex-mcp-config.mjs +183 -0
  399. package/cli/init/contracts.mjs +120 -0
  400. package/cli/init/detect.mjs +97 -0
  401. package/cli/init/file-template.mjs +248 -0
  402. package/cli/init/install-methods.mjs +508 -0
  403. package/cli/init/registry.mjs +74 -0
  404. package/cli/init/run-command.mjs +30 -0
  405. package/cli/init/select.mjs +111 -0
  406. package/cli/init/steps/credential-seed.mjs +751 -0
  407. package/cli/init/steps/daemon-setup.mjs +246 -0
  408. package/cli/init/steps/plugin-install.mjs +37 -0
  409. package/cli/init-args.mjs +137 -0
  410. package/cli/init.mjs +198 -0
  411. package/cli/kiro-spawner.mjs +4 -0
  412. package/cli/mcp-args.mjs +280 -0
  413. package/cli/mcp.mjs +164 -0
  414. package/cli/spawner-select.mjs +45 -2
  415. package/package.json +1 -1
  416. package/.next/standalone/.next/server/chunks/3594.js +0 -1
  417. package/.next/standalone/.next/server/chunks/5351.js +0 -33
  418. package/.next/standalone/.next/server/chunks/6667.js +0 -1
  419. package/.next/standalone/.next/server/chunks/6995.js +0 -1
  420. package/.next/standalone/.next/static/chunks/19887-b805e1dcee8c367b.js +0 -1
  421. package/.next/standalone/.next/static/chunks/29108-5a11eea003f4cc11.js +0 -1
  422. package/.next/standalone/.next/static/chunks/53073-a7ed20af6538a178.js +0 -1
  423. package/.next/standalone/.next/static/chunks/6603-e70ddeab6ad09c50.js +0 -1
  424. package/.next/standalone/.next/static/chunks/78917-1b59cbb806b3ecfc.js +0 -1
  425. package/.next/standalone/.next/static/chunks/82751-3e161e1d8dbda3ac.js +0 -1
  426. package/.next/standalone/.next/static/chunks/99366-425e9ef22e60e3e2.js +0 -1
  427. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/dashboard/page-f636e00c28f425ea.js +0 -1
  428. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/documents/[documentUuid]/page-c004f1a194af7fa5.js +0 -1
  429. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/graph/page-fdd617457730a116.js +0 -1
  430. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/[proposalUuid]/page-b9eb4e0692996657.js +0 -1
  431. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/new/page-d5b222f379b2e8ca.js +0 -1
  432. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/page-0a6c2d0e1b68e0e4.js +0 -1
  433. package/.next/standalone/.next/static/chunks/app/(dashboard)/settings/page-1507a761e67c2aa9.js +0 -1
  434. /package/.next/standalone/.next/static/{6sHDgeKioa0SJR1MAbcYG → 0spgxl3lP26Fl1otd1D7R}/_buildManifest.js +0 -0
  435. /package/.next/standalone/.next/static/{6sHDgeKioa0SJR1MAbcYG → 0spgxl3lP26Fl1otd1D7R}/_ssgManifest.js +0 -0
@@ -0,0 +1,137 @@
1
+ // cli/init/adapters.mjs
2
+ // The per-agent adapters `chorus init` configures. One descriptor per supported
3
+ // coding-agent harness; buildAdapter() turns each into an AgentAdapter
4
+ // (contracts.mjs). Detection is shared (cli/init/detect.mjs); the plugin-install
5
+ // mechanism (descriptor.install) is added by the plugin-install task — until
6
+ // then installPlugin reports "unsupported" rather than guessing a command.
7
+ //
8
+ // LAYOUT PROVENANCE (binary + config dir), so future edits don't drift into
9
+ // LLM-guessed paths (verified against each agent's real CLI / install-*.sh):
10
+ // - claude : bin `claude`; dir ~/.claude (this machine + docs/CONNECT_CLAUDE_CODE.md)
11
+ // - codex : bin `codex`; dir ~/.codex (public/install-codex.sh: CODEX_HOME=$HOME/.codex)
12
+ // - kiro : bin `kiro`; dir ~/.kiro (public/install-kiro.sh: ~/.kiro global)
13
+ // - opencode : bin `opencode`; dir ~/.config/opencode (public/install-opencode.sh: OPENCODE_CONFIG_DIR)
14
+ // - openclaw : bin `openclaw`; dir ~/.openclaw|~/.config/openclaw (NOT independently verified — probe both; see NOTE)
15
+ // - pi : bin `pi`; dir ~/.pi|~/.config/pi (NOT independently verified — probe both; see NOTE)
16
+ // - dsh : bin `dsh`; dir $DSH_HOME|~/.dsh ($DSH_HOME per dsh integration; see NOTE)
17
+ //
18
+ // NOTE: openclaw / pi / dsh config-dir specifics were not verifiable on this
19
+ // build host (their CLIs/config were not all present); the descriptors probe the
20
+ // most likely locations. A wrong config-dir guess only weakens the *config-dir*
21
+ // half of the dual signal (the binary-on-PATH half still detects them) and never
22
+ // blocks selection — undetected agents remain selectable. The plugin-install
23
+ // task must still verify each install command against the real CLI.
24
+
25
+ import { readFileSync } from "node:fs";
26
+ import { homedir } from "node:os";
27
+ import { join } from "node:path";
28
+ import { detectSignals } from "./detect.mjs";
29
+ import { OUTCOME_ACTIONS } from "./contracts.mjs";
30
+ import { CHORUS_PLUGIN_ID, CHORUS_MARKETPLACE_NAME, CHORUS_MARKETPLACE_SOURCE } from "./chorus-plugin-consts.mjs";
31
+ import {
32
+ installClaude,
33
+ installCodex,
34
+ installOpencode,
35
+ installDsh,
36
+ installOpenclaw,
37
+ installKiro,
38
+ readCodexInstallState,
39
+ readOpencodeInstallState,
40
+ readDshInstallState,
41
+ readOpenclawInstallState,
42
+ readKiroInstallState,
43
+ guided,
44
+ GUIDED_MESSAGES,
45
+ } from "./install-methods.mjs";
46
+
47
+ // Re-export the shared marketplace identifiers from their canonical home so
48
+ // existing importers of these names from adapters.mjs keep working.
49
+ export { CHORUS_PLUGIN_ID, CHORUS_MARKETPLACE_NAME, CHORUS_MARKETPLACE_SOURCE };
50
+
51
+ /** Read + JSON-parse a file, or null on any error. Never throws. */
52
+ function readJsonSafe(path) {
53
+ try {
54
+ return JSON.parse(readFileSync(path, "utf8"));
55
+ } catch {
56
+ return null;
57
+ }
58
+ }
59
+
60
+ /**
61
+ * Claude Code install-state reader (verified against CC 2.1.235 on-disk layout):
62
+ * `~/.claude/plugins/installed_plugins.json` (v2 keyed by `<plugin>@<marketplace>`)
63
+ * and `known_marketplaces.json`. Read-only — never hand-writes these files.
64
+ * @param {{ home?: string, readJson?: (p: string) => any }} [deps]
65
+ * @returns {{ marketplaceRegistered: boolean, pluginInstalled: boolean, version?: string }}
66
+ */
67
+ export function readClaudeInstallState({ home = homedir(), readJson = readJsonSafe } = {}) {
68
+ const pluginsDir = join(home, ".claude", "plugins");
69
+ const installed = readJson(join(pluginsDir, "installed_plugins.json"));
70
+ const markets = readJson(join(pluginsDir, "known_marketplaces.json"));
71
+
72
+ const marketplaceRegistered = !!(markets && typeof markets === "object" && markets[CHORUS_MARKETPLACE_NAME]);
73
+
74
+ let pluginInstalled = false;
75
+ let version;
76
+ const entries = installed && typeof installed === "object" ? installed.plugins?.[CHORUS_PLUGIN_ID] : null;
77
+ if (Array.isArray(entries) && entries.length > 0) {
78
+ pluginInstalled = true;
79
+ version = entries[0]?.version;
80
+ }
81
+ return { marketplaceRegistered, pluginInstalled, version };
82
+ }
83
+
84
+ /**
85
+ * The supported-agent descriptors. `install` / `readState` are optional hooks the
86
+ * plugin-install task fills in per agent; absent ⇒ generic behavior.
87
+ * @type {Array<{
88
+ * id: string, displayName: string, binaries: string[], configDirs: string[],
89
+ * readState?: (deps: object) => object, install?: (ctx: object) => object,
90
+ * }>}
91
+ */
92
+ export const AGENT_DESCRIPTORS = [
93
+ { id: "claude", displayName: "Claude Code", binaries: ["claude"], configDirs: ["~/.claude"], readState: readClaudeInstallState, install: installClaude },
94
+ { id: "codex", displayName: "Codex CLI", binaries: ["codex"], configDirs: ["~/.codex"], readState: readCodexInstallState, install: installCodex },
95
+ { id: "kiro", displayName: "Kiro CLI", binaries: ["kiro"], configDirs: ["~/.kiro"], readState: readKiroInstallState, install: installKiro },
96
+ { id: "opencode", displayName: "opencode", binaries: ["opencode"], configDirs: ["~/.config/opencode", "~/.opencode"], readState: readOpencodeInstallState, install: installOpencode },
97
+ { id: "openclaw", displayName: "OpenClaw", binaries: ["openclaw"], configDirs: ["~/.openclaw", "~/.config/openclaw"], readState: readOpenclawInstallState, install: installOpenclaw },
98
+ { id: "pi", displayName: "Pi", binaries: ["pi"], configDirs: ["~/.pi", "~/.config/pi"], install: guided("pi", GUIDED_MESSAGES.pi) },
99
+ { id: "dsh", displayName: "DeepSeek Harness (dsh)", binaries: ["dsh"], configDirs: ["$DSH_HOME", "~/.dsh"], readState: readDshInstallState, install: installDsh },
100
+ ];
101
+
102
+ /**
103
+ * Build an AgentAdapter from a descriptor.
104
+ * @param {typeof AGENT_DESCRIPTORS[number]} d
105
+ * @returns {import("./contracts.mjs").AgentAdapter}
106
+ */
107
+ export function buildAdapter(d) {
108
+ return {
109
+ id: d.id,
110
+ displayName: d.displayName,
111
+ detect: (env = process.env) => detectSignals(d, { env }),
112
+ readInstallState: (deps = {}) => {
113
+ const base = typeof d.readState === "function"
114
+ ? d.readState(deps)
115
+ : { marketplaceRegistered: false, pluginInstalled: false };
116
+ // `supported` = a REAL automated install path exists for this agent. A
117
+ // `guided()` fallback also returns a function (so `typeof d.install ===
118
+ // "function"` alone would report every fallback agent as supported — the
119
+ // pre-existing latent bug); guided installers are tagged `.guided === true`,
120
+ // so exclude them here. Real installers (claude/codex/opencode + dsh/openclaw/
121
+ // kiro) → true; guided (pi) → false.
122
+ return { supported: typeof d.install === "function" && d.install.guided !== true, ...base };
123
+ },
124
+ installPlugin: (ctx = {}) =>
125
+ typeof d.install === "function"
126
+ ? d.install(ctx)
127
+ : {
128
+ stepId: "plugin-install",
129
+ agentId: d.id,
130
+ action: OUTCOME_ACTIONS.UNSUPPORTED,
131
+ detail: `no automated plugin install for ${d.displayName} yet — configure manually`,
132
+ },
133
+ };
134
+ }
135
+
136
+ /** All supported adapters, built from the descriptors. */
137
+ export const ADAPTERS = AGENT_DESCRIPTORS.map(buildAdapter);
@@ -0,0 +1,60 @@
1
+ // cli/init/agent-type-map.mjs
2
+ // The single translation between a `chorus init` adapter selection id (see
3
+ // cli/init/adapters.mjs — "claude" | "codex" | "kiro" | "opencode" | "openclaw" |
4
+ // "pi" | "dsh") and the daemon's agentType vocabulary (cli/daemon-agent.mjs
5
+ // KNOWN_AGENTS). It lives in ONE place so the credential-seed step (which writes
6
+ // each selected agent's daemon.json agents[] entry) and the daemon-setup step
7
+ // (which gates auto-start on whether any selected agent is wakeable) can never
8
+ // disagree about how a selection maps to a backend.
9
+ //
10
+ // Two rules the callers rely on:
11
+ // 1. The init id "claude" is NOT the daemon agentType — it renames to
12
+ // "claude-code" EXPLICITLY here. No caller ever passes the raw init id
13
+ // through to daemon.json; every write goes through agentTypeForSelection.
14
+ // 2. Any selection the daemon cannot wake as a first-class backend
15
+ // (opencode / openclaw / pi, and dsh while its harness is dormant/offline)
16
+ // maps to the non-wakeable "offline" classification. Its key is still parked
17
+ // in agents[] for the `chorus mcp` proxy, but the daemon builds no spawner
18
+ // and dispatches no wake (spawner-select.mjs fail-closes on "offline").
19
+ //
20
+ // Fail-closed by default: an unknown / unmapped id maps to "offline" rather than a
21
+ // wakeable backend, so a future adapter added without a mapping is never silently
22
+ // woken as claude-code.
23
+
24
+ /**
25
+ * Selection id → daemon agentType. Only claude/codex/kiro are wakeable backends;
26
+ * everything else is classified offline. `dsh` maps to offline because the dsh
27
+ * harness is de-advertised (offline) — re-map it here to bring it back online.
28
+ * @type {Readonly<Record<string, string>>}
29
+ */
30
+ export const SELECTION_TO_AGENT_TYPE = Object.freeze({
31
+ claude: "claude-code", // explicit rename — never pass the init id "claude" through verbatim
32
+ codex: "codex",
33
+ kiro: "kiro",
34
+ opencode: "offline",
35
+ openclaw: "offline",
36
+ pi: "offline",
37
+ dsh: "offline",
38
+ });
39
+
40
+ /**
41
+ * Map a `chorus init` selection id to the daemon agentType written into
42
+ * daemon.json `agents[]`. Unknown ids fail closed to "offline" (never a wakeable
43
+ * default), so an agent is only ever woken when its backend is explicitly known.
44
+ * @param {string} selectionId
45
+ * @returns {string} a KNOWN_AGENTS agentType ("claude-code" | "codex" | "kiro" | "offline")
46
+ */
47
+ export function agentTypeForSelection(selectionId) {
48
+ return SELECTION_TO_AGENT_TYPE[selectionId] ?? "offline";
49
+ }
50
+
51
+ /**
52
+ * Whether a daemon agentType is one the daemon can actually wake. "offline" is the
53
+ * one non-wakeable classification; every other value the init mapping produces
54
+ * (claude-code / codex / kiro) is wakeable.
55
+ * @param {string} agentType
56
+ * @returns {boolean}
57
+ */
58
+ export function isWakeableAgentType(agentType) {
59
+ return agentType !== "offline";
60
+ }
@@ -0,0 +1,16 @@
1
+ // cli/init/chorus-plugin-consts.mjs
2
+ // Canonical Chorus plugin/marketplace identifiers, shared by the adapters and the
3
+ // per-agent install methods. Kept in its own module so adapters.mjs and
4
+ // install-methods.mjs can both import them without a circular dependency.
5
+
6
+ /** Plugin selector used by marketplace-based agents (Claude Code, Codex). */
7
+ export const CHORUS_PLUGIN_ID = "chorus@chorus-plugins";
8
+ /** Marketplace name as it appears in agents' on-disk state. */
9
+ export const CHORUS_MARKETPLACE_NAME = "chorus-plugins";
10
+ /**
11
+ * Remote marketplace source (owner decision: each agent's NATIVE REMOTE
12
+ * marketplace, not a local bundle). Overridable per invocation via
13
+ * CHORUS_MARKETPLACE_SOURCE. Accepted by `claude plugin marketplace add`
14
+ * (URL/path/repo). Codex prefers the `owner/repo` slug — see installCodex.
15
+ */
16
+ export const CHORUS_MARKETPLACE_SOURCE = "https://github.com/Chorus-AIDLC/Chorus";
@@ -0,0 +1,183 @@
1
+ // cli/init/codex-mcp-config.mjs
2
+ // Writes the Chorus native-MCP server block into ~/.codex/config.toml using a KEYLESS
3
+ // env-var reference — `bearer_token_env_var = "CHORUS_API_KEY"` — instead of a literal
4
+ // `Authorization: Bearer <key>`. Codex loads ~/.codex/.env into its process env at arg0
5
+ // startup and resolves that env var into `Authorization: Bearer <key>` at connect time
6
+ // (config/src/mcp_types.rs StreamableHttp.bearer_token_env_var; codex-mcp resolve_bearer_token),
7
+ // so the API key lives in exactly ONE place (~/.codex/.env). A daemon-woken Codex — whose
8
+ // spawner exports CHORUS_API_KEY into the child env — then also authenticates to native MCP,
9
+ // closing the gap a literal Bearer left (cli/codex-spawner.mjs:16-22).
10
+ //
11
+ // `codex plugin add` does NOT write [mcp_servers.chorus] (its marketplace `authentication:
12
+ // ON_INSTALL` is metadata only — verified codex-cli 0.150.1), so `chorus agents add` writes it
13
+ // here, AFTER the plugin install (authoritative, no race).
14
+ //
15
+ // TARGETED TEXTUAL upsert — no TOML-parser dependency (the repo stays pure-JS / cross-platform),
16
+ // preserving every other section, key, and comment verbatim. The secret is NEVER written here
17
+ // (bearer_token_env_var is a variable NAME, not the key).
18
+
19
+ import { mkdirSync, readFileSync, renameSync, writeFileSync } from "node:fs";
20
+ import { homedir } from "node:os";
21
+ import { dirname, join } from "node:path";
22
+
23
+ const BEARER_ENV_VAR = "CHORUS_API_KEY";
24
+
25
+ /** A non-empty trimmed string, or undefined. */
26
+ function nonEmpty(value) {
27
+ return typeof value === "string" && value.trim() ? value.trim() : undefined;
28
+ }
29
+
30
+ /**
31
+ * Resolve the Codex `~/.codex/config.toml` path. Honors `CODEX_HOME`, then `HOME` (so tests
32
+ * can inject a temp home), else the OS home dir — matching cli/codex-spawner.mjs +
33
+ * install-methods.mjs.
34
+ * @param {Record<string, string | undefined>} env
35
+ */
36
+ export function resolveCodexConfigPath(env) {
37
+ const base = nonEmpty(env.CODEX_HOME) ?? join(nonEmpty(env.HOME) ?? homedir(), ".codex");
38
+ return join(base, "config.toml");
39
+ }
40
+
41
+ /**
42
+ * Normalize a Chorus base URL to the MCP endpoint the same way the hook wrapper
43
+ * (chorus-mcp-call.sh) does: a URL that already has a path segment beyond the host is used
44
+ * as-is; a bare host gains `/api/mcp`. Returns undefined for an empty URL.
45
+ * @param {string | undefined} rawUrl
46
+ */
47
+ export function codexMcpUrl(rawUrl) {
48
+ const u = nonEmpty(rawUrl);
49
+ if (!u) return undefined;
50
+ const trimmed = u.replace(/\/+$/, "");
51
+ const m = trimmed.match(/^https?:\/\/[^/]+(\/.*)?$/);
52
+ if (m && m[1] && m[1].length > 0) return trimmed; // already a full endpoint
53
+ return `${trimmed}/api/mcp`;
54
+ }
55
+
56
+ // TOML basic-string value: escape backslash then double-quote. URLs don't contain these, but
57
+ // escape defensively so we never emit invalid TOML.
58
+ const toToml = (v) => `"${String(v).replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`;
59
+
60
+ /**
61
+ * Upsert `[mcp_servers.chorus]` in `~/.codex/config.toml` to
62
+ * url = "<mcp-endpoint>"
63
+ * bearer_token_env_var = "CHORUS_API_KEY"
64
+ * and MIGRATE away any legacy literal auth: a `bearer_token = "..."` line is dropped, and a
65
+ * `[mcp_servers.chorus.http_headers]` `Authorization = "..."` line is removed (dropping the
66
+ * whole http_headers subtable when it becomes empty, preserving any OTHER header). Every other
67
+ * section/key/comment in the file is preserved verbatim.
68
+ *
69
+ * Atomic 0600 temp+rename; idempotent (a re-run with the same url reproduces the file). The API
70
+ * key is NEVER written — only the env-var NAME.
71
+ * @param {{ configPath: string, url: string }} args
72
+ * @param {{
73
+ * read?: (p: string) => string,
74
+ * write?: (p: string, c: string, o: object) => void,
75
+ * mkdir?: (p: string, o: object) => void,
76
+ * rename?: (from: string, to: string) => void,
77
+ * }} [deps]
78
+ * @returns {string} the config.toml path written
79
+ */
80
+ export function writeCodexMcpServer({ configPath, url }, deps = {}) {
81
+ const read = deps.read ?? ((p) => readFileSync(p, "utf8"));
82
+ const write = deps.write ?? writeFileSync;
83
+ const mkdir = deps.mkdir ?? mkdirSync;
84
+ const rename = deps.rename ?? renameSync;
85
+
86
+ const mcpUrl = codexMcpUrl(url);
87
+ if (!mcpUrl) throw new Error("writeCodexMcpServer requires a url");
88
+
89
+ let existing = "";
90
+ try {
91
+ existing = read(configPath);
92
+ } catch {
93
+ existing = ""; // no file yet — start fresh
94
+ }
95
+
96
+ const lines = existing.length ? existing.split(/\r?\n/) : [];
97
+ if (lines.length && lines[lines.length - 1] === "") lines.pop();
98
+
99
+ const isHeader = (s) => /^\s*\[/.test(s);
100
+ const chorusHeaderRe = /^\s*\[mcp_servers\.chorus\]\s*$/;
101
+ const headersHeaderRe = /^\s*\[mcp_servers\.chorus\.http_headers\]\s*$/;
102
+ // A `key = value` line (not a comment or blank) — used to tell whether a subtable still has
103
+ // content after removing Authorization.
104
+ const isKvLine = (s) => /^\s*[^#\s][^=]*=/.test(s);
105
+
106
+ // Split into groups: a preamble (before the first table header) + one group per table header.
107
+ const groups = [];
108
+ let cur = { header: null, body: [] };
109
+ for (const line of lines) {
110
+ if (isHeader(line)) {
111
+ groups.push(cur);
112
+ cur = { header: line, body: [] };
113
+ } else {
114
+ cur.body.push(line);
115
+ }
116
+ }
117
+ groups.push(cur);
118
+
119
+ const outGroups = [];
120
+ let wroteChorus = false;
121
+ for (const g of groups) {
122
+ if (g.header === null) {
123
+ outGroups.push(...g.body); // preamble verbatim
124
+ continue;
125
+ }
126
+ if (chorusHeaderRe.test(g.header)) {
127
+ // Normalize the [mcp_servers.chorus] body: set url + bearer_token_env_var in place,
128
+ // drop any literal bearer_token, preserve every other key.
129
+ let seenUrl = false;
130
+ let seenBearerEnv = false;
131
+ const body = [];
132
+ for (const l of g.body) {
133
+ if (/^\s*url\s*=/.test(l)) {
134
+ body.push(`url = ${toToml(mcpUrl)}`);
135
+ seenUrl = true;
136
+ continue;
137
+ }
138
+ if (/^\s*bearer_token_env_var\s*=/.test(l)) {
139
+ body.push(`bearer_token_env_var = ${toToml(BEARER_ENV_VAR)}`);
140
+ seenBearerEnv = true;
141
+ continue;
142
+ }
143
+ if (/^\s*bearer_token\s*=/.test(l)) continue; // drop legacy literal bearer_token
144
+ body.push(l);
145
+ }
146
+ const head = [];
147
+ if (!seenUrl) head.push(`url = ${toToml(mcpUrl)}`);
148
+ if (!seenBearerEnv) head.push(`bearer_token_env_var = ${toToml(BEARER_ENV_VAR)}`);
149
+ outGroups.push(g.header, ...head, ...body);
150
+ wroteChorus = true;
151
+ continue;
152
+ }
153
+ if (headersHeaderRe.test(g.header)) {
154
+ // Strip the literal Authorization; drop the whole subtable if nothing else remains.
155
+ const body = g.body.filter((l) => !/^\s*Authorization\s*=/i.test(l));
156
+ if (body.some(isKvLine)) {
157
+ outGroups.push(g.header, ...body);
158
+ }
159
+ // else: drop the emptied subtable entirely
160
+ continue;
161
+ }
162
+ outGroups.push(g.header, ...g.body);
163
+ }
164
+
165
+ if (!wroteChorus) {
166
+ if (outGroups.length && outGroups[outGroups.length - 1] !== "") outGroups.push("");
167
+ outGroups.push(
168
+ "[mcp_servers.chorus]",
169
+ `url = ${toToml(mcpUrl)}`,
170
+ `bearer_token_env_var = ${toToml(BEARER_ENV_VAR)}`,
171
+ );
172
+ }
173
+
174
+ // Trim trailing blank lines so idempotent re-runs never accumulate them.
175
+ while (outGroups.length && outGroups[outGroups.length - 1] === "") outGroups.pop();
176
+ const content = outGroups.join("\n") + "\n";
177
+
178
+ mkdir(dirname(configPath), { recursive: true });
179
+ const tmp = `${configPath}.tmp`;
180
+ write(tmp, content, { mode: 0o600 });
181
+ rename(tmp, configPath);
182
+ return configPath;
183
+ }
@@ -0,0 +1,120 @@
1
+ // cli/init/contracts.mjs
2
+ // Shared contracts for `chorus init` (idea c055e285, A1 foundation). Two
3
+ // extension points let sibling ideas grow the command without editing its core:
4
+ //
5
+ // 1. AgentAdapter — one per coding-agent harness (Claude Code, Codex, Kiro,
6
+ // opencode, OpenClaw, Pi, dsh). Adding an agent = adding an adapter to the
7
+ // registry (cli/init/registry.mjs). Detection, install-state read, and the
8
+ // plugin install all live behind this interface.
9
+ //
10
+ // 2. InitStep — one per configuration concern. THIS change ships the
11
+ // credential-seed step (scope "once") and the plugin-install step (scope
12
+ // "per-agent"). Sibling ideas register more steps (MCP proxy cc115e6b,
13
+ // daemon setup a7c2a3e8) into the same ordered registry.
14
+ //
15
+ // Iteration ownership (resolves proposal-review note #3): the ORCHESTRATOR
16
+ // (runInit) owns per-agent iteration. A `per-agent` step's run(ctx) is invoked
17
+ // once per selected agent with ctx.agentId set; a `once` step's run(ctx) is
18
+ // invoked a single time with ctx.agentId undefined. Steps never loop the
19
+ // selection themselves.
20
+ //
21
+ // Plain ESM, zero dependencies — ships verbatim in the npm package. This module
22
+ // is intentionally (mostly) JSDoc typedefs plus a few frozen enums so the shape
23
+ // is one source of truth for the whole cli/init tree and its tests.
24
+
25
+ /**
26
+ * Step scopes. `once` runs a single time per `chorus init` invocation;
27
+ * `per-agent` runs once for each selected agent.
28
+ * @readonly
29
+ */
30
+ export const STEP_SCOPES = Object.freeze({ ONCE: "once", PER_AGENT: "per-agent" });
31
+
32
+ /**
33
+ * Terminal per-unit outcomes a step reports for the summary table.
34
+ * - installed: a fresh configuration was applied
35
+ * - repaired: an existing but incomplete/broken configuration was fixed
36
+ * - skipped: already configured / nothing to do
37
+ * - seeded: a `once` step persisted shared state (e.g. credentials)
38
+ * - failed: the unit could not be configured (detail carries the reason)
39
+ * - unsupported: the agent has no verified automated mechanism (guided message)
40
+ * @readonly
41
+ */
42
+ export const OUTCOME_ACTIONS = Object.freeze({
43
+ INSTALLED: "installed",
44
+ REPAIRED: "repaired",
45
+ SKIPPED: "skipped",
46
+ SEEDED: "seeded",
47
+ FAILED: "failed",
48
+ UNSUPPORTED: "unsupported",
49
+ });
50
+
51
+ /** Outcome actions that mean "this unit did not succeed" — drive the exit code. */
52
+ export const FAILURE_ACTIONS = Object.freeze([OUTCOME_ACTIONS.FAILED]);
53
+
54
+ /**
55
+ * @typedef {Object} AgentDetection
56
+ * @property {string} id Stable adapter id (e.g. "claude").
57
+ * @property {string} displayName Human label (e.g. "Claude Code").
58
+ * @property {boolean} binaryOnPath Whether the agent's CLI resolves on PATH.
59
+ * @property {boolean} configDirPresent Whether the agent's config dir exists.
60
+ * @property {boolean} detected `binaryOnPath || configDirPresent` — drives
61
+ * default pre-selection only, never gates choice.
62
+ */
63
+
64
+ /**
65
+ * @typedef {Object} AgentInstallState
66
+ * @property {boolean} supported Whether an automated install is available on
67
+ * this machine (false ⇒ guided message only).
68
+ * @property {boolean} marketplaceRegistered Whether the Chorus marketplace/source
69
+ * is already registered for this agent.
70
+ * @property {boolean} pluginInstalled Whether the Chorus plugin is already installed.
71
+ * @property {string} [version] Installed plugin version, when known.
72
+ * @property {string} [detail] Optional human note (e.g. why unsupported).
73
+ */
74
+
75
+ /**
76
+ * @typedef {Object} AgentAdapter
77
+ * @property {string} id
78
+ * @property {string} displayName
79
+ * @property {(env: NodeJS.ProcessEnv) => {binaryOnPath: boolean, configDirPresent: boolean}} detect
80
+ * Pure-ish: may stat the filesystem and look up PATH; MUST NOT mutate anything.
81
+ * @property {(deps: object) => AgentInstallState} readInstallState
82
+ * Read-only idempotency probe (e.g. parse the agent's own state files).
83
+ * @property {(ctx: StepContext) => StepOutcome} installPlugin
84
+ * Register the agent's native remote marketplace and install/enable the Chorus
85
+ * plugin surface. MUST be idempotent, MUST back up before overwrite via
86
+ * ctx.backup(), and MUST NOT write any per-agent MCP/credential config.
87
+ */
88
+
89
+ /**
90
+ * @typedef {Object} InitStep
91
+ * @property {string} id Stable step id (e.g. "credential-seed").
92
+ * @property {number} order Ascending run order.
93
+ * @property {("once"|"per-agent")} scope
94
+ * @property {(ctx: StepContext) => (StepOutcome | Promise<StepOutcome>)} run
95
+ */
96
+
97
+ /**
98
+ * @typedef {Object} StepOutcome
99
+ * @property {string} stepId
100
+ * @property {string} [agentId] Present for per-agent outcomes.
101
+ * @property {("installed"|"repaired"|"skipped"|"seeded"|"failed"|"unsupported")} action
102
+ * @property {string} detail One-line human explanation for the summary.
103
+ */
104
+
105
+ /**
106
+ * @typedef {Object} StepContext
107
+ * @property {string[]} selection Selected agent ids (for `once` steps that need the set).
108
+ * @property {string} [agentId] The current agent id (per-agent steps only).
109
+ * @property {AgentAdapter} [adapter] The current agent's adapter (per-agent steps only).
110
+ * @property {object} flags Parsed init flags (see cli/init-args.mjs).
111
+ * @property {{ log: (m: string) => void, ask: Function, isTTY: boolean }} io
112
+ * @property {(path: string) => (string|null)} backup Copy a file to <path>.chorus-bak
113
+ * once before overwrite; returns the backup path or null if the source is absent.
114
+ * @property {NodeJS.ProcessEnv} env
115
+ */
116
+
117
+ /** True when an outcome represents a failure (drives the process exit code). */
118
+ export function isFailureOutcome(outcome) {
119
+ return !!outcome && FAILURE_ACTIONS.includes(outcome.action);
120
+ }
@@ -0,0 +1,97 @@
1
+ // cli/init/detect.mjs
2
+ // Cross-platform detection primitives for `chorus init` adapters. Dual signal:
3
+ // a CLI binary resolvable on PATH, and/or an agent config directory present.
4
+ // All IO (env, filesystem, platform, home) is injectable so adapters unit-test
5
+ // without a real machine. Zero runtime dependencies beyond node core.
6
+
7
+ import { existsSync as fsExistsSync } from "node:fs";
8
+ import { homedir } from "node:os";
9
+ import { join, delimiter as pathDelimiter } from "node:path";
10
+
11
+ /**
12
+ * Expand a config-dir spec into an absolute path:
13
+ * - a leading `~` → the home directory,
14
+ * - a leading `$VAR` segment → env[VAR] (whole spec dropped if unset),
15
+ * Returns null when the spec cannot be resolved (e.g. `$DSH_HOME` unset).
16
+ * @param {string} spec
17
+ * @param {{ env?: Record<string,string|undefined>, home?: string }} [deps]
18
+ * @returns {string | null}
19
+ */
20
+ export function expandPath(spec, { env = process.env, home = homedir() } = {}) {
21
+ if (typeof spec !== "string" || !spec) return null;
22
+ if (spec.startsWith("~")) {
23
+ return join(home, spec.slice(1).replace(/^[/\\]/, ""));
24
+ }
25
+ if (spec.startsWith("$")) {
26
+ const slash = spec.search(/[/\\]/);
27
+ const varName = (slash === -1 ? spec.slice(1) : spec.slice(1, slash));
28
+ const value = env[varName];
29
+ if (!value) return null; // unset env var → this candidate does not apply
30
+ const rest = slash === -1 ? "" : spec.slice(slash + 1);
31
+ return rest ? join(value, rest) : value;
32
+ }
33
+ return spec;
34
+ }
35
+
36
+ /**
37
+ * True if any of `names` resolves to an executable on PATH. Scans PATH entries
38
+ * and (on Windows) the PATHEXT extension list. Pure lookup — never executes.
39
+ * @param {string[]} names candidate binary base names (e.g. ["claude"])
40
+ * @param {{
41
+ * env?: Record<string,string|undefined>,
42
+ * existsSync?: (p: string) => boolean,
43
+ * platform?: NodeJS.Platform,
44
+ * }} [deps]
45
+ * @returns {boolean}
46
+ */
47
+ export function binaryOnPath(names, { env = process.env, existsSync = fsExistsSync, platform = process.platform } = {}) {
48
+ const rawPath = env.PATH ?? env.Path ?? "";
49
+ if (!rawPath) return false;
50
+ const sep = platform === "win32" ? ";" : pathDelimiter;
51
+ const dirs = rawPath.split(sep).filter(Boolean);
52
+ const exts =
53
+ platform === "win32"
54
+ ? ["", ...String(env.PATHEXT ?? ".EXE;.CMD;.BAT;.COM").split(";").filter(Boolean)]
55
+ : [""];
56
+ for (const name of names) {
57
+ if (!name) continue;
58
+ for (const dir of dirs) {
59
+ for (const ext of exts) {
60
+ // Windows filesystems are case-insensitive; try the ext as-given.
61
+ if (existsSync(join(dir, name + ext))) return true;
62
+ }
63
+ }
64
+ }
65
+ return false;
66
+ }
67
+
68
+ /**
69
+ * True if any of the config-dir specs (after expandPath) exists on disk.
70
+ * @param {string[]} specs
71
+ * @param {{
72
+ * env?: Record<string,string|undefined>,
73
+ * existsSync?: (p: string) => boolean,
74
+ * home?: string,
75
+ * }} [deps]
76
+ * @returns {boolean}
77
+ */
78
+ export function configDirPresent(specs, { env = process.env, existsSync = fsExistsSync, home = homedir() } = {}) {
79
+ for (const spec of specs || []) {
80
+ const resolved = expandPath(spec, { env, home });
81
+ if (resolved && existsSync(resolved)) return true;
82
+ }
83
+ return false;
84
+ }
85
+
86
+ /**
87
+ * Compute the dual-signal detection for one agent descriptor.
88
+ * @param {{ binaries: string[], configDirs: string[] }} descriptor
89
+ * @param {object} [deps] forwarded to binaryOnPath / configDirPresent
90
+ * @returns {{ binaryOnPath: boolean, configDirPresent: boolean }}
91
+ */
92
+ export function detectSignals(descriptor, deps = {}) {
93
+ return {
94
+ binaryOnPath: binaryOnPath(descriptor.binaries || [], deps),
95
+ configDirPresent: configDirPresent(descriptor.configDirs || [], deps),
96
+ };
97
+ }