@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
@@ -0,0 +1,599 @@
1
+ #!/usr/bin/env bash
2
+ # test-subagent-session-name.sh — Regression test for Claude Code sub-agent
3
+ # session NAMING (on-pre-spawn-agent.sh + on-subagent-start.sh).
4
+ #
5
+ # The defect this guards against: `tool_input.name` does not exist on CC's Task
6
+ # tool, so the name was empty at PreToolUse time, the pending filename became
7
+ # `unknown-$(date +%s%N)`, and SubagentStart used that filename as the session
8
+ # name — every sub-agent session showed up in Chorus as `unknown-<19 digits>`.
9
+ #
10
+ # The fix: the session name comes from the SubagentStart event's own
11
+ # `agent_type`, falling back to `worker-<agent_id first 8>`. The pending file is
12
+ # only a SPAWN GATE (proof the SubagentStart came from a real Task call), never a
13
+ # name channel.
14
+ #
15
+ # Harness mechanism — why we copy the hooks:
16
+ # Both hooks resolve their MCP wrapper as `API="${SCRIPT_DIR}/chorus-api.sh"`
17
+ # from `dirname "$0"`, so a PATH shim would NOT be picked up. We therefore
18
+ # COPY each hook into a sandbox dir next to a stub `chorus-api.sh` that RECORDS
19
+ # (tool, payload) pairs to a log instead of calling a server — the same
20
+ # convention as tests/test-on-post-verify-task.sh.
21
+ #
22
+ # We deliberately do NOT copy `chorus-paths.sh` into the sandbox: that file
23
+ # unconditionally recomputes CHORUS_STATE_DIR from ~/.chorus. Both hooks source
24
+ # it fail-soft (`[ -f ... ] && ...`), so with it absent they honor the
25
+ # CHORUS_STATE_DIR we export, and the test never touches the real ~/.chorus.
26
+ #
27
+ # Cases:
28
+ # 1. positive — agent_type "claude" -> session name == "claude"
29
+ # 2. fallback — empty agent_type -> name == worker-<agentId8>
30
+ # 3. no unknown-* — asserted in every case, on the session name AND on the
31
+ # pending filename
32
+ # 4. parallel batch — two same-second Task spawns of the same subagent_type
33
+ # write two DISTINCT pending files; two SubagentStart runs
34
+ # each claim one and each get its OWN event's agent_type
35
+ # as the name (FIFO mis-pairing can no longer mis-name)
36
+ # 5. gate — SubagentStart with an empty pending dir issues NO
37
+ # chorus_create_session and exits 0
38
+ # 6. skip parity — a Task spawn of a skip-listed type (chorus:task-reviewer)
39
+ # writes NO pending file, so it cannot be FIFO-claimed
40
+ # later by an unrelated agent
41
+ # 7. shared stop — TEARDOWN of a shared type-named session (on-subagent-stop.sh).
42
+ # Two same-type sub-agents reuse ONE session, so the stop
43
+ # hook refcounts holders on disk
44
+ # (<state>/holders/<sanitized name>/<agentId>): the FIRST
45
+ # exit must NOT close the session, must NOT check the
46
+ # sibling's task out, must NOT auto-verify and must leave
47
+ # session_<name> / sessions/<name>.json /
48
+ # agent_for_session_<uuid> intact; the LAST exit must tear
49
+ # everything down exactly as before.
50
+ # 8. single stop — the one-agent case is unchanged: close + full cleanup.
51
+ #
52
+ # Offline, self-contained, Bash 3.2 compatible. Run:
53
+ # /bin/bash public/chorus-plugin/bin/tests/test-subagent-session-name.sh
54
+
55
+ set -euo pipefail
56
+
57
+ REPO_ROOT="$(cd "$(dirname "$0")/../../../.." && pwd)"
58
+ PRE_SPAWN_HOOK="$REPO_ROOT/public/chorus-plugin/bin/on-pre-spawn-agent.sh"
59
+ SUBAGENT_START_HOOK="$REPO_ROOT/public/chorus-plugin/bin/on-subagent-start.sh"
60
+ SUBAGENT_STOP_HOOK="$REPO_ROOT/public/chorus-plugin/bin/on-subagent-stop.sh"
61
+
62
+ [ -f "$PRE_SPAWN_HOOK" ] || { echo "FAIL: missing $PRE_SPAWN_HOOK" >&2; exit 1; }
63
+ [ -f "$SUBAGENT_START_HOOK" ] || { echo "FAIL: missing $SUBAGENT_START_HOOK" >&2; exit 1; }
64
+ [ -f "$SUBAGENT_STOP_HOOK" ] || { echo "FAIL: missing $SUBAGENT_STOP_HOOK" >&2; exit 1; }
65
+
66
+ PASS=0
67
+ FAIL=0
68
+ FAILED=""
69
+
70
+ pass() {
71
+ echo " PASS $1"
72
+ PASS=$((PASS + 1))
73
+ }
74
+
75
+ fail() {
76
+ echo " FAIL $1: $2"
77
+ FAIL=$((FAIL + 1))
78
+ FAILED="$FAILED $1"
79
+ }
80
+
81
+ # ----- Sandbox -----
82
+
83
+ SANDBOX=$(mktemp -d)
84
+ cleanup() { rm -rf "$SANDBOX"; }
85
+ trap cleanup EXIT
86
+
87
+ HOOK_DIR="$SANDBOX/hooks"
88
+ mkdir -p "$HOOK_DIR"
89
+ cp "$PRE_SPAWN_HOOK" "$HOOK_DIR/on-pre-spawn-agent.sh"
90
+ cp "$SUBAGENT_START_HOOK" "$HOOK_DIR/on-subagent-start.sh"
91
+ cp "$SUBAGENT_STOP_HOOK" "$HOOK_DIR/on-subagent-stop.sh"
92
+ chmod +x "$HOOK_DIR/on-pre-spawn-agent.sh" "$HOOK_DIR/on-subagent-start.sh" \
93
+ "$HOOK_DIR/on-subagent-stop.sh"
94
+
95
+ # ----- Stub: chorus-api.sh -----
96
+ # Records every call as one line: <cmd>|<tool>|<payload> in $CHORUS_RECORD.
97
+ # mcp-tool chorus_list_sessions -> the sessions this sandbox has created so
98
+ # far (a per-case registry file), so
99
+ # reuse-by-name behaves like production
100
+ # mcp-tool chorus_create_session -> a fresh canned uuid, appended to the registry
101
+ # mcp-tool chorus_reopen_session -> flips registry status back to active
102
+ # mcp-tool chorus_close_session -> flips registry status to closed
103
+ # mcp-tool chorus_get_session -> $CHORUS_STUB_SESSION_JSON if set, else {}
104
+ # state-set/get/delete -> recorded AND backed by a real file store,
105
+ # so SubagentStop's state lookups resolve
106
+ # hook-output -> real jq, same JSON shape as production
107
+ cat > "$HOOK_DIR/chorus-api.sh" <<'STUB'
108
+ #!/usr/bin/env bash
109
+ set -euo pipefail
110
+ cmd="${1:-}"; shift || true
111
+ rec="${CHORUS_RECORD:-/dev/null}"
112
+ store="${CHORUS_STATE_DIR:-/tmp}/stubstate"
113
+ sessions_db="${CHORUS_STATE_DIR:-/tmp}/stub-sessions.json"
114
+ key_file() { printf '%s/%s' "$store" "$(printf '%s' "$1" | tr -c '[:alnum:]._-' '_')"; }
115
+ case "$cmd" in
116
+ mcp-tool)
117
+ tool="${1:-}"; payload="${2:-}"
118
+ printf 'mcp-tool|%s|%s\n' "$tool" "$payload" >> "$rec"
119
+ [ -f "$sessions_db" ] || echo '[]' > "$sessions_db"
120
+ case "$tool" in
121
+ chorus_list_sessions)
122
+ jq -c '{sessions: ., total: length}' "$sessions_db"
123
+ ;;
124
+ chorus_create_session)
125
+ nm=$(printf '%s' "$payload" | jq -r '.name // empty')
126
+ n=$(jq 'length' "$sessions_db")
127
+ uuid=$(printf '11111111-2222-3333-4444-%012d' "$((n + 1))")
128
+ tmp=$(mktemp)
129
+ jq --arg u "$uuid" --arg n "$nm" '. + [{uuid:$u, name:$n, status:"active"}]' \
130
+ "$sessions_db" > "$tmp" && mv "$tmp" "$sessions_db"
131
+ jq -n --arg u "$uuid" --arg n "$nm" '{uuid:$u, name:$n}'
132
+ ;;
133
+ chorus_reopen_session)
134
+ u=$(printf '%s' "$payload" | jq -r '.sessionUuid // empty')
135
+ tmp=$(mktemp)
136
+ jq --arg u "$u" 'map(if .uuid == $u then .status = "active" else . end)' \
137
+ "$sessions_db" > "$tmp" && mv "$tmp" "$sessions_db"
138
+ jq -n --arg u "$u" '{uuid:$u}'
139
+ ;;
140
+ chorus_close_session)
141
+ u=$(printf '%s' "$payload" | jq -r '.sessionUuid // empty')
142
+ tmp=$(mktemp)
143
+ jq --arg u "$u" 'map(if .uuid == $u then .status = "closed" else . end)' \
144
+ "$sessions_db" > "$tmp" && mv "$tmp" "$sessions_db"
145
+ echo '{}'
146
+ ;;
147
+ chorus_get_session)
148
+ if [ -n "${CHORUS_STUB_SESSION_JSON:-}" ] && [ -f "${CHORUS_STUB_SESSION_JSON}" ]; then
149
+ cat "${CHORUS_STUB_SESSION_JSON}"
150
+ else
151
+ echo '{}'
152
+ fi
153
+ ;;
154
+ *) echo '{}' ;;
155
+ esac
156
+ ;;
157
+ state-set)
158
+ printf 'state-set|%s|%s\n' "${1:-}" "${2:-}" >> "$rec"
159
+ mkdir -p "$store" 2>/dev/null || true
160
+ printf '%s' "${2:-}" > "$(key_file "${1:-}")"
161
+ ;;
162
+ state-get)
163
+ printf 'state-get|%s|\n' "${1:-}" >> "$rec"
164
+ f="$(key_file "${1:-}")"
165
+ if [ -f "$f" ]; then cat "$f"; else echo ""; fi
166
+ ;;
167
+ state-delete)
168
+ printf 'state-delete|%s|\n' "${1:-}" >> "$rec"
169
+ rm -f "$(key_file "${1:-}")" 2>/dev/null || true
170
+ ;;
171
+ hook-output)
172
+ sm="${1:-}"; ac="${2:-}"; hen="${3:-}"
173
+ printf 'hook-output|%s|%s\n' "$hen" "$sm" >> "$rec"
174
+ if [ -n "$ac" ]; then
175
+ jq -n --arg sm "$sm" --arg ac "$ac" --arg hen "$hen" \
176
+ '{systemMessage:$sm, hookSpecificOutput:{hookEventName:$hen, additionalContext:$ac}}'
177
+ else
178
+ jq -n --arg sm "$sm" '{systemMessage:$sm}'
179
+ fi
180
+ ;;
181
+ *)
182
+ echo "stub chorus-api.sh: unknown cmd $cmd" >&2; exit 2 ;;
183
+ esac
184
+ STUB
185
+ chmod +x "$HOOK_DIR/chorus-api.sh"
186
+
187
+ # ----- Per-case state -----
188
+
189
+ STATE_DIR=""
190
+ RECORD=""
191
+ LAST_RC=0
192
+ LAST_STDERR=""
193
+ STUB_SESSION_JSON=""
194
+
195
+ new_case() {
196
+ # $1 = case slug
197
+ STATE_DIR="$SANDBOX/state/$1"
198
+ RECORD="$SANDBOX/rec/$1.log"
199
+ mkdir -p "$STATE_DIR" "$SANDBOX/rec"
200
+ : > "$RECORD"
201
+ STUB_SESSION_JSON=""
202
+ }
203
+
204
+ # Start a fresh recording window inside the current case, so an assertion can
205
+ # say "this hook run issued no chorus_close_session" without earlier runs' calls
206
+ # leaking in. State and the session registry are untouched.
207
+ rec_reset() { : > "$RECORD"; }
208
+
209
+ # run_hook <hook-file> <event-json>
210
+ run_hook() {
211
+ local hook="$1"
212
+ local event="$2"
213
+ local err
214
+ err=$(mktemp)
215
+ LAST_RC=0
216
+ printf '%s' "$event" \
217
+ | env -i \
218
+ HOME="$SANDBOX/home" \
219
+ PATH="$PATH" \
220
+ CHORUS_URL="http://127.0.0.1:0" \
221
+ CHORUS_API_KEY="cho_test" \
222
+ CHORUS_STATE_DIR="$STATE_DIR" \
223
+ CHORUS_RECORD="$RECORD" \
224
+ CHORUS_STUB_SESSION_JSON="$STUB_SESSION_JSON" \
225
+ CLAUDE_PROJECT_DIR="$SANDBOX/project" \
226
+ /bin/bash "$HOOK_DIR/$hook" >/dev/null 2>"$err" || LAST_RC=$?
227
+ LAST_STDERR=$(cat "$err")
228
+ rm -f "$err"
229
+ }
230
+
231
+ pre_spawn() {
232
+ # $1 = subagent_type
233
+ run_hook "on-pre-spawn-agent.sh" \
234
+ "$(printf '{"session_id":"cc-sess-1","tool_name":"Task","tool_input":{"subagent_type":"%s","description":"do work","prompt":"go"}}' "$1")"
235
+ }
236
+
237
+ subagent_start() {
238
+ # $1 = agent_id, $2 = agent_type (may be empty)
239
+ run_hook "on-subagent-start.sh" \
240
+ "$(printf '{"session_id":"cc-sess-1","agent_id":"%s","agent_type":"%s"}' "$1" "$2")"
241
+ }
242
+
243
+ subagent_stop() {
244
+ # $1 = agent_id
245
+ run_hook "on-subagent-stop.sh" \
246
+ "$(printf '{"session_id":"cc-sess-1","agent_id":"%s"}' "$1")"
247
+ }
248
+
249
+ # How many times a given MCP tool was called in the current recording window.
250
+ tool_count() {
251
+ grep -c "^mcp-tool|$1|" "$RECORD" 2>/dev/null || true
252
+ }
253
+
254
+ # Stub state store introspection (same key sanitization as the stub).
255
+ state_key_file() {
256
+ printf '%s/stubstate/%s' "$STATE_DIR" "$(printf '%s' "$1" | tr -c '[:alnum:]._-' '_')"
257
+ }
258
+
259
+ state_has() {
260
+ [ -f "$(state_key_file "$1")" ]
261
+ }
262
+
263
+ state_val() {
264
+ cat "$(state_key_file "$1")" 2>/dev/null || true
265
+ }
266
+
267
+ holder_count() {
268
+ # $1 = sanitized session name
269
+ ls -1 "$STATE_DIR/holders/$1" 2>/dev/null | grep -c . || true
270
+ }
271
+
272
+ pending_count() {
273
+ ls -1 "$STATE_DIR/pending" 2>/dev/null | grep -c . || true
274
+ }
275
+
276
+ pending_names() {
277
+ ls -1 "$STATE_DIR/pending" 2>/dev/null || true
278
+ }
279
+
280
+ # All names passed to chorus_create_session, one per line, in call order.
281
+ created_names() {
282
+ grep '^mcp-tool|chorus_create_session|' "$RECORD" 2>/dev/null \
283
+ | sed 's/^mcp-tool|chorus_create_session|//' \
284
+ | while IFS= read -r payload; do
285
+ printf '%s' "$payload" | jq -r '.name // empty'
286
+ done
287
+ }
288
+
289
+ created_count() {
290
+ grep -c '^mcp-tool|chorus_create_session|' "$RECORD" 2>/dev/null || true
291
+ }
292
+
293
+ # Guard used by every case: a name must never look like the pre-fix placeholder.
294
+ assert_not_unknown() {
295
+ # $1 = case name, $2 = label, $3 = value
296
+ case "$3" in
297
+ unknown-*)
298
+ fail "$1" "$2 is the pre-fix placeholder shape 'unknown-*' (got '$3')"
299
+ return 1
300
+ ;;
301
+ esac
302
+ return 0
303
+ }
304
+
305
+ echo "Sandbox: $SANDBOX"
306
+ echo ""
307
+
308
+ # ===== Case 1: positive — session name == event agent_type =====
309
+ new_case "positive"
310
+ pre_spawn "claude"
311
+ if [ "$LAST_RC" -ne 0 ]; then
312
+ fail "positive" "on-pre-spawn-agent.sh exited $LAST_RC: $LAST_STDERR"
313
+ else
314
+ pending="$(pending_names)"
315
+ if ! assert_not_unknown "positive-pending-filename" "pending filename" "$pending"; then
316
+ :
317
+ else
318
+ pass "positive-pending-filename (no unknown-* filename: '$pending')"
319
+ fi
320
+
321
+ subagent_start "agentid00deadbeef" "claude"
322
+ if [ "$LAST_RC" -ne 0 ]; then
323
+ fail "positive" "on-subagent-start.sh exited $LAST_RC: $LAST_STDERR"
324
+ else
325
+ name="$(created_names)"
326
+ if [ "$name" != "claude" ]; then
327
+ fail "positive" "expected chorus_create_session name 'claude', got '$name'"
328
+ elif ! assert_not_unknown "positive" "session name" "$name"; then
329
+ :
330
+ else
331
+ pass "positive (session name == event agent_type 'claude')"
332
+ fi
333
+ fi
334
+ fi
335
+
336
+ # ===== Case 2: fallback — empty agent_type -> worker-<agentId first 8> =====
337
+ # The pending file is written by a normal "claude" spawn; the SubagentStart event
338
+ # then arrives with an EMPTY agent_type. The name must be derived from agent_id,
339
+ # never from the pending file's name/filename.
340
+ new_case "fallback"
341
+ pre_spawn "claude"
342
+ if [ "$LAST_RC" -ne 0 ]; then
343
+ fail "fallback" "on-pre-spawn-agent.sh exited $LAST_RC: $LAST_STDERR"
344
+ else
345
+ subagent_start "abcdef1234567890" ""
346
+ if [ "$LAST_RC" -ne 0 ]; then
347
+ fail "fallback" "on-subagent-start.sh exited $LAST_RC: $LAST_STDERR"
348
+ else
349
+ name="$(created_names)"
350
+ if [ "$name" != "worker-abcdef12" ]; then
351
+ fail "fallback" "expected name 'worker-abcdef12' (worker- + agent_id first 8), got '$name'"
352
+ elif ! assert_not_unknown "fallback" "session name" "$name"; then
353
+ :
354
+ else
355
+ pass "fallback (empty agent_type -> 'worker-abcdef12')"
356
+ fi
357
+ fi
358
+ fi
359
+
360
+ # ===== Case 3: parallel batch — two same-second spawns of the SAME type =====
361
+ # Two PreToolUse:Task invocations of "claude" within the same second must produce
362
+ # two DISTINCT pending files (BSD date has no %N, so uniqueness comes from $$).
363
+ # Then two SubagentStart events — deliberately of DIFFERENT types — each claim
364
+ # one file FIFO and each must be named after their OWN event's agent_type, which
365
+ # is what makes plain FIFO claiming safe in a mixed batch.
366
+ new_case "parallel"
367
+ pre_spawn "claude"
368
+ rc1=$LAST_RC
369
+ pre_spawn "claude"
370
+ rc2=$LAST_RC
371
+ if [ "$rc1" -ne 0 ] || [ "$rc2" -ne 0 ]; then
372
+ fail "parallel-distinct-pending" "on-pre-spawn-agent.sh exited $rc1/$rc2: $LAST_STDERR"
373
+ else
374
+ n="$(pending_count)"
375
+ if [ "$n" != "2" ]; then
376
+ fail "parallel-distinct-pending" "expected 2 distinct pending files from 2 same-second spawns of the same type, got $n: $(pending_names | tr '\n' ' ')"
377
+ else
378
+ bad=0
379
+ for f in $(pending_names); do
380
+ assert_not_unknown "parallel-distinct-pending" "pending filename" "$f" || bad=1
381
+ done
382
+ [ "$bad" -eq 0 ] && pass "parallel-distinct-pending (2 distinct non-unknown pending files)"
383
+ fi
384
+
385
+ subagent_start "aaaaaaaa11112222" "claude"
386
+ rc1=$LAST_RC
387
+ subagent_start "bbbbbbbb33334444" "general-purpose"
388
+ rc2=$LAST_RC
389
+ if [ "$rc1" -ne 0 ] || [ "$rc2" -ne 0 ]; then
390
+ fail "parallel-names" "on-subagent-start.sh exited $rc1/$rc2: $LAST_STDERR"
391
+ else
392
+ names="$(created_names | tr '\n' ',')"
393
+ if [ "$names" != "claude,general-purpose," ]; then
394
+ fail "parallel-names" "expected each session named after its OWN event agent_type ('claude','general-purpose'), got '$names'"
395
+ else
396
+ pass "parallel-names (each spawn named from its own event agent_type)"
397
+ fi
398
+ if [ "$(pending_count)" != "0" ]; then
399
+ fail "parallel-claimed" "expected both pending files claimed, still pending: $(pending_names | tr '\n' ' ')"
400
+ else
401
+ pass "parallel-claimed (both pending files claimed exactly once)"
402
+ fi
403
+ fi
404
+ fi
405
+
406
+ # ===== Case 4: gate — empty pending dir -> no session, exit 0 =====
407
+ new_case "gate"
408
+ mkdir -p "$STATE_DIR/pending"
409
+ subagent_start "cccccccc55556666" "claude"
410
+ if [ "$LAST_RC" -ne 0 ]; then
411
+ fail "gate" "expected exit 0 with an empty pending dir, got $LAST_RC: $LAST_STDERR"
412
+ elif [ "$(created_count)" != "0" ]; then
413
+ fail "gate" "expected NO chorus_create_session with an empty pending dir, got $(created_count): $(created_names | tr '\n' ' ')"
414
+ else
415
+ pass "gate (empty pending dir -> no session created, exit 0)"
416
+ fi
417
+
418
+ # ===== Case 5: skip-list parity — skipped type writes no pending file =====
419
+ # on-subagent-start.sh exits early on chorus:task-reviewer, so
420
+ # on-pre-spawn-agent.sh must not leave a pending file for it — otherwise that
421
+ # orphan could be FIFO-claimed by an unrelated internal agent, defeating the gate.
422
+ new_case "skip-parity"
423
+ pre_spawn "chorus:task-reviewer"
424
+ if [ "$LAST_RC" -ne 0 ]; then
425
+ fail "skip-parity" "on-pre-spawn-agent.sh exited $LAST_RC: $LAST_STDERR"
426
+ elif [ "$(pending_count)" != "0" ]; then
427
+ fail "skip-parity" "skip-listed type left an orphan pending file: $(pending_names | tr '\n' ' ')"
428
+ else
429
+ pass "skip-parity (chorus:task-reviewer leaves no pending file)"
430
+ fi
431
+
432
+ # ===== Case 6: same-type parallel — FIRST stop must NOT tear down the session ==
433
+ # Two "claude" sub-agents run in parallel. Because the session name is the
434
+ # repeating agent_type, the second SubagentStart reuses the FIRST one's session,
435
+ # so ONE session row has TWO holders. When the first sibling exits, the stop hook
436
+ # must leave everything the surviving sibling depends on alone.
437
+ SHARED_A="aaaa000011112222"
438
+ SHARED_B="bbbb000033334444"
439
+
440
+ new_case "shared-stop"
441
+ printf '%s\n' \
442
+ '{"checkins":[{"taskUuid":"task-of-a","checkoutAt":null},{"taskUuid":"task-of-b","checkoutAt":null}]}' \
443
+ > "$STATE_DIR/session-detail.json"
444
+ STUB_SESSION_JSON="$STATE_DIR/session-detail.json"
445
+
446
+ pre_spawn "claude"; rc1=$LAST_RC
447
+ pre_spawn "claude"; rc2=$LAST_RC
448
+ subagent_start "$SHARED_A" "claude"; rc3=$LAST_RC
449
+ subagent_start "$SHARED_B" "claude"; rc4=$LAST_RC
450
+
451
+ if [ "$rc1" -ne 0 ] || [ "$rc2" -ne 0 ] || [ "$rc3" -ne 0 ] || [ "$rc4" -ne 0 ]; then
452
+ fail "shared-stop-setup" "setup hooks exited $rc1/$rc2/$rc3/$rc4: $LAST_STDERR"
453
+ else
454
+ SHARED_UUID="$(state_val "session_claude")"
455
+ if [ "$(created_count)" != "1" ]; then
456
+ fail "shared-stop-setup" "expected the 2nd same-type start to REUSE one session (1 create), got $(created_count) creates"
457
+ elif [ -z "$SHARED_UUID" ]; then
458
+ fail "shared-stop-setup" "no shared session uuid in state key session_claude"
459
+ elif [ "$(holder_count claude)" != "2" ]; then
460
+ fail "shared-stop-holders" "expected 2 holder entries in holders/claude, got $(holder_count claude): $(ls -1 "$STATE_DIR/holders/claude" 2>/dev/null | tr '\n' ' ')"
461
+ else
462
+ pass "shared-stop-holders (2 same-type starts share 1 session and register 2 holders)"
463
+ fi
464
+
465
+ # --- first sibling exits ---
466
+ rec_reset
467
+ subagent_stop "$SHARED_A"
468
+ if [ "$LAST_RC" -ne 0 ]; then
469
+ fail "shared-stop-first" "on-subagent-stop.sh exited $LAST_RC: $LAST_STDERR"
470
+ else
471
+ bad=""
472
+ [ "$(tool_count chorus_close_session)" = "0" ] \
473
+ || bad="$bad closed-the-shared-session"
474
+ [ "$(tool_count chorus_session_checkout_task)" = "0" ] \
475
+ || bad="$bad checked-out-a-siblings-task"
476
+ [ "$(tool_count chorus_get_task)" = "0" ] \
477
+ || bad="$bad ran-the-auto-verify-block"
478
+ [ -f "$STATE_DIR/sessions/claude.json" ] \
479
+ || bad="$bad removed-sessions/claude.json"
480
+ state_has "session_claude" \
481
+ || bad="$bad deleted-name-keyed-state"
482
+ state_has "agent_for_session_${SHARED_UUID}" \
483
+ || bad="$bad deleted-reverse-map-agent_for_session"
484
+ state_has "session_${SHARED_B}" \
485
+ || bad="$bad deleted-siblings-session_<agentId>"
486
+ [ "$(holder_count claude)" = "1" ] \
487
+ || bad="$bad holder-count-not-1-after-own-entry-removed"
488
+ if state_has "session_${SHARED_A}" || state_has "name_for_agent_${SHARED_A}"; then
489
+ bad="$bad kept-own-id-keyed-state"
490
+ fi
491
+ [ -f "$STATE_DIR/claimed/${SHARED_A}" ] && bad="$bad kept-own-claimed-file" || true
492
+ if [ -n "$bad" ]; then
493
+ fail "shared-stop-first" "first stop of a shared session:$bad"
494
+ else
495
+ pass "shared-stop-first (no close/checkout/auto-verify; shared state + sessions/claude.json intact; own state gone)"
496
+ fi
497
+ fi
498
+
499
+ # --- last sibling exits: full teardown, exactly as the single-agent case ---
500
+ rec_reset
501
+ subagent_stop "$SHARED_B"
502
+ if [ "$LAST_RC" -ne 0 ]; then
503
+ fail "shared-stop-last" "on-subagent-stop.sh exited $LAST_RC: $LAST_STDERR"
504
+ else
505
+ bad=""
506
+ [ "$(tool_count chorus_close_session)" = "1" ] \
507
+ || bad="$bad close_session-calls=$(tool_count chorus_close_session)"
508
+ [ "$(tool_count chorus_session_checkout_task)" = "2" ] \
509
+ || bad="$bad checkout-calls=$(tool_count chorus_session_checkout_task)(expected both open checkins)"
510
+ [ "$(tool_count chorus_get_task)" -ge 1 ] 2>/dev/null \
511
+ || bad="$bad auto-verify-block-did-not-run"
512
+ [ -f "$STATE_DIR/sessions/claude.json" ] && bad="$bad sessions/claude.json-not-removed" || true
513
+ [ -d "$STATE_DIR/holders/claude" ] && bad="$bad holder-dir-not-removed" || true
514
+ state_has "session_claude" && bad="$bad session_<name>-not-deleted" || true
515
+ state_has "agent_for_session_${SHARED_UUID}" && bad="$bad agent_for_session-not-deleted" || true
516
+ state_has "session_${SHARED_B}" && bad="$bad session_<agentId>-not-deleted" || true
517
+ state_has "name_for_agent_${SHARED_B}" && bad="$bad name_for_agent-not-deleted" || true
518
+ [ -f "$STATE_DIR/claimed/${SHARED_B}" ] && bad="$bad claimed-file-not-removed" || true
519
+ if [ -n "$bad" ]; then
520
+ fail "shared-stop-last" "last stop of a shared session:$bad"
521
+ else
522
+ pass "shared-stop-last (close + auto-checkout of both checkins + all 4 state keys, session file, holder dir and claimed file removed)"
523
+ fi
524
+ fi
525
+ fi
526
+
527
+ # ===== Case 7: single agent — teardown on its only stop is unchanged =====
528
+ new_case "single-stop"
529
+ printf '%s\n' '{"checkins":[{"taskUuid":"task-solo","checkoutAt":null}]}' \
530
+ > "$STATE_DIR/session-detail.json"
531
+ STUB_SESSION_JSON="$STATE_DIR/session-detail.json"
532
+ SOLO="dddd000077778888"
533
+
534
+ pre_spawn "claude"; rc1=$LAST_RC
535
+ subagent_start "$SOLO" "claude"; rc2=$LAST_RC
536
+ if [ "$rc1" -ne 0 ] || [ "$rc2" -ne 0 ]; then
537
+ fail "single-stop-setup" "setup hooks exited $rc1/$rc2: $LAST_STDERR"
538
+ else
539
+ SOLO_UUID="$(state_val "session_claude")"
540
+ rec_reset
541
+ subagent_stop "$SOLO"
542
+ if [ "$LAST_RC" -ne 0 ]; then
543
+ fail "single-stop" "on-subagent-stop.sh exited $LAST_RC: $LAST_STDERR"
544
+ else
545
+ bad=""
546
+ [ "$(tool_count chorus_close_session)" = "1" ] \
547
+ || bad="$bad close_session-calls=$(tool_count chorus_close_session)"
548
+ [ "$(tool_count chorus_session_checkout_task)" = "1" ] \
549
+ || bad="$bad checkout-calls=$(tool_count chorus_session_checkout_task)"
550
+ [ -f "$STATE_DIR/sessions/claude.json" ] && bad="$bad session-file-not-removed" || true
551
+ [ -d "$STATE_DIR/holders/claude" ] && bad="$bad holder-dir-not-removed" || true
552
+ state_has "session_claude" && bad="$bad session_<name>-not-deleted" || true
553
+ state_has "agent_for_session_${SOLO_UUID}" && bad="$bad agent_for_session-not-deleted" || true
554
+ state_has "session_${SOLO}" && bad="$bad session_<agentId>-not-deleted" || true
555
+ state_has "name_for_agent_${SOLO}" && bad="$bad name_for_agent-not-deleted" || true
556
+ [ -f "$STATE_DIR/claimed/${SOLO}" ] && bad="$bad claimed-file-not-removed" || true
557
+ if [ -n "$bad" ]; then
558
+ fail "single-stop" "single-agent stop regressed:$bad"
559
+ else
560
+ pass "single-stop (only holder -> close + full cleanup, unchanged behaviour)"
561
+ fi
562
+ fi
563
+ fi
564
+
565
+ # ===== Case 8: no unknown-* anywhere across all cases =====
566
+ # Belt-and-braces sweep: no session name recorded by ANY case may match
567
+ # unknown-*, and no pending filename left behind may either. (We match on the
568
+ # `name` field only — the create description legitimately contains
569
+ # "type: unknown" for the empty-agent_type fallback.)
570
+ sweep_bad=""
571
+ for rec in "$SANDBOX"/rec/*.log; do
572
+ [ -f "$rec" ] || continue
573
+ while IFS= read -r payload; do
574
+ [ -n "$payload" ] || continue
575
+ nm=$(printf '%s' "$payload" | jq -r '.name // empty')
576
+ case "$nm" in
577
+ unknown-*) sweep_bad="$sweep_bad $(basename "$rec"):$nm" ;;
578
+ esac
579
+ done <<SWEEP
580
+ $(grep '^mcp-tool|chorus_create_session|' "$rec" 2>/dev/null | sed 's/^mcp-tool|chorus_create_session|//')
581
+ SWEEP
582
+ done
583
+ for f in $(find "$SANDBOX/state" -type f -name 'unknown-*' 2>/dev/null); do
584
+ sweep_bad="$sweep_bad file:$f"
585
+ done
586
+ if [ -n "$sweep_bad" ]; then
587
+ fail "no-unknown-sweep" "found pre-fix 'unknown-*' artifacts:$sweep_bad"
588
+ else
589
+ pass "no-unknown-sweep (no unknown-* session name or pending filename anywhere)"
590
+ fi
591
+
592
+ echo ""
593
+ echo "Results: $PASS passed, $FAIL failed"
594
+
595
+ if [ "$FAIL" -gt 0 ]; then
596
+ echo "Failed:$FAILED"
597
+ exit 1
598
+ fi
599
+ exit 0
@@ -4,7 +4,7 @@ description: Optional divergent-then-convergent dialogue for fuzzy ideas. Invoke
4
4
  license: AGPL-3.0
5
5
  metadata:
6
6
  author: chorus
7
- version: "0.17.3"
7
+ version: "0.18.1"
8
8
  category: project-management
9
9
  mcp_server: chorus
10
10
  ---
@@ -4,7 +4,7 @@ description: Chorus AI Agent collaboration platform — overview, common tools,
4
4
  license: AGPL-3.0
5
5
  metadata:
6
6
  author: chorus
7
- version: "0.17.3"
7
+ version: "0.18.1"
8
8
  category: project-management
9
9
  mcp_server: chorus
10
10
  ---
@@ -344,9 +344,13 @@ To disable, reconfigure the plugin via `/plugin` settings or manually edit `~/.c
344
344
 
345
345
  When enabled, reviewers run as read-only sub-agents and post a VERDICT comment on the proposal/task/idea. Three possible outcomes: **PASS** (no issues), **PASS WITH NOTES** (minor non-blocking notes), or **FAIL** (BLOCKERs found). Results are advisory — they do not block approval, verification, or ship; the code-review gateway in particular is behavioral (it does not change the Idea's stored status). On a code-review FAIL, fix it via the `/chorus:quick-dev` workflow: `chorus_create_tasks` with `proposalUuid` set to the current approved proposal so the fix tasks attach to it. Group related small BLOCKERs into one cohesive task by default; split only materially large or independently testable fixes. Each fix task must self-check its acceptance criteria and pass independent task review plus admin verification. Re-run the gateway only after every fix task is successfully `done`; if there is a failed or cancelled fix task, stop and escalate instead. Disabling reduces token usage but removes the independent quality gate.
346
346
 
347
- ### 6. Enable OpenSpec Mode (Optional)
347
+ **First-principles alignment (a stage-tailored instruction in all three reviewers).** Each reviewer also checks, top-down, that the work still serves the *original Idea's intent*. It resolves the Idea from the entity under review (proposal-reviewer → the proposal's `inputUuids[0]`; task-reviewer → its proposal's `inputUuids[0]`; code-reviewer → the given `ideaUuid`), reads it with the existing `chorus_get_idea` + `chorus_get_elaboration` + `chorus_get_comments`, and builds the intent **baseline** from **human input only** — the Idea content + elaboration answers where `answeredBy.type == "user"` + comments where `author.type == "user"`. Agent-answered elaboration and agent-authored comments are audit context only: they cannot expand, shrink, or override the baseline. It flags **scope creep** (work beyond intent), **requirement loss / shrink** (intent dropped or reduced), or **semantic drift** (passes AC but misses the point). Unauthorized drift is a **BLOCKER → VERDICT: FAIL / reject**, downgraded to a cited `NOTE` only when traceable to a **human** authorization: a human-authored Idea comment (`author.type == "user"`), a human-answered elaboration entry (`answeredBy.type == "user"`), or an explicit human override at the gate. **An agent's own comment never authorizes**, so a drifting agent cannot self-clear. The alignment finding folds into the existing VERDICT; the dimension is skipped when the entity has no attached Idea.
348
348
 
349
- Opt-in spec-driven path: `/proposal`, `/develop`, `/yolo` write `proposal.md` / `design.md` / spec deltas on disk and mirror them into Chorus drafts. Fully optional — free-form authoring works without it. Activates only when all three hold: the `enableOpenSpec` toggle is on (default) and `CHORUS_OPENSPEC_MODE` ≠ `off`, an `openspec/` directory exists at the project root, and the `openspec` CLI is on `PATH`.
349
+ ### 6. Spec mode: OpenSpec (default when usable) vs spec-lite (fallback)
350
+
351
+ The SessionStart hook resolves one **spec mode** per session and prints a `## Spec Mode` section stating it. Resolution: an explicit `CHORUS_SPEC_MODE` (`lite`/`openspec`/`off`) wins; when unset, **OpenSpec is the default whenever it is usable** — the `enableOpenSpec` toggle on (default) and `CHORUS_OPENSPEC_MODE` ≠ `off`, an `openspec/` directory at the project root, and the `openspec` CLI on `PATH`. When OpenSpec is absent or disabled, the mode falls back to **spec-lite** — a Chorus-native, git-tracked model: a durable local spec `.chorus/specs/<slug>/spec.md` per capability (edited in place, **never synced** to Chorus), plus one dated folder per change effort `.chorus/specs/<slug>/<YYYY-MM-DD>-<change-slug>/` of plain-markdown docs named by Document type (`prd.md`, `tech_design.md`, …), each of those dated-folder docs mirrored 1:1 into a persistent Chorus Document (see the `spec-lite` skill). `CHORUS_SPEC_MODE=off` selects free-form (no spec artifact).
352
+
353
+ OpenSpec spec-driven path: `/proposal`, `/develop`, `/yolo` write `proposal.md` / `design.md` / spec deltas on disk and mirror them into Chorus drafts.
350
354
 
351
355
  **When the user wants it on** (e.g. they ran `/chorus enable openspec` after the `(OpenSpec off — …)` banner), actually **enable it for them** — run whichever steps are missing, don't just describe them:
352
356
 
@@ -355,9 +359,9 @@ npm i -g @fission-ai/openspec # 1. install the CLI if it's not on PATH (gl
355
359
  openspec init --tools claude # 2. scaffold openspec/ + wire up Claude Code's native commands/skills
356
360
  ```
357
361
 
358
- `openspec init` is interactive if you omit `--tools`; pass `--tools claude` to run it unattended. Chorus's detection only needs the `openspec/` directory, but wiring up Claude Code also gives OpenSpec its own commands + skills. The OpenSpec signal is read **once at SessionStart**, so it can't flip mid-session — after the steps succeed, tell the user to **re-launch the session**; the banner then reads `(OpenSpec Enabled)` and the stage skills fold in the `openspec-aware` skill automatically.
362
+ `openspec init` is interactive if you omit `--tools`; pass `--tools claude` to run it unattended. Chorus's detection only needs the `openspec/` directory, but wiring up Claude Code also gives OpenSpec its own commands + skills. The spec mode is resolved **once at SessionStart**, so it can't flip mid-session — after the steps succeed, tell the user to **re-launch the session**; the `## Spec Mode` section then reads `CHORUS_SPEC_MODE=openspec (…)` and the stage skills fold in the `openspec-aware` skill automatically.
359
363
 
360
- To turn it off, flip `enableOpenSpec` to `false` or set `CHORUS_OPENSPEC_MODE=off` — the banner then reads a neutral `(OpenSpec off)`.
364
+ To turn OpenSpec off, flip `enableOpenSpec` to `false` or set `CHORUS_OPENSPEC_MODE=off` — the mode then falls back to **spec-lite** (or set `CHORUS_SPEC_MODE=off` for free-form). The `## Spec Mode` section always states the resolved mode + reason.
361
365
 
362
366
  ### 7. Daemon auto-start via `chorus agents add`
363
367
 
@@ -438,7 +442,8 @@ This is the core overview skill. For stage-specific workflows, use:
438
442
  | **Development** | `/develop` | Claim Tasks, report work, session & sub-agent management, Agent Teams integration |
439
443
  | **Review** | `/review` | Approve/reject Proposals, verify Tasks, project governance |
440
444
  | **Docs** | `/docs` | Consult the live Chorus documentation site to answer product-usage questions — UI workflow, agent/plugin setup, API/MCP, deployment, operations |
441
- | **OpenSpec mode** | `openspec-aware` | Opt-in **shared sub-procedure** invoked by `/proposal`, `/develop`, and `/yolo` whenever the user has the `openspec` CLI installed. Scaffolds `openspec/changes/<slug>/` on disk and mirrors files into Chorus document drafts via the `chorus-api.sh` wrapper. Skips silently in fallback mode. See `.claude/skills/openspec-aware/SKILL.md`. |
445
+ | **OpenSpec mode** | `openspec-aware` | **Shared sub-procedure** invoked by `/proposal`, `/develop`, and `/yolo` when the resolved spec mode is a usable OpenSpec (the default when `openspec/` + CLI present and not disabled). Scaffolds `openspec/changes/<slug>/` on disk and mirrors files into Chorus document drafts via the `chorus-api.sh` wrapper. No-op when the mode isn't a usable OpenSpec. See `.claude/skills/openspec-aware/SKILL.md`. |
446
+ | **spec-lite mode** | `spec-lite` | **Shared sub-procedure** and the fallback when OpenSpec isn't usable (or `CHORUS_SPEC_MODE=lite`). Durable local `.chorus/specs/<slug>/spec.md` (never synced) + dated per-change folders of Chorus-typed docs mirrored 1:1 into Chorus via `--arg-file`. No CLI/validation/archive. See `.claude/skills/spec-lite/SKILL.md`. |
442
447
 
443
448
  ### Getting Started
444
449
 
@@ -4,7 +4,7 @@ description: How to install, configure, and use the `chorus` CLI — install it,
4
4
  license: AGPL-3.0
5
5
  metadata:
6
6
  author: chorus
7
- version: "0.17.3"
7
+ version: "0.18.1"
8
8
  category: project-management
9
9
  mcp_server: chorus
10
10
  ---