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,140 +0,0 @@
1
- /**
2
- * Per-project chat routing (v0.7.1 Phase C).
3
- *
4
- * Note on src.legacy/ placement (TG.1 (f) / WAB.2): the "legacy" label is a
5
- * pre-0.5.x architecture marker, NOT a "dead code" marker. The chat-daemon
6
- * compiled from `src.legacy/chat/` is the production runtime for inbound
7
- * Telegram + outbound chat_send. This file is actively maintained — see
8
- * `inbound_dm_user_ids` (v0.5.94 / WAB.2 Part A) below.
9
- *
10
- * Schema on disk: `~/.opensquid/projects/<uuid>/chat-routing.json`
11
- *
12
- * ```jsonc
13
- * {
14
- * "telegram": {
15
- * "report_channel": "telegram:-1001234567890", // outbound default
16
- * "report_topic_id": 15, // forum-topic id for outbound
17
- * "inbound_chat_ids": ["-1001234567890"], // accepts inbound from these chats
18
- * "inbound_topic_ids": [15], // strict whitelist when set
19
- * "inbound_dm_user_ids": ["8075471258"] // v0.5.94 — DM allowlist
20
- * },
21
- * "discord": {
22
- * "report_channel": "discord:1234567890",
23
- * "inbound_channel_ids": ["1234567890"]
24
- * },
25
- * "slack": {
26
- * "report_channel": "slack:C012345",
27
- * "inbound_channel_ids": ["C012345"]
28
- * }
29
- * }
30
- * ```
31
- *
32
- * Routing rules:
33
- * - **Outbound** (agent → chat): the MCP tool picks `report_channel`
34
- * from the active project's routing config. (Phase E wires the MCP
35
- * tools; this module just exposes the lookup.)
36
- * - **Inbound** (chat → agent): the daemon's gateway.onMessage handler
37
- * constructs a routing key (DM key, topic key, or chat-only key per
38
- * TG.1 policy decision (a)+(d)) and looks it up in the index this
39
- * module builds. Match → JSONL append to that project's inbox.
40
- * No match → JSONL append to the orphan inbox.
41
- *
42
- * UUID is the stable primary key because the project's human-friendly
43
- * `id` can be renamed via `opensquid project init` without rewriting
44
- * routing files.
45
- */
46
- export interface TelegramRouting {
47
- report_channel?: string;
48
- /**
49
- * v0.7.2 — forum-topic id within the supergroup (`report_channel`)
50
- * that outbound reports for this project should post to. When set,
51
- * outbound `chat_send` via `project:telegram` includes the
52
- * `message_thread_id` so the message lands in the right topic.
53
- */
54
- report_topic_id?: number;
55
- inbound_chat_ids?: string[];
56
- /**
57
- * v0.7.2 — when set, ONLY inbound messages with one of these
58
- * `message_thread_id` values route to this project. Empty/unset means
59
- * accept any topic (legacy v0.7.1 behavior — accepts all messages
60
- * from the listed `inbound_chat_ids`).
61
- */
62
- inbound_topic_ids?: number[];
63
- /**
64
- * v0.5.94 (WAB.2 Part A / TG.1 decision (a)) — allowlist of user IDs
65
- * whose Telegram DMs route to this project. A "DM" is detected when the
66
- * inbound `chat.id === from.id` (Telegram's canonical private-chat
67
- * shape). On match, the routing key is `telegram:dm:<user_id>`. Group
68
- * messages from the same user use `inbound_chat_ids` + topic semantics
69
- * — this field does NOT shadow group routing.
70
- *
71
- * Schema is additive: existing chat-routing.json files without this
72
- * field continue to load and route correctly (DM routing simply
73
- * disabled for that project).
74
- */
75
- inbound_dm_user_ids?: string[];
76
- }
77
- export interface DiscordRouting {
78
- report_channel?: string;
79
- inbound_channel_ids?: string[];
80
- }
81
- export interface SlackRouting {
82
- report_channel?: string;
83
- inbound_channel_ids?: string[];
84
- }
85
- export interface ProjectChatRouting {
86
- telegram?: TelegramRouting;
87
- discord?: DiscordRouting;
88
- slack?: SlackRouting;
89
- }
90
- /**
91
- * In-memory index built from all per-project routing files. Used by
92
- * the daemon's inbound handler to decide which project's inbox an
93
- * incoming message belongs to.
94
- *
95
- * Key shape: `<platform>:<native_chat_id>` — same shape as ChannelId
96
- * so the daemon can index directly off the parsed channel field of
97
- * an inbound ChatMessage.
98
- */
99
- export type RoutingIndex = Map<string, string>;
100
- export declare function projectsRootPath(dataRoot?: string): string;
101
- export declare function projectChatRoutingPath(projectUuid: string, dataRoot?: string): string;
102
- export declare function projectInboxDir(projectUuid: string, dataRoot?: string): string;
103
- export declare function orphanInboxDir(dataRoot?: string): string;
104
- /**
105
- * Read a single project's routing config. Returns null if the file
106
- * doesn't exist or fails to parse — both are non-fatal (the project
107
- * just doesn't have routing configured, so inbound for it goes to
108
- * the orphan inbox).
109
- */
110
- export declare function loadProjectChatRouting(projectUuid: string, dataRoot?: string): Promise<ProjectChatRouting | null>;
111
- /**
112
- * Scan `~/.opensquid/projects/*` and load every routing file that
113
- * exists. Returns a Map keyed by project_uuid → routing config. Used
114
- * by `buildRoutingIndex` to construct the lookup map.
115
- */
116
- export declare function loadAllProjectChatRouting(dataRoot?: string): Promise<Map<string, ProjectChatRouting>>;
117
- /**
118
- * Build the inbound chat_id → project_uuid lookup map from a collection
119
- * of per-project routing configs. Used at daemon startup AND whenever
120
- * the file watcher fires on a routing change.
121
- *
122
- * Collision handling: if two projects claim the same inbound chat_id,
123
- * the LATER one wins (Map.set overwrite). Surface a warning via the
124
- * optional `onWarn` callback so the operator can fix it.
125
- */
126
- export declare function buildRoutingIndex(configs: Map<string, ProjectChatRouting>, onWarn?: (message: string) => void): RoutingIndex;
127
- /**
128
- * Yield each inbound channel id (in `<platform>:<native_id>` shape) a
129
- * routing config declares.
130
- */
131
- export declare function collectInboundChannels(cfg: ProjectChatRouting): string[];
132
- /**
133
- * Persist a project's routing config. Creates the project directory if
134
- * missing. Atomic-ish via write-then-rename so partial writes never
135
- * leave a corrupt file.
136
- */
137
- export declare function saveProjectChatRouting(projectUuid: string, routing: ProjectChatRouting, dataRoot?: string): Promise<{
138
- path: string;
139
- }>;
140
- //# sourceMappingURL=routing.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"routing.d.ts","sourceRoot":"","sources":["../../../src.legacy/chat/daemon/routing.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AAWH,MAAM,WAAW,eAAe;IAC9B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;OAKG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B;;;;;;;;;;;OAWG;IACH,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;CAChC;AAED,MAAM,WAAW,cAAc;IAC7B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;CAChC;AAED,MAAM,WAAW,YAAY;IAC3B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;CAChC;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,KAAK,CAAC,EAAE,YAAY,CAAC;CACtB;AAED;;;;;;;;GAQG;AACH,MAAM,MAAM,YAAY,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAoB,CAAC;AAMlE,wBAAgB,gBAAgB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAErF;AAED,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAE9E;AAED,wBAAgB,cAAc,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAExD;AAMD;;;;;GAKG;AACH,wBAAsB,sBAAsB,CAC1C,WAAW,EAAE,MAAM,EACnB,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAcpC;AAED;;;;GAIG;AACH,wBAAsB,yBAAyB,CAC7C,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC,CAiB1C;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,kBAAkB,CAAC,EACxC,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,GACjC,YAAY,CAcd;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,kBAAkB,GAAG,MAAM,EAAE,CAgCxE;AAMD;;;;GAIG;AACH,wBAAsB,sBAAsB,CAC1C,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,kBAAkB,EAC3B,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAO3B"}
@@ -1,198 +0,0 @@
1
- /**
2
- * Per-project chat routing (v0.7.1 Phase C).
3
- *
4
- * Note on src.legacy/ placement (TG.1 (f) / WAB.2): the "legacy" label is a
5
- * pre-0.5.x architecture marker, NOT a "dead code" marker. The chat-daemon
6
- * compiled from `src.legacy/chat/` is the production runtime for inbound
7
- * Telegram + outbound chat_send. This file is actively maintained — see
8
- * `inbound_dm_user_ids` (v0.5.94 / WAB.2 Part A) below.
9
- *
10
- * Schema on disk: `~/.opensquid/projects/<uuid>/chat-routing.json`
11
- *
12
- * ```jsonc
13
- * {
14
- * "telegram": {
15
- * "report_channel": "telegram:-1001234567890", // outbound default
16
- * "report_topic_id": 15, // forum-topic id for outbound
17
- * "inbound_chat_ids": ["-1001234567890"], // accepts inbound from these chats
18
- * "inbound_topic_ids": [15], // strict whitelist when set
19
- * "inbound_dm_user_ids": ["8075471258"] // v0.5.94 — DM allowlist
20
- * },
21
- * "discord": {
22
- * "report_channel": "discord:1234567890",
23
- * "inbound_channel_ids": ["1234567890"]
24
- * },
25
- * "slack": {
26
- * "report_channel": "slack:C012345",
27
- * "inbound_channel_ids": ["C012345"]
28
- * }
29
- * }
30
- * ```
31
- *
32
- * Routing rules:
33
- * - **Outbound** (agent → chat): the MCP tool picks `report_channel`
34
- * from the active project's routing config. (Phase E wires the MCP
35
- * tools; this module just exposes the lookup.)
36
- * - **Inbound** (chat → agent): the daemon's gateway.onMessage handler
37
- * constructs a routing key (DM key, topic key, or chat-only key per
38
- * TG.1 policy decision (a)+(d)) and looks it up in the index this
39
- * module builds. Match → JSONL append to that project's inbox.
40
- * No match → JSONL append to the orphan inbox.
41
- *
42
- * UUID is the stable primary key because the project's human-friendly
43
- * `id` can be renamed via `opensquid project init` without rewriting
44
- * routing files.
45
- */
46
- import { promises as fs } from "node:fs";
47
- import * as path from "node:path";
48
- import { resolveDataRoot } from "../../codex/store.js";
49
- // ---------------------------------------------------------------------
50
- // Paths
51
- // ---------------------------------------------------------------------
52
- export function projectsRootPath(dataRoot) {
53
- return path.join(resolveDataRoot(dataRoot), "projects");
54
- }
55
- export function projectChatRoutingPath(projectUuid, dataRoot) {
56
- return path.join(projectsRootPath(dataRoot), projectUuid, "chat-routing.json");
57
- }
58
- export function projectInboxDir(projectUuid, dataRoot) {
59
- return path.join(projectsRootPath(dataRoot), projectUuid, "inbox");
60
- }
61
- export function orphanInboxDir(dataRoot) {
62
- return path.join(resolveDataRoot(dataRoot), "inbox", "orphan");
63
- }
64
- // ---------------------------------------------------------------------
65
- // Load
66
- // ---------------------------------------------------------------------
67
- /**
68
- * Read a single project's routing config. Returns null if the file
69
- * doesn't exist or fails to parse — both are non-fatal (the project
70
- * just doesn't have routing configured, so inbound for it goes to
71
- * the orphan inbox).
72
- */
73
- export async function loadProjectChatRouting(projectUuid, dataRoot) {
74
- const p = projectChatRoutingPath(projectUuid, dataRoot);
75
- try {
76
- const raw = await fs.readFile(p, "utf8");
77
- return JSON.parse(raw);
78
- }
79
- catch (err) {
80
- if (err.code === "ENOENT")
81
- return null;
82
- // Malformed JSON: log on stderr (daemon log) and fall back to
83
- // no-routing. Better than crashing the daemon over a bad file.
84
- process.stderr.write(`[chat-routing] failed to parse ${p}: ${err instanceof Error ? err.message : err}\n`);
85
- return null;
86
- }
87
- }
88
- /**
89
- * Scan `~/.opensquid/projects/*` and load every routing file that
90
- * exists. Returns a Map keyed by project_uuid → routing config. Used
91
- * by `buildRoutingIndex` to construct the lookup map.
92
- */
93
- export async function loadAllProjectChatRouting(dataRoot) {
94
- const root = projectsRootPath(dataRoot);
95
- const out = new Map();
96
- let entries;
97
- try {
98
- entries = await fs.readdir(root);
99
- }
100
- catch (err) {
101
- if (err.code === "ENOENT")
102
- return out;
103
- throw err;
104
- }
105
- for (const uuid of entries) {
106
- // Skip hidden files; only consider directory-like entries.
107
- if (uuid.startsWith("."))
108
- continue;
109
- const routing = await loadProjectChatRouting(uuid, dataRoot);
110
- if (routing)
111
- out.set(uuid, routing);
112
- }
113
- return out;
114
- }
115
- /**
116
- * Build the inbound chat_id → project_uuid lookup map from a collection
117
- * of per-project routing configs. Used at daemon startup AND whenever
118
- * the file watcher fires on a routing change.
119
- *
120
- * Collision handling: if two projects claim the same inbound chat_id,
121
- * the LATER one wins (Map.set overwrite). Surface a structured warning
122
- * via the optional `onCollision` callback so the operator can fix it.
123
- */
124
- export function buildRoutingIndex(configs, onCollision) {
125
- const idx = new Map();
126
- for (const [projectUuid, cfg] of configs) {
127
- for (const channelKey of collectInboundChannels(cfg)) {
128
- const existing = idx.get(channelKey);
129
- if (existing && existing !== projectUuid && onCollision) {
130
- onCollision({
131
- channel_key: channelKey,
132
- existing_uuid: existing,
133
- newcomer_uuid: projectUuid,
134
- });
135
- }
136
- idx.set(channelKey, projectUuid);
137
- }
138
- }
139
- return idx;
140
- }
141
- /**
142
- * Yield each inbound channel id (in `<platform>:<native_id>` shape) a
143
- * routing config declares.
144
- */
145
- export function collectInboundChannels(cfg) {
146
- const out = [];
147
- if (cfg.telegram?.inbound_chat_ids) {
148
- // v0.7.2: if inbound_topic_ids is set, emit a more-specific key per
149
- // (chat_id, topic_id) tuple so the routing index can distinguish
150
- // multiple projects sharing one supergroup. Otherwise emit the
151
- // chat-only key (v0.7.1 behavior).
152
- const topicIds = cfg.telegram.inbound_topic_ids;
153
- for (const chatId of cfg.telegram.inbound_chat_ids) {
154
- if (topicIds && topicIds.length > 0) {
155
- for (const tid of topicIds)
156
- out.push(`telegram:${chatId}:${tid}`);
157
- }
158
- else {
159
- out.push(`telegram:${chatId}`);
160
- }
161
- }
162
- }
163
- // v0.5.94 (WAB.2 Part A / TG.1 (a)): emit DM allowlist keys as
164
- // `telegram:dm:<user_id>`. Worker's onMessage detects DMs (chat.id ===
165
- // from.id) and looks up against this key. Separate key namespace from
166
- // `telegram:<chat_id>` so a user whose user_id collides with a
167
- // supergroup chat_id (unlikely but possible — both are integers) does
168
- // not silently cross-route.
169
- if (cfg.telegram?.inbound_dm_user_ids) {
170
- for (const uid of cfg.telegram.inbound_dm_user_ids)
171
- out.push(`telegram:dm:${uid}`);
172
- }
173
- if (cfg.discord?.inbound_channel_ids) {
174
- for (const id of cfg.discord.inbound_channel_ids)
175
- out.push(`discord:${id}`);
176
- }
177
- if (cfg.slack?.inbound_channel_ids) {
178
- for (const id of cfg.slack.inbound_channel_ids)
179
- out.push(`slack:${id}`);
180
- }
181
- return out;
182
- }
183
- // ---------------------------------------------------------------------
184
- // Write
185
- // ---------------------------------------------------------------------
186
- /**
187
- * Persist a project's routing config. Creates the project directory if
188
- * missing. Atomic-ish via write-then-rename so partial writes never
189
- * leave a corrupt file.
190
- */
191
- export async function saveProjectChatRouting(projectUuid, routing, dataRoot) {
192
- const filePath = projectChatRoutingPath(projectUuid, dataRoot);
193
- await fs.mkdir(path.dirname(filePath), { recursive: true });
194
- const tmp = `${filePath}.tmp-${process.pid}-${Date.now()}`;
195
- await fs.writeFile(tmp, `${JSON.stringify(routing, null, 2)}\n`, "utf8");
196
- await fs.rename(tmp, filePath);
197
- return { path: filePath };
198
- }
@@ -1 +0,0 @@
1
- {"version":3,"file":"routing.js","sourceRoot":"","sources":["../../../src.legacy/chat/daemon/routing.ts"],"names":[],"mappings":"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"}
@@ -1,259 +0,0 @@
1
- /**
2
- * routing.ts unit tests (v0.7.1 Phase C).
3
- */
4
- import { promises as fs } from "node:fs";
5
- import * as os from "node:os";
6
- import * as path from "node:path";
7
- import { afterEach, beforeEach, describe, expect, it } from "vitest";
8
- import { buildRoutingIndex, collectInboundChannels, loadAllProjectChatRouting, loadProjectChatRouting, projectChatRoutingPath, projectInboxDir, projectsRootPath, saveProjectChatRouting, } from "./routing.js";
9
- let tmpRoot;
10
- let prevHome;
11
- beforeEach(async () => {
12
- tmpRoot = await fs.mkdtemp(path.join(os.tmpdir(), "opensquid-routing-test-"));
13
- prevHome = process.env.OPENSQUID_HOME;
14
- process.env.OPENSQUID_HOME = tmpRoot;
15
- });
16
- afterEach(async () => {
17
- if (prevHome === undefined)
18
- delete process.env.OPENSQUID_HOME;
19
- else
20
- process.env.OPENSQUID_HOME = prevHome;
21
- await fs.rm(tmpRoot, { recursive: true, force: true });
22
- });
23
- describe("path derivation", () => {
24
- it("projectsRootPath = <dataRoot>/projects", () => {
25
- expect(projectsRootPath(tmpRoot)).toBe(path.join(tmpRoot, "projects"));
26
- });
27
- it("projectChatRoutingPath = <dataRoot>/projects/<uuid>/chat-routing.json", () => {
28
- expect(projectChatRoutingPath("abc-uuid", tmpRoot)).toBe(path.join(tmpRoot, "projects", "abc-uuid", "chat-routing.json"));
29
- });
30
- it("projectInboxDir = <dataRoot>/projects/<uuid>/inbox", () => {
31
- expect(projectInboxDir("abc-uuid", tmpRoot)).toBe(path.join(tmpRoot, "projects", "abc-uuid", "inbox"));
32
- });
33
- });
34
- describe("loadProjectChatRouting", () => {
35
- it("returns null when the routing file is missing", async () => {
36
- const r = await loadProjectChatRouting("missing-uuid", tmpRoot);
37
- expect(r).toBeNull();
38
- });
39
- it("loads a valid routing file", async () => {
40
- const uuid = "test-uuid";
41
- await fs.mkdir(path.join(tmpRoot, "projects", uuid), { recursive: true });
42
- await fs.writeFile(path.join(tmpRoot, "projects", uuid, "chat-routing.json"), JSON.stringify({
43
- telegram: { report_channel: "telegram:-100", inbound_chat_ids: ["-100", "-200"] },
44
- }));
45
- const r = await loadProjectChatRouting(uuid, tmpRoot);
46
- expect(r).not.toBeNull();
47
- expect(r?.telegram?.report_channel).toBe("telegram:-100");
48
- expect(r?.telegram?.inbound_chat_ids).toEqual(["-100", "-200"]);
49
- });
50
- it("returns null on malformed JSON (does not throw)", async () => {
51
- const uuid = "bad-uuid";
52
- await fs.mkdir(path.join(tmpRoot, "projects", uuid), { recursive: true });
53
- await fs.writeFile(path.join(tmpRoot, "projects", uuid, "chat-routing.json"), "{ not json");
54
- const r = await loadProjectChatRouting(uuid, tmpRoot);
55
- expect(r).toBeNull();
56
- });
57
- });
58
- describe("loadAllProjectChatRouting", () => {
59
- it("returns empty map when projects root doesn't exist", async () => {
60
- const r = await loadAllProjectChatRouting(tmpRoot);
61
- expect(r.size).toBe(0);
62
- });
63
- it("collects all valid routing files, skipping hidden entries", async () => {
64
- const projectsDir = path.join(tmpRoot, "projects");
65
- await fs.mkdir(path.join(projectsDir, "uuid-a"), { recursive: true });
66
- await fs.mkdir(path.join(projectsDir, "uuid-b"), { recursive: true });
67
- await fs.mkdir(path.join(projectsDir, ".hidden"), { recursive: true });
68
- await fs.writeFile(path.join(projectsDir, "uuid-a", "chat-routing.json"), JSON.stringify({ telegram: { inbound_chat_ids: ["1"] } }));
69
- await fs.writeFile(path.join(projectsDir, "uuid-b", "chat-routing.json"), JSON.stringify({ discord: { inbound_channel_ids: ["2"] } }));
70
- await fs.writeFile(path.join(projectsDir, ".hidden", "chat-routing.json"), JSON.stringify({ slack: { inbound_channel_ids: ["3"] } }));
71
- const all = await loadAllProjectChatRouting(tmpRoot);
72
- expect(all.size).toBe(2);
73
- expect(all.has("uuid-a")).toBe(true);
74
- expect(all.has("uuid-b")).toBe(true);
75
- expect(all.has(".hidden")).toBe(false);
76
- });
77
- });
78
- describe("collectInboundChannels", () => {
79
- it("returns empty list for empty config", () => {
80
- expect(collectInboundChannels({})).toEqual([]);
81
- });
82
- it("formats telegram ids as telegram:<id>", () => {
83
- const ch = collectInboundChannels({ telegram: { inbound_chat_ids: ["100", "200"] } });
84
- expect(ch).toEqual(["telegram:100", "telegram:200"]);
85
- });
86
- it("collects across all platforms", () => {
87
- const ch = collectInboundChannels({
88
- telegram: { inbound_chat_ids: ["t1"] },
89
- discord: { inbound_channel_ids: ["d1"] },
90
- slack: { inbound_channel_ids: ["s1"] },
91
- });
92
- expect(ch).toEqual(["telegram:t1", "discord:d1", "slack:s1"]);
93
- });
94
- });
95
- // v0.5.94 (WAB.2 Part A / TG.1 (a)) — DM allowlist key emission.
96
- describe("collectInboundChannels — v0.5.94 DM allowlist", () => {
97
- it("emits DM keys as telegram:dm:<user_id> when inbound_dm_user_ids is set", () => {
98
- const ch = collectInboundChannels({
99
- telegram: { inbound_dm_user_ids: ["123"] },
100
- });
101
- expect(ch).toEqual(["telegram:dm:123"]);
102
- });
103
- it("supports multiple DM user_ids", () => {
104
- const ch = collectInboundChannels({
105
- telegram: { inbound_dm_user_ids: ["123", "456"] },
106
- });
107
- expect(ch).toEqual(["telegram:dm:123", "telegram:dm:456"]);
108
- });
109
- it("emits both group + topic + DM keys when all are configured", () => {
110
- const ch = collectInboundChannels({
111
- telegram: {
112
- inbound_chat_ids: ["-100super"],
113
- inbound_topic_ids: [15],
114
- inbound_dm_user_ids: ["8075471258"],
115
- },
116
- });
117
- expect(ch).toEqual(["telegram:-100super:15", "telegram:dm:8075471258"]);
118
- });
119
- it("schema backwards-compat: config without inbound_dm_user_ids still works", () => {
120
- const ch = collectInboundChannels({
121
- telegram: { inbound_chat_ids: ["-100"] },
122
- });
123
- expect(ch).toEqual(["telegram:-100"]);
124
- });
125
- it("empty inbound_dm_user_ids list emits no DM keys", () => {
126
- const ch = collectInboundChannels({
127
- telegram: { inbound_dm_user_ids: [] },
128
- });
129
- expect(ch).toEqual([]);
130
- });
131
- });
132
- describe("buildRoutingIndex — v0.5.94 DM key indexing", () => {
133
- it("indexes DM keys so worker can look up by telegram:dm:<user_id>", () => {
134
- const cfgs = new Map([
135
- ["uuid-dm", { telegram: { inbound_dm_user_ids: ["8075471258"] } }],
136
- ]);
137
- const idx = buildRoutingIndex(cfgs);
138
- expect(idx.get("telegram:dm:8075471258")).toBe("uuid-dm");
139
- expect(idx.size).toBe(1);
140
- });
141
- it("two projects can each have their own DM allowlist (no collision)", () => {
142
- const cfgs = new Map([
143
- ["uuid-a", { telegram: { inbound_dm_user_ids: ["111"] } }],
144
- ["uuid-b", { telegram: { inbound_dm_user_ids: ["222"] } }],
145
- ]);
146
- const idx = buildRoutingIndex(cfgs);
147
- expect(idx.get("telegram:dm:111")).toBe("uuid-a");
148
- expect(idx.get("telegram:dm:222")).toBe("uuid-b");
149
- expect(idx.size).toBe(2);
150
- });
151
- it("same DM user across two projects: collision warned, last wins (consistent with existing behavior)", () => {
152
- const cfgs = new Map([
153
- ["uuid-a", { telegram: { inbound_dm_user_ids: ["999"] } }],
154
- ["uuid-b", { telegram: { inbound_dm_user_ids: ["999"] } }],
155
- ]);
156
- const warnings = [];
157
- const idx = buildRoutingIndex(cfgs, (m) => warnings.push(m));
158
- expect(idx.get("telegram:dm:999")).toBe("uuid-b");
159
- expect(warnings.length).toBe(1);
160
- expect(warnings[0]).toMatch(/collision.*telegram:dm:999/);
161
- });
162
- it("group + DM in same project: both keys index to same uuid", () => {
163
- const cfgs = new Map([
164
- [
165
- "uuid-x",
166
- {
167
- telegram: {
168
- inbound_chat_ids: ["-100"],
169
- inbound_topic_ids: [15],
170
- inbound_dm_user_ids: ["8075471258"],
171
- },
172
- },
173
- ],
174
- ]);
175
- const idx = buildRoutingIndex(cfgs);
176
- expect(idx.get("telegram:-100:15")).toBe("uuid-x");
177
- expect(idx.get("telegram:dm:8075471258")).toBe("uuid-x");
178
- expect(idx.get("telegram:-100")).toBeUndefined(); // strict topic whitelist preserved
179
- expect(idx.size).toBe(2);
180
- });
181
- });
182
- describe("buildRoutingIndex — v0.7.2 topic-aware keys", () => {
183
- it("emits topic-specific keys when inbound_topic_ids is set", () => {
184
- const cfgs = new Map([
185
- [
186
- "uuid-a",
187
- {
188
- telegram: {
189
- inbound_chat_ids: ["-1001234567890"],
190
- inbound_topic_ids: [5, 12],
191
- },
192
- },
193
- ],
194
- ]);
195
- const idx = buildRoutingIndex(cfgs);
196
- expect(idx.get("telegram:-1001234567890:5")).toBe("uuid-a");
197
- expect(idx.get("telegram:-1001234567890:12")).toBe("uuid-a");
198
- // Chat-only key NOT registered when topic_ids are set — we want
199
- // routing to be topic-strict.
200
- expect(idx.get("telegram:-1001234567890")).toBeUndefined();
201
- });
202
- it("two projects sharing one supergroup but different topics get distinct routing", () => {
203
- const cfgs = new Map([
204
- ["uuid-a", { telegram: { inbound_chat_ids: ["-100common"], inbound_topic_ids: [5] } }],
205
- ["uuid-b", { telegram: { inbound_chat_ids: ["-100common"], inbound_topic_ids: [10] } }],
206
- ]);
207
- const idx = buildRoutingIndex(cfgs);
208
- expect(idx.get("telegram:-100common:5")).toBe("uuid-a");
209
- expect(idx.get("telegram:-100common:10")).toBe("uuid-b");
210
- expect(idx.size).toBe(2);
211
- });
212
- it("falls back to chat-only key when inbound_topic_ids is empty/unset (legacy v0.7.1)", () => {
213
- const cfgs = new Map([["uuid-legacy", { telegram: { inbound_chat_ids: ["-100legacy"] } }]]);
214
- const idx = buildRoutingIndex(cfgs);
215
- expect(idx.get("telegram:-100legacy")).toBe("uuid-legacy");
216
- expect(idx.size).toBe(1);
217
- });
218
- });
219
- describe("buildRoutingIndex", () => {
220
- it("builds a chat_id → uuid map", () => {
221
- const cfgs = new Map([
222
- ["uuid-a", { telegram: { inbound_chat_ids: ["100", "200"] } }],
223
- ["uuid-b", { discord: { inbound_channel_ids: ["d1"] } }],
224
- ]);
225
- const idx = buildRoutingIndex(cfgs);
226
- expect(idx.get("telegram:100")).toBe("uuid-a");
227
- expect(idx.get("telegram:200")).toBe("uuid-a");
228
- expect(idx.get("discord:d1")).toBe("uuid-b");
229
- expect(idx.size).toBe(3);
230
- });
231
- it("calls onWarn on collision and lets the later project win", () => {
232
- const cfgs = new Map([
233
- ["uuid-a", { telegram: { inbound_chat_ids: ["100"] } }],
234
- ["uuid-b", { telegram: { inbound_chat_ids: ["100"] } }],
235
- ]);
236
- const warnings = [];
237
- const idx = buildRoutingIndex(cfgs, (m) => warnings.push(m));
238
- // Map iteration order on insertion → uuid-b wins.
239
- expect(idx.get("telegram:100")).toBe("uuid-b");
240
- expect(warnings.length).toBe(1);
241
- expect(warnings[0]).toMatch(/collision.*telegram:100/);
242
- });
243
- });
244
- describe("saveProjectChatRouting", () => {
245
- it("writes a routing file atomically, creating the project dir if missing", async () => {
246
- const uuid = "save-test";
247
- const res = await saveProjectChatRouting(uuid, { telegram: { report_channel: "telegram:abc", inbound_chat_ids: ["abc"] } }, tmpRoot);
248
- expect(res.path).toBe(path.join(tmpRoot, "projects", uuid, "chat-routing.json"));
249
- const back = await loadProjectChatRouting(uuid, tmpRoot);
250
- expect(back?.telegram?.report_channel).toBe("telegram:abc");
251
- });
252
- it("overwrites an existing routing file (rename-over)", async () => {
253
- const uuid = "overwrite-test";
254
- await saveProjectChatRouting(uuid, { telegram: { report_channel: "telegram:v1" } }, tmpRoot);
255
- await saveProjectChatRouting(uuid, { telegram: { report_channel: "telegram:v2" } }, tmpRoot);
256
- const back = await loadProjectChatRouting(uuid, tmpRoot);
257
- expect(back?.telegram?.report_channel).toBe("telegram:v2");
258
- });
259
- });
@@ -1,45 +0,0 @@
1
- /**
2
- * chat-daemon RPC client (v0.7.1 Phase B).
3
- *
4
- * Used by the MCP server when it wants to send a chat message but
5
- * doesn't want to start its own long-poll adapter (which would
6
- * collide with any other MCP server holding the same bot token).
7
- *
8
- * Behavior:
9
- * - One short-lived connection per request — keeps the implementation
10
- * trivial and avoids reconnect/backoff logic. Performance is fine
11
- * for v0.7.1's expected traffic (a handful of agent reports per
12
- * project session).
13
- * - Returns a typed result on success.
14
- * - Throws `DaemonUnreachableError` when the socket can't be reached
15
- * so callers can fall back to in-process send.
16
- * - Throws `DaemonRpcError` on JSON-RPC error responses.
17
- */
18
- import { type CreateTopicParams, type CreateTopicResult, type ListChannelsResult, type PingResult, type SendParams, type SendResult } from "./protocol.js";
19
- export declare class DaemonUnreachableError extends Error {
20
- constructor(message: string);
21
- }
22
- export declare class DaemonRpcError extends Error {
23
- readonly code: number;
24
- constructor(message: string, code: number);
25
- }
26
- export interface RpcClientOptions {
27
- dataRoot?: string;
28
- /** Connect timeout in ms. Default 1500 — local socket, fast. */
29
- connectTimeoutMs?: number;
30
- /** Request timeout in ms (waiting for response). Default 5000. */
31
- requestTimeoutMs?: number;
32
- }
33
- export declare class DaemonClient {
34
- private readonly address;
35
- private readonly connectTimeoutMs;
36
- private readonly requestTimeoutMs;
37
- constructor(opts?: RpcClientOptions);
38
- ping(): Promise<PingResult>;
39
- listChannels(): Promise<ListChannelsResult>;
40
- send(params: SendParams): Promise<SendResult>;
41
- createTopic(params: CreateTopicParams): Promise<CreateTopicResult>;
42
- call<R>(method: string, params: unknown): Promise<R>;
43
- private openSocket;
44
- }
45
- //# sourceMappingURL=rpc-client.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"rpc-client.d.ts","sourceRoot":"","sources":["../../../src.legacy/chat/daemon/rpc-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAIH,OAAO,EACL,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EAGtB,KAAK,kBAAkB,EACvB,KAAK,UAAU,EACf,KAAK,UAAU,EACf,KAAK,UAAU,EAEhB,MAAM,eAAe,CAAC;AAEvB,qBAAa,sBAAuB,SAAQ,KAAK;gBACnC,OAAO,EAAE,MAAM;CAI5B;AAED,qBAAa,cAAe,SAAQ,KAAK;IAGrC,QAAQ,CAAC,IAAI,EAAE,MAAM;gBADrB,OAAO,EAAE,MAAM,EACN,IAAI,EAAE,MAAM;CAKxB;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gEAAgE;IAChE,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,kEAAkE;IAClE,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAID,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAC1C,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;gBAE9B,IAAI,GAAE,gBAAqB;IAMvC,IAAI,IAAI,OAAO,CAAC,UAAU,CAAC;IAI3B,YAAY,IAAI,OAAO,CAAC,kBAAkB,CAAC;IAI3C,IAAI,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;IAI7C,WAAW,CAAC,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAI5D,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC;IAiB1D,OAAO,CAAC,UAAU;CAwBnB"}