opensquid 0.5.441 → 0.5.449

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (391) hide show
  1. package/README.md +1 -0
  2. package/dist/functions/arm_scope.d.ts +27 -0
  3. package/dist/functions/arm_scope.d.ts.map +1 -0
  4. package/dist/functions/arm_scope.js +52 -0
  5. package/dist/functions/arm_scope.js.map +1 -0
  6. package/dist/functions/index.d.ts +1 -0
  7. package/dist/functions/index.d.ts.map +1 -1
  8. package/dist/functions/index.js +1 -0
  9. package/dist/functions/index.js.map +1 -1
  10. package/dist/functions/recall_pre_inject.d.ts.map +1 -1
  11. package/dist/functions/recall_pre_inject.js +12 -0
  12. package/dist/functions/recall_pre_inject.js.map +1 -1
  13. package/dist/rag/store_git.d.ts +23 -0
  14. package/dist/rag/store_git.d.ts.map +1 -0
  15. package/dist/rag/store_git.js +57 -0
  16. package/dist/rag/store_git.js.map +1 -0
  17. package/dist/runtime/bootstrap.d.ts.map +1 -1
  18. package/dist/runtime/bootstrap.js +2 -0
  19. package/dist/runtime/bootstrap.js.map +1 -1
  20. package/dist/runtime/handoff/render.d.ts +5 -4
  21. package/dist/runtime/handoff/render.d.ts.map +1 -1
  22. package/dist/runtime/handoff/render.js +7 -7
  23. package/dist/runtime/handoff/render.js.map +1 -1
  24. package/dist/runtime/hooks/active_task_mirror.js +0 -0
  25. package/dist/runtime/hooks/apply_patch.js +0 -0
  26. package/dist/runtime/hooks/dispatch.js +0 -0
  27. package/dist/runtime/hooks/hook_output.js +0 -0
  28. package/dist/runtime/hooks/memory_reconcile.js +0 -0
  29. package/dist/runtime/hooks/new_project_detect.js +0 -0
  30. package/dist/runtime/hooks/profession_resolver.js +0 -0
  31. package/dist/runtime/hooks/scope_intent.js +0 -0
  32. package/dist/runtime/hooks/session-end.js +11 -0
  33. package/dist/runtime/hooks/session-end.js.map +1 -1
  34. package/dist/runtime/hooks/session_id.js +0 -0
  35. package/dist/runtime/hooks/session_liveness.js +0 -0
  36. package/dist/runtime/hooks/stop_drive.js +0 -0
  37. package/dist/runtime/hooks/stop_stream.js +0 -0
  38. package/dist/runtime/hooks/subagent_guard.js +0 -0
  39. package/dist/runtime/hooks/transcript.js +0 -0
  40. package/dist/runtime/hooks/transcript_tasks.js +0 -0
  41. package/dist/runtime/ralph/orchestrator.d.ts.map +1 -1
  42. package/dist/runtime/ralph/orchestrator.js +2 -1
  43. package/dist/runtime/ralph/orchestrator.js.map +1 -1
  44. package/dist/setup/cli/limits_state.d.ts.map +1 -1
  45. package/dist/setup/cli/limits_state.js +6 -40
  46. package/dist/setup/cli/limits_state.js.map +1 -1
  47. package/dist/setup/cli/pack_walk.d.ts +32 -0
  48. package/dist/setup/cli/pack_walk.d.ts.map +1 -0
  49. package/dist/setup/cli/pack_walk.js +76 -0
  50. package/dist/setup/cli/pack_walk.js.map +1 -0
  51. package/dist/setup/cli/permissions_state.d.ts.map +1 -1
  52. package/dist/setup/cli/permissions_state.js +6 -37
  53. package/dist/setup/cli/permissions_state.js.map +1 -1
  54. package/dist/setup/cli/triggers_state.d.ts.map +1 -1
  55. package/dist/setup/cli/triggers_state.js +3 -29
  56. package/dist/setup/cli/triggers_state.js.map +1 -1
  57. package/dist/workgraph/events.d.ts.map +1 -1
  58. package/dist/workgraph/events.js +10 -0
  59. package/dist/workgraph/events.js.map +1 -1
  60. package/dist/workgraph/store.d.ts.map +1 -1
  61. package/dist/workgraph/store.js +5 -0
  62. package/dist/workgraph/store.js.map +1 -1
  63. package/dist/workgraph/types.d.ts +2 -1
  64. package/dist/workgraph/types.d.ts.map +1 -1
  65. package/docs/ARCHITECTURE.md +268 -0
  66. package/docs/pack-runtime.md +15 -12
  67. package/docs/skill-grammar-guide.md +4 -4
  68. package/package.json +5 -3
  69. package/packs/builtin/coding-flow/skills/entry-and-handoffs/skill.yaml +13 -17
  70. package/dist/anti-drift/evaluator.d.ts +0 -88
  71. package/dist/anti-drift/evaluator.d.ts.map +0 -1
  72. package/dist/anti-drift/evaluator.js +0 -417
  73. package/dist/anti-drift/evaluator.js.map +0 -1
  74. package/dist/anti-drift/evaluator.test.js +0 -78
  75. package/dist/anti-drift/rules.d.ts +0 -80
  76. package/dist/anti-drift/rules.d.ts.map +0 -1
  77. package/dist/anti-drift/rules.js +0 -368
  78. package/dist/anti-drift/rules.js.map +0 -1
  79. package/dist/anti-drift/rules.test.js +0 -213
  80. package/dist/anti-drift/state.d.ts +0 -107
  81. package/dist/anti-drift/state.d.ts.map +0 -1
  82. package/dist/anti-drift/state.js +0 -177
  83. package/dist/anti-drift/state.js.map +0 -1
  84. package/dist/anti-drift/state.test.js +0 -120
  85. package/dist/chat/adapters/discord.d.ts +0 -41
  86. package/dist/chat/adapters/discord.d.ts.map +0 -1
  87. package/dist/chat/adapters/discord.js +0 -176
  88. package/dist/chat/adapters/discord.js.map +0 -1
  89. package/dist/chat/adapters/discord.test.js +0 -25
  90. package/dist/chat/adapters/slack.d.ts +0 -43
  91. package/dist/chat/adapters/slack.d.ts.map +0 -1
  92. package/dist/chat/adapters/slack.js +0 -172
  93. package/dist/chat/adapters/slack.js.map +0 -1
  94. package/dist/chat/adapters/slack.test.js +0 -30
  95. package/dist/chat/adapters/telegram.d.ts +0 -148
  96. package/dist/chat/adapters/telegram.d.ts.map +0 -1
  97. package/dist/chat/adapters/telegram.js +0 -498
  98. package/dist/chat/adapters/telegram.js.map +0 -1
  99. package/dist/chat/adapters/telegram.test.js +0 -94
  100. package/dist/chat/config.d.ts +0 -98
  101. package/dist/chat/config.d.ts.map +0 -1
  102. package/dist/chat/config.js +0 -185
  103. package/dist/chat/config.js.map +0 -1
  104. package/dist/chat/daemon/active-project.d.ts +0 -17
  105. package/dist/chat/daemon/active-project.d.ts.map +0 -1
  106. package/dist/chat/daemon/active-project.js +0 -23
  107. package/dist/chat/daemon/active-project.js.map +0 -1
  108. package/dist/chat/daemon/autospawn.d.ts +0 -40
  109. package/dist/chat/daemon/autospawn.d.ts.map +0 -1
  110. package/dist/chat/daemon/autospawn.js +0 -129
  111. package/dist/chat/daemon/autospawn.js.map +0 -1
  112. package/dist/chat/daemon/autospawn.test.js +0 -112
  113. package/dist/chat/daemon/cli.d.ts +0 -18
  114. package/dist/chat/daemon/cli.d.ts.map +0 -1
  115. package/dist/chat/daemon/cli.js +0 -71
  116. package/dist/chat/daemon/cli.js.map +0 -1
  117. package/dist/chat/daemon/collisions.js +0 -384
  118. package/dist/chat/daemon/health-check.d.ts +0 -69
  119. package/dist/chat/daemon/health-check.d.ts.map +0 -1
  120. package/dist/chat/daemon/health-check.js +0 -112
  121. package/dist/chat/daemon/health-check.js.map +0 -1
  122. package/dist/chat/daemon/inbox-read.d.ts +0 -35
  123. package/dist/chat/daemon/inbox-read.d.ts.map +0 -1
  124. package/dist/chat/daemon/inbox-read.js +0 -75
  125. package/dist/chat/daemon/inbox-read.js.map +0 -1
  126. package/dist/chat/daemon/inbox-read.test.js +0 -97
  127. package/dist/chat/daemon/inbox.d.ts +0 -63
  128. package/dist/chat/daemon/inbox.d.ts.map +0 -1
  129. package/dist/chat/daemon/inbox.js +0 -56
  130. package/dist/chat/daemon/inbox.js.map +0 -1
  131. package/dist/chat/daemon/inbox.test.js +0 -110
  132. package/dist/chat/daemon/lifecycle.d.ts +0 -71
  133. package/dist/chat/daemon/lifecycle.d.ts.map +0 -1
  134. package/dist/chat/daemon/lifecycle.js +0 -221
  135. package/dist/chat/daemon/lifecycle.js.map +0 -1
  136. package/dist/chat/daemon/lifecycle.test.js +0 -163
  137. package/dist/chat/daemon/protocol.d.ts +0 -107
  138. package/dist/chat/daemon/protocol.d.ts.map +0 -1
  139. package/dist/chat/daemon/protocol.js +0 -54
  140. package/dist/chat/daemon/protocol.js.map +0 -1
  141. package/dist/chat/daemon/routing.d.ts +0 -140
  142. package/dist/chat/daemon/routing.d.ts.map +0 -1
  143. package/dist/chat/daemon/routing.js +0 -198
  144. package/dist/chat/daemon/routing.js.map +0 -1
  145. package/dist/chat/daemon/routing.test.js +0 -259
  146. package/dist/chat/daemon/rpc-client.d.ts +0 -45
  147. package/dist/chat/daemon/rpc-client.d.ts.map +0 -1
  148. package/dist/chat/daemon/rpc-client.js +0 -133
  149. package/dist/chat/daemon/rpc-client.js.map +0 -1
  150. package/dist/chat/daemon/rpc-server.d.ts +0 -39
  151. package/dist/chat/daemon/rpc-server.d.ts.map +0 -1
  152. package/dist/chat/daemon/rpc-server.js +0 -385
  153. package/dist/chat/daemon/rpc-server.js.map +0 -1
  154. package/dist/chat/daemon/rpc.test.js +0 -177
  155. package/dist/chat/daemon/subscribers.js +0 -257
  156. package/dist/chat/daemon/worker.d.ts +0 -27
  157. package/dist/chat/daemon/worker.d.ts.map +0 -1
  158. package/dist/chat/daemon/worker.js +0 -313
  159. package/dist/chat/daemon/worker.js.map +0 -1
  160. package/dist/chat/daemon/workspace-topic.js +0 -324
  161. package/dist/chat/env-token.d.ts +0 -60
  162. package/dist/chat/env-token.d.ts.map +0 -1
  163. package/dist/chat/env-token.js +0 -137
  164. package/dist/chat/env-token.js.map +0 -1
  165. package/dist/chat/env-token.test.js +0 -160
  166. package/dist/chat/factory.d.ts +0 -30
  167. package/dist/chat/factory.d.ts.map +0 -1
  168. package/dist/chat/factory.js +0 -50
  169. package/dist/chat/factory.js.map +0 -1
  170. package/dist/chat/factory.test.js +0 -55
  171. package/dist/chat/gateway.d.ts +0 -176
  172. package/dist/chat/gateway.d.ts.map +0 -1
  173. package/dist/chat/gateway.js +0 -146
  174. package/dist/chat/gateway.js.map +0 -1
  175. package/dist/chat/gateway.test.js +0 -192
  176. package/dist/claude-md.d.ts +0 -39
  177. package/dist/claude-md.d.ts.map +0 -1
  178. package/dist/claude-md.js +0 -113
  179. package/dist/claude-md.js.map +0 -1
  180. package/dist/claude-md.test.js +0 -91
  181. package/dist/codex/activate.d.ts +0 -66
  182. package/dist/codex/activate.d.ts.map +0 -1
  183. package/dist/codex/activate.js +0 -329
  184. package/dist/codex/activate.js.map +0 -1
  185. package/dist/codex/activate.test.js +0 -229
  186. package/dist/codex/bundled-default/bundled-default.test.js +0 -161
  187. package/dist/codex/cli-publish.test.js +0 -133
  188. package/dist/codex/cli.d.ts +0 -35
  189. package/dist/codex/cli.d.ts.map +0 -1
  190. package/dist/codex/cli.js +0 -554
  191. package/dist/codex/cli.js.map +0 -1
  192. package/dist/codex/cli.test.js +0 -277
  193. package/dist/codex/import-skill-md.d.ts +0 -53
  194. package/dist/codex/import-skill-md.d.ts.map +0 -1
  195. package/dist/codex/import-skill-md.js +0 -236
  196. package/dist/codex/import-skill-md.js.map +0 -1
  197. package/dist/codex/import-skill-md.test.js +0 -225
  198. package/dist/codex/loader.d.ts +0 -27
  199. package/dist/codex/loader.d.ts.map +0 -1
  200. package/dist/codex/loader.js +0 -86
  201. package/dist/codex/loader.js.map +0 -1
  202. package/dist/codex/loader.test.js +0 -75
  203. package/dist/codex/parse.d.ts +0 -28
  204. package/dist/codex/parse.d.ts.map +0 -1
  205. package/dist/codex/parse.js +0 -309
  206. package/dist/codex/parse.js.map +0 -1
  207. package/dist/codex/parse.test.js +0 -241
  208. package/dist/codex/store.d.ts +0 -87
  209. package/dist/codex/store.d.ts.map +0 -1
  210. package/dist/codex/store.js +0 -205
  211. package/dist/codex/store.js.map +0 -1
  212. package/dist/codex/store.test.js +0 -242
  213. package/dist/codex/types.d.ts +0 -398
  214. package/dist/codex/types.d.ts.map +0 -1
  215. package/dist/codex/types.js +0 -21
  216. package/dist/codex/types.js.map +0 -1
  217. package/dist/config.d.ts +0 -53
  218. package/dist/config.d.ts.map +0 -1
  219. package/dist/config.js +0 -202
  220. package/dist/config.js.map +0 -1
  221. package/dist/config.test.js +0 -117
  222. package/dist/engine/cli.d.ts +0 -14
  223. package/dist/engine/cli.d.ts.map +0 -1
  224. package/dist/engine/cli.js +0 -171
  225. package/dist/engine/cli.js.map +0 -1
  226. package/dist/engine/client.d.ts +0 -219
  227. package/dist/engine/client.d.ts.map +0 -1
  228. package/dist/engine/client.js +0 -312
  229. package/dist/engine/client.js.map +0 -1
  230. package/dist/engine/config.d.ts +0 -62
  231. package/dist/engine/config.d.ts.map +0 -1
  232. package/dist/engine/config.js +0 -223
  233. package/dist/engine/config.js.map +0 -1
  234. package/dist/engine/index.d.ts +0 -17
  235. package/dist/engine/index.d.ts.map +0 -1
  236. package/dist/engine/index.js +0 -16
  237. package/dist/engine/index.js.map +0 -1
  238. package/dist/engine/resolver.d.ts +0 -62
  239. package/dist/engine/resolver.d.ts.map +0 -1
  240. package/dist/engine/resolver.js +0 -103
  241. package/dist/engine/resolver.js.map +0 -1
  242. package/dist/engine/singleton.d.ts +0 -95
  243. package/dist/engine/singleton.d.ts.map +0 -1
  244. package/dist/engine/singleton.js +0 -325
  245. package/dist/engine/singleton.js.map +0 -1
  246. package/dist/engine/types.d.ts +0 -402
  247. package/dist/engine/types.d.ts.map +0 -1
  248. package/dist/engine/types.js +0 -22
  249. package/dist/engine/types.js.map +0 -1
  250. package/dist/engine-binary-resolver.js +0 -110
  251. package/dist/engine-binary-resolver.test.js +0 -61
  252. package/dist/engine-cli.js +0 -60
  253. package/dist/engine-client.js +0 -301
  254. package/dist/engine-client.test.js +0 -118
  255. package/dist/functions/chain_state.d.ts +0 -51
  256. package/dist/functions/chain_state.d.ts.map +0 -1
  257. package/dist/functions/chain_state.js +0 -59
  258. package/dist/functions/chain_state.js.map +0 -1
  259. package/dist/hooks/drift-catalog.d.ts +0 -68
  260. package/dist/hooks/drift-catalog.d.ts.map +0 -1
  261. package/dist/hooks/drift-catalog.js +0 -184
  262. package/dist/hooks/drift-catalog.js.map +0 -1
  263. package/dist/hooks/drift-catalog.test.js +0 -154
  264. package/dist/hooks/drift-patterns.d.ts +0 -110
  265. package/dist/hooks/drift-patterns.d.ts.map +0 -1
  266. package/dist/hooks/drift-patterns.js +0 -289
  267. package/dist/hooks/drift-patterns.js.map +0 -1
  268. package/dist/hooks/drift-patterns.test.js +0 -325
  269. package/dist/hooks/engine-vocab-gate.d.ts +0 -108
  270. package/dist/hooks/engine-vocab-gate.d.ts.map +0 -1
  271. package/dist/hooks/engine-vocab-gate.js +0 -225
  272. package/dist/hooks/engine-vocab-gate.js.map +0 -1
  273. package/dist/hooks/engine-vocab-gate.test.js +0 -170
  274. package/dist/hooks/heartbeat.d.ts +0 -107
  275. package/dist/hooks/heartbeat.d.ts.map +0 -1
  276. package/dist/hooks/heartbeat.js +0 -316
  277. package/dist/hooks/heartbeat.js.map +0 -1
  278. package/dist/hooks/heartbeat.test.js +0 -393
  279. package/dist/hooks/honesty-ledger-session-scope.test.js +0 -100
  280. package/dist/hooks/honesty-ledger.d.ts +0 -123
  281. package/dist/hooks/honesty-ledger.d.ts.map +0 -1
  282. package/dist/hooks/honesty-ledger.js +0 -226
  283. package/dist/hooks/honesty-ledger.js.map +0 -1
  284. package/dist/hooks/honesty-ledger.test.js +0 -466
  285. package/dist/hooks/inline-report-check.d.ts +0 -63
  286. package/dist/hooks/inline-report-check.d.ts.map +0 -1
  287. package/dist/hooks/inline-report-check.js +0 -88
  288. package/dist/hooks/inline-report-check.js.map +0 -1
  289. package/dist/hooks/inline-report-check.test.js +0 -96
  290. package/dist/hooks/pre-tool-use.d.ts +0 -62
  291. package/dist/hooks/pre-tool-use.d.ts.map +0 -1
  292. package/dist/hooks/pre-tool-use.js +0 -342
  293. package/dist/hooks/pre-tool-use.js.map +0 -1
  294. package/dist/hooks/pre-tool-use.test.js +0 -134
  295. package/dist/hooks/session-end.d.ts +0 -15
  296. package/dist/hooks/session-end.d.ts.map +0 -1
  297. package/dist/hooks/session-end.js +0 -60
  298. package/dist/hooks/session-end.js.map +0 -1
  299. package/dist/hooks/session-end.test.js +0 -52
  300. package/dist/hooks/stop.d.ts +0 -35
  301. package/dist/hooks/stop.d.ts.map +0 -1
  302. package/dist/hooks/stop.js +0 -136
  303. package/dist/hooks/stop.js.map +0 -1
  304. package/dist/hooks/transcript-active-task.test.js +0 -342
  305. package/dist/hooks/transcript.d.ts +0 -26
  306. package/dist/hooks/transcript.d.ts.map +0 -1
  307. package/dist/hooks/transcript.js +0 -266
  308. package/dist/hooks/transcript.js.map +0 -1
  309. package/dist/hooks/transcript.test.js +0 -103
  310. package/dist/hooks/user-prompt-submit.d.ts +0 -74
  311. package/dist/hooks/user-prompt-submit.d.ts.map +0 -1
  312. package/dist/hooks/user-prompt-submit.js +0 -256
  313. package/dist/hooks/user-prompt-submit.js.map +0 -1
  314. package/dist/hooks/user-prompt-submit.test.js +0 -118
  315. package/dist/hooks/versioning-gate.d.ts +0 -101
  316. package/dist/hooks/versioning-gate.d.ts.map +0 -1
  317. package/dist/hooks/versioning-gate.js +0 -245
  318. package/dist/hooks/versioning-gate.js.map +0 -1
  319. package/dist/hooks/versioning-gate.test.js +0 -368
  320. package/dist/hooks/workflow-gate.d.ts +0 -64
  321. package/dist/hooks/workflow-gate.d.ts.map +0 -1
  322. package/dist/hooks/workflow-gate.js +0 -152
  323. package/dist/hooks/workflow-gate.js.map +0 -1
  324. package/dist/hooks/workflow-gate.test.js +0 -197
  325. package/dist/hooks-cli.d.ts +0 -25
  326. package/dist/hooks-cli.d.ts.map +0 -1
  327. package/dist/hooks-cli.js +0 -286
  328. package/dist/hooks-cli.js.map +0 -1
  329. package/dist/hooks-cli.test.js +0 -148
  330. package/dist/origin.d.ts +0 -16
  331. package/dist/origin.d.ts.map +0 -1
  332. package/dist/origin.js +0 -92
  333. package/dist/origin.js.map +0 -1
  334. package/dist/packs/seed_lessons_ingest.d.ts +0 -30
  335. package/dist/packs/seed_lessons_ingest.d.ts.map +0 -1
  336. package/dist/packs/seed_lessons_ingest.js +0 -107
  337. package/dist/packs/seed_lessons_ingest.js.map +0 -1
  338. package/dist/project-cli.d.ts +0 -7
  339. package/dist/project-cli.d.ts.map +0 -1
  340. package/dist/project-cli.js +0 -145
  341. package/dist/project-cli.js.map +0 -1
  342. package/dist/project.d.ts +0 -127
  343. package/dist/project.d.ts.map +0 -1
  344. package/dist/project.js +0 -281
  345. package/dist/project.js.map +0 -1
  346. package/dist/project.test.js +0 -287
  347. package/dist/rag/backends/loop_engine.d.ts +0 -61
  348. package/dist/rag/backends/loop_engine.d.ts.map +0 -1
  349. package/dist/rag/backends/loop_engine.js +0 -160
  350. package/dist/rag/backends/loop_engine.js.map +0 -1
  351. package/dist/recall.d.ts +0 -82
  352. package/dist/recall.d.ts.map +0 -1
  353. package/dist/recall.js +0 -81
  354. package/dist/recall.js.map +0 -1
  355. package/dist/runtime/agent_bridge/autospawn.d.ts +0 -131
  356. package/dist/runtime/agent_bridge/autospawn.d.ts.map +0 -1
  357. package/dist/runtime/agent_bridge/autospawn.js +0 -251
  358. package/dist/runtime/agent_bridge/autospawn.js.map +0 -1
  359. package/dist/runtime/chain_state.d.ts +0 -124
  360. package/dist/runtime/chain_state.d.ts.map +0 -1
  361. package/dist/runtime/chain_state.js +0 -189
  362. package/dist/runtime/chain_state.js.map +0 -1
  363. package/dist/runtime/hooks/permission_decision.d.ts +0 -34
  364. package/dist/runtime/hooks/permission_decision.d.ts.map +0 -1
  365. package/dist/runtime/hooks/permission_decision.js +0 -39
  366. package/dist/runtime/hooks/permission_decision.js.map +0 -1
  367. package/dist/runtime/workflow_fsm.d.ts +0 -21
  368. package/dist/runtime/workflow_fsm.d.ts.map +0 -1
  369. package/dist/runtime/workflow_fsm.js +0 -25
  370. package/dist/runtime/workflow_fsm.js.map +0 -1
  371. package/dist/runtime/workflow_map.d.ts +0 -26
  372. package/dist/runtime/workflow_map.d.ts.map +0 -1
  373. package/dist/runtime/workflow_map.js +0 -38
  374. package/dist/runtime/workflow_map.js.map +0 -1
  375. package/dist/scope.d.ts +0 -48
  376. package/dist/scope.d.ts.map +0 -1
  377. package/dist/scope.js +0 -111
  378. package/dist/scope.js.map +0 -1
  379. package/dist/setup/cli/topic_create_step.d.ts +0 -84
  380. package/dist/setup/cli/topic_create_step.d.ts.map +0 -1
  381. package/dist/setup/cli/topic_create_step.js +0 -213
  382. package/dist/setup/cli/topic_create_step.js.map +0 -1
  383. package/dist/system-export.d.ts +0 -65
  384. package/dist/system-export.d.ts.map +0 -1
  385. package/dist/system-export.js +0 -194
  386. package/dist/system-export.js.map +0 -1
  387. package/dist/utterance/classifier.d.ts +0 -53
  388. package/dist/utterance/classifier.d.ts.map +0 -1
  389. package/dist/utterance/classifier.js +0 -184
  390. package/dist/utterance/classifier.js.map +0 -1
  391. package/dist/utterance/classifier.test.js +0 -147
@@ -1,108 +0,0 @@
1
- /**
2
- * Engine vocabulary gate — pre-commit check enforcing substrate purity
3
- * in engine repos (0.7.21 / drift D6).
4
- *
5
- * Wired into the PreToolUse hook for `git commit` commands when the
6
- * cwd is detected as an engine repo. Catches commit messages AND
7
- * staged content (CHANGELOG.md, code comments, etc.) that reference
8
- * consumer-product names like `opensquid` or `claude code` — engine
9
- * is general substrate and must not name specific consumers per
10
- * `[[feedback_engine_vocabulary_discipline]]`.
11
- *
12
- * Why this gate exists: the existing `substrate-purity` pattern in
13
- * drift-patterns.ts only matched commit messages where the bash
14
- * command itself contained the path `loop/engine`. Real engine work
15
- * happens in cwd /Users/slee/projects/loop/engine/ with the command
16
- * just `git commit -m "..."` — the path isn't in the command. This
17
- * gate uses cwd directly + scans both the -m message AND the staged
18
- * diff content.
19
- *
20
- * Detection:
21
- * 1. Skip silently if cwd doesn't look like an engine repo.
22
- * 2. Parse the -m message text from the bash command; check for
23
- * consumer names.
24
- * 3. Run `git diff --cached` and scan added lines for consumer
25
- * names, excluding `src/host/claude_code/**` paths and lines
26
- * that look like MIT attribution comments.
27
- * 4. Block with an actionable message if any leak found.
28
- *
29
- * Fail-open invariant: any error parsing the command, running git, or
30
- * scanning the diff → allow with stderr warning. Mirrors the
31
- * workflow-gate / versioning-gate precedent.
32
- *
33
- * Override: `OPENSQUID_SKIP_ENGINE_VOCAB_GATE=1` bypasses with loud
34
- * stderr warning. For genuine emergencies where naming the consumer
35
- * is unavoidable (e.g. a migration-note commit explicitly tracking
36
- * cross-product impact).
37
- */
38
- export interface EngineVocabGateInput {
39
- /** Working directory — used to detect if this is an engine repo and
40
- * as the cwd for the git diff subprocess. */
41
- cwd?: string;
42
- /** The full bash command text — scanned for `-m "..."` message content. */
43
- bashCommand?: string;
44
- }
45
- export interface EngineVocabGateResult {
46
- block: boolean;
47
- stderr: string;
48
- }
49
- /**
50
- * Evaluate the gate against a planned `git commit` invocation.
51
- *
52
- * Exported for direct unit testing.
53
- */
54
- export declare function evaluateEngineVocabGate(input: EngineVocabGateInput): Promise<EngineVocabGateResult>;
55
- /**
56
- * Heuristic: is this cwd an engine repo?
57
- *
58
- * Catches:
59
- * - /any/path/engine (engine repo as a directory inside a monorepo)
60
- * - /any/path/loop-engine (standalone engine repo)
61
- * - /any/path/<anything>-engine
62
- *
63
- * False-positives risk: a `/Users/foo/projects/build-engine/` Vue.js
64
- * project would match. Acceptable — this gate runs only on `git commit`
65
- * in that dir, and the regex would not match any of its content. Net
66
- * cost: one git-diff subprocess call. Cheap.
67
- *
68
- * Exported for direct unit testing.
69
- */
70
- export declare function isEngineRepoCwd(cwd: string): boolean;
71
- /**
72
- * Parse a `git commit -m "..."` (or `-m '...'`) message from a bash
73
- * command and check for consumer names. Returns the first matched
74
- * consumer-name substring, or null if clean.
75
- *
76
- * Handles common shells: -m followed by a quoted string, OR -m
77
- * followed by a HEREDOC (`-m "$(cat <<'EOF' ... EOF)"`). For HEREDOC
78
- * the regex below catches the body since it's embedded in the bash
79
- * command string.
80
- *
81
- * Exported for direct unit testing.
82
- */
83
- export declare function scanCommitMessage(bashCommand: string): string | null;
84
- interface DiffHit {
85
- file: string;
86
- match: string;
87
- }
88
- /**
89
- * Run `git diff --cached` and scan added lines for consumer names.
90
- * Excludes structurally-allowed paths and MIT attribution comments.
91
- *
92
- * Returns the list of hits (empty if clean).
93
- *
94
- * Exported for direct unit testing.
95
- */
96
- export declare function scanStagedDiff(cwd: string): Promise<DiffHit[]>;
97
- /**
98
- * Parse a unified diff text and return consumer-name hits on added
99
- * lines, with path-prefix and attribution-comment exclusions applied.
100
- *
101
- * Exported for direct unit testing (avoids needing a git subprocess
102
- * in unit tests).
103
- */
104
- export declare function parseDiffForConsumerNames(diff: string): DiffHit[];
105
- /** Exported for the test suite. */
106
- export declare function checkOverrideEnv(): boolean;
107
- export {};
108
- //# sourceMappingURL=engine-vocab-gate.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"engine-vocab-gate.d.ts","sourceRoot":"","sources":["../../src.legacy/hooks/engine-vocab-gate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AA4BH,MAAM,WAAW,oBAAoB;IACnC;iDAC6C;IAC7C,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,2EAA2E;IAC3E,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;GAIG;AACH,wBAAsB,uBAAuB,CAC3C,KAAK,EAAE,oBAAoB,GAC1B,OAAO,CAAC,qBAAqB,CAAC,CA6ChC;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAKpD;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAWpE;AAED,UAAU,OAAO;IACf,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;GAOG;AACH,wBAAsB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAMpE;AAED;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,EAAE,CA8BjE;AAoBD,mCAAmC;AACnC,wBAAgB,gBAAgB,IAAI,OAAO,CAE1C"}
@@ -1,225 +0,0 @@
1
- /**
2
- * Engine vocabulary gate — pre-commit check enforcing substrate purity
3
- * in engine repos (0.7.21 / drift D6).
4
- *
5
- * Wired into the PreToolUse hook for `git commit` commands when the
6
- * cwd is detected as an engine repo. Catches commit messages AND
7
- * staged content (CHANGELOG.md, code comments, etc.) that reference
8
- * consumer-product names like `opensquid` or `claude code` — engine
9
- * is general substrate and must not name specific consumers per
10
- * `[[feedback_engine_vocabulary_discipline]]`.
11
- *
12
- * Why this gate exists: the existing `substrate-purity` pattern in
13
- * drift-patterns.ts only matched commit messages where the bash
14
- * command itself contained the path `loop/engine`. Real engine work
15
- * happens in cwd /Users/slee/projects/loop/engine/ with the command
16
- * just `git commit -m "..."` — the path isn't in the command. This
17
- * gate uses cwd directly + scans both the -m message AND the staged
18
- * diff content.
19
- *
20
- * Detection:
21
- * 1. Skip silently if cwd doesn't look like an engine repo.
22
- * 2. Parse the -m message text from the bash command; check for
23
- * consumer names.
24
- * 3. Run `git diff --cached` and scan added lines for consumer
25
- * names, excluding `src/host/claude_code/**` paths and lines
26
- * that look like MIT attribution comments.
27
- * 4. Block with an actionable message if any leak found.
28
- *
29
- * Fail-open invariant: any error parsing the command, running git, or
30
- * scanning the diff → allow with stderr warning. Mirrors the
31
- * workflow-gate / versioning-gate precedent.
32
- *
33
- * Override: `OPENSQUID_SKIP_ENGINE_VOCAB_GATE=1` bypasses with loud
34
- * stderr warning. For genuine emergencies where naming the consumer
35
- * is unavoidable (e.g. a migration-note commit explicitly tracking
36
- * cross-product impact).
37
- */
38
- import { exec as execCb } from "node:child_process";
39
- import { promisify } from "node:util";
40
- const exec = promisify(execCb);
41
- /**
42
- * Consumer product names that may not appear in engine artifacts.
43
- * Case-insensitive. Word-boundary-ish so substrings like
44
- * "openssquidly" don't false-fire — but tight enough to catch
45
- * "opensquid's", "claude_code", "open squid", etc.
46
- */
47
- const CONSUMER_NAME_REGEX = /\b(opensquid|claude[._\- ]code|open[._\- ]squid)\b/i;
48
- /**
49
- * File path prefix that's allowed to name consumer products structurally
50
- * (engine's per-host adapter directories). Adding more here as new host
51
- * adapters land is fine.
52
- */
53
- const STRUCTURALLY_ALLOWED_PATH_PREFIXES = ["src/host/claude_code/"];
54
- /**
55
- * Lines starting with comment syntax that mention MIT attribution are
56
- * allowed — they're licence headers for cherry-picked code.
57
- */
58
- const MIT_ATTRIBUTION_REGEX = /(\/\/|#|\*).*\b(MIT|Copyright|License)\b/i;
59
- /**
60
- * Evaluate the gate against a planned `git commit` invocation.
61
- *
62
- * Exported for direct unit testing.
63
- */
64
- export async function evaluateEngineVocabGate(input) {
65
- if (checkOverrideEnv()) {
66
- return {
67
- block: false,
68
- stderr: "🦑 [opensquid engine-vocab-gate] BYPASSED via OPENSQUID_SKIP_ENGINE_VOCAB_GATE=1\n",
69
- };
70
- }
71
- const cwd = input.cwd;
72
- if (!cwd || !isEngineRepoCwd(cwd)) {
73
- // Not an engine repo — gate doesn't apply. Silent allow.
74
- return { block: false, stderr: "" };
75
- }
76
- const violations = [];
77
- // Scan 1: the -m message text from the bash command.
78
- if (input.bashCommand) {
79
- const messageHit = scanCommitMessage(input.bashCommand);
80
- if (messageHit) {
81
- violations.push(` - commit message references "${messageHit}"`);
82
- }
83
- }
84
- // Scan 2: staged file content (CHANGELOG.md edits, code comments, etc.).
85
- try {
86
- const stagedHits = await scanStagedDiff(cwd);
87
- for (const hit of stagedHits) {
88
- violations.push(` - ${hit.file}: "${hit.match}" on added line`);
89
- }
90
- }
91
- catch (err) {
92
- return {
93
- block: false,
94
- stderr: `[opensquid engine-vocab-gate] git diff failed (proceeding): ${err instanceof Error ? err.message : err}\n`,
95
- };
96
- }
97
- if (violations.length === 0) {
98
- return { block: false, stderr: "" };
99
- }
100
- return {
101
- block: true,
102
- stderr: buildBlockMessage(violations),
103
- };
104
- }
105
- /**
106
- * Heuristic: is this cwd an engine repo?
107
- *
108
- * Catches:
109
- * - /any/path/engine (engine repo as a directory inside a monorepo)
110
- * - /any/path/loop-engine (standalone engine repo)
111
- * - /any/path/<anything>-engine
112
- *
113
- * False-positives risk: a `/Users/foo/projects/build-engine/` Vue.js
114
- * project would match. Acceptable — this gate runs only on `git commit`
115
- * in that dir, and the regex would not match any of its content. Net
116
- * cost: one git-diff subprocess call. Cheap.
117
- *
118
- * Exported for direct unit testing.
119
- */
120
- export function isEngineRepoCwd(cwd) {
121
- // Normalize trailing slash.
122
- const normalized = cwd.replace(/\/+$/, "");
123
- // Match: ends with `/engine` OR ends with `*-engine`
124
- return /\/engine$|-engine$/.test(normalized);
125
- }
126
- /**
127
- * Parse a `git commit -m "..."` (or `-m '...'`) message from a bash
128
- * command and check for consumer names. Returns the first matched
129
- * consumer-name substring, or null if clean.
130
- *
131
- * Handles common shells: -m followed by a quoted string, OR -m
132
- * followed by a HEREDOC (`-m "$(cat <<'EOF' ... EOF)"`). For HEREDOC
133
- * the regex below catches the body since it's embedded in the bash
134
- * command string.
135
- *
136
- * Exported for direct unit testing.
137
- */
138
- export function scanCommitMessage(bashCommand) {
139
- // Look for -m followed by a quoted string. Match both `-m "..."` and
140
- // `-m '...'` forms, including HEREDOC bodies that get interpolated.
141
- // Simple approach: scan the ENTIRE command for consumer names that
142
- // appear after a `-m`. False-positives if the command has unrelated
143
- // `-m` content followed by consumer names — acceptable for D6.
144
- const dashMIndex = bashCommand.search(/\s-m\b/);
145
- if (dashMIndex === -1)
146
- return null;
147
- const afterDashM = bashCommand.slice(dashMIndex);
148
- const match = afterDashM.match(CONSUMER_NAME_REGEX);
149
- return match ? match[0] : null;
150
- }
151
- /**
152
- * Run `git diff --cached` and scan added lines for consumer names.
153
- * Excludes structurally-allowed paths and MIT attribution comments.
154
- *
155
- * Returns the list of hits (empty if clean).
156
- *
157
- * Exported for direct unit testing.
158
- */
159
- export async function scanStagedDiff(cwd) {
160
- const { stdout } = await exec("git diff --cached --unified=0 --no-color", {
161
- cwd,
162
- maxBuffer: 4 * 1024 * 1024,
163
- });
164
- return parseDiffForConsumerNames(stdout);
165
- }
166
- /**
167
- * Parse a unified diff text and return consumer-name hits on added
168
- * lines, with path-prefix and attribution-comment exclusions applied.
169
- *
170
- * Exported for direct unit testing (avoids needing a git subprocess
171
- * in unit tests).
172
- */
173
- export function parseDiffForConsumerNames(diff) {
174
- const hits = [];
175
- let currentFile = null;
176
- for (const line of diff.split("\n")) {
177
- // Track file context. Unified diff: `+++ b/path/to/file`
178
- if (line.startsWith("+++ ")) {
179
- const path = line.slice(4).replace(/^b\//, "").trim();
180
- currentFile = path === "/dev/null" ? null : path;
181
- continue;
182
- }
183
- if (line.startsWith("--- "))
184
- continue;
185
- if (line.startsWith("@@"))
186
- continue;
187
- // Only scan added lines.
188
- if (!line.startsWith("+"))
189
- continue;
190
- // Skip the `+++` header (caught above) and pure `+` lines.
191
- if (line.length === 1)
192
- continue;
193
- const content = line.slice(1);
194
- if (currentFile === null)
195
- continue;
196
- if (isStructurallyAllowedPath(currentFile))
197
- continue;
198
- if (MIT_ATTRIBUTION_REGEX.test(content))
199
- continue;
200
- const match = content.match(CONSUMER_NAME_REGEX);
201
- if (match) {
202
- hits.push({ file: currentFile, match: match[0] });
203
- }
204
- }
205
- return hits;
206
- }
207
- function isStructurallyAllowedPath(path) {
208
- return STRUCTURALLY_ALLOWED_PATH_PREFIXES.some((prefix) => path.startsWith(prefix));
209
- }
210
- function buildBlockMessage(violations) {
211
- return (`🦑 [opensquid engine-vocab-gate] engine commit blocked — consumer-product names detected\n` +
212
- `${violations.join("\n")}\n` +
213
- `\n` +
214
- `Engine is general substrate per [[feedback_engine_vocabulary_discipline]].\n` +
215
- `Re-word using engine-domain terminology (e.g. "the RPC writer" / "the consumer",\n` +
216
- `not "opensquid"; "claude_session_id" → neutral identifier). For per-host adapter\n` +
217
- `code that is structurally consumer-specific, place under src/host/claude_code/**.\n` +
218
- `\n` +
219
- `Override (genuine emergency): set OPENSQUID_SKIP_ENGINE_VOCAB_GATE=1 for this command.\n`);
220
- }
221
- /** Exported for the test suite. */
222
- export function checkOverrideEnv() {
223
- return process.env.OPENSQUID_SKIP_ENGINE_VOCAB_GATE === "1";
224
- }
225
- //# sourceMappingURL=engine-vocab-gate.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"engine-vocab-gate.js","sourceRoot":"","sources":["../../src.legacy/hooks/engine-vocab-gate.ts"],"names":[],"mappings":"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"}
@@ -1,170 +0,0 @@
1
- /**
2
- * Tests for engine-vocab-gate (0.7.21 / drift D6).
3
- *
4
- * Covers the pure-function decomposition (isEngineRepoCwd,
5
- * scanCommitMessage, parseDiffForConsumerNames) so we don't need to
6
- * set up a git fixture for every assertion. End-to-end coverage via
7
- * the existing pre-tool-use integration tests is left as a follow-up.
8
- */
9
- import { afterEach, beforeEach, describe, expect, it } from "vitest";
10
- import { checkOverrideEnv, isEngineRepoCwd, parseDiffForConsumerNames, scanCommitMessage, } from "./engine-vocab-gate.js";
11
- describe("isEngineRepoCwd", () => {
12
- it("matches monorepo engine subdir", () => {
13
- expect(isEngineRepoCwd("/Users/slee/projects/loop/engine")).toBe(true);
14
- });
15
- it("matches monorepo engine subdir with trailing slash", () => {
16
- expect(isEngineRepoCwd("/Users/slee/projects/loop/engine/")).toBe(true);
17
- });
18
- it("matches standalone loop-engine repo", () => {
19
- expect(isEngineRepoCwd("/Users/slee/projects/loop-engine")).toBe(true);
20
- });
21
- it("matches any other -engine repo", () => {
22
- expect(isEngineRepoCwd("/home/alice/work/search-engine")).toBe(true);
23
- });
24
- it("does NOT match an unrelated subdir", () => {
25
- expect(isEngineRepoCwd("/Users/slee/projects/loop/opensquid")).toBe(false);
26
- });
27
- it("does NOT match a path that just contains 'engine' in the middle", () => {
28
- expect(isEngineRepoCwd("/Users/slee/engine-tutorials/lesson1")).toBe(false);
29
- });
30
- it("does NOT match the repo parent (loop monorepo root)", () => {
31
- expect(isEngineRepoCwd("/Users/slee/projects/loop")).toBe(false);
32
- });
33
- });
34
- describe("scanCommitMessage", () => {
35
- it("flags 'opensquid' in a -m message", () => {
36
- expect(scanCommitMessage('git commit -m "ships in lockstep with opensquid 0.7.11"')).toBe("opensquid");
37
- });
38
- it("flags 'opensquid' in a HEREDOC -m body", () => {
39
- const cmd = `git commit -m "$(cat <<'EOF'
40
- fix something
41
- ships alongside opensquid 0.7.x
42
- EOF
43
- )"`;
44
- expect(scanCommitMessage(cmd)).toBe("opensquid");
45
- });
46
- it("flags 'claude code' with various separators", () => {
47
- expect(scanCommitMessage('git commit -m "tested against Claude Code session UUID"')).toBe("Claude Code");
48
- expect(scanCommitMessage('git commit -m "claude_code adapter update"')).toBe("claude_code");
49
- expect(scanCommitMessage('git commit -m "claude-code session"')).toBe("claude-code");
50
- });
51
- it("returns null on a clean engine commit message", () => {
52
- expect(scanCommitMessage('git commit -m "fix(phase_ledger): drop session_id from storage scheme"')).toBeNull();
53
- });
54
- it("returns null when there is no -m flag at all", () => {
55
- expect(scanCommitMessage("git status")).toBeNull();
56
- expect(scanCommitMessage("git commit")).toBeNull();
57
- });
58
- it("does NOT false-fire on substrings like 'openssquidly'", () => {
59
- // CONSUMER_NAME_REGEX uses \b word boundaries so partial matches don't trip.
60
- expect(scanCommitMessage('git commit -m "openssquidly is not a real word"')).toBeNull();
61
- });
62
- });
63
- describe("parseDiffForConsumerNames", () => {
64
- it("flags an added line in CHANGELOG.md that mentions opensquid", () => {
65
- const diff = `diff --git a/CHANGELOG.md b/CHANGELOG.md
66
- index abc..def 100644
67
- --- a/CHANGELOG.md
68
- +++ b/CHANGELOG.md
69
- @@ -1,3 +1,4 @@
70
- +ships in lockstep with opensquid 0.7.11
71
- existing line
72
- `;
73
- const hits = parseDiffForConsumerNames(diff);
74
- expect(hits).toHaveLength(1);
75
- expect(hits[0].file).toBe("CHANGELOG.md");
76
- expect(hits[0].match).toBe("opensquid");
77
- });
78
- it("flags an added comment in src/lib.rs that mentions 'Claude Code'", () => {
79
- const diff = `diff --git a/src/lib.rs b/src/lib.rs
80
- --- a/src/lib.rs
81
- +++ b/src/lib.rs
82
- @@ -10,0 +11 @@
83
- + // Tested against Claude Code session UUID format.
84
- `;
85
- const hits = parseDiffForConsumerNames(diff);
86
- expect(hits).toHaveLength(1);
87
- expect(hits[0].file).toBe("src/lib.rs");
88
- });
89
- it("does NOT flag added lines under src/host/claude_code/", () => {
90
- const diff = `diff --git a/src/host/claude_code/adapter.rs b/src/host/claude_code/adapter.rs
91
- --- a/src/host/claude_code/adapter.rs
92
- +++ b/src/host/claude_code/adapter.rs
93
- @@ -0,0 +1 @@
94
- +// Claude Code-specific adapter logic — opensquid is the consumer.
95
- `;
96
- const hits = parseDiffForConsumerNames(diff);
97
- expect(hits).toHaveLength(0);
98
- });
99
- it("does NOT flag MIT attribution comment lines", () => {
100
- const diff = `diff --git a/src/engine/buffer.rs b/src/engine/buffer.rs
101
- --- a/src/engine/buffer.rs
102
- +++ b/src/engine/buffer.rs
103
- @@ -0,0 +1 @@
104
- +// MIT-licensed code cherry-picked from claude_code's transcript reader.
105
- `;
106
- const hits = parseDiffForConsumerNames(diff);
107
- expect(hits).toHaveLength(0);
108
- });
109
- it("does NOT flag removed lines (we only care about additions)", () => {
110
- const diff = `diff --git a/CHANGELOG.md b/CHANGELOG.md
111
- --- a/CHANGELOG.md
112
- +++ b/CHANGELOG.md
113
- @@ -1,2 +1,1 @@
114
- -old line that mentioned opensquid
115
- kept line
116
- `;
117
- const hits = parseDiffForConsumerNames(diff);
118
- expect(hits).toHaveLength(0);
119
- });
120
- it("returns empty array on a fully clean engine diff", () => {
121
- const diff = `diff --git a/src/engine/mod.rs b/src/engine/mod.rs
122
- --- a/src/engine/mod.rs
123
- +++ b/src/engine/mod.rs
124
- @@ -10,0 +11 @@
125
- + let task_id = ctx.task_id();
126
- `;
127
- expect(parseDiffForConsumerNames(diff)).toEqual([]);
128
- });
129
- it("collects multiple hits across multiple files", () => {
130
- const diff = `diff --git a/CHANGELOG.md b/CHANGELOG.md
131
- --- a/CHANGELOG.md
132
- +++ b/CHANGELOG.md
133
- @@ -1,0 +1 @@
134
- +now compatible with opensquid 0.7.x
135
- diff --git a/src/serve.rs b/src/serve.rs
136
- --- a/src/serve.rs
137
- +++ b/src/serve.rs
138
- @@ -10,0 +11 @@
139
- + // The opensquid MCP server expects this format.
140
- `;
141
- const hits = parseDiffForConsumerNames(diff);
142
- expect(hits).toHaveLength(2);
143
- expect(hits.map((h) => h.file)).toEqual(["CHANGELOG.md", "src/serve.rs"]);
144
- });
145
- });
146
- describe("checkOverrideEnv", () => {
147
- const previousValue = process.env.OPENSQUID_SKIP_ENGINE_VOCAB_GATE;
148
- beforeEach(() => {
149
- delete process.env.OPENSQUID_SKIP_ENGINE_VOCAB_GATE;
150
- });
151
- afterEach(() => {
152
- if (previousValue === undefined) {
153
- delete process.env.OPENSQUID_SKIP_ENGINE_VOCAB_GATE;
154
- }
155
- else {
156
- process.env.OPENSQUID_SKIP_ENGINE_VOCAB_GATE = previousValue;
157
- }
158
- });
159
- it("returns true when the env var is exactly '1'", () => {
160
- process.env.OPENSQUID_SKIP_ENGINE_VOCAB_GATE = "1";
161
- expect(checkOverrideEnv()).toBe(true);
162
- });
163
- it("returns false when the env var is unset", () => {
164
- expect(checkOverrideEnv()).toBe(false);
165
- });
166
- it("returns false when the env var is some other value", () => {
167
- process.env.OPENSQUID_SKIP_ENGINE_VOCAB_GATE = "true";
168
- expect(checkOverrideEnv()).toBe(false);
169
- });
170
- });
@@ -1,107 +0,0 @@
1
- /**
2
- * Token-threshold heartbeat — opensquid's in-ecosystem replacement for
3
- * the auto-classifier subprocess.
4
- *
5
- * The agent (Claude Code itself) is the LLM in the loop and is already
6
- * authenticated. There is no reason to spawn a second LLM subprocess
7
- * to classify what the user said — the agent can do that work inline
8
- * per the CLAUDE.md classify-and-act block.
9
- *
10
- * What the agent IS bad at: noticing when its in-context understanding
11
- * has drifted enough that it should re-anchor via `recall`. That's a
12
- * timing problem opensquid can solve cleanly: count tokens in the
13
- * transcript, compare to a checkpoint, and if the delta crosses a
14
- * threshold, drop a one-line nudge into the next turn's UserPromptSubmit
15
- * stdout so the agent sees it at the top of its system context.
16
- *
17
- * Flow:
18
- * Stop hook (every turn) → `checkAndMaybeArm(sessionId, transcriptPath)`
19
- * - Estimates total transcript tokens (char count / 4)
20
- * - Loads last checkpoint from `<data-root>/sessions/<sid>/heartbeat-checkpoint.json`
21
- * - If (current - last) >= threshold, writes a marker at
22
- * `<data-root>/sessions/<sid>/heartbeat-pending.txt` AND updates
23
- * the checkpoint to the current count
24
- * UserPromptSubmit hook (next turn) → `consumePendingHeartbeat(sessionId)`
25
- * - Reads marker if present, returns its contents (for stdout injection)
26
- * - Deletes the marker so the nudge fires exactly once per crossing
27
- *
28
- * Threshold: `OPENSQUID_HEARTBEAT_TOKENS` env, default 20000.
29
- * Calibrated against the existing CLAUDE.md "drifts after ~10 unrelated
30
- * turns" observation (~2000 tokens per turn typical).
31
- *
32
- * Zero subprocess. Zero external LLM. Zero new dependency. The agent
33
- * (which already exists in the loop) does the actual recall + classify
34
- * work inline after seeing the nudge.
35
- */
36
- /** Default threshold — see file docstring for rationale. */
37
- export declare const DEFAULT_HEARTBEAT_TOKENS = 20000;
38
- /**
39
- * Resolve the configured heartbeat threshold. Env var `OPENSQUID_HEARTBEAT_TOKENS`
40
- * overrides; values <= 0 or non-numeric fall back to the default. Returning a
41
- * sentinel `Infinity` would let callers disable cheaply, but we keep the
42
- * contract simple: any positive integer is honored.
43
- */
44
- export declare function heartbeatThresholdTokens(): number;
45
- /**
46
- * Rough token estimate from raw text — char-count / 4. Cheap, dependency-
47
- * free, and accurate enough for "did the conversation grow by 20K tokens
48
- * since last checkpoint" decisions. Real tokenizers (tiktoken,
49
- * @anthropic-ai/tokenizer) would be more accurate but add a runtime dep
50
- * for marginal gain on a threshold comparison.
51
- */
52
- export declare function estimateTokens(text: string): number;
53
- export declare function estimateTranscriptTokens(transcriptPath: string): Promise<number>;
54
- interface Checkpoint {
55
- last_token_count: number;
56
- last_checkpoint_at: string;
57
- }
58
- export declare function readCheckpoint(sessionId: string, options?: {
59
- dataRoot?: string;
60
- }): Promise<Checkpoint | null>;
61
- export declare function writeCheckpoint(sessionId: string, checkpoint: Checkpoint, options?: {
62
- dataRoot?: string;
63
- }): Promise<void>;
64
- /**
65
- * Build the one-line nudge that gets injected into the agent's next-
66
- * turn system context. Kept short — the agent's existing system prompt
67
- * (CLAUDE.md classify-and-act + the user-is-god promoted lesson)
68
- * already tells it what to do with classification work.
69
- */
70
- export declare function formatHeartbeatNudge(delta: number, threshold: number): string;
71
- /**
72
- * Stop-hook entrypoint: check whether the transcript has grown past
73
- * the threshold since the last checkpoint. If so, arm a pending
74
- * heartbeat marker for UserPromptSubmit to surface on the next turn,
75
- * and bump the checkpoint to the current count.
76
- *
77
- * Returns the nudge text written (or null if no arming happened) for
78
- * test introspection and Stop-hook stderr surfacing.
79
- */
80
- export declare function checkAndMaybeArm(sessionId: string, transcriptPath: string, options?: {
81
- dataRoot?: string;
82
- thresholdTokens?: number;
83
- }): Promise<string | null>;
84
- /**
85
- * UserPromptSubmit-hook entrypoint: consume any armed heartbeat marker
86
- * and return its text. Caller injects via stdout. Marker is removed so
87
- * the nudge fires exactly once per threshold crossing.
88
- */
89
- export declare function consumePendingHeartbeat(sessionId: string, options?: {
90
- dataRoot?: string;
91
- }): Promise<string | null>;
92
- /** Test/SessionEnd helper — paths the cleanup phase removes. */
93
- export declare function heartbeatSessionFiles(sessionId: string, dataRoot?: string): string[];
94
- /** Set the flag — called after the heartbeat nudge is surfaced. */
95
- export declare function markRecallRequired(sessionId: string, options?: {
96
- dataRoot?: string;
97
- }): Promise<void>;
98
- /** Check whether the flag is set for this session. */
99
- export declare function isRecallRequired(sessionId: string, options?: {
100
- dataRoot?: string;
101
- }): Promise<boolean>;
102
- /** Clear the flag — called after the agent calls recall. */
103
- export declare function clearRecallRequired(sessionId: string, options?: {
104
- dataRoot?: string;
105
- }): Promise<void>;
106
- export {};
107
- //# sourceMappingURL=heartbeat.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"heartbeat.d.ts","sourceRoot":"","sources":["../../src.legacy/hooks/heartbeat.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAOH,4DAA4D;AAC5D,eAAO,MAAM,wBAAwB,QAAS,CAAC;AAE/C;;;;;GAKG;AACH,wBAAgB,wBAAwB,IAAI,MAAM,CAMjD;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAGnD;AAyCD,wBAAsB,wBAAwB,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAmBtF;AAwCD,UAAU,UAAU;IAClB,gBAAgB,EAAE,MAAM,CAAC;IACzB,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAUD,wBAAsB,cAAc,CAClC,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAO,GAClC,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAe5B;AAED,wBAAsB,eAAe,CACnC,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,UAAU,EACtB,OAAO,GAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAO,GAClC,OAAO,CAAC,IAAI,CAAC,CAIf;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAO7E;AAED;;;;;;;;GAQG;AACH,wBAAsB,gBAAgB,CACpC,SAAS,EAAE,MAAM,EACjB,cAAc,EAAE,MAAM,EACtB,OAAO,GAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,eAAe,CAAC,EAAE,MAAM,CAAA;CAAO,GAC5D,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CA+BxB;AAED;;;;GAIG;AACH,wBAAsB,uBAAuB,CAC3C,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAO,GAClC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAcxB;AAED,gEAAgE;AAChE,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAMpF;AA2BD,mEAAmE;AACnE,wBAAsB,kBAAkB,CACtC,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAO,GAClC,OAAO,CAAC,IAAI,CAAC,CAIf;AAED,sDAAsD;AACtD,wBAAsB,gBAAgB,CACpC,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAO,GAClC,OAAO,CAAC,OAAO,CAAC,CAQlB;AAED,4DAA4D;AAC5D,wBAAsB,mBAAmB,CACvC,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAO,GAClC,OAAO,CAAC,IAAI,CAAC,CAOf"}