@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
@@ -1,47 +1,23 @@
1
- // cli/codex-spawner.mjs
2
- // Cross-platform headless Codex spawner — the `codex` counterpart to
3
- // ClaudeSpawner, satisfying the SAME backend-agnostic Spawner.wake(...) contract
4
- // so the daemon's wake pipeline (queue, waker, directed delivery, headless guard,
5
- // reporters) stays backend-neutral.
6
- //
7
- // Codex diverges structurally from Claude (verified against codex-cli 0.142.3 +
8
- // the ../codex source + a live `codex exec --json` run):
9
- // • `codex exec --json` emits JSONL (one event per line); the prompt is read
10
- // from STDIN (never argv). `codex exec resume <id> --json` continues a run.
11
- // • The FIRST event is `{"type":"thread.started","thread_id":"<uuid>"}` — Codex
12
- // GENERATES its own id (it does NOT accept a client `--session-id`). We capture
13
- // it and persist anchor→thread_id (codex-session-map.mjs) so a later wake can
14
- // `resume <thread_id>`. (serde: ThreadEvent tag="type", rename="thread.started";
15
- // ThreadStartedEvent.thread_id: String — codex-rs/exec/src/exec_events.rs.)
16
- // • No `--mcp-config`: Codex reads MCP servers from the user's ~/.codex/config.toml.
17
- // `chorus agents add` writes [mcp_servers.chorus] with bearer_token_env_var =
18
- // "CHORUS_API_KEY" — a KEYLESS reference (no literal key in config.toml), and Codex
19
- // resolves that env var into `Authorization: Bearer <key>` at connect. So the
20
- // CHORUS_API_KEY the daemon exports into the child env below DOES reach Codex's MCP
21
- // auth (as well as the plugin's shell tooling — chorus-api.sh / SessionStart hooks);
22
- // never argv. (Multi-agent: two Codex agents with different keys each need their own
23
- // CODEX_HOME so their config.toml + ~/.codex/.env don't collide.)
24
- // • Permission is a SANDBOX mode, not a tool allowlist.
25
- //
26
- // Reuses claude-spawner's platform-neutral helpers: parseNdjsonChunk (NDJSON
27
- // stream parse) and the PATH-walk shape of resolveClaudePath.
28
-
1
+ // One isolated Codex App Server stdio connection per daemon wake.
29
2
  import { spawn } from "node:child_process";
30
3
  import { safeSpawnError } from "./launch-diagnostics.mjs";
31
- import { validateAgentCliConfig, overlayAgentEnv, getAgentEnv, assertConfiguredShimArgs } from "./agent-cli-config.mjs";
4
+ import { validateAgentCliConfig, codexAppServerArgs, overlayAgentEnv, getAgentEnv, assertConfiguredShimArgs } from "./agent-cli-config.mjs";
32
5
  import { readFileSync, statSync } from "node:fs";
33
6
  import { homedir } from "node:os";
34
7
  import { join, win32 as pathWin32, posix as pathPosix } from "node:path";
35
- import { parseNdjsonChunk } from "./claude-spawner.mjs";
8
+ import { CodexAppServerClient, CodexAppServerError, isHistoryUnavailableError } from "./codex-app-server-client.mjs";
9
+ import { CodexAppServerEvents } from "./codex-app-server-events.mjs";
10
+ import { registerProcessStopHook } from "./process-stop-hooks.mjs";
11
+ import { killProcessTree } from "./process-killer.mjs";
36
12
  import { awaitChildSettled } from "./child-exit.mjs";
37
13
  import { getThreadId as defaultGetThreadId, setThreadId as defaultSetThreadId } from "./codex-session-map.mjs";
38
14
  import {
39
15
  getCodexUsageSnapshot as defaultGetUsageSnapshot,
40
- normalizeCodexUsageEvent,
41
16
  setCodexUsageSnapshot as defaultSetUsageSnapshot,
42
17
  } from "./codex-usage-map.mjs";
43
18
 
44
19
  const NOOP_LOGGER = { info() {}, warn() {}, error() {} };
20
+ const CLIENT_VERSION = JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf8")).version;
45
21
 
46
22
  /**
47
23
  * Check whether the user's Codex config declares the Chorus MCP server.
@@ -75,60 +51,9 @@ export function hasChorusMcpServer(deps = {}) {
75
51
  * implement it; the daemon injects one based on the resolved agent type.
76
52
  */
77
53
 
78
- /**
79
- * Map the daemon's backend-agnostic permission mode to a Codex sandbox posture.
80
- * The expression is SUBCOMMAND-AWARE because the two surfaces differ (verified
81
- * against codex 0.142.3): the top-level `codex exec` accepts `--sandbox <mode>`,
82
- * but `codex exec resume` does NOT — passing `--sandbox` there errors with exit 2.
83
- * yolo → --dangerously-bypass-approvals-and-sandbox (valid on BOTH exec and
84
- * resume; full autonomy)
85
- * chorus → exec: --sandbox read-only
86
- * resume: -c sandbox_mode="read-only" (the `-c` config override is how
87
- * `codex exec resume` accepts a sandbox mode; `sandbox_mode` is a real
88
- * config key, value spelled `read-only` per protocol/src/config_types.rs,
89
- * confirmed via `--strict-config`).
90
- * Anything other than yolo falls back to the restricted read-only posture.
91
- * @param {"yolo"|"chorus"|undefined} permissionMode
92
- * @param {{ resume?: boolean }} [opts] resume:true selects the `codex exec resume` surface.
93
- * @returns {string[]}
94
- */
95
- export function sandboxFlags(permissionMode, opts = {}) {
96
- if (permissionMode === "yolo") return ["--dangerously-bypass-approvals-and-sandbox"];
97
- // restricted read-only posture, expressed per subcommand:
98
- return opts.resume ? ["-c", 'sandbox_mode="read-only"'] : ["--sandbox", "read-only"];
99
- }
100
-
101
- /**
102
- * Build the argv for a headless codex run. Prompt is NEVER here — it goes over
103
- * stdin. `--skip-git-repo-check` lets a non-repo cwd still run.
104
- * @param {{ isNew: boolean, threadId?: string|null, permissionMode?: "yolo"|"chorus" }} o
105
- * @returns {string[]}
106
- */
107
- export function buildCodexArgs({ isNew, threadId, permissionMode }) {
108
- if (!isNew && threadId) {
109
- const sandbox = sandboxFlags(permissionMode, { resume: true });
110
- return ["exec", "resume", threadId, "--json", ...sandbox, "--skip-git-repo-check"];
111
- }
112
- const sandbox = sandboxFlags(permissionMode);
113
- return ["exec", "--json", ...sandbox, "--skip-git-repo-check"];
114
- }
115
-
116
- /**
117
- * Extract the Codex thread id from a stream event, or null. Accepts the live
118
- * `thread.started` shape (authoritative) and the on-disk rollout `session_meta`
119
- * shape as a defensive fallback.
120
- * @param {any} obj
121
- * @returns {string|null}
122
- */
123
- export function extractThreadId(obj) {
124
- if (!obj || typeof obj !== "object") return null;
125
- if (obj.type === "thread.started" && typeof obj.thread_id === "string") {
126
- return obj.thread_id.trim() || null;
127
- }
128
- if (obj.type === "session_meta" && obj.payload && typeof obj.payload.id === "string") {
129
- return obj.payload.id.trim() || null;
130
- }
131
- return null;
54
+ /** App Server transport is daemon-owned; policy is applied by RPC. */
55
+ export function buildCodexArgs({ args = [] } = {}) {
56
+ return ["app-server", "--listen", "stdio://", ...codexAppServerArgs(args)];
132
57
  }
133
58
 
134
59
  /**
@@ -217,182 +142,263 @@ export class CodexSpawner {
217
142
  this.platform = opts.platform ?? process.platform;
218
143
  this.cliConfig = validateAgentCliConfig(opts.cliConfig, "codex", opts.label);
219
144
  this.env = overlayAgentEnv(opts.env ?? process.env, this.cliConfig.env, this.platform);
220
- this.getThreadIdFn = opts.getThreadIdFn ?? defaultGetThreadId;
221
- this.setThreadIdFn = opts.setThreadIdFn ?? defaultSetThreadId;
222
- this.getUsageSnapshotFn = opts.getUsageSnapshotFn ?? defaultGetUsageSnapshot;
223
- this.setUsageSnapshotFn = opts.setUsageSnapshotFn ?? defaultSetUsageSnapshot;
145
+ const storeLogger = { warn: () => { throw new CodexAppServerError("STORE_IO_ERROR", "Codex local storage failed"); } };
146
+ this.getThreadIdFn = opts.getThreadIdFn ?? ((anchor) => defaultGetThreadId(anchor, { logger: storeLogger }));
147
+ this.setThreadIdFn = opts.setThreadIdFn ?? ((anchor, id) => defaultSetThreadId(anchor, id, { logger: storeLogger }));
148
+ this.getUsageSnapshotFn = opts.getUsageSnapshotFn ?? ((anchor, id) => defaultGetUsageSnapshot(anchor, id, { logger: storeLogger }));
149
+ this.setUsageSnapshotFn = opts.setUsageSnapshotFn ?? ((anchor, id, usage) => defaultSetUsageSnapshot(anchor, id, usage, { logger: storeLogger }));
224
150
  this.resolveCodexPathFn = opts.resolveCodexPathFn ?? resolveCodexPath;
225
151
  this.hasChorusMcpServerFn = opts.hasChorusMcpServerFn ?? hasChorusMcpServer;
226
152
  this.mcpConfigChecked = false;
153
+ this.rpcLimits = opts.rpcLimits;
154
+ this.cleanupTimeoutMs = opts.cleanupTimeoutMs ?? 10_000;
155
+ this.stdioGraceMs = opts.stdioGraceMs ?? 2_000;
156
+ this.maxBufferedBytes = opts.maxBufferedBytes;
157
+ this.killProcessTreeFn = opts.killProcessTreeFn ?? killProcessTree;
158
+ this.killOptions = opts.killOptions ?? {};
227
159
  }
228
160
 
229
- /**
230
- * Spawn a headless Codex run. Resolves when the subprocess exits. The prompt is
231
- * written to stdin (never argv). `sessionId` is the Chorus anchor (direct idea
232
- * uuid, or entity uuid). Codex owns its session id, so we IGNORE the passed
233
- * `isNew`/`mcpConfigPath` and decide new-vs-resume from the persisted
234
- * anchor→thread_id map: a recorded thread id → `resume`, otherwise a fresh run.
235
- *
236
- * @param {{ prompt: string, sessionId: string|null, isNew?: boolean, mcpConfigPath?: string,
237
- * cwd?: string, onMessage?: (obj: any) => void,
238
- * onChild?: (child: import("node:child_process").ChildProcess) => void }} params
239
- * @returns {Promise<{ sessionId: string, backendSessionId: string|null, exitCode: number|null, isNew: boolean }>}
240
- */
241
- async wake({ prompt, sessionId, cwd, onMessage, onChild }) {
161
+ /** One real stdio child and one authoritative turn per wake. */
162
+ async wake({ prompt, sessionId, cwd = process.cwd(), onMessage, onChild }) {
242
163
  const anchor = typeof sessionId === "string" ? sessionId : "";
243
-
244
- // new-vs-resume is OWNED by this backend (Codex session model), not the
245
- // waker's Claude transcript probe: a recorded thread id means resume.
246
- const knownThreadId = anchor ? this.getThreadIdFn(anchor) : null;
247
- const isNew = !knownThreadId;
248
- let previousUsage = knownThreadId
249
- ? this.getUsageSnapshotFn(anchor, knownThreadId)
250
- : null;
251
- // Existing threads created before this baseline store was introduced cannot
252
- // yield a trustworthy first delta. Seed once and omit that turn's usage
253
- // instead of publishing the entire historical cumulative total.
254
- let needsUsageSeed = Boolean(knownThreadId && !previousUsage);
255
-
256
- const codexPath = this.codexPath ?? this.resolveCodexPathFn({ env: this.env, platform: this.platform });
257
- if (!codexPath) {
258
- // No crash — surface visibly and resolve with a failure result.
259
- this.logger.error("[Chorus] cannot locate the `codex` executable on PATH; skipping wake");
260
- return { sessionId: anchor, backendSessionId: knownThreadId, exitCode: null, isNew };
261
- }
262
-
263
- if (!this.mcpConfigChecked) {
264
- this.mcpConfigChecked = true;
265
- if (!this.hasChorusMcpServerFn({ env: this.env, platform: this.platform })) {
266
- this.logger.warn(
267
- "[Chorus] Codex config has no [mcp_servers.chorus] entry; wake will continue without Chorus MCP tools",
268
- );
164
+ let threadId = null;
165
+ let isNew = true;
166
+ let child, client, adapter, unsubscribe, unregister, onProcessError;
167
+ let cancelled = false;
168
+ let stopWork;
169
+ let stopDeadline;
170
+ let rawSettled;
171
+ let rawDone = false;
172
+ let rawCode = null;
173
+ let wakeFault = null;
174
+ const fault = (code) => new CodexAppServerError(code, `Codex App Server: ${code}`);
175
+ // Diagnostic text is fixed, never provider errors, callbacks, paths or values.
176
+ const log = (level, text) => { try { this.logger[level]?.(text); } catch {} };
177
+ const result = (exitCode) => ({ sessionId: anchor, backendSessionId: threadId, exitCode, isNew });
178
+ const ensureRunning = () => {
179
+ if (cancelled) throw fault("CANCELLED");
180
+ if (client?.closed) throw client.error;
181
+ };
182
+ try {
183
+ try { threadId = anchor ? this.getThreadIdFn(anchor) : null; }
184
+ catch {
185
+ threadId = null;
186
+ log("warn", "[Chorus] Codex session mapping could not be read; starting a fresh thread with Chorus context.");
187
+ }
188
+ isNew = !threadId;
189
+ const previousThreadId = threadId;
190
+ const previousUsage = threadId ? this.getUsageSnapshotFn(anchor, threadId) : null;
191
+ let activeSetup = null;
192
+ const captureThread = (id) => {
193
+ activeSetup.observedId = id;
194
+ isNew = activeSetup.method === "thread/start";
195
+ // Latch before best-effort IO so duplicate notifications/responses never
196
+ // retry a failed write or lose the in-memory identity on interruption.
197
+ if (threadId === id) return;
198
+ threadId = id;
199
+ if (anchor) {
200
+ try { this.setThreadIdFn(anchor, id); }
201
+ catch {
202
+ log("warn", "[Chorus] Codex session mapping could not be saved; continuing this thread, but future wake continuity may be reduced.");
203
+ }
204
+ }
205
+ };
206
+ const establishThread = async (method, params) => {
207
+ activeSetup = { method, expectedId: params.threadId, observedId: null };
208
+ try {
209
+ const established = await client.request(method, params);
210
+ const id = established?.thread?.id;
211
+ if (typeof id !== "string" || !id.trim()) throw fault("INVALID_THREAD_ID");
212
+ if (activeSetup.expectedId && id !== activeSetup.expectedId) throw fault("MISMATCHED_THREAD_ID");
213
+ if (activeSetup.observedId && activeSetup.observedId !== id) throw fault("MISMATCHED_THREAD_ID");
214
+ // Keep a response already received even if cancellation won this await.
215
+ captureThread(id);
216
+ } finally { activeSetup = null; }
217
+ };
218
+ const codexPath = this.codexPath ?? this.resolveCodexPathFn({ env: this.env, platform: this.platform });
219
+ if (!codexPath) throw fault("EXECUTABLE_MISSING");
220
+ if (!this.mcpConfigChecked) {
221
+ this.mcpConfigChecked = true;
222
+ if (!this.hasChorusMcpServerFn({ env: this.env, platform: this.platform }))
223
+ log("warn", "[Chorus] Codex config has no [mcp_servers.chorus] entry; wake will continue without Chorus MCP tools");
224
+ }
225
+ try { assertConfiguredShimArgs(codexPath, this.cliConfig.args, this.platform); }
226
+ catch {
227
+ log("error", "[Chorus] Codex Windows shim cannot safely carry configured arguments; configure a native executable.");
228
+ throw fault("UNSAFE_WINDOWS_SHIM_ARGS");
229
+ }
230
+ let args;
231
+ try { args = buildCodexArgs({ args: this.cliConfig.args }); }
232
+ catch { throw fault("UNSUPPORTED_DAEMON_ARGS"); }
233
+ const { command, argv } = resolveSpawnCommand(codexPath, args, this.platform, this.env);
234
+ const childEnv = { ...this.env, CHORUS_DAEMON_HEADLESS: "1" };
235
+ if (this.creds) {
236
+ if (this.creds.url) childEnv.CHORUS_URL = this.creds.url;
237
+ if (this.creds.apiKey) childEnv.CHORUS_API_KEY = this.creds.apiKey;
238
+ if (this.creds.agentUuid || this.creds.agentName)
239
+ childEnv.CHORUS_AGENT_PROFILE = this.creds.agentUuid || this.creds.agentName;
269
240
  }
270
- }
271
-
272
- assertConfiguredShimArgs(codexPath, this.cliConfig.args, this.platform);
273
- const args = [...buildCodexArgs({ isNew, threadId: knownThreadId, permissionMode: this.permissionMode }), ...this.cliConfig.args,
274
- ...(this.cliConfig.args.length ? ["-"] : [])];
275
- const { command, argv } = resolveSpawnCommand(codexPath, args, this.platform, this.env);
276
-
277
- // POSIX: detached process group so the interrupt path can group-kill the tree
278
- // (codex exec forks child shells for tools). Windows uses taskkill /T. stdio
279
- // stays piped — prompt over stdin + NDJSON stdout parse are unaffected.
280
- const detached = this.platform !== "win32";
281
-
282
- // Export the daemon's resolved connection pair for both Codex MCP auth and
283
- // SessionStart hooks. Explicitly overwrite inherited values so the hook and
284
- // daemon cannot disagree about which Chorus instance this wake belongs to.
285
- const childEnv = { ...this.env, CHORUS_DAEMON_HEADLESS: "1" };
286
- if (this.creds) {
287
- if (this.creds.url) childEnv.CHORUS_URL = this.creds.url;
288
- if (this.creds.apiKey) childEnv.CHORUS_API_KEY = this.creds.apiKey;
289
- // Identity profile for the woken session — its hooks/skills pass this to
290
- // `chorus mcp --agent`, which resolves the key from ~/.chorus/daemon.json.
291
- if (this.creds.agentUuid || this.creds.agentName)
292
- childEnv.CHORUS_AGENT_PROFILE = this.creds.agentUuid || this.creds.agentName;
293
- }
294
-
295
- return new Promise((resolve) => {
296
- let child;
297
241
  try {
298
242
  child = this.spawnImpl(command, argv, {
299
- cwd: cwd ?? process.cwd(),
300
- stdio: ["pipe", "pipe", "pipe"],
301
- env: childEnv,
302
- shell: false,
303
- detached,
304
- windowsHide: true,
243
+ cwd, stdio: ["pipe", "pipe", "pipe"], env: childEnv,
244
+ shell: false, detached: this.platform !== "win32", windowsHide: true,
305
245
  });
306
246
  } catch (error) {
307
- this.logger.error(`[Chorus] failed to spawn codex: ${safeSpawnError(error)}`);
308
- resolve({ sessionId: anchor, backendSessionId: knownThreadId, exitCode: null, isNew });
309
- return;
247
+ log("error", `[Chorus] Codex startup: ${safeSpawnError(error)}`);
248
+ throw fault("SPAWN_FAILED");
310
249
  }
311
-
312
- // Hand the live child to the caller (interrupt registry) before resolving.
313
- // Never let a throwing callback escape into the spawn path.
314
- if (onChild) {
315
- try {
316
- onChild(child);
317
- } catch (err) {
318
- this.logger.warn(`[Chorus] onChild handler threw: ${err}`);
250
+ onProcessError = (error) => log("error", `[Chorus] Codex process: ${safeSpawnError(error)}`);
251
+ child.on("error", onProcessError);
252
+ rawSettled = awaitChildSettled(child, { logger: this.logger, label: "codex", stdioGraceMs: this.stdioGraceMs })
253
+ .then((code) => { rawDone = true; rawCode = code; return code; });
254
+ client = new CodexAppServerClient(child, {
255
+ limits: this.rpcLimits,
256
+ // CLOSED is emitted only by our explicit close(), including normal
257
+ // completion. Keep real transport faults visible at warning severity.
258
+ onDiagnostic: (text) => log(text === "Codex App Server: CLOSED" ? "info" : "warn", `[Chorus] ${text}`),
259
+ });
260
+ // Subscribe before setup, but don't feed setup/history snapshots to T3.
261
+ unsubscribe = client.subscribe((message) => {
262
+ if (activeSetup && !cancelled && message.method === "thread/started" && !Object.hasOwn(message, "id")) {
263
+ const id = message.params?.thread?.id;
264
+ // This process has only one setup request at a time. A fresh start's
265
+ // first ID is authoritative; resume must match its requested ID, and
266
+ // fallback must not accept a late notification for the old thread.
267
+ if (typeof id === "string" && id.trim()
268
+ && (!activeSetup.expectedId || id === activeSetup.expectedId)
269
+ && (activeSetup.method !== "thread/start" || id !== previousThreadId)
270
+ && (!activeSetup.observedId || id === activeSetup.observedId)) captureThread(id);
319
271
  }
320
- }
321
-
322
- let stdoutBuf = "";
323
- let observedThreadId = knownThreadId || null;
324
- let threadIdPersisted = false;
325
-
326
- child.stdout?.setEncoding?.("utf8");
327
- child.stdout?.on("data", (chunk) => {
328
- stdoutBuf = parseNdjsonChunk(
329
- stdoutBuf,
330
- String(chunk),
331
- (obj) => {
332
- const tid = extractThreadId(obj);
333
- if (tid) {
334
- observedThreadId = tid;
335
- if (isNew && anchor && !threadIdPersisted) {
336
- threadIdPersisted = true;
337
- this.setThreadIdFn(anchor, tid);
338
- }
339
- }
340
- let delivered = obj;
341
- if (obj?.type === "turn.completed" && obj.usage) {
342
- delivered = needsUsageSeed
343
- ? { ...obj, usage: null }
344
- : normalizeCodexUsageEvent(obj, previousUsage);
345
- if (anchor && observedThreadId) {
346
- this.setUsageSnapshotFn(anchor, observedThreadId, obj.usage);
347
- }
348
- previousUsage = obj.usage;
349
- needsUsageSeed = false;
350
- }
351
- if (onMessage) {
272
+ adapter?.accept(message);
273
+ });
274
+ unregister = registerProcessStopHook(child, ({ deadline, protocolDeadline = deadline, reason, beforeClose }) => {
275
+ stopDeadline = Math.min(stopDeadline ?? Infinity, deadline);
276
+ if (reason !== "cleanup") cancelled = true;
277
+ if (reason === "cleanup") {
278
+ return (async () => { try { await beforeClose?.(); } finally { client.close(); } })();
279
+ }
280
+ if (stopWork) return stopWork;
281
+ stopWork = (async () => {
282
+ try {
283
+ const turnId = adapter?.turnId ?? adapter?.observedTurnId;
284
+ if (turnId && !adapter.outcome && !client.closed) {
285
+ await client.request("turn/interrupt", { threadId, turnId }, {
286
+ timeoutMs: Math.max(1, protocolDeadline - Date.now()),
287
+ });
288
+ let timer;
352
289
  try {
353
- onMessage(delivered);
354
- } catch (err) {
355
- this.logger.warn(`[Chorus] onMessage handler threw: ${err}`);
356
- }
290
+ await Promise.race([
291
+ adapter.completion, client.failure,
292
+ new Promise((resolve) => { timer = setTimeout(resolve, Math.max(0, protocolDeadline - Date.now())); }),
293
+ ]);
294
+ } finally { clearTimeout(timer); }
357
295
  }
358
- },
359
- (msg) => this.logger.warn(`[Chorus] ${msg}`)
360
- );
296
+ } finally {
297
+ try { await beforeClose?.(); } finally { client.close(); }
298
+ }
299
+ })();
300
+ return stopWork;
361
301
  });
362
-
363
- child.stderr?.setEncoding?.("utf8");
364
- child.stderr?.on("data", (chunk) => {
365
- const text = String(chunk).trim();
366
- if (text) this.logger.warn(`[Chorus] codex stderr: ${text}`);
302
+ try { onChild?.(child); } catch { log("warn", "[Chorus] Codex onChild callback failed"); }
303
+ ensureRunning();
304
+ await client.request("initialize", {
305
+ clientInfo: { name: "chorus", version: CLIENT_VERSION }, capabilities: { experimentalApi: false },
367
306
  });
368
-
369
- child.on("error", (error) => {
370
- this.logger.error(`[Chorus] codex process error: ${safeSpawnError(error)}`);
371
- resolve({ sessionId: anchor, backendSessionId: observedThreadId, exitCode: null, isNew });
372
- });
373
-
374
- // Settle on process exit, not only on stdio close: a detached descendant can
375
- // inherit the pipes and keep `close` from ever firing (see cli/child-exit.mjs).
376
- awaitChildSettled(child, { logger: this.logger, label: "codex" }).then((code) => {
377
- if (code !== 0) {
378
- this.logger.warn(`[Chorus] codex exited with code ${code}`);
307
+ ensureRunning();
308
+ await client.notify("initialized");
309
+ ensureRunning();
310
+ const fullAccess = this.permissionMode === "yolo";
311
+ const setup = { cwd, approvalPolicy: "never", sandbox: fullAccess ? "danger-full-access" : "read-only" };
312
+ let fallback = false;
313
+ if (threadId) {
314
+ try {
315
+ await establishThread("thread/resume", { ...setup, threadId, excludeTurns: true });
316
+ } catch (error) {
317
+ ensureRunning();
318
+ if (!isHistoryUnavailableError(error, threadId)) throw error;
319
+ fallback = true;
320
+ await establishThread("thread/start", setup);
379
321
  }
380
- resolve({ sessionId: anchor, backendSessionId: observedThreadId, exitCode: code, isNew });
322
+ } else await establishThread("thread/start", setup);
323
+ ensureRunning();
324
+ adapter = new CodexAppServerEvents({
325
+ threadId, isNew, previousUsage: threadId === previousThreadId ? previousUsage : null,
326
+ maxBufferedBytes: this.maxBufferedBytes,
327
+ onMessage: (message) => {
328
+ try { onMessage?.(message); } catch { log("warn", "[Chorus] Codex onMessage callback failed"); }
329
+ },
330
+ onUsageSnapshot: (snapshot) => {
331
+ if (anchor) this.setUsageSnapshotFn(anchor, threadId, snapshot);
332
+ },
381
333
  });
382
-
383
- // Guard against an ASYNC stdin error (EPIPE) so it never becomes an
384
- // uncaughtException that kills the daemon.
385
- child.stdin?.on?.("error", (err) => {
386
- this.logger.warn(`[Chorus] codex stdin error (ignored): ${err}`);
334
+ if (fallback) {
335
+ const notice = "Previous Codex history could not be restored; continuing in a new thread with Chorus context.";
336
+ // Native IDs are UUIDs. Do not echo arbitrary provider-controlled strings.
337
+ const displayId = (id) => /^[0-9a-f]{8}(?:-[0-9a-f]{4}){3}-[0-9a-f]{12}$/i.test(id)
338
+ ? id : "(unavailable)";
339
+ log("warn", `[Chorus] ${notice} Old thread: ${displayId(previousThreadId)}; new thread: ${displayId(threadId)}.`);
340
+ adapter.notice(notice);
341
+ }
342
+ ensureRunning();
343
+ const started = await client.request("turn/start", {
344
+ threadId, cwd, approvalPolicy: "never",
345
+ sandboxPolicy: fullAccess ? { type: "dangerFullAccess" } : { type: "readOnly", networkAccess: false },
346
+ input: [{ type: "text", text: prompt, text_elements: [] }],
387
347
  });
388
-
389
- // Feed the prompt over stdin, then close it so the model runs.
390
- try {
391
- child.stdin?.write(prompt);
392
- child.stdin?.end();
393
- } catch (err) {
394
- this.logger.warn(`[Chorus] failed writing prompt to codex stdin: ${err}`);
348
+ adapter.confirmTurn(started?.turn?.id);
349
+ await Promise.race([
350
+ adapter.completion,
351
+ client.failure.then((error) => {
352
+ if (adapter.outcome && ["CLOSED", "EOF"].includes(error.code)) return;
353
+ throw error;
354
+ }),
355
+ rawSettled.then(() => { if (!adapter.outcome) throw fault("MISSING_TERMINAL"); }),
356
+ ]);
357
+ } catch (error) {
358
+ wakeFault = error;
359
+ const code = error instanceof CodexAppServerError ? error.code : "SETUP_OR_STORE_ERROR";
360
+ log("error", `[Chorus] Codex App Server wake failed (${code}); check Codex 0.157.1+ installation, login, model/config and local session storage. Unsupported args must use model or permitted -c settings.`);
361
+ } finally {
362
+ try { adapter?.finish(); } catch {
363
+ wakeFault ??= fault("USAGE_STORE_ERROR");
364
+ log("error", "[Chorus] Codex usage persistence failed; check local session storage.");
395
365
  }
396
- });
366
+ if (child) {
367
+ // Normal close never marks a user interrupt. Concurrent authorized stops
368
+ // still invoke the registered hook and latch cancellation synchronously.
369
+ const deadline = stopDeadline ?? Date.now() + this.cleanupTimeoutMs;
370
+ try {
371
+ const cleanup = await this.killProcessTreeFn(child, {
372
+ ...this.killOptions, platform: this.platform, logger: this.logger,
373
+ sigintTimeoutMs: Math.max(0, deadline - Date.now()), reason: "cleanup",
374
+ });
375
+ if (cleanup?.cleanupFailed) throw fault("CLEANUP_ERROR");
376
+ if (!rawDone && rawSettled) {
377
+ let timer;
378
+ try {
379
+ await Promise.race([rawSettled, new Promise((resolve) => {
380
+ timer = setTimeout(resolve, Math.max(0, deadline - Date.now()));
381
+ })]);
382
+ } finally { clearTimeout(timer); }
383
+ }
384
+ } catch {
385
+ wakeFault ??= fault("CLEANUP_ERROR");
386
+ log("error", "[Chorus] Codex process-tree cleanup failed; check process termination permissions.");
387
+ }
388
+ client?.close();
389
+ // Release descendant-held pipes after the bounded shared drain/cleanup.
390
+ for (const stream of [child.stdin, child.stdout, child.stderr]) stream?.destroy?.();
391
+ }
392
+ unsubscribe?.();
393
+ unregister?.();
394
+ if (onProcessError) child?.removeListener("error", onProcessError);
395
+ }
396
+ // CLOSED/EOF is expected only after a confirmed valid terminal. All other
397
+ // protocol faults stay failures even if completion arrived in the same chunk.
398
+ const transportFault = client?.error && !["CLOSED", "EOF"].includes(client.error.code);
399
+ if (cancelled) return result(130);
400
+ if (wakeFault || transportFault || !adapter?.outcome) return result(null);
401
+ if (adapter.outcome.status !== "completed") return result(1);
402
+ return result(rawDone && rawCode === 0 ? 0 : null);
397
403
  }
398
404
  }
@@ -64,8 +64,8 @@ function readJsonSafe(path) {
64
64
  * @param {{ home?: string, readJson?: (p: string) => any }} [deps]
65
65
  * @returns {{ marketplaceRegistered: boolean, pluginInstalled: boolean, version?: string }}
66
66
  */
67
- export function readClaudeInstallState({ home = homedir(), readJson = readJsonSafe } = {}) {
68
- const pluginsDir = join(home, ".claude", "plugins");
67
+ export function readClaudeInstallState({ env = process.env, home = env.HOME || env.USERPROFILE || homedir(), readJson = readJsonSafe } = {}) {
68
+ const pluginsDir = join(env.CLAUDE_CONFIG_DIR || join(home, ".claude"), "plugins");
69
69
  const installed = readJson(join(pluginsDir, "installed_plugins.json"));
70
70
  const markets = readJson(join(pluginsDir, "known_marketplaces.json"));
71
71
 
@@ -136,6 +136,7 @@ export function mergeChorusServer(existingText, serverObj) {
136
136
  * backup?: (path: string) => (string|null),
137
137
  * platform?: NodeJS.Platform,
138
138
  * log?: (m: string) => void,
139
+ * preserveExistingChorus?: boolean,
139
140
  * }} opts
140
141
  * @returns {Promise<{ skills: number, reviewerAgents: number, hookScripts: number, kiroDir: string, chorusBinAbs: string }>}
141
142
  */
@@ -146,6 +147,7 @@ export async function installFileTemplate({
146
147
  backup,
147
148
  platform = process.platform,
148
149
  log,
150
+ preserveExistingChorus = false,
149
151
  } = {}) {
150
152
  const assetBase = normalizeAssetBase(chorusUrl); // throws on bad/empty URL
151
153
  const doFetch = fetchImpl ?? globalThis.fetch;
@@ -216,6 +218,14 @@ export async function installFileTemplate({
216
218
  }
217
219
  serverObj.url = `${assetBase}/api/mcp`;
218
220
 
221
+ // Validate the destination before dropping any assets. Upgrade preserves an
222
+ // existing Chorus connection too; changing credentials is an agents-add action.
223
+ const mcpJsonPath = join(kiroDir, "settings", "mcp.json");
224
+ const existed = existsSync(mcpJsonPath);
225
+ const existingText = existed ? readFileSync(mcpJsonPath, "utf8") : "";
226
+ const existingServer = existingText.trim() ? JSON.parse(existingText)?.mcpServers?.chorus : undefined;
227
+ const merged = mergeChorusServer(existingText, preserveExistingChorus && existingServer ? existingServer : serverObj);
228
+
219
229
  // ---- phase 2: write to disk (every fetch already verified) ----
220
230
  for (const [dest, { text, exec }] of files) {
221
231
  mkdirSync(dirname(dest), { recursive: true });
@@ -230,12 +240,9 @@ export async function installFileTemplate({
230
240
  }
231
241
 
232
242
  // ---- merge the `chorus` MCP server into settings/mcp.json (back up first) ----
233
- const mcpJsonPath = join(kiroDir, "settings", "mcp.json");
234
243
  mkdirSync(dirname(mcpJsonPath), { recursive: true });
235
- const existed = existsSync(mcpJsonPath);
236
244
  if (existed && typeof backup === "function") backup(mcpJsonPath);
237
- const existingText = existed ? readFileSync(mcpJsonPath, "utf8") : "";
238
- writeFileSync(mcpJsonPath, mergeChorusServer(existingText, serverObj));
245
+ writeFileSync(mcpJsonPath, merged);
239
246
 
240
247
  log?.(`[chorus agents add] kiro: wrote .kiro/ template into ${kiroDir}`);
241
248
  return {
@@ -135,7 +135,7 @@ export function installCodex(ctx) {
135
135
  // (agents[0]) — that covers the interactive path where the operator typed the URL at a
136
136
  // prompt (credential-seed, order 10, already wrote it there before this step runs).
137
137
  let chorusUrl = nonEmpty(ctx.flags?.url) ?? nonEmpty(env.CHORUS_URL);
138
- if (!chorusUrl) {
138
+ if (!chorusUrl && !ctx.flags?.pluginOnly) {
139
139
  try {
140
140
  chorusUrl = nonEmpty(resolveCreds(ctx.flags ?? {}, { env }).url);
141
141
  } catch {
@@ -147,6 +147,7 @@ export function installCodex(ctx) {
147
147
  // form. Idempotent; runs on both fresh install and re-run. Never writes a secret. A missing
148
148
  // URL is a non-fatal skip (the plugin surface is still installed). Returns a note suffix.
149
149
  const ensureMcp = () => {
150
+ if (ctx.flags?.pluginOnly) return ""; // Upgrade preserves existing connection settings.
150
151
  if (!chorusUrl) {
151
152
  return " (skipped [mcp_servers.chorus]: no Chorus URL — pass --url or set CHORUS_URL)";
152
153
  }
@@ -648,6 +649,7 @@ export async function installKiro(ctx) {
648
649
  backup: ctx.backup,
649
650
  platform: ctx.platform,
650
651
  log: ctx.io?.log,
652
+ preserveExistingChorus: ctx.flags?.pluginOnly === true,
651
653
  });
652
654
  return out(
653
655
  "kiro",