opensquid 0.5.441 → 0.5.449

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 (391) 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/index.d.ts +1 -0
  7. package/dist/functions/index.d.ts.map +1 -1
  8. package/dist/functions/index.js +1 -0
  9. package/dist/functions/index.js.map +1 -1
  10. package/dist/functions/recall_pre_inject.d.ts.map +1 -1
  11. package/dist/functions/recall_pre_inject.js +12 -0
  12. package/dist/functions/recall_pre_inject.js.map +1 -1
  13. package/dist/rag/store_git.d.ts +23 -0
  14. package/dist/rag/store_git.d.ts.map +1 -0
  15. package/dist/rag/store_git.js +57 -0
  16. package/dist/rag/store_git.js.map +1 -0
  17. package/dist/runtime/bootstrap.d.ts.map +1 -1
  18. package/dist/runtime/bootstrap.js +2 -0
  19. package/dist/runtime/bootstrap.js.map +1 -1
  20. package/dist/runtime/handoff/render.d.ts +5 -4
  21. package/dist/runtime/handoff/render.d.ts.map +1 -1
  22. package/dist/runtime/handoff/render.js +7 -7
  23. package/dist/runtime/handoff/render.js.map +1 -1
  24. package/dist/runtime/hooks/active_task_mirror.js +0 -0
  25. package/dist/runtime/hooks/apply_patch.js +0 -0
  26. package/dist/runtime/hooks/dispatch.js +0 -0
  27. package/dist/runtime/hooks/hook_output.js +0 -0
  28. package/dist/runtime/hooks/memory_reconcile.js +0 -0
  29. package/dist/runtime/hooks/new_project_detect.js +0 -0
  30. package/dist/runtime/hooks/profession_resolver.js +0 -0
  31. package/dist/runtime/hooks/scope_intent.js +0 -0
  32. package/dist/runtime/hooks/session-end.js +11 -0
  33. package/dist/runtime/hooks/session-end.js.map +1 -1
  34. package/dist/runtime/hooks/session_id.js +0 -0
  35. package/dist/runtime/hooks/session_liveness.js +0 -0
  36. package/dist/runtime/hooks/stop_drive.js +0 -0
  37. package/dist/runtime/hooks/stop_stream.js +0 -0
  38. package/dist/runtime/hooks/subagent_guard.js +0 -0
  39. package/dist/runtime/hooks/transcript.js +0 -0
  40. package/dist/runtime/hooks/transcript_tasks.js +0 -0
  41. package/dist/runtime/ralph/orchestrator.d.ts.map +1 -1
  42. package/dist/runtime/ralph/orchestrator.js +2 -1
  43. package/dist/runtime/ralph/orchestrator.js.map +1 -1
  44. package/dist/setup/cli/limits_state.d.ts.map +1 -1
  45. package/dist/setup/cli/limits_state.js +6 -40
  46. package/dist/setup/cli/limits_state.js.map +1 -1
  47. package/dist/setup/cli/pack_walk.d.ts +32 -0
  48. package/dist/setup/cli/pack_walk.d.ts.map +1 -0
  49. package/dist/setup/cli/pack_walk.js +76 -0
  50. package/dist/setup/cli/pack_walk.js.map +1 -0
  51. package/dist/setup/cli/permissions_state.d.ts.map +1 -1
  52. package/dist/setup/cli/permissions_state.js +6 -37
  53. package/dist/setup/cli/permissions_state.js.map +1 -1
  54. package/dist/setup/cli/triggers_state.d.ts.map +1 -1
  55. package/dist/setup/cli/triggers_state.js +3 -29
  56. package/dist/setup/cli/triggers_state.js.map +1 -1
  57. package/dist/workgraph/events.d.ts.map +1 -1
  58. package/dist/workgraph/events.js +10 -0
  59. package/dist/workgraph/events.js.map +1 -1
  60. package/dist/workgraph/store.d.ts.map +1 -1
  61. package/dist/workgraph/store.js +5 -0
  62. package/dist/workgraph/store.js.map +1 -1
  63. package/dist/workgraph/types.d.ts +2 -1
  64. package/dist/workgraph/types.d.ts.map +1 -1
  65. package/docs/ARCHITECTURE.md +268 -0
  66. package/docs/pack-runtime.md +15 -12
  67. package/docs/skill-grammar-guide.md +4 -4
  68. package/package.json +5 -3
  69. package/packs/builtin/coding-flow/skills/entry-and-handoffs/skill.yaml +13 -17
  70. package/dist/anti-drift/evaluator.d.ts +0 -88
  71. package/dist/anti-drift/evaluator.d.ts.map +0 -1
  72. package/dist/anti-drift/evaluator.js +0 -417
  73. package/dist/anti-drift/evaluator.js.map +0 -1
  74. package/dist/anti-drift/evaluator.test.js +0 -78
  75. package/dist/anti-drift/rules.d.ts +0 -80
  76. package/dist/anti-drift/rules.d.ts.map +0 -1
  77. package/dist/anti-drift/rules.js +0 -368
  78. package/dist/anti-drift/rules.js.map +0 -1
  79. package/dist/anti-drift/rules.test.js +0 -213
  80. package/dist/anti-drift/state.d.ts +0 -107
  81. package/dist/anti-drift/state.d.ts.map +0 -1
  82. package/dist/anti-drift/state.js +0 -177
  83. package/dist/anti-drift/state.js.map +0 -1
  84. package/dist/anti-drift/state.test.js +0 -120
  85. package/dist/chat/adapters/discord.d.ts +0 -41
  86. package/dist/chat/adapters/discord.d.ts.map +0 -1
  87. package/dist/chat/adapters/discord.js +0 -176
  88. package/dist/chat/adapters/discord.js.map +0 -1
  89. package/dist/chat/adapters/discord.test.js +0 -25
  90. package/dist/chat/adapters/slack.d.ts +0 -43
  91. package/dist/chat/adapters/slack.d.ts.map +0 -1
  92. package/dist/chat/adapters/slack.js +0 -172
  93. package/dist/chat/adapters/slack.js.map +0 -1
  94. package/dist/chat/adapters/slack.test.js +0 -30
  95. package/dist/chat/adapters/telegram.d.ts +0 -148
  96. package/dist/chat/adapters/telegram.d.ts.map +0 -1
  97. package/dist/chat/adapters/telegram.js +0 -498
  98. package/dist/chat/adapters/telegram.js.map +0 -1
  99. package/dist/chat/adapters/telegram.test.js +0 -94
  100. package/dist/chat/config.d.ts +0 -98
  101. package/dist/chat/config.d.ts.map +0 -1
  102. package/dist/chat/config.js +0 -185
  103. package/dist/chat/config.js.map +0 -1
  104. package/dist/chat/daemon/active-project.d.ts +0 -17
  105. package/dist/chat/daemon/active-project.d.ts.map +0 -1
  106. package/dist/chat/daemon/active-project.js +0 -23
  107. package/dist/chat/daemon/active-project.js.map +0 -1
  108. package/dist/chat/daemon/autospawn.d.ts +0 -40
  109. package/dist/chat/daemon/autospawn.d.ts.map +0 -1
  110. package/dist/chat/daemon/autospawn.js +0 -129
  111. package/dist/chat/daemon/autospawn.js.map +0 -1
  112. package/dist/chat/daemon/autospawn.test.js +0 -112
  113. package/dist/chat/daemon/cli.d.ts +0 -18
  114. package/dist/chat/daemon/cli.d.ts.map +0 -1
  115. package/dist/chat/daemon/cli.js +0 -71
  116. package/dist/chat/daemon/cli.js.map +0 -1
  117. package/dist/chat/daemon/collisions.js +0 -384
  118. package/dist/chat/daemon/health-check.d.ts +0 -69
  119. package/dist/chat/daemon/health-check.d.ts.map +0 -1
  120. package/dist/chat/daemon/health-check.js +0 -112
  121. package/dist/chat/daemon/health-check.js.map +0 -1
  122. package/dist/chat/daemon/inbox-read.d.ts +0 -35
  123. package/dist/chat/daemon/inbox-read.d.ts.map +0 -1
  124. package/dist/chat/daemon/inbox-read.js +0 -75
  125. package/dist/chat/daemon/inbox-read.js.map +0 -1
  126. package/dist/chat/daemon/inbox-read.test.js +0 -97
  127. package/dist/chat/daemon/inbox.d.ts +0 -63
  128. package/dist/chat/daemon/inbox.d.ts.map +0 -1
  129. package/dist/chat/daemon/inbox.js +0 -56
  130. package/dist/chat/daemon/inbox.js.map +0 -1
  131. package/dist/chat/daemon/inbox.test.js +0 -110
  132. package/dist/chat/daemon/lifecycle.d.ts +0 -71
  133. package/dist/chat/daemon/lifecycle.d.ts.map +0 -1
  134. package/dist/chat/daemon/lifecycle.js +0 -221
  135. package/dist/chat/daemon/lifecycle.js.map +0 -1
  136. package/dist/chat/daemon/lifecycle.test.js +0 -163
  137. package/dist/chat/daemon/protocol.d.ts +0 -107
  138. package/dist/chat/daemon/protocol.d.ts.map +0 -1
  139. package/dist/chat/daemon/protocol.js +0 -54
  140. package/dist/chat/daemon/protocol.js.map +0 -1
  141. package/dist/chat/daemon/routing.d.ts +0 -140
  142. package/dist/chat/daemon/routing.d.ts.map +0 -1
  143. package/dist/chat/daemon/routing.js +0 -198
  144. package/dist/chat/daemon/routing.js.map +0 -1
  145. package/dist/chat/daemon/routing.test.js +0 -259
  146. package/dist/chat/daemon/rpc-client.d.ts +0 -45
  147. package/dist/chat/daemon/rpc-client.d.ts.map +0 -1
  148. package/dist/chat/daemon/rpc-client.js +0 -133
  149. package/dist/chat/daemon/rpc-client.js.map +0 -1
  150. package/dist/chat/daemon/rpc-server.d.ts +0 -39
  151. package/dist/chat/daemon/rpc-server.d.ts.map +0 -1
  152. package/dist/chat/daemon/rpc-server.js +0 -385
  153. package/dist/chat/daemon/rpc-server.js.map +0 -1
  154. package/dist/chat/daemon/rpc.test.js +0 -177
  155. package/dist/chat/daemon/subscribers.js +0 -257
  156. package/dist/chat/daemon/worker.d.ts +0 -27
  157. package/dist/chat/daemon/worker.d.ts.map +0 -1
  158. package/dist/chat/daemon/worker.js +0 -313
  159. package/dist/chat/daemon/worker.js.map +0 -1
  160. package/dist/chat/daemon/workspace-topic.js +0 -324
  161. package/dist/chat/env-token.d.ts +0 -60
  162. package/dist/chat/env-token.d.ts.map +0 -1
  163. package/dist/chat/env-token.js +0 -137
  164. package/dist/chat/env-token.js.map +0 -1
  165. package/dist/chat/env-token.test.js +0 -160
  166. package/dist/chat/factory.d.ts +0 -30
  167. package/dist/chat/factory.d.ts.map +0 -1
  168. package/dist/chat/factory.js +0 -50
  169. package/dist/chat/factory.js.map +0 -1
  170. package/dist/chat/factory.test.js +0 -55
  171. package/dist/chat/gateway.d.ts +0 -176
  172. package/dist/chat/gateway.d.ts.map +0 -1
  173. package/dist/chat/gateway.js +0 -146
  174. package/dist/chat/gateway.js.map +0 -1
  175. package/dist/chat/gateway.test.js +0 -192
  176. package/dist/claude-md.d.ts +0 -39
  177. package/dist/claude-md.d.ts.map +0 -1
  178. package/dist/claude-md.js +0 -113
  179. package/dist/claude-md.js.map +0 -1
  180. package/dist/claude-md.test.js +0 -91
  181. package/dist/codex/activate.d.ts +0 -66
  182. package/dist/codex/activate.d.ts.map +0 -1
  183. package/dist/codex/activate.js +0 -329
  184. package/dist/codex/activate.js.map +0 -1
  185. package/dist/codex/activate.test.js +0 -229
  186. package/dist/codex/bundled-default/bundled-default.test.js +0 -161
  187. package/dist/codex/cli-publish.test.js +0 -133
  188. package/dist/codex/cli.d.ts +0 -35
  189. package/dist/codex/cli.d.ts.map +0 -1
  190. package/dist/codex/cli.js +0 -554
  191. package/dist/codex/cli.js.map +0 -1
  192. package/dist/codex/cli.test.js +0 -277
  193. package/dist/codex/import-skill-md.d.ts +0 -53
  194. package/dist/codex/import-skill-md.d.ts.map +0 -1
  195. package/dist/codex/import-skill-md.js +0 -236
  196. package/dist/codex/import-skill-md.js.map +0 -1
  197. package/dist/codex/import-skill-md.test.js +0 -225
  198. package/dist/codex/loader.d.ts +0 -27
  199. package/dist/codex/loader.d.ts.map +0 -1
  200. package/dist/codex/loader.js +0 -86
  201. package/dist/codex/loader.js.map +0 -1
  202. package/dist/codex/loader.test.js +0 -75
  203. package/dist/codex/parse.d.ts +0 -28
  204. package/dist/codex/parse.d.ts.map +0 -1
  205. package/dist/codex/parse.js +0 -309
  206. package/dist/codex/parse.js.map +0 -1
  207. package/dist/codex/parse.test.js +0 -241
  208. package/dist/codex/store.d.ts +0 -87
  209. package/dist/codex/store.d.ts.map +0 -1
  210. package/dist/codex/store.js +0 -205
  211. package/dist/codex/store.js.map +0 -1
  212. package/dist/codex/store.test.js +0 -242
  213. package/dist/codex/types.d.ts +0 -398
  214. package/dist/codex/types.d.ts.map +0 -1
  215. package/dist/codex/types.js +0 -21
  216. package/dist/codex/types.js.map +0 -1
  217. package/dist/config.d.ts +0 -53
  218. package/dist/config.d.ts.map +0 -1
  219. package/dist/config.js +0 -202
  220. package/dist/config.js.map +0 -1
  221. package/dist/config.test.js +0 -117
  222. package/dist/engine/cli.d.ts +0 -14
  223. package/dist/engine/cli.d.ts.map +0 -1
  224. package/dist/engine/cli.js +0 -171
  225. package/dist/engine/cli.js.map +0 -1
  226. package/dist/engine/client.d.ts +0 -219
  227. package/dist/engine/client.d.ts.map +0 -1
  228. package/dist/engine/client.js +0 -312
  229. package/dist/engine/client.js.map +0 -1
  230. package/dist/engine/config.d.ts +0 -62
  231. package/dist/engine/config.d.ts.map +0 -1
  232. package/dist/engine/config.js +0 -223
  233. package/dist/engine/config.js.map +0 -1
  234. package/dist/engine/index.d.ts +0 -17
  235. package/dist/engine/index.d.ts.map +0 -1
  236. package/dist/engine/index.js +0 -16
  237. package/dist/engine/index.js.map +0 -1
  238. package/dist/engine/resolver.d.ts +0 -62
  239. package/dist/engine/resolver.d.ts.map +0 -1
  240. package/dist/engine/resolver.js +0 -103
  241. package/dist/engine/resolver.js.map +0 -1
  242. package/dist/engine/singleton.d.ts +0 -95
  243. package/dist/engine/singleton.d.ts.map +0 -1
  244. package/dist/engine/singleton.js +0 -325
  245. package/dist/engine/singleton.js.map +0 -1
  246. package/dist/engine/types.d.ts +0 -402
  247. package/dist/engine/types.d.ts.map +0 -1
  248. package/dist/engine/types.js +0 -22
  249. package/dist/engine/types.js.map +0 -1
  250. package/dist/engine-binary-resolver.js +0 -110
  251. package/dist/engine-binary-resolver.test.js +0 -61
  252. package/dist/engine-cli.js +0 -60
  253. package/dist/engine-client.js +0 -301
  254. package/dist/engine-client.test.js +0 -118
  255. package/dist/functions/chain_state.d.ts +0 -51
  256. package/dist/functions/chain_state.d.ts.map +0 -1
  257. package/dist/functions/chain_state.js +0 -59
  258. package/dist/functions/chain_state.js.map +0 -1
  259. package/dist/hooks/drift-catalog.d.ts +0 -68
  260. package/dist/hooks/drift-catalog.d.ts.map +0 -1
  261. package/dist/hooks/drift-catalog.js +0 -184
  262. package/dist/hooks/drift-catalog.js.map +0 -1
  263. package/dist/hooks/drift-catalog.test.js +0 -154
  264. package/dist/hooks/drift-patterns.d.ts +0 -110
  265. package/dist/hooks/drift-patterns.d.ts.map +0 -1
  266. package/dist/hooks/drift-patterns.js +0 -289
  267. package/dist/hooks/drift-patterns.js.map +0 -1
  268. package/dist/hooks/drift-patterns.test.js +0 -325
  269. package/dist/hooks/engine-vocab-gate.d.ts +0 -108
  270. package/dist/hooks/engine-vocab-gate.d.ts.map +0 -1
  271. package/dist/hooks/engine-vocab-gate.js +0 -225
  272. package/dist/hooks/engine-vocab-gate.js.map +0 -1
  273. package/dist/hooks/engine-vocab-gate.test.js +0 -170
  274. package/dist/hooks/heartbeat.d.ts +0 -107
  275. package/dist/hooks/heartbeat.d.ts.map +0 -1
  276. package/dist/hooks/heartbeat.js +0 -316
  277. package/dist/hooks/heartbeat.js.map +0 -1
  278. package/dist/hooks/heartbeat.test.js +0 -393
  279. package/dist/hooks/honesty-ledger-session-scope.test.js +0 -100
  280. package/dist/hooks/honesty-ledger.d.ts +0 -123
  281. package/dist/hooks/honesty-ledger.d.ts.map +0 -1
  282. package/dist/hooks/honesty-ledger.js +0 -226
  283. package/dist/hooks/honesty-ledger.js.map +0 -1
  284. package/dist/hooks/honesty-ledger.test.js +0 -466
  285. package/dist/hooks/inline-report-check.d.ts +0 -63
  286. package/dist/hooks/inline-report-check.d.ts.map +0 -1
  287. package/dist/hooks/inline-report-check.js +0 -88
  288. package/dist/hooks/inline-report-check.js.map +0 -1
  289. package/dist/hooks/inline-report-check.test.js +0 -96
  290. package/dist/hooks/pre-tool-use.d.ts +0 -62
  291. package/dist/hooks/pre-tool-use.d.ts.map +0 -1
  292. package/dist/hooks/pre-tool-use.js +0 -342
  293. package/dist/hooks/pre-tool-use.js.map +0 -1
  294. package/dist/hooks/pre-tool-use.test.js +0 -134
  295. package/dist/hooks/session-end.d.ts +0 -15
  296. package/dist/hooks/session-end.d.ts.map +0 -1
  297. package/dist/hooks/session-end.js +0 -60
  298. package/dist/hooks/session-end.js.map +0 -1
  299. package/dist/hooks/session-end.test.js +0 -52
  300. package/dist/hooks/stop.d.ts +0 -35
  301. package/dist/hooks/stop.d.ts.map +0 -1
  302. package/dist/hooks/stop.js +0 -136
  303. package/dist/hooks/stop.js.map +0 -1
  304. package/dist/hooks/transcript-active-task.test.js +0 -342
  305. package/dist/hooks/transcript.d.ts +0 -26
  306. package/dist/hooks/transcript.d.ts.map +0 -1
  307. package/dist/hooks/transcript.js +0 -266
  308. package/dist/hooks/transcript.js.map +0 -1
  309. package/dist/hooks/transcript.test.js +0 -103
  310. package/dist/hooks/user-prompt-submit.d.ts +0 -74
  311. package/dist/hooks/user-prompt-submit.d.ts.map +0 -1
  312. package/dist/hooks/user-prompt-submit.js +0 -256
  313. package/dist/hooks/user-prompt-submit.js.map +0 -1
  314. package/dist/hooks/user-prompt-submit.test.js +0 -118
  315. package/dist/hooks/versioning-gate.d.ts +0 -101
  316. package/dist/hooks/versioning-gate.d.ts.map +0 -1
  317. package/dist/hooks/versioning-gate.js +0 -245
  318. package/dist/hooks/versioning-gate.js.map +0 -1
  319. package/dist/hooks/versioning-gate.test.js +0 -368
  320. package/dist/hooks/workflow-gate.d.ts +0 -64
  321. package/dist/hooks/workflow-gate.d.ts.map +0 -1
  322. package/dist/hooks/workflow-gate.js +0 -152
  323. package/dist/hooks/workflow-gate.js.map +0 -1
  324. package/dist/hooks/workflow-gate.test.js +0 -197
  325. package/dist/hooks-cli.d.ts +0 -25
  326. package/dist/hooks-cli.d.ts.map +0 -1
  327. package/dist/hooks-cli.js +0 -286
  328. package/dist/hooks-cli.js.map +0 -1
  329. package/dist/hooks-cli.test.js +0 -148
  330. package/dist/origin.d.ts +0 -16
  331. package/dist/origin.d.ts.map +0 -1
  332. package/dist/origin.js +0 -92
  333. package/dist/origin.js.map +0 -1
  334. package/dist/packs/seed_lessons_ingest.d.ts +0 -30
  335. package/dist/packs/seed_lessons_ingest.d.ts.map +0 -1
  336. package/dist/packs/seed_lessons_ingest.js +0 -107
  337. package/dist/packs/seed_lessons_ingest.js.map +0 -1
  338. package/dist/project-cli.d.ts +0 -7
  339. package/dist/project-cli.d.ts.map +0 -1
  340. package/dist/project-cli.js +0 -145
  341. package/dist/project-cli.js.map +0 -1
  342. package/dist/project.d.ts +0 -127
  343. package/dist/project.d.ts.map +0 -1
  344. package/dist/project.js +0 -281
  345. package/dist/project.js.map +0 -1
  346. package/dist/project.test.js +0 -287
  347. package/dist/rag/backends/loop_engine.d.ts +0 -61
  348. package/dist/rag/backends/loop_engine.d.ts.map +0 -1
  349. package/dist/rag/backends/loop_engine.js +0 -160
  350. package/dist/rag/backends/loop_engine.js.map +0 -1
  351. package/dist/recall.d.ts +0 -82
  352. package/dist/recall.d.ts.map +0 -1
  353. package/dist/recall.js +0 -81
  354. package/dist/recall.js.map +0 -1
  355. package/dist/runtime/agent_bridge/autospawn.d.ts +0 -131
  356. package/dist/runtime/agent_bridge/autospawn.d.ts.map +0 -1
  357. package/dist/runtime/agent_bridge/autospawn.js +0 -251
  358. package/dist/runtime/agent_bridge/autospawn.js.map +0 -1
  359. package/dist/runtime/chain_state.d.ts +0 -124
  360. package/dist/runtime/chain_state.d.ts.map +0 -1
  361. package/dist/runtime/chain_state.js +0 -189
  362. package/dist/runtime/chain_state.js.map +0 -1
  363. package/dist/runtime/hooks/permission_decision.d.ts +0 -34
  364. package/dist/runtime/hooks/permission_decision.d.ts.map +0 -1
  365. package/dist/runtime/hooks/permission_decision.js +0 -39
  366. package/dist/runtime/hooks/permission_decision.js.map +0 -1
  367. package/dist/runtime/workflow_fsm.d.ts +0 -21
  368. package/dist/runtime/workflow_fsm.d.ts.map +0 -1
  369. package/dist/runtime/workflow_fsm.js +0 -25
  370. package/dist/runtime/workflow_fsm.js.map +0 -1
  371. package/dist/runtime/workflow_map.d.ts +0 -26
  372. package/dist/runtime/workflow_map.d.ts.map +0 -1
  373. package/dist/runtime/workflow_map.js +0 -38
  374. package/dist/runtime/workflow_map.js.map +0 -1
  375. package/dist/scope.d.ts +0 -48
  376. package/dist/scope.d.ts.map +0 -1
  377. package/dist/scope.js +0 -111
  378. package/dist/scope.js.map +0 -1
  379. package/dist/setup/cli/topic_create_step.d.ts +0 -84
  380. package/dist/setup/cli/topic_create_step.d.ts.map +0 -1
  381. package/dist/setup/cli/topic_create_step.js +0 -213
  382. package/dist/setup/cli/topic_create_step.js.map +0 -1
  383. package/dist/system-export.d.ts +0 -65
  384. package/dist/system-export.d.ts.map +0 -1
  385. package/dist/system-export.js +0 -194
  386. package/dist/system-export.js.map +0 -1
  387. package/dist/utterance/classifier.d.ts +0 -53
  388. package/dist/utterance/classifier.d.ts.map +0 -1
  389. package/dist/utterance/classifier.js +0 -184
  390. package/dist/utterance/classifier.js.map +0 -1
  391. package/dist/utterance/classifier.test.js +0 -147
@@ -1,96 +0,0 @@
1
- /**
2
- * Tests for inline-report-check (0.7.30 / D3 inline variant).
3
- *
4
- * Covers checkInlineReportFormat + the count helpers. Stop-hook
5
- * integration left to integration tests (it composes the existing
6
- * BrokenPromise pipeline which already has its own coverage).
7
- */
8
- import { describe, expect, it } from "vitest";
9
- import { checkInlineReportFormat, countCommitHashes, countVersionRefs, hasPhasesBlock, } from "./inline-report-check.js";
10
- describe("countVersionRefs", () => {
11
- it("counts distinct 0.X.Y refs", () => {
12
- expect(countVersionRefs("shipped 0.7.20 then 0.7.21 and 0.7.22")).toBe(3);
13
- });
14
- it("dedupes repeated mentions", () => {
15
- expect(countVersionRefs("0.7.20 fixed in 0.7.20 again")).toBe(1);
16
- });
17
- it("returns 0 on plain prose with no version", () => {
18
- expect(countVersionRefs("hello world, no versions here")).toBe(0);
19
- });
20
- it("does NOT count partial versions like '0.7'", () => {
21
- expect(countVersionRefs("the 0.7 series")).toBe(0);
22
- });
23
- });
24
- describe("countCommitHashes", () => {
25
- it("counts distinct 7-char hashes", () => {
26
- expect(countCommitHashes("see 92fe415 and 0e59ba3 and 40342e3")).toBe(3);
27
- });
28
- it("requires at least one a-f letter (excludes pure decimal)", () => {
29
- // 7-digit decimals like timestamps shouldn't trigger.
30
- expect(countCommitHashes("count is 1234567 and 9876543")).toBe(0);
31
- });
32
- it("counts full 40-char shas", () => {
33
- expect(countCommitHashes("4eaf39d2d21f0540342e3e881d2c47cde6d4ab39 abc")).toBe(1);
34
- });
35
- it("dedupes repeated hashes", () => {
36
- expect(countCommitHashes("92fe415 ... revisit 92fe415")).toBe(1);
37
- });
38
- });
39
- describe("hasPhasesBlock", () => {
40
- it("true for 'PHASES:' uppercase block", () => {
41
- expect(hasPhasesBlock("\nPHASES:\n- pre_research: ...")).toBe(true);
42
- });
43
- it("true for 'phases:' lowercase", () => {
44
- expect(hasPhasesBlock("phases:\n- x")).toBe(true);
45
- });
46
- it("true when 'PHASES' is followed by a newline", () => {
47
- expect(hasPhasesBlock("PHASES\n- pre_research")).toBe(true);
48
- });
49
- it("false when 'phases' appears in unrelated prose", () => {
50
- expect(hasPhasesBlock("we have three phases of testing")).toBe(false);
51
- });
52
- });
53
- describe("checkInlineReportFormat", () => {
54
- it("flags multi-version status report without PHASES", () => {
55
- const text = `Shipped 0.7.20, 0.7.21, 0.7.22 today. All tests green.`;
56
- const v = checkInlineReportFormat(text);
57
- expect(v).not.toBeNull();
58
- expect(v.signals.version_refs).toBe(3);
59
- });
60
- it("flags multi-commit chain-ship without PHASES", () => {
61
- const text = `Commits: 92fe415, 0e59ba3, 40342e3, d6275a1 all pushed.`;
62
- const v = checkInlineReportFormat(text);
63
- expect(v).not.toBeNull();
64
- expect(v.signals.hash_refs).toBeGreaterThanOrEqual(2);
65
- });
66
- it("does NOT flag when PHASES block is present", () => {
67
- const text = `🦑 #7 shipped 0.7.20, 0.7.21, 0.7.22.\n\nPHASES:\n- pre_research: ...\n- learn: ...\n- code: ...\n- test: ...\n- audit: ...\n- post_research: ...\n- fix: ...`;
68
- expect(checkInlineReportFormat(text)).toBeNull();
69
- });
70
- it("does NOT flag a single-version prose mention (signal too weak)", () => {
71
- const text = `I bumped opensquid to 0.7.30 in package.json.`;
72
- expect(checkInlineReportFormat(text)).toBeNull();
73
- });
74
- it("does NOT flag a single-commit-hash prose mention", () => {
75
- const text = `The commit 92fe415 introduced the D9 guard.`;
76
- expect(checkInlineReportFormat(text)).toBeNull();
77
- });
78
- it("does NOT flag empty input", () => {
79
- expect(checkInlineReportFormat("")).toBeNull();
80
- });
81
- it("matched_text condenses to <=120 chars + trims whitespace", () => {
82
- const long = "Shipped 0.7.20 and 0.7.21 today.\n\n".repeat(10);
83
- const v = checkInlineReportFormat(long);
84
- expect(v).not.toBeNull();
85
- expect(v.matched_text.length).toBeLessThanOrEqual(120);
86
- });
87
- it("dogfood: catches the 'where are my 7 phases' incident shape", () => {
88
- // The user's complaint was the summary table I posted with 10
89
- // versions and 10 commit hashes but no PHASES heading.
90
- const text = `Final tally: 0.7.20 92fe415, 0.7.21 0e59ba3, 0.7.22 40342e3, 0.7.23 d6275a1, 0.7.24 e881d2c, 0.7.25 e47b65c, 0.7.26 2d21f05, 0.7.27 4ab3977, 0.7.28 47cde6d, 0.7.29 4eaf39d.`;
91
- const v = checkInlineReportFormat(text);
92
- expect(v).not.toBeNull();
93
- expect(v.signals.version_refs).toBe(10);
94
- expect(v.signals.hash_refs).toBe(10);
95
- });
96
- });
@@ -1,62 +0,0 @@
1
- /**
2
- * `opensquid hook pre-tool-use` — Claude Code PreToolUse hook handler.
3
- *
4
- * Wired in `~/.claude/settings.json`:
5
- *
6
- * {
7
- * "hooks": {
8
- * "PreToolUse": [
9
- * {
10
- * "matcher": "Bash",
11
- * "hooks": [
12
- * { "type": "command",
13
- * "command": "node /path/to/opensquid/dist/index.js hook pre-tool-use" }
14
- * ]
15
- * }
16
- * ]
17
- * }
18
- * }
19
- *
20
- * Stdin: JSON describing the planned tool call (Claude Code's hook
21
- * input schema). Stdout: empty on no-op. Stderr: drift findings.
22
- * Exit code: 0 to proceed, 2 to block the call.
23
- *
24
- * The catalog of intercepts lives in src/hooks/drift-patterns.ts and
25
- * grows lesson-by-lesson as drifts are observed and the user endorses
26
- * the rule.
27
- */
28
- import { type ToolCallInput } from "./drift-patterns.js";
29
- /**
30
- * #173 — return a warning string when an active-task-gated MCP tool is
31
- * about to be called without an in_progress TodoWrite task in the
32
- * transcript. Returns `null` when the tool isn't gated, no transcript
33
- * path is available, or an active task is detected.
34
- *
35
- * Transcript-read failures (missing file, malformed JSONL) swallow to
36
- * null — the hook must never block a legitimate call on its own bug.
37
- * The workflow-gate fail-opens silently in this case
38
- * (workflow-gate.ts:97-100); this surface makes that fail-open
39
- * observable from the call site.
40
- *
41
- * Exported for direct testing.
42
- */
43
- export declare function checkActiveTaskRequirement(call: ToolCallInput, transcriptPath: string | undefined): Promise<string | null>;
44
- /**
45
- * 0.7.25 / D3 — when `chat_send` is called with a body that looks like
46
- * a task-completion report (starts with the agent's `🦑 #<N>` marker),
47
- * verify the body includes a `PHASES` heading + at least 7 phase
48
- * lines per `[[feedback_telegram_reports]]`. Returns a non-blocking
49
- * warning string when the format is missing, null otherwise.
50
- *
51
- * Catches D3: paragraph summary sent instead of the locked 7-phase
52
- * format. Detection is heuristic (the agent could write a real
53
- * non-report message starting with `🦑 #N` — accepted noise).
54
- *
55
- * Exported for direct testing.
56
- */
57
- export declare function checkChatSendReportFormat(call: ToolCallInput): string | null;
58
- /**
59
- * Read JSON from stdin, evaluate drifts, exit with the appropriate code.
60
- */
61
- export declare function runPreToolUseHook(): Promise<void>;
62
- //# sourceMappingURL=pre-tool-use.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"pre-tool-use.d.ts","sourceRoot":"","sources":["../../src.legacy/hooks/pre-tool-use.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,EAAsB,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAsB7E;;;;;;;;;;;;;GAaG;AACH,wBAAsB,0BAA0B,CAC9C,IAAI,EAAE,aAAa,EACnB,cAAc,EAAE,MAAM,GAAG,SAAS,GACjC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAcxB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,aAAa,GAAG,MAAM,GAAG,IAAI,CAkB5E;AAoBD;;GAEG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC,CA2KvD"}
@@ -1,342 +0,0 @@
1
- /**
2
- * `opensquid hook pre-tool-use` — Claude Code PreToolUse hook handler.
3
- *
4
- * Wired in `~/.claude/settings.json`:
5
- *
6
- * {
7
- * "hooks": {
8
- * "PreToolUse": [
9
- * {
10
- * "matcher": "Bash",
11
- * "hooks": [
12
- * { "type": "command",
13
- * "command": "node /path/to/opensquid/dist/index.js hook pre-tool-use" }
14
- * ]
15
- * }
16
- * ]
17
- * }
18
- * }
19
- *
20
- * Stdin: JSON describing the planned tool call (Claude Code's hook
21
- * input schema). Stdout: empty on no-op. Stderr: drift findings.
22
- * Exit code: 0 to proceed, 2 to block the call.
23
- *
24
- * The catalog of intercepts lives in src/hooks/drift-patterns.ts and
25
- * grows lesson-by-lesson as drifts are observed and the user endorses
26
- * the rule.
27
- */
28
- import { decide, findDrifts } from "./drift-patterns.js";
29
- import { evaluateEngineVocabGate } from "./engine-vocab-gate.js";
30
- import { clearRecallRequired, isRecallRequired } from "./heartbeat.js";
31
- import { recordToolCall } from "./honesty-ledger.js";
32
- import { readActiveTaskId } from "./transcript.js";
33
- import { evaluateVersioningGate } from "./versioning-gate.js";
34
- import { evaluateWorkflowGate } from "./workflow-gate.js";
35
- /**
36
- * MCP tools that participate in the drift-protection track. When any
37
- * of these is called WITHOUT an in_progress TodoWrite task in the
38
- * transcript, the workflow-gate / chat-routing signals end up writing
39
- * to a ledger that no gate validates against. We can't BLOCK these
40
- * calls (legitimate ad-hoc usage exists), but emit a loud stderr
41
- * warning so the gap is visible. #173 / drift D1 structural fix
42
- * (locked 2026-05-17).
43
- */
44
- const ACTIVE_TASK_GATED_MCP_TOOLS = new Set([
45
- "mcp__opensquid__log_phase",
46
- "mcp__opensquid__chat_send",
47
- ]);
48
- /**
49
- * #173 — return a warning string when an active-task-gated MCP tool is
50
- * about to be called without an in_progress TodoWrite task in the
51
- * transcript. Returns `null` when the tool isn't gated, no transcript
52
- * path is available, or an active task is detected.
53
- *
54
- * Transcript-read failures (missing file, malformed JSONL) swallow to
55
- * null — the hook must never block a legitimate call on its own bug.
56
- * The workflow-gate fail-opens silently in this case
57
- * (workflow-gate.ts:97-100); this surface makes that fail-open
58
- * observable from the call site.
59
- *
60
- * Exported for direct testing.
61
- */
62
- export async function checkActiveTaskRequirement(call, transcriptPath) {
63
- if (!ACTIVE_TASK_GATED_MCP_TOOLS.has(call.tool))
64
- return null;
65
- if (!transcriptPath)
66
- return null;
67
- try {
68
- const activeTaskId = await readActiveTaskId(transcriptPath);
69
- if (activeTaskId)
70
- return null;
71
- }
72
- catch {
73
- return null;
74
- }
75
- return (`🦑 [opensquid] ${call.tool} called without an in_progress TodoWrite task — ` +
76
- `the entries it writes WON'T be validated by the workflow-gate. ` +
77
- `Call TaskCreate (and set in_progress) first so the gate has an active task to enforce against.\n`);
78
- }
79
- /**
80
- * 0.7.25 / D3 — when `chat_send` is called with a body that looks like
81
- * a task-completion report (starts with the agent's `🦑 #<N>` marker),
82
- * verify the body includes a `PHASES` heading + at least 7 phase
83
- * lines per `[[feedback_telegram_reports]]`. Returns a non-blocking
84
- * warning string when the format is missing, null otherwise.
85
- *
86
- * Catches D3: paragraph summary sent instead of the locked 7-phase
87
- * format. Detection is heuristic (the agent could write a real
88
- * non-report message starting with `🦑 #N` — accepted noise).
89
- *
90
- * Exported for direct testing.
91
- */
92
- export function checkChatSendReportFormat(call) {
93
- if (call.tool !== "mcp__opensquid__chat_send")
94
- return null;
95
- const text = call.input.text;
96
- if (typeof text !== "string")
97
- return null;
98
- // Trigger: message starts with the report marker `🦑 #N`.
99
- if (!/^\s*🦑\s+#\d/.test(text))
100
- return null;
101
- // Format requirement: must include a PHASES heading and the 7 phase
102
- // names. The phase names match the codex's default workflow.
103
- if (!/\bPHASES\b/.test(text)) {
104
- return (`🦑 [opensquid] chat_send body looks like a task-completion report ` +
105
- `(starts with \`🦑 #N\`) but is missing the \`PHASES\` block. ` +
106
- `Per [[feedback_telegram_reports]] reports must list each phase ` +
107
- `(pre_research, learn, code, test, audit, post_research, fix) ` +
108
- `with a concrete one-line finding — not just ✅. Catches drift D3.\n`);
109
- }
110
- return null;
111
- }
112
- /**
113
- * Read JSON from stdin, evaluate drifts, exit with the appropriate code.
114
- */
115
- export async function runPreToolUseHook() {
116
- let raw = "";
117
- for await (const chunk of process.stdin) {
118
- raw += chunk;
119
- }
120
- // Empty stdin → nothing to evaluate. Some hook configurations may
121
- // pipe nothing during tests; bail gracefully.
122
- if (!raw.trim()) {
123
- process.exit(0);
124
- }
125
- let payload;
126
- try {
127
- payload = JSON.parse(raw);
128
- }
129
- catch {
130
- // Malformed input — don't block on opensquid's own bug.
131
- process.stderr.write("[opensquid hook] malformed PreToolUse input — proceeding\n");
132
- process.exit(0);
133
- }
134
- if (!payload.tool_name || typeof payload.tool_name !== "string") {
135
- process.exit(0);
136
- }
137
- const call = {
138
- tool: payload.tool_name,
139
- input: payload.tool_input ?? {},
140
- };
141
- // #173 / 0.7.29 — D1 BLOCK upgrade. When an active-task-gated MCP
142
- // tool is called without an in_progress TodoWrite task in the
143
- // transcript, BLOCK (was: WARN). The design doc rule #1 says BLOCK
144
- // is the right semantic: log_phase / chat_send without an active
145
- // task is exactly the failure mode the workflow-gate exists to
146
- // prevent, and a soft warning was empirically ignored every time.
147
- // Bypass: OPENSQUID_SKIP_ACTIVE_TASK_GATE=1 for legitimate
148
- // non-task-scoped calls.
149
- const taskWarning = await checkActiveTaskRequirement(call, payload.transcript_path);
150
- if (taskWarning) {
151
- process.stderr.write(taskWarning);
152
- if (!checkActiveTaskBypassEnv()) {
153
- process.stderr.write(` This is a BLOCK (was WARN through 0.7.28). Call TaskCreate first.\n` +
154
- ` Override (genuine non-task-scoped call): set OPENSQUID_SKIP_ACTIVE_TASK_GATE=1.\n`);
155
- process.exit(2);
156
- }
157
- process.stderr.write(` 🦑 [opensquid active-task-gate] BYPASSED via OPENSQUID_SKIP_ACTIVE_TASK_GATE=1\n`);
158
- }
159
- // 0.7.25 / D3 — when chat_send body looks like a report but is missing
160
- // the 7-phase format, warn. Non-blocking.
161
- const formatWarning = checkChatSendReportFormat(call);
162
- if (formatWarning) {
163
- process.stderr.write(formatWarning);
164
- }
165
- // 0.7.26 / D7 — heartbeat-recall enforcement. When UPS surfaced a
166
- // heartbeat nudge this turn, the recall-required flag is set; block
167
- // any mcp__opensquid__* tool other than `recall` until the agent
168
- // actually calls recall. On a recall call, clear the flag.
169
- if (payload.session_id) {
170
- try {
171
- if (call.tool === "mcp__opensquid__recall" && (await isRecallRequired(payload.session_id))) {
172
- await clearRecallRequired(payload.session_id);
173
- }
174
- else if (call.tool.startsWith("mcp__opensquid__") &&
175
- !checkRecallBypassEnv() &&
176
- (await isRecallRequired(payload.session_id))) {
177
- process.stderr.write(buildRecallRequiredBlockMessage(call.tool));
178
- process.exit(2);
179
- }
180
- }
181
- catch (err) {
182
- process.stderr.write(`[opensquid hook] recall-required check failed (proceeding): ${err instanceof Error ? err.message : err}\n`);
183
- }
184
- }
185
- // v0.4: append to the honesty ledger so the Stop hook can reconcile
186
- // assistant claims against tool calls. Best-effort — never block the
187
- // call on a ledger write failure.
188
- if (payload.session_id) {
189
- try {
190
- const inputSummary = summarizeInput(call.tool, call.input);
191
- await recordToolCall(payload.session_id, call.tool, inputSummary);
192
- }
193
- catch (err) {
194
- process.stderr.write(`[opensquid hook] honesty-ledger write failed (non-fatal): ${err instanceof Error ? err.message : err}\n`);
195
- }
196
- }
197
- const hits = findDrifts(call);
198
- const { exit, stderr } = decide(hits, call);
199
- if (stderr)
200
- process.stderr.write(stderr);
201
- if (exit !== 0) {
202
- // Existing drift gate already blocking; don't spend RPC budget on
203
- // the workflow gate.
204
- process.exit(exit);
205
- }
206
- // v0.6.1 workflow gate — when the tool call is `git commit` (not
207
- // --amend, which has its own gate), check that the active task's
208
- // phase ledger has the required phases logged. Engine-RPC-backed,
209
- // so only fires when the engine binary is reachable. Fail-open on
210
- // any error (per [[honesty-ledger]] precedent — never block on
211
- // opensquid's own bug). Spawning the engine just for this check is
212
- // expensive (~hundreds of ms per hook), so it's scoped tightly to
213
- // commit commands.
214
- if (looksLikeGitCommit(call)) {
215
- try {
216
- const gateResult = await evaluateWorkflowGate({
217
- transcriptPath: payload.transcript_path,
218
- });
219
- if (gateResult.block) {
220
- process.stderr.write(gateResult.stderr);
221
- process.exit(2);
222
- }
223
- else if (gateResult.stderr) {
224
- // Warning only — proceed.
225
- process.stderr.write(gateResult.stderr);
226
- }
227
- }
228
- catch (err) {
229
- process.stderr.write(`[opensquid hook] workflow-gate failed (proceeding): ${err instanceof Error ? err.message : err}\n`);
230
- }
231
- // v0.6.3 versioning gate — enforce per-commit patch bumps. Local
232
- // git diff inspection only (no RPC), so cheap. Same fail-open
233
- // invariant as the workflow gate.
234
- try {
235
- const versionResult = await evaluateVersioningGate({ cwd: payload.cwd });
236
- if (versionResult.block) {
237
- process.stderr.write(versionResult.stderr);
238
- process.exit(2);
239
- }
240
- else if (versionResult.stderr) {
241
- process.stderr.write(versionResult.stderr);
242
- }
243
- }
244
- catch (err) {
245
- process.stderr.write(`[opensquid hook] versioning-gate failed (proceeding): ${err instanceof Error ? err.message : err}\n`);
246
- }
247
- // 0.7.21 / D6 — engine vocabulary gate. Blocks engine commits whose
248
- // -m message OR staged diff content references consumer-product
249
- // names (opensquid, claude code, etc.). Early-exits on non-engine
250
- // cwd; cheap when not applicable.
251
- try {
252
- const bashCmd = stringField(call.input, "command");
253
- const vocabResult = await evaluateEngineVocabGate({
254
- cwd: payload.cwd,
255
- bashCommand: bashCmd ?? undefined,
256
- });
257
- if (vocabResult.block) {
258
- process.stderr.write(vocabResult.stderr);
259
- process.exit(2);
260
- }
261
- else if (vocabResult.stderr) {
262
- process.stderr.write(vocabResult.stderr);
263
- }
264
- }
265
- catch (err) {
266
- process.stderr.write(`[opensquid hook] engine-vocab-gate failed (proceeding): ${err instanceof Error ? err.message : err}\n`);
267
- }
268
- }
269
- process.exit(0);
270
- }
271
- function stringField(input, field) {
272
- const v = input[field];
273
- return typeof v === "string" ? v : null;
274
- }
275
- /**
276
- * 0.7.26 / D7 — emergency bypass for the recall-required block. For
277
- * cases where the engine is unreachable and the agent can't call
278
- * recall through normal channels.
279
- */
280
- function checkRecallBypassEnv() {
281
- return process.env.OPENSQUID_SKIP_RECALL_GATE === "1";
282
- }
283
- /**
284
- * 0.7.29 / D1 BLOCK upgrade — emergency bypass for the active-task
285
- * requirement. For legitimate non-task-scoped log_phase / chat_send
286
- * calls (e.g. an ad-hoc one-shot ping to the user).
287
- */
288
- function checkActiveTaskBypassEnv() {
289
- return process.env.OPENSQUID_SKIP_ACTIVE_TASK_GATE === "1";
290
- }
291
- function buildRecallRequiredBlockMessage(tool) {
292
- return (`🦑 [opensquid recall-gate] ${tool} blocked — heartbeat was surfaced ` +
293
- `this turn but recall hasn't been called yet.\n` +
294
- `Call \`mcp__opensquid__recall\` first to re-anchor on the active task, ` +
295
- `then retry. Drift D7.\n` +
296
- `Override (genuine emergency, e.g. engine unreachable): set ` +
297
- `OPENSQUID_SKIP_RECALL_GATE=1 for this command.\n`);
298
- }
299
- function looksLikeGitCommit(call) {
300
- if (call.tool !== "Bash")
301
- return false;
302
- const cmd = call.input.command;
303
- if (typeof cmd !== "string")
304
- return false;
305
- // Match `git commit ...` but NOT `git commit --amend` (handled by
306
- // existing drift pattern). Also skip cases where the command is
307
- // clearly a comment or inside quotes (drift-patterns.ts uses the
308
- // same quote-stripping; we duplicate the minimal version here).
309
- const stripped = cmd.replace(/"[^"]*"/g, "").replace(/'[^']*'/g, "");
310
- if (!/\bgit\s+commit\b/.test(stripped))
311
- return false;
312
- if (/\bgit\s+commit\b[^|;&]*--amend/.test(stripped))
313
- return false;
314
- return true;
315
- }
316
- /**
317
- * Tight summary of tool input for the ledger. We keep just enough to
318
- * reconcile claims (e.g. "did the agent run npm test?") without writing
319
- * the whole tool_input blob.
320
- */
321
- function summarizeInput(tool, input) {
322
- if (tool === "Bash") {
323
- const cmd = input.command;
324
- return typeof cmd === "string" ? cmd.slice(0, 500) : "";
325
- }
326
- if (tool === "Edit" || tool === "Write" || tool === "Read") {
327
- const fp = input.file_path;
328
- return typeof fp === "string" ? fp : "";
329
- }
330
- if (tool === "Agent") {
331
- const desc = input.description ?? input.subagent_type ?? "";
332
- return typeof desc === "string" ? desc.slice(0, 200) : "";
333
- }
334
- // Default — short JSON peek for unknown tools.
335
- try {
336
- return JSON.stringify(input).slice(0, 200);
337
- }
338
- catch {
339
- return "";
340
- }
341
- }
342
- //# sourceMappingURL=pre-tool-use.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"pre-tool-use.js","sourceRoot":"","sources":["../../src.legacy/hooks/pre-tool-use.ts"],"names":[],"mappings":"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"}
@@ -1,134 +0,0 @@
1
- /**
2
- * Pre-tool-use hook tests — focused on the #173 (drift D1) active-task
3
- * requirement check. Runs against a synthetic transcript file with
4
- * controllable TodoWrite shape.
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 { checkActiveTaskRequirement, checkChatSendReportFormat } from "./pre-tool-use.js";
12
- let tmpDir;
13
- let transcriptPath;
14
- beforeEach(async () => {
15
- tmpDir = path.join(os.tmpdir(), `opensquid-ptu-${crypto.randomUUID()}`);
16
- await fs.mkdir(tmpDir, { recursive: true });
17
- transcriptPath = path.join(tmpDir, "transcript.jsonl");
18
- });
19
- afterEach(async () => {
20
- await fs.rm(tmpDir, { recursive: true, force: true });
21
- });
22
- async function writeTranscriptWithActiveTask(taskId) {
23
- const event = {
24
- type: "assistant",
25
- message: {
26
- role: "assistant",
27
- content: [
28
- {
29
- type: "tool_use",
30
- name: "TodoWrite",
31
- input: {
32
- todos: [{ id: taskId, status: "in_progress", content: "active thing" }],
33
- },
34
- },
35
- ],
36
- },
37
- };
38
- await fs.writeFile(transcriptPath, JSON.stringify(event) + "\n", "utf8");
39
- }
40
- describe("checkActiveTaskRequirement — #173 / drift D1 fix", () => {
41
- it("returns null for tools that aren't active-task-gated", async () => {
42
- const result = await checkActiveTaskRequirement({ tool: "Bash", input: { command: "ls" } }, transcriptPath);
43
- expect(result).toBeNull();
44
- });
45
- it("returns null when no transcript path is provided", async () => {
46
- const result = await checkActiveTaskRequirement({ tool: "mcp__opensquid__log_phase", input: {} }, undefined);
47
- expect(result).toBeNull();
48
- });
49
- it("returns null when an in_progress task exists in the transcript", async () => {
50
- await writeTranscriptWithActiveTask("42");
51
- const result = await checkActiveTaskRequirement({ tool: "mcp__opensquid__log_phase", input: { task_id: "42", phase: "code" } }, transcriptPath);
52
- expect(result).toBeNull();
53
- });
54
- it("returns a warning when log_phase is called with no in_progress task", async () => {
55
- await fs.writeFile(transcriptPath, "", "utf8"); // empty transcript = no tasks
56
- const result = await checkActiveTaskRequirement({ tool: "mcp__opensquid__log_phase", input: { task_id: "42", phase: "code" } }, transcriptPath);
57
- expect(result).not.toBeNull();
58
- expect(result).toContain("mcp__opensquid__log_phase called without an in_progress");
59
- expect(result).toContain("TaskCreate");
60
- });
61
- it("returns a warning when chat_send is called with no in_progress task", async () => {
62
- await fs.writeFile(transcriptPath, "", "utf8");
63
- const result = await checkActiveTaskRequirement({ tool: "mcp__opensquid__chat_send", input: { channel: "telegram:1", text: "hi" } }, transcriptPath);
64
- expect(result).not.toBeNull();
65
- expect(result).toContain("mcp__opensquid__chat_send called without an in_progress");
66
- });
67
- it("emits the warning even when the transcript file is missing (readActiveTaskId returns null gracefully)", async () => {
68
- // readActiveTaskId handles missing files internally and returns
69
- // null. The D1 check treats null-active-task as "no in_progress
70
- // signal" regardless of cause, which is the right semantic — the
71
- // agent skipped TaskCreate is the failure mode either way.
72
- const result = await checkActiveTaskRequirement({ tool: "mcp__opensquid__log_phase", input: {} }, path.join(tmpDir, "nonexistent.jsonl"));
73
- expect(result).not.toBeNull();
74
- expect(result).toContain("called without an in_progress");
75
- });
76
- });
77
- describe("checkChatSendReportFormat — 0.7.25 / drift D3", () => {
78
- it("returns null for tools other than chat_send", () => {
79
- const result = checkChatSendReportFormat({
80
- tool: "Bash",
81
- input: { command: "🦑 #4 fake bash" },
82
- });
83
- expect(result).toBeNull();
84
- });
85
- it("returns null when text doesn't start with the 🦑 #N marker", () => {
86
- const result = checkChatSendReportFormat({
87
- tool: "mcp__opensquid__chat_send",
88
- input: { text: "just a regular ping" },
89
- });
90
- expect(result).toBeNull();
91
- });
92
- it("returns null when text starts with the marker AND has PHASES heading", () => {
93
- const result = checkChatSendReportFormat({
94
- tool: "mcp__opensquid__chat_send",
95
- input: {
96
- text: "🦑 #170 — engine-client startupAck fix\n\n" +
97
- "PHASES:\n" +
98
- "- pre_research: surveyed engine-client.ts and engine-client.test.ts\n" +
99
- "- learn: bug localized to startupAck memoization\n" +
100
- "- code: 3-LOC fix in src/engine-client.ts:103-110\n" +
101
- "- test: 2 new tests for respawn-after-exit\n" +
102
- "- audit: reviewed for regressions; none found\n" +
103
- "- post_research: docs note on resume behavior\n" +
104
- "- fix: applied + committed\n",
105
- },
106
- });
107
- expect(result).toBeNull();
108
- });
109
- it("WARNS when text starts with marker but PHASES heading missing", () => {
110
- const result = checkChatSendReportFormat({
111
- tool: "mcp__opensquid__chat_send",
112
- input: {
113
- text: "🦑 #170 — engine-client startupAck fix\n\nshipped, all green",
114
- },
115
- });
116
- expect(result).not.toBeNull();
117
- expect(result).toContain("missing the `PHASES` block");
118
- expect(result).toContain("drift D3");
119
- });
120
- it("respects leading whitespace before the marker", () => {
121
- const result = checkChatSendReportFormat({
122
- tool: "mcp__opensquid__chat_send",
123
- input: { text: " 🦑 #4 cleanup\n\nno phases here" },
124
- });
125
- expect(result).not.toBeNull();
126
- });
127
- it("returns null when text input is missing entirely", () => {
128
- const result = checkChatSendReportFormat({
129
- tool: "mcp__opensquid__chat_send",
130
- input: { channel: "telegram:1" },
131
- });
132
- expect(result).toBeNull();
133
- });
134
- });
@@ -1,15 +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
- export declare function runSessionEndHook(): Promise<void>;
15
- //# sourceMappingURL=session-end.d.ts.map