@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
@@ -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')
@@ -101,6 +101,129 @@ export function registerImproveCommands(program) {
101
101
  .join('\n');
102
102
  print({ ...result, committed }, options, text);
103
103
  });
104
+ improve
105
+ .command('tools')
106
+ .description('Author + behaviorally validate NEW tools for the agent (held-out gated, anti-gaming)')
107
+ .option('--json', 'output JSON')
108
+ .option('--apply', 'keep validated tools for this session (overrides propose-only)')
109
+ .action(async (options) => {
110
+ const { ToolImprovementEngine } = await import('../../agent/self-improvement/tool-engine.js');
111
+ const { LlmToolProposer } = await import('../../agent/self-improvement/llm-tool-proposer.js');
112
+ const { SEED_TOOL_SCENARIOS } = await import('../../agent/self-improvement/tool-benchmark.js');
113
+ const engine = new ToolImprovementEngine({
114
+ scenarios: SEED_TOOL_SCENARIOS,
115
+ proposer: new LlmToolProposer(),
116
+ ...(options.apply ? { autonomy: 'auto-apply' } : {}),
117
+ });
118
+ const results = await engine.runLoop();
119
+ const kept = results.map((r) => (r.applied ? r.gate?.appliedRef : null)).filter(Boolean);
120
+ const text = [
121
+ `Autonomy: ${results[0]?.autonomy ?? 'propose-only'}`,
122
+ `Cycles: ${results.length}`,
123
+ ...results.map((r) => ` ${r.selectedScenarioId ?? '—'}: ${r.applied
124
+ ? `AUTHORED + KEPT (${r.gate?.appliedRef})`
125
+ : r.gate?.accepted
126
+ ? 'accepted (propose-only) — re-run with --apply to keep'
127
+ : r.gate?.rejectionReason
128
+ ? `rejected (${r.gate.rejectionReason})`
129
+ : r.notes.join('; ')}`),
130
+ kept.length
131
+ ? `Kept: ${kept.join(', ')} (archived + persisted to .codebuddy/self-improvement; reloaded at next start when CODEBUDDY_SELF_IMPROVE=true)`
132
+ : 'No tool kept this run',
133
+ ].join('\n');
134
+ print({ kind: 'self_improvement_tools', cycles: results }, options, text);
135
+ });
136
+ improve
137
+ .command('skills')
138
+ .description('Author + safety-gate NEW skills for the agent (firewall + coverage)')
139
+ .option('--json', 'output JSON')
140
+ .option('--apply', 'install validated skills (overrides propose-only)')
141
+ .action(async (options) => {
142
+ const { SkillImprovementEngine } = await import('../../agent/self-improvement/skill-engine.js');
143
+ const { LlmSkillProposer } = await import('../../agent/self-improvement/skill-proposer.js');
144
+ const { SEED_SKILL_SCENARIOS } = await import('../../agent/self-improvement/skill-benchmark.js');
145
+ const engine = new SkillImprovementEngine({
146
+ scenarios: SEED_SKILL_SCENARIOS,
147
+ proposer: new LlmSkillProposer(),
148
+ ...(options.apply ? { autonomy: 'auto-apply' } : {}),
149
+ });
150
+ const results = await engine.runLoop();
151
+ const kept = results.map((r) => (r.applied ? r.gate?.appliedRef : null)).filter(Boolean);
152
+ const text = [
153
+ `Autonomy: ${results[0]?.autonomy ?? 'propose-only'}`,
154
+ `Cycles: ${results.length}`,
155
+ ...results.map((r) => ` ${r.selectedScenarioId ?? '—'}: ${r.applied
156
+ ? `AUTHORED + INSTALLED (${r.gate?.appliedRef})`
157
+ : r.gate?.accepted
158
+ ? 'accepted (propose-only) — re-run with --apply to install'
159
+ : r.gate?.rejectionReason
160
+ ? `rejected (${r.gate.rejectionReason})`
161
+ : r.notes.join('; ')}`),
162
+ kept.length ? `Installed: ${kept.join(', ')} (under .codebuddy/skills/authored)` : 'No skill installed this run',
163
+ ].join('\n');
164
+ print({ kind: 'self_improvement_skills', cycles: results }, options, text);
165
+ });
166
+ improve
167
+ .command('skills-list')
168
+ .description('List installed authored skills (with pinned status)')
169
+ .option('--json', 'output JSON')
170
+ .action(async (options) => {
171
+ const { LiveSkillMutator } = await import('../../agent/self-improvement/skill-mutator.js');
172
+ const m = new LiveSkillMutator();
173
+ const skills = m.listAuthored().map((name) => ({ name, pinned: m.isPinned(name) }));
174
+ const text = skills.length
175
+ ? skills.map((s) => ` ${s.pinned ? '📌' : ' '} ${s.name}`).join('\n')
176
+ : 'No authored skills installed';
177
+ print({ kind: 'authored_skills', skills }, options, text);
178
+ });
179
+ improve
180
+ .command('skills-pin <name>')
181
+ .description('Pin an authored skill (protect it from curation overwrite/remove/consolidation)')
182
+ .option('--json', 'output JSON')
183
+ .action(async (name, options) => {
184
+ const { LiveSkillMutator } = await import('../../agent/self-improvement/skill-mutator.js');
185
+ const ok = new LiveSkillMutator().pin(name);
186
+ print({ kind: 'skill_pin', name, ok }, options, ok ? `Pinned ${name}` : `Skill not found: ${name}`);
187
+ });
188
+ improve
189
+ .command('skills-unpin <name>')
190
+ .description('Unpin an authored skill')
191
+ .option('--json', 'output JSON')
192
+ .action(async (name, options) => {
193
+ const { LiveSkillMutator } = await import('../../agent/self-improvement/skill-mutator.js');
194
+ const ok = new LiveSkillMutator().unpin(name);
195
+ print({ kind: 'skill_unpin', name, ok }, options, ok ? `Unpinned ${name}` : `Skill not found: ${name}`);
196
+ });
197
+ improve
198
+ .command('skills-restore <name>')
199
+ .description('Restore a previously archived authored skill')
200
+ .option('--json', 'output JSON')
201
+ .action(async (name, options) => {
202
+ const { LiveSkillMutator } = await import('../../agent/self-improvement/skill-mutator.js');
203
+ const ok = new LiveSkillMutator().restore(name);
204
+ print({ kind: 'skill_restore', name, ok }, options, ok ? `Restored ${name}` : `No archived skill: ${name}`);
205
+ });
206
+ improve
207
+ .command('skills-consolidate')
208
+ .description('Merge overlapping authored skills into one umbrella (coverage-gated)')
209
+ .option('--json', 'output JSON')
210
+ .option('--apply', 'install the umbrella + archive merged siblings (else preview)')
211
+ .action(async (options) => {
212
+ const { LiveSkillMutator } = await import('../../agent/self-improvement/skill-mutator.js');
213
+ const { consolidateCluster, buildClusterFromInstalled, LlmUmbrellaProposer } = await import('../../agent/self-improvement/skill-consolidator.js');
214
+ const { SEED_SKILL_SCENARIOS } = await import('../../agent/self-improvement/skill-benchmark.js');
215
+ const mutator = new LiveSkillMutator();
216
+ const cluster = buildClusterFromInstalled(mutator, SEED_SKILL_SCENARIOS);
217
+ const out = await consolidateCluster(cluster, new LlmUmbrellaProposer(), mutator, new EvolutionaryArchive(), {
218
+ keepOnAccept: options.apply === true,
219
+ });
220
+ const text = out.accepted
221
+ ? out.absorbed.length
222
+ ? `Consolidated ${out.absorbed.join(', ')} into ${out.umbrellaName}` + (out.skippedPinned.length ? ` (kept pinned: ${out.skippedPinned.join(', ')})` : '')
223
+ : `Would consolidate into ${out.umbrellaName} — re-run with --apply` + (out.skippedPinned.length ? ` (would keep pinned: ${out.skippedPinned.join(', ')})` : '')
224
+ : `No consolidation: ${out.rejectionReason} — ${out.reasons.join('; ')}`;
225
+ print({ kind: 'skill_consolidation', ...out }, options, text);
226
+ });
104
227
  improve
105
228
  .command('loop')
106
229
  .description('Run improvement cycles until no further validated progress is made')
@@ -9,6 +9,16 @@ import { buildHeartbeatStatusReport } from '../../daemon/status-reports.js';
9
9
  // Heartbeat commands
10
10
  // ============================================================================
11
11
  export { buildHeartbeatStatusReport };
12
+ function parsePositiveIntegerCliOption(value, flagName) {
13
+ if (value === undefined)
14
+ return undefined;
15
+ const trimmed = value.trim();
16
+ const n = Number(trimmed);
17
+ if (!/^[1-9]\d*$/.test(trimmed) || !Number.isSafeInteger(n)) {
18
+ throw new Error(`${flagName} must be a positive integer`);
19
+ }
20
+ return n;
21
+ }
12
22
  export function registerHeartbeatCommands(program) {
13
23
  const heartbeat = program
14
24
  .command('heartbeat')
@@ -745,7 +755,7 @@ export function registerFleetAutonomyCommands(program) {
745
755
  .action(async (opts) => {
746
756
  const { createDefaultAutonomousLoop, FleetAutonomousDaemon, watchFleetTasks } = await import('../../daemon/autonomous-daemon.js');
747
757
  const path = await import('path');
748
- const loop = createDefaultAutonomousLoop({
758
+ const loop = await createDefaultAutonomousLoop({
749
759
  ...(opts.dir ? { dir: opts.dir } : {}),
750
760
  ...(opts.outputDir ? { outputDir: opts.outputDir } : {}),
751
761
  });
@@ -780,6 +790,86 @@ export function registerFleetAutonomyCommands(program) {
780
790
  console.log(`\nDone: ${summary.ticks} tick(s), ${JSON.stringify(summary.outcomes)} (${summary.stoppedReason}).`);
781
791
  }
782
792
  });
793
+ fleet
794
+ .command('bench')
795
+ .description('Benchmark live Tailnet Ollama peers and rank the network model tier')
796
+ .option('--peer <pattern>', 'only benchmark peers whose hostname or IP contains the pattern')
797
+ .option('--models <csv>', 'only benchmark models whose name contains one of the comma-separated patterns')
798
+ .option('--prompt-set <name>', 'prompt set: balanced, coding, or latency', 'coding')
799
+ .option('--runs <n>', 'repeat the prompt set N times per candidate', '1')
800
+ .option('--timeout <ms>', 'request timeout per prompt', '60000')
801
+ .option('--json', 'output JSON')
802
+ .option('--no-write-cache', 'do not persist the score cache used by the router')
803
+ .action(async (opts) => {
804
+ const { TailscaleManager } = await import('../../integrations/tailscale.js');
805
+ const { BENCHMARK_PROMPT_SETS, benchmarkCandidates, writeBenchmarkIndex, defaultBenchmarkIndexPath, } = await import('../../agent/model-benchmark.js');
806
+ const peers = await TailscaleManager.getInstance().discoverOllamaPeers();
807
+ const filteredPeers = opts.peer
808
+ ? peers.filter((peer) => peer.hostname.toLowerCase().includes(opts.peer.toLowerCase())
809
+ || peer.ip.includes(opts.peer.trim()))
810
+ : peers;
811
+ const modelFilters = opts.models
812
+ ? opts.models.split(',').map((part) => part.trim()).filter(Boolean)
813
+ : [];
814
+ const candidates = filteredPeers.flatMap((peer) => peer.models
815
+ .filter((model) => modelFilters.length === 0
816
+ ? true
817
+ : modelFilters.some((filter) => model.toLowerCase().includes(filter.toLowerCase())))
818
+ .map((model) => ({
819
+ model,
820
+ baseUrl: peer.baseURL,
821
+ label: peer.hostname,
822
+ })));
823
+ if (candidates.length === 0) {
824
+ const message = opts.peer
825
+ ? `No Tailnet Ollama peers matched "${opts.peer}".`
826
+ : 'No Tailnet Ollama peers were discovered.';
827
+ if (opts.json) {
828
+ console.log(JSON.stringify({ ok: false, error: message }, null, 2));
829
+ return;
830
+ }
831
+ console.log(message);
832
+ return;
833
+ }
834
+ const suite = BENCHMARK_PROMPT_SETS[opts.promptSet] ? opts.promptSet : 'coding';
835
+ const reports = await benchmarkCandidates(candidates, {
836
+ promptSet: suite,
837
+ runs: Math.max(1, parseInt(opts.runs, 10) || 1),
838
+ timeoutMs: Math.max(5_000, parseInt(opts.timeout, 10) || 60_000),
839
+ });
840
+ const ranked = [...reports].sort((a, b) => b.summary.score - a.summary.score);
841
+ let indexPath;
842
+ if (opts.writeCache !== false) {
843
+ indexPath = defaultBenchmarkIndexPath();
844
+ await writeBenchmarkIndex(ranked, suite, indexPath);
845
+ }
846
+ const best = ranked[0];
847
+ if (opts.json) {
848
+ console.log(JSON.stringify({
849
+ ok: true,
850
+ suite,
851
+ indexPath,
852
+ best,
853
+ reports: ranked,
854
+ }, null, 2));
855
+ return;
856
+ }
857
+ console.log(`\nTailnet Ollama benchmark (${suite})`);
858
+ if (indexPath)
859
+ console.log(` Cache: ${indexPath}`);
860
+ console.log(` Candidates: ${ranked.length}`);
861
+ if (best) {
862
+ console.log(` Best: ${best.candidate.label ?? best.candidate.model} / ${best.candidate.model}`);
863
+ console.log(` Score: ${best.summary.score.toFixed(1)} compliance ${(best.summary.complianceRate * 100).toFixed(0)}% ttft ${Math.round(best.summary.avgTtftMs)}ms total ${Math.round(best.summary.avgTotalMs)}ms`);
864
+ }
865
+ console.log('');
866
+ ranked.forEach((report, index) => {
867
+ console.log(`${String(index + 1).padStart(2, ' ')}. ${report.candidate.label ?? report.candidate.model} / ${report.candidate.model}`);
868
+ console.log(` ${report.candidate.baseUrl}`);
869
+ console.log(` score=${report.summary.score.toFixed(1)} compliance=${(report.summary.complianceRate * 100).toFixed(0)}% ttft=${Math.round(report.summary.avgTtftMs)}ms total=${Math.round(report.summary.avgTotalMs)}ms`);
870
+ });
871
+ console.log('');
872
+ });
783
873
  fleet
784
874
  .command('status')
785
875
  .description('Show the fleet task queue + presence')
@@ -822,6 +912,15 @@ export function registerFleetAutonomyCommands(program) {
822
912
  .option('--dir <path>', 'colab dir')
823
913
  .option('--json', 'output JSON')
824
914
  .action(async (title, opts) => {
915
+ let goalMaxTurns;
916
+ try {
917
+ goalMaxTurns = parsePositiveIntegerCliOption(opts.goalMaxTurns, '--goal-max-turns');
918
+ }
919
+ catch (error) {
920
+ console.error(error instanceof Error ? error.message : String(error));
921
+ process.exit(1);
922
+ return;
923
+ }
825
924
  const { FleetColabStore } = await import('../../fleet/colab-store.js');
826
925
  const store = new FleetColabStore({ ...(opts.dir ? { dir: opts.dir } : {}) });
827
926
  const priority = ['critical', 'high', 'medium', 'low'].find((p) => p === opts.priority) ?? 'medium';
@@ -831,7 +930,7 @@ export function registerFleetAutonomyCommands(program) {
831
930
  ...(opts.description ? { description: opts.description } : {}),
832
931
  ...(opts.dependsOn ? { dependsOn: opts.dependsOn.split(',').map((s) => s.trim()).filter(Boolean) } : {}),
833
932
  ...(opts.goalMode ? { goalMode: true } : {}),
834
- ...(opts.goalMaxTurns ? { goalMaxTurns: parseInt(opts.goalMaxTurns, 10) } : {}),
933
+ ...(goalMaxTurns !== undefined ? { goalMaxTurns } : {}),
835
934
  });
836
935
  if (opts.json) {
837
936
  console.log(JSON.stringify({ task }, null, 2));
@@ -1129,7 +1228,7 @@ export function registerCompanionCommands(program) {
1129
1228
  .option('--no-set-model', 'Do not set the project model to the ChatGPT companion default')
1130
1229
  .option('--language <lang>', 'Voice language', 'fr')
1131
1230
  .option('--stt-provider <provider>', 'Voice input provider (system, whisper-local, whisper-api)')
1132
- .option('--tts-provider <provider>', 'TTS provider (edge-tts, espeak, say, piper, audioreader, kokoro)')
1231
+ .option('--tts-provider <provider>', 'TTS provider (edge-tts, espeak, say, piper, audioreader)')
1133
1232
  .option('--tts-voice <voice>', 'TTS voice name')
1134
1233
  .option('--model <model>', 'ChatGPT model to use when OAuth credentials are present')
1135
1234
  .action(async (opts) => {
@@ -4,6 +4,7 @@
4
4
  * Extracted from index.ts for modularity.
5
5
  */
6
6
  import { resolve } from 'path';
7
+ import { buildOllamaUpdatePlan, fetchOllamaStatus, runOllamaUpdatePlan } from '../ollama.js';
7
8
  function resolveCommandDirectory(program) {
8
9
  const directory = program.opts().directory;
9
10
  return resolve(process.cwd(), directory || process.cwd());
@@ -93,6 +94,50 @@ export function registerUtilityCommands(program) {
93
94
  const { runOnboarding } = await import('../../wizard/onboarding.js');
94
95
  await runOnboarding();
95
96
  });
97
+ const ollamaCommand = program
98
+ .command('ollama')
99
+ .description('Inspect or update the local Ollama runtime');
100
+ ollamaCommand
101
+ .command('status')
102
+ .description('Show local Ollama version and models')
103
+ .option('--url <url>', 'Ollama base URL', process.env.OLLAMA_HOST ?? 'http://localhost:11434')
104
+ .option('--json', 'Output JSON')
105
+ .action(async (options) => {
106
+ const status = await fetchOllamaStatus(options.url);
107
+ if (options.json) {
108
+ console.log(JSON.stringify(status, null, 2));
109
+ return;
110
+ }
111
+ console.log('\nOllama status\n');
112
+ console.log(` Base URL: ${status.baseUrl}`);
113
+ console.log(` Reachable: ${status.reachable ? 'YES' : 'NO'}`);
114
+ console.log(` Version: ${status.version ?? '(unknown)'}`);
115
+ console.log(` Models: ${status.models.length > 0 ? status.models.join(', ') : '(none)'}`);
116
+ if (status.error) {
117
+ console.log(` Error: ${status.error}`);
118
+ }
119
+ console.log('');
120
+ });
121
+ ollamaCommand
122
+ .command('update')
123
+ .description('Run the official Ollama Windows update script')
124
+ .option('--script-url <url>', 'Official installer/update script URL', 'https://ollama.com/install.ps1')
125
+ .option('--repo-root <dir>', 'Repository root', resolveCommandDirectory(program))
126
+ .action(async (options) => {
127
+ const plan = buildOllamaUpdatePlan({
128
+ repoRoot: options.repoRoot,
129
+ scriptUrl: options.scriptUrl,
130
+ });
131
+ if (!plan.supported) {
132
+ console.error(plan.message);
133
+ console.error(`Use the update script directly on Windows: ${plan.scriptPath}`);
134
+ process.exit(1);
135
+ return;
136
+ }
137
+ console.log(`Running Ollama updater: ${plan.scriptPath}`);
138
+ await runOllamaUpdatePlan(plan);
139
+ console.log('Ollama update completed.');
140
+ });
96
141
  // Webhook command
97
142
  const webhookCommand = program
98
143
  .command('webhook')
@@ -314,7 +314,7 @@ export class EnhancedCommandHandler {
314
314
  ['__ULTRAPLAN__', (args) => handleUltraplan(args)],
315
315
  ['__LIST_CHECKPOINTS__', (args) => handleListCheckpoints(args)],
316
316
  ['__RESTORE_CHECKPOINT__', (args) => handleRestoreCheckpoint(args)],
317
- ['__INIT_GROK__', () => handleInitGrok()],
317
+ ['__INIT_GROK__', (args) => handleInitGrok(args)],
318
318
  ['__REINIT_GROK__', () => handleReinitGrok()],
319
319
  ['__FEATURES__', () => handleFeatures()],
320
320
  ['__LESSONS__', (args) => handleLessonsCommand(args.join(' '))],
@@ -340,7 +340,7 @@ export class EnhancedCommandHandler {
340
340
  // Heartbeat engine activation (fleet AUTONOMOUS-FLEET-PROTOCOL v0.1)
341
341
  ['__HEARTBEAT__', (args) => handleHeartbeat(args)],
342
342
  // Standing goal — judge + auto-continue loop (Hermes Agent parity)
343
- ['__GOAL__', (args) => handleGoal(args)],
343
+ ['__GOAL__', (args) => handleGoal(args, { client: this.codebuddyClient })],
344
344
  ['__SUBGOAL__', (args) => handleSubgoal(args)],
345
345
  // Daily reset scheduler (audit OpenClaw heritage activation)
346
346
  ['__DAILY_RESET__', (args) => handleDailyReset(args)],
@@ -15,14 +15,22 @@
15
15
  import { Command } from 'commander';
16
16
  import type { ChatEntry } from '../agent/codebuddy-agent.js';
17
17
  import type { CodeBuddyClient } from '../codebuddy/client.js';
18
+ import { type GoalJudgeProviderInfo } from '../goals/goal-judge-client.js';
18
19
  import { GoalStatus } from '../goals/goal-state.js';
19
20
  /** The slice of CodeBuddyAgent the loop needs — injectable for tests. */
20
21
  export interface GoalLoopAgent {
21
22
  processUserMessage(input: string): Promise<ChatEntry[]>;
22
23
  getClient(): CodeBuddyClient;
23
24
  }
25
+ export interface GoalCommandRuntimeAgent extends GoalLoopAgent {
26
+ systemPromptReady: Promise<unknown>;
27
+ setSystemPrompt?: (prompt: string) => void;
28
+ dispose?: () => void | Promise<void>;
29
+ }
24
30
  export interface GoalLoopRunOptions {
25
31
  maxTurns?: number;
32
+ /** Optional standalone judge client. Defaults to the agent client. */
33
+ judgeClient?: CodeBuddyClient;
26
34
  /** Progress sink (status lines ⊙/↻/✓/⏸). Defaults to silent. */
27
35
  onMessage?: (text: string) => void;
28
36
  }
@@ -31,6 +39,19 @@ export interface GoalLoopRunResult {
31
39
  turnsUsed: number;
32
40
  lastReason?: string;
33
41
  }
42
+ export interface GoalCommandRuntimeOptions {
43
+ maxTurns?: number;
44
+ judgeModel?: string;
45
+ provider: GoalJudgeProviderInfo;
46
+ workingDirectory?: string;
47
+ onMessage?: (text: string) => void;
48
+ createJudgeClient?: typeof createStandaloneJudgeClient;
49
+ runLoop?: typeof runGoalLoop;
50
+ }
51
+ export declare const LOCAL_GOAL_ACTOR_SYSTEM_PROMPT: string;
52
+ export declare function buildLocalGoalActorSystemPrompt(workingDirectory?: string): string;
53
+ export declare function shouldUseLocalGoalActorPrompt(provider: GoalJudgeProviderInfo): boolean;
54
+ export declare function resolveLocalGoalActorSystemPrompt(provider: GoalJudgeProviderInfo, workingDirectory?: string): string | undefined;
34
55
  /**
35
56
  * Drive the goal loop headlessly on an in-process agent. Sets the goal,
36
57
  * runs the first turn with the goal text (mirroring the interactive
@@ -38,4 +59,13 @@ export interface GoalLoopRunResult {
38
59
  * stops continuing.
39
60
  */
40
61
  export declare function runGoalLoop(agent: GoalLoopAgent, goalText: string, options?: GoalLoopRunOptions): Promise<GoalLoopRunResult>;
62
+ declare function createStandaloneJudgeClient(judgeModel: string | undefined, agentProvider: GoalJudgeProviderInfo, currentClient: CodeBuddyClient): Promise<CodeBuddyClient | undefined>;
63
+ export declare function runGoalCommandWithAgent(agent: GoalCommandRuntimeAgent, goal: string, options: GoalCommandRuntimeOptions): Promise<GoalLoopRunResult>;
64
+ export declare function resolveGoalCliJudgeModel(explicitJudgeModel: string | undefined): string | undefined;
65
+ export declare function resolveGoalCliMaxToolRounds(commandValue: number | undefined, command?: Command): number;
66
+ export declare function resolveGoalCliWorkingDirectory(command?: Command): string | undefined;
67
+ export declare function applyGoalCliWorkingDirectory(command?: Command): string;
68
+ export declare function parsePositiveIntegerOption(value: string, optionName: string): number;
69
+ export declare function validateGoalCommandNumericOptions(argv: readonly string[]): void;
41
70
  export declare function createGoalCommand(): Command;
71
+ export {};