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,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