@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
@@ -0,0 +1,35 @@
1
+ import { type ResolvedRuntimeProvider } from './provider-catalog.js';
2
+ import type { AuthProfile } from '../auth/profile-manager.js';
3
+ type EnvLike = Record<string, string | undefined>;
4
+ export type RuntimeFallbackSource = 'environment' | 'auth-profile';
5
+ export interface RuntimeAuthProfilePool {
6
+ getHealthyProfiles(): AuthProfile[];
7
+ markFailed(profileId: string, error: string, isBilling?: boolean): void;
8
+ markSuccess(profileId: string): void;
9
+ }
10
+ export interface RuntimeFallbackProvider extends ResolvedRuntimeProvider {
11
+ model: string;
12
+ rawSpec: string;
13
+ fallbackSource: RuntimeFallbackSource;
14
+ profileId?: string;
15
+ profileManager?: RuntimeAuthProfilePool;
16
+ }
17
+ export interface RuntimeFallbackResolveOptions {
18
+ env?: EnvLike;
19
+ hasChatGptOAuth?: boolean;
20
+ active?: {
21
+ provider?: string;
22
+ apiKey?: string;
23
+ baseURL?: string;
24
+ model?: string;
25
+ };
26
+ }
27
+ export interface RuntimeCredentialPoolResolveOptions {
28
+ active?: RuntimeFallbackResolveOptions['active'];
29
+ authProfileManager?: RuntimeAuthProfilePool;
30
+ }
31
+ export declare function resolveRuntimeFallbackProviders(options?: RuntimeFallbackResolveOptions): RuntimeFallbackProvider[];
32
+ export declare function resolveRuntimeCredentialPoolProviders(options?: RuntimeCredentialPoolResolveOptions): RuntimeFallbackProvider[];
33
+ export declare function recordRuntimeFallbackSuccess(fallback: RuntimeFallbackProvider): void;
34
+ export declare function recordRuntimeFallbackFailure(fallback: RuntimeFallbackProvider, error: unknown): void;
35
+ export {};
@@ -0,0 +1,171 @@
1
+ import { hasCodexCredentials } from './codex-oauth.js';
2
+ import { findRuntimeProvider, getDirectRuntimeProviderCatalog, resolveProviderFromCatalog, } from './provider-catalog.js';
3
+ import { getAuthProfileManager } from '../auth/profile-manager.js';
4
+ export function resolveRuntimeFallbackProviders(options = {}) {
5
+ const env = options.env ?? process.env;
6
+ const specs = parseFallbackSpecs(env);
7
+ if (specs.length === 0)
8
+ return [];
9
+ const hasOAuth = options.hasChatGptOAuth ?? hasCodexCredentials();
10
+ const activeBaseURL = options.active?.baseURL?.replace(/\/+$/, '');
11
+ const activeModel = options.active?.model;
12
+ const seen = new Set();
13
+ const resolved = [];
14
+ for (const spec of specs) {
15
+ const provider = resolveProviderFromCatalog({
16
+ providerOverride: spec.provider,
17
+ env,
18
+ hasChatGptOAuth: hasOAuth,
19
+ requireConfigured: true,
20
+ });
21
+ if (!provider)
22
+ continue;
23
+ const model = spec.model || provider.defaultModel;
24
+ const baseURL = provider.baseURL.replace(/\/+$/, '');
25
+ if (activeBaseURL === baseURL && activeModel === model)
26
+ continue;
27
+ const key = `${provider.provider}:${baseURL}:${model}`;
28
+ if (seen.has(key))
29
+ continue;
30
+ seen.add(key);
31
+ resolved.push({
32
+ ...provider,
33
+ model,
34
+ rawSpec: spec.rawSpec,
35
+ fallbackSource: 'environment',
36
+ });
37
+ }
38
+ return resolved;
39
+ }
40
+ export function resolveRuntimeCredentialPoolProviders(options = {}) {
41
+ const manager = options.authProfileManager ?? getAuthProfileManager();
42
+ const activeProvider = canonicalProviderId(options.active?.provider ?? inferRuntimeProviderIdFromBaseURL(options.active?.baseURL));
43
+ if (!activeProvider)
44
+ return [];
45
+ const activeApiKey = options.active?.apiKey;
46
+ const seen = new Set();
47
+ const resolved = [];
48
+ for (const profile of manager.getHealthyProfiles()) {
49
+ const profileProvider = canonicalProviderId(profile.provider);
50
+ if (profileProvider !== activeProvider)
51
+ continue;
52
+ const provider = resolveProfileProvider(profile);
53
+ if (!provider)
54
+ continue;
55
+ const model = profile.metadata.model || provider.defaultModel;
56
+ const baseURL = (profile.metadata.baseURL || provider.baseURL).replace(/\/+$/, '');
57
+ const apiKey = profile.credentials.apiKey || profile.credentials.accessToken || provider.apiKey;
58
+ if (!apiKey)
59
+ continue;
60
+ if (activeApiKey && apiKey === activeApiKey)
61
+ continue;
62
+ const key = `${provider.provider}:${baseURL}:${model}:${profile.id}`;
63
+ if (seen.has(key))
64
+ continue;
65
+ seen.add(key);
66
+ resolved.push({
67
+ ...provider,
68
+ apiKey,
69
+ baseURL,
70
+ defaultModel: model,
71
+ model,
72
+ rawSpec: `auth-profile:${profile.id}`,
73
+ fallbackSource: 'auth-profile',
74
+ profileId: profile.id,
75
+ profileManager: manager,
76
+ });
77
+ }
78
+ return resolved;
79
+ }
80
+ export function recordRuntimeFallbackSuccess(fallback) {
81
+ if (fallback.fallbackSource !== 'auth-profile' || !fallback.profileId)
82
+ return;
83
+ fallback.profileManager?.markSuccess(fallback.profileId);
84
+ }
85
+ export function recordRuntimeFallbackFailure(fallback, error) {
86
+ if (fallback.fallbackSource !== 'auth-profile' || !fallback.profileId)
87
+ return;
88
+ fallback.profileManager?.markFailed(fallback.profileId, error instanceof Error ? error.message : String(error), isBillingLikeProviderError(error));
89
+ }
90
+ function parseFallbackSpecs(env) {
91
+ const specs = [];
92
+ const list = env.CODEBUDDY_FALLBACK_PROVIDERS?.trim();
93
+ if (list) {
94
+ specs.push(...list.split(','));
95
+ }
96
+ const singleProvider = env.CODEBUDDY_FALLBACK_PROVIDER?.trim();
97
+ if (singleProvider) {
98
+ const singleModel = env.CODEBUDDY_FALLBACK_MODEL?.trim();
99
+ specs.push(singleModel ? `${singleProvider}:${singleModel}` : singleProvider);
100
+ }
101
+ return specs
102
+ .map(parseFallbackSpec)
103
+ .filter((spec) => spec !== null);
104
+ }
105
+ function parseFallbackSpec(spec) {
106
+ const rawSpec = spec.trim();
107
+ if (!rawSpec)
108
+ return null;
109
+ const separator = rawSpec.indexOf(':');
110
+ if (separator === -1) {
111
+ return { provider: rawSpec, rawSpec };
112
+ }
113
+ const provider = rawSpec.slice(0, separator).trim();
114
+ const model = rawSpec.slice(separator + 1).trim();
115
+ if (!provider)
116
+ return null;
117
+ return {
118
+ provider,
119
+ model: model || undefined,
120
+ rawSpec,
121
+ };
122
+ }
123
+ function resolveProfileProvider(profile) {
124
+ const entry = findRuntimeProvider(profile.provider);
125
+ if (!entry || entry.runtimeSupport !== 'direct')
126
+ return null;
127
+ return {
128
+ provider: entry.id,
129
+ label: entry.label,
130
+ apiMode: entry.apiMode,
131
+ authMode: entry.authMode,
132
+ apiKey: profile.credentials.apiKey || profile.credentials.accessToken || entry.apiKeyPlaceholder || '',
133
+ baseURL: profile.metadata.baseURL || entry.defaultBaseURL,
134
+ defaultModel: profile.metadata.model || entry.defaultModel,
135
+ source: 'override',
136
+ };
137
+ }
138
+ function canonicalProviderId(provider) {
139
+ if (!provider)
140
+ return undefined;
141
+ return findRuntimeProvider(provider)?.id ?? provider.trim().toLowerCase();
142
+ }
143
+ function inferRuntimeProviderIdFromBaseURL(baseURL) {
144
+ if (!baseURL)
145
+ return undefined;
146
+ const normalized = baseURL.replace(/\/+$/, '').toLowerCase();
147
+ const directCatalog = getDirectRuntimeProviderCatalog();
148
+ const exact = directCatalog.find((entry) => normalizeEntryBaseURL(entry) === normalized);
149
+ if (exact)
150
+ return exact.id;
151
+ const host = safeHost(normalized);
152
+ if (!host)
153
+ return undefined;
154
+ return directCatalog.find((entry) => safeHost(normalizeEntryBaseURL(entry)) === host)?.id;
155
+ }
156
+ function normalizeEntryBaseURL(entry) {
157
+ return entry.defaultBaseURL.replace(/\/+$/, '').toLowerCase();
158
+ }
159
+ function safeHost(value) {
160
+ try {
161
+ return new URL(value).host;
162
+ }
163
+ catch {
164
+ return undefined;
165
+ }
166
+ }
167
+ function isBillingLikeProviderError(error) {
168
+ const message = error instanceof Error ? error.message : String(error);
169
+ return /\b(billing|quota|insufficient[_\s-]?credits?|payment|required balance)\b/i.test(message);
170
+ }
171
+ //# sourceMappingURL=provider-fallback.js.map
@@ -0,0 +1,128 @@
1
+ /**
2
+ * xAI / Grok OAuth — Authorization Code + PKCE flow (subscription login).
3
+ *
4
+ * Lets a SuperGrok / xAI subscriber use their plan as the brain of Code
5
+ * Buddy via a one-time browser login — no `XAI_API_KEY`, no per-token API
6
+ * metering — mirroring the ChatGPT `buddy login` path (`codex-oauth.ts`).
7
+ *
8
+ * Flow (RFC 7636 PKCE + loopback redirect, per RFC 8252):
9
+ * 1. Fetch OIDC discovery (`https://auth.x.ai/.well-known/openid-configuration`)
10
+ * → `authorization_endpoint` + `token_endpoint` (validated to be on *.x.ai).
11
+ * 2. Generate a 64-byte `code_verifier` → SHA-256 `code_challenge` (S256).
12
+ * 3. Spin a callback server on `127.0.0.1:56121` (fallback ephemeral).
13
+ * 4. Open the authorize URL in the browser; the user consents.
14
+ * 5. Browser redirects to `http://127.0.0.1:<port>/callback?code=...&state=...`.
15
+ * 6. Exchange the code (form-encoded, with `code_challenge` re-sent — an xAI
16
+ * defense-in-depth quirk) for `{access_token, refresh_token, ...}`.
17
+ * 7. Tokens land under `~/.codebuddy/xai-auth.json` (0600).
18
+ *
19
+ * Inference: the `access_token` is sent **directly** as `Authorization:
20
+ * Bearer` to `https://api.x.ai/v1` (`/chat/completions` or `/responses`).
21
+ * There is NO key-exchange / management API step — the OAuth token is the
22
+ * inference credential. (Verified against the Hermes Agent reference impl.)
23
+ *
24
+ * Client id `b1a00492-…` is xAI's first-party Grok CLI public OAuth client
25
+ * (paired with PKCE, not a secret) — the same reuse pattern as the ChatGPT
26
+ * Codex CLI client id in `codex-oauth.ts`.
27
+ */
28
+ /** Default inference base URL for the xAI OAuth path. */
29
+ export declare const XAI_OAUTH_BASE_URL = "https://api.x.ai/v1";
30
+ /** Minimal auth summary returned to callers after login. */
31
+ export interface XaiAuth {
32
+ access_token: string;
33
+ email?: string;
34
+ /** Seconds until the access token expires, when derivable from the JWT. */
35
+ expires_in_seconds?: number;
36
+ }
37
+ /** Remove cached tokens. `buddy logout xai` calls this. */
38
+ export declare function clearXaiCredentials(): void;
39
+ /** Whether a non-empty auth file with an access token exists. Used for
40
+ * provider auto-detection (no token loading, just presence). */
41
+ export declare function hasXaiCredentials(): boolean;
42
+ /** Absolute path to the auth file. Exposed for doctor / debug. */
43
+ export declare function getXaiAuthFilePath(): string;
44
+ declare function base64URLEncode(buffer: Buffer): string;
45
+ interface PkceCodes {
46
+ code_verifier: string;
47
+ code_challenge: string;
48
+ }
49
+ /** Generate a fresh PKCE pair (64 bytes of entropy, S256). */
50
+ declare function generatePkce(): PkceCodes;
51
+ interface JwtClaims {
52
+ exp?: number;
53
+ email?: string;
54
+ [key: string]: unknown;
55
+ }
56
+ /** Decode a JWT payload (no signature verification — the IdP vouched for it).
57
+ * Returns null for opaque (non-JWT) tokens. */
58
+ declare function decodeJwtClaims(token: string): JwtClaims | null;
59
+ /** Seconds until the access token expires, or null when not derivable
60
+ * (opaque token, or missing `exp`). */
61
+ declare function accessTokenTtlSeconds(accessToken: string): number | null;
62
+ /** True when the token is a JWT expiring within the refresh skew window.
63
+ * Opaque tokens (no `exp`) are treated as NOT-expiring → refreshed only
64
+ * reactively on a 401. */
65
+ declare function isAccessTokenExpiring(accessToken: string): boolean;
66
+ /** Validate an endpoint is HTTPS on the `*.x.ai` origin — prevents a
67
+ * poisoned discovery doc from redirecting credentials elsewhere. */
68
+ declare function isXaiHttpsEndpoint(url: string): boolean;
69
+ declare function buildAuthorizeUrl(authorizeEndpoint: string, redirectUri: string, codeChallenge: string, state: string, nonce: string): string;
70
+ /** Parse what the user pastes back from the browser. xAI's current consent
71
+ * screen shows the bare authorization code in-page (rather than redirecting
72
+ * to the loopback), so accept either a bare code, a full callback URL, or a
73
+ * `?code=...&state=...` fragment. Returns null when no code is found. */
74
+ declare function parsePastedCallback(raw: string): {
75
+ code: string;
76
+ state?: string;
77
+ } | null;
78
+ /**
79
+ * Begin a login: run discovery, generate PKCE, persist the pending material,
80
+ * and return the authorize URL to open. Does NOT block — the caller opens the
81
+ * browser and later calls `completeLogin(code)` with the in-page code.
82
+ */
83
+ export declare function beginLogin(): Promise<{
84
+ authorizeUrl: string;
85
+ redirectUri: string;
86
+ }>;
87
+ /**
88
+ * Complete a login started by `beginLogin()`: exchange the authorization code
89
+ * (bare code or a pasted callback URL) for tokens, persist them, and clear the
90
+ * pending file. Throws when there's no pending login or the exchange fails.
91
+ */
92
+ export declare function completeLogin(rawCode: string): Promise<XaiAuth>;
93
+ /**
94
+ * Run the interactive login flow. Because xAI's consent screen currently
95
+ * shows the authorization code **in-page** (rather than redirecting to the
96
+ * loopback), this races two completion paths:
97
+ * - a loopback callback server on 127.0.0.1:56121 (used if xAI redirects), and
98
+ * - a stdin prompt where the user pastes the in-page code.
99
+ * Whichever resolves first wins. The `redirect_uri` stays byte-identical in
100
+ * the authorize URL and the token exchange (xAI cross-checks it). Returns a
101
+ * minimal `XaiAuth`. Rejects on failure / timeout (5 minutes).
102
+ */
103
+ export declare function loginInteractive(openUrl?: (url: string) => void | Promise<void>): Promise<XaiAuth>;
104
+ /**
105
+ * Returns a valid xAI access token for inference, refreshing it when the
106
+ * JWT is within the skew window (or when `forceRefresh` is set, e.g. after a
107
+ * 401). Returns null when no credentials are on disk, or when a refresh
108
+ * fails (token revoked / entitlement lost) — the caller should re-login.
109
+ */
110
+ export declare function getValidXaiAccessToken(forceRefresh?: boolean): Promise<string | null>;
111
+ export declare const __test: {
112
+ buildAuthorizeUrl: typeof buildAuthorizeUrl;
113
+ generatePkce: typeof generatePkce;
114
+ decodeJwtClaims: typeof decodeJwtClaims;
115
+ accessTokenTtlSeconds: typeof accessTokenTtlSeconds;
116
+ isAccessTokenExpiring: typeof isAccessTokenExpiring;
117
+ isXaiHttpsEndpoint: typeof isXaiHttpsEndpoint;
118
+ parsePastedCallback: typeof parsePastedCallback;
119
+ base64URLEncode: typeof base64URLEncode;
120
+ CLIENT_ID: string;
121
+ SCOPES: string;
122
+ ISSUER: string;
123
+ FALLBACK_TOKEN_ENDPOINT: string;
124
+ FALLBACK_AUTHORIZE_ENDPOINT: string;
125
+ CALLBACK_PORT: number;
126
+ CALLBACK_PATH: string;
127
+ };
128
+ export {};