opensquid 0.5.432 → 0.5.447

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 (440) hide show
  1. package/README.md +1 -0
  2. package/dist/functions/arm_scope.d.ts +27 -0
  3. package/dist/functions/arm_scope.d.ts.map +1 -0
  4. package/dist/functions/arm_scope.js +52 -0
  5. package/dist/functions/arm_scope.js.map +1 -0
  6. package/dist/functions/event.d.ts.map +1 -1
  7. package/dist/functions/event.js +18 -2
  8. package/dist/functions/event.js.map +1 -1
  9. package/dist/functions/index.d.ts +4 -0
  10. package/dist/functions/index.d.ts.map +1 -1
  11. package/dist/functions/index.js +4 -0
  12. package/dist/functions/index.js.map +1 -1
  13. package/dist/functions/inject_context.d.ts +18 -0
  14. package/dist/functions/inject_context.d.ts.map +1 -0
  15. package/dist/functions/inject_context.js +16 -0
  16. package/dist/functions/inject_context.js.map +1 -0
  17. package/dist/functions/procedure_pre_inject.d.ts +23 -0
  18. package/dist/functions/procedure_pre_inject.d.ts.map +1 -0
  19. package/dist/functions/procedure_pre_inject.js +49 -0
  20. package/dist/functions/procedure_pre_inject.js.map +1 -0
  21. package/dist/functions/registry.d.ts +6 -0
  22. package/dist/functions/registry.d.ts.map +1 -1
  23. package/dist/functions/registry.js.map +1 -1
  24. package/dist/functions/rubric_pre_inject.d.ts.map +1 -1
  25. package/dist/functions/rubric_pre_inject.js +2 -1
  26. package/dist/functions/rubric_pre_inject.js.map +1 -1
  27. package/dist/functions/set_request_type.d.ts +11 -0
  28. package/dist/functions/set_request_type.d.ts.map +1 -0
  29. package/dist/functions/set_request_type.js +34 -0
  30. package/dist/functions/set_request_type.js.map +1 -0
  31. package/dist/functions/shell_parse.d.ts +1 -0
  32. package/dist/functions/shell_parse.d.ts.map +1 -1
  33. package/dist/functions/shell_parse.js +22 -4
  34. package/dist/functions/shell_parse.js.map +1 -1
  35. package/dist/packs/loader.d.ts.map +1 -1
  36. package/dist/packs/loader.js +26 -0
  37. package/dist/packs/loader.js.map +1 -1
  38. package/dist/runtime/bootstrap.d.ts.map +1 -1
  39. package/dist/runtime/bootstrap.js +6 -0
  40. package/dist/runtime/bootstrap.js.map +1 -1
  41. package/dist/runtime/fsm_state.d.ts +6 -0
  42. package/dist/runtime/fsm_state.d.ts.map +1 -1
  43. package/dist/runtime/fsm_state.js +14 -0
  44. package/dist/runtime/fsm_state.js.map +1 -1
  45. package/dist/runtime/handoff/render.d.ts +5 -4
  46. package/dist/runtime/handoff/render.d.ts.map +1 -1
  47. package/dist/runtime/handoff/render.js +7 -7
  48. package/dist/runtime/handoff/render.js.map +1 -1
  49. package/dist/runtime/handoff/stranded_scoping.d.ts +21 -0
  50. package/dist/runtime/handoff/stranded_scoping.d.ts.map +1 -0
  51. package/dist/runtime/handoff/stranded_scoping.js +39 -0
  52. package/dist/runtime/handoff/stranded_scoping.js.map +1 -0
  53. package/dist/runtime/hooks/active_task_mirror.js +0 -0
  54. package/dist/runtime/hooks/apply_patch.js +0 -0
  55. package/dist/runtime/hooks/dispatch.d.ts.map +1 -1
  56. package/dist/runtime/hooks/dispatch.js +3 -0
  57. package/dist/runtime/hooks/dispatch.js.map +1 -1
  58. package/dist/runtime/hooks/hook_output.js +0 -0
  59. package/dist/runtime/hooks/memory_reconcile.js +0 -0
  60. package/dist/runtime/hooks/new_project_detect.js +0 -0
  61. package/dist/runtime/hooks/profession_resolver.js +0 -0
  62. package/dist/runtime/hooks/scope_intent.js +0 -0
  63. package/dist/runtime/hooks/session-start.js +17 -0
  64. package/dist/runtime/hooks/session-start.js.map +1 -1
  65. package/dist/runtime/hooks/session_id.js +0 -0
  66. package/dist/runtime/hooks/session_liveness.js +0 -0
  67. package/dist/runtime/hooks/stop_drive.js +0 -0
  68. package/dist/runtime/hooks/stop_stream.js +0 -0
  69. package/dist/runtime/hooks/subagent_guard.js +0 -0
  70. package/dist/runtime/hooks/transcript.js +0 -0
  71. package/dist/runtime/hooks/transcript_tasks.js +0 -0
  72. package/dist/runtime/hooks/user-prompt-submit.d.ts.map +1 -1
  73. package/dist/runtime/hooks/user-prompt-submit.js +22 -1
  74. package/dist/runtime/hooks/user-prompt-submit.js.map +1 -1
  75. package/dist/runtime/ralph/orchestrator.d.ts.map +1 -1
  76. package/dist/runtime/ralph/orchestrator.js +2 -1
  77. package/dist/runtime/ralph/orchestrator.js.map +1 -1
  78. package/dist/runtime/request_type.d.ts +33 -0
  79. package/dist/runtime/request_type.d.ts.map +1 -0
  80. package/dist/runtime/request_type.js +38 -0
  81. package/dist/runtime/request_type.js.map +1 -0
  82. package/dist/runtime/session_state.d.ts +11 -0
  83. package/dist/runtime/session_state.d.ts.map +1 -1
  84. package/dist/runtime/session_state.js +30 -0
  85. package/dist/runtime/session_state.js.map +1 -1
  86. package/dist/runtime/types.d.ts +5 -0
  87. package/dist/runtime/types.d.ts.map +1 -1
  88. package/dist/runtime/types.js +3 -0
  89. package/dist/runtime/types.js.map +1 -1
  90. package/dist/setup/cli/limits_state.d.ts.map +1 -1
  91. package/dist/setup/cli/limits_state.js +6 -40
  92. package/dist/setup/cli/limits_state.js.map +1 -1
  93. package/dist/setup/cli/pack_walk.d.ts +32 -0
  94. package/dist/setup/cli/pack_walk.d.ts.map +1 -0
  95. package/dist/setup/cli/pack_walk.js +76 -0
  96. package/dist/setup/cli/pack_walk.js.map +1 -0
  97. package/dist/setup/cli/permissions_state.d.ts.map +1 -1
  98. package/dist/setup/cli/permissions_state.js +6 -37
  99. package/dist/setup/cli/permissions_state.js.map +1 -1
  100. package/dist/setup/cli/triggers_state.d.ts.map +1 -1
  101. package/dist/setup/cli/triggers_state.js +3 -29
  102. package/dist/setup/cli/triggers_state.js.map +1 -1
  103. package/dist/workgraph/events.d.ts.map +1 -1
  104. package/dist/workgraph/events.js +10 -0
  105. package/dist/workgraph/events.js.map +1 -1
  106. package/dist/workgraph/store.d.ts.map +1 -1
  107. package/dist/workgraph/store.js +5 -0
  108. package/dist/workgraph/store.js.map +1 -1
  109. package/dist/workgraph/types.d.ts +2 -1
  110. package/dist/workgraph/types.d.ts.map +1 -1
  111. package/docs/ARCHITECTURE.md +268 -0
  112. package/docs/pack-runtime.md +26 -10
  113. package/package.json +5 -3
  114. package/packs/builtin/coding-flow/procedure.md +43 -0
  115. package/packs/builtin/coding-flow/skills/entry-and-handoffs/skill.yaml +49 -6
  116. package/packs/builtin/coding-flow/skills/pause-stop-guard/skill.yaml +11 -1
  117. package/packs/builtin/default-discipline/manifest.yaml +15 -6
  118. package/packs/builtin/pack-architect/skills/skill-yaml-author-walkthrough/skill.yaml +8 -0
  119. package/dist/anti-drift/evaluator.d.ts +0 -88
  120. package/dist/anti-drift/evaluator.d.ts.map +0 -1
  121. package/dist/anti-drift/evaluator.js +0 -417
  122. package/dist/anti-drift/evaluator.js.map +0 -1
  123. package/dist/anti-drift/evaluator.test.js +0 -78
  124. package/dist/anti-drift/rules.d.ts +0 -80
  125. package/dist/anti-drift/rules.d.ts.map +0 -1
  126. package/dist/anti-drift/rules.js +0 -368
  127. package/dist/anti-drift/rules.js.map +0 -1
  128. package/dist/anti-drift/rules.test.js +0 -213
  129. package/dist/anti-drift/state.d.ts +0 -107
  130. package/dist/anti-drift/state.d.ts.map +0 -1
  131. package/dist/anti-drift/state.js +0 -177
  132. package/dist/anti-drift/state.js.map +0 -1
  133. package/dist/anti-drift/state.test.js +0 -120
  134. package/dist/chat/adapters/discord.d.ts +0 -41
  135. package/dist/chat/adapters/discord.d.ts.map +0 -1
  136. package/dist/chat/adapters/discord.js +0 -176
  137. package/dist/chat/adapters/discord.js.map +0 -1
  138. package/dist/chat/adapters/discord.test.js +0 -25
  139. package/dist/chat/adapters/slack.d.ts +0 -43
  140. package/dist/chat/adapters/slack.d.ts.map +0 -1
  141. package/dist/chat/adapters/slack.js +0 -172
  142. package/dist/chat/adapters/slack.js.map +0 -1
  143. package/dist/chat/adapters/slack.test.js +0 -30
  144. package/dist/chat/adapters/telegram.d.ts +0 -148
  145. package/dist/chat/adapters/telegram.d.ts.map +0 -1
  146. package/dist/chat/adapters/telegram.js +0 -498
  147. package/dist/chat/adapters/telegram.js.map +0 -1
  148. package/dist/chat/adapters/telegram.test.js +0 -94
  149. package/dist/chat/config.d.ts +0 -98
  150. package/dist/chat/config.d.ts.map +0 -1
  151. package/dist/chat/config.js +0 -185
  152. package/dist/chat/config.js.map +0 -1
  153. package/dist/chat/daemon/active-project.d.ts +0 -17
  154. package/dist/chat/daemon/active-project.d.ts.map +0 -1
  155. package/dist/chat/daemon/active-project.js +0 -23
  156. package/dist/chat/daemon/active-project.js.map +0 -1
  157. package/dist/chat/daemon/autospawn.d.ts +0 -40
  158. package/dist/chat/daemon/autospawn.d.ts.map +0 -1
  159. package/dist/chat/daemon/autospawn.js +0 -129
  160. package/dist/chat/daemon/autospawn.js.map +0 -1
  161. package/dist/chat/daemon/autospawn.test.js +0 -112
  162. package/dist/chat/daemon/cli.d.ts +0 -18
  163. package/dist/chat/daemon/cli.d.ts.map +0 -1
  164. package/dist/chat/daemon/cli.js +0 -71
  165. package/dist/chat/daemon/cli.js.map +0 -1
  166. package/dist/chat/daemon/collisions.js +0 -384
  167. package/dist/chat/daemon/health-check.d.ts +0 -69
  168. package/dist/chat/daemon/health-check.d.ts.map +0 -1
  169. package/dist/chat/daemon/health-check.js +0 -112
  170. package/dist/chat/daemon/health-check.js.map +0 -1
  171. package/dist/chat/daemon/inbox-read.d.ts +0 -35
  172. package/dist/chat/daemon/inbox-read.d.ts.map +0 -1
  173. package/dist/chat/daemon/inbox-read.js +0 -75
  174. package/dist/chat/daemon/inbox-read.js.map +0 -1
  175. package/dist/chat/daemon/inbox-read.test.js +0 -97
  176. package/dist/chat/daemon/inbox.d.ts +0 -63
  177. package/dist/chat/daemon/inbox.d.ts.map +0 -1
  178. package/dist/chat/daemon/inbox.js +0 -56
  179. package/dist/chat/daemon/inbox.js.map +0 -1
  180. package/dist/chat/daemon/inbox.test.js +0 -110
  181. package/dist/chat/daemon/lifecycle.d.ts +0 -71
  182. package/dist/chat/daemon/lifecycle.d.ts.map +0 -1
  183. package/dist/chat/daemon/lifecycle.js +0 -221
  184. package/dist/chat/daemon/lifecycle.js.map +0 -1
  185. package/dist/chat/daemon/lifecycle.test.js +0 -163
  186. package/dist/chat/daemon/protocol.d.ts +0 -107
  187. package/dist/chat/daemon/protocol.d.ts.map +0 -1
  188. package/dist/chat/daemon/protocol.js +0 -54
  189. package/dist/chat/daemon/protocol.js.map +0 -1
  190. package/dist/chat/daemon/routing.d.ts +0 -140
  191. package/dist/chat/daemon/routing.d.ts.map +0 -1
  192. package/dist/chat/daemon/routing.js +0 -198
  193. package/dist/chat/daemon/routing.js.map +0 -1
  194. package/dist/chat/daemon/routing.test.js +0 -259
  195. package/dist/chat/daemon/rpc-client.d.ts +0 -45
  196. package/dist/chat/daemon/rpc-client.d.ts.map +0 -1
  197. package/dist/chat/daemon/rpc-client.js +0 -133
  198. package/dist/chat/daemon/rpc-client.js.map +0 -1
  199. package/dist/chat/daemon/rpc-server.d.ts +0 -39
  200. package/dist/chat/daemon/rpc-server.d.ts.map +0 -1
  201. package/dist/chat/daemon/rpc-server.js +0 -385
  202. package/dist/chat/daemon/rpc-server.js.map +0 -1
  203. package/dist/chat/daemon/rpc.test.js +0 -177
  204. package/dist/chat/daemon/subscribers.js +0 -257
  205. package/dist/chat/daemon/worker.d.ts +0 -27
  206. package/dist/chat/daemon/worker.d.ts.map +0 -1
  207. package/dist/chat/daemon/worker.js +0 -313
  208. package/dist/chat/daemon/worker.js.map +0 -1
  209. package/dist/chat/daemon/workspace-topic.js +0 -324
  210. package/dist/chat/env-token.d.ts +0 -60
  211. package/dist/chat/env-token.d.ts.map +0 -1
  212. package/dist/chat/env-token.js +0 -137
  213. package/dist/chat/env-token.js.map +0 -1
  214. package/dist/chat/env-token.test.js +0 -160
  215. package/dist/chat/factory.d.ts +0 -30
  216. package/dist/chat/factory.d.ts.map +0 -1
  217. package/dist/chat/factory.js +0 -50
  218. package/dist/chat/factory.js.map +0 -1
  219. package/dist/chat/factory.test.js +0 -55
  220. package/dist/chat/gateway.d.ts +0 -176
  221. package/dist/chat/gateway.d.ts.map +0 -1
  222. package/dist/chat/gateway.js +0 -146
  223. package/dist/chat/gateway.js.map +0 -1
  224. package/dist/chat/gateway.test.js +0 -192
  225. package/dist/claude-md.d.ts +0 -39
  226. package/dist/claude-md.d.ts.map +0 -1
  227. package/dist/claude-md.js +0 -113
  228. package/dist/claude-md.js.map +0 -1
  229. package/dist/claude-md.test.js +0 -91
  230. package/dist/codex/activate.d.ts +0 -66
  231. package/dist/codex/activate.d.ts.map +0 -1
  232. package/dist/codex/activate.js +0 -329
  233. package/dist/codex/activate.js.map +0 -1
  234. package/dist/codex/activate.test.js +0 -229
  235. package/dist/codex/bundled-default/bundled-default.test.js +0 -161
  236. package/dist/codex/cli-publish.test.js +0 -133
  237. package/dist/codex/cli.d.ts +0 -35
  238. package/dist/codex/cli.d.ts.map +0 -1
  239. package/dist/codex/cli.js +0 -554
  240. package/dist/codex/cli.js.map +0 -1
  241. package/dist/codex/cli.test.js +0 -277
  242. package/dist/codex/import-skill-md.d.ts +0 -53
  243. package/dist/codex/import-skill-md.d.ts.map +0 -1
  244. package/dist/codex/import-skill-md.js +0 -236
  245. package/dist/codex/import-skill-md.js.map +0 -1
  246. package/dist/codex/import-skill-md.test.js +0 -225
  247. package/dist/codex/loader.d.ts +0 -27
  248. package/dist/codex/loader.d.ts.map +0 -1
  249. package/dist/codex/loader.js +0 -86
  250. package/dist/codex/loader.js.map +0 -1
  251. package/dist/codex/loader.test.js +0 -75
  252. package/dist/codex/parse.d.ts +0 -28
  253. package/dist/codex/parse.d.ts.map +0 -1
  254. package/dist/codex/parse.js +0 -309
  255. package/dist/codex/parse.js.map +0 -1
  256. package/dist/codex/parse.test.js +0 -241
  257. package/dist/codex/store.d.ts +0 -87
  258. package/dist/codex/store.d.ts.map +0 -1
  259. package/dist/codex/store.js +0 -205
  260. package/dist/codex/store.js.map +0 -1
  261. package/dist/codex/store.test.js +0 -242
  262. package/dist/codex/types.d.ts +0 -398
  263. package/dist/codex/types.d.ts.map +0 -1
  264. package/dist/codex/types.js +0 -21
  265. package/dist/codex/types.js.map +0 -1
  266. package/dist/config.d.ts +0 -53
  267. package/dist/config.d.ts.map +0 -1
  268. package/dist/config.js +0 -202
  269. package/dist/config.js.map +0 -1
  270. package/dist/config.test.js +0 -117
  271. package/dist/engine/cli.d.ts +0 -14
  272. package/dist/engine/cli.d.ts.map +0 -1
  273. package/dist/engine/cli.js +0 -171
  274. package/dist/engine/cli.js.map +0 -1
  275. package/dist/engine/client.d.ts +0 -219
  276. package/dist/engine/client.d.ts.map +0 -1
  277. package/dist/engine/client.js +0 -312
  278. package/dist/engine/client.js.map +0 -1
  279. package/dist/engine/config.d.ts +0 -62
  280. package/dist/engine/config.d.ts.map +0 -1
  281. package/dist/engine/config.js +0 -223
  282. package/dist/engine/config.js.map +0 -1
  283. package/dist/engine/index.d.ts +0 -17
  284. package/dist/engine/index.d.ts.map +0 -1
  285. package/dist/engine/index.js +0 -16
  286. package/dist/engine/index.js.map +0 -1
  287. package/dist/engine/resolver.d.ts +0 -62
  288. package/dist/engine/resolver.d.ts.map +0 -1
  289. package/dist/engine/resolver.js +0 -103
  290. package/dist/engine/resolver.js.map +0 -1
  291. package/dist/engine/singleton.d.ts +0 -95
  292. package/dist/engine/singleton.d.ts.map +0 -1
  293. package/dist/engine/singleton.js +0 -325
  294. package/dist/engine/singleton.js.map +0 -1
  295. package/dist/engine/types.d.ts +0 -402
  296. package/dist/engine/types.d.ts.map +0 -1
  297. package/dist/engine/types.js +0 -22
  298. package/dist/engine/types.js.map +0 -1
  299. package/dist/engine-binary-resolver.js +0 -110
  300. package/dist/engine-binary-resolver.test.js +0 -61
  301. package/dist/engine-cli.js +0 -60
  302. package/dist/engine-client.js +0 -301
  303. package/dist/engine-client.test.js +0 -118
  304. package/dist/functions/chain_state.d.ts +0 -51
  305. package/dist/functions/chain_state.d.ts.map +0 -1
  306. package/dist/functions/chain_state.js +0 -59
  307. package/dist/functions/chain_state.js.map +0 -1
  308. package/dist/hooks/drift-catalog.d.ts +0 -68
  309. package/dist/hooks/drift-catalog.d.ts.map +0 -1
  310. package/dist/hooks/drift-catalog.js +0 -184
  311. package/dist/hooks/drift-catalog.js.map +0 -1
  312. package/dist/hooks/drift-catalog.test.js +0 -154
  313. package/dist/hooks/drift-patterns.d.ts +0 -110
  314. package/dist/hooks/drift-patterns.d.ts.map +0 -1
  315. package/dist/hooks/drift-patterns.js +0 -289
  316. package/dist/hooks/drift-patterns.js.map +0 -1
  317. package/dist/hooks/drift-patterns.test.js +0 -325
  318. package/dist/hooks/engine-vocab-gate.d.ts +0 -108
  319. package/dist/hooks/engine-vocab-gate.d.ts.map +0 -1
  320. package/dist/hooks/engine-vocab-gate.js +0 -225
  321. package/dist/hooks/engine-vocab-gate.js.map +0 -1
  322. package/dist/hooks/engine-vocab-gate.test.js +0 -170
  323. package/dist/hooks/heartbeat.d.ts +0 -107
  324. package/dist/hooks/heartbeat.d.ts.map +0 -1
  325. package/dist/hooks/heartbeat.js +0 -316
  326. package/dist/hooks/heartbeat.js.map +0 -1
  327. package/dist/hooks/heartbeat.test.js +0 -393
  328. package/dist/hooks/honesty-ledger-session-scope.test.js +0 -100
  329. package/dist/hooks/honesty-ledger.d.ts +0 -123
  330. package/dist/hooks/honesty-ledger.d.ts.map +0 -1
  331. package/dist/hooks/honesty-ledger.js +0 -226
  332. package/dist/hooks/honesty-ledger.js.map +0 -1
  333. package/dist/hooks/honesty-ledger.test.js +0 -466
  334. package/dist/hooks/inline-report-check.d.ts +0 -63
  335. package/dist/hooks/inline-report-check.d.ts.map +0 -1
  336. package/dist/hooks/inline-report-check.js +0 -88
  337. package/dist/hooks/inline-report-check.js.map +0 -1
  338. package/dist/hooks/inline-report-check.test.js +0 -96
  339. package/dist/hooks/pre-tool-use.d.ts +0 -62
  340. package/dist/hooks/pre-tool-use.d.ts.map +0 -1
  341. package/dist/hooks/pre-tool-use.js +0 -342
  342. package/dist/hooks/pre-tool-use.js.map +0 -1
  343. package/dist/hooks/pre-tool-use.test.js +0 -134
  344. package/dist/hooks/session-end.d.ts +0 -15
  345. package/dist/hooks/session-end.d.ts.map +0 -1
  346. package/dist/hooks/session-end.js +0 -60
  347. package/dist/hooks/session-end.js.map +0 -1
  348. package/dist/hooks/session-end.test.js +0 -52
  349. package/dist/hooks/stop.d.ts +0 -35
  350. package/dist/hooks/stop.d.ts.map +0 -1
  351. package/dist/hooks/stop.js +0 -136
  352. package/dist/hooks/stop.js.map +0 -1
  353. package/dist/hooks/transcript-active-task.test.js +0 -342
  354. package/dist/hooks/transcript.d.ts +0 -26
  355. package/dist/hooks/transcript.d.ts.map +0 -1
  356. package/dist/hooks/transcript.js +0 -266
  357. package/dist/hooks/transcript.js.map +0 -1
  358. package/dist/hooks/transcript.test.js +0 -103
  359. package/dist/hooks/user-prompt-submit.d.ts +0 -74
  360. package/dist/hooks/user-prompt-submit.d.ts.map +0 -1
  361. package/dist/hooks/user-prompt-submit.js +0 -256
  362. package/dist/hooks/user-prompt-submit.js.map +0 -1
  363. package/dist/hooks/user-prompt-submit.test.js +0 -118
  364. package/dist/hooks/versioning-gate.d.ts +0 -101
  365. package/dist/hooks/versioning-gate.d.ts.map +0 -1
  366. package/dist/hooks/versioning-gate.js +0 -245
  367. package/dist/hooks/versioning-gate.js.map +0 -1
  368. package/dist/hooks/versioning-gate.test.js +0 -368
  369. package/dist/hooks/workflow-gate.d.ts +0 -64
  370. package/dist/hooks/workflow-gate.d.ts.map +0 -1
  371. package/dist/hooks/workflow-gate.js +0 -152
  372. package/dist/hooks/workflow-gate.js.map +0 -1
  373. package/dist/hooks/workflow-gate.test.js +0 -197
  374. package/dist/hooks-cli.d.ts +0 -25
  375. package/dist/hooks-cli.d.ts.map +0 -1
  376. package/dist/hooks-cli.js +0 -286
  377. package/dist/hooks-cli.js.map +0 -1
  378. package/dist/hooks-cli.test.js +0 -148
  379. package/dist/origin.d.ts +0 -16
  380. package/dist/origin.d.ts.map +0 -1
  381. package/dist/origin.js +0 -92
  382. package/dist/origin.js.map +0 -1
  383. package/dist/packs/seed_lessons_ingest.d.ts +0 -30
  384. package/dist/packs/seed_lessons_ingest.d.ts.map +0 -1
  385. package/dist/packs/seed_lessons_ingest.js +0 -107
  386. package/dist/packs/seed_lessons_ingest.js.map +0 -1
  387. package/dist/project-cli.d.ts +0 -7
  388. package/dist/project-cli.d.ts.map +0 -1
  389. package/dist/project-cli.js +0 -145
  390. package/dist/project-cli.js.map +0 -1
  391. package/dist/project.d.ts +0 -127
  392. package/dist/project.d.ts.map +0 -1
  393. package/dist/project.js +0 -281
  394. package/dist/project.js.map +0 -1
  395. package/dist/project.test.js +0 -287
  396. package/dist/rag/backends/loop_engine.d.ts +0 -61
  397. package/dist/rag/backends/loop_engine.d.ts.map +0 -1
  398. package/dist/rag/backends/loop_engine.js +0 -160
  399. package/dist/rag/backends/loop_engine.js.map +0 -1
  400. package/dist/recall.d.ts +0 -82
  401. package/dist/recall.d.ts.map +0 -1
  402. package/dist/recall.js +0 -81
  403. package/dist/recall.js.map +0 -1
  404. package/dist/runtime/agent_bridge/autospawn.d.ts +0 -131
  405. package/dist/runtime/agent_bridge/autospawn.d.ts.map +0 -1
  406. package/dist/runtime/agent_bridge/autospawn.js +0 -251
  407. package/dist/runtime/agent_bridge/autospawn.js.map +0 -1
  408. package/dist/runtime/chain_state.d.ts +0 -124
  409. package/dist/runtime/chain_state.d.ts.map +0 -1
  410. package/dist/runtime/chain_state.js +0 -189
  411. package/dist/runtime/chain_state.js.map +0 -1
  412. package/dist/runtime/hooks/permission_decision.d.ts +0 -34
  413. package/dist/runtime/hooks/permission_decision.d.ts.map +0 -1
  414. package/dist/runtime/hooks/permission_decision.js +0 -39
  415. package/dist/runtime/hooks/permission_decision.js.map +0 -1
  416. package/dist/runtime/workflow_fsm.d.ts +0 -21
  417. package/dist/runtime/workflow_fsm.d.ts.map +0 -1
  418. package/dist/runtime/workflow_fsm.js +0 -25
  419. package/dist/runtime/workflow_fsm.js.map +0 -1
  420. package/dist/runtime/workflow_map.d.ts +0 -26
  421. package/dist/runtime/workflow_map.d.ts.map +0 -1
  422. package/dist/runtime/workflow_map.js +0 -38
  423. package/dist/runtime/workflow_map.js.map +0 -1
  424. package/dist/scope.d.ts +0 -48
  425. package/dist/scope.d.ts.map +0 -1
  426. package/dist/scope.js +0 -111
  427. package/dist/scope.js.map +0 -1
  428. package/dist/setup/cli/topic_create_step.d.ts +0 -84
  429. package/dist/setup/cli/topic_create_step.d.ts.map +0 -1
  430. package/dist/setup/cli/topic_create_step.js +0 -213
  431. package/dist/setup/cli/topic_create_step.js.map +0 -1
  432. package/dist/system-export.d.ts +0 -65
  433. package/dist/system-export.d.ts.map +0 -1
  434. package/dist/system-export.js +0 -194
  435. package/dist/system-export.js.map +0 -1
  436. package/dist/utterance/classifier.d.ts +0 -53
  437. package/dist/utterance/classifier.d.ts.map +0 -1
  438. package/dist/utterance/classifier.js +0 -184
  439. package/dist/utterance/classifier.js.map +0 -1
  440. package/dist/utterance/classifier.test.js +0 -147
@@ -1 +0,0 @@
1
- {"version":3,"file":"session-end.d.ts","sourceRoot":"","sources":["../../src.legacy/hooks/session-end.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAaH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC,CA+CvD"}
@@ -1,60 +0,0 @@
1
- /**
2
- * `opensquid hook session-end` — Claude Code SessionEnd hook handler.
3
- *
4
- * Fires when a Claude Code session terminates. Wipes the session's
5
- * honesty-ledger state (turn-ledger.jsonl + broken-promises.jsonl) so
6
- * the ledger doesn't grow unbounded across all-time sessions.
7
- *
8
- * Without this hook, every Claude Code session creates a
9
- * <data-root>/sessions/<id>/ directory with two JSONL files that
10
- * never get cleaned up. Disk usage grows linearly with session count.
11
- *
12
- * Exit 0 always — SessionEnd is cleanup, not blocking.
13
- */
14
- import { runDriftCatalogScan } from "./drift-catalog.js";
15
- import { clearSession } from "./honesty-ledger.js";
16
- export async function runSessionEndHook() {
17
- let raw = "";
18
- for await (const chunk of process.stdin) {
19
- raw += chunk;
20
- }
21
- if (!raw.trim())
22
- process.exit(0);
23
- let payload;
24
- try {
25
- payload = JSON.parse(raw);
26
- }
27
- catch {
28
- process.exit(0);
29
- }
30
- const sessionId = payload.session_id;
31
- if (!sessionId)
32
- process.exit(0);
33
- // 0.7.22 / D10 — automated drift catalog. Scan the transcript for
34
- // drift markers (user corrections, locked-rule citations, agent
35
- // mea-culpas) and append to the project's drift-catalog.jsonl. Runs
36
- // BEFORE clearSession so any session-scoped state used for context
37
- // is still available.
38
- try {
39
- const count = await runDriftCatalogScan({
40
- sessionId,
41
- transcriptPath: payload.transcript_path,
42
- cwd: payload.cwd,
43
- });
44
- if (count > 0) {
45
- process.stderr.write(`🦑 [opensquid drift-catalog] recorded ${count} drift marker(s)\n`);
46
- }
47
- }
48
- catch (err) {
49
- process.stderr.write(`[opensquid hook session-end] drift-catalog scan failed (non-fatal): ${err instanceof Error ? err.message : err}\n`);
50
- }
51
- try {
52
- await clearSession(sessionId);
53
- }
54
- catch (err) {
55
- // Cleanup failure is non-fatal — disk-space leak, not a correctness bug.
56
- process.stderr.write(`[opensquid hook session-end] clearSession failed: ${err instanceof Error ? err.message : err}\n`);
57
- }
58
- process.exit(0);
59
- }
60
- //# sourceMappingURL=session-end.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"session-end.js","sourceRoot":"","sources":["../../src.legacy/hooks/session-end.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAUnD,MAAM,CAAC,KAAK,UAAU,iBAAiB;IACrC,IAAI,GAAG,GAAG,EAAE,CAAC;IACb,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;QACxC,GAAG,IAAI,KAAK,CAAC;IACf,CAAC;IACD,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE;QAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAEjC,IAAI,OAAwB,CAAC;IAC7B,IAAI,CAAC;QACH,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC5B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC;IACrC,IAAI,CAAC,SAAS;QAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAEhC,kEAAkE;IAClE,gEAAgE;IAChE,oEAAoE;IACpE,mEAAmE;IACnE,sBAAsB;IACtB,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,mBAAmB,CAAC;YACtC,SAAS;YACT,cAAc,EAAE,OAAO,CAAC,eAAe;YACvC,GAAG,EAAE,OAAO,CAAC,GAAG;SACjB,CAAC,CAAC;QACH,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;YACd,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,yCAAyC,KAAK,oBAAoB,CAAC,CAAC;QAC3F,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,uEAAuE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI,CACpH,CAAC;IACJ,CAAC;IAED,IAAI,CAAC;QACH,MAAM,YAAY,CAAC,SAAS,CAAC,CAAC;IAChC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,yEAAyE;QACzE,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,qDAAqD,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI,CAClG,CAAC;IACJ,CAAC;IAED,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC"}
@@ -1,52 +0,0 @@
1
- import * as crypto from "node:crypto";
2
- import { promises as fs } from "node:fs";
3
- import * as os from "node:os";
4
- import * as path from "node:path";
5
- import { afterEach, beforeEach, describe, expect, it } from "vitest";
6
- import { clearSession, readBrokenPromises, readTurnLedger, recordBrokenPromise, recordToolCall, } from "./honesty-ledger.js";
7
- let tmpRoot;
8
- const SESSION = "session-end-test";
9
- beforeEach(async () => {
10
- tmpRoot = path.join(os.tmpdir(), `oscli-session-end-${crypto.randomUUID()}`);
11
- await fs.mkdir(tmpRoot, { recursive: true });
12
- });
13
- afterEach(async () => {
14
- await fs.rm(tmpRoot, { recursive: true, force: true });
15
- });
16
- describe("SessionEnd cleanup (clearSession via the hook)", () => {
17
- it("wipes both ledger and broken-promises after population", async () => {
18
- await recordToolCall(SESSION, "Bash", "npm test", { dataRoot: tmpRoot });
19
- await recordToolCall(SESSION, "Bash", "git commit -m foo", { dataRoot: tmpRoot });
20
- await recordBrokenPromise(SESSION, {
21
- ts: "2026-05-15T00:00:00Z",
22
- claim_id: "fake",
23
- claim_label: "x",
24
- matched_text: "y",
25
- reason: "z",
26
- }, { dataRoot: tmpRoot });
27
- // Sanity-check the precondition.
28
- expect((await readTurnLedger(SESSION, { dataRoot: tmpRoot })).length).toBe(2);
29
- expect((await readBrokenPromises(SESSION, { dataRoot: tmpRoot })).length).toBe(1);
30
- // SessionEnd action.
31
- await clearSession(SESSION, { dataRoot: tmpRoot });
32
- expect(await readTurnLedger(SESSION, { dataRoot: tmpRoot })).toEqual([]);
33
- expect(await readBrokenPromises(SESSION, { dataRoot: tmpRoot })).toEqual([]);
34
- });
35
- it("session directory remains, just empty of ledger files", async () => {
36
- await recordToolCall(SESSION, "Bash", "ls", { dataRoot: tmpRoot });
37
- await clearSession(SESSION, { dataRoot: tmpRoot });
38
- // The sessions/<id>/ directory itself is preserved (cheap),
39
- // only the JSONL files inside are removed.
40
- const dir = path.join(tmpRoot, "sessions", SESSION);
41
- await expect(fs.access(dir)).resolves.toBeUndefined();
42
- const entries = await fs.readdir(dir);
43
- expect(entries).toEqual([]);
44
- });
45
- it("does NOT touch other sessions' ledgers", async () => {
46
- await recordToolCall(SESSION, "Bash", "ls", { dataRoot: tmpRoot });
47
- await recordToolCall("other-session", "Bash", "ls", { dataRoot: tmpRoot });
48
- await clearSession(SESSION, { dataRoot: tmpRoot });
49
- expect((await readTurnLedger(SESSION, { dataRoot: tmpRoot })).length).toBe(0);
50
- expect((await readTurnLedger("other-session", { dataRoot: tmpRoot })).length).toBe(1);
51
- });
52
- });
@@ -1,35 +0,0 @@
1
- /**
2
- * `opensquid hook stop` — Claude Code Stop hook handler.
3
- *
4
- * Fires at the end of every assistant turn. Two responsibilities:
5
- *
6
- * 1. Honesty ledger reconciliation: cross-reference the assistant's
7
- * final message against the session's accumulated tool-call ledger.
8
- * Any unfulfilled claim is recorded as a broken promise that the
9
- * next turn's UserPromptSubmit hook surfaces back to the agent.
10
- *
11
- * 2. Token-threshold heartbeat: estimate transcript token count, and
12
- * if the conversation has grown past the configured threshold
13
- * since the last checkpoint, arm a pending heartbeat marker so
14
- * the next UserPromptSubmit hook injects a re-anchor nudge into
15
- * the agent's context. The agent (already authenticated and in
16
- * the loop) does the actual recall + classify work inline.
17
- *
18
- * Exit 0 always — Stop hook is observational, not blocking.
19
- *
20
- * Wired in ~/.claude/settings.json:
21
- *
22
- * "Stop": [
23
- * { "hooks": [{
24
- * "type": "command",
25
- * "command": "node /path/to/opensquid/dist/index.js hook stop"
26
- * }] }
27
- * ]
28
- *
29
- * Pre-#124: this hook also spawned a detached LLM-classifier subprocess.
30
- * Removed in favor of the heartbeat path — opensquid stays in-MCP-ecosystem
31
- * (no external LLM dependency, no subprocess), and the agent does the
32
- * classification work inline per CLAUDE.md classify-and-act rules.
33
- */
34
- export declare function runStopHook(): Promise<void>;
35
- //# sourceMappingURL=stop.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"stop.d.ts","sourceRoot":"","sources":["../../src.legacy/hooks/stop.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAmBH,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CA4GjD"}
@@ -1,136 +0,0 @@
1
- /**
2
- * `opensquid hook stop` — Claude Code Stop hook handler.
3
- *
4
- * Fires at the end of every assistant turn. Two responsibilities:
5
- *
6
- * 1. Honesty ledger reconciliation: cross-reference the assistant's
7
- * final message against the session's accumulated tool-call ledger.
8
- * Any unfulfilled claim is recorded as a broken promise that the
9
- * next turn's UserPromptSubmit hook surfaces back to the agent.
10
- *
11
- * 2. Token-threshold heartbeat: estimate transcript token count, and
12
- * if the conversation has grown past the configured threshold
13
- * since the last checkpoint, arm a pending heartbeat marker so
14
- * the next UserPromptSubmit hook injects a re-anchor nudge into
15
- * the agent's context. The agent (already authenticated and in
16
- * the loop) does the actual recall + classify work inline.
17
- *
18
- * Exit 0 always — Stop hook is observational, not blocking.
19
- *
20
- * Wired in ~/.claude/settings.json:
21
- *
22
- * "Stop": [
23
- * { "hooks": [{
24
- * "type": "command",
25
- * "command": "node /path/to/opensquid/dist/index.js hook stop"
26
- * }] }
27
- * ]
28
- *
29
- * Pre-#124: this hook also spawned a detached LLM-classifier subprocess.
30
- * Removed in favor of the heartbeat path — opensquid stays in-MCP-ecosystem
31
- * (no external LLM dependency, no subprocess), and the agent does the
32
- * classification work inline per CLAUDE.md classify-and-act rules.
33
- */
34
- import { clearTurnLedger, reconcile, readBrokenPromises, readTurnLedger, recordBrokenPromise, } from "./honesty-ledger.js";
35
- import { checkAndMaybeArm } from "./heartbeat.js";
36
- import { checkInlineReportFormat } from "./inline-report-check.js";
37
- import { readLastAssistantText } from "./transcript.js";
38
- export async function runStopHook() {
39
- let raw = "";
40
- for await (const chunk of process.stdin) {
41
- raw += chunk;
42
- }
43
- if (!raw.trim()) {
44
- process.exit(0);
45
- }
46
- let payload;
47
- try {
48
- payload = JSON.parse(raw);
49
- }
50
- catch {
51
- process.stderr.write("[opensquid hook stop] malformed input — proceeding\n");
52
- process.exit(0);
53
- }
54
- const sessionId = payload.session_id;
55
- if (!sessionId)
56
- process.exit(0);
57
- // -- (1) Honesty-ledger reconcile ----------------------------------
58
- const assistantText = payload.transcript_path
59
- ? await readLastAssistantText(payload.transcript_path)
60
- : "";
61
- const ledger = await readTurnLedger(sessionId);
62
- const broken = reconcile(assistantText, ledger);
63
- const existing = await readBrokenPromises(sessionId);
64
- const existingKeys = new Set(existing.map((p) => `${p.claim_id}|${p.matched_text}`));
65
- const fresh = [];
66
- for (const promise of broken) {
67
- const key = `${promise.claim_id}|${promise.matched_text}`;
68
- if (existingKeys.has(key))
69
- continue;
70
- fresh.push(promise);
71
- try {
72
- await recordBrokenPromise(sessionId, promise);
73
- }
74
- catch (err) {
75
- process.stderr.write(`[opensquid hook stop] failed to record promise: ${err instanceof Error ? err.message : err}\n`);
76
- }
77
- }
78
- if (fresh.length > 0) {
79
- for (const p of fresh) {
80
- process.stderr.write(`🦑 [opensquid honesty] ${p.claim_id}: ${p.reason}\n`);
81
- }
82
- }
83
- // 0.7.30 / D3 follow-up — when the agent writes a completion-report-
84
- // shaped status update inline (vs. via mcp__opensquid__chat_send),
85
- // D3's chat_send check doesn't fire. Catch the inline case here at
86
- // Stop time and surface as a broken-promise next turn.
87
- if (assistantText) {
88
- const inlineViolation = checkInlineReportFormat(assistantText);
89
- if (inlineViolation) {
90
- const broken = {
91
- ts: new Date().toISOString(),
92
- claim_id: "inline-report-missing-phases",
93
- claim_label: "PHASES block per [[feedback_telegram_reports]]",
94
- matched_text: inlineViolation.matched_text,
95
- reason: `inline message shape suggests a completion report ` +
96
- `(version_refs=${inlineViolation.signals.version_refs}, ` +
97
- `commit_hashes=${inlineViolation.signals.hash_refs}) but the ` +
98
- `PHASES heading is missing. Catches D3 inline variant.`,
99
- };
100
- try {
101
- await recordBrokenPromise(sessionId, broken);
102
- process.stderr.write(`🦑 [opensquid honesty] ${broken.claim_id}: ${broken.reason}\n`);
103
- }
104
- catch (err) {
105
- process.stderr.write(`[opensquid hook stop] inline-report check write failed: ${err instanceof Error ? err.message : err}\n`);
106
- }
107
- }
108
- }
109
- // 0.7.8 (#162): clear the turn-ledger AFTER reconciliation so the
110
- // next turn's claims reconcile against ONLY that turn's tool calls.
111
- // Previously the ledger only cleared at SessionEnd, which meant
112
- // yesterday's git push satisfied today's "I'll push" claim on long
113
- // resumed sessions — the load-bearing #160 finding for ledger drift.
114
- try {
115
- await clearTurnLedger(sessionId);
116
- }
117
- catch (err) {
118
- process.stderr.write(`[opensquid hook stop] turn-ledger clear failed (non-fatal): ${err instanceof Error ? err.message : err}\n`);
119
- }
120
- // -- (2) Token-threshold heartbeat ---------------------------------
121
- if (payload.transcript_path) {
122
- try {
123
- const armed = await checkAndMaybeArm(sessionId, payload.transcript_path);
124
- if (armed) {
125
- // Surface to stderr too so the user sees that opensquid noticed
126
- // drift (in addition to the agent seeing it next turn via UPS).
127
- process.stderr.write(`🦑 [opensquid heartbeat-armed] ${armed}\n`);
128
- }
129
- }
130
- catch (err) {
131
- process.stderr.write(`[opensquid hook stop] heartbeat check failed (non-fatal): ${err instanceof Error ? err.message : err}\n`);
132
- }
133
- }
134
- process.exit(0);
135
- }
136
- //# sourceMappingURL=stop.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"stop.js","sourceRoot":"","sources":["../../src.legacy/hooks/stop.ts"],"names":[],"mappings":"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"}
@@ -1,342 +0,0 @@
1
- /**
2
- * Tests for `readActiveTaskId` — the transcript-walking helper that
3
- * finds the most-recent TodoWrite in_progress task id. Used by the
4
- * workflow gate to figure out which task's phase ledger to query.
5
- */
6
- import { afterEach, beforeEach, describe, expect, it } from "vitest";
7
- import * as crypto from "node:crypto";
8
- import { promises as fs } from "node:fs";
9
- import * as os from "node:os";
10
- import * as path from "node:path";
11
- import { fileURLToPath } from "node:url";
12
- import { readActiveTaskId } from "./transcript.js";
13
- const __dirname = path.dirname(fileURLToPath(import.meta.url));
14
- let tmpDir;
15
- let transcriptPath;
16
- beforeEach(async () => {
17
- tmpDir = path.join(os.tmpdir(), `opensquid-tx-${crypto.randomUUID()}`);
18
- await fs.mkdir(tmpDir, { recursive: true });
19
- transcriptPath = path.join(tmpDir, "transcript.jsonl");
20
- });
21
- afterEach(async () => {
22
- await fs.rm(tmpDir, { recursive: true, force: true });
23
- });
24
- async function writeEvents(events) {
25
- const lines = events.map((e) => JSON.stringify(e)).join("\n") + "\n";
26
- await fs.writeFile(transcriptPath, lines, "utf8");
27
- }
28
- function todoWriteEvent(todos) {
29
- return {
30
- type: "assistant",
31
- message: {
32
- role: "assistant",
33
- content: [
34
- {
35
- type: "tool_use",
36
- name: "TodoWrite",
37
- input: { todos },
38
- },
39
- ],
40
- },
41
- };
42
- }
43
- describe("readActiveTaskId", () => {
44
- it("returns null when transcript doesn't exist", async () => {
45
- expect(await readActiveTaskId(path.join(tmpDir, "missing.jsonl"))).toBeNull();
46
- });
47
- it("returns null when transcript is empty", async () => {
48
- await fs.writeFile(transcriptPath, "", "utf8");
49
- expect(await readActiveTaskId(transcriptPath)).toBeNull();
50
- });
51
- it("returns null when no TodoWrite block exists", async () => {
52
- await writeEvents([
53
- { type: "user", message: { role: "user", content: "hi" } },
54
- { type: "assistant", message: { role: "assistant", content: "hello" } },
55
- ]);
56
- expect(await readActiveTaskId(transcriptPath)).toBeNull();
57
- });
58
- it("returns null when TodoWrite has no in_progress items", async () => {
59
- await writeEvents([
60
- todoWriteEvent([
61
- { id: "1", status: "completed" },
62
- { id: "2", status: "pending" },
63
- ]),
64
- ]);
65
- expect(await readActiveTaskId(transcriptPath)).toBeNull();
66
- });
67
- it("returns the in_progress task id from a single TodoWrite", async () => {
68
- await writeEvents([
69
- todoWriteEvent([
70
- { id: "1", status: "completed" },
71
- { id: "2", status: "in_progress" },
72
- { id: "3", status: "pending" },
73
- ]),
74
- ]);
75
- expect(await readActiveTaskId(transcriptPath)).toBe("2");
76
- });
77
- it("prefers the MOST RECENT TodoWrite when multiple exist", async () => {
78
- await writeEvents([
79
- todoWriteEvent([{ id: "old-task", status: "in_progress" }]),
80
- todoWriteEvent([{ id: "newer-task", status: "in_progress" }]),
81
- ]);
82
- expect(await readActiveTaskId(transcriptPath)).toBe("newer-task");
83
- });
84
- it("stops at the most-recent TodoWrite even if its in_progress is null", async () => {
85
- // The MOST RECENT TodoWrite has no in_progress (all completed).
86
- // We must NOT fall back to an OLDER TodoWrite's in_progress that
87
- // may have been overwritten. Returns null.
88
- await writeEvents([
89
- todoWriteEvent([{ id: "stale-task", status: "in_progress" }]),
90
- todoWriteEvent([
91
- { id: "stale-task", status: "completed" },
92
- { id: "all-done", status: "completed" },
93
- ]),
94
- ]);
95
- expect(await readActiveTaskId(transcriptPath)).toBeNull();
96
- });
97
- it("ignores non-assistant events between TodoWrites", async () => {
98
- await writeEvents([
99
- { type: "user", message: { role: "user", content: "do thing" } },
100
- todoWriteEvent([{ id: "active", status: "in_progress" }]),
101
- { type: "user", message: { role: "user", content: "now go" } },
102
- ]);
103
- expect(await readActiveTaskId(transcriptPath)).toBe("active");
104
- });
105
- it("ignores assistant text events without tool_use blocks", async () => {
106
- await writeEvents([
107
- todoWriteEvent([{ id: "real-active", status: "in_progress" }]),
108
- {
109
- type: "assistant",
110
- message: {
111
- role: "assistant",
112
- content: [{ type: "text", text: "thinking..." }],
113
- },
114
- },
115
- ]);
116
- expect(await readActiveTaskId(transcriptPath)).toBe("real-active");
117
- });
118
- it("ignores other tool_use events (Bash, Edit, etc.)", async () => {
119
- await writeEvents([
120
- todoWriteEvent([{ id: "active", status: "in_progress" }]),
121
- {
122
- type: "assistant",
123
- message: {
124
- role: "assistant",
125
- content: [{ type: "tool_use", name: "Bash", input: { command: "ls" } }],
126
- },
127
- },
128
- ]);
129
- expect(await readActiveTaskId(transcriptPath)).toBe("active");
130
- });
131
- it("coerces numeric ids to strings", async () => {
132
- await writeEvents([
133
- todoWriteEvent([
134
- // Some serializations encode id as number.
135
- { id: 127, status: "in_progress" },
136
- ]),
137
- ]);
138
- expect(await readActiveTaskId(transcriptPath)).toBe("127");
139
- });
140
- it("handles malformed JSON lines gracefully", async () => {
141
- await fs.writeFile(transcriptPath, [
142
- "{ malformed",
143
- JSON.stringify(todoWriteEvent([{ id: "active", status: "in_progress" }])),
144
- "still bad json",
145
- ].join("\n"), "utf8");
146
- expect(await readActiveTaskId(transcriptPath)).toBe("active");
147
- });
148
- });
149
- // =====================================================================
150
- // v0.6.2 — TaskCreate + TaskUpdate recognition (the real-world Claude
151
- // Code shape; TodoWrite was the v0.6.1 shape). My own dogfood session
152
- // today used TaskCreate/TaskUpdate exclusively → workflow gate silent-
153
- // allowed every commit because readActiveTaskId only recognized
154
- // TodoWrite. This block is the regression coverage for the fix.
155
- // =====================================================================
156
- function assistantToolUse(name, blockId, input) {
157
- return {
158
- type: "assistant",
159
- message: {
160
- role: "assistant",
161
- content: [
162
- {
163
- type: "tool_use",
164
- id: blockId,
165
- name,
166
- input,
167
- caller: { type: "direct" },
168
- },
169
- ],
170
- },
171
- };
172
- }
173
- function toolResult(toolUseId, content) {
174
- return {
175
- type: "user",
176
- message: {
177
- role: "user",
178
- content: [
179
- {
180
- type: "tool_result",
181
- tool_use_id: toolUseId,
182
- content,
183
- },
184
- ],
185
- },
186
- };
187
- }
188
- describe("readActiveTaskId — TaskUpdate (v0.6.2 fix)", () => {
189
- it("returns the taskId from TaskUpdate(status=in_progress)", async () => {
190
- await writeEvents([
191
- assistantToolUse("TaskUpdate", "tu-1", { taskId: "131", status: "in_progress" }),
192
- ]);
193
- expect(await readActiveTaskId(transcriptPath)).toBe("131");
194
- });
195
- it("does not return tasks marked completed by a later TaskUpdate", async () => {
196
- await writeEvents([
197
- assistantToolUse("TaskUpdate", "tu-1", { taskId: "131", status: "in_progress" }),
198
- assistantToolUse("TaskUpdate", "tu-2", { taskId: "131", status: "completed" }),
199
- ]);
200
- expect(await readActiveTaskId(transcriptPath)).toBeNull();
201
- });
202
- it("picks the most-recently-touched in_progress task when multiple are active", async () => {
203
- await writeEvents([
204
- assistantToolUse("TaskUpdate", "tu-1", { taskId: "100", status: "in_progress" }),
205
- assistantToolUse("TaskUpdate", "tu-2", { taskId: "200", status: "in_progress" }),
206
- assistantToolUse("TaskUpdate", "tu-3", { taskId: "300", status: "in_progress" }),
207
- ]);
208
- expect(await readActiveTaskId(transcriptPath)).toBe("300");
209
- });
210
- it("coerces numeric taskId to string", async () => {
211
- await writeEvents([
212
- assistantToolUse("TaskUpdate", "tu-1", { taskId: 131, status: "in_progress" }),
213
- ]);
214
- expect(await readActiveTaskId(transcriptPath)).toBe("131");
215
- });
216
- it("ignores TaskUpdate with deleted status", async () => {
217
- await writeEvents([
218
- assistantToolUse("TaskUpdate", "tu-1", { taskId: "131", status: "in_progress" }),
219
- assistantToolUse("TaskUpdate", "tu-2", { taskId: "131", status: "deleted" }),
220
- ]);
221
- expect(await readActiveTaskId(transcriptPath)).toBeNull();
222
- });
223
- });
224
- describe("readActiveTaskId — TaskCreate (v0.6.2 fix)", () => {
225
- it("does NOT return TaskCreate'd tasks (default status = pending, not in_progress)", async () => {
226
- // TaskCreate alone leaves the task as pending. Active-task detection
227
- // requires an explicit TaskUpdate(in_progress) — otherwise no gate
228
- // for tasks that were created but never started.
229
- await writeEvents([
230
- assistantToolUse("TaskCreate", "tc-1", {
231
- subject: "Some task",
232
- description: "...",
233
- }),
234
- toolResult("tc-1", "Task #131 created successfully: Some task"),
235
- ]);
236
- expect(await readActiveTaskId(transcriptPath)).toBeNull();
237
- });
238
- it("returns the assigned id when TaskCreate is followed by TaskUpdate(in_progress)", async () => {
239
- await writeEvents([
240
- assistantToolUse("TaskCreate", "tc-1", { subject: "X", description: "..." }),
241
- toolResult("tc-1", "Task #131 created successfully: X"),
242
- assistantToolUse("TaskUpdate", "tu-1", { taskId: "131", status: "in_progress" }),
243
- ]);
244
- expect(await readActiveTaskId(transcriptPath)).toBe("131");
245
- });
246
- it("handles TaskCreate without a matching tool_result (truncated transcript)", async () => {
247
- await writeEvents([
248
- assistantToolUse("TaskCreate", "tc-1", { subject: "X", description: "..." }),
249
- // No tool_result follows
250
- ]);
251
- // No id assigned, no in_progress → null.
252
- expect(await readActiveTaskId(transcriptPath)).toBeNull();
253
- });
254
- });
255
- // =====================================================================
256
- // Real-world fixture — captured from an actual Claude Code session.
257
- // The fixture lives at __fixtures__/real-task-shape.jsonl. If Claude
258
- // Code ever changes the wire format for TaskCreate / TaskUpdate, this
259
- // test fails BEFORE the workflow gate silently regresses in
260
- // production. Earlier audit recommendation (v0.6.2 audit MED): synthesized
261
- // tests passed in v0.6.1 but real-world shape didn't match — the same
262
- // failure mode would have been caught here.
263
- // =====================================================================
264
- describe("readActiveTaskId — real Claude Code transcript fixture", () => {
265
- it("recognizes TaskCreate + tool_result + TaskUpdate captured from a real session", async () => {
266
- const fixturePath = path.resolve(__dirname, "__fixtures__", "real-task-shape.jsonl");
267
- // The fixture is 3 events: TaskCreate "X" → tool_result "Task #1 created" →
268
- // TaskUpdate(taskId=1, status=in_progress). Expected active task: "1".
269
- const active = await readActiveTaskId(fixturePath);
270
- expect(active).toBe("1");
271
- });
272
- });
273
- // =====================================================================
274
- // 0.7.9 (#163) — stale in_progress demotion
275
- // =====================================================================
276
- function assistantToolUseAt(name, blockId, input, timestamp) {
277
- return {
278
- type: "assistant",
279
- timestamp,
280
- message: {
281
- role: "assistant",
282
- content: [{ type: "tool_use", id: blockId, name, input, caller: { type: "direct" } }],
283
- },
284
- };
285
- }
286
- function userEventAt(timestamp, text = "hello") {
287
- return { type: "user", timestamp, message: { role: "user", content: text } };
288
- }
289
- describe("readActiveTaskId — stale-task demotion (#163)", () => {
290
- const oldDay = "2026-05-16T08:00:00Z"; // ~24h before latest
291
- const today = "2026-05-17T08:00:00Z"; // latest activity
292
- it("returns null when the only in_progress task is >1hr stale relative to latest activity", async () => {
293
- await writeEvents([
294
- assistantToolUseAt("TaskUpdate", "tu-1", { taskId: "999", status: "in_progress" }, oldDay),
295
- // Many later events with newer timestamps — none touch task 999.
296
- userEventAt(today, "new conversation today"),
297
- ]);
298
- expect(await readActiveTaskId(transcriptPath)).toBeNull();
299
- });
300
- it("keeps the in_progress task when it was recently touched", async () => {
301
- const recent = "2026-05-17T07:30:00Z"; // 30 min before latest
302
- await writeEvents([
303
- assistantToolUseAt("TaskUpdate", "tu-1", { taskId: "42", status: "in_progress" }, recent),
304
- userEventAt(today),
305
- ]);
306
- expect(await readActiveTaskId(transcriptPath)).toBe("42");
307
- });
308
- it("picks the more-recent in_progress when two exist (one stale, one fresh)", async () => {
309
- const recent = "2026-05-17T07:45:00Z";
310
- await writeEvents([
311
- assistantToolUseAt("TaskUpdate", "tu-1", { taskId: "X", status: "in_progress" }, oldDay),
312
- assistantToolUseAt("TaskUpdate", "tu-2", { taskId: "Y", status: "in_progress" }, recent),
313
- userEventAt(today),
314
- ]);
315
- expect(await readActiveTaskId(transcriptPath)).toBe("Y");
316
- });
317
- it("falls back to line-idx pick (no demotion) when events have no timestamps", async () => {
318
- // Pre-existing behavior preserved when timestamps aren't available.
319
- await writeEvents([
320
- assistantToolUse("TaskUpdate", "tu-1", { taskId: "no-ts", status: "in_progress" }),
321
- ]);
322
- expect(await readActiveTaskId(transcriptPath)).toBe("no-ts");
323
- });
324
- });
325
- describe("readActiveTaskId — mixed TodoWrite + TaskUpdate", () => {
326
- it("latest write wins per id, regardless of which tool", async () => {
327
- // TodoWrite snapshot says id=5 is in_progress; later TaskUpdate
328
- // marks id=5 completed. TaskUpdate is later → wins.
329
- await writeEvents([
330
- todoWriteEvent([{ id: "5", status: "in_progress" }]),
331
- assistantToolUse("TaskUpdate", "tu-1", { taskId: "5", status: "completed" }),
332
- ]);
333
- expect(await readActiveTaskId(transcriptPath)).toBeNull();
334
- });
335
- it("TodoWrite snapshot can revive an id that TaskUpdate marked completed if it comes later", async () => {
336
- await writeEvents([
337
- assistantToolUse("TaskUpdate", "tu-1", { taskId: "5", status: "completed" }),
338
- todoWriteEvent([{ id: "5", status: "in_progress" }]),
339
- ]);
340
- expect(await readActiveTaskId(transcriptPath)).toBe("5");
341
- });
342
- });