@phuetz/code-buddy 1.1.0 → 1.2.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 (291) hide show
  1. package/README.md +160 -165
  2. package/dist/agent/autonomous/agentic-coding-contract.d.ts +6 -6
  3. package/dist/agent/codebuddy-agent.d.ts +1 -1
  4. package/dist/agent/codebuddy-agent.js +69 -14
  5. package/dist/agent/execution/agent-executor.js +122 -12
  6. package/dist/agent/execution/tool-dependency-graph.js +7 -0
  7. package/dist/agent/execution/tool-hooks.d.ts +6 -0
  8. package/dist/agent/execution/tool-hooks.js +13 -5
  9. package/dist/agent/execution/tool-selection-strategy.d.ts +11 -2
  10. package/dist/agent/execution/tool-selection-strategy.js +67 -10
  11. package/dist/agent/extended-thinking.d.ts +8 -0
  12. package/dist/agent/extended-thinking.js +27 -0
  13. package/dist/agent/hermes-browser-backends.js +151 -11
  14. package/dist/agent/hermes-claw-migrate.d.ts +59 -0
  15. package/dist/agent/hermes-claw-migrate.js +427 -26
  16. package/dist/agent/hermes-parity-manifest.js +78 -71
  17. package/dist/agent/hermes-runtime-lifecycle.d.ts +67 -0
  18. package/dist/agent/hermes-runtime-lifecycle.js +468 -0
  19. package/dist/agent/middleware/index.d.ts +1 -0
  20. package/dist/agent/middleware/index.js +1 -0
  21. package/dist/agent/middleware/visual-validation-middleware.d.ts +17 -0
  22. package/dist/agent/middleware/visual-validation-middleware.js +67 -0
  23. package/dist/agent/model-benchmark.d.ts +77 -0
  24. package/dist/agent/model-benchmark.js +309 -0
  25. package/dist/agent/model-tier.d.ts +14 -0
  26. package/dist/agent/model-tier.js +71 -0
  27. package/dist/agent/multi-agent/agents/orchestrator-agent.js +17 -6
  28. package/dist/agent/multi-agent/multi-agent-system.js +3 -1
  29. package/dist/agent/multi-agent/session-fleet-bridge.d.ts +2 -0
  30. package/dist/agent/multi-agent/session-fleet-bridge.js +9 -1
  31. package/dist/agent/multi-agent/session-tools.js +22 -5
  32. package/dist/agent/reasoning/mcts.js +20 -6
  33. package/dist/agent/session-end-flush.d.ts +6 -1
  34. package/dist/agent/session-end-flush.js +20 -4
  35. package/dist/agent/streaming/streaming-handler.d.ts +7 -0
  36. package/dist/agent/streaming/streaming-handler.js +8 -1
  37. package/dist/agent/tool-executor.js +1 -0
  38. package/dist/agent/tool-handler.d.ts +5 -0
  39. package/dist/agent/tool-handler.js +130 -4
  40. package/dist/browser-automation/browser-operator-executor.js +15 -0
  41. package/dist/browser-automation/browser-use-runner.d.ts +96 -0
  42. package/dist/browser-automation/browser-use-runner.js +492 -0
  43. package/dist/browser-automation/camofox-runner.d.ts +107 -0
  44. package/dist/browser-automation/camofox-runner.js +287 -0
  45. package/dist/channels/dingtalk/index.js +3 -0
  46. package/dist/channels/discord/client.d.ts +9 -0
  47. package/dist/channels/discord/client.js +12 -0
  48. package/dist/channels/feishu/index.d.ts +167 -1
  49. package/dist/channels/feishu/index.js +432 -7
  50. package/dist/channels/gateway-lifecycle.d.ts +132 -0
  51. package/dist/channels/gateway-lifecycle.js +219 -0
  52. package/dist/channels/google-chat/index.d.ts +5 -1
  53. package/dist/channels/google-chat/index.js +5 -1
  54. package/dist/channels/imessage/index.d.ts +14 -0
  55. package/dist/channels/imessage/index.js +64 -17
  56. package/dist/channels/index.d.ts +4 -0
  57. package/dist/channels/index.js +4 -0
  58. package/dist/channels/irc/index.d.ts +73 -3
  59. package/dist/channels/irc/index.js +446 -11
  60. package/dist/channels/line/index.js +3 -0
  61. package/dist/channels/mattermost/index.d.ts +51 -4
  62. package/dist/channels/mattermost/index.js +303 -20
  63. package/dist/channels/nextcloud-talk/index.d.ts +89 -8
  64. package/dist/channels/nextcloud-talk/index.js +367 -16
  65. package/dist/channels/nostr/index.d.ts +121 -1
  66. package/dist/channels/nostr/index.js +396 -8
  67. package/dist/channels/ntfy/index.js +3 -0
  68. package/dist/channels/qq/index.js +3 -0
  69. package/dist/channels/slash-parity.d.ts +117 -0
  70. package/dist/channels/slash-parity.js +185 -0
  71. package/dist/channels/synology-chat/index.js +3 -0
  72. package/dist/channels/teams/index.d.ts +3 -0
  73. package/dist/channels/teams/index.js +3 -0
  74. package/dist/channels/telegram/client.d.ts +9 -0
  75. package/dist/channels/telegram/client.js +12 -0
  76. package/dist/channels/twilio-voice/index.js +3 -0
  77. package/dist/channels/webchat/index.d.ts +7 -1
  78. package/dist/channels/webchat/index.js +7 -1
  79. package/dist/channels/wecom/index.js +3 -0
  80. package/dist/channels/weixin/index.js +3 -0
  81. package/dist/channels/zalo/index.js +3 -0
  82. package/dist/cli/config-loader.js +1 -1
  83. package/dist/codebuddy/client.d.ts +30 -1
  84. package/dist/codebuddy/client.js +167 -20
  85. package/dist/codebuddy/providers/provider-chatgpt-responses.d.ts +5 -0
  86. package/dist/codebuddy/providers/provider-chatgpt-responses.js +1 -0
  87. package/dist/codebuddy/providers/provider-gemini-native.js +1 -1
  88. package/dist/codebuddy/providers/provider-openai-compat.d.ts +5 -0
  89. package/dist/codebuddy/providers/provider-openai-compat.js +82 -2
  90. package/dist/codebuddy/tool-definitions/computer-control-tools.js +32 -2
  91. package/dist/codebuddy/tool-definitions/core-tools.js +3 -3
  92. package/dist/codebuddy/tool-definitions/index.d.ts +2 -1
  93. package/dist/codebuddy/tool-definitions/index.js +2 -1
  94. package/dist/codebuddy/tool-definitions/multimodal-tools.d.ts +1 -0
  95. package/dist/codebuddy/tool-definitions/multimodal-tools.js +44 -1
  96. package/dist/codebuddy/tool-definitions/windows-tools.d.ts +2 -0
  97. package/dist/codebuddy/tool-definitions/windows-tools.js +34 -0
  98. package/dist/codebuddy/tools.d.ts +1 -1
  99. package/dist/codebuddy/tools.js +27 -24
  100. package/dist/commands/cli/hermes-commands.js +108 -0
  101. package/dist/commands/cli/native-engine-commands.js +102 -3
  102. package/dist/commands/cli/utility-commands.js +45 -0
  103. package/dist/commands/enhanced-command-handler.js +1 -1
  104. package/dist/commands/goal-cli.d.ts +30 -0
  105. package/dist/commands/goal-cli.js +210 -27
  106. package/dist/commands/handlers/goal-handler.d.ts +9 -2
  107. package/dist/commands/handlers/goal-handler.js +36 -9
  108. package/dist/commands/handlers/infra-handlers.js +36 -0
  109. package/dist/commands/handlers/memory-handlers.js +96 -1
  110. package/dist/commands/headless-slash.d.ts +2 -0
  111. package/dist/commands/headless-slash.js +12 -0
  112. package/dist/commands/llm-provider-resolution.d.ts +5 -3
  113. package/dist/commands/llm-provider-resolution.js +87 -33
  114. package/dist/commands/ollama.d.ts +25 -0
  115. package/dist/commands/ollama.js +100 -0
  116. package/dist/commands/provider.d.ts +5 -0
  117. package/dist/commands/provider.js +106 -55
  118. package/dist/commands/spec-next.js +2 -1
  119. package/dist/commands/spec-plan.js +5 -16
  120. package/dist/commands/tunnel.d.ts +2 -0
  121. package/dist/commands/tunnel.js +48 -0
  122. package/dist/config/config-resolver.d.ts +2 -1
  123. package/dist/config/config-resolver.js +54 -41
  124. package/dist/config/constants.d.ts +28 -0
  125. package/dist/config/constants.js +7 -0
  126. package/dist/config/env-schema.js +756 -0
  127. package/dist/config/model-tools.js +4 -4
  128. package/dist/config/toml-config.d.ts +16 -0
  129. package/dist/config/toml-config.js +3 -0
  130. package/dist/context/context-manager-v2.js +1 -0
  131. package/dist/daemon/autonomous-daemon.d.ts +1 -1
  132. package/dist/daemon/autonomous-daemon.js +3 -3
  133. package/dist/daemon/autonomous-loop.js +11 -2
  134. package/dist/daemon/colab-goal.js +9 -1
  135. package/dist/daemon/cron-agent-bridge.d.ts +12 -3
  136. package/dist/daemon/cron-agent-bridge.js +25 -9
  137. package/dist/desktop/codebuddy-engine-adapter.d.ts +32 -0
  138. package/dist/desktop/codebuddy-engine-adapter.js +257 -80
  139. package/dist/desktop/engine-adapter.d.ts +14 -0
  140. package/dist/desktop-automation/automation-manager.js +16 -0
  141. package/dist/desktop-automation/omniparser-runner.d.ts +63 -0
  142. package/dist/desktop-automation/omniparser-runner.js +115 -0
  143. package/dist/desktop-automation/smart-snapshot.d.ts +11 -0
  144. package/dist/desktop-automation/smart-snapshot.js +72 -5
  145. package/dist/doctor/index.js +40 -23
  146. package/dist/events/types.d.ts +11 -0
  147. package/dist/fleet/colab-store.js +14 -2
  148. package/dist/fleet/peer-session-bridge.js +50 -12
  149. package/dist/fleet/peer-tool-bridge.js +14 -0
  150. package/dist/goals/goal-decomposer.d.ts +27 -0
  151. package/dist/goals/goal-decomposer.js +293 -0
  152. package/dist/goals/goal-judge-client.d.ts +15 -0
  153. package/dist/goals/goal-judge-client.js +45 -0
  154. package/dist/goals/goal-judge.d.ts +2 -0
  155. package/dist/goals/goal-judge.js +35 -6
  156. package/dist/goals/goal-loop.d.ts +14 -0
  157. package/dist/goals/goal-loop.js +47 -2
  158. package/dist/goals/goal-manager.d.ts +6 -0
  159. package/dist/goals/goal-manager.js +67 -14
  160. package/dist/goals/goal-state.d.ts +13 -0
  161. package/dist/goals/goal-state.js +83 -13
  162. package/dist/goals/goal-store.d.ts +3 -0
  163. package/dist/goals/goal-store.js +31 -15
  164. package/dist/hooks/user-hooks.js +17 -3
  165. package/dist/index.js +464 -25
  166. package/dist/input/text-to-speech.d.ts +2 -6
  167. package/dist/input/text-to-speech.js +2 -27
  168. package/dist/integrations/screenpipe/screenpipe-client.d.ts +10 -0
  169. package/dist/integrations/screenpipe/screenpipe-client.js +12 -2
  170. package/dist/integrations/tailscale.d.ts +13 -0
  171. package/dist/integrations/tailscale.js +87 -34
  172. package/dist/knowledge/workspace-indexer.js +53 -9
  173. package/dist/mcp/client.js +1 -0
  174. package/dist/mcp/mcp-desktop-tools.d.ts +23 -0
  175. package/dist/mcp/mcp-desktop-tools.js +158 -0
  176. package/dist/mcp/mcp-server.js +2 -0
  177. package/dist/memory/enhanced-memory.d.ts +10 -0
  178. package/dist/memory/enhanced-memory.js +33 -2
  179. package/dist/memory/index.d.ts +3 -1
  180. package/dist/memory/index.js +4 -1
  181. package/dist/memory/memory-auto-proposer.d.ts +23 -0
  182. package/dist/memory/memory-auto-proposer.js +308 -0
  183. package/dist/memory/memory-candidate-queue.d.ts +92 -0
  184. package/dist/memory/memory-candidate-queue.js +261 -0
  185. package/dist/memory/persistent-memory.d.ts +45 -2
  186. package/dist/memory/persistent-memory.js +236 -40
  187. package/dist/ml/bayesian-qualifier.d.ts +1 -1
  188. package/dist/ml/bayesian-qualifier.js +35 -2
  189. package/dist/openclaw/gateway-bridge.js +5 -0
  190. package/dist/plugins/marketplace.d.ts +1 -0
  191. package/dist/plugins/marketplace.js +7 -0
  192. package/dist/prompts/execution-discipline.d.ts +14 -0
  193. package/dist/prompts/execution-discipline.js +29 -0
  194. package/dist/prompts/variation-injector.js +9 -2
  195. package/dist/protocols/acp/acp-agentic-runner.d.ts +7 -6
  196. package/dist/protocols/acp/acp-agentic-runner.js +115 -18
  197. package/dist/protocols/acp/acp-session-store.d.ts +23 -0
  198. package/dist/protocols/acp/acp-session-store.js +77 -0
  199. package/dist/protocols/acp/acp-stdio-server.d.ts +7 -0
  200. package/dist/protocols/acp/acp-stdio-server.js +71 -16
  201. package/dist/providers/active-llm-registry.d.ts +37 -0
  202. package/dist/providers/active-llm-registry.js +186 -0
  203. package/dist/providers/auxiliary-provider.d.ts +25 -0
  204. package/dist/providers/auxiliary-provider.js +192 -0
  205. package/dist/providers/codex-oauth.d.ts +1 -1
  206. package/dist/providers/codex-oauth.js +27 -4
  207. package/dist/providers/index.d.ts +3 -0
  208. package/dist/providers/index.js +4 -0
  209. package/dist/providers/provider-catalog.d.ts +70 -0
  210. package/dist/providers/provider-catalog.js +738 -0
  211. package/dist/providers/provider-fallback.d.ts +35 -0
  212. package/dist/providers/provider-fallback.js +171 -0
  213. package/dist/providers/xai-oauth.d.ts +128 -0
  214. package/dist/providers/xai-oauth.js +735 -0
  215. package/dist/scheduler/cron-scheduler.d.ts +15 -3
  216. package/dist/scheduler/cron-scheduler.js +53 -7
  217. package/dist/scheduler/script-runner.d.ts +2 -0
  218. package/dist/scheduler/script-runner.js +19 -4
  219. package/dist/scheduler/watchdog-handlers.js +7 -20
  220. package/dist/search/usearch-index.js +7 -2
  221. package/dist/security/tool-policy/tool-groups.js +2 -0
  222. package/dist/server/index.js +17 -2
  223. package/dist/server/routes/mobile.d.ts +12 -4
  224. package/dist/server/routes/mobile.js +116 -1
  225. package/dist/server/tls-config.d.ts +35 -0
  226. package/dist/server/tls-config.js +142 -0
  227. package/dist/server/tunnel-manager.d.ts +20 -0
  228. package/dist/server/tunnel-manager.js +58 -0
  229. package/dist/server/websocket/fleet-bridge.js +5 -0
  230. package/dist/services/prompt-builder.d.ts +1 -0
  231. package/dist/services/prompt-builder.js +49 -8
  232. package/dist/shared/engine-types.d.ts +15 -1
  233. package/dist/sidecar/sidecar-bridge.d.ts +1 -0
  234. package/dist/sidecar/sidecar-bridge.js +21 -10
  235. package/dist/spec/spec-store.js +8 -1
  236. package/dist/talk-mode/providers/audioreader-tts.d.ts +1 -1
  237. package/dist/talk-mode/providers/audioreader-tts.js +8 -8
  238. package/dist/templates/project-scaffolding.js +3 -2
  239. package/dist/themes/theme-schema.d.ts +10 -10
  240. package/dist/tools/application-profiles.js +38 -0
  241. package/dist/tools/bash/bash-tool.d.ts +1 -0
  242. package/dist/tools/bash/bash-tool.js +16 -2
  243. package/dist/tools/bash/command-validator.js +3 -0
  244. package/dist/tools/bash/rtk-rewrite.d.ts +16 -0
  245. package/dist/tools/bash/rtk-rewrite.js +100 -0
  246. package/dist/tools/bash/streaming-executor.js +14 -1
  247. package/dist/tools/computer-control-tool.d.ts +16 -1
  248. package/dist/tools/computer-control-tool.js +317 -5
  249. package/dist/tools/document-generator.d.ts +14 -0
  250. package/dist/tools/document-generator.js +79 -0
  251. package/dist/tools/execute-code-rpc-invoker.d.ts +26 -2
  252. package/dist/tools/execute-code-rpc-invoker.js +46 -5
  253. package/dist/tools/metadata.js +28 -0
  254. package/dist/tools/office-macro-tool.d.ts +10 -0
  255. package/dist/tools/office-macro-tool.js +93 -0
  256. package/dist/tools/registry/index.d.ts +2 -1
  257. package/dist/tools/registry/index.js +2 -1
  258. package/dist/tools/registry/memory-tools.d.ts +20 -0
  259. package/dist/tools/registry/memory-tools.js +225 -3
  260. package/dist/tools/registry/multimodal-tools.js +2 -2
  261. package/dist/tools/registry/vision-tools.d.ts +33 -0
  262. package/dist/tools/registry/vision-tools.js +308 -6
  263. package/dist/tools/registry/windows-tools.d.ts +2 -0
  264. package/dist/tools/registry/windows-tools.js +47 -0
  265. package/dist/tools/route-peer-tool.js +14 -0
  266. package/dist/tools/screenshot-tool.js +14 -2
  267. package/dist/tools/text-to-speech-tool.d.ts +1 -1
  268. package/dist/tools/text-to-speech-tool.js +2 -12
  269. package/dist/tools/tool-selector.js +3 -59
  270. package/dist/utils/config-validation/schema.d.ts +40 -7
  271. package/dist/utils/config-validation/schema.js +130 -1
  272. package/dist/utils/cost-tracker.js +21 -1
  273. package/dist/utils/disk-guard.d.ts +180 -0
  274. package/dist/utils/disk-guard.js +404 -0
  275. package/dist/utils/interactive-setup.js +35 -2
  276. package/dist/utils/model-utils.js +11 -2
  277. package/dist/utils/output-sanitizer.js +11 -0
  278. package/dist/utils/provider-detector.d.ts +8 -7
  279. package/dist/utils/provider-detector.js +19 -77
  280. package/dist/utils/settings-manager.d.ts +7 -0
  281. package/dist/utils/token-display.d.ts +3 -3
  282. package/dist/utils/token-display.js +22 -4
  283. package/dist/wizard/onboarding.d.ts +39 -0
  284. package/dist/wizard/onboarding.js +433 -21
  285. package/dist/wizard/provider-onboarding.d.ts +8 -23
  286. package/dist/wizard/provider-onboarding.js +39 -158
  287. package/package.json +4 -2
  288. package/dist/plugins/provider-onboarding.d.ts +0 -23
  289. package/dist/plugins/provider-onboarding.js +0 -116
  290. package/dist/utils/kokoro-tts.d.ts +0 -8
  291. package/dist/utils/kokoro-tts.js +0 -67
@@ -161,6 +161,11 @@ interface BuildRequestBodyOpts {
161
161
  input: ResponsesInputItem[];
162
162
  tools: CodeBuddyTool[];
163
163
  reasoningEffort?: string;
164
+ /**
165
+ * Accepted for Provider interface parity, but deliberately not serialized:
166
+ * the ChatGPT Codex backend rejects `max_output_tokens` with 400.
167
+ */
168
+ maxTokens?: number;
164
169
  promptCacheKey?: string;
165
170
  /** When true, ask the backend to emit encrypted reasoning blobs so we
166
171
  * can re-inject them next turn (preserves chain-of-thought across
@@ -164,6 +164,7 @@ export class ChatGptResponsesProvider {
164
164
  input,
165
165
  tools,
166
166
  reasoningEffort,
167
+ maxTokens: opts.maxTokens,
167
168
  promptCacheKey: this.promptCacheKey,
168
169
  // Only ask for encrypted reasoning when reasoning effort is set —
169
170
  // saves bandwidth on plain Q&A turns.
@@ -218,7 +218,7 @@ export class GeminiNativeProvider {
218
218
  // Build generationConfig with optional thinkingConfig for Gemini 3.x
219
219
  const generationConfig = {
220
220
  temperature: opts?.temperature ?? 0.7,
221
- maxOutputTokens: this.defaultMaxTokens,
221
+ maxOutputTokens: opts?.maxTokens ?? this.defaultMaxTokens,
222
222
  };
223
223
  // Add thinkingLevel for Gemini 3.x models (never mix with budget_tokens)
224
224
  // Use explicitly passed level, or fall back to the default from settings
@@ -57,6 +57,10 @@ export declare class OpenAICompatProvider implements Provider {
57
57
  * Derive a human-readable provider name from the base URL.
58
58
  */
59
59
  getProviderName(): string;
60
+ private getOpenRouterProviderRouting;
61
+ private setListProviderOption;
62
+ private readBooleanEnv;
63
+ private readEnv;
60
64
  /**
61
65
  * Get prompt cache statistics
62
66
  */
@@ -84,6 +88,7 @@ export declare class OpenAICompatProvider implements Provider {
84
88
  private isXaiProvider;
85
89
  /** Gate legacy search_parameters by provider compatibility. */
86
90
  private shouldIncludeSearchParameters;
91
+ private getOllamaReasoningEffort;
87
92
  private isAsyncIterableStream;
88
93
  private isNonStreamingChatResponse;
89
94
  private nonStreamingResponseToChunks;
@@ -104,6 +104,61 @@ export class OpenAICompatProvider {
104
104
  return 'Local';
105
105
  return 'API';
106
106
  }
107
+ getOpenRouterProviderRouting() {
108
+ if (!this.baseURL.toLowerCase().includes('openrouter.ai'))
109
+ return undefined;
110
+ const provider = {};
111
+ this.setListProviderOption(provider, 'only', 'OPENROUTER_PROVIDER_ONLY', 'CODEBUDDY_OPENROUTER_PROVIDER_ONLY');
112
+ this.setListProviderOption(provider, 'ignore', 'OPENROUTER_PROVIDER_IGNORE', 'CODEBUDDY_OPENROUTER_PROVIDER_IGNORE');
113
+ this.setListProviderOption(provider, 'order', 'OPENROUTER_PROVIDER_ORDER', 'CODEBUDDY_OPENROUTER_PROVIDER_ORDER');
114
+ const sort = this.readEnv('OPENROUTER_PROVIDER_SORT', 'CODEBUDDY_OPENROUTER_PROVIDER_SORT')?.toLowerCase();
115
+ if (sort && ['price', 'throughput', 'latency'].includes(sort)) {
116
+ provider.sort = sort;
117
+ }
118
+ const dataCollection = this.readEnv('OPENROUTER_PROVIDER_DATA_COLLECTION', 'CODEBUDDY_OPENROUTER_PROVIDER_DATA_COLLECTION')?.toLowerCase();
119
+ if (dataCollection && ['allow', 'deny'].includes(dataCollection)) {
120
+ provider.data_collection = dataCollection;
121
+ }
122
+ const requireParameters = this.readBooleanEnv('OPENROUTER_PROVIDER_REQUIRE_PARAMETERS', 'CODEBUDDY_OPENROUTER_PROVIDER_REQUIRE_PARAMETERS');
123
+ if (requireParameters !== undefined) {
124
+ provider.require_parameters = requireParameters;
125
+ }
126
+ const allowFallbacks = this.readBooleanEnv('OPENROUTER_PROVIDER_ALLOW_FALLBACKS', 'CODEBUDDY_OPENROUTER_PROVIDER_ALLOW_FALLBACKS');
127
+ if (allowFallbacks !== undefined) {
128
+ provider.allow_fallbacks = allowFallbacks;
129
+ }
130
+ return Object.keys(provider).length > 0 ? provider : undefined;
131
+ }
132
+ setListProviderOption(provider, field, ...keys) {
133
+ const value = this.readEnv(...keys);
134
+ if (!value)
135
+ return;
136
+ const items = value
137
+ .split(',')
138
+ .map((item) => item.trim())
139
+ .filter(Boolean);
140
+ if (items.length > 0) {
141
+ provider[field] = items;
142
+ }
143
+ }
144
+ readBooleanEnv(...keys) {
145
+ const value = this.readEnv(...keys)?.toLowerCase();
146
+ if (!value)
147
+ return undefined;
148
+ if (['1', 'true', 'yes', 'on'].includes(value))
149
+ return true;
150
+ if (['0', 'false', 'no', 'off'].includes(value))
151
+ return false;
152
+ return undefined;
153
+ }
154
+ readEnv(...keys) {
155
+ for (const key of keys) {
156
+ const value = process.env[key]?.trim();
157
+ if (value)
158
+ return value;
159
+ }
160
+ return undefined;
161
+ }
107
162
  /**
108
163
  * Get prompt cache statistics
109
164
  */
@@ -270,6 +325,15 @@ export class OpenAICompatProvider {
270
325
  }
271
326
  return true;
272
327
  }
328
+ getOllamaReasoningEffort(model) {
329
+ const modelInfo = getModelInfo(model);
330
+ const isOllama = modelInfo.provider === 'ollama' ||
331
+ this.baseURL.includes('localhost:11434') ||
332
+ this.baseURL.includes('127.0.0.1:11434');
333
+ if (!isOllama)
334
+ return undefined;
335
+ return process.env.CODEBUDDY_OLLAMA_REASONING_EFFORT?.trim() || 'none';
336
+ }
273
337
  isAsyncIterableStream(value) {
274
338
  return !!value
275
339
  && typeof value === 'object'
@@ -416,8 +480,16 @@ export class OpenAICompatProvider {
416
480
  tools: useTools ? tools : [],
417
481
  tool_choice: useTools ? 'auto' : undefined,
418
482
  temperature: opts.temperature ?? 0.7,
419
- max_tokens: this.defaultMaxTokens,
483
+ max_tokens: opts.maxTokens ?? this.defaultMaxTokens,
420
484
  };
485
+ const openRouterProviderRouting = this.getOpenRouterProviderRouting();
486
+ if (openRouterProviderRouting) {
487
+ requestPayload.provider = openRouterProviderRouting;
488
+ }
489
+ const ollamaReasoningEffort = this.getOllamaReasoningEffort(requestPayload.model);
490
+ if (ollamaReasoningEffort) {
491
+ requestPayload.reasoning_effort = ollamaReasoningEffort;
492
+ }
421
493
  const searchOpts = opts.searchOptions || searchOptions;
422
494
  const searchParameters = searchOpts?.search_parameters;
423
495
  if (this.shouldIncludeSearchParameters(searchParameters)) {
@@ -539,8 +611,16 @@ export class OpenAICompatProvider {
539
611
  tools: useTools ? tools : [],
540
612
  tool_choice: useTools ? 'auto' : undefined,
541
613
  temperature: opts.temperature ?? 0.7,
542
- max_tokens: this.defaultMaxTokens,
614
+ max_tokens: opts.maxTokens ?? this.defaultMaxTokens,
543
615
  };
616
+ const openRouterProviderRouting = this.getOpenRouterProviderRouting();
617
+ if (openRouterProviderRouting) {
618
+ requestPayload.provider = openRouterProviderRouting;
619
+ }
620
+ const ollamaReasoningEffort = this.getOllamaReasoningEffort(requestPayload.model);
621
+ if (ollamaReasoningEffort) {
622
+ requestPayload.reasoning_effort = ollamaReasoningEffort;
623
+ }
544
624
  const searchOpts = opts.searchOptions || searchOptions;
545
625
  const searchParameters = searchOpts?.search_parameters;
546
626
  const searchParams = this.shouldIncludeSearchParameters(searchParameters)
@@ -58,6 +58,13 @@ ACTIONS:
58
58
  - excel_set_cell: Set an Excel cell value via Windows COM
59
59
  - excel_get_cell: Read an Excel cell value via Windows COM
60
60
  - excel_save_workbook: Save or Save As an Excel workbook via Windows COM
61
+ - powerpoint_open_presentation: Open or create a PowerPoint presentation via Windows COM
62
+ - powerpoint_add_slide: Add a slide (layoutIndex optional) via Windows COM
63
+ - powerpoint_set_text: Set text of a shape (slideIndex + shapeIndex) via Windows COM
64
+ - powerpoint_save_presentation: Save or Save As a PowerPoint presentation via Windows COM
65
+ - word_open_document: Open or create a Word document via Windows COM
66
+ - word_type_text: Append text (value) to a Word document via Windows COM
67
+ - word_save_document: Save or Save As a Word document via Windows COM
61
68
  - use_app_workflow: Execute a short sequence of computer_control steps
62
69
  - click_text: Click visible text using OCR fallback
63
70
  - click: Click at position or element ref
@@ -146,6 +153,13 @@ ACTIONS:
146
153
  'excel_set_cell',
147
154
  'excel_get_cell',
148
155
  'excel_save_workbook',
156
+ 'powerpoint_open_presentation',
157
+ 'powerpoint_add_slide',
158
+ 'powerpoint_set_text',
159
+ 'powerpoint_save_presentation',
160
+ 'word_open_document',
161
+ 'word_type_text',
162
+ 'word_save_document',
149
163
  'use_app_workflow',
150
164
  'macro',
151
165
  'click_text',
@@ -246,11 +260,23 @@ ACTIONS:
246
260
  },
247
261
  filePath: {
248
262
  type: 'string',
249
- description: 'File/folder path for app launch or Excel workbook path',
263
+ description: 'File/folder path for app launch or Office document path (Excel workbook, PowerPoint presentation, Word document)',
250
264
  },
251
265
  saveAsPath: {
252
266
  type: 'string',
253
- description: 'Save-as path for Excel workbook',
267
+ description: 'Save-as path for an Office document (Excel/PowerPoint/Word)',
268
+ },
269
+ slideIndex: {
270
+ type: 'number',
271
+ description: 'PowerPoint 1-based slide index for powerpoint_set_text',
272
+ },
273
+ shapeIndex: {
274
+ type: 'number',
275
+ description: 'PowerPoint 1-based shape index on the slide for powerpoint_set_text',
276
+ },
277
+ layoutIndex: {
278
+ type: 'number',
279
+ description: 'PowerPoint slide layout index for powerpoint_add_slide (e.g. 1=title, 2=text); defaults to 1',
254
280
  },
255
281
  sheetName: {
256
282
  type: 'string',
@@ -428,6 +454,10 @@ ACTIONS:
428
454
  type: 'boolean',
429
455
  description: 'Only include interactive elements in snapshot',
430
456
  },
457
+ useOmniParser: {
458
+ type: 'boolean',
459
+ description: 'For snapshot_with_screenshot: route the screenshot through a self-hosted OmniParser v2 server (set OMNIPARSER_API_URL) to overlay numbered bounding boxes and append parsed elements with clickable center coordinates. No-op (original snapshot) when the server is unavailable.',
460
+ },
431
461
  steps: {
432
462
  type: 'array',
433
463
  items: { type: 'object' },
@@ -12,7 +12,7 @@ export const VIEW_FILE_TOOL = {
12
12
  type: "function",
13
13
  function: {
14
14
  name: "view_file",
15
- description: "View contents of a file or list directory contents",
15
+ description: "View contents of a file or list directory contents. Read/inspect a file before editing it — never guess its contents.",
16
16
  parameters: {
17
17
  type: "object",
18
18
  properties: {
@@ -94,7 +94,7 @@ export const STR_REPLACE_EDITOR_TOOL = {
94
94
  type: "function",
95
95
  function: {
96
96
  name: "str_replace_editor",
97
- description: "Replace specific text in a file. Use this for single line edits only",
97
+ description: "Replace specific text in a file. Use this for single line edits only. After editing, verify the change with view_file.",
98
98
  parameters: {
99
99
  type: "object",
100
100
  properties: {
@@ -192,7 +192,7 @@ export const BASH_TOOL = {
192
192
  type: "function",
193
193
  function: {
194
194
  name: "bash",
195
- description: "Execute a bash command",
195
+ description: "Execute a bash command. Prefer it to check facts and state you can verify (git status, test output, file existence, exit codes) rather than assuming.",
196
196
  parameters: {
197
197
  type: "object",
198
198
  properties: {
@@ -19,7 +19,7 @@ export { FEISHU_DOC_READ_TOOL, FEISHU_DRIVE_LIST_COMMENTS_TOOL, FEISHU_DRIVE_LIS
19
19
  export { CRONJOB_TOOL, CRON_TOOLS, } from './cron-tools.js';
20
20
  export { WEB_SEARCH_TOOL, WEB_FETCH_TOOL, WEB_EXTRACT_TOOL, WEB_TOOLS, } from './web-tools.js';
21
21
  export { MULTI_EDIT_TOOL, GIT_TOOL, CODEBASE_MAP_TOOL, CODE_GRAPH_TOOL, SUBAGENT_TOOL, DOCKER_TOOL, KUBERNETES_TOOL, PROCESS_TOOL, JS_REPL_TOOL, REASON_TOOL, PLAN_TOOL, EXECUTE_CODE_TOOL, RUN_SCRIPT_TOOL, ADVANCED_TOOLS, } from './advanced-tools.js';
22
- export { PDF_TOOL, AUDIO_TOOL, TEXT_TO_SPEECH_TOOL, IMAGE_GENERATE_TOOL, VIDEO_TOOL, VIDEO_ANALYZE_TOOL, VIDEO_GENERATE_TOOL, SCREENSHOT_TOOL, CAMERA_SNAPSHOT_TOOL, CLIPBOARD_TOOL, DOCUMENT_TOOL, OCR_TOOL, VISION_ANALYZE_TOOL, DIAGRAM_TOOL, EXPORT_TOOL, QR_TOOL, ARCHIVE_TOOL, MULTIMODAL_TOOLS, } from './multimodal-tools.js';
22
+ export { PDF_TOOL, AUDIO_TOOL, TEXT_TO_SPEECH_TOOL, IMAGE_GENERATE_TOOL, VIDEO_TOOL, VIDEO_ANALYZE_TOOL, VIDEO_GENERATE_TOOL, SCREENSHOT_TOOL, CAMERA_SNAPSHOT_TOOL, CAMERA_ANALYZE_TOOL, CLIPBOARD_TOOL, DOCUMENT_TOOL, OCR_TOOL, VISION_ANALYZE_TOOL, DIAGRAM_TOOL, EXPORT_TOOL, QR_TOOL, ARCHIVE_TOOL, MULTIMODAL_TOOLS, } from './multimodal-tools.js';
23
23
  export { COMPUTER_CONTROL_TOOL, COMPUTER_CONTROL_TOOLS, } from './computer-control-tools.js';
24
24
  export { INTERNET_SCOUT_RUN_TOOL, INTERNET_SCOUT_PLAN_TOOL, BROWSER_NAVIGATE_TOOL, BROWSER_CLICK_TOOL, BROWSER_TYPE_TOOL, BROWSER_SCROLL_TOOL, BROWSER_BACK_TOOL, BROWSER_PRESS_TOOL, BROWSER_VISION_TOOL, BROWSER_TOOL, BROWSER_TOOLS, } from './browser-tools.js';
25
25
  export { A2UI_TOOL, VISUAL_CANVAS_TOOL, CANVAS_TOOLS, } from './canvas-tools.js';
@@ -39,3 +39,4 @@ export { GENERATE_DOCUMENT_TOOL, DOCUMENT_GENERATOR_TOOLS, } from './document-to
39
39
  export { SESSION_TOOLS } from './session-tools.js';
40
40
  export { GITNEXUS_ASK_TOOL, GITNEXUS_TOOLS, } from './gitnexus-tools.js';
41
41
  export type { CodeBuddyTool as Tool } from './types.js';
42
+ export * from "./windows-tools.js";
@@ -33,7 +33,7 @@ export { WEB_SEARCH_TOOL, WEB_FETCH_TOOL, WEB_EXTRACT_TOOL, WEB_TOOLS, } from '.
33
33
  // Advanced tools
34
34
  export { MULTI_EDIT_TOOL, GIT_TOOL, CODEBASE_MAP_TOOL, CODE_GRAPH_TOOL, SUBAGENT_TOOL, DOCKER_TOOL, KUBERNETES_TOOL, PROCESS_TOOL, JS_REPL_TOOL, REASON_TOOL, PLAN_TOOL, EXECUTE_CODE_TOOL, RUN_SCRIPT_TOOL, ADVANCED_TOOLS, } from './advanced-tools.js';
35
35
  // Multimodal tools
36
- export { PDF_TOOL, AUDIO_TOOL, TEXT_TO_SPEECH_TOOL, IMAGE_GENERATE_TOOL, VIDEO_TOOL, VIDEO_ANALYZE_TOOL, VIDEO_GENERATE_TOOL, SCREENSHOT_TOOL, CAMERA_SNAPSHOT_TOOL, CLIPBOARD_TOOL, DOCUMENT_TOOL, OCR_TOOL, VISION_ANALYZE_TOOL, DIAGRAM_TOOL, EXPORT_TOOL, QR_TOOL, ARCHIVE_TOOL, MULTIMODAL_TOOLS, } from './multimodal-tools.js';
36
+ export { PDF_TOOL, AUDIO_TOOL, TEXT_TO_SPEECH_TOOL, IMAGE_GENERATE_TOOL, VIDEO_TOOL, VIDEO_ANALYZE_TOOL, VIDEO_GENERATE_TOOL, SCREENSHOT_TOOL, CAMERA_SNAPSHOT_TOOL, CAMERA_ANALYZE_TOOL, CLIPBOARD_TOOL, DOCUMENT_TOOL, OCR_TOOL, VISION_ANALYZE_TOOL, DIAGRAM_TOOL, EXPORT_TOOL, QR_TOOL, ARCHIVE_TOOL, MULTIMODAL_TOOLS, } from './multimodal-tools.js';
37
37
  // Computer Control tools (Enterprise-grade)
38
38
  export { COMPUTER_CONTROL_TOOL, COMPUTER_CONTROL_TOOLS, } from './computer-control-tools.js';
39
39
  // Browser tools (Enterprise-grade CDP automation)
@@ -70,4 +70,5 @@ export { GENERATE_DOCUMENT_TOOL, DOCUMENT_GENERATOR_TOOLS, } from './document-to
70
70
  export { SESSION_TOOLS } from './session-tools.js';
71
71
  // GitNexus tools
72
72
  export { GITNEXUS_ASK_TOOL, GITNEXUS_TOOLS, } from './gitnexus-tools.js';
73
+ export * from "./windows-tools.js";
73
74
  //# sourceMappingURL=index.js.map
@@ -24,6 +24,7 @@ export declare const VIDEO_ANALYZE_TOOL: CodeBuddyTool;
24
24
  export declare const VIDEO_GENERATE_TOOL: CodeBuddyTool;
25
25
  export declare const SCREENSHOT_TOOL: CodeBuddyTool;
26
26
  export declare const CAMERA_SNAPSHOT_TOOL: CodeBuddyTool;
27
+ export declare const CAMERA_ANALYZE_TOOL: CodeBuddyTool;
27
28
  export declare const CLIPBOARD_TOOL: CodeBuddyTool;
28
29
  export declare const DOCUMENT_TOOL: CodeBuddyTool;
29
30
  export declare const OCR_TOOL: CodeBuddyTool;
@@ -96,7 +96,7 @@ export const TEXT_TO_SPEECH_TOOL = {
96
96
  },
97
97
  provider: {
98
98
  type: "string",
99
- enum: ["auto", "system", "edge-tts", "espeak", "say", "kokoro", "audioreader"],
99
+ enum: ["auto", "system", "edge-tts", "espeak", "say", "audioreader"],
100
100
  description: "TTS provider. auto detects a local provider; system uses Windows SAPI"
101
101
  },
102
102
  voice: {
@@ -351,6 +351,48 @@ export const CAMERA_SNAPSHOT_TOOL = {
351
351
  }
352
352
  }
353
353
  };
354
+ // Camera Analyze Tool - Capture a webcam frame AND describe it with a vision model
355
+ export const CAMERA_ANALYZE_TOOL = {
356
+ type: "function",
357
+ function: {
358
+ name: "camera_analyze",
359
+ description: "Capture one local webcam frame and return a natural-language description from a local multimodal vision model (default Ollama gemma4:12b). Use this to actually SEE what the camera shows, not just save a PNG. Requires ffmpeg, OS camera permission, and a reachable local vision model.",
360
+ parameters: {
361
+ type: "object",
362
+ properties: {
363
+ prompt: {
364
+ type: "string",
365
+ description: "What to ask the vision model about the frame. Default \"Describe what you see.\""
366
+ },
367
+ device: {
368
+ type: "string",
369
+ description: "Optional ffmpeg camera device. Linux example: /dev/video0; Windows: video=Integrated Camera; macOS: 0."
370
+ },
371
+ model: {
372
+ type: "string",
373
+ description: "Local multimodal model id served by Ollama. Default gemma4:12b."
374
+ },
375
+ include_ocr: {
376
+ type: "boolean",
377
+ description: "Also attach local OCR text evidence from the captured frame (default: false)."
378
+ },
379
+ ocr_language: {
380
+ type: "string",
381
+ description: "OCR language code when include_ocr is true (default: eng)."
382
+ },
383
+ output_path: {
384
+ type: "string",
385
+ description: "Optional output image path. Defaults to .codebuddy/camera/camera-<timestamp>.png in the active workspace."
386
+ },
387
+ timeout_ms: {
388
+ type: "number",
389
+ description: "Capture timeout in milliseconds (default: 10000)."
390
+ }
391
+ },
392
+ required: []
393
+ }
394
+ }
395
+ };
354
396
  // Clipboard Tool - System clipboard operations
355
397
  export const CLIPBOARD_TOOL = {
356
398
  type: "function",
@@ -799,6 +841,7 @@ export const MULTIMODAL_TOOLS = [
799
841
  VIDEO_GENERATE_TOOL,
800
842
  SCREENSHOT_TOOL,
801
843
  CAMERA_SNAPSHOT_TOOL,
844
+ CAMERA_ANALYZE_TOOL,
802
845
  CLIPBOARD_TOOL,
803
846
  DOCUMENT_TOOL,
804
847
  OCR_TOOL,
@@ -0,0 +1,2 @@
1
+ import { CodeBuddyTool } from "./types.js";
2
+ export declare const WINDOWS_TOOLS: CodeBuddyTool[];
@@ -0,0 +1,34 @@
1
+ export const WINDOWS_TOOLS = [
2
+ {
3
+ type: "function",
4
+ function: {
5
+ name: "office_macro_execute",
6
+ description: "Executes VBA or PowerShell macros directly in Windows Microsoft Office applications (Excel, Word, PowerPoint). This tool is only available on Windows.",
7
+ parameters: {
8
+ type: "object",
9
+ properties: {
10
+ application: {
11
+ type: "string",
12
+ description: "The Microsoft Office application to target",
13
+ enum: ["Excel", "Word", "PowerPoint"],
14
+ },
15
+ macroCode: {
16
+ type: "string",
17
+ description: "The VBA code or PowerShell code to execute",
18
+ },
19
+ type: {
20
+ type: "string",
21
+ description: "The type of macro code being provided",
22
+ enum: ["vba", "powershell"],
23
+ },
24
+ runHeadless: {
25
+ type: "boolean",
26
+ description: "If true, the application will run invisibly in the background and will be closed after execution.",
27
+ },
28
+ },
29
+ required: ["application", "macroCode", "type"],
30
+ },
31
+ },
32
+ },
33
+ ];
34
+ //# sourceMappingURL=windows-tools.js.map
@@ -19,7 +19,7 @@ export interface PluginToolDefinition {
19
19
  };
20
20
  }
21
21
  export type { CodeBuddyTool, JsonSchemaProperty };
22
- export { CORE_TOOLS, MORPH_EDIT_TOOL, isMorphEnabled, SEARCH_TOOLS, TODO_TOOLS, KANBAN_TOOLS, MESSAGING_TOOLS, YUANBAO_TOOLS, HOMEASSISTANT_TOOLS, MOA_TOOLS, SPOTIFY_TOOLS, X_SEARCH_TOOLS, FEISHU_TOOLS, CRON_TOOLS, WEB_TOOLS, ADVANCED_TOOLS, MULTIMODAL_TOOLS, COMPUTER_CONTROL_TOOLS, BROWSER_TOOLS, CANVAS_TOOLS, REASON_TOOL, EXECUTE_CODE_TOOL, } from "./tool-definitions/index.js";
22
+ export { CORE_TOOLS, MORPH_EDIT_TOOL, isMorphEnabled, SEARCH_TOOLS, TODO_TOOLS, KANBAN_TOOLS, MESSAGING_TOOLS, YUANBAO_TOOLS, HOMEASSISTANT_TOOLS, MOA_TOOLS, SPOTIFY_TOOLS, X_SEARCH_TOOLS, FEISHU_TOOLS, CRON_TOOLS, WEB_TOOLS, ADVANCED_TOOLS, MULTIMODAL_TOOLS, COMPUTER_CONTROL_TOOLS, BROWSER_TOOLS, CANVAS_TOOLS, REASON_TOOL, EXECUTE_CODE_TOOL, WINDOWS_TOOLS, } from "./tool-definitions/index.js";
23
23
  export declare function getBuiltinToolNames(): string[];
24
24
  /**
25
25
  * Initialize the tool registry with all built-in tools
@@ -13,10 +13,10 @@ import { applyToolFilter } from "../utils/tool-filter.js";
13
13
  import { TOOL_METADATA } from "../tools/metadata.js";
14
14
  import { getPluginMarketplace } from "../plugins/marketplace.js";
15
15
  // Import modular tool definitions
16
- import { CORE_TOOLS, MORPH_EDIT_TOOL, isMorphEnabled, SEARCH_TOOLS, TODO_TOOLS, KANBAN_TOOLS, MESSAGING_TOOLS, YUANBAO_TOOLS, HOMEASSISTANT_TOOLS, MOA_TOOLS, SPOTIFY_TOOLS, X_SEARCH_TOOLS, FEISHU_TOOLS, CRON_TOOLS, WEB_TOOLS, ADVANCED_TOOLS, MULTIMODAL_TOOLS, COMPUTER_CONTROL_TOOLS, BROWSER_TOOLS, CANVAS_TOOLS, AGENT_TOOLS, FIRECRAWL_TOOLS, LSP_TOOLS, SECRETS_TOOLS, ADVISOR_TOOLS, ASK_USER_QUESTION_TOOLS, EXIT_PLAN_MODE_TOOLS, CODEBASE_REPLACE_TOOLS, SESSION_TOOLS, GITNEXUS_TOOLS, } from "./tool-definitions/index.js";
16
+ import { CORE_TOOLS, MORPH_EDIT_TOOL, isMorphEnabled, SEARCH_TOOLS, TODO_TOOLS, KANBAN_TOOLS, MESSAGING_TOOLS, YUANBAO_TOOLS, HOMEASSISTANT_TOOLS, MOA_TOOLS, SPOTIFY_TOOLS, X_SEARCH_TOOLS, FEISHU_TOOLS, CRON_TOOLS, WEB_TOOLS, ADVANCED_TOOLS, MULTIMODAL_TOOLS, COMPUTER_CONTROL_TOOLS, BROWSER_TOOLS, CANVAS_TOOLS, AGENT_TOOLS, FIRECRAWL_TOOLS, LSP_TOOLS, SECRETS_TOOLS, ADVISOR_TOOLS, ASK_USER_QUESTION_TOOLS, EXIT_PLAN_MODE_TOOLS, CODEBASE_REPLACE_TOOLS, SESSION_TOOLS, GITNEXUS_TOOLS, WINDOWS_TOOLS, } from "./tool-definitions/index.js";
17
17
  import { FLEET_TOOLS } from "./fleet-tool-defs.js";
18
18
  // Explicit re-exports from tool-definitions (no blanket export *)
19
- export { CORE_TOOLS, MORPH_EDIT_TOOL, isMorphEnabled, SEARCH_TOOLS, TODO_TOOLS, KANBAN_TOOLS, MESSAGING_TOOLS, YUANBAO_TOOLS, HOMEASSISTANT_TOOLS, MOA_TOOLS, SPOTIFY_TOOLS, X_SEARCH_TOOLS, FEISHU_TOOLS, CRON_TOOLS, WEB_TOOLS, ADVANCED_TOOLS, MULTIMODAL_TOOLS, COMPUTER_CONTROL_TOOLS, BROWSER_TOOLS, CANVAS_TOOLS, REASON_TOOL, EXECUTE_CODE_TOOL, } from "./tool-definitions/index.js";
19
+ export { CORE_TOOLS, MORPH_EDIT_TOOL, isMorphEnabled, SEARCH_TOOLS, TODO_TOOLS, KANBAN_TOOLS, MESSAGING_TOOLS, YUANBAO_TOOLS, HOMEASSISTANT_TOOLS, MOA_TOOLS, SPOTIFY_TOOLS, X_SEARCH_TOOLS, FEISHU_TOOLS, CRON_TOOLS, WEB_TOOLS, ADVANCED_TOOLS, MULTIMODAL_TOOLS, COMPUTER_CONTROL_TOOLS, BROWSER_TOOLS, CANVAS_TOOLS, REASON_TOOL, EXECUTE_CODE_TOOL, WINDOWS_TOOLS, } from "./tool-definitions/index.js";
20
20
  export function getBuiltinToolNames() {
21
21
  const groups = [
22
22
  CORE_TOOLS,
@@ -49,6 +49,7 @@ export function getBuiltinToolNames() {
49
49
  SESSION_TOOLS,
50
50
  FLEET_TOOLS,
51
51
  GITNEXUS_TOOLS,
52
+ WINDOWS_TOOLS,
52
53
  ];
53
54
  return Array.from(new Set(groups.flatMap((tools) => tools.map((tool) => tool.function.name))));
54
55
  }
@@ -118,6 +119,8 @@ export function initializeToolRegistry() {
118
119
  registerGroup(ASK_USER_QUESTION_TOOLS);
119
120
  // ExitPlanMode tool (request approval to leave plan mode)
120
121
  registerGroup(EXIT_PLAN_MODE_TOOLS);
122
+ // Windows OS-specific tools (Office VBA, etc.)
123
+ registerGroup(WINDOWS_TOOLS, () => process.platform === 'win32');
121
124
  // Codebase replace tools
122
125
  registerGroup(CODEBASE_REPLACE_TOOLS);
123
126
  // Session tools — multi-agent coordination (Phase E wake of SessionToolExecutor).
@@ -319,29 +322,29 @@ export async function getAllCodeBuddyTools() {
319
322
  // Ensure registry is initialized with built-in tools
320
323
  initializeToolRegistry();
321
324
  const manager = getMCPManager();
322
- // Initialize MCP servers if not already done.
323
- //
324
- // In interactive mode this stays fire-and-forget: a hung/slow MCP server must
325
- // never block a turn, and the agent self-heals across turns (a missed server
326
- // simply shows up on the next round).
327
- //
328
- // In headless / one-shot mode (`buddy --print`) there is no "next round" to
329
- // recover in, and RAG tool selection is cached after the first round — so if
330
- // the lazy connection loses the race against the first selection, the MCP
331
- // tools are cached out for the entire run and the model never sees them. We
332
- // therefore await initialization here so MCP tools are present before the
333
- // first tool-selection pass. Note: this is the *lazy* init path and is
334
- // intentionally NOT gated by CODEBUDDY_DISABLE_MCP that flag only skips the
335
- // *eager* constructor init for startup speed; the await below is what makes
336
- // the lazy init win the race when the tools are actually needed.
337
- const initPromise = manager.ensureServersInitialized().catch((err) => {
338
- // Log but don't fail - MCP servers are optional
339
- if (process.env.DEBUG) {
340
- logger.warn(`MCP initialization warning: ${err.message || String(err)}`);
325
+ const mcpDisabled = process.env.CODEBUDDY_DISABLE_MCP === 'true' ||
326
+ process.env.CODEBUDDY_DISABLE_MCP === '1';
327
+ if (!mcpDisabled) {
328
+ // Initialize MCP servers if not already done.
329
+ //
330
+ // In interactive mode this stays fire-and-forget: a hung/slow MCP server
331
+ // must never block a turn, and the agent self-heals across turns (a missed
332
+ // server simply shows up on the next round).
333
+ //
334
+ // In headless / one-shot mode (`buddy --print`) there is no "next round" to
335
+ // recover in, and RAG tool selection is cached after the first round — so if
336
+ // the lazy connection loses the race against the first selection, MCP tools
337
+ // are cached out for the entire run. We therefore await initialization here
338
+ // unless MCP has explicitly been disabled for the process.
339
+ const initPromise = manager.ensureServersInitialized().catch((err) => {
340
+ // Log but don't fail - MCP servers are optional
341
+ if (process.env.DEBUG) {
342
+ logger.warn(`MCP initialization warning: ${err.message || String(err)}`);
343
+ }
344
+ });
345
+ if (process.env.CODEBUDDY_HEADLESS === 'true') {
346
+ await initPromise;
341
347
  }
342
- });
343
- if (process.env.CODEBUDDY_HEADLESS === 'true') {
344
- await initPromise;
345
348
  }
346
349
  const registry = getToolRegistry();
347
350
  const builtInTools = registry.getEnabledTools();
@@ -22,6 +22,7 @@ import { buildHermesToolsetCatalog, } from '../../agent/hermes-toolset-catalog.j
22
22
  import { buildHermesHookLifecycleManifest, renderHermesHookLifecycleManifest, } from '../../hooks/hermes-lifecycle-hooks.js';
23
23
  import { buildHermesPortalStatus, renderHermesPortalStatus, } from '../../agent/hermes-portal-status.js';
24
24
  import { buildHermesRuntimeBackendsReadiness, renderHermesRuntimeBackendsReadiness, runHermesRuntimeBackendSmoke, } from '../../agent/hermes-runtime-backends.js';
25
+ import { buildBackendLifecycleStatusReport, executeBackendLifecycleAction, renderBackendLifecycleAction, renderBackendLifecycleStatusReport, } from '../../agent/hermes-runtime-lifecycle.js';
25
26
  import { buildHermesBrowserBackendsReadiness, renderHermesBrowserBackendsReadiness, renderHermesBrowserSmoke, runHermesBrowserBackendSmoke, } from '../../agent/hermes-browser-backends.js';
26
27
  import { buildHermesMemoryProvidersReadiness, renderHermesMemoryProvidersReadiness, probeMemoryProvider, renderHermesMemoryProbe, } from '../../agent/hermes-memory-providers.js';
27
28
  import { buildHermesLearningLoopStatus, renderHermesLearningLoopStatus, } from '../../agent/hermes-learning-loop-status.js';
@@ -2455,6 +2456,47 @@ export function registerHermesCommands(program) {
2455
2456
  console.log(`Command: ${command}`);
2456
2457
  console.log(renderHermesMessagingGatewayStatus(status));
2457
2458
  });
2459
+ messaging
2460
+ .command('gateway-status')
2461
+ .description('Print gateway lifecycle status and per-platform slash-command parity')
2462
+ .option('--json', 'output JSON')
2463
+ .action(async (options) => {
2464
+ const { getGatewayLifecycle, buildSlashParityManifest, renderSlashParityManifest } = await import('../../channels/index.js');
2465
+ const lifecycle = getGatewayLifecycle();
2466
+ const gatewayStatus = lifecycle.status();
2467
+ const slashParity = buildSlashParityManifest(lifecycle.getManager());
2468
+ const command = 'buddy hermes messaging gateway-status --json';
2469
+ const payload = {
2470
+ command,
2471
+ kind: 'hermes_messaging_gateway_lifecycle_status',
2472
+ schemaVersion: 1,
2473
+ gateway: gatewayStatus,
2474
+ slashParity,
2475
+ };
2476
+ if (options.json) {
2477
+ console.log(stableJson(payload));
2478
+ return;
2479
+ }
2480
+ const lines = [
2481
+ `Command: ${command}`,
2482
+ '',
2483
+ 'Gateway lifecycle status:',
2484
+ ` Status: ${gatewayStatus.ok ? 'ok' : 'needs attention'}`,
2485
+ ` Channels: ${gatewayStatus.totalChannels} total, ${gatewayStatus.connectedCount} connected, ${gatewayStatus.disconnectedCount} disconnected, ${gatewayStatus.errorCount} errors`,
2486
+ ];
2487
+ if (gatewayStatus.channels.length > 0) {
2488
+ lines.push('');
2489
+ lines.push('Per-channel readiness:');
2490
+ for (const ch of gatewayStatus.channels) {
2491
+ lines.push(` - ${ch.channelId}: ${ch.readiness}` +
2492
+ `${ch.authenticated ? ', authenticated' : ''}` +
2493
+ `${ch.error ? `, error: ${ch.error}` : ''}`);
2494
+ }
2495
+ }
2496
+ lines.push('');
2497
+ lines.push(renderSlashParityManifest(slashParity));
2498
+ console.log(lines.join('\n'));
2499
+ });
2458
2500
  const mobile = hermes
2459
2501
  .command('mobile')
2460
2502
  .description('Inspect Hermes mobile supervision gateway readiness');
@@ -2863,6 +2905,72 @@ export function registerHermesCommands(program) {
2863
2905
  console.log(`Command: ${command}`);
2864
2906
  console.log(renderHermesRuntimeBackendsReadiness(readiness));
2865
2907
  });
2908
+ runtime
2909
+ .command('hibernate')
2910
+ .description('Hibernate (suspend) a managed runtime backend')
2911
+ .argument('<backendId>', 'backend id to hibernate (e.g. docker, ssh, modal, daytona)')
2912
+ .option('--container-id <id>', 'Docker container id or name')
2913
+ .option('--ssh-host <host>', 'SSH host for ssh backend')
2914
+ .option('--modal-app <app>', 'Modal app name')
2915
+ .option('--daytona-workspace <ws>', 'Daytona workspace id')
2916
+ .option('--json', 'output JSON')
2917
+ .action((backendId, options) => {
2918
+ const result = executeBackendLifecycleAction(backendId, 'hibernate', {
2919
+ containerId: options.containerId,
2920
+ sshHost: options.sshHost,
2921
+ modalApp: options.modalApp,
2922
+ daytonaWorkspace: options.daytonaWorkspace,
2923
+ });
2924
+ const payload = {
2925
+ kind: 'hermes_runtime_lifecycle_action',
2926
+ schemaVersion: 1,
2927
+ result,
2928
+ };
2929
+ if (options.json) {
2930
+ console.log(stableJson(payload));
2931
+ return;
2932
+ }
2933
+ console.log(renderBackendLifecycleAction(result));
2934
+ });
2935
+ runtime
2936
+ .command('wake')
2937
+ .description('Wake (resume) a managed runtime backend')
2938
+ .argument('<backendId>', 'backend id to wake (e.g. docker, ssh, modal, daytona)')
2939
+ .option('--container-id <id>', 'Docker container id or name')
2940
+ .option('--ssh-host <host>', 'SSH host for ssh backend')
2941
+ .option('--modal-app <app>', 'Modal app name')
2942
+ .option('--daytona-workspace <ws>', 'Daytona workspace id')
2943
+ .option('--json', 'output JSON')
2944
+ .action((backendId, options) => {
2945
+ const result = executeBackendLifecycleAction(backendId, 'wake', {
2946
+ containerId: options.containerId,
2947
+ sshHost: options.sshHost,
2948
+ modalApp: options.modalApp,
2949
+ daytonaWorkspace: options.daytonaWorkspace,
2950
+ });
2951
+ const payload = {
2952
+ kind: 'hermes_runtime_lifecycle_action',
2953
+ schemaVersion: 1,
2954
+ result,
2955
+ };
2956
+ if (options.json) {
2957
+ console.log(stableJson(payload));
2958
+ return;
2959
+ }
2960
+ console.log(renderBackendLifecycleAction(result));
2961
+ });
2962
+ runtime
2963
+ .command('lifecycle-status')
2964
+ .description('Show lifecycle state for all runtime backends')
2965
+ .option('--json', 'output JSON')
2966
+ .action((options) => {
2967
+ const report = buildBackendLifecycleStatusReport();
2968
+ if (options.json) {
2969
+ console.log(stableJson(report));
2970
+ return;
2971
+ }
2972
+ console.log(renderBackendLifecycleStatusReport(report));
2973
+ });
2866
2974
  hermes
2867
2975
  .command('runtime-smoke')
2868
2976
  .description('Run an opt-in live smoke for one Hermes runtime backend')