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,98 +0,0 @@
1
- /**
2
- * Chat-connection configuration loaded from
3
- * `~/.opensquid/config.json` `chat_connections` block. Per-platform
4
- * blocks are independent — having one configured doesn't require any
5
- * of the others.
6
- *
7
- * Shape:
8
- * ```json
9
- * {
10
- * "version": 1,
11
- * "chat_connections": {
12
- * "telegram": { "bot_token": "...", "allowlist_chat_ids": ["8075471258"] },
13
- * "discord": { "bot_token": "...", "allowlist_user_ids": ["..."] },
14
- * "slack": { "bot_token": "xoxb-...", "app_token": "xapp-...", "allowlist_user_ids": ["..."] }
15
- * }
16
- * }
17
- * ```
18
- *
19
- * Tokens are stored in cleartext in `config.json`; advise users to
20
- * `chmod 600 ~/.opensquid/config.json` (the file lives in a hidden
21
- * dir already, so this is a small additional hardening — not a real
22
- * defense against a compromised user account).
23
- */
24
- import { type EnvSource } from "./env-token.js";
25
- import type { ChatPlatform } from "./gateway.js";
26
- export interface TelegramConfig {
27
- bot_token: string;
28
- /**
29
- * Chat ids the bot will accept messages from. Empty = accept from any
30
- * chat (NOT recommended — the bot is publicly addressable via Telegram).
31
- */
32
- allowlist_chat_ids?: string[];
33
- }
34
- export interface DiscordConfig {
35
- bot_token: string;
36
- /** User ids whose DMs / @-mentions the bot will respond to. Empty = bot owner only. */
37
- allowlist_user_ids?: string[];
38
- }
39
- export interface SlackConfig {
40
- /** Bot User OAuth Token — starts with `xoxb-`. Used for Web API calls. */
41
- bot_token: string;
42
- /**
43
- * App-level Token — starts with `xapp-`. Required for Socket Mode
44
- * (the no-public-ingress connection style we use).
45
- */
46
- app_token: string;
47
- /** User ids the bot will respond to. Empty = bot owner only. */
48
- allowlist_user_ids?: string[];
49
- }
50
- export interface ChatConnectionsConfig {
51
- telegram?: TelegramConfig;
52
- discord?: DiscordConfig;
53
- slack?: SlackConfig;
54
- }
55
- export declare function loadChatConfig(dataRoot?: string): Promise<ChatConnectionsConfig>;
56
- export interface ChatTokenSources {
57
- telegram?: EnvSource;
58
- discord?: EnvSource;
59
- slack_bot?: EnvSource;
60
- slack_app?: EnvSource;
61
- env_file_path?: string;
62
- }
63
- /**
64
- * Like loadChatConfig but also returns which source each token came
65
- * from. The chat-daemon uses this to log "[chat-daemon] telegram
66
- * bot_token source: env-file (~/.loop/.env)" so operators can debug
67
- * "which bot is this daemon actually using" without exposing the
68
- * secret.
69
- */
70
- export declare function loadChatConfigWithSources(dataRoot?: string): Promise<{
71
- config: ChatConnectionsConfig;
72
- sources: ChatTokenSources;
73
- }>;
74
- export declare function saveChatConfig(chat: ChatConnectionsConfig, dataRoot?: string): Promise<void>;
75
- /**
76
- * Set a single platform's config block. Convenience for the future
77
- * `opensquid chat setup <platform>` wizard.
78
- */
79
- export declare function setPlatformConfig<P extends ChatPlatform>(platform: P, config: P extends "telegram" ? TelegramConfig : P extends "discord" ? DiscordConfig : SlackConfig, dataRoot?: string): Promise<void>;
80
- /**
81
- * Forget a single platform's config block. Reverts that platform to
82
- * inactive on the next opensquid restart.
83
- */
84
- export declare function forgetPlatformConfig(platform: ChatPlatform, dataRoot?: string): Promise<void>;
85
- export interface ConfigValidationIssue {
86
- platform: ChatPlatform;
87
- field: string;
88
- problem: string;
89
- }
90
- /**
91
- * Surface obvious config errors without trying to validate the token
92
- * against the live API (that happens on adapter start). Catches
93
- * empty-string / undefined / shape mistakes before opening a connection.
94
- */
95
- export declare function validateChatConfig(config: ChatConnectionsConfig): ConfigValidationIssue[];
96
- /** Which platforms have any non-empty config block? */
97
- export declare function configuredPlatforms(config: ChatConnectionsConfig): ChatPlatform[];
98
- //# sourceMappingURL=config.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src.legacy/chat/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAKH,OAAO,EAAgB,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC9D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAMjD,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC/B;AAED,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,uFAAuF;IACvF,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC/B;AAED,MAAM,WAAW,WAAW;IAC1B,0EAA0E;IAC1E,SAAS,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,SAAS,EAAE,MAAM,CAAC;IAClB,gEAAgE;IAChE,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC/B;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,KAAK,CAAC,EAAE,WAAW,CAAC;CACrB;AAcD,wBAAsB,cAAc,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAQtF;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;GAMG;AACH,wBAAsB,yBAAyB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAC1E,MAAM,EAAE,qBAAqB,CAAC;IAC9B,OAAO,EAAE,gBAAgB,CAAC;CAC3B,CAAC,CAGD;AA+CD,wBAAsB,cAAc,CAClC,IAAI,EAAE,qBAAqB,EAC3B,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC,CAIf;AAED;;;GAGG;AACH,wBAAsB,iBAAiB,CAAC,CAAC,SAAS,YAAY,EAC5D,QAAQ,EAAE,CAAC,EACX,MAAM,EAAE,CAAC,SAAS,UAAU,GAAG,cAAc,GAAG,CAAC,SAAS,SAAS,GAAG,aAAa,GAAG,WAAW,EACjG,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC,CAKf;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CACxC,QAAQ,EAAE,YAAY,EACtB,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC,CAIf;AAMD,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,YAAY,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,qBAAqB,GAAG,qBAAqB,EAAE,CAyDzF;AAED,uDAAuD;AACvD,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,qBAAqB,GAAG,YAAY,EAAE,CAMjF"}
@@ -1,185 +0,0 @@
1
- /**
2
- * Chat-connection configuration loaded from
3
- * `~/.opensquid/config.json` `chat_connections` block. Per-platform
4
- * blocks are independent — having one configured doesn't require any
5
- * of the others.
6
- *
7
- * Shape:
8
- * ```json
9
- * {
10
- * "version": 1,
11
- * "chat_connections": {
12
- * "telegram": { "bot_token": "...", "allowlist_chat_ids": ["8075471258"] },
13
- * "discord": { "bot_token": "...", "allowlist_user_ids": ["..."] },
14
- * "slack": { "bot_token": "xoxb-...", "app_token": "xapp-...", "allowlist_user_ids": ["..."] }
15
- * }
16
- * }
17
- * ```
18
- *
19
- * Tokens are stored in cleartext in `config.json`; advise users to
20
- * `chmod 600 ~/.opensquid/config.json` (the file lives in a hidden
21
- * dir already, so this is a small additional hardening — not a real
22
- * defense against a compromised user account).
23
- */
24
- import { loadConfig, saveConfig } from "../config.js";
25
- import { resolveToken } from "./env-token.js";
26
- export async function loadChatConfig(dataRoot) {
27
- const raw = (await loadConfig(dataRoot));
28
- // 0.7.5 (#148): overlay env-var + .env tokens atop config.json. Lets
29
- // the user park a Telegram bot token in ~/.loop/.env so opensquid
30
- // uses a DIFFERENT bot than Claude Code's plugin:telegram (no 409
31
- // collision possible — they're different bots). Priority is
32
- // env > .env > config.json (per resolveToken).
33
- return overlayEnvTokens(raw.chat_connections ?? {});
34
- }
35
- /**
36
- * Like loadChatConfig but also returns which source each token came
37
- * from. The chat-daemon uses this to log "[chat-daemon] telegram
38
- * bot_token source: env-file (~/.loop/.env)" so operators can debug
39
- * "which bot is this daemon actually using" without exposing the
40
- * secret.
41
- */
42
- export async function loadChatConfigWithSources(dataRoot) {
43
- const raw = (await loadConfig(dataRoot));
44
- return overlayEnvTokensWithSources(raw.chat_connections ?? {});
45
- }
46
- async function overlayEnvTokens(base) {
47
- const { config } = await overlayEnvTokensWithSources(base);
48
- return config;
49
- }
50
- async function overlayEnvTokensWithSources(base) {
51
- const out = { ...base };
52
- const sources = {};
53
- // Telegram
54
- const tg = await resolveToken("OPENSQUID_TELEGRAM_BOT_TOKEN", base.telegram?.bot_token);
55
- if (tg.value) {
56
- out.telegram = { ...(base.telegram ?? {}), bot_token: tg.value };
57
- sources.telegram = tg.source;
58
- if (tg.env_file_path)
59
- sources.env_file_path = tg.env_file_path;
60
- }
61
- // Discord
62
- const dc = await resolveToken("OPENSQUID_DISCORD_BOT_TOKEN", base.discord?.bot_token);
63
- if (dc.value) {
64
- out.discord = { ...(base.discord ?? {}), bot_token: dc.value };
65
- sources.discord = dc.source;
66
- if (dc.env_file_path && !sources.env_file_path)
67
- sources.env_file_path = dc.env_file_path;
68
- }
69
- // Slack: needs both bot_token + app_token
70
- const sb = await resolveToken("OPENSQUID_SLACK_BOT_TOKEN", base.slack?.bot_token);
71
- const sa = await resolveToken("OPENSQUID_SLACK_APP_TOKEN", base.slack?.app_token);
72
- if (sb.value || sa.value || base.slack) {
73
- out.slack = {
74
- ...(base.slack ?? { bot_token: "", app_token: "" }),
75
- bot_token: sb.value ?? base.slack?.bot_token ?? "",
76
- app_token: sa.value ?? base.slack?.app_token ?? "",
77
- };
78
- sources.slack_bot = sb.source;
79
- sources.slack_app = sa.source;
80
- if (sb.env_file_path && !sources.env_file_path)
81
- sources.env_file_path = sb.env_file_path;
82
- if (sa.env_file_path && !sources.env_file_path)
83
- sources.env_file_path = sa.env_file_path;
84
- }
85
- return { config: out, sources };
86
- }
87
- export async function saveChatConfig(chat, dataRoot) {
88
- const raw = (await loadConfig(dataRoot));
89
- raw.chat_connections = chat;
90
- await saveConfig(raw, dataRoot);
91
- }
92
- /**
93
- * Set a single platform's config block. Convenience for the future
94
- * `opensquid chat setup <platform>` wizard.
95
- */
96
- export async function setPlatformConfig(platform, config, dataRoot) {
97
- const chat = await loadChatConfig(dataRoot);
98
- // Cast narrows correctly per the conditional type above.
99
- chat[platform] = config;
100
- await saveChatConfig(chat, dataRoot);
101
- }
102
- /**
103
- * Forget a single platform's config block. Reverts that platform to
104
- * inactive on the next opensquid restart.
105
- */
106
- export async function forgetPlatformConfig(platform, dataRoot) {
107
- const chat = await loadChatConfig(dataRoot);
108
- delete chat[platform];
109
- await saveChatConfig(chat, dataRoot);
110
- }
111
- /**
112
- * Surface obvious config errors without trying to validate the token
113
- * against the live API (that happens on adapter start). Catches
114
- * empty-string / undefined / shape mistakes before opening a connection.
115
- */
116
- export function validateChatConfig(config) {
117
- const issues = [];
118
- if (config.telegram) {
119
- if (!config.telegram.bot_token?.trim()) {
120
- issues.push({
121
- platform: "telegram",
122
- field: "bot_token",
123
- problem: "empty — get one from @BotFather and run `opensquid chat setup telegram`",
124
- });
125
- }
126
- else if (!/^\d+:[A-Za-z0-9_-]+$/.test(config.telegram.bot_token)) {
127
- issues.push({
128
- platform: "telegram",
129
- field: "bot_token",
130
- problem: "wrong format — should look like '123456:ABC-DEF...'",
131
- });
132
- }
133
- }
134
- if (config.discord) {
135
- if (!config.discord.bot_token?.trim()) {
136
- issues.push({
137
- platform: "discord",
138
- field: "bot_token",
139
- problem: "empty — Discord Developer Portal → Application → Bot → Reset Token",
140
- });
141
- }
142
- }
143
- if (config.slack) {
144
- if (!config.slack.bot_token?.trim()) {
145
- issues.push({
146
- platform: "slack",
147
- field: "bot_token",
148
- problem: "empty — api.slack.com/apps → OAuth & Permissions → Bot User OAuth Token (xoxb-...)",
149
- });
150
- }
151
- else if (!config.slack.bot_token.startsWith("xoxb-")) {
152
- issues.push({
153
- platform: "slack",
154
- field: "bot_token",
155
- problem: "should start with 'xoxb-' (Bot User OAuth Token, not Workspace token)",
156
- });
157
- }
158
- if (!config.slack.app_token?.trim()) {
159
- issues.push({
160
- platform: "slack",
161
- field: "app_token",
162
- problem: "empty — required for Socket Mode; api.slack.com/apps → Basic Information → App-Level Tokens (xapp-...)",
163
- });
164
- }
165
- else if (!config.slack.app_token.startsWith("xapp-")) {
166
- issues.push({
167
- platform: "slack",
168
- field: "app_token",
169
- problem: "should start with 'xapp-' (App-Level Token, NOT Bot User OAuth Token)",
170
- });
171
- }
172
- }
173
- return issues;
174
- }
175
- /** Which platforms have any non-empty config block? */
176
- export function configuredPlatforms(config) {
177
- const out = [];
178
- if (config.telegram)
179
- out.push("telegram");
180
- if (config.discord)
181
- out.push("discord");
182
- if (config.slack)
183
- out.push("slack");
184
- return out;
185
- }
@@ -1 +0,0 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src.legacy/chat/config.ts"],"names":[],"mappings":"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"}
@@ -1,17 +0,0 @@
1
- /**
2
- * Resolve the active project's UUID for chat-routing operations
3
- * (v0.7.1 Phase E).
4
- *
5
- * Strategy:
6
- * 1. If `OPENSQUID_PROJECT_UUID` env var is set, use it verbatim.
7
- * 2. Walk up from `cwd` looking for `.opensquid/project.json` and
8
- * return its uuid.
9
- * 3. Return null — the caller decides whether to error or fall back
10
- * to the orphan path.
11
- *
12
- * Per-tool fallback: tools that need a project uuid surface a clear
13
- * error message instead of silently routing to orphan; the user can
14
- * run `opensquid project init` to create a card if missing.
15
- */
16
- export declare function resolveActiveProjectUuid(cwd?: string): Promise<string | null>;
17
- //# sourceMappingURL=active-project.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"active-project.d.ts","sourceRoot":"","sources":["../../../src.legacy/chat/daemon/active-project.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH,wBAAsB,wBAAwB,CAC5C,GAAG,GAAE,MAAsB,GAC1B,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAIxB"}
@@ -1,23 +0,0 @@
1
- /**
2
- * Resolve the active project's UUID for chat-routing operations
3
- * (v0.7.1 Phase E).
4
- *
5
- * Strategy:
6
- * 1. If `OPENSQUID_PROJECT_UUID` env var is set, use it verbatim.
7
- * 2. Walk up from `cwd` looking for `.opensquid/project.json` and
8
- * return its uuid.
9
- * 3. Return null — the caller decides whether to error or fall back
10
- * to the orphan path.
11
- *
12
- * Per-tool fallback: tools that need a project uuid surface a clear
13
- * error message instead of silently routing to orphan; the user can
14
- * run `opensquid project init` to create a card if missing.
15
- */
16
- import { findProjectCard } from "../../project.js";
17
- export async function resolveActiveProjectUuid(cwd = process.cwd()) {
18
- if (process.env.OPENSQUID_PROJECT_UUID)
19
- return process.env.OPENSQUID_PROJECT_UUID;
20
- const found = await findProjectCard(cwd);
21
- return found?.card.uuid ?? null;
22
- }
23
- //# sourceMappingURL=active-project.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"active-project.js","sourceRoot":"","sources":["../../../src.legacy/chat/daemon/active-project.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAEnD,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC5C,MAAc,OAAO,CAAC,GAAG,EAAE;IAE3B,IAAI,OAAO,CAAC,GAAG,CAAC,sBAAsB;QAAE,OAAO,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC;IAClF,MAAM,KAAK,GAAG,MAAM,eAAe,CAAC,GAAG,CAAC,CAAC;IACzC,OAAO,KAAK,EAAE,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC;AAClC,CAAC"}
@@ -1,40 +0,0 @@
1
- /**
2
- * Daemon auto-spawn from MCP server (v0.7.1 Phase D).
3
- *
4
- * On MCP server boot, we want to opportunistically ensure the chat-
5
- * daemon is running so chat_send routes through the daemon (Phase B)
6
- * and inbound messages land in per-project inboxes (Phase C). Without
7
- * auto-spawn the user has to remember `opensquid chat-daemon start`
8
- * once per machine after every reboot, which defeats the
9
- * "unconscious tool" goal.
10
- *
11
- * Behavior:
12
- * - No-op if no chat_connections configured (no point in a daemon
13
- * with zero adapters).
14
- * - No-op if daemon already running.
15
- * - Otherwise try to acquire an atomic spawn lock (fs.open(lock,
16
- * 'wx') — EEXIST = another MCP server is spawning). If acquired,
17
- * spawn and release. If not, wait briefly for the other process's
18
- * pidfile to appear.
19
- * - Always async fire-and-forget — never blocks MCP server boot.
20
- *
21
- * Stale lock handling: a lockfile older than ~15s is assumed stale
22
- * (longer than the plausible spawn time) and is unlinked before
23
- * retry. Prevents permanent jam if a previous spawner crashed.
24
- */
25
- export interface AutoSpawnResult {
26
- status: "spawned" | "already_running" | "waited_for_peer" | "no_config" | "skipped" | "error";
27
- pid?: number;
28
- error?: string;
29
- }
30
- /**
31
- * Best-effort: ensure a chat-daemon is running. Returns immediately
32
- * on the no-op paths (no config, already running, peer-spawning).
33
- * Never throws — callers can fire-and-forget without try/catch.
34
- */
35
- export declare function ensureDaemonRunning(opts?: {
36
- dataRoot?: string;
37
- /** For tests: override the entrypoint passed to startDaemon. */
38
- entrypoint?: string;
39
- }): Promise<AutoSpawnResult>;
40
- //# sourceMappingURL=autospawn.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"autospawn.d.ts","sourceRoot":"","sources":["../../../src.legacy/chat/daemon/autospawn.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAaH,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,SAAS,GAAG,iBAAiB,GAAG,iBAAiB,GAAG,WAAW,GAAG,SAAS,GAAG,OAAO,CAAC;IAC9F,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;GAIG;AACH,wBAAsB,mBAAmB,CACvC,IAAI,GAAE;IACJ,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gEAAgE;IAChE,UAAU,CAAC,EAAE,MAAM,CAAC;CAChB,GACL,OAAO,CAAC,eAAe,CAAC,CAyC1B"}
@@ -1,129 +0,0 @@
1
- /**
2
- * Daemon auto-spawn from MCP server (v0.7.1 Phase D).
3
- *
4
- * On MCP server boot, we want to opportunistically ensure the chat-
5
- * daemon is running so chat_send routes through the daemon (Phase B)
6
- * and inbound messages land in per-project inboxes (Phase C). Without
7
- * auto-spawn the user has to remember `opensquid chat-daemon start`
8
- * once per machine after every reboot, which defeats the
9
- * "unconscious tool" goal.
10
- *
11
- * Behavior:
12
- * - No-op if no chat_connections configured (no point in a daemon
13
- * with zero adapters).
14
- * - No-op if daemon already running.
15
- * - Otherwise try to acquire an atomic spawn lock (fs.open(lock,
16
- * 'wx') — EEXIST = another MCP server is spawning). If acquired,
17
- * spawn and release. If not, wait briefly for the other process's
18
- * pidfile to appear.
19
- * - Always async fire-and-forget — never blocks MCP server boot.
20
- *
21
- * Stale lock handling: a lockfile older than ~15s is assumed stale
22
- * (longer than the plausible spawn time) and is unlinked before
23
- * retry. Prevents permanent jam if a previous spawner crashed.
24
- */
25
- import { promises as fs } from "node:fs";
26
- import * as path from "node:path";
27
- import { resolveDataRoot } from "../../codex/store.js";
28
- import { loadChatConfig } from "../config.js";
29
- import { startDaemon, status } from "./lifecycle.js";
30
- const STALE_LOCK_AGE_MS = 15_000;
31
- const PIDFILE_WAIT_MS = 8_000;
32
- const PIDFILE_POLL_INTERVAL_MS = 100;
33
- /**
34
- * Best-effort: ensure a chat-daemon is running. Returns immediately
35
- * on the no-op paths (no config, already running, peer-spawning).
36
- * Never throws — callers can fire-and-forget without try/catch.
37
- */
38
- export async function ensureDaemonRunning(opts = {}) {
39
- try {
40
- const config = await loadChatConfig(opts.dataRoot);
41
- if (!config.telegram && !config.discord && !config.slack) {
42
- return { status: "no_config" };
43
- }
44
- const s = await status(opts.dataRoot);
45
- if (s.running)
46
- return { status: "already_running", pid: s.pid };
47
- const lockPath = spawnLockPath(opts.dataRoot);
48
- const acquired = await tryAcquireLock(lockPath);
49
- if (acquired) {
50
- try {
51
- // Re-check after acquiring the lock; a peer might have
52
- // finished spawning between our first status() and lock
53
- // acquisition.
54
- const s2 = await status(opts.dataRoot);
55
- if (s2.running)
56
- return { status: "already_running", pid: s2.pid };
57
- const res = await startDaemon({
58
- dataRoot: opts.dataRoot,
59
- entrypoint: opts.entrypoint,
60
- });
61
- return res.already_running
62
- ? { status: "already_running", pid: res.pid }
63
- : { status: "spawned", pid: res.pid };
64
- }
65
- finally {
66
- await releaseLock(lockPath);
67
- }
68
- }
69
- // Another MCP server has the lock — wait for the pidfile to
70
- // appear, then trust that daemon.
71
- const pid = await waitForPeerSpawn(opts.dataRoot);
72
- if (pid !== null)
73
- return { status: "waited_for_peer", pid };
74
- return { status: "error", error: "peer spawn timed out" };
75
- }
76
- catch (err) {
77
- return {
78
- status: "error",
79
- error: err instanceof Error ? err.message : String(err),
80
- };
81
- }
82
- }
83
- function spawnLockPath(dataRoot) {
84
- return path.join(resolveDataRoot(dataRoot), "chat-daemon.spawn.lock");
85
- }
86
- async function tryAcquireLock(lockPath) {
87
- await fs.mkdir(path.dirname(lockPath), { recursive: true });
88
- try {
89
- const fd = await fs.open(lockPath, "wx");
90
- await fd.write(`${process.pid}\n`);
91
- await fd.close();
92
- return true;
93
- }
94
- catch (err) {
95
- if (err.code !== "EEXIST")
96
- throw err;
97
- // Lock exists. Check age — if stale, unlink and retry once.
98
- try {
99
- const stat = await fs.stat(lockPath);
100
- if (Date.now() - stat.mtimeMs > STALE_LOCK_AGE_MS) {
101
- await fs.unlink(lockPath).catch(() => {
102
- /* race */
103
- });
104
- return tryAcquireLock(lockPath);
105
- }
106
- }
107
- catch {
108
- /* lock vanished between EEXIST and stat — retry */
109
- return tryAcquireLock(lockPath);
110
- }
111
- return false;
112
- }
113
- }
114
- async function releaseLock(lockPath) {
115
- await fs.unlink(lockPath).catch(() => {
116
- /* race-tolerant */
117
- });
118
- }
119
- async function waitForPeerSpawn(dataRoot) {
120
- const deadline = Date.now() + PIDFILE_WAIT_MS;
121
- while (Date.now() < deadline) {
122
- const s = await status(dataRoot);
123
- if (s.running)
124
- return s.pid;
125
- await new Promise((r) => setTimeout(r, PIDFILE_POLL_INTERVAL_MS));
126
- }
127
- return null;
128
- }
129
- //# sourceMappingURL=autospawn.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"autospawn.js","sourceRoot":"","sources":["../../../src.legacy/chat/daemon/autospawn.ts"],"names":[],"mappings":"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"}
@@ -1,112 +0,0 @@
1
- /**
2
- * autospawn.test.ts (v0.7.1 Phase D) — exercises ensureDaemonRunning
3
- * decision branches against real tmpdirs. Uses the real lifecycle
4
- * primitives so the spawn behavior is end-to-end realistic.
5
- */
6
- import { promises as fs } from "node:fs";
7
- import * as os from "node:os";
8
- import * as path from "node:path";
9
- import { afterEach, beforeEach, describe, expect, it } from "vitest";
10
- import { ensureDaemonRunning } from "./autospawn.js";
11
- import { saveChatConfig } from "../config.js";
12
- import { stopDaemon } from "./lifecycle.js";
13
- // Resolve to the built dist/index.js so the spawned worker runs the
14
- // real chat-daemon-worker subcommand (vitest's runner doesn't have it).
15
- const REPO_ROOT = path.resolve(__dirname, "../../..");
16
- const ENTRYPOINT = path.join(REPO_ROOT, "dist", "index.js");
17
- let tmpRoot;
18
- let prevHome;
19
- let prevOsHome;
20
- beforeEach(async () => {
21
- tmpRoot = await fs.mkdtemp(path.join(os.tmpdir(), "opensquid-autospawn-test-"));
22
- prevHome = process.env.OPENSQUID_HOME;
23
- prevOsHome = process.env.HOME;
24
- process.env.OPENSQUID_HOME = tmpRoot;
25
- // 0.7.5 (#148): override HOME so the env-token .env candidate paths
26
- // (~/.loop/.env etc) point at the empty tmpdir, not the real home
27
- // where a user-saved .env would synthesize a telegram config and
28
- // turn what should be `no_config` into `spawned`.
29
- process.env.HOME = tmpRoot;
30
- });
31
- afterEach(async () => {
32
- // Best-effort stop any daemon left behind by a failing test.
33
- try {
34
- await stopDaemon({ dataRoot: tmpRoot });
35
- }
36
- catch {
37
- /* ignore */
38
- }
39
- if (prevHome === undefined)
40
- delete process.env.OPENSQUID_HOME;
41
- else
42
- process.env.OPENSQUID_HOME = prevHome;
43
- if (prevOsHome === undefined)
44
- delete process.env.HOME;
45
- else
46
- process.env.HOME = prevOsHome;
47
- await fs.rm(tmpRoot, { recursive: true, force: true });
48
- });
49
- describe("ensureDaemonRunning — decision branches", () => {
50
- it("returns no_config when chat_connections is empty", async () => {
51
- const res = await ensureDaemonRunning({ dataRoot: tmpRoot, entrypoint: ENTRYPOINT });
52
- expect(res.status).toBe("no_config");
53
- });
54
- // The spawn-success path requires a real Telegram bot token (or the
55
- // adapter start fails and the worker exits — autospawn correctly
56
- // reports "error"). The full spawn path is already covered by
57
- // lifecycle.test.ts (empty config → worker parks idle → spawn
58
- // succeeds without network) and by manual end-to-end smoke. Here
59
- // we exercise the autospawn-specific behaviors that DON'T require
60
- // a real token: lock release, stale-lock cleanup, and decision
61
- // logic with no config.
62
- it("releases the spawn lock after the attempt (regardless of spawn outcome)", async () => {
63
- await saveChatConfig({ telegram: { bot_token: "1234:fake-token-for-test-only-no-network" } }, tmpRoot);
64
- await ensureDaemonRunning({ dataRoot: tmpRoot, entrypoint: ENTRYPOINT });
65
- const lockPath = path.join(tmpRoot, "chat-daemon.spawn.lock");
66
- const lockExists = await fs
67
- .access(lockPath)
68
- .then(() => true)
69
- .catch(() => false);
70
- expect(lockExists).toBe(false);
71
- }, 15000);
72
- it("clears a stale spawn lock (older than threshold) and re-attempts", async () => {
73
- await saveChatConfig({ telegram: { bot_token: "1234:fake-token-for-test-only-no-network" } }, tmpRoot);
74
- // Create an aged lockfile by writing it then back-dating its mtime.
75
- const lockPath = path.join(tmpRoot, "chat-daemon.spawn.lock");
76
- await fs.writeFile(lockPath, "stale\n");
77
- const ancient = new Date(Date.now() - 60_000);
78
- await fs.utimes(lockPath, ancient, ancient);
79
- const res = await ensureDaemonRunning({ dataRoot: tmpRoot, entrypoint: ENTRYPOINT });
80
- // Regardless of spawn success (depends on whether the fake token
81
- // is accepted), the stale lock should be gone afterwards.
82
- const stillExists = await fs
83
- .access(lockPath)
84
- .then(() => true)
85
- .catch(() => false);
86
- expect(stillExists).toBe(false);
87
- // Status must be a real decision outcome, not 'no_config'.
88
- expect(res.status).not.toBe("no_config");
89
- }, 15000);
90
- it("returns already_running when called against a manually-started daemon", async () => {
91
- // No chat config → empty-config daemon parks idle without a network call.
92
- // We start the daemon ourselves, then call ensureDaemonRunning
93
- // with config present to force the autospawn check path.
94
- const { startDaemon } = await import("./lifecycle.js");
95
- await startDaemon({ dataRoot: tmpRoot, entrypoint: ENTRYPOINT });
96
- // Configure chat AFTER spawning so the daemon parks without a
97
- // token (the empty config at spawn time means no adapter starts,
98
- // but the post-hoc save lets the autospawn check find a config).
99
- await saveChatConfig({ telegram: { bot_token: "1234:fake-token-for-test-only-no-network" } }, tmpRoot);
100
- const res = await ensureDaemonRunning({ dataRoot: tmpRoot, entrypoint: ENTRYPOINT });
101
- expect(res.status).toBe("already_running");
102
- expect(res.pid).toBeGreaterThan(0);
103
- }, 15000);
104
- it("never throws on a corrupt config — surfaces as status:error", async () => {
105
- // Write a config.json that loadChatConfig will read OK but with no chat
106
- // blocks. That triggers the no_config path, not an error.
107
- await fs.writeFile(path.join(tmpRoot, "config.json"), JSON.stringify({ version: 1 }));
108
- const res = await ensureDaemonRunning({ dataRoot: tmpRoot, entrypoint: ENTRYPOINT });
109
- // No chat → no_config (not an error).
110
- expect(res.status).toBe("no_config");
111
- });
112
- });
@@ -1,18 +0,0 @@
1
- /**
2
- * Chat-daemon CLI dispatch (v0.7.1 Phase A).
3
- *
4
- * Two entry shapes:
5
- * `opensquid chat-daemon {start|stop|status}` — user-facing
6
- * `opensquid chat-daemon-worker` — internal, never type
7
- *
8
- * `start` spawns the worker as a detached child and exits. The worker
9
- * subcommand IS the long-running daemon — never invoke it manually
10
- * unless you want to inspect logs in the foreground.
11
- */
12
- export declare function runChatDaemonCli(subcommand: string, argv: string[]): Promise<number>;
13
- /**
14
- * Internal worker entrypoint — not for direct user invocation.
15
- * Called by the detached child spawned by lifecycle.startDaemon().
16
- */
17
- export declare function runChatDaemonWorker(): Promise<never>;
18
- //# sourceMappingURL=cli.d.ts.map