opensquid 0.5.441 → 0.5.447

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (380) hide show
  1. package/README.md +1 -0
  2. package/dist/functions/arm_scope.d.ts +27 -0
  3. package/dist/functions/arm_scope.d.ts.map +1 -0
  4. package/dist/functions/arm_scope.js +52 -0
  5. package/dist/functions/arm_scope.js.map +1 -0
  6. package/dist/functions/index.d.ts +1 -0
  7. package/dist/functions/index.d.ts.map +1 -1
  8. package/dist/functions/index.js +1 -0
  9. package/dist/functions/index.js.map +1 -1
  10. package/dist/runtime/bootstrap.d.ts.map +1 -1
  11. package/dist/runtime/bootstrap.js +2 -0
  12. package/dist/runtime/bootstrap.js.map +1 -1
  13. package/dist/runtime/handoff/render.d.ts +5 -4
  14. package/dist/runtime/handoff/render.d.ts.map +1 -1
  15. package/dist/runtime/handoff/render.js +7 -7
  16. package/dist/runtime/handoff/render.js.map +1 -1
  17. package/dist/runtime/hooks/active_task_mirror.js +0 -0
  18. package/dist/runtime/hooks/apply_patch.js +0 -0
  19. package/dist/runtime/hooks/dispatch.js +0 -0
  20. package/dist/runtime/hooks/hook_output.js +0 -0
  21. package/dist/runtime/hooks/memory_reconcile.js +0 -0
  22. package/dist/runtime/hooks/new_project_detect.js +0 -0
  23. package/dist/runtime/hooks/profession_resolver.js +0 -0
  24. package/dist/runtime/hooks/scope_intent.js +0 -0
  25. package/dist/runtime/hooks/session_id.js +0 -0
  26. package/dist/runtime/hooks/session_liveness.js +0 -0
  27. package/dist/runtime/hooks/stop_drive.js +0 -0
  28. package/dist/runtime/hooks/stop_stream.js +0 -0
  29. package/dist/runtime/hooks/subagent_guard.js +0 -0
  30. package/dist/runtime/hooks/transcript.js +0 -0
  31. package/dist/runtime/hooks/transcript_tasks.js +0 -0
  32. package/dist/runtime/ralph/orchestrator.d.ts.map +1 -1
  33. package/dist/runtime/ralph/orchestrator.js +2 -1
  34. package/dist/runtime/ralph/orchestrator.js.map +1 -1
  35. package/dist/setup/cli/limits_state.d.ts.map +1 -1
  36. package/dist/setup/cli/limits_state.js +6 -40
  37. package/dist/setup/cli/limits_state.js.map +1 -1
  38. package/dist/setup/cli/pack_walk.d.ts +32 -0
  39. package/dist/setup/cli/pack_walk.d.ts.map +1 -0
  40. package/dist/setup/cli/pack_walk.js +76 -0
  41. package/dist/setup/cli/pack_walk.js.map +1 -0
  42. package/dist/setup/cli/permissions_state.d.ts.map +1 -1
  43. package/dist/setup/cli/permissions_state.js +6 -37
  44. package/dist/setup/cli/permissions_state.js.map +1 -1
  45. package/dist/setup/cli/triggers_state.d.ts.map +1 -1
  46. package/dist/setup/cli/triggers_state.js +3 -29
  47. package/dist/setup/cli/triggers_state.js.map +1 -1
  48. package/dist/workgraph/events.d.ts.map +1 -1
  49. package/dist/workgraph/events.js +10 -0
  50. package/dist/workgraph/events.js.map +1 -1
  51. package/dist/workgraph/store.d.ts.map +1 -1
  52. package/dist/workgraph/store.js +5 -0
  53. package/dist/workgraph/store.js.map +1 -1
  54. package/dist/workgraph/types.d.ts +2 -1
  55. package/dist/workgraph/types.d.ts.map +1 -1
  56. package/docs/ARCHITECTURE.md +268 -0
  57. package/package.json +5 -3
  58. package/packs/builtin/coding-flow/skills/entry-and-handoffs/skill.yaml +13 -17
  59. package/dist/anti-drift/evaluator.d.ts +0 -88
  60. package/dist/anti-drift/evaluator.d.ts.map +0 -1
  61. package/dist/anti-drift/evaluator.js +0 -417
  62. package/dist/anti-drift/evaluator.js.map +0 -1
  63. package/dist/anti-drift/evaluator.test.js +0 -78
  64. package/dist/anti-drift/rules.d.ts +0 -80
  65. package/dist/anti-drift/rules.d.ts.map +0 -1
  66. package/dist/anti-drift/rules.js +0 -368
  67. package/dist/anti-drift/rules.js.map +0 -1
  68. package/dist/anti-drift/rules.test.js +0 -213
  69. package/dist/anti-drift/state.d.ts +0 -107
  70. package/dist/anti-drift/state.d.ts.map +0 -1
  71. package/dist/anti-drift/state.js +0 -177
  72. package/dist/anti-drift/state.js.map +0 -1
  73. package/dist/anti-drift/state.test.js +0 -120
  74. package/dist/chat/adapters/discord.d.ts +0 -41
  75. package/dist/chat/adapters/discord.d.ts.map +0 -1
  76. package/dist/chat/adapters/discord.js +0 -176
  77. package/dist/chat/adapters/discord.js.map +0 -1
  78. package/dist/chat/adapters/discord.test.js +0 -25
  79. package/dist/chat/adapters/slack.d.ts +0 -43
  80. package/dist/chat/adapters/slack.d.ts.map +0 -1
  81. package/dist/chat/adapters/slack.js +0 -172
  82. package/dist/chat/adapters/slack.js.map +0 -1
  83. package/dist/chat/adapters/slack.test.js +0 -30
  84. package/dist/chat/adapters/telegram.d.ts +0 -148
  85. package/dist/chat/adapters/telegram.d.ts.map +0 -1
  86. package/dist/chat/adapters/telegram.js +0 -498
  87. package/dist/chat/adapters/telegram.js.map +0 -1
  88. package/dist/chat/adapters/telegram.test.js +0 -94
  89. package/dist/chat/config.d.ts +0 -98
  90. package/dist/chat/config.d.ts.map +0 -1
  91. package/dist/chat/config.js +0 -185
  92. package/dist/chat/config.js.map +0 -1
  93. package/dist/chat/daemon/active-project.d.ts +0 -17
  94. package/dist/chat/daemon/active-project.d.ts.map +0 -1
  95. package/dist/chat/daemon/active-project.js +0 -23
  96. package/dist/chat/daemon/active-project.js.map +0 -1
  97. package/dist/chat/daemon/autospawn.d.ts +0 -40
  98. package/dist/chat/daemon/autospawn.d.ts.map +0 -1
  99. package/dist/chat/daemon/autospawn.js +0 -129
  100. package/dist/chat/daemon/autospawn.js.map +0 -1
  101. package/dist/chat/daemon/autospawn.test.js +0 -112
  102. package/dist/chat/daemon/cli.d.ts +0 -18
  103. package/dist/chat/daemon/cli.d.ts.map +0 -1
  104. package/dist/chat/daemon/cli.js +0 -71
  105. package/dist/chat/daemon/cli.js.map +0 -1
  106. package/dist/chat/daemon/collisions.js +0 -384
  107. package/dist/chat/daemon/health-check.d.ts +0 -69
  108. package/dist/chat/daemon/health-check.d.ts.map +0 -1
  109. package/dist/chat/daemon/health-check.js +0 -112
  110. package/dist/chat/daemon/health-check.js.map +0 -1
  111. package/dist/chat/daemon/inbox-read.d.ts +0 -35
  112. package/dist/chat/daemon/inbox-read.d.ts.map +0 -1
  113. package/dist/chat/daemon/inbox-read.js +0 -75
  114. package/dist/chat/daemon/inbox-read.js.map +0 -1
  115. package/dist/chat/daemon/inbox-read.test.js +0 -97
  116. package/dist/chat/daemon/inbox.d.ts +0 -63
  117. package/dist/chat/daemon/inbox.d.ts.map +0 -1
  118. package/dist/chat/daemon/inbox.js +0 -56
  119. package/dist/chat/daemon/inbox.js.map +0 -1
  120. package/dist/chat/daemon/inbox.test.js +0 -110
  121. package/dist/chat/daemon/lifecycle.d.ts +0 -71
  122. package/dist/chat/daemon/lifecycle.d.ts.map +0 -1
  123. package/dist/chat/daemon/lifecycle.js +0 -221
  124. package/dist/chat/daemon/lifecycle.js.map +0 -1
  125. package/dist/chat/daemon/lifecycle.test.js +0 -163
  126. package/dist/chat/daemon/protocol.d.ts +0 -107
  127. package/dist/chat/daemon/protocol.d.ts.map +0 -1
  128. package/dist/chat/daemon/protocol.js +0 -54
  129. package/dist/chat/daemon/protocol.js.map +0 -1
  130. package/dist/chat/daemon/routing.d.ts +0 -140
  131. package/dist/chat/daemon/routing.d.ts.map +0 -1
  132. package/dist/chat/daemon/routing.js +0 -198
  133. package/dist/chat/daemon/routing.js.map +0 -1
  134. package/dist/chat/daemon/routing.test.js +0 -259
  135. package/dist/chat/daemon/rpc-client.d.ts +0 -45
  136. package/dist/chat/daemon/rpc-client.d.ts.map +0 -1
  137. package/dist/chat/daemon/rpc-client.js +0 -133
  138. package/dist/chat/daemon/rpc-client.js.map +0 -1
  139. package/dist/chat/daemon/rpc-server.d.ts +0 -39
  140. package/dist/chat/daemon/rpc-server.d.ts.map +0 -1
  141. package/dist/chat/daemon/rpc-server.js +0 -385
  142. package/dist/chat/daemon/rpc-server.js.map +0 -1
  143. package/dist/chat/daemon/rpc.test.js +0 -177
  144. package/dist/chat/daemon/subscribers.js +0 -257
  145. package/dist/chat/daemon/worker.d.ts +0 -27
  146. package/dist/chat/daemon/worker.d.ts.map +0 -1
  147. package/dist/chat/daemon/worker.js +0 -313
  148. package/dist/chat/daemon/worker.js.map +0 -1
  149. package/dist/chat/daemon/workspace-topic.js +0 -324
  150. package/dist/chat/env-token.d.ts +0 -60
  151. package/dist/chat/env-token.d.ts.map +0 -1
  152. package/dist/chat/env-token.js +0 -137
  153. package/dist/chat/env-token.js.map +0 -1
  154. package/dist/chat/env-token.test.js +0 -160
  155. package/dist/chat/factory.d.ts +0 -30
  156. package/dist/chat/factory.d.ts.map +0 -1
  157. package/dist/chat/factory.js +0 -50
  158. package/dist/chat/factory.js.map +0 -1
  159. package/dist/chat/factory.test.js +0 -55
  160. package/dist/chat/gateway.d.ts +0 -176
  161. package/dist/chat/gateway.d.ts.map +0 -1
  162. package/dist/chat/gateway.js +0 -146
  163. package/dist/chat/gateway.js.map +0 -1
  164. package/dist/chat/gateway.test.js +0 -192
  165. package/dist/claude-md.d.ts +0 -39
  166. package/dist/claude-md.d.ts.map +0 -1
  167. package/dist/claude-md.js +0 -113
  168. package/dist/claude-md.js.map +0 -1
  169. package/dist/claude-md.test.js +0 -91
  170. package/dist/codex/activate.d.ts +0 -66
  171. package/dist/codex/activate.d.ts.map +0 -1
  172. package/dist/codex/activate.js +0 -329
  173. package/dist/codex/activate.js.map +0 -1
  174. package/dist/codex/activate.test.js +0 -229
  175. package/dist/codex/bundled-default/bundled-default.test.js +0 -161
  176. package/dist/codex/cli-publish.test.js +0 -133
  177. package/dist/codex/cli.d.ts +0 -35
  178. package/dist/codex/cli.d.ts.map +0 -1
  179. package/dist/codex/cli.js +0 -554
  180. package/dist/codex/cli.js.map +0 -1
  181. package/dist/codex/cli.test.js +0 -277
  182. package/dist/codex/import-skill-md.d.ts +0 -53
  183. package/dist/codex/import-skill-md.d.ts.map +0 -1
  184. package/dist/codex/import-skill-md.js +0 -236
  185. package/dist/codex/import-skill-md.js.map +0 -1
  186. package/dist/codex/import-skill-md.test.js +0 -225
  187. package/dist/codex/loader.d.ts +0 -27
  188. package/dist/codex/loader.d.ts.map +0 -1
  189. package/dist/codex/loader.js +0 -86
  190. package/dist/codex/loader.js.map +0 -1
  191. package/dist/codex/loader.test.js +0 -75
  192. package/dist/codex/parse.d.ts +0 -28
  193. package/dist/codex/parse.d.ts.map +0 -1
  194. package/dist/codex/parse.js +0 -309
  195. package/dist/codex/parse.js.map +0 -1
  196. package/dist/codex/parse.test.js +0 -241
  197. package/dist/codex/store.d.ts +0 -87
  198. package/dist/codex/store.d.ts.map +0 -1
  199. package/dist/codex/store.js +0 -205
  200. package/dist/codex/store.js.map +0 -1
  201. package/dist/codex/store.test.js +0 -242
  202. package/dist/codex/types.d.ts +0 -398
  203. package/dist/codex/types.d.ts.map +0 -1
  204. package/dist/codex/types.js +0 -21
  205. package/dist/codex/types.js.map +0 -1
  206. package/dist/config.d.ts +0 -53
  207. package/dist/config.d.ts.map +0 -1
  208. package/dist/config.js +0 -202
  209. package/dist/config.js.map +0 -1
  210. package/dist/config.test.js +0 -117
  211. package/dist/engine/cli.d.ts +0 -14
  212. package/dist/engine/cli.d.ts.map +0 -1
  213. package/dist/engine/cli.js +0 -171
  214. package/dist/engine/cli.js.map +0 -1
  215. package/dist/engine/client.d.ts +0 -219
  216. package/dist/engine/client.d.ts.map +0 -1
  217. package/dist/engine/client.js +0 -312
  218. package/dist/engine/client.js.map +0 -1
  219. package/dist/engine/config.d.ts +0 -62
  220. package/dist/engine/config.d.ts.map +0 -1
  221. package/dist/engine/config.js +0 -223
  222. package/dist/engine/config.js.map +0 -1
  223. package/dist/engine/index.d.ts +0 -17
  224. package/dist/engine/index.d.ts.map +0 -1
  225. package/dist/engine/index.js +0 -16
  226. package/dist/engine/index.js.map +0 -1
  227. package/dist/engine/resolver.d.ts +0 -62
  228. package/dist/engine/resolver.d.ts.map +0 -1
  229. package/dist/engine/resolver.js +0 -103
  230. package/dist/engine/resolver.js.map +0 -1
  231. package/dist/engine/singleton.d.ts +0 -95
  232. package/dist/engine/singleton.d.ts.map +0 -1
  233. package/dist/engine/singleton.js +0 -325
  234. package/dist/engine/singleton.js.map +0 -1
  235. package/dist/engine/types.d.ts +0 -402
  236. package/dist/engine/types.d.ts.map +0 -1
  237. package/dist/engine/types.js +0 -22
  238. package/dist/engine/types.js.map +0 -1
  239. package/dist/engine-binary-resolver.js +0 -110
  240. package/dist/engine-binary-resolver.test.js +0 -61
  241. package/dist/engine-cli.js +0 -60
  242. package/dist/engine-client.js +0 -301
  243. package/dist/engine-client.test.js +0 -118
  244. package/dist/functions/chain_state.d.ts +0 -51
  245. package/dist/functions/chain_state.d.ts.map +0 -1
  246. package/dist/functions/chain_state.js +0 -59
  247. package/dist/functions/chain_state.js.map +0 -1
  248. package/dist/hooks/drift-catalog.d.ts +0 -68
  249. package/dist/hooks/drift-catalog.d.ts.map +0 -1
  250. package/dist/hooks/drift-catalog.js +0 -184
  251. package/dist/hooks/drift-catalog.js.map +0 -1
  252. package/dist/hooks/drift-catalog.test.js +0 -154
  253. package/dist/hooks/drift-patterns.d.ts +0 -110
  254. package/dist/hooks/drift-patterns.d.ts.map +0 -1
  255. package/dist/hooks/drift-patterns.js +0 -289
  256. package/dist/hooks/drift-patterns.js.map +0 -1
  257. package/dist/hooks/drift-patterns.test.js +0 -325
  258. package/dist/hooks/engine-vocab-gate.d.ts +0 -108
  259. package/dist/hooks/engine-vocab-gate.d.ts.map +0 -1
  260. package/dist/hooks/engine-vocab-gate.js +0 -225
  261. package/dist/hooks/engine-vocab-gate.js.map +0 -1
  262. package/dist/hooks/engine-vocab-gate.test.js +0 -170
  263. package/dist/hooks/heartbeat.d.ts +0 -107
  264. package/dist/hooks/heartbeat.d.ts.map +0 -1
  265. package/dist/hooks/heartbeat.js +0 -316
  266. package/dist/hooks/heartbeat.js.map +0 -1
  267. package/dist/hooks/heartbeat.test.js +0 -393
  268. package/dist/hooks/honesty-ledger-session-scope.test.js +0 -100
  269. package/dist/hooks/honesty-ledger.d.ts +0 -123
  270. package/dist/hooks/honesty-ledger.d.ts.map +0 -1
  271. package/dist/hooks/honesty-ledger.js +0 -226
  272. package/dist/hooks/honesty-ledger.js.map +0 -1
  273. package/dist/hooks/honesty-ledger.test.js +0 -466
  274. package/dist/hooks/inline-report-check.d.ts +0 -63
  275. package/dist/hooks/inline-report-check.d.ts.map +0 -1
  276. package/dist/hooks/inline-report-check.js +0 -88
  277. package/dist/hooks/inline-report-check.js.map +0 -1
  278. package/dist/hooks/inline-report-check.test.js +0 -96
  279. package/dist/hooks/pre-tool-use.d.ts +0 -62
  280. package/dist/hooks/pre-tool-use.d.ts.map +0 -1
  281. package/dist/hooks/pre-tool-use.js +0 -342
  282. package/dist/hooks/pre-tool-use.js.map +0 -1
  283. package/dist/hooks/pre-tool-use.test.js +0 -134
  284. package/dist/hooks/session-end.d.ts +0 -15
  285. package/dist/hooks/session-end.d.ts.map +0 -1
  286. package/dist/hooks/session-end.js +0 -60
  287. package/dist/hooks/session-end.js.map +0 -1
  288. package/dist/hooks/session-end.test.js +0 -52
  289. package/dist/hooks/stop.d.ts +0 -35
  290. package/dist/hooks/stop.d.ts.map +0 -1
  291. package/dist/hooks/stop.js +0 -136
  292. package/dist/hooks/stop.js.map +0 -1
  293. package/dist/hooks/transcript-active-task.test.js +0 -342
  294. package/dist/hooks/transcript.d.ts +0 -26
  295. package/dist/hooks/transcript.d.ts.map +0 -1
  296. package/dist/hooks/transcript.js +0 -266
  297. package/dist/hooks/transcript.js.map +0 -1
  298. package/dist/hooks/transcript.test.js +0 -103
  299. package/dist/hooks/user-prompt-submit.d.ts +0 -74
  300. package/dist/hooks/user-prompt-submit.d.ts.map +0 -1
  301. package/dist/hooks/user-prompt-submit.js +0 -256
  302. package/dist/hooks/user-prompt-submit.js.map +0 -1
  303. package/dist/hooks/user-prompt-submit.test.js +0 -118
  304. package/dist/hooks/versioning-gate.d.ts +0 -101
  305. package/dist/hooks/versioning-gate.d.ts.map +0 -1
  306. package/dist/hooks/versioning-gate.js +0 -245
  307. package/dist/hooks/versioning-gate.js.map +0 -1
  308. package/dist/hooks/versioning-gate.test.js +0 -368
  309. package/dist/hooks/workflow-gate.d.ts +0 -64
  310. package/dist/hooks/workflow-gate.d.ts.map +0 -1
  311. package/dist/hooks/workflow-gate.js +0 -152
  312. package/dist/hooks/workflow-gate.js.map +0 -1
  313. package/dist/hooks/workflow-gate.test.js +0 -197
  314. package/dist/hooks-cli.d.ts +0 -25
  315. package/dist/hooks-cli.d.ts.map +0 -1
  316. package/dist/hooks-cli.js +0 -286
  317. package/dist/hooks-cli.js.map +0 -1
  318. package/dist/hooks-cli.test.js +0 -148
  319. package/dist/origin.d.ts +0 -16
  320. package/dist/origin.d.ts.map +0 -1
  321. package/dist/origin.js +0 -92
  322. package/dist/origin.js.map +0 -1
  323. package/dist/packs/seed_lessons_ingest.d.ts +0 -30
  324. package/dist/packs/seed_lessons_ingest.d.ts.map +0 -1
  325. package/dist/packs/seed_lessons_ingest.js +0 -107
  326. package/dist/packs/seed_lessons_ingest.js.map +0 -1
  327. package/dist/project-cli.d.ts +0 -7
  328. package/dist/project-cli.d.ts.map +0 -1
  329. package/dist/project-cli.js +0 -145
  330. package/dist/project-cli.js.map +0 -1
  331. package/dist/project.d.ts +0 -127
  332. package/dist/project.d.ts.map +0 -1
  333. package/dist/project.js +0 -281
  334. package/dist/project.js.map +0 -1
  335. package/dist/project.test.js +0 -287
  336. package/dist/rag/backends/loop_engine.d.ts +0 -61
  337. package/dist/rag/backends/loop_engine.d.ts.map +0 -1
  338. package/dist/rag/backends/loop_engine.js +0 -160
  339. package/dist/rag/backends/loop_engine.js.map +0 -1
  340. package/dist/recall.d.ts +0 -82
  341. package/dist/recall.d.ts.map +0 -1
  342. package/dist/recall.js +0 -81
  343. package/dist/recall.js.map +0 -1
  344. package/dist/runtime/agent_bridge/autospawn.d.ts +0 -131
  345. package/dist/runtime/agent_bridge/autospawn.d.ts.map +0 -1
  346. package/dist/runtime/agent_bridge/autospawn.js +0 -251
  347. package/dist/runtime/agent_bridge/autospawn.js.map +0 -1
  348. package/dist/runtime/chain_state.d.ts +0 -124
  349. package/dist/runtime/chain_state.d.ts.map +0 -1
  350. package/dist/runtime/chain_state.js +0 -189
  351. package/dist/runtime/chain_state.js.map +0 -1
  352. package/dist/runtime/hooks/permission_decision.d.ts +0 -34
  353. package/dist/runtime/hooks/permission_decision.d.ts.map +0 -1
  354. package/dist/runtime/hooks/permission_decision.js +0 -39
  355. package/dist/runtime/hooks/permission_decision.js.map +0 -1
  356. package/dist/runtime/workflow_fsm.d.ts +0 -21
  357. package/dist/runtime/workflow_fsm.d.ts.map +0 -1
  358. package/dist/runtime/workflow_fsm.js +0 -25
  359. package/dist/runtime/workflow_fsm.js.map +0 -1
  360. package/dist/runtime/workflow_map.d.ts +0 -26
  361. package/dist/runtime/workflow_map.d.ts.map +0 -1
  362. package/dist/runtime/workflow_map.js +0 -38
  363. package/dist/runtime/workflow_map.js.map +0 -1
  364. package/dist/scope.d.ts +0 -48
  365. package/dist/scope.d.ts.map +0 -1
  366. package/dist/scope.js +0 -111
  367. package/dist/scope.js.map +0 -1
  368. package/dist/setup/cli/topic_create_step.d.ts +0 -84
  369. package/dist/setup/cli/topic_create_step.d.ts.map +0 -1
  370. package/dist/setup/cli/topic_create_step.js +0 -213
  371. package/dist/setup/cli/topic_create_step.js.map +0 -1
  372. package/dist/system-export.d.ts +0 -65
  373. package/dist/system-export.d.ts.map +0 -1
  374. package/dist/system-export.js +0 -194
  375. package/dist/system-export.js.map +0 -1
  376. package/dist/utterance/classifier.d.ts +0 -53
  377. package/dist/utterance/classifier.d.ts.map +0 -1
  378. package/dist/utterance/classifier.js +0 -184
  379. package/dist/utterance/classifier.js.map +0 -1
  380. package/dist/utterance/classifier.test.js +0 -147
@@ -1,176 +0,0 @@
1
- /**
2
- * Chat gateway — unified surface for bot-style chat connections (v0.7).
3
- *
4
- * Three concrete adapters plug into this interface: Telegram, Discord,
5
- * Slack. Each is independently activatable via a token in
6
- * `~/.opensquid/config.json` `chat_connections.<platform>.bot_token`.
7
- * Adapters that don't have a token configured are skipped at startup —
8
- * opensquid works fine with zero, one, or all three chat platforms wired.
9
- *
10
- * Scope decisions (per [[find-simple-solutions]]):
11
- * - Single bot owner per platform (no multi-tenancy, no OAuth flows).
12
- * The user runs their OWN bot with their OWN token.
13
- * - Bot owner is the only authorized chat participant by default.
14
- * Allowlist of additional chat/channel/user ids in config.
15
- * - Outbound-only connection mechanism (long-poll, WebSocket, Socket
16
- * Mode) — no inbound HTTP server, no webhook URL, no public
17
- * ingress required. Works behind any NAT.
18
- * - Text-only messages in v0.7. Images / files / inline buttons
19
- * deferred until concrete user-need surfaces.
20
- *
21
- * Why a gateway abstraction at all (vs per-platform code paths):
22
- * the opensquid-side MCP tool surface (`chat.send`, `chat.list_channels`,
23
- * the inbound-message → MCP-context bridge) should NOT care which
24
- * platform a message came from. The gateway normalizes incoming events
25
- * to a single `ChatMessage` shape and routes outgoing sends by
26
- * channel id.
27
- *
28
- * What is NOT in this file:
29
- * - Token storage / config loading (lives in `chat/config.ts`).
30
- * - The actual SDK calls (live in `chat/adapters/<platform>.ts`).
31
- * - The MCP tool wiring (lives in `chat/mcp-tools.ts`).
32
- *
33
- * What IS in this file: types + the `ChatGateway` orchestrator that
34
- * holds N adapters and presents a single send/subscribe API.
35
- */
36
- /** Stable platform identifier. */
37
- export type ChatPlatform = "telegram" | "discord" | "slack";
38
- /**
39
- * A logical destination for outbound messages. The shape varies by
40
- * platform but always normalizes to a single string id from opensquid's
41
- * point of view. Adapters parse the id back to platform-native form
42
- * (Telegram chat_id, Discord channel snowflake, Slack channel id).
43
- *
44
- * Format: `<platform>:<native_id>`, e.g. `telegram:8075471258`.
45
- */
46
- export type ChannelId = string;
47
- /** Normalized inbound message (platform-agnostic shape). */
48
- export interface ChatMessage {
49
- /** Stable id from the platform (snowflake / message_id / ts). */
50
- id: string;
51
- /**
52
- * Optional thread / topic id for platforms that support sub-threads
53
- * within a single channel (Telegram forum topics, Discord threads).
54
- * Preserved on inbound so the daemon can route to per-topic projects;
55
- * preserved on outbound so replies thread correctly. v0.7.2.
56
- */
57
- threadId?: string;
58
- /** Which platform delivered this. */
59
- platform: ChatPlatform;
60
- /** Channel the message was posted in (DM, group, server channel). */
61
- channel: ChannelId;
62
- /** Display name of the sender (best-effort; falls back to user id). */
63
- sender: string;
64
- /** Native sender id (preserved for allowlist checks + replies). */
65
- senderId: string;
66
- /** Message body, text only in v0.7. */
67
- text: string;
68
- /** Wall-clock the platform stamped the message with. */
69
- receivedAt: Date;
70
- /** True when the message contains @-mention or trigger-word for the bot. */
71
- mentionsBot: boolean;
72
- }
73
- /**
74
- * Outbound message payload — text-only in v0.7. `replyTo` populates
75
- * platform-specific threading metadata where it's free (Telegram
76
- * `reply_to_message_id`, Slack `thread_ts`, Discord `message_reference`).
77
- */
78
- export interface OutboundMessage {
79
- channel: ChannelId;
80
- text: string;
81
- /** Source message id to reply-thread under (best-effort per platform). */
82
- replyTo?: string;
83
- /**
84
- * Optional thread / topic id for platforms that support sub-threads
85
- * within a single channel:
86
- *
87
- * - **Telegram**: `message_thread_id` for forum topics (a supergroup
88
- * with Topics enabled has multiple topic threads, each one a
89
- * separate logical channel within the same chat_id). v0.7.2.
90
- * - **Discord**: thread id for thread messages.
91
- * - **Slack**: not used (Slack threading is via `replyTo` only).
92
- *
93
- * Adapters that don't support thread_id ignore it.
94
- */
95
- threadId?: string;
96
- }
97
- /** Result of a single send. Adapter-defined fields preserved opaquely. */
98
- export interface SendResult {
99
- platform: ChatPlatform;
100
- /** Native id of the delivered message — for future edit / delete / react. */
101
- messageId: string;
102
- /** Wall-clock the platform stamped the delivered message with. */
103
- deliveredAt: Date;
104
- }
105
- /** Inbound message handler. Async return for await-based pipelines. */
106
- export type MessageHandler = (msg: ChatMessage) => Promise<void> | void;
107
- /**
108
- * What every chat adapter must implement. Adapter authors hold the
109
- * platform-specific SDK / WebSocket / long-poll loop; this interface
110
- * is the only surface opensquid touches.
111
- *
112
- * Lifecycle:
113
- * 1. `start()` — open the connection (login, attach handlers).
114
- * Resolves when ready to receive + send. Throws on auth failure.
115
- * 2. `onMessage(handler)` — subscribe to inbound events. Multiple
116
- * subscriptions stack; all fire per message in registration order.
117
- * 3. `send(message)` — push outbound. Throws on permanent failures
118
- * (channel doesn't exist, bot kicked); transient errors are
119
- * retried internally per the adapter's policy.
120
- * 4. `shutdown()` — close the connection cleanly. Idempotent.
121
- *
122
- * `identity()` returns the bot's own user info (username + native id) —
123
- * used by the gateway to recognize self-authored messages and to
124
- * resolve @-mention tokens to bot identity.
125
- */
126
- export interface ChatAdapter {
127
- /** Platform identifier this adapter handles. */
128
- readonly platform: ChatPlatform;
129
- start(): Promise<void>;
130
- shutdown(): Promise<void>;
131
- onMessage(handler: MessageHandler): void;
132
- send(message: OutboundMessage): Promise<SendResult>;
133
- identity(): Promise<{
134
- username: string;
135
- nativeId: string;
136
- }>;
137
- }
138
- /**
139
- * Holds N adapters and presents the unified API. Construct with the
140
- * adapter array you want active for this opensquid process. Pre-wired
141
- * tokens live in config; the factory at `chat/factory.ts` builds the
142
- * adapter array based on which tokens are present.
143
- */
144
- export declare class ChatGateway {
145
- private readonly adapters;
146
- private readonly handlers;
147
- private started;
148
- constructor(adapters: ChatAdapter[]);
149
- /** Open all adapter connections in parallel. First failure surfaces. */
150
- start(): Promise<void>;
151
- /** Close all adapter connections. Errors are logged and swallowed
152
- * so shutdown is always best-effort. */
153
- shutdown(): Promise<void>;
154
- /** Subscribe to inbound messages from any platform. */
155
- onMessage(handler: MessageHandler): void;
156
- /** Route an outbound message to the right adapter by `channel` prefix. */
157
- send(message: OutboundMessage): Promise<SendResult>;
158
- /** List the platforms currently wired up. Used by `chat.list_channels`. */
159
- activePlatforms(): ChatPlatform[];
160
- /**
161
- * v0.7.2 — get the active adapter for a platform so daemon-internal
162
- * code paths (e.g. `chat-daemon-worker` RPC dispatch) can reach
163
- * platform-specific methods like Telegram's `createTopic`. Returns
164
- * undefined when the platform isn't activated.
165
- */
166
- getAdapter(platform: ChatPlatform): ChatAdapter | undefined;
167
- private dispatch;
168
- }
169
- export declare class ChatGatewayError extends Error {
170
- readonly hint?: string | undefined;
171
- constructor(message: string, hint?: string | undefined);
172
- }
173
- export declare function formatChannelId(platform: ChatPlatform, nativeId: string): ChannelId;
174
- export declare function platformFromChannel(channel: ChannelId): ChatPlatform;
175
- export declare function nativeIdFromChannel(channel: ChannelId): string;
176
- //# sourceMappingURL=gateway.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"gateway.d.ts","sourceRoot":"","sources":["../../src.legacy/chat/gateway.ts"],"names":[],"mappings":"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"}
@@ -1,146 +0,0 @@
1
- /**
2
- * Chat gateway — unified surface for bot-style chat connections (v0.7).
3
- *
4
- * Three concrete adapters plug into this interface: Telegram, Discord,
5
- * Slack. Each is independently activatable via a token in
6
- * `~/.opensquid/config.json` `chat_connections.<platform>.bot_token`.
7
- * Adapters that don't have a token configured are skipped at startup —
8
- * opensquid works fine with zero, one, or all three chat platforms wired.
9
- *
10
- * Scope decisions (per [[find-simple-solutions]]):
11
- * - Single bot owner per platform (no multi-tenancy, no OAuth flows).
12
- * The user runs their OWN bot with their OWN token.
13
- * - Bot owner is the only authorized chat participant by default.
14
- * Allowlist of additional chat/channel/user ids in config.
15
- * - Outbound-only connection mechanism (long-poll, WebSocket, Socket
16
- * Mode) — no inbound HTTP server, no webhook URL, no public
17
- * ingress required. Works behind any NAT.
18
- * - Text-only messages in v0.7. Images / files / inline buttons
19
- * deferred until concrete user-need surfaces.
20
- *
21
- * Why a gateway abstraction at all (vs per-platform code paths):
22
- * the opensquid-side MCP tool surface (`chat.send`, `chat.list_channels`,
23
- * the inbound-message → MCP-context bridge) should NOT care which
24
- * platform a message came from. The gateway normalizes incoming events
25
- * to a single `ChatMessage` shape and routes outgoing sends by
26
- * channel id.
27
- *
28
- * What is NOT in this file:
29
- * - Token storage / config loading (lives in `chat/config.ts`).
30
- * - The actual SDK calls (live in `chat/adapters/<platform>.ts`).
31
- * - The MCP tool wiring (lives in `chat/mcp-tools.ts`).
32
- *
33
- * What IS in this file: types + the `ChatGateway` orchestrator that
34
- * holds N adapters and presents a single send/subscribe API.
35
- */
36
- // ---------------------------------------------------------------------
37
- // Gateway orchestrator
38
- // ---------------------------------------------------------------------
39
- /**
40
- * Holds N adapters and presents the unified API. Construct with the
41
- * adapter array you want active for this opensquid process. Pre-wired
42
- * tokens live in config; the factory at `chat/factory.ts` builds the
43
- * adapter array based on which tokens are present.
44
- */
45
- export class ChatGateway {
46
- adapters;
47
- handlers = [];
48
- started = false;
49
- constructor(adapters) {
50
- this.adapters = new Map(adapters.map((a) => [a.platform, a]));
51
- }
52
- /** Open all adapter connections in parallel. First failure surfaces. */
53
- async start() {
54
- if (this.started)
55
- return;
56
- // Wire incoming handler dispatch BEFORE starting connections so we
57
- // don't drop early messages.
58
- for (const adapter of this.adapters.values()) {
59
- adapter.onMessage((msg) => this.dispatch(msg));
60
- }
61
- await Promise.all([...this.adapters.values()].map((a) => a.start()));
62
- this.started = true;
63
- }
64
- /** Close all adapter connections. Errors are logged and swallowed
65
- * so shutdown is always best-effort. */
66
- async shutdown() {
67
- if (!this.started)
68
- return;
69
- await Promise.allSettled([...this.adapters.values()].map((a) => a.shutdown()));
70
- this.started = false;
71
- }
72
- /** Subscribe to inbound messages from any platform. */
73
- onMessage(handler) {
74
- this.handlers.push(handler);
75
- }
76
- /** Route an outbound message to the right adapter by `channel` prefix. */
77
- async send(message) {
78
- const platform = platformFromChannel(message.channel);
79
- const adapter = this.adapters.get(platform);
80
- if (!adapter) {
81
- throw new ChatGatewayError(`no adapter active for platform '${platform}' (channel '${message.channel}')`, "ensure the corresponding bot_token is set in ~/.opensquid/config.json chat_connections");
82
- }
83
- return adapter.send(message);
84
- }
85
- /** List the platforms currently wired up. Used by `chat.list_channels`. */
86
- activePlatforms() {
87
- return [...this.adapters.keys()];
88
- }
89
- /**
90
- * v0.7.2 — get the active adapter for a platform so daemon-internal
91
- * code paths (e.g. `chat-daemon-worker` RPC dispatch) can reach
92
- * platform-specific methods like Telegram's `createTopic`. Returns
93
- * undefined when the platform isn't activated.
94
- */
95
- getAdapter(platform) {
96
- return this.adapters.get(platform);
97
- }
98
- async dispatch(msg) {
99
- for (const handler of this.handlers) {
100
- try {
101
- await handler(msg);
102
- }
103
- catch (err) {
104
- const e = err instanceof Error ? err.message : String(err);
105
- // Don't let one handler break the dispatch chain.
106
- // eslint-disable-next-line no-console
107
- console.error(`[chat-gateway] handler error on ${msg.platform}: ${e}`);
108
- }
109
- }
110
- }
111
- }
112
- // ---------------------------------------------------------------------
113
- // Errors
114
- // ---------------------------------------------------------------------
115
- export class ChatGatewayError extends Error {
116
- hint;
117
- constructor(message, hint) {
118
- super(message);
119
- this.hint = hint;
120
- this.name = "ChatGatewayError";
121
- }
122
- }
123
- // ---------------------------------------------------------------------
124
- // ChannelId helpers
125
- // ---------------------------------------------------------------------
126
- export function formatChannelId(platform, nativeId) {
127
- return `${platform}:${nativeId}`;
128
- }
129
- export function platformFromChannel(channel) {
130
- const idx = channel.indexOf(":");
131
- if (idx === -1) {
132
- throw new ChatGatewayError(`malformed channel id '${channel}'`, "channel ids must be '<platform>:<native_id>', e.g. 'telegram:8075471258'");
133
- }
134
- const candidate = channel.slice(0, idx);
135
- if (candidate !== "telegram" && candidate !== "discord" && candidate !== "slack") {
136
- throw new ChatGatewayError(`unknown platform '${candidate}' in channel id '${channel}'`, "supported platforms: telegram, discord, slack");
137
- }
138
- return candidate;
139
- }
140
- export function nativeIdFromChannel(channel) {
141
- const idx = channel.indexOf(":");
142
- if (idx === -1) {
143
- throw new ChatGatewayError(`malformed channel id '${channel}'`);
144
- }
145
- return channel.slice(idx + 1);
146
- }
@@ -1 +0,0 @@
1
- {"version":3,"file":"gateway.js","sourceRoot":"","sources":["../../src.legacy/chat/gateway.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAuHH,wEAAwE;AACxE,uBAAuB;AACvB,wEAAwE;AAExE;;;;;GAKG;AACH,MAAM,OAAO,WAAW;IACL,QAAQ,CAAiC;IACzC,QAAQ,GAAqB,EAAE,CAAC;IACzC,OAAO,GAAG,KAAK,CAAC;IAExB,YAAY,QAAuB;QACjC,IAAI,CAAC,QAAQ,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAChE,CAAC;IAED,wEAAwE;IACxE,KAAK,CAAC,KAAK;QACT,IAAI,IAAI,CAAC,OAAO;YAAE,OAAO;QACzB,mEAAmE;QACnE,6BAA6B;QAC7B,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC;YAC7C,OAAO,CAAC,SAAS,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;QACjD,CAAC;QACD,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;QACrE,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;IACtB,CAAC;IAED;4CACwC;IACxC,KAAK,CAAC,QAAQ;QACZ,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE,OAAO;QAC1B,MAAM,OAAO,CAAC,UAAU,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;QAC/E,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;IACvB,CAAC;IAED,uDAAuD;IACvD,SAAS,CAAC,OAAuB;QAC/B,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC9B,CAAC;IAED,0EAA0E;IAC1E,KAAK,CAAC,IAAI,CAAC,OAAwB;QACjC,MAAM,QAAQ,GAAG,mBAAmB,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACtD,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC5C,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,gBAAgB,CACxB,mCAAmC,QAAQ,eAAe,OAAO,CAAC,OAAO,IAAI,EAC7E,wFAAwF,CACzF,CAAC;QACJ,CAAC;QACD,OAAO,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC/B,CAAC;IAED,2EAA2E;IAC3E,eAAe;QACb,OAAO,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;IACnC,CAAC;IAED;;;;;OAKG;IACH,UAAU,CAAC,QAAsB;QAC/B,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACrC,CAAC;IAEO,KAAK,CAAC,QAAQ,CAAC,GAAgB;QACrC,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YACpC,IAAI,CAAC;gBACH,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC;YACrB,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,MAAM,CAAC,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;gBAC3D,kDAAkD;gBAClD,sCAAsC;gBACtC,OAAO,CAAC,KAAK,CAAC,mCAAmC,GAAG,CAAC,QAAQ,KAAK,CAAC,EAAE,CAAC,CAAC;YACzE,CAAC;QACH,CAAC;IACH,CAAC;CACF;AAED,wEAAwE;AACxE,SAAS;AACT,wEAAwE;AAExE,MAAM,OAAO,gBAAiB,SAAQ,KAAK;IAGvB;IAFlB,YACE,OAAe,EACC,IAAa;QAE7B,KAAK,CAAC,OAAO,CAAC,CAAC;QAFC,SAAI,GAAJ,IAAI,CAAS;QAG7B,IAAI,CAAC,IAAI,GAAG,kBAAkB,CAAC;IACjC,CAAC;CACF;AAED,wEAAwE;AACxE,oBAAoB;AACpB,wEAAwE;AAExE,MAAM,UAAU,eAAe,CAAC,QAAsB,EAAE,QAAgB;IACtE,OAAO,GAAG,QAAQ,IAAI,QAAQ,EAAE,CAAC;AACnC,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,OAAkB;IACpD,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACjC,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC;QACf,MAAM,IAAI,gBAAgB,CACxB,yBAAyB,OAAO,GAAG,EACnC,0EAA0E,CAC3E,CAAC;IACJ,CAAC;IACD,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACxC,IAAI,SAAS,KAAK,UAAU,IAAI,SAAS,KAAK,SAAS,IAAI,SAAS,KAAK,OAAO,EAAE,CAAC;QACjF,MAAM,IAAI,gBAAgB,CACxB,qBAAqB,SAAS,oBAAoB,OAAO,GAAG,EAC5D,+CAA+C,CAChD,CAAC;IACJ,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,OAAkB;IACpD,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACjC,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC;QACf,MAAM,IAAI,gBAAgB,CAAC,yBAAyB,OAAO,GAAG,CAAC,CAAC;IAClE,CAAC;IACD,OAAO,OAAO,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;AAChC,CAAC"}
@@ -1,192 +0,0 @@
1
- import { describe, expect, it, vi } from "vitest";
2
- import { ChatGateway, ChatGatewayError, formatChannelId, nativeIdFromChannel, platformFromChannel, } from "./gateway.js";
3
- // ---------------------------------------------------------------------
4
- // Mock adapter
5
- // ---------------------------------------------------------------------
6
- class MockAdapter {
7
- platform;
8
- started = false;
9
- shutdownCalls = 0;
10
- sends = [];
11
- handlers = [];
12
- constructor(platform) {
13
- this.platform = platform;
14
- }
15
- async start() {
16
- this.started = true;
17
- }
18
- async shutdown() {
19
- this.shutdownCalls++;
20
- this.started = false;
21
- }
22
- onMessage(handler) {
23
- this.handlers.push(handler);
24
- }
25
- async send(message) {
26
- this.sends.push(message);
27
- return {
28
- platform: this.platform,
29
- messageId: `mock-${this.sends.length}`,
30
- deliveredAt: new Date("2026-05-16T00:00:00Z"),
31
- };
32
- }
33
- async identity() {
34
- return { username: `mock-${this.platform}-bot`, nativeId: "bot-1" };
35
- }
36
- // Test helper: simulate an inbound message.
37
- async simulateMessage(text, sender = "user-1") {
38
- const msg = {
39
- id: `m-${Date.now()}`,
40
- platform: this.platform,
41
- channel: formatChannelId(this.platform, "channel-1"),
42
- sender,
43
- senderId: sender,
44
- text,
45
- receivedAt: new Date("2026-05-16T00:00:00Z"),
46
- mentionsBot: false,
47
- };
48
- for (const h of this.handlers)
49
- await h(msg);
50
- }
51
- }
52
- // ---------------------------------------------------------------------
53
- // channel id helpers
54
- // ---------------------------------------------------------------------
55
- describe("channel id helpers", () => {
56
- it("formatChannelId joins with colon", () => {
57
- expect(formatChannelId("telegram", "8075471258")).toBe("telegram:8075471258");
58
- });
59
- it("platformFromChannel parses telegram", () => {
60
- expect(platformFromChannel("telegram:8075471258")).toBe("telegram");
61
- });
62
- it("platformFromChannel parses discord", () => {
63
- expect(platformFromChannel("discord:1234567890")).toBe("discord");
64
- });
65
- it("platformFromChannel parses slack", () => {
66
- expect(platformFromChannel("slack:C012345")).toBe("slack");
67
- });
68
- it("platformFromChannel rejects unknown platform", () => {
69
- expect(() => platformFromChannel("hipchat:xyz")).toThrow(ChatGatewayError);
70
- });
71
- it("platformFromChannel rejects malformed", () => {
72
- expect(() => platformFromChannel("telegram-no-colon")).toThrow(ChatGatewayError);
73
- });
74
- it("nativeIdFromChannel strips the prefix", () => {
75
- expect(nativeIdFromChannel("telegram:8075471258")).toBe("8075471258");
76
- });
77
- it("nativeIdFromChannel preserves colons in native id (slack thread_ts)", () => {
78
- expect(nativeIdFromChannel("slack:C012345:1234.5678")).toBe("C012345:1234.5678");
79
- });
80
- });
81
- // ---------------------------------------------------------------------
82
- // ChatGateway lifecycle
83
- // ---------------------------------------------------------------------
84
- describe("ChatGateway lifecycle", () => {
85
- it("start() calls start on every adapter", async () => {
86
- const tg = new MockAdapter("telegram");
87
- const dc = new MockAdapter("discord");
88
- const gw = new ChatGateway([tg, dc]);
89
- expect(tg.started).toBe(false);
90
- expect(dc.started).toBe(false);
91
- await gw.start();
92
- expect(tg.started).toBe(true);
93
- expect(dc.started).toBe(true);
94
- });
95
- it("start() is idempotent", async () => {
96
- const tg = new MockAdapter("telegram");
97
- const startSpy = vi.spyOn(tg, "start");
98
- const gw = new ChatGateway([tg]);
99
- await gw.start();
100
- await gw.start();
101
- expect(startSpy).toHaveBeenCalledTimes(1);
102
- });
103
- it("shutdown() closes every adapter", async () => {
104
- const tg = new MockAdapter("telegram");
105
- const dc = new MockAdapter("discord");
106
- const gw = new ChatGateway([tg, dc]);
107
- await gw.start();
108
- await gw.shutdown();
109
- expect(tg.shutdownCalls).toBe(1);
110
- expect(dc.shutdownCalls).toBe(1);
111
- });
112
- it("shutdown() before start is a no-op", async () => {
113
- const tg = new MockAdapter("telegram");
114
- const gw = new ChatGateway([tg]);
115
- await gw.shutdown();
116
- expect(tg.shutdownCalls).toBe(0);
117
- });
118
- it("activePlatforms reports configured set", () => {
119
- const tg = new MockAdapter("telegram");
120
- const sl = new MockAdapter("slack");
121
- const gw = new ChatGateway([tg, sl]);
122
- expect(gw.activePlatforms().sort()).toEqual(["slack", "telegram"]);
123
- });
124
- });
125
- // ---------------------------------------------------------------------
126
- // Routing
127
- // ---------------------------------------------------------------------
128
- describe("ChatGateway routing", () => {
129
- it("send() routes to the adapter matching the channel prefix", async () => {
130
- const tg = new MockAdapter("telegram");
131
- const dc = new MockAdapter("discord");
132
- const gw = new ChatGateway([tg, dc]);
133
- await gw.start();
134
- await gw.send({ channel: "telegram:8075471258", text: "hi tg" });
135
- await gw.send({ channel: "discord:1234", text: "hi dc" });
136
- expect(tg.sends.map((s) => s.text)).toEqual(["hi tg"]);
137
- expect(dc.sends.map((s) => s.text)).toEqual(["hi dc"]);
138
- });
139
- it("send() throws when no adapter is configured for the platform", async () => {
140
- const tg = new MockAdapter("telegram");
141
- const gw = new ChatGateway([tg]);
142
- await gw.start();
143
- await expect(gw.send({ channel: "slack:C012", text: "hi" })).rejects.toThrow(ChatGatewayError);
144
- });
145
- });
146
- // ---------------------------------------------------------------------
147
- // Inbound dispatch
148
- // ---------------------------------------------------------------------
149
- describe("ChatGateway inbound dispatch", () => {
150
- it("forwards inbound messages to all registered handlers", async () => {
151
- const tg = new MockAdapter("telegram");
152
- const gw = new ChatGateway([tg]);
153
- await gw.start();
154
- const h1 = vi.fn();
155
- const h2 = vi.fn();
156
- gw.onMessage(h1);
157
- gw.onMessage(h2);
158
- await tg.simulateMessage("hello");
159
- expect(h1).toHaveBeenCalledOnce();
160
- expect(h2).toHaveBeenCalledOnce();
161
- expect(h1.mock.calls[0][0].text).toBe("hello");
162
- });
163
- it("one handler throwing doesn't block the others", async () => {
164
- const tg = new MockAdapter("telegram");
165
- const gw = new ChatGateway([tg]);
166
- await gw.start();
167
- const errorSpy = vi.spyOn(console, "error").mockImplementation(() => { });
168
- const failing = vi.fn(() => {
169
- throw new Error("boom");
170
- });
171
- const ok = vi.fn();
172
- gw.onMessage(failing);
173
- gw.onMessage(ok);
174
- await tg.simulateMessage("test");
175
- expect(failing).toHaveBeenCalledOnce();
176
- expect(ok).toHaveBeenCalledOnce();
177
- errorSpy.mockRestore();
178
- });
179
- it("messages route through with correct platform tag", async () => {
180
- const dc = new MockAdapter("discord");
181
- const gw = new ChatGateway([dc]);
182
- await gw.start();
183
- const captured = [];
184
- gw.onMessage((m) => {
185
- captured.push(m);
186
- });
187
- await dc.simulateMessage("from discord");
188
- expect(captured).toHaveLength(1);
189
- expect(captured[0].platform).toBe("discord");
190
- expect(captured[0].channel).toBe("discord:channel-1");
191
- });
192
- });
@@ -1,39 +0,0 @@
1
- /** Resolved path to the user's global CLAUDE.md. */
2
- export declare function defaultClaudeMdPath(): string;
3
- export interface PromotedLessonEntry {
4
- /** Engine lesson id (e.g. "les-abc12345"). */
5
- id: string;
6
- /** One-line description (trigger phrase + concise summary). */
7
- description: string;
8
- /** ISO timestamp the promotion happened. */
9
- promoted_at: string;
10
- }
11
- /**
12
- * Append a one-line entry for a newly promoted lesson into the
13
- * CLAUDE.md rules sub-block. Idempotent — if an entry for `id` already
14
- * exists, the line is left untouched. Returns the path written + the
15
- * new content of the rules block (without sentinels).
16
- *
17
- * No-op (silent) when:
18
- * - CLAUDE.md doesn't exist
19
- * - The rules sub-block isn't installed yet (user hasn't run
20
- * `opensquid install` against this CLAUDE.md)
21
- *
22
- * Failure is intentionally non-fatal: lesson promotion is the
23
- * authoritative event; CLAUDE.md is downstream display. We never block
24
- * the promote on a CLAUDE.md write failure.
25
- */
26
- export declare function appendPromotedLessonToClaudeMd(entry: PromotedLessonEntry, options?: {
27
- target?: string;
28
- }): Promise<{
29
- target: string;
30
- appended: boolean;
31
- } | null>;
32
- /**
33
- * For tests + diagnostics: list the lesson ids currently appearing in
34
- * the rules sub-block of a given CLAUDE.md.
35
- */
36
- export declare function listRulesBlockLessonIds(options?: {
37
- target?: string;
38
- }): Promise<string[]>;
39
- //# sourceMappingURL=claude-md.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"claude-md.d.ts","sourceRoot":"","sources":["../src.legacy/claude-md.ts"],"names":[],"mappings":"AA6BA,oDAAoD;AACpD,wBAAgB,mBAAmB,IAAI,MAAM,CAE5C;AAED,MAAM,WAAW,mBAAmB;IAClC,8CAA8C;IAC9C,EAAE,EAAE,MAAM,CAAC;IACX,+DAA+D;IAC/D,WAAW,EAAE,MAAM,CAAC;IACpB,4CAA4C;IAC5C,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,8BAA8B,CAClD,KAAK,EAAE,mBAAmB,EAC1B,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAO,GAChC,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,GAAG,IAAI,CAAC,CA4BvD;AA4BD;;;GAGG;AACH,wBAAsB,uBAAuB,CAC3C,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAO,GAChC,OAAO,CAAC,MAAM,EAAE,CAAC,CAgBnB"}