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,60 +0,0 @@
1
- /**
2
- * Telegram / Discord / Slack bot-token loading from env var + .env
3
- * file (0.7.5+, #148).
4
- *
5
- * Priority (highest first):
6
- * 1. process.env.OPENSQUID_TELEGRAM_BOT_TOKEN (or _DISCORD_, _SLACK_)
7
- * 2. .env file (first match wins):
8
- * - $OPENSQUID_ENV_FILE
9
- * - ~/.loop/.env
10
- * - ~/.opensquid/.env
11
- * - <cwd>/.env
12
- * 3. ~/.opensquid/config.json chat_connections.<platform>.bot_token
13
- *
14
- * The .env parser supports standard KEY=VALUE lines AND a tolerant
15
- * "bare token" fallback (single non-comment line, no `=`) — the user
16
- * may save just the token. Bare tokens are treated as
17
- * OPENSQUID_TELEGRAM_BOT_TOKEN.
18
- *
19
- * NEVER logs the token value. Only logs which SOURCE the active token
20
- * came from, so operators can debug "which bot is this daemon
21
- * actually using" without leaking the secret.
22
- */
23
- export type EnvKey = "OPENSQUID_TELEGRAM_BOT_TOKEN" | "OPENSQUID_DISCORD_BOT_TOKEN" | "OPENSQUID_SLACK_BOT_TOKEN" | "OPENSQUID_SLACK_APP_TOKEN";
24
- export type EnvSource = "env" | "env-file" | "config-json" | "missing";
25
- export interface TokenLookup {
26
- value: string | undefined;
27
- source: EnvSource;
28
- /** Path to the .env file used (only set when source === "env-file"). */
29
- env_file_path?: string;
30
- }
31
- /**
32
- * Resolve a token by priority: process.env → .env file → config.json
33
- * fallback (caller-supplied). Returns the value AND the source it
34
- * came from so the caller can log the source without exposing the
35
- * value.
36
- */
37
- export declare function resolveToken(key: EnvKey, configJsonFallback: string | undefined): Promise<TokenLookup>;
38
- /**
39
- * Find the first existing .env file in the search order. Returns null
40
- * if none exist.
41
- */
42
- export declare function locateEnvFile(): Promise<string | null>;
43
- /**
44
- * Parse a .env file into a flat string map. Supports:
45
- *
46
- * - `KEY=VALUE` lines (standard dotenv format)
47
- * - `KEY="quoted value"` (double-quoted)
48
- * - `KEY='quoted value'` (single-quoted)
49
- * - `#` comments + blank lines
50
- * - Bare-token fallback: if the file has exactly ONE non-comment
51
- * line and that line has no `=`, treat it as
52
- * OPENSQUID_TELEGRAM_BOT_TOKEN (most common shape for "user
53
- * saved just the token")
54
- *
55
- * Caches by path to avoid re-reading on every call.
56
- */
57
- export declare function loadEnvFile(envPath: string): Promise<Record<string, string>>;
58
- /** Test-only: clear the .env cache so subsequent loads re-read disk. */
59
- export declare function _clearEnvFileCache(): void;
60
- //# sourceMappingURL=env-token.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"env-token.d.ts","sourceRoot":"","sources":["../../src.legacy/chat/env-token.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAMH,MAAM,MAAM,MAAM,GACd,8BAA8B,GAC9B,6BAA6B,GAC7B,2BAA2B,GAC3B,2BAA2B,CAAC;AAEhC,MAAM,MAAM,SAAS,GAAG,KAAK,GAAG,UAAU,GAAG,aAAa,GAAG,SAAS,CAAC;AAEvE,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,MAAM,EAAE,SAAS,CAAC;IAClB,wEAAwE;IACxE,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAKD;;;;;GAKG;AACH,wBAAsB,YAAY,CAChC,GAAG,EAAE,MAAM,EACX,kBAAkB,EAAE,MAAM,GAAG,SAAS,GACrC,OAAO,CAAC,WAAW,CAAC,CAuBtB;AAED;;;GAGG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAiB5D;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAwClF;AAED,wEAAwE;AACxE,wBAAgB,kBAAkB,IAAI,IAAI,CAEzC"}
@@ -1,137 +0,0 @@
1
- /**
2
- * Telegram / Discord / Slack bot-token loading from env var + .env
3
- * file (0.7.5+, #148).
4
- *
5
- * Priority (highest first):
6
- * 1. process.env.OPENSQUID_TELEGRAM_BOT_TOKEN (or _DISCORD_, _SLACK_)
7
- * 2. .env file (first match wins):
8
- * - $OPENSQUID_ENV_FILE
9
- * - ~/.loop/.env
10
- * - ~/.opensquid/.env
11
- * - <cwd>/.env
12
- * 3. ~/.opensquid/config.json chat_connections.<platform>.bot_token
13
- *
14
- * The .env parser supports standard KEY=VALUE lines AND a tolerant
15
- * "bare token" fallback (single non-comment line, no `=`) — the user
16
- * may save just the token. Bare tokens are treated as
17
- * OPENSQUID_TELEGRAM_BOT_TOKEN.
18
- *
19
- * NEVER logs the token value. Only logs which SOURCE the active token
20
- * came from, so operators can debug "which bot is this daemon
21
- * actually using" without leaking the secret.
22
- */
23
- import { promises as fs } from "node:fs";
24
- import * as os from "node:os";
25
- import * as path from "node:path";
26
- /** In-memory cache for parsed .env files. Invalidated on each new process. */
27
- let envFileCache = null;
28
- /**
29
- * Resolve a token by priority: process.env → .env file → config.json
30
- * fallback (caller-supplied). Returns the value AND the source it
31
- * came from so the caller can log the source without exposing the
32
- * value.
33
- */
34
- export async function resolveToken(key, configJsonFallback) {
35
- // 1. process.env
36
- const envVal = process.env[key];
37
- if (envVal && envVal.trim()) {
38
- return { value: envVal.trim(), source: "env" };
39
- }
40
- // 2. .env file
41
- const envFile = await locateEnvFile();
42
- if (envFile) {
43
- const parsed = await loadEnvFile(envFile);
44
- const fileVal = parsed[key];
45
- if (fileVal && fileVal.trim()) {
46
- return { value: fileVal.trim(), source: "env-file", env_file_path: envFile };
47
- }
48
- }
49
- // 3. config.json fallback
50
- if (configJsonFallback && configJsonFallback.trim()) {
51
- return { value: configJsonFallback.trim(), source: "config-json" };
52
- }
53
- return { value: undefined, source: "missing" };
54
- }
55
- /**
56
- * Find the first existing .env file in the search order. Returns null
57
- * if none exist.
58
- */
59
- export async function locateEnvFile() {
60
- const candidates = [];
61
- if (process.env.OPENSQUID_ENV_FILE)
62
- candidates.push(process.env.OPENSQUID_ENV_FILE);
63
- const home = os.homedir();
64
- candidates.push(path.join(home, ".loop", ".env"));
65
- candidates.push(path.join(home, ".opensquid", ".env"));
66
- candidates.push(path.join(process.cwd(), ".env"));
67
- for (const c of candidates) {
68
- try {
69
- await fs.access(c);
70
- return c;
71
- }
72
- catch {
73
- // not present, keep looking
74
- }
75
- }
76
- return null;
77
- }
78
- /**
79
- * Parse a .env file into a flat string map. Supports:
80
- *
81
- * - `KEY=VALUE` lines (standard dotenv format)
82
- * - `KEY="quoted value"` (double-quoted)
83
- * - `KEY='quoted value'` (single-quoted)
84
- * - `#` comments + blank lines
85
- * - Bare-token fallback: if the file has exactly ONE non-comment
86
- * line and that line has no `=`, treat it as
87
- * OPENSQUID_TELEGRAM_BOT_TOKEN (most common shape for "user
88
- * saved just the token")
89
- *
90
- * Caches by path to avoid re-reading on every call.
91
- */
92
- export async function loadEnvFile(envPath) {
93
- if (envFileCache && envFileCache.path === envPath) {
94
- return envFileCache.parsed;
95
- }
96
- const raw = await fs.readFile(envPath, "utf8");
97
- const lines = raw.split(/\r?\n/);
98
- const out = {};
99
- const nonComment = [];
100
- for (const line of lines) {
101
- const trimmed = line.trim();
102
- if (!trimmed || trimmed.startsWith("#"))
103
- continue;
104
- nonComment.push(trimmed);
105
- }
106
- let hadKeyValue = false;
107
- for (const line of nonComment) {
108
- const eq = line.indexOf("=");
109
- if (eq === -1)
110
- continue;
111
- hadKeyValue = true;
112
- const key = line.slice(0, eq).trim();
113
- let value = line.slice(eq + 1).trim();
114
- // Strip surrounding quotes (single or double).
115
- if ((value.startsWith('"') && value.endsWith('"')) ||
116
- (value.startsWith("'") && value.endsWith("'"))) {
117
- value = value.slice(1, -1);
118
- }
119
- if (key)
120
- out[key] = value;
121
- }
122
- // Bare-token fallback: exactly one non-comment line, no =, looks
123
- // like a Telegram bot token. Treat as OPENSQUID_TELEGRAM_BOT_TOKEN.
124
- if (!hadKeyValue && nonComment.length === 1) {
125
- const bare = nonComment[0];
126
- // Telegram tokens look like <digits>:<alphanum_-> (47+ chars total).
127
- if (/^\d+:[A-Za-z0-9_-]{20,}$/.test(bare)) {
128
- out.OPENSQUID_TELEGRAM_BOT_TOKEN = bare;
129
- }
130
- }
131
- envFileCache = { path: envPath, parsed: out };
132
- return out;
133
- }
134
- /** Test-only: clear the .env cache so subsequent loads re-read disk. */
135
- export function _clearEnvFileCache() {
136
- envFileCache = null;
137
- }
@@ -1 +0,0 @@
1
- {"version":3,"file":"env-token.js","sourceRoot":"","sources":["../../src.legacy/chat/env-token.ts"],"names":[],"mappings":"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"}
@@ -1,160 +0,0 @@
1
- /**
2
- * env-token.ts tests (#148): priority + .env parsing.
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 { _clearEnvFileCache, loadEnvFile, locateEnvFile, resolveToken } from "./env-token.js";
9
- let tmpDir;
10
- const SAVED_ENV = {};
11
- function saveEnv(...keys) {
12
- for (const k of keys)
13
- SAVED_ENV[k] = process.env[k];
14
- }
15
- function restoreEnv() {
16
- for (const [k, v] of Object.entries(SAVED_ENV)) {
17
- if (v === undefined)
18
- delete process.env[k];
19
- else
20
- process.env[k] = v;
21
- }
22
- }
23
- beforeEach(async () => {
24
- tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), "opensquid-envtoken-"));
25
- saveEnv("OPENSQUID_TELEGRAM_BOT_TOKEN", "OPENSQUID_DISCORD_BOT_TOKEN", "OPENSQUID_SLACK_BOT_TOKEN", "OPENSQUID_SLACK_APP_TOKEN", "OPENSQUID_ENV_FILE", "HOME");
26
- // Wipe inherited values so tests run from a known empty state.
27
- delete process.env.OPENSQUID_TELEGRAM_BOT_TOKEN;
28
- delete process.env.OPENSQUID_DISCORD_BOT_TOKEN;
29
- delete process.env.OPENSQUID_SLACK_BOT_TOKEN;
30
- delete process.env.OPENSQUID_SLACK_APP_TOKEN;
31
- delete process.env.OPENSQUID_ENV_FILE;
32
- // Override HOME so the .env candidate paths (~/.loop/.env etc) point
33
- // at the empty tmpdir, not the real home directory where the user
34
- // may have a real .env that would taint the test.
35
- process.env.HOME = tmpDir;
36
- _clearEnvFileCache();
37
- });
38
- afterEach(async () => {
39
- restoreEnv();
40
- _clearEnvFileCache();
41
- await fs.rm(tmpDir, { recursive: true, force: true });
42
- });
43
- describe("loadEnvFile — parsing", () => {
44
- it("parses standard KEY=VALUE lines", async () => {
45
- const p = path.join(tmpDir, ".env");
46
- await fs.writeFile(p, "OPENSQUID_TELEGRAM_BOT_TOKEN=1234:abcdef\nSOMETHING_ELSE=value\n");
47
- const parsed = await loadEnvFile(p);
48
- expect(parsed.OPENSQUID_TELEGRAM_BOT_TOKEN).toBe("1234:abcdef");
49
- expect(parsed.SOMETHING_ELSE).toBe("value");
50
- });
51
- it("strips surrounding double quotes", async () => {
52
- const p = path.join(tmpDir, ".env");
53
- await fs.writeFile(p, 'KEY="quoted value with spaces"\n');
54
- const parsed = await loadEnvFile(p);
55
- expect(parsed.KEY).toBe("quoted value with spaces");
56
- });
57
- it("strips surrounding single quotes", async () => {
58
- const p = path.join(tmpDir, ".env");
59
- await fs.writeFile(p, "KEY='quoted value'\n");
60
- const parsed = await loadEnvFile(p);
61
- expect(parsed.KEY).toBe("quoted value");
62
- });
63
- it("ignores blank lines and # comments", async () => {
64
- const p = path.join(tmpDir, ".env");
65
- await fs.writeFile(p, "# top comment\n\nKEY=value\n# trailing comment\n");
66
- const parsed = await loadEnvFile(p);
67
- expect(parsed).toEqual({ KEY: "value" });
68
- });
69
- it("treats a single bare Telegram-token line as OPENSQUID_TELEGRAM_BOT_TOKEN", async () => {
70
- const p = path.join(tmpDir, ".env");
71
- await fs.writeFile(p, "8684088310:AAFgYblhOAadDN_i5osTtfkSTAgwlnneU-4\n");
72
- const parsed = await loadEnvFile(p);
73
- expect(parsed.OPENSQUID_TELEGRAM_BOT_TOKEN).toBe("8684088310:AAFgYblhOAadDN_i5osTtfkSTAgwlnneU-4");
74
- });
75
- it("does NOT treat a bare line as a token if it doesn't match the token shape", async () => {
76
- const p = path.join(tmpDir, ".env");
77
- await fs.writeFile(p, "just-some-random-text\n");
78
- const parsed = await loadEnvFile(p);
79
- expect(parsed.OPENSQUID_TELEGRAM_BOT_TOKEN).toBeUndefined();
80
- });
81
- it("does NOT use bare-line fallback if KEY=VALUE lines are also present", async () => {
82
- const p = path.join(tmpDir, ".env");
83
- await fs.writeFile(p, "OTHER=ok\n1234:abcdefghij1234567890\n");
84
- const parsed = await loadEnvFile(p);
85
- expect(parsed.OPENSQUID_TELEGRAM_BOT_TOKEN).toBeUndefined();
86
- expect(parsed.OTHER).toBe("ok");
87
- });
88
- });
89
- describe("locateEnvFile — search order", () => {
90
- it("returns the path given by OPENSQUID_ENV_FILE if it exists", async () => {
91
- const p = path.join(tmpDir, "custom.env");
92
- await fs.writeFile(p, "KEY=value\n");
93
- process.env.OPENSQUID_ENV_FILE = p;
94
- expect(await locateEnvFile()).toBe(p);
95
- });
96
- it("returns null if no .env exists in any candidate location", async () => {
97
- // Override HOME so the function looks at our empty tmpDir
98
- const savedHome = process.env.HOME;
99
- process.env.HOME = tmpDir;
100
- try {
101
- const r = await locateEnvFile();
102
- // Could still hit a cwd .env in the actual project — accept that
103
- // and only assert null when no env file at all.
104
- if (r) {
105
- expect(r).not.toBe(path.join(tmpDir, ".loop", ".env"));
106
- expect(r).not.toBe(path.join(tmpDir, ".opensquid", ".env"));
107
- }
108
- }
109
- finally {
110
- if (savedHome)
111
- process.env.HOME = savedHome;
112
- else
113
- delete process.env.HOME;
114
- }
115
- });
116
- });
117
- describe("resolveToken — priority order", () => {
118
- it("returns env-var value with source='env' when set", async () => {
119
- process.env.OPENSQUID_TELEGRAM_BOT_TOKEN = "from-env";
120
- const r = await resolveToken("OPENSQUID_TELEGRAM_BOT_TOKEN", "from-config");
121
- expect(r.value).toBe("from-env");
122
- expect(r.source).toBe("env");
123
- });
124
- it("falls back to .env file when env-var unset", async () => {
125
- const p = path.join(tmpDir, ".env");
126
- await fs.writeFile(p, "OPENSQUID_TELEGRAM_BOT_TOKEN=from-file\n");
127
- process.env.OPENSQUID_ENV_FILE = p;
128
- const r = await resolveToken("OPENSQUID_TELEGRAM_BOT_TOKEN", "from-config");
129
- expect(r.value).toBe("from-file");
130
- expect(r.source).toBe("env-file");
131
- expect(r.env_file_path).toBe(p);
132
- });
133
- it("falls back to config.json value when neither env-var nor .env set", async () => {
134
- const r = await resolveToken("OPENSQUID_TELEGRAM_BOT_TOKEN", "from-config");
135
- expect(r.value).toBe("from-config");
136
- expect(r.source).toBe("config-json");
137
- });
138
- it("returns missing when no source has a value", async () => {
139
- const r = await resolveToken("OPENSQUID_TELEGRAM_BOT_TOKEN", undefined);
140
- expect(r.value).toBeUndefined();
141
- expect(r.source).toBe("missing");
142
- });
143
- it("env-var WINS over .env even when both are set", async () => {
144
- process.env.OPENSQUID_TELEGRAM_BOT_TOKEN = "from-env";
145
- const p = path.join(tmpDir, ".env");
146
- await fs.writeFile(p, "OPENSQUID_TELEGRAM_BOT_TOKEN=from-file\n");
147
- process.env.OPENSQUID_ENV_FILE = p;
148
- const r = await resolveToken("OPENSQUID_TELEGRAM_BOT_TOKEN", "from-config");
149
- expect(r.value).toBe("from-env");
150
- expect(r.source).toBe("env");
151
- });
152
- it(".env WINS over config.json even when both have values", async () => {
153
- const p = path.join(tmpDir, ".env");
154
- await fs.writeFile(p, "OPENSQUID_TELEGRAM_BOT_TOKEN=from-file\n");
155
- process.env.OPENSQUID_ENV_FILE = p;
156
- const r = await resolveToken("OPENSQUID_TELEGRAM_BOT_TOKEN", "from-config");
157
- expect(r.value).toBe("from-file");
158
- expect(r.source).toBe("env-file");
159
- });
160
- });
@@ -1,30 +0,0 @@
1
- /**
2
- * Build a ChatGateway from `~/.opensquid/config.json`'s
3
- * `chat_connections` block. Skips adapters whose tokens are missing —
4
- * opensquid works with zero, one, or all three chat platforms wired.
5
- *
6
- * Per-platform adapter modules (telegram/discord/slack) are imported
7
- * dynamically here so the factory doesn't pull all three SDK trees
8
- * into the cold-start path. Each adapter's own dynamic-import of its
9
- * SDK runs only inside `.start()`.
10
- */
11
- import { ChatGateway } from "./gateway.js";
12
- import type { ChatConnectionsConfig } from "./config.js";
13
- export interface BuildOptions {
14
- dataRoot?: string;
15
- /** Inject a pre-loaded config (skips disk read). For tests. */
16
- config?: ChatConnectionsConfig;
17
- }
18
- export interface BuildResult {
19
- gateway: ChatGateway;
20
- /** Platforms that ended up in the gateway. */
21
- activated: Array<"telegram" | "discord" | "slack">;
22
- /** Validation issues — surfaced but non-fatal for partial activation. */
23
- issues: Array<{
24
- platform: string;
25
- field: string;
26
- problem: string;
27
- }>;
28
- }
29
- export declare function buildChatGateway(opts?: BuildOptions): Promise<BuildResult>;
30
- //# sourceMappingURL=factory.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../src.legacy/chat/factory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,EAAE,WAAW,EAAoB,MAAM,cAAc,CAAC;AAE7D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAEzD,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,+DAA+D;IAC/D,MAAM,CAAC,EAAE,qBAAqB,CAAC;CAChC;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,WAAW,CAAC;IACrB,8CAA8C;IAC9C,SAAS,EAAE,KAAK,CAAC,UAAU,GAAG,SAAS,GAAG,OAAO,CAAC,CAAC;IACnD,yEAAyE;IACzE,MAAM,EAAE,KAAK,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACrE;AAED,wBAAsB,gBAAgB,CAAC,IAAI,GAAE,YAAiB,GAAG,OAAO,CAAC,WAAW,CAAC,CA+CpF"}
@@ -1,50 +0,0 @@
1
- /**
2
- * Build a ChatGateway from `~/.opensquid/config.json`'s
3
- * `chat_connections` block. Skips adapters whose tokens are missing —
4
- * opensquid works with zero, one, or all three chat platforms wired.
5
- *
6
- * Per-platform adapter modules (telegram/discord/slack) are imported
7
- * dynamically here so the factory doesn't pull all three SDK trees
8
- * into the cold-start path. Each adapter's own dynamic-import of its
9
- * SDK runs only inside `.start()`.
10
- */
11
- import { ChatGateway, ChatGatewayError } from "./gateway.js";
12
- import { loadChatConfig, validateChatConfig } from "./config.js";
13
- export async function buildChatGateway(opts = {}) {
14
- const config = opts.config ?? (await loadChatConfig(opts.dataRoot));
15
- const issues = validateChatConfig(config);
16
- const adapters = [];
17
- const activated = [];
18
- // Each block: only activate if (a) config block exists AND (b) no
19
- // validation issue against this platform's tokens. An issue here
20
- // means the user has a partial config (e.g. typo'd token) — better
21
- // to skip with a logged warning than throw and prevent the other
22
- // adapters from working.
23
- if (config.telegram && !issues.some((i) => i.platform === "telegram")) {
24
- const { TelegramAdapter } = await import("./adapters/telegram.js");
25
- adapters.push(new TelegramAdapter(config.telegram));
26
- activated.push("telegram");
27
- }
28
- if (config.discord && !issues.some((i) => i.platform === "discord")) {
29
- const { DiscordAdapter } = await import("./adapters/discord.js");
30
- adapters.push(new DiscordAdapter(config.discord));
31
- activated.push("discord");
32
- }
33
- if (config.slack && !issues.some((i) => i.platform === "slack")) {
34
- const { SlackAdapter } = await import("./adapters/slack.js");
35
- adapters.push(new SlackAdapter(config.slack));
36
- activated.push("slack");
37
- }
38
- // Throw when the user clearly mis-configured a token. All three
39
- // platforms are now implemented (v0.7c), so any validation issue
40
- // against a configured platform is a real problem.
41
- const blockingIssues = issues.filter((i) => (i.platform === "telegram" && !!config.telegram) ||
42
- (i.platform === "discord" && !!config.discord) ||
43
- (i.platform === "slack" && !!config.slack));
44
- if (blockingIssues.length > 0 && adapters.length === 0) {
45
- throw new ChatGatewayError("chat connections configured but failed validation — see issues", `validation: ${blockingIssues
46
- .map((i) => `${i.platform}.${i.field}: ${i.problem}`)
47
- .join("; ")}`);
48
- }
49
- return { gateway: new ChatGateway(adapters), activated, issues };
50
- }
@@ -1 +0,0 @@
1
- {"version":3,"file":"factory.js","sourceRoot":"","sources":["../../src.legacy/chat/factory.ts"],"names":[],"mappings":"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"}
@@ -1,55 +0,0 @@
1
- import { describe, expect, it, vi } from "vitest";
2
- import { ChatGatewayError } from "./gateway.js";
3
- import { buildChatGateway } from "./factory.js";
4
- describe("buildChatGateway", () => {
5
- it("returns an empty gateway when no chat config is present", async () => {
6
- const result = await buildChatGateway({ config: {} });
7
- expect(result.activated).toEqual([]);
8
- expect(result.gateway.activePlatforms()).toEqual([]);
9
- expect(result.issues).toEqual([]);
10
- });
11
- it("v0.7c: activates all three platforms when all are validly configured", async () => {
12
- const result = await buildChatGateway({
13
- config: {
14
- telegram: { bot_token: "123456:ABC-DEF1234" },
15
- discord: { bot_token: "MTAxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" },
16
- slack: { bot_token: "xoxb-1-2-3", app_token: "xapp-1-2-3" },
17
- },
18
- });
19
- expect(result.activated.sort()).toEqual(["discord", "slack", "telegram"]);
20
- });
21
- it("v0.7c: activates discord + slack independently of telegram", async () => {
22
- const result = await buildChatGateway({
23
- config: {
24
- discord: { bot_token: "MTAxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" },
25
- slack: { bot_token: "xoxb-1-2-3", app_token: "xapp-1-2-3" },
26
- },
27
- });
28
- expect(result.activated.sort()).toEqual(["discord", "slack"]);
29
- });
30
- it("activates telegram when its config block is valid", async () => {
31
- const result = await buildChatGateway({
32
- config: { telegram: { bot_token: "123456:ABC-DEF1234" } },
33
- });
34
- expect(result.activated).toEqual(["telegram"]);
35
- expect(result.gateway.activePlatforms()).toEqual(["telegram"]);
36
- });
37
- it("skips telegram with invalid token format AND throws because no other adapter activated", async () => {
38
- await expect(buildChatGateway({
39
- config: { telegram: { bot_token: "not-a-real-format" } },
40
- })).rejects.toThrow(ChatGatewayError);
41
- });
42
- it("partial config: telegram valid + slack invalid → telegram activates, slack issue logged", async () => {
43
- const warn = vi.spyOn(console, "warn").mockImplementation(() => { });
44
- const result = await buildChatGateway({
45
- config: {
46
- telegram: { bot_token: "123456:ABC-DEF1234" },
47
- // slack with wrong-shape tokens triggers validation issues
48
- slack: { bot_token: "wrong-prefix", app_token: "also-wrong" },
49
- },
50
- });
51
- expect(result.activated).toEqual(["telegram"]);
52
- expect(result.issues.find((i) => i.platform === "slack")).toBeTruthy();
53
- warn.mockRestore();
54
- });
55
- });