opensquid 0.5.441 → 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 (380) 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/runtime/bootstrap.d.ts.map +1 -1
  11. package/dist/runtime/bootstrap.js +2 -0
  12. package/dist/runtime/bootstrap.js.map +1 -1
  13. package/dist/runtime/handoff/render.d.ts +5 -4
  14. package/dist/runtime/handoff/render.d.ts.map +1 -1
  15. package/dist/runtime/handoff/render.js +7 -7
  16. package/dist/runtime/handoff/render.js.map +1 -1
  17. package/dist/runtime/hooks/active_task_mirror.js +0 -0
  18. package/dist/runtime/hooks/apply_patch.js +0 -0
  19. package/dist/runtime/hooks/dispatch.js +0 -0
  20. package/dist/runtime/hooks/hook_output.js +0 -0
  21. package/dist/runtime/hooks/memory_reconcile.js +0 -0
  22. package/dist/runtime/hooks/new_project_detect.js +0 -0
  23. package/dist/runtime/hooks/profession_resolver.js +0 -0
  24. package/dist/runtime/hooks/scope_intent.js +0 -0
  25. package/dist/runtime/hooks/session_id.js +0 -0
  26. package/dist/runtime/hooks/session_liveness.js +0 -0
  27. package/dist/runtime/hooks/stop_drive.js +0 -0
  28. package/dist/runtime/hooks/stop_stream.js +0 -0
  29. package/dist/runtime/hooks/subagent_guard.js +0 -0
  30. package/dist/runtime/hooks/transcript.js +0 -0
  31. package/dist/runtime/hooks/transcript_tasks.js +0 -0
  32. package/dist/runtime/ralph/orchestrator.d.ts.map +1 -1
  33. package/dist/runtime/ralph/orchestrator.js +2 -1
  34. package/dist/runtime/ralph/orchestrator.js.map +1 -1
  35. package/dist/setup/cli/limits_state.d.ts.map +1 -1
  36. package/dist/setup/cli/limits_state.js +6 -40
  37. package/dist/setup/cli/limits_state.js.map +1 -1
  38. package/dist/setup/cli/pack_walk.d.ts +32 -0
  39. package/dist/setup/cli/pack_walk.d.ts.map +1 -0
  40. package/dist/setup/cli/pack_walk.js +76 -0
  41. package/dist/setup/cli/pack_walk.js.map +1 -0
  42. package/dist/setup/cli/permissions_state.d.ts.map +1 -1
  43. package/dist/setup/cli/permissions_state.js +6 -37
  44. package/dist/setup/cli/permissions_state.js.map +1 -1
  45. package/dist/setup/cli/triggers_state.d.ts.map +1 -1
  46. package/dist/setup/cli/triggers_state.js +3 -29
  47. package/dist/setup/cli/triggers_state.js.map +1 -1
  48. package/dist/workgraph/events.d.ts.map +1 -1
  49. package/dist/workgraph/events.js +10 -0
  50. package/dist/workgraph/events.js.map +1 -1
  51. package/dist/workgraph/store.d.ts.map +1 -1
  52. package/dist/workgraph/store.js +5 -0
  53. package/dist/workgraph/store.js.map +1 -1
  54. package/dist/workgraph/types.d.ts +2 -1
  55. package/dist/workgraph/types.d.ts.map +1 -1
  56. package/docs/ARCHITECTURE.md +268 -0
  57. package/package.json +5 -3
  58. package/packs/builtin/coding-flow/skills/entry-and-handoffs/skill.yaml +13 -17
  59. package/dist/anti-drift/evaluator.d.ts +0 -88
  60. package/dist/anti-drift/evaluator.d.ts.map +0 -1
  61. package/dist/anti-drift/evaluator.js +0 -417
  62. package/dist/anti-drift/evaluator.js.map +0 -1
  63. package/dist/anti-drift/evaluator.test.js +0 -78
  64. package/dist/anti-drift/rules.d.ts +0 -80
  65. package/dist/anti-drift/rules.d.ts.map +0 -1
  66. package/dist/anti-drift/rules.js +0 -368
  67. package/dist/anti-drift/rules.js.map +0 -1
  68. package/dist/anti-drift/rules.test.js +0 -213
  69. package/dist/anti-drift/state.d.ts +0 -107
  70. package/dist/anti-drift/state.d.ts.map +0 -1
  71. package/dist/anti-drift/state.js +0 -177
  72. package/dist/anti-drift/state.js.map +0 -1
  73. package/dist/anti-drift/state.test.js +0 -120
  74. package/dist/chat/adapters/discord.d.ts +0 -41
  75. package/dist/chat/adapters/discord.d.ts.map +0 -1
  76. package/dist/chat/adapters/discord.js +0 -176
  77. package/dist/chat/adapters/discord.js.map +0 -1
  78. package/dist/chat/adapters/discord.test.js +0 -25
  79. package/dist/chat/adapters/slack.d.ts +0 -43
  80. package/dist/chat/adapters/slack.d.ts.map +0 -1
  81. package/dist/chat/adapters/slack.js +0 -172
  82. package/dist/chat/adapters/slack.js.map +0 -1
  83. package/dist/chat/adapters/slack.test.js +0 -30
  84. package/dist/chat/adapters/telegram.d.ts +0 -148
  85. package/dist/chat/adapters/telegram.d.ts.map +0 -1
  86. package/dist/chat/adapters/telegram.js +0 -498
  87. package/dist/chat/adapters/telegram.js.map +0 -1
  88. package/dist/chat/adapters/telegram.test.js +0 -94
  89. package/dist/chat/config.d.ts +0 -98
  90. package/dist/chat/config.d.ts.map +0 -1
  91. package/dist/chat/config.js +0 -185
  92. package/dist/chat/config.js.map +0 -1
  93. package/dist/chat/daemon/active-project.d.ts +0 -17
  94. package/dist/chat/daemon/active-project.d.ts.map +0 -1
  95. package/dist/chat/daemon/active-project.js +0 -23
  96. package/dist/chat/daemon/active-project.js.map +0 -1
  97. package/dist/chat/daemon/autospawn.d.ts +0 -40
  98. package/dist/chat/daemon/autospawn.d.ts.map +0 -1
  99. package/dist/chat/daemon/autospawn.js +0 -129
  100. package/dist/chat/daemon/autospawn.js.map +0 -1
  101. package/dist/chat/daemon/autospawn.test.js +0 -112
  102. package/dist/chat/daemon/cli.d.ts +0 -18
  103. package/dist/chat/daemon/cli.d.ts.map +0 -1
  104. package/dist/chat/daemon/cli.js +0 -71
  105. package/dist/chat/daemon/cli.js.map +0 -1
  106. package/dist/chat/daemon/collisions.js +0 -384
  107. package/dist/chat/daemon/health-check.d.ts +0 -69
  108. package/dist/chat/daemon/health-check.d.ts.map +0 -1
  109. package/dist/chat/daemon/health-check.js +0 -112
  110. package/dist/chat/daemon/health-check.js.map +0 -1
  111. package/dist/chat/daemon/inbox-read.d.ts +0 -35
  112. package/dist/chat/daemon/inbox-read.d.ts.map +0 -1
  113. package/dist/chat/daemon/inbox-read.js +0 -75
  114. package/dist/chat/daemon/inbox-read.js.map +0 -1
  115. package/dist/chat/daemon/inbox-read.test.js +0 -97
  116. package/dist/chat/daemon/inbox.d.ts +0 -63
  117. package/dist/chat/daemon/inbox.d.ts.map +0 -1
  118. package/dist/chat/daemon/inbox.js +0 -56
  119. package/dist/chat/daemon/inbox.js.map +0 -1
  120. package/dist/chat/daemon/inbox.test.js +0 -110
  121. package/dist/chat/daemon/lifecycle.d.ts +0 -71
  122. package/dist/chat/daemon/lifecycle.d.ts.map +0 -1
  123. package/dist/chat/daemon/lifecycle.js +0 -221
  124. package/dist/chat/daemon/lifecycle.js.map +0 -1
  125. package/dist/chat/daemon/lifecycle.test.js +0 -163
  126. package/dist/chat/daemon/protocol.d.ts +0 -107
  127. package/dist/chat/daemon/protocol.d.ts.map +0 -1
  128. package/dist/chat/daemon/protocol.js +0 -54
  129. package/dist/chat/daemon/protocol.js.map +0 -1
  130. package/dist/chat/daemon/routing.d.ts +0 -140
  131. package/dist/chat/daemon/routing.d.ts.map +0 -1
  132. package/dist/chat/daemon/routing.js +0 -198
  133. package/dist/chat/daemon/routing.js.map +0 -1
  134. package/dist/chat/daemon/routing.test.js +0 -259
  135. package/dist/chat/daemon/rpc-client.d.ts +0 -45
  136. package/dist/chat/daemon/rpc-client.d.ts.map +0 -1
  137. package/dist/chat/daemon/rpc-client.js +0 -133
  138. package/dist/chat/daemon/rpc-client.js.map +0 -1
  139. package/dist/chat/daemon/rpc-server.d.ts +0 -39
  140. package/dist/chat/daemon/rpc-server.d.ts.map +0 -1
  141. package/dist/chat/daemon/rpc-server.js +0 -385
  142. package/dist/chat/daemon/rpc-server.js.map +0 -1
  143. package/dist/chat/daemon/rpc.test.js +0 -177
  144. package/dist/chat/daemon/subscribers.js +0 -257
  145. package/dist/chat/daemon/worker.d.ts +0 -27
  146. package/dist/chat/daemon/worker.d.ts.map +0 -1
  147. package/dist/chat/daemon/worker.js +0 -313
  148. package/dist/chat/daemon/worker.js.map +0 -1
  149. package/dist/chat/daemon/workspace-topic.js +0 -324
  150. package/dist/chat/env-token.d.ts +0 -60
  151. package/dist/chat/env-token.d.ts.map +0 -1
  152. package/dist/chat/env-token.js +0 -137
  153. package/dist/chat/env-token.js.map +0 -1
  154. package/dist/chat/env-token.test.js +0 -160
  155. package/dist/chat/factory.d.ts +0 -30
  156. package/dist/chat/factory.d.ts.map +0 -1
  157. package/dist/chat/factory.js +0 -50
  158. package/dist/chat/factory.js.map +0 -1
  159. package/dist/chat/factory.test.js +0 -55
  160. package/dist/chat/gateway.d.ts +0 -176
  161. package/dist/chat/gateway.d.ts.map +0 -1
  162. package/dist/chat/gateway.js +0 -146
  163. package/dist/chat/gateway.js.map +0 -1
  164. package/dist/chat/gateway.test.js +0 -192
  165. package/dist/claude-md.d.ts +0 -39
  166. package/dist/claude-md.d.ts.map +0 -1
  167. package/dist/claude-md.js +0 -113
  168. package/dist/claude-md.js.map +0 -1
  169. package/dist/claude-md.test.js +0 -91
  170. package/dist/codex/activate.d.ts +0 -66
  171. package/dist/codex/activate.d.ts.map +0 -1
  172. package/dist/codex/activate.js +0 -329
  173. package/dist/codex/activate.js.map +0 -1
  174. package/dist/codex/activate.test.js +0 -229
  175. package/dist/codex/bundled-default/bundled-default.test.js +0 -161
  176. package/dist/codex/cli-publish.test.js +0 -133
  177. package/dist/codex/cli.d.ts +0 -35
  178. package/dist/codex/cli.d.ts.map +0 -1
  179. package/dist/codex/cli.js +0 -554
  180. package/dist/codex/cli.js.map +0 -1
  181. package/dist/codex/cli.test.js +0 -277
  182. package/dist/codex/import-skill-md.d.ts +0 -53
  183. package/dist/codex/import-skill-md.d.ts.map +0 -1
  184. package/dist/codex/import-skill-md.js +0 -236
  185. package/dist/codex/import-skill-md.js.map +0 -1
  186. package/dist/codex/import-skill-md.test.js +0 -225
  187. package/dist/codex/loader.d.ts +0 -27
  188. package/dist/codex/loader.d.ts.map +0 -1
  189. package/dist/codex/loader.js +0 -86
  190. package/dist/codex/loader.js.map +0 -1
  191. package/dist/codex/loader.test.js +0 -75
  192. package/dist/codex/parse.d.ts +0 -28
  193. package/dist/codex/parse.d.ts.map +0 -1
  194. package/dist/codex/parse.js +0 -309
  195. package/dist/codex/parse.js.map +0 -1
  196. package/dist/codex/parse.test.js +0 -241
  197. package/dist/codex/store.d.ts +0 -87
  198. package/dist/codex/store.d.ts.map +0 -1
  199. package/dist/codex/store.js +0 -205
  200. package/dist/codex/store.js.map +0 -1
  201. package/dist/codex/store.test.js +0 -242
  202. package/dist/codex/types.d.ts +0 -398
  203. package/dist/codex/types.d.ts.map +0 -1
  204. package/dist/codex/types.js +0 -21
  205. package/dist/codex/types.js.map +0 -1
  206. package/dist/config.d.ts +0 -53
  207. package/dist/config.d.ts.map +0 -1
  208. package/dist/config.js +0 -202
  209. package/dist/config.js.map +0 -1
  210. package/dist/config.test.js +0 -117
  211. package/dist/engine/cli.d.ts +0 -14
  212. package/dist/engine/cli.d.ts.map +0 -1
  213. package/dist/engine/cli.js +0 -171
  214. package/dist/engine/cli.js.map +0 -1
  215. package/dist/engine/client.d.ts +0 -219
  216. package/dist/engine/client.d.ts.map +0 -1
  217. package/dist/engine/client.js +0 -312
  218. package/dist/engine/client.js.map +0 -1
  219. package/dist/engine/config.d.ts +0 -62
  220. package/dist/engine/config.d.ts.map +0 -1
  221. package/dist/engine/config.js +0 -223
  222. package/dist/engine/config.js.map +0 -1
  223. package/dist/engine/index.d.ts +0 -17
  224. package/dist/engine/index.d.ts.map +0 -1
  225. package/dist/engine/index.js +0 -16
  226. package/dist/engine/index.js.map +0 -1
  227. package/dist/engine/resolver.d.ts +0 -62
  228. package/dist/engine/resolver.d.ts.map +0 -1
  229. package/dist/engine/resolver.js +0 -103
  230. package/dist/engine/resolver.js.map +0 -1
  231. package/dist/engine/singleton.d.ts +0 -95
  232. package/dist/engine/singleton.d.ts.map +0 -1
  233. package/dist/engine/singleton.js +0 -325
  234. package/dist/engine/singleton.js.map +0 -1
  235. package/dist/engine/types.d.ts +0 -402
  236. package/dist/engine/types.d.ts.map +0 -1
  237. package/dist/engine/types.js +0 -22
  238. package/dist/engine/types.js.map +0 -1
  239. package/dist/engine-binary-resolver.js +0 -110
  240. package/dist/engine-binary-resolver.test.js +0 -61
  241. package/dist/engine-cli.js +0 -60
  242. package/dist/engine-client.js +0 -301
  243. package/dist/engine-client.test.js +0 -118
  244. package/dist/functions/chain_state.d.ts +0 -51
  245. package/dist/functions/chain_state.d.ts.map +0 -1
  246. package/dist/functions/chain_state.js +0 -59
  247. package/dist/functions/chain_state.js.map +0 -1
  248. package/dist/hooks/drift-catalog.d.ts +0 -68
  249. package/dist/hooks/drift-catalog.d.ts.map +0 -1
  250. package/dist/hooks/drift-catalog.js +0 -184
  251. package/dist/hooks/drift-catalog.js.map +0 -1
  252. package/dist/hooks/drift-catalog.test.js +0 -154
  253. package/dist/hooks/drift-patterns.d.ts +0 -110
  254. package/dist/hooks/drift-patterns.d.ts.map +0 -1
  255. package/dist/hooks/drift-patterns.js +0 -289
  256. package/dist/hooks/drift-patterns.js.map +0 -1
  257. package/dist/hooks/drift-patterns.test.js +0 -325
  258. package/dist/hooks/engine-vocab-gate.d.ts +0 -108
  259. package/dist/hooks/engine-vocab-gate.d.ts.map +0 -1
  260. package/dist/hooks/engine-vocab-gate.js +0 -225
  261. package/dist/hooks/engine-vocab-gate.js.map +0 -1
  262. package/dist/hooks/engine-vocab-gate.test.js +0 -170
  263. package/dist/hooks/heartbeat.d.ts +0 -107
  264. package/dist/hooks/heartbeat.d.ts.map +0 -1
  265. package/dist/hooks/heartbeat.js +0 -316
  266. package/dist/hooks/heartbeat.js.map +0 -1
  267. package/dist/hooks/heartbeat.test.js +0 -393
  268. package/dist/hooks/honesty-ledger-session-scope.test.js +0 -100
  269. package/dist/hooks/honesty-ledger.d.ts +0 -123
  270. package/dist/hooks/honesty-ledger.d.ts.map +0 -1
  271. package/dist/hooks/honesty-ledger.js +0 -226
  272. package/dist/hooks/honesty-ledger.js.map +0 -1
  273. package/dist/hooks/honesty-ledger.test.js +0 -466
  274. package/dist/hooks/inline-report-check.d.ts +0 -63
  275. package/dist/hooks/inline-report-check.d.ts.map +0 -1
  276. package/dist/hooks/inline-report-check.js +0 -88
  277. package/dist/hooks/inline-report-check.js.map +0 -1
  278. package/dist/hooks/inline-report-check.test.js +0 -96
  279. package/dist/hooks/pre-tool-use.d.ts +0 -62
  280. package/dist/hooks/pre-tool-use.d.ts.map +0 -1
  281. package/dist/hooks/pre-tool-use.js +0 -342
  282. package/dist/hooks/pre-tool-use.js.map +0 -1
  283. package/dist/hooks/pre-tool-use.test.js +0 -134
  284. package/dist/hooks/session-end.d.ts +0 -15
  285. package/dist/hooks/session-end.d.ts.map +0 -1
  286. package/dist/hooks/session-end.js +0 -60
  287. package/dist/hooks/session-end.js.map +0 -1
  288. package/dist/hooks/session-end.test.js +0 -52
  289. package/dist/hooks/stop.d.ts +0 -35
  290. package/dist/hooks/stop.d.ts.map +0 -1
  291. package/dist/hooks/stop.js +0 -136
  292. package/dist/hooks/stop.js.map +0 -1
  293. package/dist/hooks/transcript-active-task.test.js +0 -342
  294. package/dist/hooks/transcript.d.ts +0 -26
  295. package/dist/hooks/transcript.d.ts.map +0 -1
  296. package/dist/hooks/transcript.js +0 -266
  297. package/dist/hooks/transcript.js.map +0 -1
  298. package/dist/hooks/transcript.test.js +0 -103
  299. package/dist/hooks/user-prompt-submit.d.ts +0 -74
  300. package/dist/hooks/user-prompt-submit.d.ts.map +0 -1
  301. package/dist/hooks/user-prompt-submit.js +0 -256
  302. package/dist/hooks/user-prompt-submit.js.map +0 -1
  303. package/dist/hooks/user-prompt-submit.test.js +0 -118
  304. package/dist/hooks/versioning-gate.d.ts +0 -101
  305. package/dist/hooks/versioning-gate.d.ts.map +0 -1
  306. package/dist/hooks/versioning-gate.js +0 -245
  307. package/dist/hooks/versioning-gate.js.map +0 -1
  308. package/dist/hooks/versioning-gate.test.js +0 -368
  309. package/dist/hooks/workflow-gate.d.ts +0 -64
  310. package/dist/hooks/workflow-gate.d.ts.map +0 -1
  311. package/dist/hooks/workflow-gate.js +0 -152
  312. package/dist/hooks/workflow-gate.js.map +0 -1
  313. package/dist/hooks/workflow-gate.test.js +0 -197
  314. package/dist/hooks-cli.d.ts +0 -25
  315. package/dist/hooks-cli.d.ts.map +0 -1
  316. package/dist/hooks-cli.js +0 -286
  317. package/dist/hooks-cli.js.map +0 -1
  318. package/dist/hooks-cli.test.js +0 -148
  319. package/dist/origin.d.ts +0 -16
  320. package/dist/origin.d.ts.map +0 -1
  321. package/dist/origin.js +0 -92
  322. package/dist/origin.js.map +0 -1
  323. package/dist/packs/seed_lessons_ingest.d.ts +0 -30
  324. package/dist/packs/seed_lessons_ingest.d.ts.map +0 -1
  325. package/dist/packs/seed_lessons_ingest.js +0 -107
  326. package/dist/packs/seed_lessons_ingest.js.map +0 -1
  327. package/dist/project-cli.d.ts +0 -7
  328. package/dist/project-cli.d.ts.map +0 -1
  329. package/dist/project-cli.js +0 -145
  330. package/dist/project-cli.js.map +0 -1
  331. package/dist/project.d.ts +0 -127
  332. package/dist/project.d.ts.map +0 -1
  333. package/dist/project.js +0 -281
  334. package/dist/project.js.map +0 -1
  335. package/dist/project.test.js +0 -287
  336. package/dist/rag/backends/loop_engine.d.ts +0 -61
  337. package/dist/rag/backends/loop_engine.d.ts.map +0 -1
  338. package/dist/rag/backends/loop_engine.js +0 -160
  339. package/dist/rag/backends/loop_engine.js.map +0 -1
  340. package/dist/recall.d.ts +0 -82
  341. package/dist/recall.d.ts.map +0 -1
  342. package/dist/recall.js +0 -81
  343. package/dist/recall.js.map +0 -1
  344. package/dist/runtime/agent_bridge/autospawn.d.ts +0 -131
  345. package/dist/runtime/agent_bridge/autospawn.d.ts.map +0 -1
  346. package/dist/runtime/agent_bridge/autospawn.js +0 -251
  347. package/dist/runtime/agent_bridge/autospawn.js.map +0 -1
  348. package/dist/runtime/chain_state.d.ts +0 -124
  349. package/dist/runtime/chain_state.d.ts.map +0 -1
  350. package/dist/runtime/chain_state.js +0 -189
  351. package/dist/runtime/chain_state.js.map +0 -1
  352. package/dist/runtime/hooks/permission_decision.d.ts +0 -34
  353. package/dist/runtime/hooks/permission_decision.d.ts.map +0 -1
  354. package/dist/runtime/hooks/permission_decision.js +0 -39
  355. package/dist/runtime/hooks/permission_decision.js.map +0 -1
  356. package/dist/runtime/workflow_fsm.d.ts +0 -21
  357. package/dist/runtime/workflow_fsm.d.ts.map +0 -1
  358. package/dist/runtime/workflow_fsm.js +0 -25
  359. package/dist/runtime/workflow_fsm.js.map +0 -1
  360. package/dist/runtime/workflow_map.d.ts +0 -26
  361. package/dist/runtime/workflow_map.d.ts.map +0 -1
  362. package/dist/runtime/workflow_map.js +0 -38
  363. package/dist/runtime/workflow_map.js.map +0 -1
  364. package/dist/scope.d.ts +0 -48
  365. package/dist/scope.d.ts.map +0 -1
  366. package/dist/scope.js +0 -111
  367. package/dist/scope.js.map +0 -1
  368. package/dist/setup/cli/topic_create_step.d.ts +0 -84
  369. package/dist/setup/cli/topic_create_step.d.ts.map +0 -1
  370. package/dist/setup/cli/topic_create_step.js +0 -213
  371. package/dist/setup/cli/topic_create_step.js.map +0 -1
  372. package/dist/system-export.d.ts +0 -65
  373. package/dist/system-export.d.ts.map +0 -1
  374. package/dist/system-export.js +0 -194
  375. package/dist/system-export.js.map +0 -1
  376. package/dist/utterance/classifier.d.ts +0 -53
  377. package/dist/utterance/classifier.d.ts.map +0 -1
  378. package/dist/utterance/classifier.js +0 -184
  379. package/dist/utterance/classifier.js.map +0 -1
  380. package/dist/utterance/classifier.test.js +0 -147
@@ -1,64 +0,0 @@
1
- /**
2
- * Workflow gate — engine-backed commit-blocking check (v0.6.1).
3
- *
4
- * Wired into the PreToolUse hook when the planned tool call is
5
- * `git commit` (without `--amend`). Checks that the active task's
6
- * phase ledger has the required workflow phases logged; blocks the
7
- * commit with an actionable stderr message if not.
8
- *
9
- * The required-phase policy is fixed for now (per user direction):
10
- * `audit` + `post_research` must be logged. These are the phases
11
- * empirically skipped under "ship fast" pressure. The other phases
12
- * (pre_research, learn, code, test, fix) are either obvious from the
13
- * commit itself or naturally happen — gating them too creates
14
- * paperwork friction without catching real drift.
15
- *
16
- * Fail-open invariant: any error reaching the engine, parsing the
17
- * transcript, or detecting the active task → return non-blocking
18
- * with a stderr warning. The gate is best-effort drift protection,
19
- * not a hard safety wall (mirrors the honesty-ledger precedent at
20
- * pre-tool-use.ts).
21
- */
22
- /**
23
- * Resolve the set of phases that must be logged before `git commit`
24
- * is allowed.
25
- *
26
- * 0.7.16 (drift-as-codex chunk 3a): the required-phase list now comes
27
- * from `bundled-default/codex.yaml`'s `default_workflow_id` workflow,
28
- * filtered to phases with `required: true`. Previously this was a
29
- * hard-coded `REQUIRED_PHASES` array; the codex is now the single
30
- * source of truth, which is what drift-as-codex was for.
31
- *
32
- * Fail-open: if the codex can't be loaded (missing file, parse error,
33
- * missing workflow id), the gate disables itself with a stderr
34
- * warning rather than blocking every commit. The codex is bundled
35
- * in the npm package so this should be unreachable in normal use.
36
- */
37
- export declare function getRequiredPhasesFromCodex(): readonly string[];
38
- export interface WorkflowGateInput {
39
- /** Path to the session's JSONL transcript. Optional — gate falls
40
- * back to allow-commit when absent (can't detect active task). */
41
- transcriptPath?: string;
42
- }
43
- export interface WorkflowGateResult {
44
- /** True when the commit should be blocked. */
45
- block: boolean;
46
- /** Stderr message (always present when stderr should be written;
47
- * non-blocking warnings also use this). */
48
- stderr: string;
49
- }
50
- /**
51
- * Evaluate whether the planned `git commit` should be blocked.
52
- * Pure function over its inputs + an engine RPC; safe to call from
53
- * the hook handler.
54
- */
55
- export declare function evaluateWorkflowGate(input: WorkflowGateInput): Promise<WorkflowGateResult>;
56
- /**
57
- * Emergency-override env var. Lets the user bypass the gate when they
58
- * know what they're doing. Logged loudly to stderr so the bypass is
59
- * always visible in scrollback / CI logs.
60
- *
61
- * Exported for the test suite.
62
- */
63
- export declare function checkOverrideEnv(): boolean;
64
- //# sourceMappingURL=workflow-gate.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"workflow-gate.d.ts","sourceRoot":"","sources":["../../src.legacy/hooks/workflow-gate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAOH;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,0BAA0B,IAAI,SAAS,MAAM,EAAE,CAW9D;AAED,MAAM,WAAW,iBAAiB;IAChC;sEACkE;IAClE,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,kBAAkB;IACjC,8CAA8C;IAC9C,KAAK,EAAE,OAAO,CAAC;IACf;+CAC2C;IAC3C,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;GAIG;AACH,wBAAsB,oBAAoB,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CA4EhG;AAiBD;;;;;;GAMG;AACH,wBAAgB,gBAAgB,IAAI,OAAO,CAE1C"}
@@ -1,152 +0,0 @@
1
- /**
2
- * Workflow gate — engine-backed commit-blocking check (v0.6.1).
3
- *
4
- * Wired into the PreToolUse hook when the planned tool call is
5
- * `git commit` (without `--amend`). Checks that the active task's
6
- * phase ledger has the required workflow phases logged; blocks the
7
- * commit with an actionable stderr message if not.
8
- *
9
- * The required-phase policy is fixed for now (per user direction):
10
- * `audit` + `post_research` must be logged. These are the phases
11
- * empirically skipped under "ship fast" pressure. The other phases
12
- * (pre_research, learn, code, test, fix) are either obvious from the
13
- * commit itself or naturally happen — gating them too creates
14
- * paperwork friction without catching real drift.
15
- *
16
- * Fail-open invariant: any error reaching the engine, parsing the
17
- * transcript, or detecting the active task → return non-blocking
18
- * with a stderr warning. The gate is best-effort drift protection,
19
- * not a hard safety wall (mirrors the honesty-ledger precedent at
20
- * pre-tool-use.ts).
21
- */
22
- import { loadBundledDefaultCodex } from "../codex/loader.js";
23
- import { OpenSquidEngine } from "../engine-client.js";
24
- import { readActiveTaskId } from "./transcript.js";
25
- /**
26
- * Resolve the set of phases that must be logged before `git commit`
27
- * is allowed.
28
- *
29
- * 0.7.16 (drift-as-codex chunk 3a): the required-phase list now comes
30
- * from `bundled-default/codex.yaml`'s `default_workflow_id` workflow,
31
- * filtered to phases with `required: true`. Previously this was a
32
- * hard-coded `REQUIRED_PHASES` array; the codex is now the single
33
- * source of truth, which is what drift-as-codex was for.
34
- *
35
- * Fail-open: if the codex can't be loaded (missing file, parse error,
36
- * missing workflow id), the gate disables itself with a stderr
37
- * warning rather than blocking every commit. The codex is bundled
38
- * in the npm package so this should be unreachable in normal use.
39
- */
40
- export function getRequiredPhasesFromCodex() {
41
- const codex = loadBundledDefaultCodex();
42
- const workflowId = codex.default_workflow_id;
43
- if (!workflowId) {
44
- throw new Error("bundled-default codex has no default_workflow_id");
45
- }
46
- const workflow = (codex.workflows ?? []).find((w) => w.id === workflowId);
47
- if (!workflow) {
48
- throw new Error(`bundled-default codex has no workflow with id=${workflowId}`);
49
- }
50
- return workflow.phases.filter((p) => p.required).map((p) => p.name);
51
- }
52
- /**
53
- * Evaluate whether the planned `git commit` should be blocked.
54
- * Pure function over its inputs + an engine RPC; safe to call from
55
- * the hook handler.
56
- */
57
- export async function evaluateWorkflowGate(input) {
58
- // Emergency override — explicit env var bypass with loud warning.
59
- if (checkOverrideEnv()) {
60
- return {
61
- block: false,
62
- stderr: "🦑 [opensquid workflow-gate] BYPASSED via OPENSQUID_SKIP_WORKFLOW_GATE=1\n",
63
- };
64
- }
65
- if (!input.transcriptPath) {
66
- // Can't detect active task. Allow with a debug-level warn so the
67
- // gate's absence is observable.
68
- return {
69
- block: false,
70
- stderr: "[opensquid workflow-gate] no transcript_path — gate skipped\n",
71
- };
72
- }
73
- let taskId = null;
74
- try {
75
- taskId = await readActiveTaskId(input.transcriptPath);
76
- }
77
- catch (err) {
78
- return {
79
- block: false,
80
- stderr: `[opensquid workflow-gate] transcript read failed (proceeding): ${err instanceof Error ? err.message : err}\n`,
81
- };
82
- }
83
- if (!taskId) {
84
- // No active task — nothing to gate. Common case: ad-hoc commits
85
- // outside any TaskCreate flow. Allow silently.
86
- return { block: false, stderr: "" };
87
- }
88
- let requiredPhases;
89
- try {
90
- requiredPhases = getRequiredPhasesFromCodex();
91
- }
92
- catch (err) {
93
- // Codex unloadable (missing bundled YAML, parse error, etc.).
94
- // Fail-open consistent with the gate's other failure modes.
95
- return {
96
- block: false,
97
- stderr: `[opensquid workflow-gate] codex unloadable (proceeding): ${err instanceof Error ? err.message : err}\n`,
98
- };
99
- }
100
- const engine = new OpenSquidEngine();
101
- let ledger = null;
102
- try {
103
- ledger = await engine.getTaskLedger({
104
- task_id: taskId,
105
- });
106
- }
107
- catch (err) {
108
- // Engine unreachable, binary missing, RPC error. Fail-open.
109
- return {
110
- block: false,
111
- stderr: `[opensquid workflow-gate] engine unreachable (proceeding): ${err instanceof Error ? err.message : err}\n`,
112
- };
113
- }
114
- finally {
115
- // The OpenSquidEngine wrapper spawns a subprocess; shut it down
116
- // so the hook process can exit cleanly.
117
- try {
118
- engine.shutdown();
119
- }
120
- catch {
121
- /* best-effort */
122
- }
123
- }
124
- const logged = new Set(ledger.phases_logged);
125
- const missing = requiredPhases.filter((p) => !logged.has(p));
126
- if (missing.length === 0) {
127
- return { block: false, stderr: "" };
128
- }
129
- return {
130
- block: true,
131
- stderr: buildBlockMessage(taskId, missing, ledger.phases_logged),
132
- };
133
- }
134
- function buildBlockMessage(taskId, missing, loggedPhases) {
135
- const loggedList = loggedPhases.length === 0 ? "(none)" : loggedPhases.join(", ");
136
- return (`🦑 [opensquid workflow-gate] commit blocked for task ${taskId}\n` +
137
- ` missing phases: ${missing.join(", ")}\n` +
138
- ` logged phases: ${loggedList}\n` +
139
- ` Log the missing phases via the \`log_phase\` MCP tool, then retry the commit.\n` +
140
- ` Override (genuine emergency): set OPENSQUID_SKIP_WORKFLOW_GATE=1 for this command.\n`);
141
- }
142
- /**
143
- * Emergency-override env var. Lets the user bypass the gate when they
144
- * know what they're doing. Logged loudly to stderr so the bypass is
145
- * always visible in scrollback / CI logs.
146
- *
147
- * Exported for the test suite.
148
- */
149
- export function checkOverrideEnv() {
150
- return process.env.OPENSQUID_SKIP_WORKFLOW_GATE === "1";
151
- }
152
- //# sourceMappingURL=workflow-gate.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"workflow-gate.js","sourceRoot":"","sources":["../../src.legacy/hooks/workflow-gate.ts"],"names":[],"mappings":"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"}
@@ -1,197 +0,0 @@
1
- /**
2
- * Workflow-gate tests — covers the pure evaluator (no engine subprocess
3
- * spawned). We mock the OpenSquidEngine.getTaskLedger to assert the
4
- * gate behavior without standing up a real engine binary. The hook
5
- * test wires the gate into the actual PreToolUse flow.
6
- */
7
- import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
8
- import * as crypto from "node:crypto";
9
- import { promises as fs } from "node:fs";
10
- import * as os from "node:os";
11
- import * as path from "node:path";
12
- import * as engineClient from "../engine-client.js";
13
- import { checkOverrideEnv, evaluateWorkflowGate, getRequiredPhasesFromCodex, } from "./workflow-gate.js";
14
- // ---------------------------------------------------------------------
15
- // Helpers
16
- // ---------------------------------------------------------------------
17
- let tmpDir;
18
- let transcriptPath;
19
- beforeEach(async () => {
20
- tmpDir = path.join(os.tmpdir(), `opensquid-gate-${crypto.randomUUID()}`);
21
- await fs.mkdir(tmpDir, { recursive: true });
22
- transcriptPath = path.join(tmpDir, "transcript.jsonl");
23
- });
24
- afterEach(async () => {
25
- await fs.rm(tmpDir, { recursive: true, force: true });
26
- delete process.env.OPENSQUID_SKIP_WORKFLOW_GATE;
27
- vi.restoreAllMocks();
28
- });
29
- async function writeTranscriptWithActiveTask(taskId) {
30
- // Single assistant tool_use event with a TodoWrite block. Matches
31
- // the shape readActiveTaskId scans for.
32
- const event = {
33
- type: "assistant",
34
- message: {
35
- role: "assistant",
36
- content: [
37
- {
38
- type: "tool_use",
39
- name: "TodoWrite",
40
- input: {
41
- todos: [
42
- { id: "999", status: "completed", content: "done thing" },
43
- { id: taskId, status: "in_progress", content: "active thing" },
44
- ],
45
- },
46
- },
47
- ],
48
- },
49
- };
50
- await fs.writeFile(transcriptPath, JSON.stringify(event) + "\n", "utf8");
51
- }
52
- /** Mock OpenSquidEngine.getTaskLedger to return a specific phase set. */
53
- function mockLedger(phasesLogged) {
54
- vi.spyOn(engineClient.OpenSquidEngine.prototype, "getTaskLedger").mockResolvedValue({
55
- task_id: "127",
56
- phases_logged: phasesLogged,
57
- entries: phasesLogged.map((p) => ({
58
- phase: p,
59
- logged_at: "2026-05-16T08:00:00.000Z",
60
- note: null,
61
- })),
62
- });
63
- // shutdown() is called in the finally block of evaluateWorkflowGate.
64
- vi.spyOn(engineClient.OpenSquidEngine.prototype, "shutdown").mockImplementation(() => { });
65
- }
66
- /** Mock the engine call to throw — simulates engine unreachable. */
67
- function mockLedgerError(message) {
68
- vi.spyOn(engineClient.OpenSquidEngine.prototype, "getTaskLedger").mockRejectedValue(new Error(message));
69
- vi.spyOn(engineClient.OpenSquidEngine.prototype, "shutdown").mockImplementation(() => { });
70
- }
71
- // ---------------------------------------------------------------------
72
- // Fail-open input scenarios — no block, no engine call
73
- // ---------------------------------------------------------------------
74
- describe("evaluateWorkflowGate — fail-open inputs", () => {
75
- it("returns allow with warning when transcriptPath is missing", async () => {
76
- const result = await evaluateWorkflowGate({});
77
- expect(result.block).toBe(false);
78
- expect(result.stderr).toContain("no transcript_path");
79
- });
80
- it("returns allow when transcript has no in_progress task", async () => {
81
- await fs.writeFile(transcriptPath, "", "utf8");
82
- const result = await evaluateWorkflowGate({ transcriptPath });
83
- expect(result.block).toBe(false);
84
- expect(result.stderr).toBe("");
85
- });
86
- it("returns allow with warning when transcript path doesn't exist", async () => {
87
- const result = await evaluateWorkflowGate({
88
- transcriptPath: path.join(tmpDir, "nonexistent.jsonl"),
89
- });
90
- expect(result.block).toBe(false);
91
- // readActiveTaskId swallows the read error → returns null → allow silently.
92
- expect(result.stderr).toBe("");
93
- });
94
- });
95
- // ---------------------------------------------------------------------
96
- // Active task detected → engine RPC drives decision
97
- // ---------------------------------------------------------------------
98
- describe("evaluateWorkflowGate — with active task", () => {
99
- // 0.7.6 (#150): REQUIRED_PHASES expanded from ["audit",
100
- // "post_research"] to all 6 required (fix stays soft). Tests
101
- // updated accordingly. The 2-phase variant used to allow #132 to
102
- // ship with most of its workflow unlogged.
103
- it("BLOCKS when most required phases are missing", async () => {
104
- await writeTranscriptWithActiveTask("127");
105
- mockLedger(["code", "test"]);
106
- const result = await evaluateWorkflowGate({ transcriptPath });
107
- expect(result.block).toBe(true);
108
- expect(result.stderr).toContain("commit blocked");
109
- expect(result.stderr).toContain("pre_research");
110
- expect(result.stderr).toContain("audit");
111
- expect(result.stderr).toContain("post_research");
112
- expect(result.stderr).toContain("127");
113
- });
114
- it("BLOCKS when only audit is missing (6-of-6 expansion)", async () => {
115
- await writeTranscriptWithActiveTask("127");
116
- mockLedger(["pre_research", "learn", "code", "test", "post_research"]);
117
- const result = await evaluateWorkflowGate({ transcriptPath });
118
- expect(result.block).toBe(true);
119
- expect(result.stderr).toContain("missing phases: audit");
120
- });
121
- it("BLOCKS when only post_research is missing", async () => {
122
- await writeTranscriptWithActiveTask("127");
123
- mockLedger(["pre_research", "learn", "code", "test", "audit"]);
124
- const result = await evaluateWorkflowGate({ transcriptPath });
125
- expect(result.block).toBe(true);
126
- expect(result.stderr).toContain("missing phases: post_research");
127
- });
128
- it("BLOCKS when only pre_research is missing (catches #132's shape)", async () => {
129
- // #132 shipped today with only audit + post_research logged.
130
- // The pre-#150 gate let it through. New gate catches it.
131
- await writeTranscriptWithActiveTask("132");
132
- mockLedger(["learn", "code", "test", "audit", "post_research"]);
133
- const result = await evaluateWorkflowGate({ transcriptPath });
134
- expect(result.block).toBe(true);
135
- expect(result.stderr).toContain("missing phases: pre_research");
136
- });
137
- it("ALLOWS when all 6 required phases are logged (fix stays optional)", async () => {
138
- await writeTranscriptWithActiveTask("127");
139
- mockLedger(["pre_research", "learn", "code", "test", "audit", "post_research"]);
140
- const result = await evaluateWorkflowGate({ transcriptPath });
141
- expect(result.block).toBe(false);
142
- expect(result.stderr).toBe("");
143
- });
144
- it("ALLOWS when more than the required phases are logged (extra is fine)", async () => {
145
- await writeTranscriptWithActiveTask("127");
146
- mockLedger(["pre_research", "learn", "code", "test", "audit", "post_research", "fix"]);
147
- const result = await evaluateWorkflowGate({ transcriptPath });
148
- expect(result.block).toBe(false);
149
- });
150
- });
151
- // ---------------------------------------------------------------------
152
- // Fail-open on engine error
153
- // ---------------------------------------------------------------------
154
- describe("evaluateWorkflowGate — fail-open invariant", () => {
155
- it("ALLOWS with stderr warning when engine RPC throws", async () => {
156
- await writeTranscriptWithActiveTask("127");
157
- mockLedgerError("ECONNREFUSED: engine not running");
158
- const result = await evaluateWorkflowGate({ transcriptPath });
159
- expect(result.block).toBe(false);
160
- expect(result.stderr).toContain("engine unreachable");
161
- expect(result.stderr).toContain("ECONNREFUSED");
162
- });
163
- });
164
- // ---------------------------------------------------------------------
165
- // Emergency override
166
- // ---------------------------------------------------------------------
167
- // ---------------------------------------------------------------------
168
- // Codex-driven required-phases (drift-as-codex chunk 3a, 0.7.16)
169
- // ---------------------------------------------------------------------
170
- describe("getRequiredPhasesFromCodex", () => {
171
- it("returns the 6 required phases from the bundled-default codex's standard-7-phase workflow", () => {
172
- const phases = getRequiredPhasesFromCodex();
173
- expect(phases).toEqual(["pre_research", "learn", "code", "test", "audit", "post_research"]);
174
- });
175
- it("excludes the `fix` phase (required: false in the codex)", () => {
176
- const phases = getRequiredPhasesFromCodex();
177
- expect(phases).not.toContain("fix");
178
- });
179
- });
180
- describe("evaluateWorkflowGate — emergency override", () => {
181
- it("ALLOWS with bypass warning when OPENSQUID_SKIP_WORKFLOW_GATE=1", async () => {
182
- process.env.OPENSQUID_SKIP_WORKFLOW_GATE = "1";
183
- expect(checkOverrideEnv()).toBe(true);
184
- // Should bypass even if all the other signals say block.
185
- await writeTranscriptWithActiveTask("127");
186
- mockLedger(["code"]); // would otherwise block
187
- const result = await evaluateWorkflowGate({ transcriptPath });
188
- expect(result.block).toBe(false);
189
- expect(result.stderr).toContain("BYPASSED");
190
- });
191
- it("respects the env var only when EXACTLY '1' (not 'true', not 'yes')", async () => {
192
- process.env.OPENSQUID_SKIP_WORKFLOW_GATE = "true";
193
- expect(checkOverrideEnv()).toBe(false);
194
- process.env.OPENSQUID_SKIP_WORKFLOW_GATE = "1";
195
- expect(checkOverrideEnv()).toBe(true);
196
- });
197
- });
@@ -1,25 +0,0 @@
1
- export declare class HooksCliError extends Error {
2
- readonly hint?: string | undefined;
3
- constructor(message: string, hint?: string | undefined);
4
- }
5
- interface ClaudeCommandHook {
6
- type: "command";
7
- command: string;
8
- /** Custom non-standard marker so we can find our own hook later. */
9
- _id?: string;
10
- }
11
- interface ClaudePromptHook {
12
- type: "prompt";
13
- prompt: string;
14
- model?: string;
15
- /** Optional timeout in seconds — Claude Code default is 30s for prompt hooks. */
16
- timeout?: number;
17
- _id?: string;
18
- }
19
- type ClaudeHook = ClaudeCommandHook | ClaudePromptHook;
20
- /** True when a hook entry is recognizably opensquid's. */
21
- export declare function isOurHook(h: ClaudeHook): boolean;
22
- export type HooksCliCmd = "install" | "uninstall" | "doctor";
23
- export declare function runHooksCli(cmd: HooksCliCmd, _argv: string[]): Promise<void>;
24
- export {};
25
- //# sourceMappingURL=hooks-cli.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"hooks-cli.d.ts","sourceRoot":"","sources":["../src.legacy/hooks-cli.ts"],"names":[],"mappings":"AAsBA,qBAAa,aAAc,SAAQ,KAAK;aAGpB,IAAI,CAAC,EAAE,MAAM;gBAD7B,OAAO,EAAE,MAAM,EACC,IAAI,CAAC,EAAE,MAAM,YAAA;CAKhC;AA2DD,UAAU,iBAAiB;IACzB,IAAI,EAAE,SAAS,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,oEAAoE;IACpE,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,UAAU,gBAAgB;IACxB,IAAI,EAAE,QAAQ,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iFAAiF;IACjF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,KAAK,UAAU,GAAG,iBAAiB,GAAG,gBAAgB,CAAC;AAsDvD,0DAA0D;AAC1D,wBAAgB,SAAS,CAAC,CAAC,EAAE,UAAU,GAAG,OAAO,CAoBhD;AAkJD,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,WAAW,GAAG,QAAQ,CAAC;AAE7D,wBAAsB,WAAW,CAAC,GAAG,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAYlF"}