@phuetz/code-buddy 1.1.0 → 1.3.0

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 (381) hide show
  1. package/README.md +211 -163
  2. package/dist/agent/autonomous/agentic-coding-contract.d.ts +12 -12
  3. package/dist/agent/base-agent.d.ts +4 -0
  4. package/dist/agent/base-agent.js +6 -0
  5. package/dist/agent/codebuddy-agent.d.ts +1 -1
  6. package/dist/agent/codebuddy-agent.js +69 -14
  7. package/dist/agent/execution/agent-executor.js +122 -12
  8. package/dist/agent/execution/tool-dependency-graph.js +7 -0
  9. package/dist/agent/execution/tool-hooks.d.ts +6 -0
  10. package/dist/agent/execution/tool-hooks.js +13 -5
  11. package/dist/agent/execution/tool-selection-strategy.d.ts +11 -2
  12. package/dist/agent/execution/tool-selection-strategy.js +67 -10
  13. package/dist/agent/extended-thinking.d.ts +8 -0
  14. package/dist/agent/extended-thinking.js +27 -0
  15. package/dist/agent/facades/infrastructure-facade.d.ts +9 -2
  16. package/dist/agent/facades/infrastructure-facade.js +15 -6
  17. package/dist/agent/hermes-browser-backends.js +151 -11
  18. package/dist/agent/hermes-claw-migrate.d.ts +59 -0
  19. package/dist/agent/hermes-claw-migrate.js +427 -26
  20. package/dist/agent/hermes-parity-manifest.js +78 -71
  21. package/dist/agent/hermes-runtime-lifecycle.d.ts +67 -0
  22. package/dist/agent/hermes-runtime-lifecycle.js +468 -0
  23. package/dist/agent/middleware/index.d.ts +1 -0
  24. package/dist/agent/middleware/index.js +1 -0
  25. package/dist/agent/middleware/visual-validation-middleware.d.ts +17 -0
  26. package/dist/agent/middleware/visual-validation-middleware.js +67 -0
  27. package/dist/agent/model-benchmark.d.ts +77 -0
  28. package/dist/agent/model-benchmark.js +309 -0
  29. package/dist/agent/model-tier.d.ts +14 -0
  30. package/dist/agent/model-tier.js +71 -0
  31. package/dist/agent/multi-agent/agents/orchestrator-agent.js +17 -6
  32. package/dist/agent/multi-agent/multi-agent-system.js +3 -1
  33. package/dist/agent/multi-agent/session-fleet-bridge.d.ts +2 -0
  34. package/dist/agent/multi-agent/session-fleet-bridge.js +9 -1
  35. package/dist/agent/multi-agent/session-tools.js +22 -5
  36. package/dist/agent/reasoning/mcts.js +20 -6
  37. package/dist/agent/self-improvement/authored-artifact-gate.d.ts +18 -0
  38. package/dist/agent/self-improvement/authored-artifact-gate.js +42 -0
  39. package/dist/agent/self-improvement/authored-tool-runtime.d.ts +27 -0
  40. package/dist/agent/self-improvement/authored-tool-runtime.js +57 -0
  41. package/dist/agent/self-improvement/authored-tool-store.d.ts +24 -0
  42. package/dist/agent/self-improvement/authored-tool-store.js +57 -0
  43. package/dist/agent/self-improvement/llm-tool-proposer.d.ts +41 -0
  44. package/dist/agent/self-improvement/llm-tool-proposer.js +136 -0
  45. package/dist/agent/self-improvement/sandbox-scorer.d.ts +17 -0
  46. package/dist/agent/self-improvement/sandbox-scorer.js +43 -0
  47. package/dist/agent/self-improvement/self-knowledge.d.ts +8 -0
  48. package/dist/agent/self-improvement/self-knowledge.js +24 -0
  49. package/dist/agent/self-improvement/skill-benchmark.d.ts +9 -0
  50. package/dist/agent/self-improvement/skill-benchmark.js +22 -0
  51. package/dist/agent/self-improvement/skill-consolidator.d.ts +71 -0
  52. package/dist/agent/self-improvement/skill-consolidator.js +137 -0
  53. package/dist/agent/self-improvement/skill-engine.d.ts +42 -0
  54. package/dist/agent/self-improvement/skill-engine.js +87 -0
  55. package/dist/agent/self-improvement/skill-gate.d.ts +19 -0
  56. package/dist/agent/self-improvement/skill-gate.js +62 -0
  57. package/dist/agent/self-improvement/skill-mutator.d.ts +74 -0
  58. package/dist/agent/self-improvement/skill-mutator.js +223 -0
  59. package/dist/agent/self-improvement/skill-proposer.d.ts +40 -0
  60. package/dist/agent/self-improvement/skill-proposer.js +82 -0
  61. package/dist/agent/self-improvement/skill-types.d.ts +41 -0
  62. package/dist/agent/self-improvement/skill-types.js +13 -0
  63. package/dist/agent/self-improvement/tool-benchmark.d.ts +10 -0
  64. package/dist/agent/self-improvement/tool-benchmark.js +37 -0
  65. package/dist/agent/self-improvement/tool-engine.d.ts +54 -0
  66. package/dist/agent/self-improvement/tool-engine.js +101 -0
  67. package/dist/agent/self-improvement/tool-gate.d.ts +20 -0
  68. package/dist/agent/self-improvement/tool-gate.js +78 -0
  69. package/dist/agent/self-improvement/tool-proposer.d.ts +31 -0
  70. package/dist/agent/self-improvement/tool-proposer.js +34 -0
  71. package/dist/agent/self-improvement/tool-skill-mutator.d.ts +40 -0
  72. package/dist/agent/self-improvement/tool-skill-mutator.js +79 -0
  73. package/dist/agent/self-improvement/tool-types.d.ts +48 -0
  74. package/dist/agent/self-improvement/tool-types.js +9 -0
  75. package/dist/agent/self-improvement/types.d.ts +3 -1
  76. package/dist/agent/session-end-flush.d.ts +6 -1
  77. package/dist/agent/session-end-flush.js +20 -4
  78. package/dist/agent/streaming/streaming-handler.d.ts +7 -0
  79. package/dist/agent/streaming/streaming-handler.js +8 -1
  80. package/dist/agent/tool-executor.js +1 -0
  81. package/dist/agent/tool-handler.d.ts +5 -0
  82. package/dist/agent/tool-handler.js +133 -4
  83. package/dist/browser-automation/browser-operator-executor.js +15 -0
  84. package/dist/browser-automation/browser-use-runner.d.ts +96 -0
  85. package/dist/browser-automation/browser-use-runner.js +492 -0
  86. package/dist/browser-automation/camofox-runner.d.ts +107 -0
  87. package/dist/browser-automation/camofox-runner.js +287 -0
  88. package/dist/channels/dingtalk/index.js +3 -0
  89. package/dist/channels/discord/client.d.ts +9 -0
  90. package/dist/channels/discord/client.js +12 -0
  91. package/dist/channels/feishu/index.d.ts +167 -1
  92. package/dist/channels/feishu/index.js +432 -7
  93. package/dist/channels/gateway-lifecycle.d.ts +132 -0
  94. package/dist/channels/gateway-lifecycle.js +219 -0
  95. package/dist/channels/google-chat/index.d.ts +5 -1
  96. package/dist/channels/google-chat/index.js +5 -1
  97. package/dist/channels/imessage/index.d.ts +14 -0
  98. package/dist/channels/imessage/index.js +64 -17
  99. package/dist/channels/index.d.ts +4 -0
  100. package/dist/channels/index.js +4 -0
  101. package/dist/channels/irc/index.d.ts +73 -3
  102. package/dist/channels/irc/index.js +446 -11
  103. package/dist/channels/line/index.js +3 -0
  104. package/dist/channels/mattermost/index.d.ts +51 -4
  105. package/dist/channels/mattermost/index.js +303 -20
  106. package/dist/channels/nextcloud-talk/index.d.ts +89 -8
  107. package/dist/channels/nextcloud-talk/index.js +367 -16
  108. package/dist/channels/nostr/index.d.ts +121 -1
  109. package/dist/channels/nostr/index.js +396 -8
  110. package/dist/channels/ntfy/index.js +3 -0
  111. package/dist/channels/qq/index.js +3 -0
  112. package/dist/channels/slash-parity.d.ts +117 -0
  113. package/dist/channels/slash-parity.js +185 -0
  114. package/dist/channels/synology-chat/index.js +3 -0
  115. package/dist/channels/teams/index.d.ts +3 -0
  116. package/dist/channels/teams/index.js +3 -0
  117. package/dist/channels/telegram/client.d.ts +9 -0
  118. package/dist/channels/telegram/client.js +12 -0
  119. package/dist/channels/twilio-voice/index.js +3 -0
  120. package/dist/channels/webchat/index.d.ts +7 -1
  121. package/dist/channels/webchat/index.js +7 -1
  122. package/dist/channels/wecom/index.js +3 -0
  123. package/dist/channels/weixin/index.js +3 -0
  124. package/dist/channels/zalo/index.js +3 -0
  125. package/dist/cli/config-loader.js +1 -1
  126. package/dist/codebuddy/client.d.ts +30 -1
  127. package/dist/codebuddy/client.js +167 -20
  128. package/dist/codebuddy/providers/provider-chatgpt-responses.d.ts +5 -0
  129. package/dist/codebuddy/providers/provider-chatgpt-responses.js +7 -1
  130. package/dist/codebuddy/providers/provider-gemini-native.js +1 -1
  131. package/dist/codebuddy/providers/provider-openai-compat.d.ts +5 -0
  132. package/dist/codebuddy/providers/provider-openai-compat.js +82 -2
  133. package/dist/codebuddy/tool-definitions/computer-control-tools.js +32 -2
  134. package/dist/codebuddy/tool-definitions/core-tools.js +3 -3
  135. package/dist/codebuddy/tool-definitions/index.d.ts +2 -1
  136. package/dist/codebuddy/tool-definitions/index.js +2 -1
  137. package/dist/codebuddy/tool-definitions/multimodal-tools.d.ts +1 -0
  138. package/dist/codebuddy/tool-definitions/multimodal-tools.js +44 -1
  139. package/dist/codebuddy/tool-definitions/windows-tools.d.ts +2 -0
  140. package/dist/codebuddy/tool-definitions/windows-tools.js +34 -0
  141. package/dist/codebuddy/tools.d.ts +8 -1
  142. package/dist/codebuddy/tools.js +67 -24
  143. package/dist/commands/cli/hermes-commands.js +108 -0
  144. package/dist/commands/cli/improve-command.js +123 -0
  145. package/dist/commands/cli/native-engine-commands.js +102 -3
  146. package/dist/commands/cli/utility-commands.js +45 -0
  147. package/dist/commands/enhanced-command-handler.js +2 -2
  148. package/dist/commands/goal-cli.d.ts +30 -0
  149. package/dist/commands/goal-cli.js +210 -27
  150. package/dist/commands/handlers/goal-handler.d.ts +9 -2
  151. package/dist/commands/handlers/goal-handler.js +36 -9
  152. package/dist/commands/handlers/infra-handlers.js +36 -0
  153. package/dist/commands/handlers/memory-handlers.js +96 -1
  154. package/dist/commands/handlers/missing-handlers.d.ts +1 -1
  155. package/dist/commands/handlers/missing-handlers.js +26 -3
  156. package/dist/commands/headless-slash.d.ts +2 -0
  157. package/dist/commands/headless-slash.js +12 -0
  158. package/dist/commands/llm-provider-resolution.d.ts +5 -3
  159. package/dist/commands/llm-provider-resolution.js +87 -33
  160. package/dist/commands/ollama.d.ts +25 -0
  161. package/dist/commands/ollama.js +100 -0
  162. package/dist/commands/provider.d.ts +5 -0
  163. package/dist/commands/provider.js +106 -55
  164. package/dist/commands/skills-cli/index.js +123 -0
  165. package/dist/commands/slash/builtin-commands.js +1 -1
  166. package/dist/commands/spec-next.js +2 -1
  167. package/dist/commands/spec-plan.js +5 -16
  168. package/dist/commands/tunnel.d.ts +2 -0
  169. package/dist/commands/tunnel.js +48 -0
  170. package/dist/companion/percepts.js +11 -1
  171. package/dist/config/config-resolver.d.ts +2 -1
  172. package/dist/config/config-resolver.js +54 -41
  173. package/dist/config/constants.d.ts +28 -0
  174. package/dist/config/constants.js +7 -0
  175. package/dist/config/env-schema.js +756 -0
  176. package/dist/config/model-tools.js +4 -4
  177. package/dist/config/toml-config.d.ts +16 -0
  178. package/dist/config/toml-config.js +3 -0
  179. package/dist/context/bootstrap-loader.js +6 -23
  180. package/dist/context/context-manager-v2.js +1 -0
  181. package/dist/context/import-directive-parser.d.ts +4 -0
  182. package/dist/context/import-directive-parser.js +51 -6
  183. package/dist/context/instruction-excludes.d.ts +30 -1
  184. package/dist/context/instruction-excludes.js +71 -1
  185. package/dist/context/jit-context.d.ts +8 -10
  186. package/dist/context/jit-context.js +28 -106
  187. package/dist/context/project-context.d.ts +90 -0
  188. package/dist/context/project-context.js +295 -0
  189. package/dist/daemon/autonomous-daemon.d.ts +1 -1
  190. package/dist/daemon/autonomous-daemon.js +3 -3
  191. package/dist/daemon/autonomous-loop.d.ts +31 -1
  192. package/dist/daemon/autonomous-loop.js +91 -4
  193. package/dist/daemon/colab-goal.js +9 -1
  194. package/dist/daemon/cron-agent-bridge.d.ts +12 -3
  195. package/dist/daemon/cron-agent-bridge.js +25 -9
  196. package/dist/desktop/codebuddy-engine-adapter.d.ts +32 -0
  197. package/dist/desktop/codebuddy-engine-adapter.js +257 -80
  198. package/dist/desktop/engine-adapter.d.ts +14 -0
  199. package/dist/desktop-automation/automation-manager.js +16 -0
  200. package/dist/desktop-automation/omniparser-runner.d.ts +63 -0
  201. package/dist/desktop-automation/omniparser-runner.js +115 -0
  202. package/dist/desktop-automation/smart-snapshot.d.ts +11 -0
  203. package/dist/desktop-automation/smart-snapshot.js +72 -5
  204. package/dist/doctor/index.js +40 -23
  205. package/dist/events/types.d.ts +11 -0
  206. package/dist/fleet/colab-store.js +14 -2
  207. package/dist/fleet/peer-session-bridge.js +50 -12
  208. package/dist/fleet/peer-tool-bridge.js +14 -0
  209. package/dist/goals/goal-decomposer.d.ts +27 -0
  210. package/dist/goals/goal-decomposer.js +293 -0
  211. package/dist/goals/goal-judge-client.d.ts +15 -0
  212. package/dist/goals/goal-judge-client.js +45 -0
  213. package/dist/goals/goal-judge.d.ts +2 -0
  214. package/dist/goals/goal-judge.js +35 -6
  215. package/dist/goals/goal-loop.d.ts +14 -0
  216. package/dist/goals/goal-loop.js +47 -2
  217. package/dist/goals/goal-manager.d.ts +6 -0
  218. package/dist/goals/goal-manager.js +67 -14
  219. package/dist/goals/goal-state.d.ts +13 -0
  220. package/dist/goals/goal-state.js +83 -13
  221. package/dist/goals/goal-store.d.ts +3 -0
  222. package/dist/goals/goal-store.js +31 -15
  223. package/dist/harness/contract.d.ts +28 -28
  224. package/dist/hooks/user-hooks.js +17 -3
  225. package/dist/identity/identity-manager.js +3 -2
  226. package/dist/index.js +481 -26
  227. package/dist/input/text-to-speech.d.ts +2 -6
  228. package/dist/input/text-to-speech.js +2 -27
  229. package/dist/integrations/screenpipe/screenpipe-client.d.ts +10 -0
  230. package/dist/integrations/screenpipe/screenpipe-client.js +12 -2
  231. package/dist/integrations/tailscale.d.ts +13 -0
  232. package/dist/integrations/tailscale.js +87 -34
  233. package/dist/knowledge/workspace-indexer.js +53 -9
  234. package/dist/mcp/client.js +1 -0
  235. package/dist/mcp/mcp-desktop-tools.d.ts +23 -0
  236. package/dist/mcp/mcp-desktop-tools.js +158 -0
  237. package/dist/mcp/mcp-resources.js +2 -3
  238. package/dist/mcp/mcp-server.js +2 -0
  239. package/dist/memory/enhanced-memory.d.ts +10 -0
  240. package/dist/memory/enhanced-memory.js +33 -2
  241. package/dist/memory/index.d.ts +3 -1
  242. package/dist/memory/index.js +4 -1
  243. package/dist/memory/memory-auto-proposer.d.ts +23 -0
  244. package/dist/memory/memory-auto-proposer.js +308 -0
  245. package/dist/memory/memory-candidate-queue.d.ts +92 -0
  246. package/dist/memory/memory-candidate-queue.js +261 -0
  247. package/dist/memory/persistent-memory.d.ts +45 -2
  248. package/dist/memory/persistent-memory.js +236 -40
  249. package/dist/ml/bayesian-qualifier.d.ts +1 -1
  250. package/dist/ml/bayesian-qualifier.js +35 -2
  251. package/dist/openclaw/gateway-bridge.js +5 -0
  252. package/dist/plugins/marketplace.d.ts +1 -0
  253. package/dist/plugins/marketplace.js +7 -0
  254. package/dist/prompts/execution-discipline.d.ts +14 -0
  255. package/dist/prompts/execution-discipline.js +29 -0
  256. package/dist/prompts/variation-injector.js +9 -2
  257. package/dist/protocols/acp/acp-agentic-runner.d.ts +7 -6
  258. package/dist/protocols/acp/acp-agentic-runner.js +115 -18
  259. package/dist/protocols/acp/acp-session-store.d.ts +23 -0
  260. package/dist/protocols/acp/acp-session-store.js +77 -0
  261. package/dist/protocols/acp/acp-stdio-server.d.ts +7 -0
  262. package/dist/protocols/acp/acp-stdio-server.js +71 -16
  263. package/dist/providers/active-llm-registry.d.ts +37 -0
  264. package/dist/providers/active-llm-registry.js +186 -0
  265. package/dist/providers/auxiliary-provider.d.ts +25 -0
  266. package/dist/providers/auxiliary-provider.js +192 -0
  267. package/dist/providers/codex-oauth.d.ts +1 -1
  268. package/dist/providers/codex-oauth.js +27 -4
  269. package/dist/providers/index.d.ts +3 -0
  270. package/dist/providers/index.js +4 -0
  271. package/dist/providers/provider-catalog.d.ts +70 -0
  272. package/dist/providers/provider-catalog.js +738 -0
  273. package/dist/providers/provider-fallback.d.ts +35 -0
  274. package/dist/providers/provider-fallback.js +171 -0
  275. package/dist/providers/xai-oauth.d.ts +128 -0
  276. package/dist/providers/xai-oauth.js +735 -0
  277. package/dist/scheduler/cron-scheduler.d.ts +15 -3
  278. package/dist/scheduler/cron-scheduler.js +53 -7
  279. package/dist/scheduler/script-runner.d.ts +2 -0
  280. package/dist/scheduler/script-runner.js +19 -4
  281. package/dist/scheduler/watchdog-handlers.js +7 -20
  282. package/dist/search/usearch-index.js +7 -2
  283. package/dist/security/tool-policy/tool-groups.js +2 -0
  284. package/dist/sensory/dreaming.d.ts +45 -0
  285. package/dist/sensory/dreaming.js +114 -0
  286. package/dist/sensory/heartbeat-scheduler.d.ts +38 -0
  287. package/dist/sensory/heartbeat-scheduler.js +72 -0
  288. package/dist/sensory/reactions.d.ts +24 -0
  289. package/dist/sensory/reactions.js +31 -0
  290. package/dist/sensory/screen-reaction.d.ts +23 -0
  291. package/dist/sensory/screen-reaction.js +59 -0
  292. package/dist/sensory/sensory-bridge.d.ts +23 -0
  293. package/dist/sensory/sensory-bridge.js +85 -0
  294. package/dist/sensory/sensory-memory.d.ts +20 -0
  295. package/dist/sensory/sensory-memory.js +39 -0
  296. package/dist/sensory/speech-reaction.d.ts +21 -0
  297. package/dist/sensory/speech-reaction.js +83 -0
  298. package/dist/sensory/vision-reaction.d.ts +31 -0
  299. package/dist/sensory/vision-reaction.js +74 -0
  300. package/dist/server/index.js +106 -2
  301. package/dist/server/routes/mobile.d.ts +12 -4
  302. package/dist/server/routes/mobile.js +116 -1
  303. package/dist/server/tls-config.d.ts +35 -0
  304. package/dist/server/tls-config.js +142 -0
  305. package/dist/server/tunnel-manager.d.ts +20 -0
  306. package/dist/server/tunnel-manager.js +58 -0
  307. package/dist/server/websocket/fleet-bridge.js +5 -0
  308. package/dist/services/prompt-builder.d.ts +11 -0
  309. package/dist/services/prompt-builder.js +124 -17
  310. package/dist/shared/engine-types.d.ts +15 -1
  311. package/dist/sidecar/sidecar-bridge.d.ts +1 -0
  312. package/dist/sidecar/sidecar-bridge.js +21 -10
  313. package/dist/skills/parser.js +3 -0
  314. package/dist/skills/skill-importer.d.ts +58 -0
  315. package/dist/skills/skill-importer.js +261 -0
  316. package/dist/skills/skill-sources.d.ts +20 -0
  317. package/dist/skills/skill-sources.js +102 -0
  318. package/dist/skills/types.d.ts +6 -0
  319. package/dist/spec/spec-store.js +8 -1
  320. package/dist/talk-mode/providers/audioreader-tts.d.ts +1 -1
  321. package/dist/talk-mode/providers/audioreader-tts.js +8 -8
  322. package/dist/templates/project-scaffolding.js +3 -2
  323. package/dist/themes/theme-schema.d.ts +10 -10
  324. package/dist/tools/application-profiles.js +38 -0
  325. package/dist/tools/bash/bash-tool.d.ts +1 -0
  326. package/dist/tools/bash/bash-tool.js +16 -2
  327. package/dist/tools/bash/command-validator.js +3 -0
  328. package/dist/tools/bash/rtk-rewrite.d.ts +16 -0
  329. package/dist/tools/bash/rtk-rewrite.js +100 -0
  330. package/dist/tools/bash/streaming-executor.js +14 -1
  331. package/dist/tools/computer-control-tool.d.ts +16 -1
  332. package/dist/tools/computer-control-tool.js +317 -5
  333. package/dist/tools/document-generator.d.ts +14 -0
  334. package/dist/tools/document-generator.js +79 -0
  335. package/dist/tools/execute-code-rpc-invoker.d.ts +26 -2
  336. package/dist/tools/execute-code-rpc-invoker.js +46 -5
  337. package/dist/tools/metadata.js +28 -0
  338. package/dist/tools/office-macro-tool.d.ts +10 -0
  339. package/dist/tools/office-macro-tool.js +93 -0
  340. package/dist/tools/register-tool-handler.d.ts +25 -0
  341. package/dist/tools/register-tool-handler.js +100 -0
  342. package/dist/tools/registry/index.d.ts +2 -1
  343. package/dist/tools/registry/index.js +2 -1
  344. package/dist/tools/registry/memory-tools.d.ts +20 -0
  345. package/dist/tools/registry/memory-tools.js +225 -3
  346. package/dist/tools/registry/multimodal-tools.js +2 -2
  347. package/dist/tools/registry/vision-tools.d.ts +33 -0
  348. package/dist/tools/registry/vision-tools.js +308 -6
  349. package/dist/tools/registry/windows-tools.d.ts +2 -0
  350. package/dist/tools/registry/windows-tools.js +47 -0
  351. package/dist/tools/registry.d.ts +6 -0
  352. package/dist/tools/registry.js +8 -0
  353. package/dist/tools/route-peer-tool.js +14 -0
  354. package/dist/tools/screenshot-tool.js +14 -2
  355. package/dist/tools/text-to-speech-tool.d.ts +1 -1
  356. package/dist/tools/text-to-speech-tool.js +2 -12
  357. package/dist/tools/tool-selector.js +3 -59
  358. package/dist/utils/config-validation/schema.d.ts +40 -7
  359. package/dist/utils/config-validation/schema.js +130 -1
  360. package/dist/utils/cost-tracker.js +21 -1
  361. package/dist/utils/disk-guard.d.ts +180 -0
  362. package/dist/utils/disk-guard.js +404 -0
  363. package/dist/utils/init-project.d.ts +7 -0
  364. package/dist/utils/init-project.js +37 -0
  365. package/dist/utils/interactive-setup.js +35 -2
  366. package/dist/utils/model-utils.js +11 -2
  367. package/dist/utils/output-sanitizer.js +11 -0
  368. package/dist/utils/provider-detector.d.ts +8 -7
  369. package/dist/utils/provider-detector.js +19 -77
  370. package/dist/utils/settings-manager.d.ts +19 -0
  371. package/dist/utils/token-display.d.ts +3 -3
  372. package/dist/utils/token-display.js +22 -4
  373. package/dist/wizard/onboarding.d.ts +39 -0
  374. package/dist/wizard/onboarding.js +433 -21
  375. package/dist/wizard/provider-onboarding.d.ts +8 -23
  376. package/dist/wizard/provider-onboarding.js +39 -158
  377. package/package.json +4 -2
  378. package/dist/plugins/provider-onboarding.d.ts +0 -23
  379. package/dist/plugins/provider-onboarding.js +0 -116
  380. package/dist/utils/kokoro-tts.d.ts +0 -8
  381. package/dist/utils/kokoro-tts.js +0 -67
@@ -0,0 +1,219 @@
1
+ /**
2
+ * Gateway Lifecycle Manager
3
+ *
4
+ * Unified lifecycle management (start/stop/restart/status) for the
5
+ * messaging gateway subsystem. Tracks which channel adapters are
6
+ * currently active and provides per-channel readiness information.
7
+ */
8
+ import { EventEmitter } from 'events';
9
+ import { getChannelManager } from './core.js';
10
+ import { logger } from '../utils/logger.js';
11
+ // ============================================================================
12
+ // Gateway Lifecycle Manager
13
+ // ============================================================================
14
+ /**
15
+ * Manages the lifecycle of the messaging gateway and its channel adapters.
16
+ *
17
+ * Wraps the existing ChannelManager with explicit start/stop/restart/status
18
+ * semantics for individual channels and the entire gateway.
19
+ */
20
+ export class GatewayLifecycleManager extends EventEmitter {
21
+ manager;
22
+ activeChannels = new Set();
23
+ channelErrors = new Map();
24
+ constructor(manager) {
25
+ super();
26
+ this.manager = manager ?? getChannelManager();
27
+ }
28
+ /**
29
+ * Get the underlying ChannelManager.
30
+ */
31
+ getManager() {
32
+ return this.manager;
33
+ }
34
+ /**
35
+ * Start a single channel adapter by its channel type.
36
+ *
37
+ * The channel must already be registered with the ChannelManager.
38
+ * This calls connect() on the adapter and marks it as active.
39
+ *
40
+ * @param channelId - The channel type to start
41
+ * @throws Error if the channel is not registered
42
+ */
43
+ async start(channelId) {
44
+ const channel = this.manager.getChannel(channelId);
45
+ if (!channel) {
46
+ throw new Error(`Channel '${channelId}' is not registered`);
47
+ }
48
+ try {
49
+ await channel.connect();
50
+ this.activeChannels.add(channelId);
51
+ this.channelErrors.delete(channelId);
52
+ this.emit('channel:started', channelId);
53
+ logger.debug('Gateway: channel started', { channelId });
54
+ }
55
+ catch (err) {
56
+ const message = err instanceof Error ? err.message : String(err);
57
+ this.channelErrors.set(channelId, message);
58
+ this.emit('channel:error', channelId, err instanceof Error ? err : new Error(message));
59
+ throw err;
60
+ }
61
+ }
62
+ /**
63
+ * Stop a single channel adapter by its channel type.
64
+ *
65
+ * Calls disconnect() on the adapter and removes it from the active set.
66
+ *
67
+ * @param channelId - The channel type to stop
68
+ * @throws Error if the channel is not registered
69
+ */
70
+ async stop(channelId) {
71
+ const channel = this.manager.getChannel(channelId);
72
+ if (!channel) {
73
+ throw new Error(`Channel '${channelId}' is not registered`);
74
+ }
75
+ try {
76
+ await channel.disconnect();
77
+ }
78
+ catch (err) {
79
+ logger.debug('Gateway: error during channel disconnect', {
80
+ channelId,
81
+ error: err instanceof Error ? err.message : String(err),
82
+ });
83
+ }
84
+ this.activeChannels.delete(channelId);
85
+ this.channelErrors.delete(channelId);
86
+ this.emit('channel:stopped', channelId);
87
+ logger.debug('Gateway: channel stopped', { channelId });
88
+ }
89
+ /**
90
+ * Restart a single channel adapter (stop + start).
91
+ *
92
+ * @param channelId - The channel type to restart
93
+ */
94
+ async restart(channelId) {
95
+ if (this.activeChannels.has(channelId)) {
96
+ await this.stop(channelId);
97
+ }
98
+ await this.start(channelId);
99
+ }
100
+ /**
101
+ * Start all registered channel adapters.
102
+ */
103
+ async startAll() {
104
+ const channels = this.manager.getAllChannels();
105
+ const errors = [];
106
+ for (const channel of channels) {
107
+ try {
108
+ await this.start(channel.type);
109
+ }
110
+ catch (err) {
111
+ errors.push({
112
+ channelId: channel.type,
113
+ error: err instanceof Error ? err.message : String(err),
114
+ });
115
+ }
116
+ }
117
+ this.emit('gateway:started');
118
+ if (errors.length > 0) {
119
+ logger.debug('Gateway: some channels failed to start', { errors });
120
+ }
121
+ }
122
+ /**
123
+ * Stop all active channel adapters.
124
+ */
125
+ async stopAll() {
126
+ const activeIds = [...this.activeChannels];
127
+ for (const channelId of activeIds) {
128
+ try {
129
+ await this.stop(channelId);
130
+ }
131
+ catch (err) {
132
+ logger.debug('Gateway: error stopping channel', {
133
+ channelId,
134
+ error: err instanceof Error ? err.message : String(err),
135
+ });
136
+ }
137
+ }
138
+ this.emit('gateway:stopped');
139
+ }
140
+ /**
141
+ * Get the full gateway status report.
142
+ *
143
+ * Aggregates per-channel readiness from the ChannelManager's status,
144
+ * the active set, and any recorded errors.
145
+ */
146
+ status() {
147
+ const channels = this.manager.getAllChannels();
148
+ const channelStatuses = [];
149
+ let connectedCount = 0;
150
+ let errorCount = 0;
151
+ let disconnectedCount = 0;
152
+ for (const channel of channels) {
153
+ const s = channel.getStatus();
154
+ const errorMsg = this.channelErrors.get(channel.type) ?? s.error;
155
+ let readiness;
156
+ if (errorMsg) {
157
+ readiness = 'error';
158
+ errorCount++;
159
+ }
160
+ else if (s.connected) {
161
+ readiness = 'connected';
162
+ connectedCount++;
163
+ }
164
+ else {
165
+ readiness = 'disconnected';
166
+ disconnectedCount++;
167
+ }
168
+ channelStatuses.push({
169
+ channelId: channel.type,
170
+ readiness,
171
+ authenticated: s.authenticated,
172
+ lastActivity: s.lastActivity?.toISOString(),
173
+ error: errorMsg,
174
+ info: s.info,
175
+ });
176
+ }
177
+ return {
178
+ ok: errorCount === 0 && channels.length > 0,
179
+ generatedAt: new Date().toISOString(),
180
+ totalChannels: channels.length,
181
+ connectedCount,
182
+ errorCount,
183
+ disconnectedCount,
184
+ channels: channelStatuses,
185
+ };
186
+ }
187
+ /**
188
+ * Check whether a specific channel is currently active.
189
+ */
190
+ isActive(channelId) {
191
+ return this.activeChannels.has(channelId);
192
+ }
193
+ /**
194
+ * Get the set of currently active channel IDs.
195
+ */
196
+ getActiveChannels() {
197
+ return [...this.activeChannels];
198
+ }
199
+ }
200
+ // ============================================================================
201
+ // Singleton
202
+ // ============================================================================
203
+ let lifecycleInstance = null;
204
+ /**
205
+ * Get the singleton GatewayLifecycleManager instance.
206
+ */
207
+ export function getGatewayLifecycle() {
208
+ if (!lifecycleInstance) {
209
+ lifecycleInstance = new GatewayLifecycleManager();
210
+ }
211
+ return lifecycleInstance;
212
+ }
213
+ /**
214
+ * Reset the singleton (for testing).
215
+ */
216
+ export function resetGatewayLifecycle() {
217
+ lifecycleInstance = null;
218
+ }
219
+ //# sourceMappingURL=gateway-lifecycle.js.map
@@ -158,7 +158,11 @@ export declare class GoogleChatChannel extends BaseChannel {
158
158
  private apiRequest;
159
159
  /**
160
160
  * Connect to Google Chat by validating the service account and
161
- * verifying API access
161
+ * verifying API access.
162
+ *
163
+ * REST/webhook adapter — outbound via the Google Chat REST API, inbound via
164
+ * webhook (or Pub/Sub) callbacks; no persistent connection is held open
165
+ * here, so reconnection (ReconnectionManager) is N/A.
162
166
  */
163
167
  connect(): Promise<void>;
164
168
  /**
@@ -139,7 +139,11 @@ export class GoogleChatChannel extends BaseChannel {
139
139
  // ==========================================================================
140
140
  /**
141
141
  * Connect to Google Chat by validating the service account and
142
- * verifying API access
142
+ * verifying API access.
143
+ *
144
+ * REST/webhook adapter — outbound via the Google Chat REST API, inbound via
145
+ * webhook (or Pub/Sub) callbacks; no persistent connection is held open
146
+ * here, so reconnection (ReconnectionManager) is N/A.
143
147
  */
144
148
  async connect() {
145
149
  try {
@@ -51,6 +51,8 @@ export declare class IMessageAdapter extends EventEmitter {
51
51
  private pollingTimer;
52
52
  private lastMessageTimestamp;
53
53
  private retryCount;
54
+ private reconnecting;
55
+ private reconnectionManager;
54
56
  constructor(config: IMessageConfig);
55
57
  start(): Promise<void>;
56
58
  stop(): Promise<void>;
@@ -70,6 +72,18 @@ export declare class IMessageAdapter extends EventEmitter {
70
72
  private startPolling;
71
73
  private stopPolling;
72
74
  private pollMessages;
75
+ /**
76
+ * Recover a dropped BlueBubbles connection via the shared
77
+ * ReconnectionManager (exponential backoff + jitter + max-retry
78
+ * exhaustion). Replaces the previous hand-rolled backoff loop so we
79
+ * never run two competing backoffs at once.
80
+ *
81
+ * `scheduleReconnect` is single-shot — one call schedules exactly one
82
+ * attempt — so on a failed health check we must re-drive it (the way
83
+ * discord's repeated WS `close` events and telegram's repeating poll loop
84
+ * naturally do) until the connection recovers or the manager exhausts its
85
+ * retries and emits `exhausted`.
86
+ */
73
87
  private reconnect;
74
88
  private getBaseUrl;
75
89
  private apiRequest;
@@ -8,6 +8,7 @@
8
8
  import { EventEmitter } from 'events';
9
9
  import { logger } from '../../utils/logger.js';
10
10
  import { BaseChannel } from '../core.js';
11
+ import { ReconnectionManager } from '../reconnection-manager.js';
11
12
  // ============================================================================
12
13
  // IMessageAdapter
13
14
  // ============================================================================
@@ -17,6 +18,8 @@ export class IMessageAdapter extends EventEmitter {
17
18
  pollingTimer = null;
18
19
  lastMessageTimestamp = 0;
19
20
  retryCount = 0;
21
+ reconnecting = false;
22
+ reconnectionManager;
20
23
  constructor(config) {
21
24
  super();
22
25
  this.config = {
@@ -28,6 +31,13 @@ export class IMessageAdapter extends EventEmitter {
28
31
  if (this.config.port === undefined) {
29
32
  this.config.port = 1234;
30
33
  }
34
+ // Persistent long-poll connection to BlueBubbles — drops are recovered
35
+ // with shared exponential backoff (same idiom as discord/slack/telegram).
36
+ this.reconnectionManager = new ReconnectionManager('imessage', {
37
+ maxRetries: this.config.maxRetries ?? 5,
38
+ initialDelayMs: this.config.retryDelay ?? 5000,
39
+ maxDelayMs: 60000,
40
+ });
31
41
  }
32
42
  // ============================================================================
33
43
  // Lifecycle
@@ -42,6 +52,11 @@ export class IMessageAdapter extends EventEmitter {
42
52
  });
43
53
  // Verify connectivity
44
54
  await this.healthCheck();
55
+ // Connectivity is confirmed for this session — reset the shared backoff
56
+ // state so a fresh start() never inherits a pre-exhausted retryCount from
57
+ // a previous outage episode (onConnected() resets retryCount + active +
58
+ // any pending timer; cancel() alone does not).
59
+ this.reconnectionManager.onConnected();
45
60
  this.running = true;
46
61
  this.lastMessageTimestamp = Date.now();
47
62
  this.retryCount = 0;
@@ -54,6 +69,9 @@ export class IMessageAdapter extends EventEmitter {
54
69
  if (!this.running) {
55
70
  throw new Error('IMessageAdapter is not running');
56
71
  }
72
+ // Cancel any pending reconnect so it can't fire after an explicit stop.
73
+ this.reconnectionManager.cancel();
74
+ this.reconnecting = false;
57
75
  this.stopPolling();
58
76
  this.running = false;
59
77
  this.emit('disconnected');
@@ -147,6 +165,9 @@ export class IMessageAdapter extends EventEmitter {
147
165
  try {
148
166
  await this.pollMessages();
149
167
  this.retryCount = 0;
168
+ // A successful poll means the connection is healthy again — reset
169
+ // the shared backoff state so a future drop starts from delay 0.
170
+ this.reconnectionManager.onConnected();
150
171
  }
151
172
  catch (error) {
152
173
  this.retryCount++;
@@ -155,7 +176,7 @@ export class IMessageAdapter extends EventEmitter {
155
176
  if (this.retryCount >= (this.config.maxRetries || 5)) {
156
177
  logger.error('IMessageAdapter: max retries exceeded, attempting reconnect');
157
178
  this.emit('error', new Error('Polling failed after max retries'));
158
- await this.reconnect();
179
+ this.reconnect();
159
180
  }
160
181
  }
161
182
  }, this.config.pollingInterval);
@@ -193,32 +214,58 @@ export class IMessageAdapter extends EventEmitter {
193
214
  // ============================================================================
194
215
  // Reconnection
195
216
  // ============================================================================
196
- async reconnect() {
217
+ /**
218
+ * Recover a dropped BlueBubbles connection via the shared
219
+ * ReconnectionManager (exponential backoff + jitter + max-retry
220
+ * exhaustion). Replaces the previous hand-rolled backoff loop so we
221
+ * never run two competing backoffs at once.
222
+ *
223
+ * `scheduleReconnect` is single-shot — one call schedules exactly one
224
+ * attempt — so on a failed health check we must re-drive it (the way
225
+ * discord's repeated WS `close` events and telegram's repeating poll loop
226
+ * naturally do) until the connection recovers or the manager exhausts its
227
+ * retries and emits `exhausted`.
228
+ */
229
+ reconnect() {
230
+ // Pause polling while we attempt to re-establish the connection; the
231
+ // backoff timer in the manager now owns the retry cadence.
197
232
  this.stopPolling();
198
- const maxRetries = this.config.maxRetries || 5;
199
- const retryDelay = this.config.retryDelay || 5000;
200
- for (let attempt = 1; attempt <= maxRetries; attempt++) {
233
+ // Surface permanent failure once the manager exhausts its retries.
234
+ if (this.reconnectionManager.listenerCount('exhausted') === 0) {
235
+ this.reconnectionManager.on('exhausted', () => {
236
+ this.reconnecting = false;
237
+ this.running = false;
238
+ this.emit('disconnected', new Error('Reconnection failed after all retries'));
239
+ logger.error('IMessageAdapter: reconnection failed permanently');
240
+ });
241
+ }
242
+ this.reconnecting = true;
243
+ this.reconnectionManager.scheduleReconnect(async () => {
201
244
  try {
202
- logger.info(`IMessageAdapter: reconnection attempt ${attempt}/${maxRetries}`);
203
245
  await this.healthCheck();
204
- // Reconnected successfully
246
+ // Health check passed — resume the poll loop and reset counters.
247
+ this.reconnecting = false;
205
248
  this.retryCount = 0;
206
249
  this.startPolling();
250
+ this.reconnectionManager.onConnected();
207
251
  this.emit('reconnected');
208
252
  logger.info('IMessageAdapter: reconnected successfully');
209
- return;
210
253
  }
211
- catch {
212
- if (attempt < maxRetries) {
213
- const delay = retryDelay * Math.pow(2, attempt - 1);
214
- logger.warn(`IMessageAdapter: reconnection failed, retrying in ${delay}ms`);
215
- await new Promise(resolve => setTimeout(resolve, delay));
254
+ catch (error) {
255
+ // This attempt failed. Defer re-driving the manager until after it
256
+ // clears its internal `active` flag (which it does in its own
257
+ // `finally`, once this closure settles), so the next attempt is
258
+ // actually scheduled instead of being dropped by the active-guard.
259
+ if (this.running) {
260
+ setTimeout(() => {
261
+ if (this.running && this.reconnecting) {
262
+ this.reconnect();
263
+ }
264
+ }, 0).unref?.();
216
265
  }
266
+ throw error instanceof Error ? error : new Error(String(error));
217
267
  }
218
- }
219
- this.running = false;
220
- this.emit('disconnected', new Error('Reconnection failed after all retries'));
221
- logger.error('IMessageAdapter: reconnection failed permanently');
268
+ });
222
269
  }
223
270
  // ============================================================================
224
271
  // Internal Helpers
@@ -48,3 +48,7 @@ export type { SynologyChatConfig, SynologyChatChannelConfig, SynologyChatMessage
48
48
  export { NtfyAdapter, NtfyChannel } from './ntfy/index.js';
49
49
  export type { NtfyConfig, NtfyChannelConfig, NtfyPublishOptions, NtfyPublishResult } from './ntfy/index.js';
50
50
  export { TwitchAdapter, TlonAdapter, GmailWebhookAdapter, DocsSearchTool } from './niche-channels.js';
51
+ export { GatewayLifecycleManager, getGatewayLifecycle, resetGatewayLifecycle, } from './gateway-lifecycle.js';
52
+ export type { ChannelReadiness, GatewayChannelStatus, GatewayStatus, } from './gateway-lifecycle.js';
53
+ export { buildSlashParityManifest, buildPlatformParityReport, extractActualCommands, renderSlashParityManifest, EXPECTED_SLASH_COMMANDS, } from './slash-parity.js';
54
+ export type { SlashCommandSpec, SlashCommandParityEntry, PlatformSlashParityReport, SlashParityManifest, SlashCommandProvider, } from './slash-parity.js';
@@ -49,4 +49,8 @@ export { SynologyChatAdapter, SynologyChatChannel } from './synology-chat/index.
49
49
  export { NtfyAdapter, NtfyChannel } from './ntfy/index.js';
50
50
  // Niche Channels (Twitch, Tlon, Gmail)
51
51
  export { TwitchAdapter, TlonAdapter, GmailWebhookAdapter, DocsSearchTool } from './niche-channels.js';
52
+ // Gateway Lifecycle
53
+ export { GatewayLifecycleManager, getGatewayLifecycle, resetGatewayLifecycle, } from './gateway-lifecycle.js';
54
+ // Slash-Command Parity
55
+ export { buildSlashParityManifest, buildPlatformParityReport, extractActualCommands, renderSlashParityManifest, EXPECTED_SLASH_COMMANDS, } from './slash-parity.js';
52
56
  //# sourceMappingURL=index.js.map
@@ -1,9 +1,13 @@
1
1
  /**
2
2
  * IRC Channel Adapter
3
3
  *
4
- * Connects to IRC servers for sending/receiving messages.
5
- * Supports multiple channels, SASL auth, and TLS.
4
+ * Connects to IRC servers for sending/receiving messages over a real,
5
+ * long-lived TCP (or TLS) socket implementing an RFC 1459/2812 subset.
6
+ * Supports multiple channels, password auth, TLS, and auto-reconnect with
7
+ * exponential backoff (shared ReconnectionManager idiom — same as
8
+ * imessage/discord/slack).
6
9
  */
10
+ import { EventEmitter } from 'events';
7
11
  import { BaseChannel, ChannelConfig, DeliveryResult, OutboundMessage } from '../core.js';
8
12
  export interface IRCConfig {
9
13
  server: string;
@@ -15,6 +19,10 @@ export interface IRCConfig {
15
19
  channels: string[];
16
20
  useTLS?: boolean;
17
21
  sasl?: boolean;
22
+ /** Milliseconds to wait for the 001 welcome reply before failing connect (default 15000) */
23
+ connectTimeoutMs?: number;
24
+ maxRetries?: number;
25
+ retryDelayMs?: number;
18
26
  }
19
27
  export interface IRCChannelConfig extends ChannelConfig {
20
28
  server: string;
@@ -26,15 +34,76 @@ export interface IRCChannelConfig extends ChannelConfig {
26
34
  channels: string[];
27
35
  useTLS?: boolean;
28
36
  sasl?: boolean;
37
+ connectTimeoutMs?: number;
38
+ maxRetries?: number;
39
+ retryDelayMs?: number;
29
40
  }
30
- export declare class IRCAdapter {
41
+ /**
42
+ * A single parsed IRC protocol line.
43
+ *
44
+ * IRC lines are either prefixed (`:<prefix> <command> <params...>`) or
45
+ * unprefixed (`<command> <params...>`). The final parameter may be a
46
+ * "trailing" param introduced by ` :` which can contain spaces.
47
+ */
48
+ interface IRCMessage {
49
+ prefix?: string;
50
+ command: string;
51
+ params: string[];
52
+ }
53
+ /**
54
+ * Parse a raw IRC line (without the trailing CRLF) into prefix/command/params.
55
+ *
56
+ * Handles both prefixed and unprefixed lines — this distinction is
57
+ * load-bearing: the welcome reply `001 <nick> :Welcome` has NO prefix while
58
+ * `:nick!u@h PRIVMSG #cb :text` does. Treating tokens[0] as always-prefix (or
59
+ * never-prefix) misparses one of them.
60
+ */
61
+ export declare function parseIRCLine(line: string): IRCMessage | null;
62
+ export declare class IRCAdapter extends EventEmitter {
31
63
  private config;
32
64
  private running;
33
65
  private joinedChannels;
66
+ private socket;
67
+ private recvBuffer;
68
+ /** True while an intentional disconnect is in progress — suppresses reconnect. */
69
+ private closing;
70
+ /** True once a close/error for the current socket has been handled (de-dup). */
71
+ private closeHandled;
72
+ private reconnecting;
73
+ private reconnectionManager;
34
74
  constructor(config: IRCConfig);
35
75
  start(): Promise<void>;
36
76
  stop(): Promise<void>;
37
77
  isRunning(): boolean;
78
+ getConfig(): IRCConfig;
79
+ /**
80
+ * Open the socket, perform the registration handshake, and resolve once the
81
+ * server sends the 001 welcome numeric. Used by both start() and the
82
+ * reconnect callback (so it deliberately omits the running-guard).
83
+ */
84
+ private connectInternal;
85
+ /**
86
+ * Buffer incoming bytes and dispatch complete CRLF-terminated lines.
87
+ * `onWelcome` is invoked when the 001 numeric is seen (resolves connect()).
88
+ */
89
+ private handleData;
90
+ private handleLine;
91
+ private handlePrivmsg;
92
+ /**
93
+ * Handle a socket 'close' or 'error' that was NOT triggered by an
94
+ * intentional disconnect. De-dupes the error→close pair (ECONNRESET fires
95
+ * 'error' then 'close') and drives a single reconnect via the shared
96
+ * ReconnectionManager.
97
+ */
98
+ private handleSocketClosed;
99
+ /**
100
+ * Recover a dropped connection via the shared ReconnectionManager
101
+ * (exponential backoff + jitter + exhaustion). `scheduleReconnect` is
102
+ * single-shot, so a failed attempt re-drives it (deferred past the manager's
103
+ * internal active-guard) until recovery or exhaustion.
104
+ */
105
+ private reconnect;
106
+ private write;
38
107
  sendMessage(target: string, text: string): Promise<{
39
108
  success: boolean;
40
109
  }>;
@@ -57,3 +126,4 @@ export declare class IRCChannel extends BaseChannel {
57
126
  disconnect(): Promise<void>;
58
127
  send(message: OutboundMessage): Promise<DeliveryResult>;
59
128
  }
129
+ export default IRCAdapter;