@chorus-aidlc/chorus 0.19.1 → 0.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (322) hide show
  1. package/.next/standalone/.next/BUILD_ID +1 -1
  2. package/.next/standalone/.next/app-build-manifest.json +349 -349
  3. package/.next/standalone/.next/app-path-routes-manifest.json +38 -38
  4. package/.next/standalone/.next/build-manifest.json +5 -5
  5. package/.next/standalone/.next/prerender-manifest.json +18 -18
  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 +2 -2
  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 +2 -2
  45. package/.next/standalone/.next/server/app/admin/companies/[uuid]/page.js +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.js +1 -1
  48. package/.next/standalone/.next/server/app/admin/companies/new/page_client-reference-manifest.js +1 -1
  49. package/.next/standalone/.next/server/app/admin/companies/new.html +2 -2
  50. package/.next/standalone/.next/server/app/admin/companies/new.rsc +3 -3
  51. package/.next/standalone/.next/server/app/admin/companies/page_client-reference-manifest.js +1 -1
  52. package/.next/standalone/.next/server/app/admin/companies.html +2 -2
  53. package/.next/standalone/.next/server/app/admin/companies.rsc +2 -2
  54. package/.next/standalone/.next/server/app/admin/page_client-reference-manifest.js +1 -1
  55. package/.next/standalone/.next/server/app/admin.html +2 -2
  56. package/.next/standalone/.next/server/app/admin.rsc +2 -2
  57. package/.next/standalone/.next/server/app/api/admin/companies/[uuid]/route_client-reference-manifest.js +1 -1
  58. package/.next/standalone/.next/server/app/api/admin/companies/route_client-reference-manifest.js +1 -1
  59. package/.next/standalone/.next/server/app/api/admin/login/route_client-reference-manifest.js +1 -1
  60. package/.next/standalone/.next/server/app/api/admin/session/route_client-reference-manifest.js +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_client-reference-manifest.js +1 -1
  64. package/.next/standalone/.next/server/app/api/agents/route_client-reference-manifest.js +1 -1
  65. package/.next/standalone/.next/server/app/api/api-keys/[uuid]/route_client-reference-manifest.js +1 -1
  66. package/.next/standalone/.next/server/app/api/api-keys/route_client-reference-manifest.js +1 -1
  67. package/.next/standalone/.next/server/app/api/auth/callback/route_client-reference-manifest.js +1 -1
  68. package/.next/standalone/.next/server/app/api/auth/check-default/route_client-reference-manifest.js +1 -1
  69. package/.next/standalone/.next/server/app/api/auth/company-oidc/route_client-reference-manifest.js +1 -1
  70. package/.next/standalone/.next/server/app/api/auth/default-login/route_client-reference-manifest.js +1 -1
  71. package/.next/standalone/.next/server/app/api/auth/identify/route_client-reference-manifest.js +1 -1
  72. package/.next/standalone/.next/server/app/api/auth/logout/route_client-reference-manifest.js +1 -1
  73. package/.next/standalone/.next/server/app/api/auth/me/route_client-reference-manifest.js +1 -1
  74. package/.next/standalone/.next/server/app/api/auth/sync-token/route_client-reference-manifest.js +1 -1
  75. package/.next/standalone/.next/server/app/api/comments/route_client-reference-manifest.js +1 -1
  76. package/.next/standalone/.next/server/app/api/daemon/connection-heartbeat/route_client-reference-manifest.js +1 -1
  77. package/.next/standalone/.next/server/app/api/daemon/control/route_client-reference-manifest.js +1 -1
  78. package/.next/standalone/.next/server/app/api/daemon/directory-request/report/route_client-reference-manifest.js +1 -1
  79. package/.next/standalone/.next/server/app/api/daemon/execution-state/route_client-reference-manifest.js +1 -1
  80. package/.next/standalone/.next/server/app/api/daemon/executions/route_client-reference-manifest.js +1 -1
  81. package/.next/standalone/.next/server/app/api/daemon/pending-turns/route_client-reference-manifest.js +1 -1
  82. package/.next/standalone/.next/server/app/api/daemon/report-interrupt/route_client-reference-manifest.js +1 -1
  83. package/.next/standalone/.next/server/app/api/daemon/resume/route_client-reference-manifest.js +1 -1
  84. package/.next/standalone/.next/server/app/api/daemon/transcript/route_client-reference-manifest.js +1 -1
  85. package/.next/standalone/.next/server/app/api/daemon/turn-advance/route_client-reference-manifest.js +1 -1
  86. package/.next/standalone/.next/server/app/api/daemon-directory-requests/[uuid]/route_client-reference-manifest.js +1 -1
  87. package/.next/standalone/.next/server/app/api/daemon-directory-requests/route_client-reference-manifest.js +1 -1
  88. package/.next/standalone/.next/server/app/api/daemon-sessions/[sessionUuid]/instruction/route_client-reference-manifest.js +1 -1
  89. package/.next/standalone/.next/server/app/api/daemon-sessions/[sessionUuid]/repoint/route_client-reference-manifest.js +1 -1
  90. package/.next/standalone/.next/server/app/api/daemon-sessions/[sessionUuid]/route_client-reference-manifest.js +1 -1
  91. package/.next/standalone/.next/server/app/api/daemon-sessions/ad-hoc/route_client-reference-manifest.js +1 -1
  92. package/.next/standalone/.next/server/app/api/daemon-sessions/route_client-reference-manifest.js +1 -1
  93. package/.next/standalone/.next/server/app/api/documents/[uuid]/route_client-reference-manifest.js +1 -1
  94. package/.next/standalone/.next/server/app/api/entities/[type]/[uuid]/root-idea/route_client-reference-manifest.js +1 -1
  95. package/.next/standalone/.next/server/app/api/events/notifications/route_client-reference-manifest.js +1 -1
  96. package/.next/standalone/.next/server/app/api/events/route_client-reference-manifest.js +1 -1
  97. package/.next/standalone/.next/server/app/api/health/route_client-reference-manifest.js +1 -1
  98. package/.next/standalone/.next/server/app/api/ideas/[uuid]/claim/route_client-reference-manifest.js +1 -1
  99. package/.next/standalone/.next/server/app/api/ideas/[uuid]/move/preview/route_client-reference-manifest.js +1 -1
  100. package/.next/standalone/.next/server/app/api/ideas/[uuid]/move/route_client-reference-manifest.js +1 -1
  101. package/.next/standalone/.next/server/app/api/ideas/[uuid]/parent/route_client-reference-manifest.js +1 -1
  102. package/.next/standalone/.next/server/app/api/ideas/[uuid]/release/route_client-reference-manifest.js +1 -1
  103. package/.next/standalone/.next/server/app/api/ideas/[uuid]/route_client-reference-manifest.js +1 -1
  104. package/.next/standalone/.next/server/app/api/ideas/[uuid]/wake-preview/route_client-reference-manifest.js +1 -1
  105. package/.next/standalone/.next/server/app/api/ideas/conversational/route_client-reference-manifest.js +1 -1
  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_client-reference-manifest.js +1 -1
  108. package/.next/standalone/.next/server/app/api/mentionables/route_client-reference-manifest.js +1 -1
  109. package/.next/standalone/.next/server/app/api/notifications/[uuid]/archive/route_client-reference-manifest.js +1 -1
  110. package/.next/standalone/.next/server/app/api/notifications/[uuid]/read/route_client-reference-manifest.js +1 -1
  111. package/.next/standalone/.next/server/app/api/notifications/preferences/route_client-reference-manifest.js +1 -1
  112. package/.next/standalone/.next/server/app/api/notifications/read-all/route_client-reference-manifest.js +1 -1
  113. package/.next/standalone/.next/server/app/api/notifications/route_client-reference-manifest.js +1 -1
  114. package/.next/standalone/.next/server/app/api/notifications/unread-count/route_client-reference-manifest.js +1 -1
  115. package/.next/standalone/.next/server/app/api/project-groups/[uuid]/dashboard/route_client-reference-manifest.js +1 -1
  116. package/.next/standalone/.next/server/app/api/project-groups/[uuid]/route_client-reference-manifest.js +1 -1
  117. package/.next/standalone/.next/server/app/api/project-groups/route_client-reference-manifest.js +1 -1
  118. package/.next/standalone/.next/server/app/api/project-visits/pin/route_client-reference-manifest.js +1 -1
  119. package/.next/standalone/.next/server/app/api/project-visits/route_client-reference-manifest.js +1 -1
  120. package/.next/standalone/.next/server/app/api/project-visits/visit/route_client-reference-manifest.js +1 -1
  121. package/.next/standalone/.next/server/app/api/projects/[uuid]/activity/route_client-reference-manifest.js +1 -1
  122. package/.next/standalone/.next/server/app/api/projects/[uuid]/agent-cwds/route_client-reference-manifest.js +1 -1
  123. package/.next/standalone/.next/server/app/api/projects/[uuid]/available/route_client-reference-manifest.js +1 -1
  124. package/.next/standalone/.next/server/app/api/projects/[uuid]/documents/route_client-reference-manifest.js +1 -1
  125. package/.next/standalone/.next/server/app/api/projects/[uuid]/group/route_client-reference-manifest.js +1 -1
  126. package/.next/standalone/.next/server/app/api/projects/[uuid]/ideas/route_client-reference-manifest.js +1 -1
  127. package/.next/standalone/.next/server/app/api/projects/[uuid]/ideas/tracker/route_client-reference-manifest.js +1 -1
  128. package/.next/standalone/.next/server/app/api/projects/[uuid]/proposals/[proposalUuid]/validate/route_client-reference-manifest.js +1 -1
  129. package/.next/standalone/.next/server/app/api/projects/[uuid]/proposals/route_client-reference-manifest.js +1 -1
  130. package/.next/standalone/.next/server/app/api/projects/[uuid]/proposals/summary/route_client-reference-manifest.js +1 -1
  131. package/.next/standalone/.next/server/app/api/projects/[uuid]/resource-graph/route_client-reference-manifest.js +1 -1
  132. package/.next/standalone/.next/server/app/api/projects/[uuid]/route_client-reference-manifest.js +1 -1
  133. package/.next/standalone/.next/server/app/api/projects/[uuid]/stats/route_client-reference-manifest.js +1 -1
  134. package/.next/standalone/.next/server/app/api/projects/[uuid]/tasks/dependencies/route_client-reference-manifest.js +1 -1
  135. package/.next/standalone/.next/server/app/api/projects/[uuid]/tasks/route_client-reference-manifest.js +1 -1
  136. package/.next/standalone/.next/server/app/api/projects/agent-cwd-options/route_client-reference-manifest.js +1 -1
  137. package/.next/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  138. package/.next/standalone/.next/server/app/api/proposals/[uuid]/approve/route_client-reference-manifest.js +1 -1
  139. package/.next/standalone/.next/server/app/api/proposals/[uuid]/close/route_client-reference-manifest.js +1 -1
  140. package/.next/standalone/.next/server/app/api/proposals/[uuid]/reject/route_client-reference-manifest.js +1 -1
  141. package/.next/standalone/.next/server/app/api/proposals/[uuid]/revoke/route_client-reference-manifest.js +1 -1
  142. package/.next/standalone/.next/server/app/api/proposals/[uuid]/route_client-reference-manifest.js +1 -1
  143. package/.next/standalone/.next/server/app/api/references/[uuid]/route_client-reference-manifest.js +1 -1
  144. package/.next/standalone/.next/server/app/api/references/route_client-reference-manifest.js +1 -1
  145. package/.next/standalone/.next/server/app/api/search/route_client-reference-manifest.js +1 -1
  146. package/.next/standalone/.next/server/app/api/session/route_client-reference-manifest.js +1 -1
  147. package/.next/standalone/.next/server/app/api/sessions/[uuid]/route_client-reference-manifest.js +1 -1
  148. package/.next/standalone/.next/server/app/api/tasks/[uuid]/claim/route_client-reference-manifest.js +1 -1
  149. package/.next/standalone/.next/server/app/api/tasks/[uuid]/dependencies/[dependsOnUuid]/route_client-reference-manifest.js +1 -1
  150. package/.next/standalone/.next/server/app/api/tasks/[uuid]/dependencies/route_client-reference-manifest.js +1 -1
  151. package/.next/standalone/.next/server/app/api/tasks/[uuid]/release/route_client-reference-manifest.js +1 -1
  152. package/.next/standalone/.next/server/app/api/tasks/[uuid]/route_client-reference-manifest.js +1 -1
  153. package/.next/standalone/.next/server/app/api/tasks/[uuid]/sessions/route_client-reference-manifest.js +1 -1
  154. package/.next/standalone/.next/server/app/index.html +2 -2
  155. package/.next/standalone/.next/server/app/index.rsc +2 -2
  156. package/.next/standalone/.next/server/app/login/admin/page.js +1 -1
  157. package/.next/standalone/.next/server/app/login/admin/page_client-reference-manifest.js +1 -1
  158. package/.next/standalone/.next/server/app/login/admin.html +2 -2
  159. package/.next/standalone/.next/server/app/login/admin.rsc +3 -3
  160. package/.next/standalone/.next/server/app/login/callback/page_client-reference-manifest.js +1 -1
  161. package/.next/standalone/.next/server/app/login/callback.html +2 -2
  162. package/.next/standalone/.next/server/app/login/callback.rsc +2 -2
  163. package/.next/standalone/.next/server/app/login/page.js +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 +2 -2
  168. package/.next/standalone/.next/server/app/login.html +2 -2
  169. package/.next/standalone/.next/server/app/login.rsc +3 -3
  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 +3 -3
  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 +4 -4
  178. package/.next/standalone/.next/server/app/settings.html +2 -2
  179. package/.next/standalone/.next/server/app/settings.rsc +4 -4
  180. package/.next/standalone/.next/server/app-paths-manifest.json +38 -38
  181. package/.next/standalone/.next/server/chunks/1559.js +2 -2
  182. package/.next/standalone/.next/server/chunks/{657.js → 186.js} +1 -1
  183. package/.next/standalone/.next/server/chunks/2572.js +1 -1
  184. package/.next/standalone/.next/server/chunks/2961.js +1 -1
  185. package/.next/standalone/.next/server/chunks/3371.js +1 -0
  186. package/.next/standalone/.next/server/chunks/4131.js +39 -0
  187. package/.next/standalone/.next/server/chunks/4672.js +2 -2
  188. package/.next/standalone/.next/server/chunks/5245.js +1 -1
  189. package/.next/standalone/.next/server/chunks/5577.js +1 -0
  190. package/.next/standalone/.next/server/chunks/5728.js +1 -0
  191. package/.next/standalone/.next/server/chunks/6113.js +1 -1
  192. package/.next/standalone/.next/server/chunks/6515.js +2 -2
  193. package/.next/standalone/.next/server/chunks/6753.js +4 -4
  194. package/.next/standalone/.next/server/chunks/679.js +1 -1
  195. package/.next/standalone/.next/server/chunks/7368.js +1 -1
  196. package/.next/standalone/.next/server/chunks/7530.js +1 -1
  197. package/.next/standalone/.next/server/chunks/8017.js +1 -1
  198. package/.next/standalone/.next/server/chunks/8177.js +1 -0
  199. package/.next/standalone/.next/server/chunks/920.js +1 -1
  200. package/.next/standalone/.next/server/chunks/9213.js +1 -1
  201. package/.next/standalone/.next/server/chunks/9378.js +1 -1
  202. package/.next/standalone/.next/server/chunks/9931.js +1 -1
  203. package/.next/standalone/.next/server/middleware-build-manifest.js +1 -1
  204. package/.next/standalone/.next/server/middleware-manifest.json +5 -5
  205. package/.next/standalone/.next/server/pages/404.html +2 -2
  206. package/.next/standalone/.next/server/pages/500.html +1 -1
  207. package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
  208. package/.next/standalone/.next/server/server-reference-manifest.json +1 -1
  209. package/.next/standalone/.next/static/chunks/{11595.b2b74d1d1d0ae9d9.js → 11595.4cebcf7499ef6a78.js} +1 -1
  210. package/.next/standalone/.next/static/chunks/27370-0d04028ec8a339f0.js +1 -0
  211. package/.next/standalone/.next/static/chunks/27787-3566e3dd0506e241.js +1 -0
  212. package/.next/standalone/.next/static/chunks/{33456.978e5f47d1c8eb93.js → 33456.a5a9acba61ca3665.js} +1 -1
  213. package/.next/standalone/.next/static/chunks/{4860.79d6eefc2861716f.js → 4860.61dfcdf8c4c5c703.js} +1 -1
  214. package/.next/standalone/.next/static/chunks/53504-3a0f6dee12a39d5d.js +1 -0
  215. package/.next/standalone/.next/static/chunks/63819-c52b5bc9ee32ca9b.js +1 -0
  216. package/.next/standalone/.next/static/chunks/76103-5d656aebd9cd5e7f.js +1 -0
  217. package/.next/standalone/.next/static/chunks/78847-9f65efbac984cf70.js +1 -0
  218. package/.next/standalone/.next/static/chunks/79919-32af2c1abfc92a30.js +1 -0
  219. package/.next/standalone/.next/static/chunks/91997-3592827b5a069beb.js +1 -0
  220. package/.next/standalone/.next/static/chunks/{99373.e659954ff5148796.js → 99373.747e181e4c952509.js} +1 -1
  221. package/.next/standalone/.next/static/chunks/app/(dashboard)/layout-6135300353d6c6ad.js +1 -0
  222. package/.next/standalone/.next/static/chunks/app/(dashboard)/project-groups/[uuid]/page-bb9f26c107a6b113.js +1 -0
  223. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/dashboard/page-31dd9042ee36b8e5.js +1 -0
  224. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/documents/[documentUuid]/page-a6bfa3b6b6893bc4.js +1 -0
  225. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/documents/page-01e81333c9beee2d.js +1 -0
  226. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/graph/{page-487d071317ae5e6d.js → page-795b161eb0694092.js} +1 -1
  227. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/[proposalUuid]/page-e20e65b5df817433.js +1 -0
  228. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/new/page-fc2d02d552bbdbf0.js +1 -0
  229. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/page-0cfa38d2de9fa9d9.js +1 -0
  230. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/tasks/[taskUuid]/{page-7cb8a91f6ca34ba8.js → page-529dec4c3bcd5ba9.js} +1 -1
  231. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/tasks/{page-6466141ca355d9a4.js → page-b211c29669eaa3e4.js} +1 -1
  232. package/.next/standalone/.next/static/chunks/app/(dashboard)/settings/page-0606d1497512e155.js +1 -0
  233. package/.next/standalone/.next/static/chunks/app/admin/companies/[uuid]/page-47e49c331996193b.js +1 -0
  234. package/.next/standalone/.next/static/chunks/app/admin/companies/new/page-c1e28205503002de.js +1 -0
  235. package/.next/standalone/.next/static/chunks/app/login/admin/page-b0d0ea2fa4102ff7.js +1 -0
  236. package/.next/standalone/.next/static/chunks/app/login/page-ee63e900cb54148c.js +1 -0
  237. package/.next/standalone/.next/static/chunks/app/onboarding/{page-323e1d93218758c5.js → page-1f3ab167cab58610.js} +1 -1
  238. package/.next/standalone/.next/static/chunks/{webpack-ec441a05567c82b0.js → webpack-6151d196b2fab7e8.js} +1 -1
  239. package/.next/standalone/.next/static/css/09ac5931fe977492.css +1 -0
  240. package/.next/standalone/package.json +1 -1
  241. package/.next/standalone/public/chorus-plugin/.claude-plugin/plugin.json +1 -1
  242. package/.next/standalone/public/chorus-plugin/bin/chorus-api.sh +1 -1
  243. package/.next/standalone/public/chorus-plugin/skills/brainstorm/SKILL.md +1 -1
  244. package/.next/standalone/public/chorus-plugin/skills/chorus/SKILL.md +1 -1
  245. package/.next/standalone/public/chorus-plugin/skills/chorus-cli/SKILL.md +1 -1
  246. package/.next/standalone/public/chorus-plugin/skills/develop/SKILL.md +1 -1
  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 +1 -1
  250. package/.next/standalone/public/chorus-plugin/skills/orchestrate/SKILL.md +1 -1
  251. package/.next/standalone/public/chorus-plugin/skills/proposal/SKILL.md +1 -1
  252. package/.next/standalone/public/chorus-plugin/skills/quick-dev/SKILL.md +1 -1
  253. package/.next/standalone/public/chorus-plugin/skills/research/SKILL.md +1 -1
  254. package/.next/standalone/public/chorus-plugin/skills/review/SKILL.md +1 -1
  255. package/.next/standalone/public/chorus-plugin/skills/spec-lite/SKILL.md +1 -1
  256. package/.next/standalone/public/chorus-plugin/skills/yolo/SKILL.md +1 -1
  257. package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-brainstorm/SKILL.md +1 -1
  258. package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-cli/SKILL.md +1 -1
  259. package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-develop/SKILL.md +1 -1
  260. package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-docs/SKILL.md +1 -1
  261. package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-idea/SKILL.md +1 -1
  262. package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-openspec-aware/SKILL.md +1 -1
  263. package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-orchestrate/SKILL.md +1 -1
  264. package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-proposal/SKILL.md +1 -1
  265. package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-quick-dev/SKILL.md +1 -1
  266. package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-research/SKILL.md +1 -1
  267. package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-review/SKILL.md +1 -1
  268. package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-spec-lite/SKILL.md +1 -1
  269. package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-yolo/SKILL.md +1 -1
  270. package/.next/standalone/public/kiro-plugin/bin/chorus-api.sh +1 -1
  271. package/README.ja.md +3 -1
  272. package/README.ko.md +3 -1
  273. package/README.md +18 -1
  274. package/README.zh.md +18 -1
  275. package/chorus.mjs +7 -1
  276. package/cli/agent-cli-config.mjs +28 -2
  277. package/cli/claude-spawner.mjs +330 -18
  278. package/cli/codex-app-server-client.mjs +402 -0
  279. package/cli/codex-app-server-events.mjs +176 -0
  280. package/cli/codex-session-map.mjs +1 -1
  281. package/cli/codex-spawner.mjs +247 -241
  282. package/cli/init/adapters.mjs +2 -2
  283. package/cli/init/file-template.mjs +11 -4
  284. package/cli/init/install-methods.mjs +3 -1
  285. package/cli/pi-spawner.mjs +472 -78
  286. package/cli/process-killer.mjs +138 -13
  287. package/cli/process-stop-hooks.mjs +13 -0
  288. package/cli/upgrade-plugins.mjs +202 -0
  289. package/cli/upgrade-process.mjs +159 -0
  290. package/cli/upgrade.mjs +125 -0
  291. package/cli/upload-hooks.mjs +2 -2
  292. package/cli/windows-process-tree.mjs +154 -0
  293. package/package.json +1 -1
  294. package/.next/standalone/.next/server/chunks/3420.js +0 -1
  295. package/.next/standalone/.next/server/chunks/38.js +0 -39
  296. package/.next/standalone/.next/server/chunks/5576.js +0 -1
  297. package/.next/standalone/.next/server/chunks/6125.js +0 -1
  298. package/.next/standalone/.next/server/chunks/6509.js +0 -1
  299. package/.next/standalone/.next/static/chunks/17081-63e2cad8c15da2fb.js +0 -1
  300. package/.next/standalone/.next/static/chunks/27370-f998ed24dd4fa975.js +0 -1
  301. package/.next/standalone/.next/static/chunks/46437-88abf056c31c7e4e.js +0 -1
  302. package/.next/standalone/.next/static/chunks/48365-13b8e43016ba16a4.js +0 -1
  303. package/.next/standalone/.next/static/chunks/71522-de2b2a9d8e5059e1.js +0 -1
  304. package/.next/standalone/.next/static/chunks/79919-d423af700ae83862.js +0 -1
  305. package/.next/standalone/.next/static/chunks/91796-d235607f577fbaeb.js +0 -1
  306. package/.next/standalone/.next/static/chunks/99540-99af558190f96511.js +0 -1
  307. package/.next/standalone/.next/static/chunks/app/(dashboard)/layout-adf9dbdf339e9038.js +0 -1
  308. package/.next/standalone/.next/static/chunks/app/(dashboard)/project-groups/[uuid]/page-cf8ff072a8bc7409.js +0 -1
  309. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/dashboard/page-00d18e26961cee2f.js +0 -1
  310. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/documents/[documentUuid]/page-9ed4d7d4f5897de0.js +0 -1
  311. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/documents/page-9d6d86299f2fadd9.js +0 -1
  312. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/[proposalUuid]/page-b18a2aba2c4f4f1c.js +0 -1
  313. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/new/page-32149a823e7abf42.js +0 -1
  314. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/page-0ac33f9146fc53c5.js +0 -1
  315. package/.next/standalone/.next/static/chunks/app/(dashboard)/settings/page-ba19aec7fde5086c.js +0 -1
  316. package/.next/standalone/.next/static/chunks/app/admin/companies/[uuid]/page-56118c51122ad639.js +0 -1
  317. package/.next/standalone/.next/static/chunks/app/admin/companies/new/page-4e20deb41357171c.js +0 -1
  318. package/.next/standalone/.next/static/chunks/app/login/admin/page-c8e40259e5d3d9e0.js +0 -1
  319. package/.next/standalone/.next/static/chunks/app/login/page-0a16a64855b771ef.js +0 -1
  320. package/.next/standalone/.next/static/css/652fcc1f1ab231c8.css +0 -1
  321. /package/.next/standalone/.next/static/{AWk31w7ryFKaxOnUlIeo2 → kDppeym4sfPwXjGFspZG8}/_buildManifest.js +0 -0
  322. /package/.next/standalone/.next/static/{AWk31w7ryFKaxOnUlIeo2 → kDppeym4sfPwXjGFspZG8}/_ssgManifest.js +0 -0
@@ -3,8 +3,9 @@
3
3
  // channel (子3 — daemon-interrupt-resume, Tech Design "Killer contract"). When an
4
4
  // authorized interrupt is verified, the daemon must STOP a running headless-Claude
5
5
  // subprocess — first gracefully (SIGINT, so the model can flush in-progress work),
6
- // then forcefully if it does not exit within a configurable window. Plain ESM, ZERO
7
- // new npm deps (CLAUDE.md pitfall #9) and Bash-3.2-safe (no shell touched).
6
+ // then forcefully if it does not exit within a configurable window. Plain ESM,
7
+ // zero new npm deps. Codex's Windows protocol path uses fixed, noninteractive
8
+ // PowerShell/CIM queries to retain process identities across graceful root exit.
8
9
  //
9
10
  // Why a process TREE, not just the direct child:
10
11
  // • POSIX: Claude may itself spawn children. Linux does NOT cascade a signal to a
@@ -28,8 +29,24 @@
28
29
  // (every signal/spawn is try/caught), and LOGS visibly (memory: no-silent-errors).
29
30
 
30
31
  import { spawn as nodeSpawn } from "node:child_process";
32
+ import { getProcessStopHook } from "./process-stop-hooks.mjs";
33
+ import { WindowsProcessTree } from "./windows-process-tree.mjs";
31
34
 
32
35
  const NOOP_LOGGER = { info() {}, warn() {}, error() {} };
36
+ const protocolStops = new WeakMap();
37
+
38
+ /** Bound even an uncooperative hook; consume late rejection and clear the timer. */
39
+ async function withinDeadline(work, deadline) {
40
+ let timer;
41
+ try {
42
+ return await Promise.race([
43
+ Promise.resolve(work).then(() => true, () => false),
44
+ new Promise((resolve) => { timer = setTimeout(() => resolve(false), Math.max(0, deadline - Date.now())); }),
45
+ ]);
46
+ } finally {
47
+ clearTimeout(timer);
48
+ }
49
+ }
33
50
 
34
51
  /** Default escalation window before a forceful kill (Tech Design / spec: 10s). */
35
52
  export const DEFAULT_SIGINT_TIMEOUT_MS = 10_000;
@@ -98,6 +115,66 @@ export async function killProcessTree(child, opts = {}) {
98
115
  const sigintTimeoutMs = opts.sigintTimeoutMs ?? DEFAULT_SIGINT_TIMEOUT_MS;
99
116
  const isWin = platform === "win32";
100
117
 
118
+ const hook = !opts.skipStopHook && getProcessStopHook(child);
119
+ if (hook) {
120
+ const existing = protocolStops.get(child);
121
+ const deadline = existing?.deadline ?? Date.now() + sigintTimeoutMs;
122
+ const protocolDeadline = existing?.protocolDeadline ??
123
+ (isWin ? deadline - Math.min(2500, Math.floor(Math.max(0, sigintTimeoutMs) / 4)) : deadline);
124
+ const windowsTree = isWin && typeof child.pid === "number"
125
+ ? existing?.windowsTree ?? new WindowsProcessTree(child, {
126
+ deadline, spawnImpl, snapshotImpl: opts.windowsSnapshotImpl,
127
+ }) : null;
128
+ // Invoke synchronously even during an existing normal cleanup: cancellation
129
+ // must latch before any pending setup/turn-start continuation can execute.
130
+ let work;
131
+ try {
132
+ work = hook({
133
+ deadline, protocolDeadline, reason: opts.reason ?? "interrupt",
134
+ beforeClose: windowsTree ? () => windowsTree.capture() : undefined,
135
+ });
136
+ } catch {
137
+ work = Promise.reject(new Error("Protocol stop failed"));
138
+ }
139
+ const attempt = withinDeadline(work, deadline);
140
+ if (existing) {
141
+ await attempt;
142
+ return existing.promise;
143
+ }
144
+ const promise = (async () => {
145
+ const graceful = await attempt;
146
+ if (!graceful) logger.warn("[Chorus] protocol stop failed or exceeded its cleanup deadline");
147
+ const exited = graceful && await waitForChildExit(child, Math.max(0, protocolDeadline - Date.now()), opts, logger);
148
+ if (windowsTree) {
149
+ let cleanup = { cleanupFailed: true, escalated: false };
150
+ const settled = await withinDeadline(windowsTree.cleanup().then(result => { cleanup = result; }), deadline);
151
+ const cleanupFailed = !settled || cleanup.cleanupFailed;
152
+ if (cleanupFailed) logger.warn("[Chorus] Windows process-tree cleanup could not be verified within its deadline.");
153
+ return { signaled: false, killed: !cleanupFailed, escalated: windowsTree.escalated,
154
+ ...(cleanupFailed ? { cleanupFailed: true } : {}) };
155
+ }
156
+ // A leader exit does not prove its process group is gone.
157
+ let treeRemains = !exited;
158
+ if (exited && typeof child.pid === "number") {
159
+ if (opts.hasTree) treeRemains = safeBool(opts.hasTree, logger);
160
+ else if (!isWin) {
161
+ try { killImpl(-child.pid, 0); treeRemains = true; }
162
+ catch (err) { treeRemains = err?.code !== "ESRCH"; }
163
+ }
164
+ }
165
+ const forced = treeRemains
166
+ ? await killProcessTree(child, { ...opts, skipStopHook: true, sigintTimeoutMs: 0, forceOnly: true, cleanupDeadline: deadline })
167
+ : null;
168
+ return { signaled: false, killed: true, escalated: Boolean(treeRemains),
169
+ ...(forced?.cleanupFailed ? { cleanupFailed: true } : {}) };
170
+ })();
171
+ protocolStops.set(child, { deadline, protocolDeadline, promise, windowsTree });
172
+ // Retain the completed operation while this child is reachable. A spawner's
173
+ // final cleanup can arrive just after escalation; it must reuse that deadline
174
+ // and result instead of starting a second stop. Weak keys require no disposal.
175
+ return await promise;
176
+ }
177
+
101
178
  if (!child || typeof child.pid !== "number") {
102
179
  // No live process to target — log and no-op (never throw into the wake path).
103
180
  logger.warn("[Chorus] killProcessTree: no child pid to target; ignoring");
@@ -106,8 +183,10 @@ export async function killProcessTree(child, opts = {}) {
106
183
  const pid = child.pid;
107
184
 
108
185
  // --- Stage 1: graceful SIGINT ---
109
- let signaled;
110
- if (isWin) {
186
+ let signaled = false;
187
+ if (opts.forceOnly) {
188
+ // The protocol path already spent its one shared graceful deadline.
189
+ } else if (isWin) {
111
190
  // Windows: deliver SIGINT to the direct child only (best-effort). Node maps
112
191
  // SIGINT to a console-stop on Windows; it cannot reach a tree there.
113
192
  try {
@@ -123,13 +202,14 @@ export async function killProcessTree(child, opts = {}) {
123
202
  }
124
203
 
125
204
  // --- Wait for graceful exit within the window ---
126
- const exitedGracefully = await waitForChildExit(child, sigintTimeoutMs, opts, logger);
205
+ const exitedGracefully = !opts.forceOnly && await waitForChildExit(child, sigintTimeoutMs, opts, logger);
127
206
  if (exitedGracefully) {
128
207
  logger.info(`[Chorus] interrupt: pid ${pid} exited gracefully within ${sigintTimeoutMs}ms`);
129
208
  return { signaled, killed: true, escalated: false };
130
209
  }
131
210
 
132
211
  // --- Stage 2: forceful tree kill ---
212
+ let cleanupFailed = false;
133
213
  if (isWin) {
134
214
  // taskkill /PID <pid> /T /F — /T ends the tree (child processes), /F forces it.
135
215
  try {
@@ -137,17 +217,59 @@ export async function killProcessTree(child, opts = {}) {
137
217
  stdio: "ignore",
138
218
  windowsHide: true,
139
219
  });
140
- // taskkill failures are logged, never thrown.
141
- tk?.on?.("error", (err) => logger.warn(`[Chorus] taskkill spawn error: ${err}`));
220
+ // Protocol cleanup certifies settlement, unlike legacy fire-and-forget
221
+ // escalation. Use only the time remaining in the original stop budget.
222
+ if (opts.forceOnly) {
223
+ cleanupFailed = !await waitForTaskkill(tk, opts.cleanupDeadline ?? Date.now(), logger);
224
+ } else {
225
+ tk?.on?.("error", (err) => logger.warn(`[Chorus] taskkill spawn error: ${err}`));
226
+ }
142
227
  logger.info(`[Chorus] interrupt: escalated — taskkill /PID ${pid} /T /F (windows)`);
143
228
  } catch (err) {
144
- logger.warn(`[Chorus] taskkill escalation failed for pid ${pid}: ${err}`);
229
+ cleanupFailed = true;
230
+ logger.warn(opts.forceOnly
231
+ ? "[Chorus] Codex process-tree cleanup could not start taskkill."
232
+ : `[Chorus] taskkill escalation failed for pid ${pid}: ${err}`);
145
233
  }
146
234
  } else {
147
- signalGroup(pid, "SIGKILL", killImpl, logger);
235
+ const delivered = signalGroup(pid, "SIGKILL", killImpl, logger);
236
+ if (!delivered && opts.forceOnly) {
237
+ try { killImpl(-pid, 0); cleanupFailed = true; }
238
+ catch (err) { cleanupFailed = err?.code !== "ESRCH"; }
239
+ }
148
240
  logger.info(`[Chorus] interrupt: escalated — SIGKILL to process group -${pid} (posix)`);
149
241
  }
150
- return { signaled, killed: true, escalated: true };
242
+ return { signaled, killed: true, escalated: true,
243
+ ...(opts.forceOnly && cleanupFailed ? { cleanupFailed: true } : {}) };
244
+ }
245
+
246
+ /** Bounded Windows termination acknowledgement; never includes tool output. */
247
+ function waitForTaskkill(child, deadline, logger) {
248
+ return new Promise(resolve => {
249
+ let settled = false;
250
+ const finish = ok => {
251
+ if (settled) return;
252
+ settled = true;
253
+ clearTimeout(timer);
254
+ child?.removeListener?.("exit", onExit);
255
+ // Keep the payload-blind error guard until close: spawn errors can arrive
256
+ // after the deadline. It retains no provider/stdio data.
257
+ if (!ok) logger.warn("[Chorus] Codex process-tree cleanup taskkill failed or exceeded its deadline.");
258
+ resolve(ok);
259
+ };
260
+ const onExit = (code, signal) => finish(code === 0 && !signal);
261
+ const onError = () => finish(false);
262
+ const onClose = code => {
263
+ finish(code === 0);
264
+ child?.removeListener?.("error", onError);
265
+ };
266
+ const timer = setTimeout(() => finish(false), Math.max(0, deadline - Date.now()));
267
+ child?.once?.("exit", onExit);
268
+ child?.once?.("close", onClose);
269
+ child?.on?.("error", onError);
270
+ if (!child?.once) finish(false);
271
+ else if (child.exitCode !== null && child.exitCode !== undefined) finish(child.exitCode === 0);
272
+ });
151
273
  }
152
274
 
153
275
  /**
@@ -170,7 +292,7 @@ async function waitForChildExit(child, ms, opts, logger) {
170
292
  const hasExited =
171
293
  typeof opts.hasExited === "function"
172
294
  ? safeBool(opts.hasExited, logger)
173
- : child.exitCode !== null && child.exitCode !== undefined;
295
+ : (child.exitCode !== null && child.exitCode !== undefined) || Boolean(child.signalCode);
174
296
  if (hasExited) return true;
175
297
 
176
298
  return await new Promise((resolve) => {
@@ -179,14 +301,17 @@ async function waitForChildExit(child, ms, opts, logger) {
179
301
  if (settled) return;
180
302
  settled = true;
181
303
  clearTimeout(timer);
304
+ child.removeListener?.("exit", onExit);
305
+ child.removeListener?.("close", onExit);
182
306
  resolve(value);
183
307
  };
308
+ const onExit = () => finish(true);
184
309
  const timer = setTimeout(() => finish(false), ms);
185
310
  // unref so a pending timer never keeps the daemon process alive on shutdown.
186
311
  timer?.unref?.();
187
312
  try {
188
- child.once?.("exit", () => finish(true));
189
- child.once?.("close", () => finish(true));
313
+ child.once?.("exit", onExit);
314
+ child.once?.("close", onExit);
190
315
  } catch (err) {
191
316
  logger.warn(`[Chorus] failed to attach exit listener: ${err}`);
192
317
  finish(false);
@@ -0,0 +1,13 @@
1
+ // Process-local capabilities: never serialized into execution snapshots.
2
+ const hooks = new WeakMap();
3
+
4
+ export function registerProcessStopHook(child, hook) {
5
+ hooks.set(child, hook);
6
+ return () => {
7
+ if (hooks.get(child) === hook) hooks.delete(child);
8
+ };
9
+ }
10
+
11
+ export function getProcessStopHook(child) {
12
+ return child && hooks.get(child);
13
+ }
@@ -0,0 +1,202 @@
1
+ import * as fs from "node:fs";
2
+ import { homedir, tmpdir } from "node:os";
3
+ import { join, posix, win32 } from "node:path";
4
+ import { overlayAgentEnv, getAgentEnv, validateAgentCliConfig, rejectSharedCliConfig } from "./agent-cli-config.mjs";
5
+ import { resolveBinaryPath } from "./agent-launcher.mjs";
6
+ import { readClaudeInstallState } from "./init/adapters.mjs";
7
+ import { installClaude, installCodex, installKiro, readCodexInstallState } from "./init/install-methods.mjs";
8
+ import { normalizeAssetBase } from "./init/file-template.mjs";
9
+ import { runUpgradeCommand, sanitizeUpgradeOutput, upgradeFailure } from "./upgrade-process.mjs";
10
+
11
+ const HOSTS = {
12
+ claude: { binary: "claude", variable: "CLAUDE_CONFIG_DIR", dir: [".claude"] },
13
+ codex: { binary: "codex", variable: "CODEX_HOME", dir: [".codex"] },
14
+ kiro: { binary: "kiro-cli", variable: "KIRO_DIR", dir: [".kiro"] },
15
+ pi: { binary: "pi", variable: "PI_CODING_AGENT_DIR", dir: [".pi", "agent"] },
16
+ };
17
+ const text = (v) => typeof v === "string" && v.trim() ? v.trim() : undefined;
18
+ const object = (v) => v && typeof v === "object" && !Array.isArray(v);
19
+
20
+ // Resolve existing ancestors too: two not-yet-created config dirs under aliased
21
+ // homes still share a destination. No directory is created during planning.
22
+ function canonical(path, io, p) {
23
+ try { return io.realpathSync(path); } catch (e) {
24
+ if (e.code !== "ENOENT") throw e;
25
+ const parent = p.dirname(path);
26
+ if (parent === path) return path;
27
+ return p.join(canonical(parent, io, p), p.basename(path));
28
+ }
29
+ }
30
+
31
+ export function planPluginTargets(config, deps = {}) {
32
+ const io = deps.fs ?? fs, platform = deps.platform ?? process.platform;
33
+ const p = platform === "win32" ? win32 : posix;
34
+ const base = deps.env ?? process.env;
35
+ if (!object(config) || (config.agents !== undefined && !Array.isArray(config.agents))) throw new Error("invalid config");
36
+ rejectSharedCliConfig(config);
37
+ const rows = config.agents ?? (Object.keys(config).length ? [config] : []);
38
+ const targets = new Map(), results = [];
39
+ rows.forEach((row, i) => {
40
+ // Stable indices associate every row without echoing untrusted names/keys.
41
+ const label = `agents[${i}]`;
42
+ if (!object(row)) { results.push({ target: label, complete: false, detail: "Malformed agent record." }); return; }
43
+ const rawType = text(row.agentType) ?? text(config.agent);
44
+ const type = rawType === "claude-code" ? "claude" : rawType;
45
+ const host = Object.hasOwn(HOSTS, type) ? HOSTS[type] : undefined;
46
+ if (!host) { results.push({ target: label, complete: false, detail: "Skipped: offline, unknown or missing explicit host type." }); return; }
47
+ try {
48
+ const overrides = validateAgentCliConfig({ env: row.env }, type, label).env;
49
+ let env = overlayAgentEnv(base, overrides, platform);
50
+ // Normalize Windows case aliases for existing installer readers.
51
+ for (const name of ["HOME", "USERPROFILE", "PATH", ...Object.values(HOSTS).map((h) => h.variable)]) {
52
+ const value = getAgentEnv(env, name, platform);
53
+ if (value !== undefined) env = overlayAgentEnv(env, { [name]: value }, platform);
54
+ }
55
+ const homeOverride = getAgentEnv(overrides, "HOME", platform) ||
56
+ getAgentEnv(overrides, "USERPROFILE", platform);
57
+ const home = p.resolve(homeOverride || env.HOME || env.USERPROFILE || homedir());
58
+ env.HOME = home;
59
+ if (platform === "win32") env.USERPROFILE = home;
60
+ const destination = canonical(p.resolve(env[host.variable] || p.join(home, ...host.dir)), io, p);
61
+ env[host.variable] = destination;
62
+ // Do not inherit an interactive Claude nesting guard into its plugin CLI.
63
+ delete env.CLAUDECODE;
64
+ delete env.CLAUDE_CODE_ENTRYPOINT;
65
+ const key = `${type}:${platform === "win32" ? destination.toLowerCase() : destination}`;
66
+ let source;
67
+ if (type === "kiro") {
68
+ source = normalizeAssetBase(text(row.url) ?? text(config.url) ?? env.CHORUS_URL);
69
+ const url = new URL(source);
70
+ if (url.username || url.password || url.search || url.hash) throw new Error("invalid source");
71
+ }
72
+ const existing = targets.get(key);
73
+ if (existing) {
74
+ existing.labels.push(label);
75
+ if (existing.source !== source) existing.conflict = true;
76
+ } else targets.set(key, { type, host, destination, env, source, labels: [label] });
77
+ } catch {
78
+ results.push({ target: label, complete: false, detail: "Invalid environment, destination or Chorus source URL." });
79
+ }
80
+ });
81
+ return { targets: [...targets.values()], results };
82
+ }
83
+
84
+ function readJson(path, io) {
85
+ try { return JSON.parse(io.readFileSync(path, "utf8")); }
86
+ catch (e) { if (e.code === "ENOENT") return undefined; throw e; }
87
+ }
88
+
89
+ // Verified against installed pi update/install --help (2026-09-30). Probe the
90
+ // actual target host as older releases have only the all-extension updater.
91
+ export function upgradePi(target, { run, fs: io = fs }) {
92
+ const settings = readJson(join(target.destination, "settings.json"), io);
93
+ if (settings !== undefined && (!object(settings) || (settings.packages !== undefined && !Array.isArray(settings.packages)))) {
94
+ throw new Error("invalid Pi settings");
95
+ }
96
+ const packages = settings?.packages ?? [];
97
+ let complete = true, changed = false, constrained = false;
98
+ const help = run("pi", ["update", "--help"]);
99
+ const targeted = help.ok && /--extension\s+<source>/.test(help.stdout) && /--no-approve\b/.test(help.stdout);
100
+ let installHelp;
101
+ for (const spec of ["npm:pi-mcp-adapter", "npm:@chorus-aidlc/chorus-pi"]) {
102
+ const sources = packages.map((entry) => {
103
+ const source = typeof entry === "string" ? entry : entry?.source;
104
+ return source;
105
+ }).filter((source) => source === spec || (typeof source === "string" && source.startsWith(`${spec}@`)));
106
+ const present = sources.length > 0;
107
+ // Pi updates by identity but retains configured constraints. Pinned versions
108
+ // are a successful no-op; ranges/tags can also exclude the latest release.
109
+ // Preserve those settings and report incomplete rather than silently unpin.
110
+ if (sources.some((source) => source !== spec && source !== `${spec}@latest`)) {
111
+ complete = false;
112
+ constrained = true;
113
+ continue;
114
+ }
115
+ if (present && !targeted) { complete = false; continue; }
116
+ if (!present) {
117
+ installHelp ??= run("pi", ["install", "--help"]);
118
+ if (!installHelp.ok || !/--no-approve\b/.test(installHelp.stdout)) { complete = false; continue; }
119
+ }
120
+ const r = run("pi", present ? ["update", "--extension", spec, "--no-approve"] : ["install", spec, "--no-approve"]);
121
+ changed = true; // A failed command can still leave a partial change.
122
+ if (!r.ok) complete = false;
123
+ }
124
+ return {
125
+ complete, changed,
126
+ detail: complete ? "Refreshed Chorus and pi-mcp-adapter only."
127
+ : constrained ? "Pi refresh incomplete: configured package version constraints were preserved; remove those constraints to permit latest updates. Other eligible components were attempted."
128
+ : "Pi refresh incomplete: targeted update/install unsupported or failed; no all-extension update was run.",
129
+ };
130
+ }
131
+
132
+ export async function upgradePlugins(deps = {}) {
133
+ const io = deps.fs ?? fs, env = deps.env ?? process.env, platform = deps.platform ?? process.platform;
134
+ const p = platform === "win32" ? win32 : posix;
135
+ const configPath = deps.configPath ?? p.join(getAgentEnv(env, "HOME", platform) || getAgentEnv(env, "USERPROFILE", platform) || homedir(), ".chorus", "daemon.json");
136
+ let plan;
137
+ try {
138
+ const config = readJson(configPath, io);
139
+ if (config === undefined) return [{ target: "plugins", complete: true, detail: "No daemon configuration; no configured plugins." }];
140
+ plan = planPluginTargets(config, deps);
141
+ } catch {
142
+ return [{ target: "plugins", complete: false, detail: "Cannot read or validate daemon configuration." }];
143
+ }
144
+ const results = plan.results;
145
+ if (!plan.targets.length && !results.length) return [{ target: "plugins", complete: true, detail: "No configured plugins." }];
146
+ for (const target of plan.targets) {
147
+ const label = `${target.type} (${target.labels.join(", ")})`;
148
+ if (target.conflict) {
149
+ results.push({ target: label, complete: false, detail: "Conflicting Chorus URLs for one Kiro destination; no update attempted." });
150
+ continue;
151
+ }
152
+ if (!(deps.resolveBinary ?? resolveBinaryPath)(target.host.binary, { env: target.env, platform })) {
153
+ results.push({ target: label, complete: false, detail: "Skipped: host executable missing from this record's PATH." });
154
+ continue;
155
+ }
156
+ let scratch;
157
+ let changed = false;
158
+ const failures = [];
159
+ const safe = (text) => sanitizeUpgradeOutput(text, { env: target.env });
160
+ try {
161
+ // Package commands must not discover project-local plugin configuration.
162
+ scratch = io.mkdtempSync(join(tmpdir(), "chorus-upgrade-"));
163
+ const run = (cmd, args) => {
164
+ if (!args.includes("--help")) changed = true;
165
+ const result = (deps.run ?? runUpgradeCommand)(cmd, args, { env: target.env, platform, cwd: scratch, timeoutMs: 120_000 });
166
+ if (!result.ok) failures.push(`${cmd} ${args.slice(0, 2).join(" ")}: ${upgradeFailure(result, { env: target.env })}`);
167
+ return result;
168
+ };
169
+ if (target.type === "pi") {
170
+ const result = upgradePi(target, { run, fs: io });
171
+ results.push({ target: label, ...result, detail: safe([result.detail, ...failures].join("\n")) });
172
+ continue;
173
+ }
174
+ const state = target.type === "claude"
175
+ ? readClaudeInstallState({ env: target.env, home: target.env.HOME, readJson: (path) => readJson(path, io) })
176
+ : target.type === "codex" ? readCodexInstallState({ env: target.env }) : {};
177
+ const install = (deps.installers ?? { claude: installClaude, codex: installCodex, kiro: installKiro })[target.type];
178
+ const outcome = await install({
179
+ env: target.env, platform, run,
180
+ flags: { updateInstalled: true, pluginOnly: true, url: target.source },
181
+ adapter: { readInstallState: () => state },
182
+ backup: (path) => {
183
+ if (io.existsSync(path)) io.copyFileSync(path, `${path}.chorus-upgrade.bak`);
184
+ },
185
+ // Keep the deadline active while response bodies are consumed too.
186
+ fetch: (url) => (deps.fetch ?? globalThis.fetch)(url, { signal: AbortSignal.timeout(30_000) }),
187
+ });
188
+ const complete = ["installed", "repaired"].includes(outcome.action);
189
+ changed ||= complete;
190
+ results.push({
191
+ target: label, complete, changed,
192
+ detail: complete ? (target.source ? `Refreshed Chorus templates from ${target.source}.` : "Chorus plugin refreshed.")
193
+ : safe([outcome.detail || "Plugin update failed or is unsupported.", ...failures].join("\n")),
194
+ });
195
+ } catch (error) {
196
+ results.push({ target: label, complete: false, changed, detail: safe(`Plugin update failed: ${error?.message || "unknown error"}\n${failures.join("\n")}`) });
197
+ } finally {
198
+ if (scratch) io.rmSync(scratch, { recursive: true, force: true });
199
+ }
200
+ }
201
+ return results;
202
+ }
@@ -0,0 +1,159 @@
1
+ // Queries are bounded; npm installation streams sanitized progress without a
2
+ // deadline that could interrupt replacement of the running package.
3
+ import { spawn, spawnSync } from "node:child_process";
4
+ import { existsSync, realpathSync } from "node:fs";
5
+ import { stripVTControlCharacters } from "node:util";
6
+ import { win32, posix } from "node:path";
7
+ import { resolveBinaryPath } from "./agent-launcher.mjs";
8
+ import { getAgentEnv } from "./agent-cli-config.mjs";
9
+
10
+ export function sanitizeUpgradeOutput(value, { env = process.env, secrets = [] } = {}) {
11
+ let text = stripVTControlCharacters(String(value ?? ""));
12
+ const values = [...secrets, ...Object.entries(env)
13
+ .filter(([key]) => /key|token|secret|password|credential|auth/i.test(key))
14
+ .map(([, v]) => v)].filter((v) => typeof v === "string" && v.length > 0);
15
+ // Streaming emits complete lines before the next line arrives. Protect each
16
+ // nonempty line of multiline credentials, including whitespace-normalized
17
+ // output, as well as whole-value JSON/URL representations in diagnostics.
18
+ const forms = new Set();
19
+ for (const value of values) {
20
+ for (const part of [value, ...value.split(/\r?\n/)]) {
21
+ for (const secret of [part, part.trim()]) {
22
+ if (!secret) continue;
23
+ forms.add(secret);
24
+ forms.add(JSON.stringify(secret).slice(1, -1));
25
+ forms.add(encodeURIComponent(secret));
26
+ }
27
+ }
28
+ }
29
+ for (const form of [...forms].sort((a, b) => b.length - a.length)) text = text.split(form).join("[redacted]");
30
+ return text
31
+ .replace(/\b(?:cho_|npm_|gh[pousr]_|sk-)[A-Za-z0-9_-]+/g, "[redacted]")
32
+ .replace(/\b(authorization["']?\s*[:=]\s*["']?)(?:bearer\s+|basic\s+)?[^"'\s,;]+/gi, "$1[redacted]")
33
+ .replace(/((?:["']?[\w.-]*(?:token|password|secret|api[_-]?key|_auth)[\w.-]*["']?)\s*[:=]\s*)(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|[^\s,;]+)/gi, "$1[redacted]")
34
+ .replace(/https?:\/\/[^\s"'<>]+/gi, (url) => {
35
+ try {
36
+ const parsed = new URL(url);
37
+ if (parsed.username || parsed.password) { parsed.username = "[redacted]"; parsed.password = ""; }
38
+ for (const key of [...parsed.searchParams.keys()]) parsed.searchParams.set(key, "[redacted]");
39
+ if (parsed.hash) parsed.hash = "[redacted]";
40
+ return parsed.toString();
41
+ } catch { return "[redacted URL]"; }
42
+ })
43
+ .replace(/[\x00-\x08\x0b-\x1f\x7f]/g, "");
44
+ }
45
+
46
+ export function upgradeFailure(result, opts = {}) {
47
+ const status = Number.isInteger(result?.code) ? `exit ${result.code}`
48
+ : result?.signal ? `signal ${result.signal}` : result?.reason || "command failed";
49
+ const sanitized = sanitizeUpgradeOutput(result?.stderr || result?.error || result?.stdout || "", opts);
50
+ const permission = sanitized.match(/\b(?:EACCES|EPERM)\b/)?.[0];
51
+ const detail = sanitized.trim().split("\n").slice(-6).join("\n").slice(-2000);
52
+ return `${status}${permission ? ` (${permission})` : ""}${detail ? `: ${detail}` : ""}`;
53
+ }
54
+
55
+ function processResult(r, opts) {
56
+ return {
57
+ ok: !r.error && r.status === 0,
58
+ code: r.status ?? null, signal: r.signal ?? null,
59
+ stdout: sanitizeUpgradeOutput(r.stdout, opts),
60
+ stderr: sanitizeUpgradeOutput(r.stderr, opts),
61
+ error: sanitizeUpgradeOutput(r.error?.message || r.error?.code, opts),
62
+ reason: r.error?.code === "ETIMEDOUT" ? "timed out" : "command failed",
63
+ };
64
+ }
65
+
66
+ export function commandForUpgrade(binary, args, {
67
+ platform = process.platform, env = process.env, node = process.execPath,
68
+ exists = existsSync, realpath = realpathSync,
69
+ } = {}) {
70
+ const p = platform === "win32" ? win32 : posix;
71
+ if (platform !== "win32" || !/\.(cmd|bat)$/i.test(binary)) {
72
+ return { command: binary, args };
73
+ }
74
+ if (/^npm\.(cmd|bat)$/i.test(p.basename(binary))) {
75
+ const cli = p.join(p.dirname(binary), "node_modules", "npm", "bin", "npm-cli.js");
76
+ if (!exists(cli)) throw new Error("npm shim has no npm-cli.js");
77
+ return { command: node, args: [realpath(cli), ...args] };
78
+ }
79
+ // Native host binaries use argv directly. For a Windows command shim, quote
80
+ // spaces and reject cmd expansion/control characters rather than interpolate.
81
+ const tokens = [binary, ...args];
82
+ if (tokens.some((s) => /["%!^&|<>()\r\n\0]/.test(s))) {
83
+ throw new Error("Unsupported characters in Windows command shim");
84
+ }
85
+ return {
86
+ command: getAgentEnv(env, "COMSPEC", platform) || "cmd.exe",
87
+ args: ["/d", "/s", "/c", `"${tokens.map((s) => `"${s}"`).join(" ")}"`],
88
+ windowsVerbatimArguments: true,
89
+ };
90
+ }
91
+
92
+ export function runUpgradeCommand(cmd, args = [], opts = {}) {
93
+ const env = opts.env ?? process.env;
94
+ const platform = opts.platform ?? process.platform;
95
+ try {
96
+ const binary = (opts.resolveBinary ?? resolveBinaryPath)(cmd, { env, platform });
97
+ if (!binary) return { ok: false, reason: "missing executable" };
98
+ const launch = commandForUpgrade(binary, args, { ...opts, env, platform });
99
+ const r = (opts.spawnSync ?? spawnSync)(launch.command, launch.args, {
100
+ env, cwd: opts.cwd, shell: false, windowsHide: true,
101
+ windowsVerbatimArguments: launch.windowsVerbatimArguments,
102
+ stdio: ["ignore", "pipe", "pipe"], encoding: "utf8",
103
+ timeout: opts.timeoutMs ?? 120_000, killSignal: "SIGKILL", maxBuffer: 2 * 1024 * 1024,
104
+ });
105
+ return processResult(r, { ...opts, env });
106
+ } catch (error) {
107
+ return processResult({ error }, { ...opts, env });
108
+ }
109
+ }
110
+
111
+ export async function runUpgradeInstall(cmd, args = [], opts = {}) {
112
+ const env = opts.env ?? process.env, platform = opts.platform ?? process.platform;
113
+ try {
114
+ const binary = (opts.resolveBinary ?? resolveBinaryPath)(cmd, { env, platform });
115
+ if (!binary) return { ok: false, reason: "missing executable" };
116
+ const launch = commandForUpgrade(binary, args, { ...opts, env, platform });
117
+ return await new Promise((resolve) => {
118
+ const child = (opts.spawn ?? spawn)(launch.command, launch.args, {
119
+ env, cwd: opts.cwd, shell: false, windowsHide: true,
120
+ windowsVerbatimArguments: launch.windowsVerbatimArguments,
121
+ stdio: ["ignore", "pipe", "pipe"],
122
+ // No timeout, timer or automatic kill: let npm complete/roll back.
123
+ });
124
+ const buffers = { stdout: "", stderr: "" };
125
+ const tails = { stdout: "", stderr: "" };
126
+ const dropping = { stdout: false, stderr: false };
127
+ const emit = (name, line) => {
128
+ const safe = sanitizeUpgradeOutput(line, { ...opts, env });
129
+ tails[name] = (tails[name] + safe + "\n").slice(-4000);
130
+ if (safe) opts.onOutput?.(safe);
131
+ };
132
+ for (const name of ["stdout", "stderr"]) {
133
+ child[name].setEncoding("utf8");
134
+ child[name].on("data", (chunk) => {
135
+ for (const part of chunk.match(/[^\n]*\n|[^\n]+$/g) ?? []) {
136
+ const ended = part.endsWith("\n");
137
+ if (!dropping[name]) buffers[name] += part;
138
+ if (buffers[name].length > 16_384) {
139
+ buffers[name] = "";
140
+ dropping[name] = true; // Never emit a fragment of a long secret.
141
+ }
142
+ if (ended) {
143
+ emit(name, dropping[name] ? "[overlong output line omitted]" : buffers[name].trimEnd());
144
+ buffers[name] = ""; dropping[name] = false;
145
+ }
146
+ }
147
+ });
148
+ }
149
+ let error;
150
+ child.on("error", (e) => { error = e; });
151
+ child.on("close", (status, signal) => {
152
+ for (const name of ["stdout", "stderr"]) {
153
+ if (dropping[name] || buffers[name]) emit(name, dropping[name] ? "[overlong output line omitted]" : buffers[name]);
154
+ }
155
+ resolve(processResult({ status, signal, error, ...tails }, { ...opts, env }));
156
+ });
157
+ });
158
+ } catch (error) { return processResult({ error }, { ...opts, env }); }
159
+ }