@chorus-aidlc/chorus 0.17.3 → 0.18.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (457) hide show
  1. package/.next/standalone/.next/BUILD_ID +1 -1
  2. package/.next/standalone/.next/app-build-manifest.json +345 -341
  3. package/.next/standalone/.next/app-path-routes-manifest.json +35 -35
  4. package/.next/standalone/.next/build-manifest.json +5 -5
  5. package/.next/standalone/.next/prerender-manifest.json +27 -27
  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.js.nft.json +1 -1
  18. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/documents/[documentUuid]/page_client-reference-manifest.js +1 -1
  19. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/documents/page.js +2 -2
  20. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/documents/page_client-reference-manifest.js +1 -1
  21. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/graph/page.js +2 -2
  22. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/graph/page.js.nft.json +1 -1
  23. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/graph/page_client-reference-manifest.js +1 -1
  24. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/[proposalUuid]/page.js +2 -2
  25. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/[proposalUuid]/page.js.nft.json +1 -1
  26. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/[proposalUuid]/page_client-reference-manifest.js +1 -1
  27. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/new/page.js +2 -2
  28. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/new/page.js.nft.json +1 -1
  29. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/new/page_client-reference-manifest.js +1 -1
  30. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/page.js +2 -2
  31. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/page_client-reference-manifest.js +1 -1
  32. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/tasks/[taskUuid]/page.js +1 -1
  33. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/tasks/[taskUuid]/page.js.nft.json +1 -1
  34. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/tasks/[taskUuid]/page_client-reference-manifest.js +1 -1
  35. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/tasks/page.js +1 -1
  36. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/tasks/page.js.nft.json +1 -1
  37. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/tasks/page_client-reference-manifest.js +1 -1
  38. package/.next/standalone/.next/server/app/(dashboard)/projects/page.js +1 -1
  39. package/.next/standalone/.next/server/app/(dashboard)/projects/page.js.nft.json +1 -1
  40. package/.next/standalone/.next/server/app/(dashboard)/projects/page_client-reference-manifest.js +1 -1
  41. package/.next/standalone/.next/server/app/(dashboard)/settings/page.js +2 -2
  42. package/.next/standalone/.next/server/app/(dashboard)/settings/page.js.nft.json +1 -1
  43. package/.next/standalone/.next/server/app/(dashboard)/settings/page_client-reference-manifest.js +1 -1
  44. package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  45. package/.next/standalone/.next/server/app/_not-found.html +2 -2
  46. package/.next/standalone/.next/server/app/_not-found.rsc +2 -2
  47. package/.next/standalone/.next/server/app/admin/companies/[uuid]/page_client-reference-manifest.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 +2 -2
  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.js.nft.json +1 -1
  62. package/.next/standalone/.next/server/app/api/agent-connections/route_client-reference-manifest.js +1 -1
  63. package/.next/standalone/.next/server/app/api/agents/[uuid]/route_client-reference-manifest.js +1 -1
  64. package/.next/standalone/.next/server/app/api/agents/[uuid]/sessions/route.js +1 -1
  65. package/.next/standalone/.next/server/app/api/agents/[uuid]/sessions/route.js.nft.json +1 -1
  66. package/.next/standalone/.next/server/app/api/agents/[uuid]/sessions/route_client-reference-manifest.js +1 -1
  67. package/.next/standalone/.next/server/app/api/agents/route_client-reference-manifest.js +1 -1
  68. package/.next/standalone/.next/server/app/api/api-keys/[uuid]/route_client-reference-manifest.js +1 -1
  69. package/.next/standalone/.next/server/app/api/api-keys/route_client-reference-manifest.js +1 -1
  70. package/.next/standalone/.next/server/app/api/auth/callback/route_client-reference-manifest.js +1 -1
  71. package/.next/standalone/.next/server/app/api/auth/check-default/route_client-reference-manifest.js +1 -1
  72. package/.next/standalone/.next/server/app/api/auth/company-oidc/route_client-reference-manifest.js +1 -1
  73. package/.next/standalone/.next/server/app/api/auth/default-login/route_client-reference-manifest.js +1 -1
  74. package/.next/standalone/.next/server/app/api/auth/identify/route_client-reference-manifest.js +1 -1
  75. package/.next/standalone/.next/server/app/api/auth/logout/route_client-reference-manifest.js +1 -1
  76. package/.next/standalone/.next/server/app/api/auth/me/route_client-reference-manifest.js +1 -1
  77. package/.next/standalone/.next/server/app/api/auth/sync-token/route_client-reference-manifest.js +1 -1
  78. package/.next/standalone/.next/server/app/api/comments/route.js +1 -1
  79. package/.next/standalone/.next/server/app/api/comments/route.js.nft.json +1 -1
  80. package/.next/standalone/.next/server/app/api/comments/route_client-reference-manifest.js +1 -1
  81. package/.next/standalone/.next/server/app/api/daemon/connection-heartbeat/route.js.nft.json +1 -1
  82. package/.next/standalone/.next/server/app/api/daemon/connection-heartbeat/route_client-reference-manifest.js +1 -1
  83. package/.next/standalone/.next/server/app/api/daemon/control/route.js +1 -1
  84. package/.next/standalone/.next/server/app/api/daemon/control/route.js.nft.json +1 -1
  85. package/.next/standalone/.next/server/app/api/daemon/control/route_client-reference-manifest.js +1 -1
  86. package/.next/standalone/.next/server/app/api/daemon/directory-request/report/route.js.nft.json +1 -1
  87. package/.next/standalone/.next/server/app/api/daemon/directory-request/report/route_client-reference-manifest.js +1 -1
  88. package/.next/standalone/.next/server/app/api/daemon/execution-state/route.js.nft.json +1 -1
  89. package/.next/standalone/.next/server/app/api/daemon/execution-state/route_client-reference-manifest.js +1 -1
  90. package/.next/standalone/.next/server/app/api/daemon/executions/route.js.nft.json +1 -1
  91. package/.next/standalone/.next/server/app/api/daemon/executions/route_client-reference-manifest.js +1 -1
  92. package/.next/standalone/.next/server/app/api/daemon/pending-turns/route.js +1 -1
  93. package/.next/standalone/.next/server/app/api/daemon/pending-turns/route.js.nft.json +1 -1
  94. package/.next/standalone/.next/server/app/api/daemon/pending-turns/route_client-reference-manifest.js +1 -1
  95. package/.next/standalone/.next/server/app/api/daemon/report-interrupt/route.js.nft.json +1 -1
  96. package/.next/standalone/.next/server/app/api/daemon/report-interrupt/route_client-reference-manifest.js +1 -1
  97. package/.next/standalone/.next/server/app/api/daemon/resume/route.js +1 -1
  98. package/.next/standalone/.next/server/app/api/daemon/resume/route.js.nft.json +1 -1
  99. package/.next/standalone/.next/server/app/api/daemon/resume/route_client-reference-manifest.js +1 -1
  100. package/.next/standalone/.next/server/app/api/daemon/transcript/route.js +1 -1
  101. package/.next/standalone/.next/server/app/api/daemon/transcript/route.js.nft.json +1 -1
  102. package/.next/standalone/.next/server/app/api/daemon/transcript/route_client-reference-manifest.js +1 -1
  103. package/.next/standalone/.next/server/app/api/daemon/turn-advance/route.js +1 -1
  104. package/.next/standalone/.next/server/app/api/daemon/turn-advance/route.js.nft.json +1 -1
  105. package/.next/standalone/.next/server/app/api/daemon/turn-advance/route_client-reference-manifest.js +1 -1
  106. package/.next/standalone/.next/server/app/api/daemon-directory-requests/[uuid]/route.js.nft.json +1 -1
  107. package/.next/standalone/.next/server/app/api/daemon-directory-requests/[uuid]/route_client-reference-manifest.js +1 -1
  108. package/.next/standalone/.next/server/app/api/daemon-directory-requests/route.js.nft.json +1 -1
  109. package/.next/standalone/.next/server/app/api/daemon-directory-requests/route_client-reference-manifest.js +1 -1
  110. package/.next/standalone/.next/server/app/api/daemon-sessions/[sessionUuid]/instruction/route.js +1 -1
  111. package/.next/standalone/.next/server/app/api/daemon-sessions/[sessionUuid]/instruction/route.js.nft.json +1 -1
  112. package/.next/standalone/.next/server/app/api/daemon-sessions/[sessionUuid]/instruction/route_client-reference-manifest.js +1 -1
  113. package/.next/standalone/.next/server/app/api/daemon-sessions/[sessionUuid]/repoint/route.js +1 -1
  114. package/.next/standalone/.next/server/app/api/daemon-sessions/[sessionUuid]/repoint/route.js.nft.json +1 -1
  115. package/.next/standalone/.next/server/app/api/daemon-sessions/[sessionUuid]/repoint/route_client-reference-manifest.js +1 -1
  116. package/.next/standalone/.next/server/app/api/daemon-sessions/[sessionUuid]/route.js +1 -1
  117. package/.next/standalone/.next/server/app/api/daemon-sessions/[sessionUuid]/route.js.nft.json +1 -1
  118. package/.next/standalone/.next/server/app/api/daemon-sessions/[sessionUuid]/route_client-reference-manifest.js +1 -1
  119. package/.next/standalone/.next/server/app/api/daemon-sessions/ad-hoc/route.js +1 -1
  120. package/.next/standalone/.next/server/app/api/daemon-sessions/ad-hoc/route.js.nft.json +1 -1
  121. package/.next/standalone/.next/server/app/api/daemon-sessions/ad-hoc/route_client-reference-manifest.js +1 -1
  122. package/.next/standalone/.next/server/app/api/daemon-sessions/route.js +1 -1
  123. package/.next/standalone/.next/server/app/api/daemon-sessions/route.js.nft.json +1 -1
  124. package/.next/standalone/.next/server/app/api/daemon-sessions/route_client-reference-manifest.js +1 -1
  125. package/.next/standalone/.next/server/app/api/documents/[uuid]/route_client-reference-manifest.js +1 -1
  126. package/.next/standalone/.next/server/app/api/entities/[type]/[uuid]/root-idea/route.js +1 -1
  127. package/.next/standalone/.next/server/app/api/entities/[type]/[uuid]/root-idea/route.js.nft.json +1 -1
  128. package/.next/standalone/.next/server/app/api/entities/[type]/[uuid]/root-idea/route_client-reference-manifest.js +1 -1
  129. package/.next/standalone/.next/server/app/api/events/notifications/route.js +1 -1
  130. package/.next/standalone/.next/server/app/api/events/notifications/route.js.nft.json +1 -1
  131. package/.next/standalone/.next/server/app/api/events/notifications/route_client-reference-manifest.js +1 -1
  132. package/.next/standalone/.next/server/app/api/events/route.js +1 -1
  133. package/.next/standalone/.next/server/app/api/events/route.js.nft.json +1 -1
  134. package/.next/standalone/.next/server/app/api/events/route_client-reference-manifest.js +1 -1
  135. package/.next/standalone/.next/server/app/api/health/route_client-reference-manifest.js +1 -1
  136. package/.next/standalone/.next/server/app/api/ideas/[uuid]/claim/route.js +1 -1
  137. package/.next/standalone/.next/server/app/api/ideas/[uuid]/claim/route.js.nft.json +1 -1
  138. package/.next/standalone/.next/server/app/api/ideas/[uuid]/claim/route_client-reference-manifest.js +1 -1
  139. package/.next/standalone/.next/server/app/api/ideas/[uuid]/move/preview/route.js +1 -1
  140. package/.next/standalone/.next/server/app/api/ideas/[uuid]/move/preview/route.js.nft.json +1 -1
  141. package/.next/standalone/.next/server/app/api/ideas/[uuid]/move/preview/route_client-reference-manifest.js +1 -1
  142. package/.next/standalone/.next/server/app/api/ideas/[uuid]/move/route.js +1 -1
  143. package/.next/standalone/.next/server/app/api/ideas/[uuid]/move/route.js.nft.json +1 -1
  144. package/.next/standalone/.next/server/app/api/ideas/[uuid]/move/route_client-reference-manifest.js +1 -1
  145. package/.next/standalone/.next/server/app/api/ideas/[uuid]/parent/route.js +1 -1
  146. package/.next/standalone/.next/server/app/api/ideas/[uuid]/parent/route.js.nft.json +1 -1
  147. package/.next/standalone/.next/server/app/api/ideas/[uuid]/parent/route_client-reference-manifest.js +1 -1
  148. package/.next/standalone/.next/server/app/api/ideas/[uuid]/release/route.js +1 -1
  149. package/.next/standalone/.next/server/app/api/ideas/[uuid]/release/route.js.nft.json +1 -1
  150. package/.next/standalone/.next/server/app/api/ideas/[uuid]/release/route_client-reference-manifest.js +1 -1
  151. package/.next/standalone/.next/server/app/api/ideas/[uuid]/route.js +1 -1
  152. package/.next/standalone/.next/server/app/api/ideas/[uuid]/route.js.nft.json +1 -1
  153. package/.next/standalone/.next/server/app/api/ideas/[uuid]/route_client-reference-manifest.js +1 -1
  154. package/.next/standalone/.next/server/app/api/ideas/[uuid]/wake-preview/route.js.nft.json +1 -1
  155. package/.next/standalone/.next/server/app/api/ideas/[uuid]/wake-preview/route_client-reference-manifest.js +1 -1
  156. package/.next/standalone/.next/server/app/api/ideas/conversational/route.js +1 -1
  157. package/.next/standalone/.next/server/app/api/ideas/conversational/route.js.nft.json +1 -1
  158. package/.next/standalone/.next/server/app/api/ideas/conversational/route_client-reference-manifest.js +1 -1
  159. package/.next/standalone/.next/server/app/api/mcp/route.js +1 -1
  160. package/.next/standalone/.next/server/app/api/mcp/route.js.nft.json +1 -1
  161. package/.next/standalone/.next/server/app/api/mcp/route_client-reference-manifest.js +1 -1
  162. package/.next/standalone/.next/server/app/api/me/assignments/route.js +1 -1
  163. package/.next/standalone/.next/server/app/api/me/assignments/route.js.nft.json +1 -1
  164. package/.next/standalone/.next/server/app/api/me/assignments/route_client-reference-manifest.js +1 -1
  165. package/.next/standalone/.next/server/app/api/mentionables/route.js +1 -1
  166. package/.next/standalone/.next/server/app/api/mentionables/route.js.nft.json +1 -1
  167. package/.next/standalone/.next/server/app/api/mentionables/route_client-reference-manifest.js +1 -1
  168. package/.next/standalone/.next/server/app/api/notifications/[uuid]/archive/route.js +1 -1
  169. package/.next/standalone/.next/server/app/api/notifications/[uuid]/archive/route.js.nft.json +1 -1
  170. package/.next/standalone/.next/server/app/api/notifications/[uuid]/archive/route_client-reference-manifest.js +1 -1
  171. package/.next/standalone/.next/server/app/api/notifications/[uuid]/read/route.js +1 -1
  172. package/.next/standalone/.next/server/app/api/notifications/[uuid]/read/route.js.nft.json +1 -1
  173. package/.next/standalone/.next/server/app/api/notifications/[uuid]/read/route_client-reference-manifest.js +1 -1
  174. package/.next/standalone/.next/server/app/api/notifications/preferences/route.js +1 -1
  175. package/.next/standalone/.next/server/app/api/notifications/preferences/route.js.nft.json +1 -1
  176. package/.next/standalone/.next/server/app/api/notifications/preferences/route_client-reference-manifest.js +1 -1
  177. package/.next/standalone/.next/server/app/api/notifications/read-all/route.js +1 -1
  178. package/.next/standalone/.next/server/app/api/notifications/read-all/route.js.nft.json +1 -1
  179. package/.next/standalone/.next/server/app/api/notifications/read-all/route_client-reference-manifest.js +1 -1
  180. package/.next/standalone/.next/server/app/api/notifications/route.js +1 -1
  181. package/.next/standalone/.next/server/app/api/notifications/route.js.nft.json +1 -1
  182. package/.next/standalone/.next/server/app/api/notifications/route_client-reference-manifest.js +1 -1
  183. package/.next/standalone/.next/server/app/api/notifications/unread-count/route.js +1 -1
  184. package/.next/standalone/.next/server/app/api/notifications/unread-count/route.js.nft.json +1 -1
  185. package/.next/standalone/.next/server/app/api/notifications/unread-count/route_client-reference-manifest.js +1 -1
  186. package/.next/standalone/.next/server/app/api/project-groups/[uuid]/dashboard/route_client-reference-manifest.js +1 -1
  187. package/.next/standalone/.next/server/app/api/project-groups/[uuid]/route_client-reference-manifest.js +1 -1
  188. package/.next/standalone/.next/server/app/api/project-groups/route_client-reference-manifest.js +1 -1
  189. package/.next/standalone/.next/server/app/api/project-visits/pin/route_client-reference-manifest.js +1 -1
  190. package/.next/standalone/.next/server/app/api/project-visits/route_client-reference-manifest.js +1 -1
  191. package/.next/standalone/.next/server/app/api/project-visits/visit/route_client-reference-manifest.js +1 -1
  192. package/.next/standalone/.next/server/app/api/projects/[uuid]/activity/route_client-reference-manifest.js +1 -1
  193. package/.next/standalone/.next/server/app/api/projects/[uuid]/agent-cwds/route.js.nft.json +1 -1
  194. package/.next/standalone/.next/server/app/api/projects/[uuid]/agent-cwds/route_client-reference-manifest.js +1 -1
  195. package/.next/standalone/.next/server/app/api/projects/[uuid]/available/route.js +1 -1
  196. package/.next/standalone/.next/server/app/api/projects/[uuid]/available/route.js.nft.json +1 -1
  197. package/.next/standalone/.next/server/app/api/projects/[uuid]/available/route_client-reference-manifest.js +1 -1
  198. package/.next/standalone/.next/server/app/api/projects/[uuid]/documents/route_client-reference-manifest.js +1 -1
  199. package/.next/standalone/.next/server/app/api/projects/[uuid]/group/route_client-reference-manifest.js +1 -1
  200. package/.next/standalone/.next/server/app/api/projects/[uuid]/ideas/route.js +1 -1
  201. package/.next/standalone/.next/server/app/api/projects/[uuid]/ideas/route.js.nft.json +1 -1
  202. package/.next/standalone/.next/server/app/api/projects/[uuid]/ideas/route_client-reference-manifest.js +1 -1
  203. package/.next/standalone/.next/server/app/api/projects/[uuid]/ideas/tracker/route.js +1 -1
  204. package/.next/standalone/.next/server/app/api/projects/[uuid]/ideas/tracker/route.js.nft.json +1 -1
  205. package/.next/standalone/.next/server/app/api/projects/[uuid]/ideas/tracker/route_client-reference-manifest.js +1 -1
  206. package/.next/standalone/.next/server/app/api/projects/[uuid]/proposals/[proposalUuid]/validate/route_client-reference-manifest.js +1 -1
  207. package/.next/standalone/.next/server/app/api/projects/[uuid]/proposals/route_client-reference-manifest.js +1 -1
  208. package/.next/standalone/.next/server/app/api/projects/[uuid]/proposals/summary/route_client-reference-manifest.js +1 -1
  209. package/.next/standalone/.next/server/app/api/projects/[uuid]/resource-graph/route.js +1 -1
  210. package/.next/standalone/.next/server/app/api/projects/[uuid]/resource-graph/route.js.nft.json +1 -1
  211. package/.next/standalone/.next/server/app/api/projects/[uuid]/resource-graph/route_client-reference-manifest.js +1 -1
  212. package/.next/standalone/.next/server/app/api/projects/[uuid]/route_client-reference-manifest.js +1 -1
  213. package/.next/standalone/.next/server/app/api/projects/[uuid]/stats/route_client-reference-manifest.js +1 -1
  214. package/.next/standalone/.next/server/app/api/projects/[uuid]/tasks/dependencies/route.js +1 -1
  215. package/.next/standalone/.next/server/app/api/projects/[uuid]/tasks/dependencies/route.js.nft.json +1 -1
  216. package/.next/standalone/.next/server/app/api/projects/[uuid]/tasks/dependencies/route_client-reference-manifest.js +1 -1
  217. package/.next/standalone/.next/server/app/api/projects/[uuid]/tasks/route.js +1 -1
  218. package/.next/standalone/.next/server/app/api/projects/[uuid]/tasks/route.js.nft.json +1 -1
  219. package/.next/standalone/.next/server/app/api/projects/[uuid]/tasks/route_client-reference-manifest.js +1 -1
  220. package/.next/standalone/.next/server/app/api/projects/agent-cwd-options/route.js.nft.json +1 -1
  221. package/.next/standalone/.next/server/app/api/projects/agent-cwd-options/route_client-reference-manifest.js +1 -1
  222. package/.next/standalone/.next/server/app/api/projects/route.js.nft.json +1 -1
  223. package/.next/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  224. package/.next/standalone/.next/server/app/api/proposals/[uuid]/approve/route_client-reference-manifest.js +1 -1
  225. package/.next/standalone/.next/server/app/api/proposals/[uuid]/close/route_client-reference-manifest.js +1 -1
  226. package/.next/standalone/.next/server/app/api/proposals/[uuid]/reject/route_client-reference-manifest.js +1 -1
  227. package/.next/standalone/.next/server/app/api/proposals/[uuid]/revoke/route_client-reference-manifest.js +1 -1
  228. package/.next/standalone/.next/server/app/api/proposals/[uuid]/route_client-reference-manifest.js +1 -1
  229. package/.next/standalone/.next/server/app/api/references/[uuid]/route_client-reference-manifest.js +1 -1
  230. package/.next/standalone/.next/server/app/api/references/route_client-reference-manifest.js +1 -1
  231. package/.next/standalone/.next/server/app/api/search/route_client-reference-manifest.js +1 -1
  232. package/.next/standalone/.next/server/app/api/session/route_client-reference-manifest.js +1 -1
  233. package/.next/standalone/.next/server/app/api/sessions/[uuid]/route.js +1 -1
  234. package/.next/standalone/.next/server/app/api/sessions/[uuid]/route.js.nft.json +1 -1
  235. package/.next/standalone/.next/server/app/api/sessions/[uuid]/route_client-reference-manifest.js +1 -1
  236. package/.next/standalone/.next/server/app/api/tasks/[uuid]/claim/route.js +1 -1
  237. package/.next/standalone/.next/server/app/api/tasks/[uuid]/claim/route.js.nft.json +1 -1
  238. package/.next/standalone/.next/server/app/api/tasks/[uuid]/claim/route_client-reference-manifest.js +1 -1
  239. package/.next/standalone/.next/server/app/api/tasks/[uuid]/dependencies/[dependsOnUuid]/route.js +1 -1
  240. package/.next/standalone/.next/server/app/api/tasks/[uuid]/dependencies/[dependsOnUuid]/route.js.nft.json +1 -1
  241. package/.next/standalone/.next/server/app/api/tasks/[uuid]/dependencies/[dependsOnUuid]/route_client-reference-manifest.js +1 -1
  242. package/.next/standalone/.next/server/app/api/tasks/[uuid]/dependencies/route.js +1 -1
  243. package/.next/standalone/.next/server/app/api/tasks/[uuid]/dependencies/route.js.nft.json +1 -1
  244. package/.next/standalone/.next/server/app/api/tasks/[uuid]/dependencies/route_client-reference-manifest.js +1 -1
  245. package/.next/standalone/.next/server/app/api/tasks/[uuid]/release/route.js +1 -1
  246. package/.next/standalone/.next/server/app/api/tasks/[uuid]/release/route.js.nft.json +1 -1
  247. package/.next/standalone/.next/server/app/api/tasks/[uuid]/release/route_client-reference-manifest.js +1 -1
  248. package/.next/standalone/.next/server/app/api/tasks/[uuid]/route.js +1 -1
  249. package/.next/standalone/.next/server/app/api/tasks/[uuid]/route.js.nft.json +1 -1
  250. package/.next/standalone/.next/server/app/api/tasks/[uuid]/route_client-reference-manifest.js +1 -1
  251. package/.next/standalone/.next/server/app/api/tasks/[uuid]/sessions/route.js +1 -1
  252. package/.next/standalone/.next/server/app/api/tasks/[uuid]/sessions/route.js.nft.json +1 -1
  253. package/.next/standalone/.next/server/app/api/tasks/[uuid]/sessions/route_client-reference-manifest.js +1 -1
  254. package/.next/standalone/.next/server/app/index.html +2 -2
  255. package/.next/standalone/.next/server/app/index.rsc +2 -2
  256. package/.next/standalone/.next/server/app/login/admin/page_client-reference-manifest.js +1 -1
  257. package/.next/standalone/.next/server/app/login/admin.html +2 -2
  258. package/.next/standalone/.next/server/app/login/admin.rsc +2 -2
  259. package/.next/standalone/.next/server/app/login/callback/page_client-reference-manifest.js +1 -1
  260. package/.next/standalone/.next/server/app/login/callback.html +2 -2
  261. package/.next/standalone/.next/server/app/login/callback.rsc +2 -2
  262. package/.next/standalone/.next/server/app/login/page_client-reference-manifest.js +1 -1
  263. package/.next/standalone/.next/server/app/login/pick-workspace/page_client-reference-manifest.js +1 -1
  264. package/.next/standalone/.next/server/app/login/pick-workspace.html +2 -2
  265. package/.next/standalone/.next/server/app/login/pick-workspace.rsc +2 -2
  266. package/.next/standalone/.next/server/app/login.html +2 -2
  267. package/.next/standalone/.next/server/app/login.rsc +2 -2
  268. package/.next/standalone/.next/server/app/onboarding/page.js +2 -2
  269. package/.next/standalone/.next/server/app/onboarding/page.js.nft.json +1 -1
  270. package/.next/standalone/.next/server/app/onboarding/page_client-reference-manifest.js +1 -1
  271. package/.next/standalone/.next/server/app/onboarding.html +2 -2
  272. package/.next/standalone/.next/server/app/onboarding.rsc +3 -3
  273. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  274. package/.next/standalone/.next/server/app/projects.html +2 -2
  275. package/.next/standalone/.next/server/app/projects.rsc +3 -3
  276. package/.next/standalone/.next/server/app/settings.html +2 -2
  277. package/.next/standalone/.next/server/app/settings.rsc +4 -4
  278. package/.next/standalone/.next/server/app-paths-manifest.json +35 -35
  279. package/.next/standalone/.next/server/chunks/1318.js +1 -1
  280. package/.next/standalone/.next/server/chunks/{5201.js → 1416.js} +2 -2
  281. package/.next/standalone/.next/server/chunks/1559.js +2 -2
  282. package/.next/standalone/.next/server/chunks/{3630.js → 2195.js} +1 -1
  283. package/.next/standalone/.next/server/chunks/2460.js +1 -0
  284. package/.next/standalone/.next/server/chunks/2572.js +2 -2
  285. package/.next/standalone/.next/server/chunks/2758.js +1 -0
  286. package/.next/standalone/.next/server/chunks/2961.js +1 -1
  287. package/.next/standalone/.next/server/chunks/3419.js +1 -1
  288. package/.next/standalone/.next/server/chunks/4066.js +1 -0
  289. package/.next/standalone/.next/server/chunks/4827.js +1 -1
  290. package/.next/standalone/.next/server/chunks/5245.js +1 -1
  291. package/.next/standalone/.next/server/chunks/5453.js +1 -1
  292. package/.next/standalone/.next/server/chunks/5489.js +1 -1
  293. package/.next/standalone/.next/server/chunks/6113.js +1 -1
  294. package/.next/standalone/.next/server/chunks/6506.js +2 -2
  295. package/.next/standalone/.next/server/chunks/6737.js +1 -0
  296. package/.next/standalone/.next/server/chunks/679.js +1 -1
  297. package/.next/standalone/.next/server/chunks/7368.js +1 -1
  298. package/.next/standalone/.next/server/chunks/7530.js +1 -1
  299. package/.next/standalone/.next/server/chunks/7578.js +2 -2
  300. package/.next/standalone/.next/server/chunks/7675.js +1 -0
  301. package/.next/standalone/.next/server/chunks/7789.js +1 -0
  302. package/.next/standalone/.next/server/chunks/{1201.js → 8030.js} +2 -2
  303. package/.next/standalone/.next/server/chunks/920.js +1 -1
  304. package/.next/standalone/.next/server/chunks/9213.js +1 -1
  305. package/.next/standalone/.next/server/chunks/9378.js +1 -1
  306. package/.next/standalone/.next/server/chunks/9931.js +1 -1
  307. package/.next/standalone/.next/server/instrumentation.js +1 -1
  308. package/.next/standalone/.next/server/middleware-build-manifest.js +1 -1
  309. package/.next/standalone/.next/server/middleware-manifest.json +5 -5
  310. package/.next/standalone/.next/server/pages/404.html +2 -2
  311. package/.next/standalone/.next/server/pages/500.html +1 -1
  312. package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
  313. package/.next/standalone/.next/server/server-reference-manifest.json +1 -1
  314. package/.next/standalone/.next/static/chunks/11595.f080a1d100972212.js +1 -0
  315. package/.next/standalone/.next/static/chunks/14628-283d3983d1fb36c9.js +1 -0
  316. package/.next/standalone/.next/static/chunks/{29305-f587e7e81bc0b200.js → 17562-56f932146e9e6c94.js} +4 -4
  317. package/.next/standalone/.next/static/chunks/25080-25ad29e64c855338.js +1 -0
  318. package/.next/standalone/.next/static/chunks/28698-7fb271ffc6e63a26.js +1 -0
  319. package/.next/standalone/.next/static/chunks/{95225-96b44da3ebd6ddad.js → 32736-aeaaa1e4c4d5529b.js} +1 -1
  320. package/.next/standalone/.next/static/chunks/33456.20313bd67a5c41cc.js +1 -0
  321. package/.next/standalone/.next/static/chunks/4860.3b555a398cdffb19.js +1 -0
  322. package/.next/standalone/.next/static/chunks/75257-99c0ce24b436847b.js +1 -0
  323. package/.next/standalone/.next/static/chunks/79919-0c6dcda1dd8646f0.js +1 -0
  324. package/.next/standalone/.next/static/chunks/91328-f501e3c3ca519a92.js +1 -0
  325. package/.next/standalone/.next/static/chunks/94643-e54eff17e941a93b.js +1 -0
  326. package/.next/standalone/.next/static/chunks/99373.b8a95d1bec5ad4e7.js +1 -0
  327. package/.next/standalone/.next/static/chunks/app/(dashboard)/layout-f3c6431432d42c7c.js +1 -0
  328. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/dashboard/{page-77b175e52a85f3cb.js → page-5d723f974bdad33b.js} +1 -1
  329. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/documents/[documentUuid]/page-8d3b1f4d8b76d66c.js +1 -0
  330. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/documents/page-57c698dea2fa6e29.js +1 -0
  331. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/graph/{page-69d3162667f85677.js → page-d2bb622855e746f1.js} +1 -1
  332. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/[proposalUuid]/page-fc255dc3612032b9.js +1 -0
  333. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/new/{page-a3f83031dfbafc81.js → page-f032ee8a80d1f56a.js} +1 -1
  334. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/page-46a0ddfd0421b0a8.js +1 -0
  335. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/tasks/[taskUuid]/{page-3c7ff3a40a4615ac.js → page-3a83748ce0ae1c4f.js} +1 -1
  336. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/tasks/{page-7b8e11fdc5b596d0.js → page-8af9bb9f96ab0258.js} +1 -1
  337. package/.next/standalone/.next/static/chunks/app/(dashboard)/settings/page-b02939820affdae5.js +1 -0
  338. package/.next/standalone/.next/static/chunks/app/onboarding/page-d2c0c7951114e763.js +1 -0
  339. package/.next/standalone/.next/static/chunks/{webpack-dffb97a4feb8faba.js → webpack-de8a36d232a91d6b.js} +1 -1
  340. package/.next/standalone/.next/static/css/44f13b43a3de716d.css +1 -0
  341. package/.next/standalone/package.json +1 -1
  342. package/.next/standalone/public/chorus-plugin/.claude-plugin/plugin.json +2 -2
  343. package/.next/standalone/public/chorus-plugin/agents/code-reviewer.md +1 -0
  344. package/.next/standalone/public/chorus-plugin/agents/proposal-reviewer.md +12 -3
  345. package/.next/standalone/public/chorus-plugin/agents/task-reviewer.md +4 -0
  346. package/.next/standalone/public/chorus-plugin/bin/chorus-api.sh +1 -1
  347. package/.next/standalone/public/chorus-plugin/bin/on-post-submit-for-verify.sh +3 -3
  348. package/.next/standalone/public/chorus-plugin/bin/on-post-submit-proposal.sh +3 -3
  349. package/.next/standalone/public/chorus-plugin/bin/on-post-verify-task.sh +2 -2
  350. package/.next/standalone/public/chorus-plugin/bin/on-pre-spawn-agent.sh +22 -9
  351. package/.next/standalone/public/chorus-plugin/bin/on-session-start.sh +39 -64
  352. package/.next/standalone/public/chorus-plugin/bin/on-subagent-start.sh +44 -29
  353. package/.next/standalone/public/chorus-plugin/bin/on-subagent-stop.sh +100 -29
  354. package/.next/standalone/public/chorus-plugin/bin/resolve-spec-mode.sh +107 -0
  355. package/.next/standalone/public/chorus-plugin/bin/test-syntax.sh +6 -2
  356. package/.next/standalone/public/chorus-plugin/bin/tests/test-resolver-drift.sh +46 -0
  357. package/.next/standalone/public/chorus-plugin/bin/tests/test-skill-harness-fidelity-negative.sh +328 -0
  358. package/.next/standalone/public/chorus-plugin/bin/tests/test-skill-harness-fidelity.sh +372 -0
  359. package/.next/standalone/public/chorus-plugin/bin/tests/test-spec-mode-resolution.sh +83 -0
  360. package/.next/standalone/public/chorus-plugin/bin/tests/test-subagent-session-name.sh +599 -0
  361. package/.next/standalone/public/chorus-plugin/skills/brainstorm/SKILL.md +1 -1
  362. package/.next/standalone/public/chorus-plugin/skills/chorus/SKILL.md +11 -6
  363. package/.next/standalone/public/chorus-plugin/skills/chorus-cli/SKILL.md +1 -1
  364. package/.next/standalone/public/chorus-plugin/skills/develop/SKILL.md +14 -9
  365. package/.next/standalone/public/chorus-plugin/skills/docs/SKILL.md +1 -1
  366. package/.next/standalone/public/chorus-plugin/skills/idea/SKILL.md +1 -1
  367. package/.next/standalone/public/chorus-plugin/skills/openspec-aware/SKILL.md +27 -31
  368. package/.next/standalone/public/chorus-plugin/skills/orchestrate/SKILL.md +11 -1
  369. package/.next/standalone/public/chorus-plugin/skills/proposal/SKILL.md +14 -7
  370. package/.next/standalone/public/chorus-plugin/skills/quick-dev/SKILL.md +6 -4
  371. package/.next/standalone/public/chorus-plugin/skills/review/SKILL.md +10 -8
  372. package/.next/standalone/public/chorus-plugin/skills/spec-lite/SKILL.md +147 -0
  373. package/.next/standalone/public/chorus-plugin/skills/yolo/SKILL.md +49 -34
  374. package/.next/standalone/public/kiro-plugin/.kiro/agents/chorus-code-reviewer.json +1 -1
  375. package/.next/standalone/public/kiro-plugin/.kiro/agents/chorus-proposal-reviewer.json +2 -1
  376. package/.next/standalone/public/kiro-plugin/.kiro/agents/chorus-task-reviewer.json +1 -1
  377. package/.next/standalone/public/kiro-plugin/.kiro/agents/chorus.md +1 -1
  378. package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-brainstorm/SKILL.md +1 -1
  379. package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-cli/SKILL.md +1 -1
  380. package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-develop/SKILL.md +9 -7
  381. package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-docs/SKILL.md +1 -1
  382. package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-idea/SKILL.md +1 -1
  383. package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-openspec-aware/SKILL.md +35 -27
  384. package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-orchestrate/SKILL.md +9 -1
  385. package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-proposal/SKILL.md +14 -7
  386. package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-quick-dev/SKILL.md +2 -2
  387. package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-review/SKILL.md +8 -8
  388. package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-spec-lite/SKILL.md +147 -0
  389. package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-yolo/SKILL.md +39 -25
  390. package/.next/standalone/public/kiro-plugin/.kiro/steering/chorus.md +11 -6
  391. package/.next/standalone/public/kiro-plugin/bin/chorus-api.sh +1 -1
  392. package/.next/standalone/public/kiro-plugin/bin/on-agent-spawn.sh +41 -0
  393. package/.next/standalone/public/kiro-plugin/bin/on-post-submit-for-verify.sh +3 -3
  394. package/.next/standalone/public/kiro-plugin/bin/on-post-submit-proposal.sh +3 -3
  395. package/.next/standalone/public/kiro-plugin/bin/on-post-verify-task.sh +2 -2
  396. package/.next/standalone/public/kiro-plugin/bin/resolve-spec-mode.sh +107 -0
  397. package/.next/standalone/public/kiro-plugin/manifest.txt +2 -0
  398. package/.next/standalone/public/skill/chorus/SKILL.md +11 -1
  399. package/.next/standalone/public/skill/code-reviewer-chorus/SKILL.md +1 -0
  400. package/.next/standalone/public/skill/develop-chorus/SKILL.md +1 -1
  401. package/.next/standalone/public/skill/orchestrate-chorus/SKILL.md +11 -1
  402. package/.next/standalone/public/skill/proposal-reviewer-chorus/SKILL.md +5 -2
  403. package/.next/standalone/public/skill/quick-dev-chorus/SKILL.md +1 -1
  404. package/.next/standalone/public/skill/review-chorus/SKILL.md +5 -3
  405. package/.next/standalone/public/skill/task-reviewer-chorus/SKILL.md +4 -0
  406. package/.next/standalone/public/skill/yolo-chorus/SKILL.md +23 -7
  407. package/README.ja.md +3 -3
  408. package/README.ko.md +3 -3
  409. package/README.md +3 -3
  410. package/README.zh.md +3 -3
  411. package/chorus.mjs +30 -2
  412. package/cli/agent-cli-config.mjs +323 -0
  413. package/cli/agent-launcher.mjs +44 -16
  414. package/cli/child-exit.mjs +77 -0
  415. package/cli/claude-spawner.mjs +26 -14
  416. package/cli/codex-spawner.mjs +27 -16
  417. package/cli/control-handler.mjs +104 -6
  418. package/cli/credentials.mjs +7 -0
  419. package/cli/daemon-config.mjs +14 -0
  420. package/cli/daemon-rest-client.mjs +98 -29
  421. package/cli/daemon.mjs +37 -7
  422. package/cli/dsh-managed-config.mjs +26 -28
  423. package/cli/dsh-spawner.mjs +27 -16
  424. package/cli/init/steps/credential-seed.mjs +1 -1
  425. package/cli/kiro-spawner.mjs +26 -16
  426. package/cli/launch-diagnostics.mjs +67 -0
  427. package/cli/login.mjs +17 -1
  428. package/cli/pi-spawner.mjs +23 -13
  429. package/cli/prompts.mjs +52 -2
  430. package/cli/spawner-select.mjs +6 -11
  431. package/package.json +1 -1
  432. package/.next/standalone/.next/server/chunks/1114.js +0 -1
  433. package/.next/standalone/.next/server/chunks/1155.js +0 -1
  434. package/.next/standalone/.next/server/chunks/6465.js +0 -1
  435. package/.next/standalone/.next/server/chunks/8105.js +0 -1
  436. package/.next/standalone/.next/server/chunks/8232.js +0 -1
  437. package/.next/standalone/.next/static/chunks/11595.f7c3ef5cd7fc8feb.js +0 -1
  438. package/.next/standalone/.next/static/chunks/33456.c81079032acc2966.js +0 -1
  439. package/.next/standalone/.next/static/chunks/45262-38b332523f00a223.js +0 -1
  440. package/.next/standalone/.next/static/chunks/46021-f5d072b0cbcb7fac.js +0 -1
  441. package/.next/standalone/.next/static/chunks/4860.f0cfb1201191ae88.js +0 -1
  442. package/.next/standalone/.next/static/chunks/66609-64a01d5cb415465b.js +0 -1
  443. package/.next/standalone/.next/static/chunks/79919-c5a2a3fd8f5f9204.js +0 -1
  444. package/.next/standalone/.next/static/chunks/94394-38194b81b489275c.js +0 -1
  445. package/.next/standalone/.next/static/chunks/94643-f1bdf37fb3bb6adb.js +0 -1
  446. package/.next/standalone/.next/static/chunks/96482-2b3bdb2544d72e5a.js +0 -1
  447. package/.next/standalone/.next/static/chunks/99373.3c23ac2efbd4db02.js +0 -1
  448. package/.next/standalone/.next/static/chunks/app/(dashboard)/layout-66328332f62c7371.js +0 -1
  449. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/documents/[documentUuid]/page-87ceae13c4950fc9.js +0 -1
  450. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/documents/page-45e95154e546460e.js +0 -1
  451. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/[proposalUuid]/page-b7b2017e5be69564.js +0 -1
  452. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/page-8b06834ca0f663bb.js +0 -1
  453. package/.next/standalone/.next/static/chunks/app/(dashboard)/settings/page-efe5326c47aca9ca.js +0 -1
  454. package/.next/standalone/.next/static/chunks/app/onboarding/page-0ce33b9327fe3d8c.js +0 -1
  455. package/.next/standalone/.next/static/css/1d9cf83f50b6db00.css +0 -1
  456. /package/.next/standalone/.next/static/{wuqYN129vOIGymh_NEdZe → dot63ILT878Tloqi7Czj_}/_buildManifest.js +0 -0
  457. /package/.next/standalone/.next/static/{wuqYN129vOIGymh_NEdZe → dot63ILT878Tloqi7Czj_}/_ssgManifest.js +0 -0
@@ -317,8 +317,8 @@ All tasks of idea-rooted proposal ${PROPOSAL_UUID} are now done. This is the fin
317
317
 
318
318
  ACTION REQUESTED: spawn code-reviewer for this idea — an independent, read-only review of the idea's AGGREGATE code change (the whole feature across all its tasks), not a single task.
319
319
 
320
- 1. Spawn the code-reviewer in FOREGROUND, passing it ideaUuid="${idea_uuid}" and the review round number (read prior code-review verdict comments on the idea to determine it). It reviews cross-task integration, architecture/convention consistency, security, regression/performance, feature-level test coverage, and overall code soundness, then posts ONE VERDICT comment on the idea.
321
- 2. Read its VERDICT on the idea (chorus_get_comments targetType="idea").
320
+ 1. Spawn the code-reviewer and wait for its completion notification, passing it ideaUuid="${idea_uuid}" and the review round number (read prior code-review verdict comments on the idea to determine it). It reviews cross-task integration, architecture/convention consistency, security, regression/performance, feature-level test coverage, and overall code soundness, then posts ONE VERDICT comment on the idea.
321
+ 2. Read THIS round's VERDICT on the idea (chorus_get_comments targetType="idea") — the comment posted after your dispatch, not an earlier round's. The launch result is not the verdict; do not declare the feature shippable before you have read that comment. If it is missing, check what the reviewer did post: a comment reporting the round limit was reached, or any other explicit refusal to review, is a deliberate escalation — STOP: do not respawn, do not self-review, do not post a VERDICT of your own; leave it pending the human's decision. If it posted nothing at all, respawn once and apply this same check again to what the retry posts — an explicit refusal still means STOP; only a second true silence lets you review the idea's aggregate change yourself as a read-only pass and post the VERDICT. Absence is never a PASS.
322
322
  3. PASS / PASS WITH NOTES -> the feature may ship.
323
323
  4. FAIL -> the orchestrator invokes Quick Dev to create new tasks on the original approved proposal; never reopen completed tasks or apply untracked fixes. Group related small BLOCKERs by default and split only materially large or independently testable fixes.
324
324
  5. Re-run only after every fix task passes AC self-check, independent task review, and admin verification to done. A failed or cancelled fix stops the loop and escalates. Keep maxCodeReviewRounds authoritative.
@@ -28,27 +28,35 @@ fi
28
28
  CHORUS_SESSION_ID=$(printf '%s' "$EVENT" | jq -r '.session_id // .sessionId // empty' 2>/dev/null) || true
29
29
  export CHORUS_SESSION_ID
30
30
 
31
- # Try to extract subagent_type and name from the tool input
31
+ # Try to extract subagent_type and name from the tool input.
32
+ # `tool_input.name` does not exist on CC's Task tool today — it is read for
33
+ # forward-compatibility and falls back to subagent_type, which is the value the
34
+ # SubagentStart hook also receives as agent_type (and uses as the session name).
32
35
  AGENT_TYPE=""
33
36
  AGENT_NAME=""
34
37
  if [ -n "$EVENT" ]; then
35
38
  AGENT_TYPE=$(echo "$EVENT" | jq -r '.tool_input.subagent_type // .input.subagent_type // empty' 2>/dev/null) || true
36
39
  AGENT_NAME=$(echo "$EVENT" | jq -r '.tool_input.name // .input.name // empty' 2>/dev/null) || true
37
40
  fi
41
+ AGENT_NAME="${AGENT_NAME:-$AGENT_TYPE}"
38
42
 
39
- # Skip non-worker types — no need to remind for Explore/Plan agents
43
+ # Skip non-worker types — no need to remind for Explore/Plan agents.
44
+ # This list MUST stay identical to the skip list in on-subagent-start.sh:
45
+ # a type skipped by only one hook leaves an orphan pending file that a later
46
+ # internal/cleanup agent could FIFO-claim, defeating the spawn gate.
40
47
  case "$(printf '%s' "$AGENT_TYPE" | tr '[:upper:]' '[:lower:]')" in
41
- explore|plan|haiku|claude-code-guide|statusline-setup)
48
+ explore|plan|haiku|claude-code-guide|statusline-setup|chorus:proposal-reviewer|chorus:task-reviewer)
42
49
  exit 0
43
50
  ;;
44
51
  esac
45
52
 
46
53
  # Write a per-agent pending file for SubagentStart to claim.
47
- # SubagentStart only receives agent_id + agent_type — not the name.
48
- # CC sometimes uses the agent name as agent_type, so we store both.
54
+ #
55
+ # The pending file is a SPAWN GATE, not a name channel: its presence proves a
56
+ # SubagentStart came from a real Task spawn. The session name is derived by
57
+ # on-subagent-start.sh from the event's own agent_type, never from this file.
49
58
  #
50
59
  # Each spawn gets its own file — no shared state, no concurrency issues.
51
- # File name is the agent name (or a unique fallback if name is empty).
52
60
  # SubagentStart claims by mv (atomic on same filesystem).
53
61
  #
54
62
  # CC may internally spawn cleanup agents that bypass PreToolUse:Task —
@@ -59,10 +67,15 @@ esac
59
67
  PENDING_DIR="${CHORUS_STATE_DIR:-${CLAUDE_PROJECT_DIR:-.}/.chorus}/pending"
60
68
  mkdir -p "$PENDING_DIR" 2>/dev/null || true
61
69
 
62
- # Use agent name as filename; fall back to timestamp-based unique name
63
- PENDING_NAME="${AGENT_NAME:-unknown-$(date +%s%N)}"
70
+ # Filename stem: sanitized subagent_type (":" and "/" in namespaced types such as
71
+ # chorus:code-reviewer become "_"), plus epoch seconds and the PID for uniqueness.
72
+ # $$ is required: BSD date (macOS) has no %N, so two same-second spawns of the same
73
+ # type would otherwise collide on a single filename and one would be lost.
74
+ PENDING_STEM=$(printf '%s' "${AGENT_TYPE:-worker}" | tr -c '[:alnum:]._-' '_')
75
+ [ -z "$PENDING_STEM" ] && PENDING_STEM="worker"
76
+ PENDING_NAME="${PENDING_STEM}__$(date +%s)-$$"
64
77
  printf '{"name":"%s","type":"%s","ts":"%s"}\n' \
65
- "${AGENT_NAME:-}" "${AGENT_TYPE:-}" "$(date -u +%Y-%m-%dT%H:%M:%S.%3NZ)" \
78
+ "${AGENT_NAME:-}" "${AGENT_TYPE:-}" "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
66
79
  > "${PENDING_DIR}/${PENDING_NAME}"
67
80
 
68
81
  CONTEXT="[Chorus Plugin — Sub-agent Spawn]
@@ -67,45 +67,17 @@ if command -v jq >/dev/null 2>&1; then
67
67
 
68
68
  fi
69
69
 
70
- # Detect OpenSpec mode for this repo, once per session.
71
- # Both conditions are required for OpenSpec mode to be usable:
72
- # (a) an openspec/ directory at the project root (this repo was inited via `openspec init`), AND
73
- # (b) the `openspec` CLI on PATH (so we can `openspec new change`, `validate`, `archive`).
74
- # Overrides (precedence high -> low, first match wins):
75
- # 1. enableOpenSpec userConfig toggle (default true) — UI-level switch.
76
- # 2. CHORUS_OPENSPEC_MODE=off env var — env-level explicit opt-out.
77
- # When the folder is present but the CLI is missing, surface that as a
78
- # specific reason so the user-visible toast can hint at the install step
79
- # instead of silently falling back.
70
+ # Resolve the active spec mode for this repo, once per session. The resolution
71
+ # logic lives in resolve-spec-mode.sh (pure: env + filesystem only) so it can be
72
+ # unit-tested — see bin/tests/test-spec-mode-resolution.sh. It sets SPEC_MODE,
73
+ # SPEC_REASON, SPEC_FAIL, OPENSPEC_USABLE_REASON, OPENSPEC_HINT, CHORUS_OPENSPEC_ACTIVE.
80
74
  #
81
- # The inactive states split into two user-facing kinds:
82
- # - OPENSPEC_OPTOUT=1 — the user explicitly turned OpenSpec off (plugin
83
- # toggle or env var). Respect it: show a neutral note, no nag.
84
- # - OPENSPEC_OPTOUT=0 — OpenSpec is simply not set up (no folder, or folder
85
- # without the CLI). Point the user at `/chorus enable openspec`, which walks
86
- # the actual install/init steps — the banner stays a one-liner.
75
+ # Summary: an explicit CHORUS_SPEC_MODE (lite|openspec|off) wins; when UNSET,
76
+ # OpenSpec stays the default whenever it is usable (openspec/ dir + CLI, not
77
+ # disabled) and lite is the fallback only when OpenSpec is absent or disabled.
78
+ # Legacy CHORUS_OPENSPEC_MODE=off still forces not-openspec (→ lite when unset).
87
79
  PROJECT_ROOT="${CLAUDE_PROJECT_DIR:-$PWD}"
88
- OPENSPEC_HINT=""
89
- OPENSPEC_OPTOUT=0
90
- if [ "${CLAUDE_PLUGIN_OPTION_ENABLEOPENSPEC:-true}" != "true" ]; then
91
- CHORUS_OPENSPEC_ACTIVE=0
92
- OPENSPEC_OPTOUT=1
93
- OPENSPEC_REASON="enableOpenSpec userConfig=false (plugin-level opt-out)"
94
- elif [ "${CHORUS_OPENSPEC_MODE:-}" = "off" ]; then
95
- CHORUS_OPENSPEC_ACTIVE=0
96
- OPENSPEC_OPTOUT=1
97
- OPENSPEC_REASON="CHORUS_OPENSPEC_MODE=off (explicit opt-out)"
98
- elif [ ! -d "${PROJECT_ROOT}/openspec" ]; then
99
- CHORUS_OPENSPEC_ACTIVE=0
100
- OPENSPEC_REASON="no openspec/ directory at ${PROJECT_ROOT}/openspec"
101
- elif ! command -v openspec >/dev/null 2>&1; then
102
- CHORUS_OPENSPEC_ACTIVE=0
103
- OPENSPEC_REASON="openspec/ directory present but \`openspec\` CLI not on PATH"
104
- OPENSPEC_HINT="install with: npm i -g @fission-ai/openspec"
105
- else
106
- CHORUS_OPENSPEC_ACTIVE=1
107
- OPENSPEC_REASON="openspec/ directory + openspec CLI both present"
108
- fi
80
+ . "${SCRIPT_DIR}/resolve-spec-mode.sh"
109
81
 
110
82
  # Build context for Claude (additionalContext)
111
83
  CONTEXT="# Chorus Plugin — Active
@@ -116,33 +88,33 @@ Chorus is connected at ${CHORUS_URL}. Session lifecycle hooks are enabled.
116
88
 
117
89
  ${CHECKIN_RESULT}
118
90
 
119
- ## OpenSpec Mode
91
+ ## Spec Mode
120
92
 
121
- CHORUS_OPENSPEC_ACTIVE=${CHORUS_OPENSPEC_ACTIVE} (${OPENSPEC_REASON})"
93
+ CHORUS_SPEC_MODE=${SPEC_MODE} (${SPEC_REASON})"
122
94
 
123
- if [ "$CHORUS_OPENSPEC_ACTIVE" = "1" ]; then
95
+ if [ "$SPEC_MODE" = "lite" ]; then
124
96
  CONTEXT="${CONTEXT}
125
97
 
126
- OpenSpec mode is **active** for this session. When the proposal / develop / yolo skills reach an OpenSpec-aware step, load the openspec-aware skill at \`.claude/skills/openspec-aware/SKILL.md\` and follow §3 (OpenSpec authoring) — do NOT re-run the §1 detection block, the answer is already known.
98
+ Routing: lite → follow the spec-lite skill (\`skills/spec-lite/SKILL.md\`). Author a Chorus-native change folder \`.chorus/specs/<slug>/\` (\`prd.md\` required; \`tech_design.md\` / \`adr.md\` / \`spec.md\` / \`guide.md\` optional) and mirror each \`<type>.md\` 1:1 into a Chorus Document of that type via \`chorus mcp call … --arg-file content=<file>\`. Do NOT scaffold \`openspec/changes/\` or add an \`OpenSpec change slug:\` line."
99
+ elif [ "$SPEC_MODE" = "off" ]; then
100
+ CONTEXT="${CONTEXT}
127
101
 
128
- Critical rule (openspec-aware §2 Rule 1): document mirror calls (\`chorus_pm_add_document_draft\` / \`chorus_pm_update_document_draft\` / \`chorus_pm_update_document\`) MUST fill \`content\` from the local file — prefer \`chorus mcp call <tool> '<json>' --arg-file content=<file>\`, falling back to \`chorus-api.sh mcp-tool\` with \`json_encode_file\` when \`chorus\` is not on PATH. Do NOT invoke these MCP tools directly with hand-typed \`content\` in OpenSpec mode."
129
- else
102
+ Routing: off → free-form, no spec artifact. Do NOT create \`.chorus/specs/\` or \`openspec/changes/\` files; author document drafts inline via direct MCP."
103
+ elif [ -n "$SPEC_FAIL" ]; then
130
104
  CONTEXT="${CONTEXT}
131
105
 
132
- OpenSpec mode is **inactive** for this session. The proposal / develop / yolo skills follow their free-form path; do NOT scaffold \`openspec/changes/\`, do NOT add an \`OpenSpec change slug:\` line to proposal descriptions, and do NOT route document mirror calls through the \`chorus\` CLI or \`chorus-api.sh\`."
133
- if [ "$OPENSPEC_OPTOUT" = "1" ]; then
134
- CONTEXT="${CONTEXT}
106
+ Routing: openspec → **cannot be honored** — ${SPEC_FAIL}. The proposal / yolo skill MUST halt after resolving the mode; do NOT silently fall back to lite/free-form. Surface this to the user."
107
+ if [ -n "$OPENSPEC_HINT" ]; then
108
+ CONTEXT="${CONTEXT} Install hint: ${OPENSPEC_HINT}."
109
+ fi
110
+ else
111
+ CONTEXT="${CONTEXT}
135
112
 
136
- OpenSpec was **explicitly turned off** (${OPENSPEC_REASON}), so this is a deliberate choice — do NOT nag the user to enable it. If they ask to turn it back on, point them at re-enabling the plugin's \`enableOpenSpec\` toggle / unsetting \`CHORUS_OPENSPEC_MODE\`, then the OpenSpec setup section in the \`/chorus\` skill."
137
- elif [ -n "$OPENSPEC_HINT" ]; then
138
- CONTEXT="${CONTEXT}
113
+ CHORUS_OPENSPEC_ACTIVE=1 (${OPENSPEC_USABLE_REASON})
139
114
 
140
- Note: this repo has an \`openspec/\` directory, so the user likely intends to use OpenSpec mode but the \`openspec\` CLI is not installed. Surface this to the user (e.g. \"This repo is OpenSpec-init'd but the \\\`openspec\\\` CLI isn't installed locally — ${OPENSPEC_HINT}\") before authoring documents. To set it up, run \`/chorus enable openspec\` (§6 walks the install + re-launch)."
141
- else
142
- CONTEXT="${CONTEXT}
115
+ Routing: openspec → load the openspec-aware skill at \`.claude/skills/openspec-aware/SKILL.md\` and follow §3 (OpenSpec authoring) — do NOT re-run the §1 detection block, the answer is already known.
143
116
 
144
- Note: OpenSpec is not set up in this repo (${OPENSPEC_REASON}). Spec-driven authoring is optional — free-form works fine. If the user wants spec-driven mode (proposal.md / design.md / spec deltas mirrored into Chorus), run \`/chorus enable openspec\` — §6 walks the \`npm i -g @fission-ai/openspec\` + \`openspec init\` steps and the re-launch."
145
- fi
117
+ Critical rule (openspec-aware §2 Rule 1): document mirror calls (\`chorus_pm_add_document_draft\` / \`chorus_pm_update_document_draft\` / \`chorus_pm_update_document\`) MUST fill \`content\` from the local file — prefer \`chorus mcp call <tool> '<json>' --arg-file content=<file>\`, falling back to \`chorus-api.sh mcp-tool\` with \`json_encode_file\` when \`chorus\` is not on PATH. Do NOT invoke these MCP tools directly with hand-typed \`content\` in OpenSpec mode."
146
118
  fi
147
119
 
148
120
  CONTEXT="${CONTEXT}
@@ -164,18 +136,21 @@ Resuming with existing Chorus session: ${MAIN_SESSION}"
164
136
  "$API" mcp-tool "chorus_session_heartbeat" "$(printf '{"sessionUuid":"%s"}' "$MAIN_SESSION")" >/dev/null 2>&1 || true
165
137
  fi
166
138
 
167
- # Build user-visible message. When OpenSpec is off-but-enable-able, point the
168
- # user at `/chorus enable openspec` — the skill walks the actual install/init.
169
- # active -> (OpenSpec Enabled)
170
- # not set up -> (OpenSpec off — run `/chorus enable openspec` to set it up)
171
- # explicit opt-out -> (OpenSpec off) [neutral, no nag — respects the choice]
139
+ # Build user-visible message. Always states the active spec mode (lite is the
140
+ # default); an explicit openspec that can't be honored is flagged as not usable.
141
+ # lite -> (Spec: lite)
142
+ # off -> (Spec: off)
143
+ # openspec (usable) -> (Spec: openspec)
144
+ # openspec (broken) -> (Spec: openspec — not usable)
172
145
  USER_MSG="Chorus connected at ${CHORUS_URL}"
173
- if [ "$CHORUS_OPENSPEC_ACTIVE" = "1" ]; then
174
- USER_MSG="${USER_MSG} (OpenSpec Enabled)"
175
- elif [ "$OPENSPEC_OPTOUT" = "1" ]; then
176
- USER_MSG="${USER_MSG} (OpenSpec off)"
146
+ if [ "$SPEC_MODE" = "lite" ]; then
147
+ USER_MSG="${USER_MSG} (Spec: lite)"
148
+ elif [ "$SPEC_MODE" = "off" ]; then
149
+ USER_MSG="${USER_MSG} (Spec: off)"
150
+ elif [ -n "$SPEC_FAIL" ]; then
151
+ USER_MSG="${USER_MSG} (Spec: openspec — not usable)"
177
152
  else
178
- USER_MSG="${USER_MSG} (OpenSpec off — run \`/chorus enable openspec\` to set it up)"
153
+ USER_MSG="${USER_MSG} (Spec: openspec)"
179
154
  fi
180
155
  if [ -n "$MAIN_SESSION" ]; then
181
156
  USER_MSG="${USER_MSG} (resumed session)"
@@ -2,8 +2,12 @@
2
2
  # on-subagent-start.sh — SubagentStart hook
3
3
  # Triggered SYNCHRONOUSLY when a sub-agent (teammate) is spawned.
4
4
  #
5
- # Name resolution: Claims a per-agent pending file written by PreToolUse:Task
6
- # using atomic mv (only one process can successfully mv a given file).
5
+ # Name resolution: the session name is the event's own agent_type (the value the
6
+ # spawning Task call passed as subagent_type), falling back to worker-<agentId8>.
7
+ #
8
+ # Spawn gate: claims a per-spawn pending file written by PreToolUse:Task using
9
+ # atomic mv (only one process can successfully mv a given file). The file only
10
+ # proves the spawn was a real Task call — it never carries the name.
7
11
  #
8
12
  # Session reuse logic:
9
13
  # 1. List existing sessions via MCP
@@ -45,14 +49,14 @@ export CHORUS_SESSION_ID
45
49
  [ -f "${SCRIPT_DIR}/chorus-paths.sh" ] && { . "${SCRIPT_DIR}/chorus-paths.sh" 2>/dev/null || true; }
46
50
  CHORUS_STATE_DIR="${CHORUS_STATE_DIR:-${CLAUDE_PROJECT_DIR:-.}/.chorus}"
47
51
 
48
- # Extract agent info from event
49
- # Note: SubagentStart only provides agent_id and agent_type — NOT the name
50
- # from the Task tool call. The name is captured by on-pre-spawn-agent.sh
51
- # (PreToolUse:Task) and stored as a per-agent file in .chorus/pending/.
52
+ # Extract agent info from event.
53
+ # agent_type is the same value the spawning Task call passed as subagent_type,
54
+ # so it is the session name source (see SESSION_NAME below).
52
55
  AGENT_ID=$(echo "$EVENT" | jq -r '.agent_id // .agentId // empty' 2>/dev/null) || true
53
56
  AGENT_TYPE=$(echo "$EVENT" | jq -r '.agent_type // .agentType // empty' 2>/dev/null) || true
54
57
 
55
- # Skip non-worker agent types (read-only agents don't need sessions)
58
+ # Skip non-worker agent types (read-only agents don't need sessions).
59
+ # This list MUST stay identical to the skip list in on-pre-spawn-agent.sh.
56
60
  case "$(printf '%s' "$AGENT_TYPE" | tr '[:upper:]' '[:lower:]')" in
57
61
  explore|plan|haiku|claude-code-guide|statusline-setup|chorus:proposal-reviewer|chorus:task-reviewer)
58
62
  exit 0
@@ -66,35 +70,24 @@ fi
66
70
  # Claim a pending file written by PreToolUse:Task (on-pre-spawn-agent.sh).
67
71
  # Each pending file represents one expected sub-agent spawn.
68
72
  #
69
- # Claim strategy (atomic mv — only one process can succeed per file):
70
- # 1. Try exact match: mv .chorus/pending/{agent_type} → claimed/{agent_id}
71
- # (CC often sets agent_type to the name from the Task tool call)
72
- # 2. Fallback: claim the oldest pending file (FIFO by modification time)
73
+ # The pending file is a SPAWN GATE, not a name channel: it only proves this
74
+ # SubagentStart corresponds to a real Task spawn. Neither its filename nor its
75
+ # contents influence the session name, so plain FIFO claiming is safe even when a
76
+ # mixed parallel batch pairs this agent with another spawn's file.
73
77
  #
74
- # If no pending file exists, this is an internal/cleanup agent → skip.
75
- AGENT_NAME=""
78
+ # Claim strategy: FIFO by modification time, atomic mv (only one process can
79
+ # succeed per file). If no pending file can be claimed, this is one of Claude
80
+ # Code's internal/cleanup agents (they bypass PreToolUse:Task) → skip.
76
81
  PENDING_DIR="${CHORUS_STATE_DIR}/pending"
77
82
  CLAIMED_DIR="${CHORUS_STATE_DIR}/claimed"
78
83
  mkdir -p "$CLAIMED_DIR" 2>/dev/null || true
79
84
 
80
85
  CLAIMED_FILE=""
81
86
 
82
- # Strategy 1: exact match by agent_type (CC uses name as agent_type)
83
- if [ -f "${PENDING_DIR}/${AGENT_TYPE}" ]; then
84
- if mv "${PENDING_DIR}/${AGENT_TYPE}" "${CLAIMED_DIR}/${AGENT_ID}" 2>/dev/null; then
85
- CLAIMED_FILE="${CLAIMED_DIR}/${AGENT_ID}"
86
- AGENT_NAME="$AGENT_TYPE"
87
- fi
88
- fi
89
-
90
- # Strategy 2: FIFO — claim oldest pending file
91
- if [ -z "$CLAIMED_FILE" ] && [ -d "$PENDING_DIR" ]; then
87
+ if [ -d "$PENDING_DIR" ]; then
92
88
  for candidate in $(ls -tr "$PENDING_DIR" 2>/dev/null); do
93
89
  if mv "${PENDING_DIR}/${candidate}" "${CLAIMED_DIR}/${AGENT_ID}" 2>/dev/null; then
94
90
  CLAIMED_FILE="${CLAIMED_DIR}/${AGENT_ID}"
95
- # Read name from file content if available
96
- FILE_NAME=$(jq -r '.name // empty' "$CLAIMED_FILE" 2>/dev/null) || true
97
- AGENT_NAME="${FILE_NAME:-$candidate}"
98
91
  break
99
92
  fi
100
93
  # mv failed → another process claimed it first, try next
@@ -106,8 +99,17 @@ if [ -z "$CLAIMED_FILE" ]; then
106
99
  exit 0
107
100
  fi
108
101
 
109
- # Fallback: use agent_type + short ID if no name was captured
110
- SESSION_NAME="${AGENT_NAME:-${AGENT_TYPE:-worker}-${AGENT_ID:0:8}}"
102
+ # Session name comes from this event's own agent_type (the same value the Task
103
+ # call passed as subagent_type). Falls back to an agent-id-derived name only when
104
+ # agent_type is empty — never a placeholder like "unknown-<digits>".
105
+ SESSION_NAME="${AGENT_TYPE:-worker-${AGENT_ID:0:8}}"
106
+
107
+ # Sanitized form for on-disk filenames only. Namespaced types such as
108
+ # chorus:code-reviewer are not skipped, so they reach this path and must not put
109
+ # a ":" or "/" into a path. The name sent to Chorus, the state keys and the
110
+ # injected workflow text all keep the raw agent_type.
111
+ SESSION_NAME_FILE=$(printf '%s' "$SESSION_NAME" | tr -c '[:alnum:]._-' '_')
112
+ [ -z "$SESSION_NAME_FILE" ] && SESSION_NAME_FILE="worker-${AGENT_ID:0:8}"
111
113
 
112
114
  # === Session reuse: list existing sessions, find by name ===
113
115
  SESSION_UUID=""
@@ -187,11 +189,24 @@ fi
187
189
  "$API" state-set "session_${SESSION_NAME}" "$SESSION_UUID"
188
190
  "$API" state-set "name_for_agent_${AGENT_ID}" "$SESSION_NAME"
189
191
 
192
+ # === Holder refcount: register this agent as a holder of the session NAME ===
193
+ # Because the name is the repeating agent_type, two parallel sub-agents of the
194
+ # same type converge on ONE session (reuse-by-name above). on-subagent-stop.sh
195
+ # removes its own entry here and only tears the shared session down when no other
196
+ # holder remains — otherwise the first sibling to exit would close the session,
197
+ # check the other sibling's task out and delete state its sibling still reads.
198
+ # Registered on every path (created / reused / reopened). The directory component
199
+ # uses the SAME sanitization as the sessions/<name>.json filename — a namespaced
200
+ # type such as chorus:code-reviewer must never put a ":" or "/" into a path.
201
+ HOLDERS_DIR="${CHORUS_STATE_DIR}/holders/${SESSION_NAME_FILE}"
202
+ mkdir -p "$HOLDERS_DIR" 2>/dev/null || true
203
+ : > "${HOLDERS_DIR}/${AGENT_ID}" 2>/dev/null || true
204
+
190
205
  # === Session file: minimal metadata for other hooks (TeammateIdle, SubagentStop) ===
191
206
  SESSIONS_DIR="${CHORUS_STATE_DIR}/sessions"
192
207
  mkdir -p "$SESSIONS_DIR" 2>/dev/null || true
193
208
 
194
- cat > "${SESSIONS_DIR}/${SESSION_NAME}.json" <<SESSIONEOF
209
+ cat > "${SESSIONS_DIR}/${SESSION_NAME_FILE}.json" <<SESSIONEOF
195
210
  {
196
211
  "sessionUuid": "${SESSION_UUID}",
197
212
  "agentId": "${AGENT_ID}",
@@ -4,6 +4,12 @@
4
4
  # Auto-checkout from all checked-in tasks, close the Chorus session,
5
5
  # clean up state files, and auto-verify if admin AC all passed.
6
6
  #
7
+ # Holder-aware: session names are the repeating agent_type, so parallel same-type
8
+ # sub-agents SHARE one session. Teardown (checkout / close / name-keyed state /
9
+ # sessions file / auto-verify) only happens for the LAST holder of the name — see
10
+ # the holder refcount block below. Non-last stops clean up only their own
11
+ # id-keyed state and leave the session running for their siblings.
12
+ #
7
13
  # NOTE: SubagentStop does NOT support additionalContext in Claude Code's
8
14
  # hookSpecificOutput schema, and systemMessage only reaches the UI —
9
15
  # not the main agent's LLM context. All agent-facing reminders must go
@@ -54,47 +60,104 @@ if [ -z "$SESSION_UUID" ]; then
54
60
  exit 0
55
61
  fi
56
62
 
57
- # === Auto-checkout from all checked-in tasks ===
63
+ # Sanitized form of the name for on-disk paths (same tr sanitization as
64
+ # on-subagent-start.sh uses for sessions/<name>.json and holders/<name>/) —
65
+ # namespaced types such as chorus:code-reviewer must not put a ":" into a path.
66
+ # The state keys keep the raw name.
67
+ AGENT_NAME_FILE=""
68
+ if [ -n "$AGENT_NAME" ]; then
69
+ AGENT_NAME_FILE=$(printf '%s' "$AGENT_NAME" | tr -c '[:alnum:]._-' '_')
70
+ fi
71
+
72
+ # === Holder refcount: is this the LAST agent holding the session name? ===
73
+ # Session names are the repeating agent_type, so two parallel sub-agents of the
74
+ # same type share ONE session (reuse-by-name in on-subagent-start.sh). Remove our
75
+ # OWN holder entry first, then count what remains: only the last holder may close
76
+ # the session, auto-checkout, auto-verify or delete the name-keyed state that
77
+ # siblings (and on-teammate-idle.sh) still read.
78
+ #
79
+ # Races are benign and must stay benign: if a sibling's start has not registered
80
+ # its holder yet we may see 0 holders and close the session; that sibling's start
81
+ # then finds a closed/inactive row and reopens it via the existing reopen path.
82
+ # Deliberately no locking.
83
+ #
84
+ # With no name in state we cannot refcount — fall back to the legacy
85
+ # single-agent behaviour (treat this stop as the last holder).
86
+ HOLDERS_DIR=""
87
+ HOLDERS_REMAINING=0
88
+ if [ -n "$AGENT_NAME_FILE" ]; then
89
+ HOLDERS_DIR="${CHORUS_STATE_DIR}/holders/${AGENT_NAME_FILE}"
90
+ rm -f "${HOLDERS_DIR}/${AGENT_ID}" 2>/dev/null || true
91
+ if [ -d "$HOLDERS_DIR" ]; then
92
+ HOLDERS_REMAINING=$(ls -1 "$HOLDERS_DIR" 2>/dev/null | grep -c . || true)
93
+ fi
94
+ fi
95
+ [ -n "$HOLDERS_REMAINING" ] || HOLDERS_REMAINING=0
96
+
97
+ IS_LAST_HOLDER=true
98
+ if [ "$HOLDERS_REMAINING" -gt 0 ]; then
99
+ IS_LAST_HOLDER=false
100
+ fi
101
+
102
+ # === Auto-checkout from all checked-in tasks (last holder only) ===
103
+ # Open checkins on a shared session may belong to a still-running sibling, so a
104
+ # non-last stop must not check them out — each sub-agent checks its own task out
105
+ # per the workflow injected by on-subagent-start.sh.
58
106
  CHECKOUT_COUNT=0
59
- SESSION_DETAIL=$("$API" mcp-tool "chorus_get_session" "$(printf '{"sessionUuid":"%s"}' "$SESSION_UUID")" 2>/dev/null) || true
107
+ SESSION_DETAIL=""
108
+ CLOSE_OK=true
60
109
 
61
- if [ -n "$SESSION_DETAIL" ]; then
62
- TASK_UUIDS=$(echo "$SESSION_DETAIL" | jq -r '
63
- .checkins[]? | select(.checkoutAt == null) | .taskUuid // empty
64
- ' 2>/dev/null) || true
110
+ if [ "$IS_LAST_HOLDER" = true ]; then
111
+ SESSION_DETAIL=$("$API" mcp-tool "chorus_get_session" "$(printf '{"sessionUuid":"%s"}' "$SESSION_UUID")" 2>/dev/null) || true
65
112
 
66
- if [ -z "$TASK_UUIDS" ]; then
113
+ if [ -n "$SESSION_DETAIL" ]; then
67
114
  TASK_UUIDS=$(echo "$SESSION_DETAIL" | jq -r '
68
- .sessionTaskCheckins[]? | select(.checkoutAt == null) | .taskUuid // empty
115
+ .checkins[]? | select(.checkoutAt == null) | .taskUuid // empty
69
116
  ' 2>/dev/null) || true
70
- fi
71
117
 
72
- for TASK_UUID in $TASK_UUIDS; do
73
- if [ -n "$TASK_UUID" ]; then
74
- "$API" mcp-tool "chorus_session_checkout_task" \
75
- "$(printf '{"sessionUuid":"%s","taskUuid":"%s"}' "$SESSION_UUID" "$TASK_UUID")" \
76
- >/dev/null 2>&1 || true
77
- CHECKOUT_COUNT=$((CHECKOUT_COUNT + 1))
118
+ if [ -z "$TASK_UUIDS" ]; then
119
+ TASK_UUIDS=$(echo "$SESSION_DETAIL" | jq -r '
120
+ .sessionTaskCheckins[]? | select(.checkoutAt == null) | .taskUuid // empty
121
+ ' 2>/dev/null) || true
78
122
  fi
79
- done
80
- fi
81
123
 
82
- # Close the Chorus session via MCP
83
- CLOSE_OK=true
84
- "$API" mcp-tool "chorus_close_session" "$(printf '{"sessionUuid":"%s"}' "$SESSION_UUID")" >/dev/null 2>&1 || CLOSE_OK=false
124
+ for TASK_UUID in $TASK_UUIDS; do
125
+ if [ -n "$TASK_UUID" ]; then
126
+ "$API" mcp-tool "chorus_session_checkout_task" \
127
+ "$(printf '{"sessionUuid":"%s","taskUuid":"%s"}' "$SESSION_UUID" "$TASK_UUID")" \
128
+ >/dev/null 2>&1 || true
129
+ CHECKOUT_COUNT=$((CHECKOUT_COUNT + 1))
130
+ fi
131
+ done
132
+ fi
85
133
 
86
- # Clean up state
134
+ # Close the Chorus session via MCP
135
+ "$API" mcp-tool "chorus_close_session" "$(printf '{"sessionUuid":"%s"}' "$SESSION_UUID")" >/dev/null 2>&1 || CLOSE_OK=false
136
+ fi
137
+
138
+ # Clean up state.
139
+ # The id-keyed keys are this agent's own and always go. The name-keyed mapping and
140
+ # the reverse map agent_for_session_<uuid> (single-valued — siblings overwrite it)
141
+ # are shared, so they only go on the last-holder path.
87
142
  "$API" state-delete "session_${AGENT_ID}" 2>/dev/null || true
88
- "$API" state-delete "agent_for_session_${SESSION_UUID}" 2>/dev/null || true
89
143
  "$API" state-delete "name_for_agent_${AGENT_ID}" 2>/dev/null || true
90
- if [ -n "$AGENT_NAME" ]; then
91
- "$API" state-delete "session_${AGENT_NAME}" 2>/dev/null || true
144
+ if [ "$IS_LAST_HOLDER" = true ]; then
145
+ "$API" state-delete "agent_for_session_${SESSION_UUID}" 2>/dev/null || true
146
+ if [ -n "$AGENT_NAME" ]; then
147
+ "$API" state-delete "session_${AGENT_NAME}" 2>/dev/null || true
148
+ fi
92
149
  fi
93
150
 
94
- # Clean up session file
151
+ # Clean up session file + holder dir (last holder only — siblings still read
152
+ # sessions/<name>.json, see on-teammate-idle.sh).
95
153
  SESSIONS_DIR="${CHORUS_STATE_DIR}/sessions"
96
- if [ -n "$AGENT_NAME" ] && [ -f "${SESSIONS_DIR}/${AGENT_NAME}.json" ]; then
97
- rm -f "${SESSIONS_DIR}/${AGENT_NAME}.json"
154
+ if [ "$IS_LAST_HOLDER" = true ]; then
155
+ if [ -n "$AGENT_NAME_FILE" ] && [ -f "${SESSIONS_DIR}/${AGENT_NAME_FILE}.json" ]; then
156
+ rm -f "${SESSIONS_DIR}/${AGENT_NAME_FILE}.json"
157
+ fi
158
+ if [ -n "$HOLDERS_DIR" ] && [ -d "$HOLDERS_DIR" ]; then
159
+ rmdir "$HOLDERS_DIR" 2>/dev/null || true
160
+ fi
98
161
  fi
99
162
 
100
163
  # Clean up claimed file (written by SubagentStart)
@@ -104,7 +167,9 @@ if [ -n "$AGENT_ID" ] && [ -f "${CLAIMED_DIR}/${AGENT_ID}" ]; then
104
167
  fi
105
168
 
106
169
  # === Auto-verify: if admin marked all AC, verify the task automatically ===
107
- if [ "$CLOSE_OK" = true ] && [ -n "$SESSION_DETAIL" ]; then
170
+ # Last holder only: on a shared session the first checkin may belong to a sibling,
171
+ # so a non-last stop must never auto-verify another agent's task.
172
+ if [ "$IS_LAST_HOLDER" = true ] && [ "$CLOSE_OK" = true ] && [ -n "$SESSION_DETAIL" ]; then
108
173
  FIRST_TASK_UUID=$(echo "$SESSION_DETAIL" | jq -r '
109
174
  (.checkins // .sessionTaskCheckins // [])[] | .taskUuid // empty
110
175
  ' 2>/dev/null | head -1) || true
@@ -144,7 +209,13 @@ fi
144
209
 
145
210
  # === Output (UI-only, not visible to main agent LLM) ===
146
211
  DISPLAY_NAME="${AGENT_NAME:-${AGENT_ID:0:8}}"
147
- if [ "$CLOSE_OK" = true ]; then
212
+ if [ "$IS_LAST_HOLDER" != true ]; then
213
+ # Shared session still has live holders — do not claim it was closed.
214
+ "$API" hook-output \
215
+ "Chorus session '${DISPLAY_NAME}' kept open (${HOLDERS_REMAINING} other agent(s) still using it)" \
216
+ "" \
217
+ "SubagentStop"
218
+ elif [ "$CLOSE_OK" = true ]; then
148
219
  USER_MSG="Chorus session closed: '${DISPLAY_NAME}'"
149
220
  if [ "$CHECKOUT_COUNT" -gt 0 ]; then
150
221
  USER_MSG="${USER_MSG} (auto-checkout ${CHECKOUT_COUNT} task(s))"
@@ -0,0 +1,107 @@
1
+ #!/usr/bin/env bash
2
+ # resolve-spec-mode.sh — resolve the active Chorus spec mode for a repo.
3
+ #
4
+ # Pure (env + filesystem only; no network). Sourced by on-session-start.sh and
5
+ # driven directly by tests/test-spec-mode-resolution.sh. Bash 3.2 compatible.
6
+ #
7
+ # Inputs (env):
8
+ # CHORUS_SPEC_MODE explicit override: lite | openspec | off (else unset)
9
+ # CHORUS_OPENSPEC_MODE legacy opt-out: "off" disables OpenSpec
10
+ # CLAUDE_PLUGIN_OPTION_ENABLEOPENSPEC plugin toggle: "false" disables OpenSpec (default "true")
11
+ # PROJECT_ROOT repo root to probe for openspec/ (defaults to $PWD)
12
+ # command -v openspec OpenSpec CLI presence on PATH
13
+ #
14
+ # Outputs (vars set in the caller's shell when sourced):
15
+ # SPEC_MODE lite | openspec | off (value surfaced to Claude)
16
+ # SPEC_REASON human-readable one-liner
17
+ # SPEC_FAIL non-empty => stage skill MUST halt (unsatisfiable explicit openspec)
18
+ # OPENSPEC_USABLE 1 | 0
19
+ # OPENSPEC_USABLE_REASON human-readable
20
+ # OPENSPEC_HINT install hint when OpenSpec is merely missing (else empty)
21
+ # CHORUS_OPENSPEC_ACTIVE 1 only when the resolved mode is a USABLE openspec
22
+ #
23
+ # Resolution (per owner): an explicit CHORUS_SPEC_MODE wins; when UNSET, OpenSpec
24
+ # stays the default whenever it is usable (openspec/ dir + CLI, not disabled), and
25
+ # lite is the fallback only when OpenSpec is absent or disabled.
26
+
27
+ : "${PROJECT_ROOT:=$PWD}"
28
+
29
+ # --- Is OpenSpec usable? (needs openspec/ dir + CLI on PATH + not disabled) ---
30
+ OPENSPEC_DISABLED=0
31
+ OPENSPEC_DISABLED_REASON=""
32
+ if [ "${CLAUDE_PLUGIN_OPTION_ENABLEOPENSPEC:-true}" != "true" ]; then
33
+ OPENSPEC_DISABLED=1
34
+ OPENSPEC_DISABLED_REASON="enableOpenSpec userConfig=false (plugin-level opt-out)"
35
+ elif [ "${CHORUS_OPENSPEC_MODE:-}" = "off" ]; then
36
+ OPENSPEC_DISABLED=1
37
+ OPENSPEC_DISABLED_REASON="CHORUS_OPENSPEC_MODE=off (legacy opt-out)"
38
+ fi
39
+
40
+ OPENSPEC_USABLE=0
41
+ OPENSPEC_USABLE_REASON=""
42
+ OPENSPEC_HINT=""
43
+ if [ "$OPENSPEC_DISABLED" = "1" ]; then
44
+ OPENSPEC_USABLE_REASON="$OPENSPEC_DISABLED_REASON"
45
+ elif [ ! -d "${PROJECT_ROOT}/openspec" ]; then
46
+ OPENSPEC_USABLE_REASON="no openspec/ directory at ${PROJECT_ROOT}/openspec"
47
+ OPENSPEC_HINT="npm i -g @fission-ai/openspec && openspec init"
48
+ elif ! command -v openspec >/dev/null 2>&1; then
49
+ OPENSPEC_USABLE_REASON="openspec/ directory present but \`openspec\` CLI not on PATH"
50
+ OPENSPEC_HINT="npm i -g @fission-ai/openspec"
51
+ else
52
+ OPENSPEC_USABLE=1
53
+ OPENSPEC_USABLE_REASON="openspec/ directory + openspec CLI both present"
54
+ fi
55
+
56
+ # --- Resolve CHORUS_SPEC_MODE ---
57
+ SPEC_FAIL=""
58
+ case "${CHORUS_SPEC_MODE:-}" in
59
+ lite)
60
+ SPEC_MODE="lite"
61
+ SPEC_REASON="explicit — Chorus-native lightweight specs in .chorus/specs/<slug>/"
62
+ ;;
63
+ off)
64
+ SPEC_MODE="off"
65
+ SPEC_REASON="explicit — free-form, no spec artifact"
66
+ ;;
67
+ openspec)
68
+ SPEC_MODE="openspec"
69
+ if [ "$OPENSPEC_USABLE" = "1" ]; then
70
+ SPEC_REASON="explicit; ${OPENSPEC_USABLE_REASON}"
71
+ elif [ "$OPENSPEC_DISABLED" = "1" ]; then
72
+ SPEC_REASON="explicit, but OpenSpec is disabled: ${OPENSPEC_USABLE_REASON}"
73
+ SPEC_FAIL="config conflict — CHORUS_SPEC_MODE=openspec vs OpenSpec disabled (${OPENSPEC_USABLE_REASON}); re-enable OpenSpec or set CHORUS_SPEC_MODE=lite"
74
+ else
75
+ SPEC_REASON="explicit, but OpenSpec is not installed: ${OPENSPEC_USABLE_REASON}"
76
+ SPEC_FAIL="OpenSpec not usable (${OPENSPEC_USABLE_REASON})"
77
+ fi
78
+ ;;
79
+ "")
80
+ # Unset: OpenSpec is the default when usable; lite is the fallback otherwise.
81
+ if [ "$OPENSPEC_USABLE" = "1" ]; then
82
+ SPEC_MODE="openspec"
83
+ SPEC_REASON="default — ${OPENSPEC_USABLE_REASON}; set CHORUS_SPEC_MODE=lite for Chorus-native specs, =off to disable"
84
+ else
85
+ SPEC_MODE="lite"
86
+ SPEC_REASON="default — OpenSpec not usable (${OPENSPEC_USABLE_REASON}); using Chorus-native lightweight specs in .chorus/specs/<slug>/"
87
+ fi
88
+ ;;
89
+ *)
90
+ # Unrecognized value: treat like unset (OpenSpec-if-usable, else lite).
91
+ if [ "$OPENSPEC_USABLE" = "1" ]; then
92
+ SPEC_MODE="openspec"
93
+ SPEC_REASON="CHORUS_SPEC_MODE='${CHORUS_SPEC_MODE}' unrecognized; falling back to default (${OPENSPEC_USABLE_REASON})"
94
+ else
95
+ SPEC_MODE="lite"
96
+ SPEC_REASON="CHORUS_SPEC_MODE='${CHORUS_SPEC_MODE}' unrecognized; OpenSpec not usable, defaulting to lite"
97
+ fi
98
+ ;;
99
+ esac
100
+
101
+ # Back-compat flag for the openspec-aware skill: active only when the resolved
102
+ # mode is a USABLE openspec.
103
+ if [ "$SPEC_MODE" = "openspec" ] && [ -z "$SPEC_FAIL" ]; then
104
+ CHORUS_OPENSPEC_ACTIVE=1
105
+ else
106
+ CHORUS_OPENSPEC_ACTIVE=0
107
+ fi