@cleocode/core 2026.3.74 → 2026.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (428) hide show
  1. package/README.md +1 -1
  2. package/dist/agents/agent-schema.d.ts.map +1 -1
  3. package/dist/agents/retry.js +26 -21
  4. package/dist/agents/retry.js.map +1 -1
  5. package/dist/cant/approval.d.ts +110 -0
  6. package/dist/cant/approval.d.ts.map +1 -0
  7. package/dist/cant/approval.js +185 -0
  8. package/dist/cant/approval.js.map +1 -0
  9. package/dist/cant/context-builder.d.ts +79 -0
  10. package/dist/cant/context-builder.d.ts.map +1 -0
  11. package/dist/cant/context-builder.js +117 -0
  12. package/dist/cant/context-builder.js.map +1 -0
  13. package/dist/cant/discretion.d.ts +95 -0
  14. package/dist/cant/discretion.d.ts.map +1 -0
  15. package/dist/cant/discretion.js +116 -0
  16. package/dist/cant/discretion.js.map +1 -0
  17. package/dist/cant/index.d.ts +25 -0
  18. package/dist/cant/index.d.ts.map +1 -0
  19. package/dist/cant/index.js +23 -0
  20. package/dist/cant/index.js.map +1 -0
  21. package/dist/cant/parallel-runner.d.ts +38 -0
  22. package/dist/cant/parallel-runner.d.ts.map +1 -0
  23. package/dist/cant/parallel-runner.js +173 -0
  24. package/dist/cant/parallel-runner.js.map +1 -0
  25. package/dist/cant/types.d.ts +127 -0
  26. package/dist/cant/types.d.ts.map +1 -0
  27. package/dist/cant/types.js +11 -0
  28. package/dist/cant/types.js.map +1 -0
  29. package/dist/cant/workflow-executor.d.ts +105 -0
  30. package/dist/cant/workflow-executor.d.ts.map +1 -0
  31. package/dist/cant/workflow-executor.js +440 -0
  32. package/dist/cant/workflow-executor.js.map +1 -0
  33. package/dist/cleo.js +21 -1
  34. package/dist/cleo.js.map +1 -1
  35. package/dist/code/index.d.ts +10 -0
  36. package/dist/code/index.d.ts.map +1 -0
  37. package/dist/code/outline.d.ts +51 -0
  38. package/dist/code/outline.d.ts.map +1 -0
  39. package/dist/code/parser.d.ts +30 -0
  40. package/dist/code/parser.d.ts.map +1 -0
  41. package/dist/code/search.d.ts +42 -0
  42. package/dist/code/search.d.ts.map +1 -0
  43. package/dist/code/unfold.d.ts +44 -0
  44. package/dist/code/unfold.d.ts.map +1 -0
  45. package/dist/conduit/conduit-client.d.ts +35 -0
  46. package/dist/conduit/conduit-client.d.ts.map +1 -0
  47. package/dist/conduit/conduit-client.js +94 -0
  48. package/dist/conduit/conduit-client.js.map +1 -0
  49. package/dist/conduit/factory.d.ts +15 -0
  50. package/dist/conduit/factory.d.ts.map +1 -0
  51. package/dist/conduit/factory.js +35 -0
  52. package/dist/conduit/factory.js.map +1 -0
  53. package/dist/conduit/http-transport.d.ts +44 -0
  54. package/dist/conduit/http-transport.d.ts.map +1 -0
  55. package/dist/conduit/http-transport.js +165 -0
  56. package/dist/conduit/http-transport.js.map +1 -0
  57. package/dist/conduit/index.d.ts +15 -0
  58. package/dist/conduit/index.d.ts.map +1 -0
  59. package/dist/conduit/index.js +12 -0
  60. package/dist/conduit/index.js.map +1 -0
  61. package/dist/conduit/local-transport.d.ts +91 -0
  62. package/dist/conduit/local-transport.d.ts.map +1 -0
  63. package/dist/conduit/sse-transport.d.ts +68 -0
  64. package/dist/conduit/sse-transport.d.ts.map +1 -0
  65. package/dist/config.js +4 -3
  66. package/dist/config.js.map +1 -1
  67. package/dist/crypto/credentials.d.ts +40 -0
  68. package/dist/crypto/credentials.d.ts.map +1 -0
  69. package/dist/crypto/credentials.js +144 -0
  70. package/dist/crypto/credentials.js.map +1 -0
  71. package/dist/engine-result.d.ts +1 -1
  72. package/dist/engine-result.d.ts.map +1 -1
  73. package/dist/error-catalog.d.ts +1 -1
  74. package/dist/error-catalog.d.ts.map +1 -1
  75. package/dist/error-registry.d.ts +1 -1
  76. package/dist/error-registry.d.ts.map +1 -1
  77. package/dist/errors.d.ts +1 -1
  78. package/dist/errors.d.ts.map +1 -1
  79. package/dist/hooks/handlers/agent-hooks.d.ts.map +1 -1
  80. package/dist/hooks/handlers/agent-hooks.js +106 -0
  81. package/dist/hooks/handlers/agent-hooks.js.map +1 -0
  82. package/dist/hooks/handlers/context-hooks.d.ts.map +1 -1
  83. package/dist/hooks/handlers/context-hooks.js +111 -0
  84. package/dist/hooks/handlers/context-hooks.js.map +1 -0
  85. package/dist/hooks/handlers/error-hooks.d.ts +14 -5
  86. package/dist/hooks/handlers/error-hooks.d.ts.map +1 -1
  87. package/dist/hooks/handlers/error-hooks.js +15 -6
  88. package/dist/hooks/handlers/error-hooks.js.map +1 -1
  89. package/dist/hooks/handlers/file-hooks.d.ts.map +1 -1
  90. package/dist/hooks/handlers/file-hooks.js +35 -11
  91. package/dist/hooks/handlers/file-hooks.js.map +1 -1
  92. package/dist/hooks/handlers/handler-helpers.d.ts +41 -0
  93. package/dist/hooks/handlers/handler-helpers.d.ts.map +1 -0
  94. package/dist/hooks/handlers/handler-helpers.js +61 -0
  95. package/dist/hooks/handlers/handler-helpers.js.map +1 -0
  96. package/dist/hooks/handlers/index.js +10 -1
  97. package/dist/hooks/handlers/index.js.map +1 -1
  98. package/dist/hooks/handlers/mcp-hooks.d.ts.map +1 -1
  99. package/dist/hooks/handlers/mcp-hooks.js +88 -21
  100. package/dist/hooks/handlers/mcp-hooks.js.map +1 -1
  101. package/dist/hooks/handlers/session-hooks.d.ts.map +1 -1
  102. package/dist/hooks/handlers/session-hooks.js +5 -10
  103. package/dist/hooks/handlers/session-hooks.js.map +1 -1
  104. package/dist/hooks/handlers/task-hooks.d.ts.map +1 -1
  105. package/dist/hooks/handlers/task-hooks.js +5 -10
  106. package/dist/hooks/handlers/task-hooks.js.map +1 -1
  107. package/dist/hooks/handlers/work-capture-hooks.d.ts.map +1 -1
  108. package/dist/hooks/handlers/work-capture-hooks.js +165 -0
  109. package/dist/hooks/handlers/work-capture-hooks.js.map +1 -0
  110. package/dist/hooks/payload-schemas.js +83 -26
  111. package/dist/hooks/payload-schemas.js.map +1 -1
  112. package/dist/hooks/provider-hooks.js +37 -5
  113. package/dist/hooks/provider-hooks.js.map +1 -1
  114. package/dist/hooks/registry.js +76 -23
  115. package/dist/hooks/registry.js.map +1 -1
  116. package/dist/hooks/types.js +17 -13
  117. package/dist/hooks/types.js.map +1 -1
  118. package/dist/index.d.ts +4 -1
  119. package/dist/index.d.ts.map +1 -1
  120. package/dist/index.js +6452 -3371
  121. package/dist/index.js.map +4 -4
  122. package/dist/init.d.ts.map +1 -1
  123. package/dist/init.js +12 -0
  124. package/dist/init.js.map +1 -1
  125. package/dist/internal.d.ts +11 -1
  126. package/dist/internal.d.ts.map +1 -1
  127. package/dist/internal.js +10 -0
  128. package/dist/internal.js.map +1 -1
  129. package/dist/lib/index.d.ts +1 -0
  130. package/dist/lib/index.d.ts.map +1 -1
  131. package/dist/lib/tree-sitter-languages.d.ts +29 -0
  132. package/dist/lib/tree-sitter-languages.d.ts.map +1 -0
  133. package/dist/memory/brain-links.d.ts.map +1 -1
  134. package/dist/memory/brain-maintenance.d.ts +13 -0
  135. package/dist/memory/brain-maintenance.d.ts.map +1 -1
  136. package/dist/memory/brain-retrieval.d.ts +3 -0
  137. package/dist/memory/brain-retrieval.d.ts.map +1 -1
  138. package/dist/memory/brain-retrieval.js +5 -0
  139. package/dist/memory/brain-retrieval.js.map +1 -1
  140. package/dist/memory/decisions.d.ts.map +1 -1
  141. package/dist/mvi-helpers.d.ts +52 -0
  142. package/dist/mvi-helpers.d.ts.map +1 -0
  143. package/dist/mvi-helpers.js +74 -0
  144. package/dist/mvi-helpers.js.map +1 -0
  145. package/dist/nexus/index.js +2 -0
  146. package/dist/nexus/index.js.map +1 -1
  147. package/dist/nexus/workspace.d.ts.map +1 -1
  148. package/dist/nexus/workspace.js +355 -0
  149. package/dist/nexus/workspace.js.map +1 -0
  150. package/dist/orchestration/hierarchy.d.ts +32 -0
  151. package/dist/orchestration/hierarchy.d.ts.map +1 -0
  152. package/dist/orchestration/index.d.ts +1 -0
  153. package/dist/orchestration/index.d.ts.map +1 -1
  154. package/dist/output.d.ts +2 -2
  155. package/dist/output.d.ts.map +1 -1
  156. package/dist/output.js +40 -8
  157. package/dist/output.js.map +1 -1
  158. package/dist/pagination.d.ts +1 -1
  159. package/dist/pagination.d.ts.map +1 -1
  160. package/dist/sessions/find.d.ts +3 -0
  161. package/dist/sessions/find.d.ts.map +1 -1
  162. package/dist/sessions/find.js +3 -1
  163. package/dist/sessions/find.js.map +1 -1
  164. package/dist/sessions/index.d.ts.map +1 -1
  165. package/dist/sessions/index.js +11 -4
  166. package/dist/sessions/index.js.map +1 -1
  167. package/dist/sessions/snapshot.js +213 -0
  168. package/dist/sessions/snapshot.js.map +1 -0
  169. package/dist/store/agent-registry-accessor.d.ts +31 -0
  170. package/dist/store/agent-registry-accessor.d.ts.map +1 -0
  171. package/dist/store/agent-registry-accessor.js +169 -0
  172. package/dist/store/agent-registry-accessor.js.map +1 -0
  173. package/dist/store/converters.d.ts.map +1 -1
  174. package/dist/store/converters.js +2 -0
  175. package/dist/store/converters.js.map +1 -1
  176. package/dist/store/cross-db-cleanup.d.ts +34 -0
  177. package/dist/store/cross-db-cleanup.d.ts.map +1 -1
  178. package/dist/store/db-helpers.d.ts.map +1 -1
  179. package/dist/store/db-helpers.js +1 -0
  180. package/dist/store/db-helpers.js.map +1 -1
  181. package/dist/store/json.js +2 -2
  182. package/dist/store/safety-data-accessor.d.ts +7 -0
  183. package/dist/store/safety-data-accessor.d.ts.map +1 -1
  184. package/dist/store/safety-data-accessor.js +14 -0
  185. package/dist/store/safety-data-accessor.js.map +1 -1
  186. package/dist/store/signaldock-sqlite.d.ts +48 -0
  187. package/dist/store/signaldock-sqlite.d.ts.map +1 -0
  188. package/dist/store/signaldock-sqlite.js +178 -0
  189. package/dist/store/signaldock-sqlite.js.map +1 -0
  190. package/dist/store/sqlite-data-accessor.d.ts.map +1 -1
  191. package/dist/store/sqlite-data-accessor.js +50 -0
  192. package/dist/store/sqlite-data-accessor.js.map +1 -1
  193. package/dist/store/sqlite.d.ts.map +1 -1
  194. package/dist/store/sqlite.js +30 -1
  195. package/dist/store/sqlite.js.map +1 -1
  196. package/dist/store/task-store.d.ts.map +1 -1
  197. package/dist/store/task-store.js +2 -0
  198. package/dist/store/task-store.js.map +1 -1
  199. package/dist/store/tasks-schema.d.ts +16 -0
  200. package/dist/store/tasks-schema.d.ts.map +1 -1
  201. package/dist/store/tasks-schema.js +33 -0
  202. package/dist/store/tasks-schema.js.map +1 -1
  203. package/dist/store/validation-schemas.d.ts +32 -0
  204. package/dist/store/validation-schemas.d.ts.map +1 -1
  205. package/dist/system/health.d.ts +1 -1
  206. package/dist/system/health.d.ts.map +1 -1
  207. package/dist/system/health.js +35 -0
  208. package/dist/system/health.js.map +1 -1
  209. package/dist/task-work/index.d.ts.map +1 -1
  210. package/dist/task-work/index.js +8 -4
  211. package/dist/task-work/index.js.map +1 -1
  212. package/dist/tasks/complete.js +5 -2
  213. package/dist/tasks/complete.js.map +1 -1
  214. package/dist/tasks/find.d.ts +3 -0
  215. package/dist/tasks/find.d.ts.map +1 -1
  216. package/dist/tasks/find.js +7 -1
  217. package/dist/tasks/find.js.map +1 -1
  218. package/dist/tasks/list.d.ts +5 -2
  219. package/dist/tasks/list.d.ts.map +1 -1
  220. package/dist/tasks/list.js +9 -2
  221. package/dist/tasks/list.js.map +1 -1
  222. package/dist/tasks/show.d.ts +3 -0
  223. package/dist/tasks/show.d.ts.map +1 -1
  224. package/dist/tasks/show.js +2 -0
  225. package/dist/tasks/show.js.map +1 -1
  226. package/dist/upgrade.d.ts.map +1 -1
  227. package/dist/upgrade.js +15 -0
  228. package/dist/upgrade.js.map +1 -1
  229. package/migrations/drizzle-tasks/20260324000000_assignee-column/migration.sql +6 -0
  230. package/migrations/drizzle-tasks/20260324000000_assignee-column/snapshot.json +9 -0
  231. package/migrations/drizzle-tasks/20260327000000_agent-credentials/migration.sql +23 -0
  232. package/package.json +17 -7
  233. package/src/__tests__/cli-parity.test.js +11 -1
  234. package/src/__tests__/cli-parity.test.js.map +1 -1
  235. package/src/__tests__/cli-parity.test.ts +17 -1
  236. package/src/__tests__/human-output.test.js +11 -1
  237. package/src/__tests__/human-output.test.js.map +1 -1
  238. package/src/__tests__/human-output.test.ts +18 -1
  239. package/src/__tests__/injection-chain.test.js +3 -2
  240. package/src/__tests__/injection-chain.test.js.map +1 -1
  241. package/src/__tests__/injection-mvi-tiers.test.d.ts +2 -2
  242. package/src/__tests__/injection-mvi-tiers.test.js +15 -15
  243. package/src/__tests__/injection-mvi-tiers.test.js.map +1 -1
  244. package/src/__tests__/lafs-conformance.test.d.ts +1 -1
  245. package/src/__tests__/lafs-conformance.test.js +2 -2
  246. package/src/__tests__/sharing.test.js +19 -0
  247. package/src/__tests__/sharing.test.js.map +1 -1
  248. package/src/agents/__tests__/agent-registry.test.d.ts +12 -0
  249. package/src/agents/__tests__/agent-registry.test.d.ts.map +1 -0
  250. package/src/agents/__tests__/agent-registry.test.js +262 -0
  251. package/src/agents/__tests__/agent-registry.test.js.map +1 -0
  252. package/src/agents/__tests__/execution-learning.test.d.ts +14 -0
  253. package/src/agents/__tests__/execution-learning.test.d.ts.map +1 -0
  254. package/src/agents/__tests__/execution-learning.test.js +533 -0
  255. package/src/agents/__tests__/execution-learning.test.js.map +1 -0
  256. package/src/agents/__tests__/health-monitor.test.d.ts +10 -0
  257. package/src/agents/__tests__/health-monitor.test.d.ts.map +1 -0
  258. package/src/agents/__tests__/health-monitor.test.js +259 -0
  259. package/src/agents/__tests__/health-monitor.test.js.map +1 -0
  260. package/src/agents/__tests__/registry.test.js +27 -2
  261. package/src/agents/__tests__/registry.test.js.map +1 -1
  262. package/src/agents/agent-schema.ts +2 -5
  263. package/src/cant/__tests__/cant-agent-parse.test.ts +94 -0
  264. package/src/cant/approval.ts +218 -0
  265. package/src/cant/context-builder.ts +135 -0
  266. package/src/cant/discretion.ts +149 -0
  267. package/src/cant/index.ts +58 -0
  268. package/src/cant/parallel-runner.ts +205 -0
  269. package/src/cant/types.ts +158 -0
  270. package/src/cant/workflow-executor.ts +618 -0
  271. package/src/code/index.ts +10 -0
  272. package/src/code/outline.ts +214 -0
  273. package/src/code/parser.ts +299 -0
  274. package/src/code/search.ts +173 -0
  275. package/src/code/unfold.ts +204 -0
  276. package/src/conduit/__tests__/dual-api-e2e.test.ts +212 -0
  277. package/src/conduit/__tests__/local-credential-flow.test.ts +230 -0
  278. package/src/conduit/__tests__/local-transport.test.ts +320 -0
  279. package/src/conduit/__tests__/sse-transport.test.ts +344 -0
  280. package/src/conduit/conduit-client.ts +123 -0
  281. package/src/conduit/factory.ts +49 -0
  282. package/src/conduit/http-transport.ts +201 -0
  283. package/src/conduit/index.ts +15 -0
  284. package/src/conduit/local-transport.ts +309 -0
  285. package/src/conduit/sse-transport.ts +382 -0
  286. package/src/crypto/credentials.ts +166 -0
  287. package/src/engine-result.ts +1 -1
  288. package/src/error-catalog.ts +1 -1
  289. package/src/error-registry.ts +1 -1
  290. package/src/errors.ts +1 -1
  291. package/src/hooks/handlers/__tests__/hook-automation-e2e.test.d.ts +13 -0
  292. package/src/hooks/handlers/__tests__/hook-automation-e2e.test.d.ts.map +1 -0
  293. package/src/hooks/handlers/__tests__/hook-automation-e2e.test.js +501 -0
  294. package/src/hooks/handlers/__tests__/hook-automation-e2e.test.js.map +1 -0
  295. package/src/hooks/handlers/agent-hooks.ts +1 -30
  296. package/src/hooks/handlers/context-hooks.ts +1 -30
  297. package/src/hooks/handlers/error-hooks.ts +14 -5
  298. package/src/hooks/handlers/file-hooks.ts +1 -6
  299. package/src/hooks/handlers/handler-helpers.ts +62 -0
  300. package/src/hooks/handlers/mcp-hooks.ts +2 -14
  301. package/src/hooks/handlers/session-hooks.ts +1 -6
  302. package/src/hooks/handlers/task-hooks.ts +1 -6
  303. package/src/hooks/handlers/work-capture-hooks.ts +1 -10
  304. package/src/index.ts +12 -1
  305. package/src/init.ts +12 -0
  306. package/src/intelligence/__tests__/adaptive-validation.test.d.ts +11 -0
  307. package/src/intelligence/__tests__/adaptive-validation.test.d.ts.map +1 -0
  308. package/src/intelligence/__tests__/adaptive-validation.test.js +517 -0
  309. package/src/intelligence/__tests__/adaptive-validation.test.js.map +1 -0
  310. package/src/intelligence/__tests__/impact.test.d.ts +1 -0
  311. package/src/intelligence/__tests__/impact.test.d.ts.map +1 -1
  312. package/src/intelligence/__tests__/impact.test.js +132 -1
  313. package/src/intelligence/__tests__/impact.test.js.map +1 -1
  314. package/src/internal.ts +22 -0
  315. package/src/lib/__tests__/retry.test.d.ts +7 -0
  316. package/src/lib/__tests__/retry.test.d.ts.map +1 -0
  317. package/src/lib/__tests__/retry.test.js +225 -0
  318. package/src/lib/__tests__/retry.test.js.map +1 -0
  319. package/src/lib/index.ts +8 -0
  320. package/src/lib/tree-sitter-languages.ts +88 -0
  321. package/src/lifecycle/__tests__/chain-store.test.js +6 -0
  322. package/src/lifecycle/__tests__/chain-store.test.js.map +1 -1
  323. package/src/lifecycle/__tests__/tessera-engine.test.js +52 -0
  324. package/src/lifecycle/__tests__/tessera-engine.test.js.map +1 -1
  325. package/src/memory/__tests__/brain-automation.test.d.ts +11 -0
  326. package/src/memory/__tests__/brain-automation.test.d.ts.map +1 -0
  327. package/src/memory/__tests__/brain-automation.test.js +730 -0
  328. package/src/memory/__tests__/brain-automation.test.js.map +1 -0
  329. package/src/memory/__tests__/brain-links.test.ts +14 -0
  330. package/src/memory/__tests__/brain-retrieval.test.ts +10 -0
  331. package/src/memory/__tests__/session-memory.test.ts +17 -0
  332. package/src/memory/brain-links.ts +17 -0
  333. package/src/memory/brain-maintenance.ts +33 -1
  334. package/src/memory/brain-retrieval.ts +27 -2
  335. package/src/memory/decisions.ts +18 -2
  336. package/src/mvi-helpers.ts +81 -0
  337. package/src/nexus/workspace.ts +19 -7
  338. package/src/orchestration/hierarchy.ts +202 -0
  339. package/src/orchestration/index.ts +1 -0
  340. package/src/output.ts +43 -10
  341. package/src/pagination.ts +1 -1
  342. package/src/sessions/__tests__/session-edge-cases.test.js +20 -1
  343. package/src/sessions/__tests__/session-edge-cases.test.js.map +1 -1
  344. package/src/sessions/__tests__/session-find.test.js +1 -1
  345. package/src/sessions/__tests__/session-find.test.js.map +1 -1
  346. package/src/sessions/__tests__/session-find.test.ts +1 -1
  347. package/src/sessions/find.ts +6 -1
  348. package/src/sessions/index.ts +9 -0
  349. package/src/store/__tests__/migration-safety.test.js +3 -0
  350. package/src/store/__tests__/migration-safety.test.js.map +1 -1
  351. package/src/store/__tests__/session-store.test.js +128 -1
  352. package/src/store/__tests__/session-store.test.js.map +1 -1
  353. package/src/store/__tests__/task-store.test.js +18 -1
  354. package/src/store/__tests__/task-store.test.js.map +1 -1
  355. package/src/store/__tests__/test-db-helper.d.ts.map +1 -1
  356. package/src/store/__tests__/test-db-helper.js +12 -0
  357. package/src/store/__tests__/test-db-helper.js.map +1 -1
  358. package/src/store/agent-registry-accessor.ts +375 -0
  359. package/src/store/converters.ts +2 -0
  360. package/src/store/cross-db-cleanup.ts +175 -1
  361. package/src/store/db-helpers.ts +1 -0
  362. package/src/store/safety-data-accessor.ts +23 -0
  363. package/src/store/signaldock-sqlite.ts +429 -0
  364. package/src/store/sqlite-data-accessor.ts +72 -0
  365. package/src/store/sqlite.ts +4 -1
  366. package/src/store/task-store.ts +9 -1
  367. package/src/store/tasks-schema.ts +7 -0
  368. package/src/system/__tests__/health.test.ts +2 -2
  369. package/src/system/health.ts +54 -2
  370. package/src/task-work/index.ts +5 -0
  371. package/src/tasks/__tests__/add.test.js +19 -1
  372. package/src/tasks/__tests__/add.test.js.map +1 -1
  373. package/src/tasks/__tests__/assignee.test.d.ts +14 -0
  374. package/src/tasks/__tests__/assignee.test.d.ts.map +1 -0
  375. package/src/tasks/__tests__/assignee.test.js +125 -0
  376. package/src/tasks/__tests__/assignee.test.js.map +1 -0
  377. package/src/tasks/__tests__/assignee.test.ts +162 -0
  378. package/src/tasks/__tests__/complete-unblocks.test.js +13 -1
  379. package/src/tasks/__tests__/complete-unblocks.test.js.map +1 -1
  380. package/src/tasks/__tests__/complete.test.js +28 -7
  381. package/src/tasks/__tests__/complete.test.js.map +1 -1
  382. package/src/tasks/__tests__/epic-enforcement.test.d.ts +15 -0
  383. package/src/tasks/__tests__/epic-enforcement.test.d.ts.map +1 -0
  384. package/src/tasks/__tests__/epic-enforcement.test.js +669 -0
  385. package/src/tasks/__tests__/epic-enforcement.test.js.map +1 -0
  386. package/src/tasks/__tests__/hierarchy-policy.test.js +5 -0
  387. package/src/tasks/__tests__/hierarchy-policy.test.js.map +1 -1
  388. package/src/tasks/__tests__/minimal-test.test.d.ts +2 -0
  389. package/src/tasks/__tests__/minimal-test.test.d.ts.map +1 -0
  390. package/src/tasks/__tests__/minimal-test.test.js +25 -0
  391. package/src/tasks/__tests__/minimal-test.test.js.map +1 -0
  392. package/src/tasks/__tests__/pipeline-stage.test.d.ts +14 -0
  393. package/src/tasks/__tests__/pipeline-stage.test.d.ts.map +1 -0
  394. package/src/tasks/__tests__/pipeline-stage.test.js +277 -0
  395. package/src/tasks/__tests__/pipeline-stage.test.js.map +1 -0
  396. package/src/tasks/__tests__/update.test.js +43 -6
  397. package/src/tasks/__tests__/update.test.js.map +1 -1
  398. package/src/tasks/find.ts +11 -1
  399. package/src/tasks/list.ts +14 -3
  400. package/src/tasks/show.ts +6 -0
  401. package/src/upgrade.ts +16 -0
  402. package/dist/tasks/reparent.d.ts +0 -38
  403. package/dist/tasks/reparent.d.ts.map +0 -1
  404. package/dist/ui/injection-legacy.d.ts +0 -26
  405. package/dist/ui/injection-legacy.d.ts.map +0 -1
  406. package/dist/ui/injection-legacy.js +0 -42
  407. package/dist/ui/injection-legacy.js.map +0 -1
  408. package/src/signaldock/__tests__/claude-code-transport.test.d.ts +0 -7
  409. package/src/signaldock/__tests__/claude-code-transport.test.d.ts.map +0 -1
  410. package/src/signaldock/__tests__/claude-code-transport.test.js +0 -147
  411. package/src/signaldock/__tests__/claude-code-transport.test.js.map +0 -1
  412. package/src/signaldock/__tests__/claude-code-transport.test.ts +0 -180
  413. package/src/signaldock/__tests__/factory.test.d.ts +0 -7
  414. package/src/signaldock/__tests__/factory.test.d.ts.map +0 -1
  415. package/src/signaldock/__tests__/factory.test.js +0 -55
  416. package/src/signaldock/__tests__/factory.test.js.map +0 -1
  417. package/src/signaldock/__tests__/factory.test.ts +0 -61
  418. package/src/signaldock/__tests__/signaldock-transport.test.d.ts +0 -9
  419. package/src/signaldock/__tests__/signaldock-transport.test.d.ts.map +0 -1
  420. package/src/signaldock/__tests__/signaldock-transport.test.js +0 -321
  421. package/src/signaldock/__tests__/signaldock-transport.test.js.map +0 -1
  422. package/src/signaldock/__tests__/signaldock-transport.test.ts +0 -421
  423. package/src/signaldock/claude-code-transport.ts +0 -137
  424. package/src/signaldock/factory.ts +0 -39
  425. package/src/signaldock/index.ts +0 -28
  426. package/src/signaldock/signaldock-transport.ts +0 -194
  427. package/src/signaldock/transport.ts +0 -78
  428. package/src/signaldock/types.ts +0 -100
@@ -0,0 +1,618 @@
1
+ /**
2
+ * CANT workflow executor — orchestrates workflow statement execution.
3
+ *
4
+ * Walks the statement list of a `WorkflowDef` AST node, dispatching to
5
+ * appropriate handlers for each statement type: sessions, pipelines,
6
+ * parallel blocks, conditionals, loops, try/catch, approval gates,
7
+ * bindings, directives, and output statements.
8
+ *
9
+ * Pipelines are delegated to the Rust executor via napi-rs bridge.
10
+ * Sessions invoke the CLEO session machinery. Discretion conditions
11
+ * are evaluated by a pluggable evaluator.
12
+ *
13
+ * @see docs/specs/CANT-DSL-SPEC.md Section 7.2 (Workflow Execution)
14
+ */
15
+
16
+ import { ApprovalManager } from './approval.js';
17
+ import { createChildScope, createScope, flattenScope, setVariable } from './context-builder.js';
18
+ import type { DiscretionEvaluator } from './discretion.js';
19
+ import { DefaultDiscretionEvaluator, RateLimitedDiscretionEvaluator } from './discretion.js';
20
+ import type { ParallelArm as ParallelArmRunner } from './parallel-runner.js';
21
+ import { executeParallel } from './parallel-runner.js';
22
+ import type {
23
+ DiscretionContext,
24
+ ExecutionResult,
25
+ ExecutionScope,
26
+ JoinStrategy,
27
+ StepResult,
28
+ } from './types.js';
29
+
30
+ // ---------------------------------------------------------------------------
31
+ // Configuration
32
+ // ---------------------------------------------------------------------------
33
+
34
+ /** Configuration options for the workflow executor. */
35
+ export interface WorkflowExecutorConfig {
36
+ /** Maximum number of discretion evaluations per workflow run (default: 100). */
37
+ maxDiscretionEvaluations?: number;
38
+ /** The session ID for this execution. */
39
+ sessionId?: string;
40
+ /** The agent ID performing the execution. */
41
+ agentId?: string;
42
+ }
43
+
44
+ // ---------------------------------------------------------------------------
45
+ // Statement type discriminators (from cant-core AST)
46
+ //
47
+ // These are lightweight type guards for the AST Statement enum variants.
48
+ // The real AST types come from the Rust parser; here we use structural
49
+ // matching to avoid tight coupling with the napi binding shape.
50
+ // ---------------------------------------------------------------------------
51
+
52
+ /** Loose AST statement shape — mirrors cant-core Statement variants. */
53
+ interface AstStatement {
54
+ type?: string;
55
+ [key: string]: unknown;
56
+ }
57
+
58
+ /** A workflow definition with a name, params, and body statements. */
59
+ interface WorkflowDef {
60
+ name: { value: string };
61
+ params: Array<{ name: { value: string } }>;
62
+ body: AstStatement[];
63
+ }
64
+
65
+ // ---------------------------------------------------------------------------
66
+ // Workflow Executor
67
+ // ---------------------------------------------------------------------------
68
+
69
+ /**
70
+ * Executes CANT workflow definitions.
71
+ *
72
+ * The executor processes each statement in the workflow body sequentially,
73
+ * maintaining an execution scope for variable bindings and dispatching to
74
+ * the appropriate handler based on statement type.
75
+ */
76
+ export class WorkflowExecutor {
77
+ private readonly discretionEvaluator: DiscretionEvaluator;
78
+ private readonly approvalManager: ApprovalManager;
79
+ private readonly config: WorkflowExecutorConfig;
80
+
81
+ /**
82
+ * Creates a new workflow executor.
83
+ *
84
+ * @param discretionEvaluator - Custom discretion evaluator (default: stub that returns true).
85
+ * @param approvalManager - Approval token manager (default: new instance).
86
+ * @param config - Executor configuration.
87
+ */
88
+ constructor(
89
+ discretionEvaluator: DiscretionEvaluator = new DefaultDiscretionEvaluator(),
90
+ approvalManager: ApprovalManager = new ApprovalManager(),
91
+ config: WorkflowExecutorConfig = {},
92
+ ) {
93
+ const maxEvals = config.maxDiscretionEvaluations ?? 100;
94
+ this.discretionEvaluator = new RateLimitedDiscretionEvaluator(discretionEvaluator, maxEvals);
95
+ this.approvalManager = approvalManager;
96
+ this.config = config;
97
+ }
98
+
99
+ /**
100
+ * Executes a workflow definition with the given parameter values.
101
+ *
102
+ * @param workflow - The parsed workflow AST node.
103
+ * @param context - Parameter values and initial context.
104
+ * @returns Execution result with outputs and step results.
105
+ */
106
+ async execute(
107
+ workflow: WorkflowDef,
108
+ context: Record<string, unknown> = {},
109
+ ): Promise<ExecutionResult> {
110
+ const start = Date.now();
111
+ const scope = createScope(context);
112
+ const steps: StepResult[] = [];
113
+ const outputs: Record<string, unknown> = {};
114
+
115
+ // Bind workflow parameters to scope
116
+ for (const param of workflow.params) {
117
+ const value = context[param.name.value];
118
+ if (value !== undefined) {
119
+ setVariable(scope, param.name.value, value);
120
+ }
121
+ }
122
+
123
+ let success = true;
124
+
125
+ for (const statement of workflow.body) {
126
+ const stepStart = Date.now();
127
+
128
+ try {
129
+ const result = await this.executeStatement(statement, scope, outputs);
130
+ if (result) {
131
+ steps.push({ ...result, duration: Date.now() - stepStart });
132
+ if (!result.success) {
133
+ success = false;
134
+ break;
135
+ }
136
+ }
137
+ } catch (err) {
138
+ const error = err instanceof Error ? err.message : String(err);
139
+ steps.push({
140
+ name: getStatementName(statement),
141
+ type: getStatementType(statement),
142
+ success: false,
143
+ error,
144
+ duration: Date.now() - stepStart,
145
+ });
146
+ success = false;
147
+ break;
148
+ }
149
+ }
150
+
151
+ return {
152
+ success,
153
+ outputs,
154
+ steps,
155
+ duration: Date.now() - start,
156
+ };
157
+ }
158
+
159
+ /**
160
+ * Dispatches a single statement to the appropriate handler.
161
+ */
162
+ private async executeStatement(
163
+ statement: AstStatement,
164
+ scope: ExecutionScope,
165
+ outputs: Record<string, unknown>,
166
+ ): Promise<StepResult | null> {
167
+ const stmtType = detectStatementType(statement);
168
+
169
+ switch (stmtType) {
170
+ case 'Binding':
171
+ return this.executeBinding(statement, scope);
172
+ case 'Output':
173
+ return this.executeOutput(statement, scope, outputs);
174
+ case 'Conditional':
175
+ return this.executeConditional(statement, scope, outputs);
176
+ case 'Parallel':
177
+ return this.executeParallelBlock(statement, scope, outputs);
178
+ case 'Session':
179
+ return this.executeSession(statement, scope);
180
+ case 'Pipeline':
181
+ return this.executePipeline(statement, scope);
182
+ case 'ApprovalGate':
183
+ return this.executeApprovalGate(statement, scope);
184
+ case 'Repeat':
185
+ return this.executeRepeat(statement, scope, outputs);
186
+ case 'ForLoop':
187
+ return this.executeForLoop(statement, scope, outputs);
188
+ case 'LoopUntil':
189
+ return this.executeLoopUntil(statement, scope, outputs);
190
+ case 'TryCatch':
191
+ return this.executeTryCatch(statement, scope, outputs);
192
+ case 'Directive':
193
+ return this.executeDirective(statement, scope);
194
+ case 'Comment':
195
+ return null; // Comments are no-ops
196
+ default:
197
+ return {
198
+ name: getStatementName(statement),
199
+ type: 'binding',
200
+ success: true,
201
+ duration: 0,
202
+ };
203
+ }
204
+ }
205
+
206
+ /** Execute a let binding statement. */
207
+ private async executeBinding(
208
+ statement: AstStatement,
209
+ scope: ExecutionScope,
210
+ ): Promise<StepResult> {
211
+ const name = (statement as { name?: { value: string } }).name?.value ?? 'binding';
212
+ const value = (statement as { value?: unknown }).value;
213
+ setVariable(scope, name, value);
214
+ return { name, type: 'binding', success: true, output: value, duration: 0 };
215
+ }
216
+
217
+ /** Execute an output binding statement. */
218
+ private async executeOutput(
219
+ statement: AstStatement,
220
+ scope: ExecutionScope,
221
+ outputs: Record<string, unknown>,
222
+ ): Promise<StepResult> {
223
+ const name = (statement as { name?: { value: string } }).name?.value ?? 'output';
224
+ const value = (statement as { value?: unknown }).value;
225
+ outputs[name] = value;
226
+ setVariable(scope, name, value);
227
+ return { name, type: 'output', success: true, output: value, duration: 0 };
228
+ }
229
+
230
+ /** Execute an if/elif/else conditional. */
231
+ private async executeConditional(
232
+ statement: AstStatement,
233
+ scope: ExecutionScope,
234
+ outputs: Record<string, unknown>,
235
+ ): Promise<StepResult> {
236
+ const conditional = statement as {
237
+ condition?: { Discretion?: { prose: string }; Expression?: unknown };
238
+ then_body?: AstStatement[];
239
+ elif_branches?: Array<{
240
+ condition: { Discretion?: { prose: string }; Expression?: unknown };
241
+ body: AstStatement[];
242
+ }>;
243
+ else_body?: AstStatement[];
244
+ };
245
+
246
+ // Evaluate the if condition
247
+ const ifResult = await this.evaluateCondition(conditional.condition, scope);
248
+
249
+ if (ifResult) {
250
+ for (const stmt of conditional.then_body ?? []) {
251
+ await this.executeStatement(stmt, scope, outputs);
252
+ }
253
+ return { name: 'if', type: 'conditional', success: true, output: true, duration: 0 };
254
+ }
255
+
256
+ // Check elif branches
257
+ for (const elif of conditional.elif_branches ?? []) {
258
+ const elifResult = await this.evaluateCondition(elif.condition, scope);
259
+ if (elifResult) {
260
+ for (const stmt of elif.body) {
261
+ await this.executeStatement(stmt, scope, outputs);
262
+ }
263
+ return { name: 'elif', type: 'conditional', success: true, output: true, duration: 0 };
264
+ }
265
+ }
266
+
267
+ // Execute else branch
268
+ if (conditional.else_body) {
269
+ for (const stmt of conditional.else_body) {
270
+ await this.executeStatement(stmt, scope, outputs);
271
+ }
272
+ }
273
+
274
+ return { name: 'else', type: 'conditional', success: true, output: false, duration: 0 };
275
+ }
276
+
277
+ /** Execute a parallel block with arms. */
278
+ private async executeParallelBlock(
279
+ statement: AstStatement,
280
+ scope: ExecutionScope,
281
+ _outputs: Record<string, unknown>,
282
+ ): Promise<StepResult> {
283
+ const parallel = statement as {
284
+ modifier?: string;
285
+ arms?: Array<{ name: string; body: AstStatement }>;
286
+ };
287
+
288
+ const strategy: JoinStrategy =
289
+ parallel.modifier === 'Race' ? 'race' : parallel.modifier === 'Settle' ? 'settle' : 'all';
290
+
291
+ const arms: ParallelArmRunner[] = (parallel.arms ?? []).map((arm) => ({
292
+ name: arm.name,
293
+ execute: async () => {
294
+ const childScope = createChildScope(scope);
295
+ const armOutputs: Record<string, unknown> = {};
296
+ const result = await this.executeStatement(arm.body, childScope, armOutputs);
297
+ return result?.output;
298
+ },
299
+ }));
300
+
301
+ const result = await executeParallel(arms, strategy);
302
+
303
+ // Bind arm results to the parent scope
304
+ for (const [name, value] of Object.entries(result.results)) {
305
+ setVariable(scope, name, value);
306
+ }
307
+
308
+ return {
309
+ name: 'parallel',
310
+ type: 'parallel',
311
+ success: result.success,
312
+ output: result.results,
313
+ duration: 0,
314
+ };
315
+ }
316
+
317
+ /** Execute a session invocation (stub — real session dispatch is a separate integration). */
318
+ private async executeSession(
319
+ statement: AstStatement,
320
+ _scope: ExecutionScope,
321
+ ): Promise<StepResult> {
322
+ const session = statement as {
323
+ target?: { Prompt?: string; Agent?: string };
324
+ };
325
+ const targetName = session.target?.Prompt ?? session.target?.Agent ?? 'session';
326
+ // Stub: real session dispatch integrates with CLEO session machinery
327
+ return {
328
+ name: targetName,
329
+ type: 'session',
330
+ success: true,
331
+ output: { stub: true, target: targetName },
332
+ duration: 0,
333
+ };
334
+ }
335
+
336
+ /** Execute a pipeline definition (stub — real pipeline calls Rust via napi-rs). */
337
+ private async executePipeline(
338
+ statement: AstStatement,
339
+ _scope: ExecutionScope,
340
+ ): Promise<StepResult> {
341
+ const pipeline = statement as { name?: { value: string } };
342
+ const name = pipeline.name?.value ?? 'pipeline';
343
+ // Stub: real implementation calls Rust pipeline executor via napi-rs bridge
344
+ return {
345
+ name,
346
+ type: 'pipeline',
347
+ success: true,
348
+ output: { stub: true },
349
+ duration: 0,
350
+ };
351
+ }
352
+
353
+ /** Execute an approval gate. */
354
+ private async executeApprovalGate(
355
+ statement: AstStatement,
356
+ _scope: ExecutionScope,
357
+ ): Promise<StepResult> {
358
+ const gate = statement as {
359
+ properties?: Array<{ key: { value: string }; value: { raw?: string } }>;
360
+ };
361
+
362
+ const message =
363
+ gate.properties?.find((p) => p.key.value === 'message')?.value?.raw ?? 'Approval required';
364
+ const gateName = 'approval-gate';
365
+
366
+ const workflowHash = ApprovalManager.computeWorkflowHash(JSON.stringify(statement));
367
+ const token = this.approvalManager.generateToken(
368
+ this.config.sessionId ?? 'unknown-session',
369
+ 'workflow',
370
+ gateName,
371
+ message,
372
+ workflowHash,
373
+ this.config.agentId ?? 'unknown-agent',
374
+ );
375
+
376
+ // In production, the executor would suspend the session here and
377
+ // wait for a /approve directive. For now, return the token info.
378
+ return {
379
+ name: gateName,
380
+ type: 'approval',
381
+ success: true,
382
+ output: { tokenId: token.token, message, status: token.status },
383
+ duration: 0,
384
+ };
385
+ }
386
+
387
+ /** Execute a repeat N loop. */
388
+ private async executeRepeat(
389
+ statement: AstStatement,
390
+ scope: ExecutionScope,
391
+ outputs: Record<string, unknown>,
392
+ ): Promise<StepResult> {
393
+ const repeat = statement as { count?: { value?: number }; body?: AstStatement[] };
394
+ const count = repeat.count?.value ?? 1;
395
+
396
+ for (let i = 0; i < count; i++) {
397
+ const iterScope = createChildScope(scope, { _iteration: i });
398
+ for (const stmt of repeat.body ?? []) {
399
+ await this.executeStatement(stmt, iterScope, outputs);
400
+ }
401
+ }
402
+
403
+ return { name: `repeat(${count})`, type: 'loop', success: true, output: count, duration: 0 };
404
+ }
405
+
406
+ /** Execute a for-in loop. */
407
+ private async executeForLoop(
408
+ statement: AstStatement,
409
+ scope: ExecutionScope,
410
+ outputs: Record<string, unknown>,
411
+ ): Promise<StepResult> {
412
+ const forLoop = statement as {
413
+ variable?: { value: string };
414
+ iterable?: unknown;
415
+ body?: AstStatement[];
416
+ };
417
+
418
+ const varName = forLoop.variable?.value ?? 'item';
419
+ const iterable = forLoop.iterable;
420
+ const items = Array.isArray(iterable) ? iterable : [];
421
+
422
+ for (const item of items) {
423
+ const iterScope = createChildScope(scope, { [varName]: item });
424
+ for (const stmt of forLoop.body ?? []) {
425
+ await this.executeStatement(stmt, iterScope, outputs);
426
+ }
427
+ }
428
+
429
+ return {
430
+ name: `for(${varName})`,
431
+ type: 'loop',
432
+ success: true,
433
+ output: items.length,
434
+ duration: 0,
435
+ };
436
+ }
437
+
438
+ /** Execute a loop-until block. */
439
+ private async executeLoopUntil(
440
+ statement: AstStatement,
441
+ scope: ExecutionScope,
442
+ outputs: Record<string, unknown>,
443
+ ): Promise<StepResult> {
444
+ const loop = statement as { body?: AstStatement[]; condition?: unknown };
445
+ let iterations = 0;
446
+ const maxIterations = 10000;
447
+ let conditionMet = false;
448
+
449
+ do {
450
+ iterations++;
451
+ if (iterations > maxIterations) {
452
+ throw new Error(`Loop exceeded maximum iterations (${maxIterations})`);
453
+ }
454
+
455
+ for (const stmt of loop.body ?? []) {
456
+ await this.executeStatement(stmt, scope, outputs);
457
+ }
458
+
459
+ conditionMet = await this.evaluateCondition(loop.condition, scope);
460
+ } while (!conditionMet);
461
+
462
+ return {
463
+ name: 'loop-until',
464
+ type: 'loop',
465
+ success: true,
466
+ output: iterations,
467
+ duration: 0,
468
+ };
469
+ }
470
+
471
+ /** Execute a try/catch/finally block. */
472
+ private async executeTryCatch(
473
+ statement: AstStatement,
474
+ scope: ExecutionScope,
475
+ outputs: Record<string, unknown>,
476
+ ): Promise<StepResult> {
477
+ const tryCatch = statement as {
478
+ try_body?: AstStatement[];
479
+ catch_name?: string;
480
+ catch_body?: AstStatement[];
481
+ finally_body?: AstStatement[];
482
+ };
483
+
484
+ let success = true;
485
+ let error: string | undefined;
486
+
487
+ try {
488
+ for (const stmt of tryCatch.try_body ?? []) {
489
+ await this.executeStatement(stmt, scope, outputs);
490
+ }
491
+ } catch (err) {
492
+ success = false;
493
+ error = err instanceof Error ? err.message : String(err);
494
+
495
+ if (tryCatch.catch_body) {
496
+ const catchScope = createChildScope(scope, {
497
+ [tryCatch.catch_name ?? 'err']: error,
498
+ });
499
+ for (const stmt of tryCatch.catch_body) {
500
+ await this.executeStatement(stmt, catchScope, outputs);
501
+ }
502
+ }
503
+ } finally {
504
+ if (tryCatch.finally_body) {
505
+ for (const stmt of tryCatch.finally_body) {
506
+ await this.executeStatement(stmt, scope, outputs);
507
+ }
508
+ }
509
+ }
510
+
511
+ return { name: 'try-catch', type: 'conditional', success, error, duration: 0 };
512
+ }
513
+
514
+ /** Execute a CANT directive statement. */
515
+ private async executeDirective(
516
+ statement: AstStatement,
517
+ _scope: ExecutionScope,
518
+ ): Promise<StepResult> {
519
+ const directive = statement as {
520
+ verb?: string;
521
+ addresses?: string[];
522
+ task_refs?: string[];
523
+ };
524
+
525
+ // Stub: real implementation dispatches via CLEO operations
526
+ return {
527
+ name: `/${directive.verb ?? 'unknown'}`,
528
+ type: 'directive',
529
+ success: true,
530
+ output: {
531
+ verb: directive.verb,
532
+ addresses: directive.addresses,
533
+ taskRefs: directive.task_refs,
534
+ },
535
+ duration: 0,
536
+ };
537
+ }
538
+
539
+ /**
540
+ * Evaluate a condition (regular expression or discretion).
541
+ */
542
+ private async evaluateCondition(condition: unknown, scope: ExecutionScope): Promise<boolean> {
543
+ if (!condition) return true;
544
+
545
+ const cond = condition as {
546
+ Discretion?: { prose: string };
547
+ Expression?: unknown;
548
+ };
549
+
550
+ if (cond.Discretion) {
551
+ const context: DiscretionContext = {
552
+ sessionId: this.config.sessionId ?? '',
553
+ taskRefs: [],
554
+ agentId: this.config.agentId ?? '',
555
+ variables: flattenScope(scope),
556
+ condition: cond.Discretion.prose,
557
+ precedingResults: {},
558
+ };
559
+ return this.discretionEvaluator.evaluate(cond.Discretion.prose, context);
560
+ }
561
+
562
+ // For regular expressions, return true as a stub
563
+ // Real implementation would evaluate the expression against the scope
564
+ return true;
565
+ }
566
+ }
567
+
568
+ // ---------------------------------------------------------------------------
569
+ // Helpers
570
+ // ---------------------------------------------------------------------------
571
+
572
+ /** Detect the statement type from an AST statement object. */
573
+ function detectStatementType(statement: AstStatement): string {
574
+ if ('Binding' in statement) return 'Binding';
575
+ if ('Output' in statement) return 'Output';
576
+ if ('Conditional' in statement || ('condition' in statement && 'then_body' in statement))
577
+ return 'Conditional';
578
+ if ('Parallel' in statement || 'arms' in statement) return 'Parallel';
579
+ if ('Session' in statement || 'target' in statement) return 'Session';
580
+ if ('Pipeline' in statement || ('steps' in statement && 'name' in statement)) return 'Pipeline';
581
+ if ('ApprovalGate' in statement) return 'ApprovalGate';
582
+ if ('Repeat' in statement || 'count' in statement) return 'Repeat';
583
+ if ('ForLoop' in statement || ('variable' in statement && 'iterable' in statement))
584
+ return 'ForLoop';
585
+ if ('LoopUntil' in statement) return 'LoopUntil';
586
+ if ('TryCatch' in statement || 'try_body' in statement) return 'TryCatch';
587
+ if ('Directive' in statement || 'verb' in statement) return 'Directive';
588
+ if ('Comment' in statement || 'text' in statement) return 'Comment';
589
+ return statement.type ?? 'unknown';
590
+ }
591
+
592
+ /** Extract a human-readable name from a statement. */
593
+ function getStatementName(statement: AstStatement): string {
594
+ const named = statement as { name?: { value: string } | string; verb?: string };
595
+ if (typeof named.name === 'object' && named.name?.value) return named.name.value;
596
+ if (typeof named.name === 'string') return named.name;
597
+ if (named.verb) return `/${named.verb}`;
598
+ return detectStatementType(statement);
599
+ }
600
+
601
+ /** Map a statement to a StepResult type category. */
602
+ function getStatementType(statement: AstStatement): StepResult['type'] {
603
+ const t = detectStatementType(statement);
604
+ const mapping: Record<string, StepResult['type']> = {
605
+ Session: 'session',
606
+ Pipeline: 'pipeline',
607
+ Parallel: 'parallel',
608
+ Conditional: 'conditional',
609
+ Repeat: 'loop',
610
+ ForLoop: 'loop',
611
+ LoopUntil: 'loop',
612
+ ApprovalGate: 'approval',
613
+ Binding: 'binding',
614
+ Output: 'output',
615
+ Directive: 'directive',
616
+ };
617
+ return mapping[t] ?? 'binding';
618
+ }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Code analysis via tree-sitter AST parsing.
3
+ *
4
+ * @module code
5
+ */
6
+
7
+ export { type OutlineNode, type SmartOutlineResult, smartOutline } from './outline.js';
8
+ export { batchParse, parseFile } from './parser.js';
9
+ export { type SmartSearchOptions, type SmartSearchResult, smartSearch } from './search.js';
10
+ export { type SmartUnfoldResult, smartUnfold } from './unfold.js';