@phuetz/code-buddy 2.0.0 → 2.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 (421) hide show
  1. package/README.fr.md +56 -0
  2. package/README.md +74 -16
  3. package/codebuddy-runtime.json +5 -5
  4. package/dist/agent/codebuddy-agent.d.ts +18 -0
  5. package/dist/agent/codebuddy-agent.js +45 -8
  6. package/dist/agent/execution/agent-executor.d.ts +0 -9
  7. package/dist/agent/execution/agent-executor.js +176 -12
  8. package/dist/agent/execution/context-pipeline.d.ts +9 -0
  9. package/dist/agent/execution/context-pipeline.js +64 -2
  10. package/dist/agent/execution/tool-loop-guard.d.ts +76 -0
  11. package/dist/agent/execution/tool-loop-guard.js +165 -0
  12. package/dist/agent/execution/tool-selection-strategy.d.ts +7 -0
  13. package/dist/agent/execution/tool-selection-strategy.js +32 -2
  14. package/dist/agent/facades/session-facade.d.ts +0 -6
  15. package/dist/agent/facades/session-facade.js +0 -45
  16. package/dist/agent/hermes-claw-migrate.d.ts +0 -21
  17. package/dist/agent/hermes-claw-migrate.js +9 -4
  18. package/dist/agent/hermes-protocol-gateways.js +8 -1
  19. package/dist/agent/repo-profiler.js +17 -4
  20. package/dist/agent/self-improvement/authored-tool-runtime.js +10 -2
  21. package/dist/agent/self-improvement/evolution/ast-novelty.d.ts +5 -0
  22. package/dist/agent/self-improvement/evolution/ast-novelty.js +58 -23
  23. package/dist/agent/self-improvement/evolution/code-variant-store.d.ts +3 -0
  24. package/dist/agent/self-improvement/evolution/evolution-engine.js +2 -0
  25. package/dist/agent/self-improvement/evolution/protected-paths.js +6 -0
  26. package/dist/agent/self-improvement/evolution/variant-fitness.d.ts +13 -2
  27. package/dist/agent/self-improvement/evolution/variant-fitness.js +184 -58
  28. package/dist/agent/self-improvement/evolution/worktree-scorer.d.ts +2 -0
  29. package/dist/agent/self-improvement/evolution/worktree-scorer.js +15 -0
  30. package/dist/agent/self-improvement/evolutionary-archive.d.ts +2 -1
  31. package/dist/agent/self-improvement/evolutionary-archive.js +34 -5
  32. package/dist/agent/self-improvement/proposal-store.d.ts +1 -0
  33. package/dist/agent/self-improvement/proposal-store.js +79 -17
  34. package/dist/agent/self-improvement/skill-apply-journal.d.ts +44 -0
  35. package/dist/agent/self-improvement/skill-apply-journal.js +178 -0
  36. package/dist/agent/self-improvement/skill-behavior-benchmark.d.ts +3 -0
  37. package/dist/agent/self-improvement/skill-behavior-benchmark.js +19 -0
  38. package/dist/agent/self-improvement/skill-behavior-gate.d.ts +34 -0
  39. package/dist/agent/self-improvement/skill-behavior-gate.js +96 -0
  40. package/dist/agent/self-improvement/skill-engine.d.ts +22 -0
  41. package/dist/agent/self-improvement/skill-engine.js +385 -13
  42. package/dist/agent/self-improvement/skill-gate.d.ts +2 -0
  43. package/dist/agent/self-improvement/skill-gate.js +17 -2
  44. package/dist/agent/self-improvement/skill-mutator.d.ts +6 -1
  45. package/dist/agent/self-improvement/skill-mutator.js +51 -15
  46. package/dist/agent/self-improvement/skill-types.d.ts +2 -1
  47. package/dist/agent/self-improvement/types.d.ts +11 -0
  48. package/dist/agent/tool-handler.d.ts +1 -1
  49. package/dist/agent/tool-handler.js +28 -9
  50. package/dist/auth/profile-manager.js +1 -1
  51. package/dist/channels/companion-channel-turn.d.ts +53 -4
  52. package/dist/channels/companion-channel-turn.js +218 -16
  53. package/dist/channels/slash-parity.d.ts +4 -6
  54. package/dist/channels/slash-parity.js +9 -44
  55. package/dist/cli/session-commands.d.ts +9 -0
  56. package/dist/cli/session-commands.js +45 -5
  57. package/dist/cli/session-picker.d.ts +43 -0
  58. package/dist/cli/session-picker.js +128 -0
  59. package/dist/codebuddy/a2a-call-tool-defs.d.ts +26 -0
  60. package/dist/codebuddy/a2a-call-tool-defs.js +12 -0
  61. package/dist/codebuddy/fleet-tool-defs.d.ts +2 -0
  62. package/dist/codebuddy/fleet-tool-defs.js +55 -0
  63. package/dist/codebuddy/providers/chatgpt-headers.d.ts +18 -0
  64. package/dist/codebuddy/providers/chatgpt-headers.js +37 -0
  65. package/dist/codebuddy/providers/provider-chatgpt-responses.d.ts +2 -1
  66. package/dist/codebuddy/providers/provider-chatgpt-responses.js +10 -23
  67. package/dist/codebuddy/providers/provider-openai-compat.d.ts +7 -0
  68. package/dist/codebuddy/providers/provider-openai-compat.js +29 -1
  69. package/dist/codebuddy/ragchat-tool-defs.d.ts +31 -0
  70. package/dist/codebuddy/ragchat-tool-defs.js +19 -0
  71. package/dist/codebuddy/resource-catalog-tool-defs.d.ts +28 -0
  72. package/dist/codebuddy/resource-catalog-tool-defs.js +18 -0
  73. package/dist/codebuddy/tool-definitions/agent-tools.js +2 -2
  74. package/dist/codebuddy/tool-definitions/code-exec-tools.js +5 -1
  75. package/dist/codebuddy/tool-definitions/cron-tools.js +6 -0
  76. package/dist/codebuddy/tool-definitions/self-describe-tools.js +6 -1
  77. package/dist/codebuddy/tools.d.ts +0 -6
  78. package/dist/codebuddy/tools.js +25 -3
  79. package/dist/commands/cli/daemon-commands.js +3 -1
  80. package/dist/commands/cli/evolve-command.js +21 -5
  81. package/dist/commands/cli/fleet-collaboration-commands.d.ts +2 -0
  82. package/dist/commands/cli/fleet-collaboration-commands.js +57 -0
  83. package/dist/commands/cli/fleet-commands.js +29 -0
  84. package/dist/commands/cli/fleet-mission-commands.d.ts +3 -0
  85. package/dist/commands/cli/fleet-mission-commands.js +72 -0
  86. package/dist/commands/cli/fleet-rooms-commands.d.ts +10 -0
  87. package/dist/commands/cli/fleet-rooms-commands.js +289 -0
  88. package/dist/commands/cli/tools-commands.js +2 -1
  89. package/dist/commands/cli/triage-command.d.ts +8 -0
  90. package/dist/commands/cli/triage-command.js +72 -0
  91. package/dist/commands/cli/utility-commands.js +25 -1
  92. package/dist/commands/client-dispatcher.d.ts +7 -0
  93. package/dist/commands/client-dispatcher.js +73 -21
  94. package/dist/commands/cron-cli/index.d.ts +3 -1
  95. package/dist/commands/cron-cli/index.js +25 -0
  96. package/dist/commands/device-auth.d.ts +10 -0
  97. package/dist/commands/device-auth.js +91 -0
  98. package/dist/commands/enhanced-command-handler.d.ts +9 -0
  99. package/dist/commands/enhanced-command-handler.js +28 -6
  100. package/dist/commands/handlers/agent-handlers.d.ts +1 -1
  101. package/dist/commands/handlers/agent-handlers.js +4 -4
  102. package/dist/commands/handlers/channel-handlers.js +53 -2
  103. package/dist/commands/handlers/export-handlers.d.ts +3 -2
  104. package/dist/commands/handlers/export-handlers.js +55 -28
  105. package/dist/commands/handlers/extra-handlers.js +5 -1
  106. package/dist/commands/handlers/grill-me-handler.js +26 -18
  107. package/dist/commands/handlers/memory-handlers.d.ts +6 -2
  108. package/dist/commands/handlers/memory-handlers.js +35 -15
  109. package/dist/commands/handlers/missing-handlers.d.ts +2 -2
  110. package/dist/commands/handlers/missing-handlers.js +12 -4
  111. package/dist/commands/handlers/resources-handler.d.ts +12 -0
  112. package/dist/commands/handlers/resources-handler.js +52 -0
  113. package/dist/commands/handlers/starter-handlers.d.ts +1 -1
  114. package/dist/commands/handlers/starter-handlers.js +32 -2
  115. package/dist/commands/handlers/switch-handler.d.ts +1 -1
  116. package/dist/commands/handlers/switch-handler.js +15 -0
  117. package/dist/commands/handlers/test-handlers.js +4 -86
  118. package/dist/commands/handlers/ui-handlers.js +11 -5
  119. package/dist/commands/login-chatgpt.d.ts +8 -0
  120. package/dist/commands/login-chatgpt.js +17 -0
  121. package/dist/commands/mcp-import.d.ts +11 -0
  122. package/dist/commands/mcp-import.js +67 -0
  123. package/dist/commands/mcp-invoke.d.ts +2 -0
  124. package/dist/commands/mcp-invoke.js +68 -0
  125. package/dist/commands/mcp.d.ts +13 -0
  126. package/dist/commands/mcp.js +66 -21
  127. package/dist/commands/pipeline.d.ts +7 -1
  128. package/dist/commands/pipeline.js +104 -7
  129. package/dist/commands/resources.d.ts +2 -0
  130. package/dist/commands/resources.js +64 -0
  131. package/dist/commands/skills-cli/index.js +35 -12
  132. package/dist/commands/slash/builtin-commands.js +16 -3
  133. package/dist/commands/slash/index.d.ts +3 -1
  134. package/dist/commands/slash/index.js +2 -0
  135. package/dist/commands/slash/surfaces.d.ts +53 -0
  136. package/dist/commands/slash/surfaces.js +177 -0
  137. package/dist/commands/slash/types.d.ts +17 -0
  138. package/dist/commands/try.d.ts +1 -1
  139. package/dist/commands/try.js +1 -1
  140. package/dist/companion/companion-identity.d.ts +43 -0
  141. package/dist/companion/companion-identity.js +136 -0
  142. package/dist/companion/companion-toolset.d.ts +66 -0
  143. package/dist/companion/companion-toolset.js +368 -0
  144. package/dist/companion/companion-turn.d.ts +10 -2
  145. package/dist/companion/companion-turn.js +38 -1
  146. package/dist/config/code-exec-policy.d.ts +25 -0
  147. package/dist/config/code-exec-policy.js +39 -0
  148. package/dist/config/model-tools.d.ts +9 -0
  149. package/dist/config/model-tools.js +103 -0
  150. package/dist/context/context-manager-v2.js +2 -2
  151. package/dist/context/lm-resizer-compressor.js +3 -2
  152. package/dist/context/lm-resizer-diagnostics.d.ts +9 -0
  153. package/dist/context/lm-resizer-diagnostics.js +30 -0
  154. package/dist/context/tool-output-masking.js +3 -4
  155. package/dist/curator/curator.d.ts +6 -0
  156. package/dist/curator/curator.js +53 -3
  157. package/dist/daemon/cron-agent-bridge.d.ts +6 -0
  158. package/dist/daemon/cron-agent-bridge.js +31 -4
  159. package/dist/doctor/index.d.ts +11 -2
  160. package/dist/doctor/index.js +84 -21
  161. package/dist/doctor/integrations.d.ts +197 -0
  162. package/dist/doctor/integrations.js +241 -0
  163. package/dist/doctor/triage.d.ts +108 -0
  164. package/dist/doctor/triage.js +304 -0
  165. package/dist/errors/crash-handler.js +2 -0
  166. package/dist/fleet/collaboration.d.ts +44 -0
  167. package/dist/fleet/collaboration.js +170 -0
  168. package/dist/fleet/fleet-listener.d.ts +1 -0
  169. package/dist/fleet/fleet-listener.js +87 -46
  170. package/dist/fleet/fleet-registry.d.ts +2 -0
  171. package/dist/fleet/resource-catalog.d.ts +245 -0
  172. package/dist/fleet/resource-catalog.js +211 -0
  173. package/dist/fleet/rooms/room-access.d.ts +138 -0
  174. package/dist/fleet/rooms/room-access.js +196 -0
  175. package/dist/fleet/rooms/room-client.d.ts +158 -0
  176. package/dist/fleet/rooms/room-client.js +685 -0
  177. package/dist/fleet/rooms/room-event.d.ts +139 -0
  178. package/dist/fleet/rooms/room-event.js +330 -0
  179. package/dist/fleet/rooms/room-filter.d.ts +48 -0
  180. package/dist/fleet/rooms/room-filter.js +152 -0
  181. package/dist/fleet/rooms/room-hub.d.ts +154 -0
  182. package/dist/fleet/rooms/room-hub.js +363 -0
  183. package/dist/fleet/rooms/room-identity.d.ts +26 -0
  184. package/dist/fleet/rooms/room-identity.js +82 -0
  185. package/dist/fleet/rooms/room-lock.d.ts +34 -0
  186. package/dist/fleet/rooms/room-lock.js +180 -0
  187. package/dist/fleet/rooms/room-observations.d.ts +7 -0
  188. package/dist/fleet/rooms/room-observations.js +61 -0
  189. package/dist/fleet/rooms/room-server.d.ts +28 -0
  190. package/dist/fleet/rooms/room-server.js +75 -0
  191. package/dist/fleet/rooms/room-store.d.ts +119 -0
  192. package/dist/fleet/rooms/room-store.js +448 -0
  193. package/dist/fleet/rooms/room-ws-bridge.d.ts +27 -0
  194. package/dist/fleet/rooms/room-ws-bridge.js +137 -0
  195. package/dist/fleet/sensory-mission-bridge.d.ts +42 -0
  196. package/dist/fleet/sensory-mission-bridge.js +136 -0
  197. package/dist/git/worktree-sessions.js +1 -0
  198. package/dist/harness/contract.d.ts +4 -4
  199. package/dist/harness/fleet-supervisor.d.ts +16 -0
  200. package/dist/harness/fleet-supervisor.js +64 -0
  201. package/dist/harness/index.d.ts +4 -0
  202. package/dist/harness/index.js +4 -0
  203. package/dist/harness/mission-runner.d.ts +3 -0
  204. package/dist/harness/mission-runner.js +53 -0
  205. package/dist/harness/mission-store.d.ts +93 -0
  206. package/dist/harness/mission-store.js +297 -0
  207. package/dist/harness/tool-harness.d.ts +56 -0
  208. package/dist/harness/tool-harness.js +153 -0
  209. package/dist/hooks/use-enhanced-input.js +48 -4
  210. package/dist/hooks/use-input-handler.d.ts +1 -0
  211. package/dist/hooks/use-input-handler.js +82 -22
  212. package/dist/hooks/use-input-history.js +1 -0
  213. package/dist/identity/lisa-introspection.js +5 -2
  214. package/dist/identity/operational-self-model.d.ts +2 -0
  215. package/dist/identity/operational-self-model.js +4 -0
  216. package/dist/index.js +52 -6
  217. package/dist/mcp/client.d.ts +11 -0
  218. package/dist/mcp/client.js +68 -3
  219. package/dist/mcp/config.d.ts +20 -0
  220. package/dist/mcp/config.js +121 -8
  221. package/dist/mcp/import-normalize.d.ts +12 -0
  222. package/dist/mcp/import-normalize.js +114 -0
  223. package/dist/mcp/mcp-oauth-constants.d.ts +8 -0
  224. package/dist/mcp/mcp-oauth-constants.js +9 -0
  225. package/dist/mcp/mcp-oauth-provider.d.ts +80 -0
  226. package/dist/mcp/mcp-oauth-provider.js +241 -0
  227. package/dist/mcp/mcp-oauth.d.ts +60 -1
  228. package/dist/mcp/mcp-oauth.js +241 -65
  229. package/dist/mcp/transports.d.ts +14 -5
  230. package/dist/mcp/transports.js +112 -101
  231. package/dist/mcp/types.d.ts +5 -0
  232. package/dist/media/comfyui-recipe-contract.d.ts +7 -7
  233. package/dist/memory/facts-memory.d.ts +11 -1
  234. package/dist/memory/facts-memory.js +47 -8
  235. package/dist/memory/memory-candidate-queue.d.ts +2 -2
  236. package/dist/memory/memory-candidate-queue.js +6 -6
  237. package/dist/memory/persistent-memory.d.ts +13 -8
  238. package/dist/memory/persistent-memory.js +77 -30
  239. package/dist/nodes/device-node.js +5 -9
  240. package/dist/observability/mobile-supervision-gateway-contract.js +20 -7
  241. package/dist/observability/run-event-writer.d.ts +21 -0
  242. package/dist/observability/run-event-writer.js +81 -0
  243. package/dist/observability/run-store.d.ts +5 -0
  244. package/dist/observability/run-store.js +18 -13
  245. package/dist/observability/run-trajectory.js +1 -1
  246. package/dist/optimization/prompt-cache.d.ts +19 -2
  247. package/dist/optimization/prompt-cache.js +41 -6
  248. package/dist/orchestration/orchestrator.d.ts +21 -0
  249. package/dist/orchestration/orchestrator.js +122 -15
  250. package/dist/persistence/session-content.d.ts +8 -0
  251. package/dist/persistence/session-content.js +76 -0
  252. package/dist/persistence/session-handoff.d.ts +64 -0
  253. package/dist/persistence/session-handoff.js +80 -0
  254. package/dist/persistence/session-history.d.ts +4 -0
  255. package/dist/persistence/session-history.js +38 -0
  256. package/dist/persistence/session-store.d.ts +9 -0
  257. package/dist/persistence/session-store.js +48 -20
  258. package/dist/personas/persona-manager.js +17 -1
  259. package/dist/plugins/code-explorer/CodeExplorerManager.d.ts +10 -4
  260. package/dist/plugins/code-explorer/CodeExplorerManager.js +69 -16
  261. package/dist/plugins/plugin-manager.js +10 -1
  262. package/dist/prompts/prompt-manager.js +11 -4
  263. package/dist/prompts/system-base.js +6 -2
  264. package/dist/protocols/a2a/codebuddy-executor.d.ts +11 -2
  265. package/dist/protocols/a2a/codebuddy-executor.js +9 -8
  266. package/dist/protocols/a2a/index.d.ts +1 -1
  267. package/dist/protocols/a2a/jsonrpc-v1.d.ts +41 -0
  268. package/dist/protocols/a2a/jsonrpc-v1.js +145 -0
  269. package/dist/protocols/a2a/peer-config.d.ts +20 -0
  270. package/dist/protocols/a2a/peer-config.js +55 -0
  271. package/dist/providers/codex-oauth.js +30 -6
  272. package/dist/providers/model-provider-compat.js +2 -1
  273. package/dist/sandbox/os-sandbox.d.ts +1 -1
  274. package/dist/scheduler/cron-scheduler.d.ts +15 -2
  275. package/dist/scheduler/cron-scheduler.js +35 -4
  276. package/dist/scheduler/job-notepad.d.ts +69 -0
  277. package/dist/scheduler/job-notepad.js +339 -0
  278. package/dist/security/audit-logger.d.ts +1 -1
  279. package/dist/security/compute-confinement.d.ts +4 -0
  280. package/dist/security/compute-confinement.js +89 -0
  281. package/dist/security/session-encryption.d.ts +4 -0
  282. package/dist/security/session-encryption.js +31 -0
  283. package/dist/sensory/voice-loop.d.ts +17 -0
  284. package/dist/sensory/voice-loop.js +72 -15
  285. package/dist/server/auth/device-session-context.d.ts +9 -0
  286. package/dist/server/auth/device-session-context.js +13 -0
  287. package/dist/server/auth/device-store.d.ts +89 -0
  288. package/dist/server/auth/device-store.js +261 -0
  289. package/dist/server/auth/device-token.d.ts +3 -0
  290. package/dist/server/auth/device-token.js +6 -0
  291. package/dist/server/auth/jwt.js +4 -0
  292. package/dist/server/index.d.ts +0 -10
  293. package/dist/server/index.js +28 -0
  294. package/dist/server/middleware/auth.js +3 -2
  295. package/dist/server/routes/a2a-jsonrpc.d.ts +9 -0
  296. package/dist/server/routes/a2a-jsonrpc.js +66 -0
  297. package/dist/server/routes/a2a-protocol.d.ts +12 -0
  298. package/dist/server/routes/a2a-protocol.js +1 -1
  299. package/dist/server/routes/device-auth.d.ts +4 -0
  300. package/dist/server/routes/device-auth.js +40 -0
  301. package/dist/server/types.d.ts +4 -0
  302. package/dist/server/websocket/handler.d.ts +13 -0
  303. package/dist/server/websocket/handler.js +102 -17
  304. package/dist/services/prompt-builder.d.ts +2 -0
  305. package/dist/services/prompt-builder.js +16 -6
  306. package/dist/services/runtime-settings-context.d.ts +81 -0
  307. package/dist/services/runtime-settings-context.js +79 -0
  308. package/dist/skills/executor.js +2 -0
  309. package/dist/skills/hub.js +16 -14
  310. package/dist/skills/local-inventory.d.ts +21 -0
  311. package/dist/skills/local-inventory.js +72 -0
  312. package/dist/skills/skill-loader.js +2 -2
  313. package/dist/skills/skill-usage-store.d.ts +49 -0
  314. package/dist/skills/skill-usage-store.js +121 -0
  315. package/dist/testing/ai-integration-tests.js +8 -5
  316. package/dist/themes/theme-manager.d.ts +12 -0
  317. package/dist/themes/theme-manager.js +29 -0
  318. package/dist/themes/theme-schema.d.ts +24 -24
  319. package/dist/tools/a2a-call-tool.d.ts +34 -0
  320. package/dist/tools/a2a-call-tool.js +75 -0
  321. package/dist/tools/bash/streaming-executor.d.ts +1 -0
  322. package/dist/tools/bash/streaming-executor.js +78 -90
  323. package/dist/tools/code-exec-preflight-runner.d.ts +41 -0
  324. package/dist/tools/code-exec-preflight-runner.js +254 -0
  325. package/dist/tools/code-exec-preflight.d.ts +44 -0
  326. package/dist/tools/code-exec-preflight.js +501 -0
  327. package/dist/tools/code-exec-tool.d.ts +48 -1
  328. package/dist/tools/code-exec-tool.js +191 -47
  329. package/dist/tools/comment-watcher.js +29 -12
  330. package/dist/tools/core-code-inspection.d.ts +56 -0
  331. package/dist/tools/core-code-inspection.js +86 -0
  332. package/dist/tools/create-skill-tool.d.ts +2 -3
  333. package/dist/tools/create-skill-tool.js +16 -75
  334. package/dist/tools/cronjob-tool.d.ts +1 -0
  335. package/dist/tools/cronjob-tool.js +1 -0
  336. package/dist/tools/env-doctor-tool.d.ts +2 -0
  337. package/dist/tools/env-doctor-tool.js +4 -3
  338. package/dist/tools/execute-code-rpc-invoker.d.ts +1 -1
  339. package/dist/tools/execute-code-rpc-invoker.js +35 -19
  340. package/dist/tools/execute-code-runner.d.ts +2 -0
  341. package/dist/tools/execute-code-runner.js +52 -17
  342. package/dist/tools/fleet-room-tool.d.ts +104 -0
  343. package/dist/tools/fleet-room-tool.js +124 -0
  344. package/dist/tools/integration-tool-hints.d.ts +4 -0
  345. package/dist/tools/integration-tool-hints.js +19 -0
  346. package/dist/tools/list-peers-tool.d.ts +3 -0
  347. package/dist/tools/list-peers-tool.js +11 -4
  348. package/dist/tools/media-generation-tool.d.ts +16 -1
  349. package/dist/tools/media-generation-tool.js +341 -9
  350. package/dist/tools/merge-conflict-tool.js +53 -25
  351. package/dist/tools/metadata.d.ts +1 -5
  352. package/dist/tools/metadata.js +30 -28
  353. package/dist/tools/peer-tool-invoke-tool.d.ts +61 -0
  354. package/dist/tools/peer-tool-invoke-tool.js +396 -0
  355. package/dist/tools/ragchat-tool.d.ts +39 -0
  356. package/dist/tools/ragchat-tool.js +105 -0
  357. package/dist/tools/registry/fleet-tools.d.ts +21 -3
  358. package/dist/tools/registry/fleet-tools.js +137 -4
  359. package/dist/tools/registry/index.d.ts +1 -1
  360. package/dist/tools/registry/index.js +2 -2
  361. package/dist/tools/registry/knowledge-tools.d.ts +2 -2
  362. package/dist/tools/registry/knowledge-tools.js +2 -2
  363. package/dist/tools/registry/lessons-tools.d.ts +7 -0
  364. package/dist/tools/registry/lessons-tools.js +43 -3
  365. package/dist/tools/registry/memory-tools.d.ts +1 -1
  366. package/dist/tools/registry/memory-tools.js +8 -8
  367. package/dist/tools/registry/research-tools.d.ts +1 -0
  368. package/dist/tools/registry/research-tools.js +4 -13
  369. package/dist/tools/registry/self-describe-tools.d.ts +1 -1
  370. package/dist/tools/registry/self-describe-tools.js +43 -30
  371. package/dist/tools/resource-catalog-tool.d.ts +38 -0
  372. package/dist/tools/resource-catalog-tool.js +46 -0
  373. package/dist/tools/skills-inspection-tool.js +30 -1
  374. package/dist/tools/stream-tool-output.d.ts +3 -0
  375. package/dist/tools/stream-tool-output.js +33 -0
  376. package/dist/tools/tool-call-scheduler.d.ts +10 -0
  377. package/dist/tools/tool-call-scheduler.js +58 -0
  378. package/dist/tools/tool-effect.d.ts +5 -0
  379. package/dist/tools/tool-effect.js +26 -0
  380. package/dist/tools/tool-search.d.ts +12 -11
  381. package/dist/tools/tool-search.js +67 -26
  382. package/dist/tools/types.d.ts +6 -0
  383. package/dist/ui/components/ChatHistory.d.ts +1 -1
  384. package/dist/ui/components/ChatHistory.js +2 -2
  385. package/dist/ui/components/ChatInput.d.ts +2 -1
  386. package/dist/ui/components/ChatInput.js +42 -88
  387. package/dist/ui/components/ChatInterface.d.ts +4 -2
  388. package/dist/ui/components/ChatInterface.js +27 -63
  389. package/dist/ui/components/CommandSuggestions.d.ts +0 -1
  390. package/dist/ui/components/CommandSuggestions.js +4 -6
  391. package/dist/ui/components/FileAutocomplete.js +1 -1
  392. package/dist/ui/components/KeyboardHelp.js +8 -6
  393. package/dist/ui/components/ModelSelection.js +6 -5
  394. package/dist/ui/components/StatusBar.d.ts +2 -1
  395. package/dist/ui/components/StatusBar.js +8 -7
  396. package/dist/ui/context/theme-context.js +3 -2
  397. package/dist/ui/index.d.ts +1 -1
  398. package/dist/ui/index.js +1 -1
  399. package/dist/ui/utils/markdown-renderer.js +4 -13
  400. package/dist/utils/atomic-write.d.ts +22 -0
  401. package/dist/utils/atomic-write.js +29 -0
  402. package/dist/utils/bounded-output.d.ts +16 -0
  403. package/dist/utils/bounded-output.js +63 -0
  404. package/dist/utils/config-validation/schema.d.ts +2 -2
  405. package/dist/utils/device-store-file.d.ts +4 -0
  406. package/dist/utils/device-store-file.js +40 -0
  407. package/dist/utils/export-manager.d.ts +9 -0
  408. package/dist/utils/export-manager.js +19 -0
  409. package/dist/utils/first-use-hints.d.ts +25 -0
  410. package/dist/utils/first-use-hints.js +58 -0
  411. package/dist/utils/graceful-shutdown.d.ts +8 -0
  412. package/dist/utils/graceful-shutdown.js +23 -7
  413. package/dist/utils/history-manager.js +1 -1
  414. package/dist/utils/update-notifier.js +16 -18
  415. package/dist/wizard/environment-detection.d.ts +5 -1
  416. package/dist/wizard/environment-detection.js +49 -7
  417. package/dist/wizard/onboarding.d.ts +5 -1
  418. package/dist/wizard/onboarding.js +90 -30
  419. package/dist/wizard/provider-onboarding.d.ts +2 -0
  420. package/dist/wizard/provider-onboarding.js +55 -17
  421. package/package.json +7 -3
@@ -18,6 +18,19 @@ export interface MCPOAuthToken {
18
18
  expiresAt: number;
19
19
  scopes: string[];
20
20
  }
21
+ /** Client id + optional DCR metadata persisted next to the token (encrypted store). */
22
+ export interface StoredClientInformation {
23
+ client_id: string;
24
+ client_secret?: string;
25
+ client_id_issued_at?: number;
26
+ client_secret_expires_at?: number;
27
+ redirect_uris?: string[];
28
+ token_endpoint_auth_method?: string;
29
+ grant_types?: string[];
30
+ response_types?: string[];
31
+ client_name?: string;
32
+ scope?: string;
33
+ }
21
34
  /**
22
35
  * Generate a cryptographically random code verifier (43-128 chars, URL-safe)
23
36
  */
@@ -26,6 +39,35 @@ export declare function generateCodeVerifier(): string;
26
39
  * Generate code challenge from verifier using S256 method
27
40
  */
28
41
  export declare function generateCodeChallenge(verifier: string): string;
42
+ interface AuthorizationResult {
43
+ code: string;
44
+ state: string;
45
+ }
46
+ export declare class OAuthCallbackCancelledError extends Error {
47
+ constructor(message?: string);
48
+ }
49
+ export interface CallbackSession {
50
+ /** Resolves only after listen() succeeded. Rejects on bind failure or abort-before-listen. */
51
+ listening: Promise<void>;
52
+ /** Resolves with the authorization code after a valid callback. */
53
+ result: Promise<AuthorizationResult>;
54
+ abort: (reason?: Error) => void;
55
+ }
56
+ /**
57
+ * Bind the loopback callback server. Callers must await `listening` before
58
+ * opening a browser: a bind failure must not leave an unhandled rejection
59
+ * nor launch a flow that can never complete.
60
+ */
61
+ export declare function startCallbackSession(redirectUri: string, expectedState: string, timeoutMs?: number, signal?: AbortSignal): CallbackSession;
62
+ /**
63
+ * Start a temporary local HTTP server to receive the OAuth callback.
64
+ * Awaits a successful listen before waiting for the code.
65
+ */
66
+ export declare function startCallbackServer(redirectUri: string, expectedState: string, timeoutMs?: number, signal?: AbortSignal): Promise<AuthorizationResult>;
67
+ /**
68
+ * Open a URL in the default browser (cross-platform)
69
+ */
70
+ export declare function openBrowser(url: string): Promise<void>;
29
71
  export declare class MCPOAuthManager {
30
72
  private tokenCache;
31
73
  /**
@@ -48,17 +90,34 @@ export declare class MCPOAuthManager {
48
90
  */
49
91
  getValidToken(serverId: string): Promise<string | null>;
50
92
  /**
51
- * Store a token encrypted on disk and in memory cache
93
+ * Store a token encrypted on disk and in memory cache.
94
+ * Preserves any previously persisted client metadata for the same server.
52
95
  */
53
96
  storeToken(serverId: string, token: MCPOAuthToken, config: MCPOAuthConfig): void;
97
+ /**
98
+ * Persist client registration (client_id and optional DCR metadata) in the
99
+ * encrypted store, even before a token exists. Never writes plaintext.
100
+ */
101
+ storeClientInformation(serverId: string, info: StoredClientInformation): void;
54
102
  /**
55
103
  * Remove a stored token
56
104
  */
57
105
  removeToken(serverId: string): void;
106
+ /** Drop access/refresh tokens only; keep client_id and DCR metadata. */
107
+ clearTokens(serverId: string): void;
58
108
  /**
59
109
  * Check if a token exists for a server (may be expired)
60
110
  */
111
+ /** Stored token and client id for a server, without refresh side effects. */
112
+ getStoredToken(serverId: string): {
113
+ token: MCPOAuthToken;
114
+ clientId: string;
115
+ client?: StoredClientInformation;
116
+ } | null;
117
+ /** Persisted client id / DCR metadata, independent of whether a token exists. */
118
+ getStoredClientInformation(serverId: string): StoredClientInformation | null;
61
119
  hasToken(serverId: string): boolean;
62
120
  }
63
121
  export declare function getMCPOAuthManager(): MCPOAuthManager;
64
122
  export declare function resetMCPOAuthManager(): void;
123
+ export {};
@@ -11,6 +11,29 @@ import * as path from 'path';
11
11
  import { URL } from 'url';
12
12
  import { logger } from '../utils/logger.js';
13
13
  import { readTextAtomicSync, writeFileAtomicSync } from '../utils/atomic-write.js';
14
+ import { SDK_MANAGED_TOKEN_URL } from './mcp-oauth-constants.js';
15
+ function storedClientFrom(info) {
16
+ const client = { client_id: info.client_id };
17
+ if (info.client_secret)
18
+ client.client_secret = info.client_secret;
19
+ if (info.client_id_issued_at !== undefined)
20
+ client.client_id_issued_at = info.client_id_issued_at;
21
+ if (info.client_secret_expires_at !== undefined)
22
+ client.client_secret_expires_at = info.client_secret_expires_at;
23
+ if (info.redirect_uris?.length)
24
+ client.redirect_uris = [...info.redirect_uris];
25
+ if (info.token_endpoint_auth_method)
26
+ client.token_endpoint_auth_method = info.token_endpoint_auth_method;
27
+ if (info.grant_types?.length)
28
+ client.grant_types = [...info.grant_types];
29
+ if (info.response_types?.length)
30
+ client.response_types = [...info.response_types];
31
+ if (info.client_name)
32
+ client.client_name = info.client_name;
33
+ if (info.scope)
34
+ client.scope = info.scope;
35
+ return client;
36
+ }
14
37
  // ============================================================================
15
38
  // PKCE (RFC 7636)
16
39
  // ============================================================================
@@ -35,7 +58,9 @@ export function generateCodeChallenge(verifier) {
35
58
  const ALGORITHM = 'aes-256-gcm';
36
59
  const SALT_LENGTH = 32;
37
60
  function getEncryptionKey() {
38
- // Use CODEBUDDY_VAULT_KEY if available, otherwise derive from machine ID
61
+ // Prefer CODEBUDDY_VAULT_KEY or CODEBUDDY_MCP_KEY. The USER+platform fallback
62
+ // is derivable by anyone on the same account: AES-GCM still runs, but that is
63
+ // not a strong vault. Set an explicit key for real confidentiality.
39
64
  return process.env.CODEBUDDY_VAULT_KEY
40
65
  || process.env.CODEBUDDY_MCP_KEY
41
66
  || `mcp-oauth-${process.env.USER || process.env.USERNAME || 'default'}-${process.platform}`;
@@ -101,63 +126,153 @@ function saveTokenStore(store) {
101
126
  const encrypted = encryptData(JSON.stringify(store));
102
127
  writeFileAtomicSync(filePath, encrypted, { mode: 0o600 });
103
128
  }
129
+ export class OAuthCallbackCancelledError extends Error {
130
+ constructor(message = 'OAuth authorization cancelled') {
131
+ super(message);
132
+ this.name = 'OAuthCallbackCancelledError';
133
+ }
134
+ }
104
135
  /**
105
- * Start a temporary local HTTP server to receive the OAuth callback.
106
- * Returns a promise that resolves with the authorization code.
136
+ * Bind the loopback callback server. Callers must await `listening` before
137
+ * opening a browser: a bind failure must not leave an unhandled rejection
138
+ * nor launch a flow that can never complete.
107
139
  */
108
- function startCallbackServer(redirectUri, expectedState, timeoutMs = 120_000) {
109
- return new Promise((resolve, reject) => {
110
- const url = new URL(redirectUri);
111
- const port = parseInt(url.port || '19836', 10);
112
- const pathname = url.pathname || '/callback';
113
- const server = http.createServer((req, res) => {
114
- const reqUrl = new URL(req.url || '/', `http://localhost:${port}`);
115
- if (reqUrl.pathname !== pathname) {
116
- res.writeHead(404);
117
- res.end('Not found');
118
- return;
119
- }
120
- const code = reqUrl.searchParams.get('code');
121
- const state = reqUrl.searchParams.get('state');
122
- const error = reqUrl.searchParams.get('error');
123
- if (error) {
124
- res.writeHead(200, { 'Content-Type': 'text/html' });
125
- res.end('<html><body><h1>Authorization Failed</h1><p>You can close this window.</p></body></html>');
126
- server.close();
127
- reject(new Error(`OAuth authorization error: ${error}`));
128
- return;
129
- }
130
- if (!code) {
131
- res.writeHead(400, { 'Content-Type': 'text/html' });
132
- res.end('<html><body><h1>Missing authorization code</h1></body></html>');
133
- return;
134
- }
135
- if (state !== expectedState) {
136
- res.writeHead(400, { 'Content-Type': 'text/html' });
137
- res.end('<html><body><h1>State mismatch — possible CSRF attack</h1></body></html>');
138
- server.close();
139
- reject(new Error('OAuth state mismatch'));
140
- return;
141
- }
140
+ export function startCallbackSession(redirectUri, expectedState, timeoutMs = 120_000, signal) {
141
+ const url = new URL(redirectUri);
142
+ const port = parseInt(url.port || '19836', 10);
143
+ const pathname = url.pathname || '/callback';
144
+ let listenResolve;
145
+ let listenReject;
146
+ let resultResolve;
147
+ let resultReject;
148
+ let listeningSettled = false;
149
+ let resultSettled = false;
150
+ let timer;
151
+ let server;
152
+ const listening = new Promise((resolve, reject) => {
153
+ listenResolve = resolve;
154
+ listenReject = reject;
155
+ });
156
+ const result = new Promise((resolve, reject) => {
157
+ resultResolve = resolve;
158
+ resultReject = reject;
159
+ });
160
+ // Attach observers at construction so a pre-aborted signal cannot leave an
161
+ // unhandledRejection on the public startCallbackServer wrapper (the early
162
+ // return used to skip the .catch() that lived after listen()).
163
+ listening.catch(() => undefined);
164
+ result.catch(() => undefined);
165
+ const settleListen = (err) => {
166
+ if (listeningSettled)
167
+ return;
168
+ listeningSettled = true;
169
+ if (err)
170
+ listenReject(err);
171
+ else
172
+ listenResolve();
173
+ };
174
+ const settleResult = (value, err) => {
175
+ if (resultSettled)
176
+ return;
177
+ resultSettled = true;
178
+ if (timer)
179
+ clearTimeout(timer);
180
+ if (err)
181
+ resultReject(err);
182
+ else
183
+ resultResolve(value);
184
+ };
185
+ let abort;
186
+ const onAbort = () => abort(new OAuthCallbackCancelledError());
187
+ const detachAbort = () => signal?.removeEventListener('abort', onAbort);
188
+ abort = (reason) => {
189
+ detachAbort();
190
+ const fail = reason ?? new OAuthCallbackCancelledError();
191
+ if (!listeningSettled)
192
+ settleListen(fail);
193
+ if (!resultSettled)
194
+ settleResult(undefined, fail);
195
+ if (timer) {
196
+ clearTimeout(timer);
197
+ timer = undefined;
198
+ }
199
+ if (server) {
200
+ server.removeAllListeners('error');
201
+ const closing = server;
202
+ server = undefined;
203
+ closing.close();
204
+ }
205
+ };
206
+ if (signal?.aborted) {
207
+ abort(new OAuthCallbackCancelledError());
208
+ return { listening, result, abort };
209
+ }
210
+ signal?.addEventListener('abort', onAbort, { once: true });
211
+ timer = setTimeout(() => {
212
+ abort(new Error('OAuth callback timed out (120s)'));
213
+ detachAbort();
214
+ }, timeoutMs);
215
+ server = http.createServer((req, res) => {
216
+ const reqUrl = new URL(req.url || '/', `http://127.0.0.1:${port}`);
217
+ if (reqUrl.pathname !== pathname) {
218
+ res.writeHead(404);
219
+ res.end('Not found');
220
+ return;
221
+ }
222
+ const code = reqUrl.searchParams.get('code');
223
+ const state = reqUrl.searchParams.get('state');
224
+ const error = reqUrl.searchParams.get('error');
225
+ if (error) {
142
226
  res.writeHead(200, { 'Content-Type': 'text/html' });
143
- res.end('<html><body><h1>Authorization Successful</h1><p>You can close this window and return to the terminal.</p></body></html>');
144
- server.close();
145
- resolve({ code, state });
146
- });
147
- // Set timeout
148
- const timer = setTimeout(() => {
149
- server.close();
150
- reject(new Error('OAuth callback timed out (120s)'));
151
- }, timeoutMs);
152
- server.on('close', () => clearTimeout(timer));
153
- server.on('error', (err) => {
227
+ res.end('<html><body><h1>Authorization Failed</h1><p>You can close this window.</p></body></html>');
228
+ detachAbort();
229
+ abort(new Error(`OAuth authorization error: ${error}`));
230
+ return;
231
+ }
232
+ if (!code) {
233
+ res.writeHead(400, { 'Content-Type': 'text/html' });
234
+ res.end('<html><body><h1>Missing authorization code</h1></body></html>');
235
+ return;
236
+ }
237
+ if (state !== expectedState) {
238
+ res.writeHead(400, { 'Content-Type': 'text/html' });
239
+ res.end('<html><body><h1>State mismatch — possible CSRF attack</h1></body></html>');
240
+ detachAbort();
241
+ abort(new Error('OAuth state mismatch'));
242
+ return;
243
+ }
244
+ res.writeHead(200, { 'Content-Type': 'text/html' });
245
+ res.end('<html><body><h1>Authorization Successful</h1><p>You can close this window and return to the terminal.</p></body></html>');
246
+ detachAbort();
247
+ if (timer) {
154
248
  clearTimeout(timer);
155
- reject(new Error(`Failed to start callback server: ${err.message}`));
156
- });
157
- server.listen(port, '127.0.0.1', () => {
158
- logger.debug(`OAuth callback server listening on port ${port}`);
159
- });
249
+ timer = undefined;
250
+ }
251
+ const closing = server;
252
+ server = undefined;
253
+ closing?.removeAllListeners('error');
254
+ closing?.close();
255
+ settleListen();
256
+ settleResult({ code, state });
257
+ });
258
+ server.on('error', (err) => {
259
+ detachAbort();
260
+ abort(new Error(`Failed to start callback server: ${err.message}`));
160
261
  });
262
+ server.listen(port, '127.0.0.1', () => {
263
+ logger.debug(`OAuth callback server listening on port ${port}`);
264
+ settleListen();
265
+ });
266
+ return { listening, result, abort };
267
+ }
268
+ /**
269
+ * Start a temporary local HTTP server to receive the OAuth callback.
270
+ * Awaits a successful listen before waiting for the code.
271
+ */
272
+ export async function startCallbackServer(redirectUri, expectedState, timeoutMs = 120_000, signal) {
273
+ const session = startCallbackSession(redirectUri, expectedState, timeoutMs, signal);
274
+ await session.listening;
275
+ return session.result;
161
276
  }
162
277
  // ============================================================================
163
278
  // Browser Opener
@@ -165,7 +280,7 @@ function startCallbackServer(redirectUri, expectedState, timeoutMs = 120_000) {
165
280
  /**
166
281
  * Open a URL in the default browser (cross-platform)
167
282
  */
168
- async function openBrowser(url) {
283
+ export async function openBrowser(url) {
169
284
  const { exec } = await import('child_process');
170
285
  const command = process.platform === 'win32'
171
286
  ? `start "" "${url}"`
@@ -244,9 +359,11 @@ export class MCPOAuthManager {
244
359
  authUrl.searchParams.set('state', state);
245
360
  authUrl.searchParams.set('code_challenge', codeChallenge);
246
361
  authUrl.searchParams.set('code_challenge_method', 'S256');
247
- // Start callback server
248
- const callbackPromise = startCallbackServer(redirectUri, state);
249
- // Open browser
362
+ // Bind the loopback callback before opening the browser: a listen failure
363
+ // must not launch a flow that can never complete (same contract as the SDK
364
+ // provider path). Keep the manual URL if the opener fails.
365
+ const session = startCallbackSession(redirectUri, state);
366
+ await session.listening;
250
367
  logger.info('Opening browser for OAuth authorization...');
251
368
  try {
252
369
  await openBrowser(authUrl.toString());
@@ -254,8 +371,7 @@ export class MCPOAuthManager {
254
371
  catch {
255
372
  logger.info(`Please open this URL in your browser:\n${authUrl.toString()}`);
256
373
  }
257
- // Wait for callback
258
- const { code } = await callbackPromise;
374
+ const { code } = await session.result;
259
375
  // Exchange code for token
260
376
  const token = await exchangeCodeForToken(config, code, codeVerifier, redirectUri);
261
377
  // Store token
@@ -306,14 +422,20 @@ export class MCPOAuthManager {
306
422
  // Load from disk
307
423
  const store = loadTokenStore();
308
424
  const entry = store[serverId];
309
- if (!entry)
425
+ const token = entry?.token;
426
+ if (!token?.accessToken || !entry)
310
427
  return null;
311
- const { token, config } = entry;
428
+ const { config } = entry;
312
429
  // If token is still valid (with 60s buffer), return it
313
430
  if (token.expiresAt > Date.now() + 60_000) {
314
431
  this.tokenCache.set(serverId, token);
315
432
  return token.accessToken;
316
433
  }
434
+ // Entries written by the SDK-backed provider are refreshed by the SDK itself.
435
+ if (config.tokenUrl === SDK_MANAGED_TOKEN_URL) {
436
+ logger.debug(`MCP OAuth token for ${serverId} is SDK-managed; refresh happens on the next transport connection`);
437
+ return null;
438
+ }
317
439
  // Try to refresh
318
440
  if (token.refreshToken) {
319
441
  try {
@@ -340,17 +462,42 @@ export class MCPOAuthManager {
340
462
  return null;
341
463
  }
342
464
  /**
343
- * Store a token encrypted on disk and in memory cache
465
+ * Store a token encrypted on disk and in memory cache.
466
+ * Preserves any previously persisted client metadata for the same server.
344
467
  */
345
468
  storeToken(serverId, token, config) {
346
469
  this.tokenCache.set(serverId, token);
347
470
  const store = loadTokenStore();
471
+ const prev = store[serverId];
472
+ const clientId = config.clientId || prev?.config.clientId || prev?.client?.client_id || '';
473
+ const client = prev?.client
474
+ ? storedClientFrom({ ...prev.client, ...(clientId ? { client_id: clientId } : {}) })
475
+ : (clientId ? storedClientFrom({ client_id: clientId }) : undefined);
348
476
  store[serverId] = {
349
477
  token,
350
478
  config: {
351
- clientId: config.clientId,
352
- tokenUrl: config.tokenUrl,
479
+ clientId,
480
+ tokenUrl: config.tokenUrl || prev?.config.tokenUrl || SDK_MANAGED_TOKEN_URL,
481
+ },
482
+ ...(client ? { client } : {}),
483
+ };
484
+ saveTokenStore(store);
485
+ }
486
+ /**
487
+ * Persist client registration (client_id and optional DCR metadata) in the
488
+ * encrypted store, even before a token exists. Never writes plaintext.
489
+ */
490
+ storeClientInformation(serverId, info) {
491
+ const client = storedClientFrom(info);
492
+ const store = loadTokenStore();
493
+ const prev = store[serverId];
494
+ store[serverId] = {
495
+ ...(prev?.token ? { token: prev.token } : {}),
496
+ config: {
497
+ clientId: client.client_id,
498
+ tokenUrl: prev?.config.tokenUrl ?? SDK_MANAGED_TOKEN_URL,
353
499
  },
500
+ client,
354
501
  };
355
502
  saveTokenStore(store);
356
503
  }
@@ -363,12 +510,41 @@ export class MCPOAuthManager {
363
510
  delete store[serverId];
364
511
  saveTokenStore(store);
365
512
  }
513
+ /** Drop access/refresh tokens only; keep client_id and DCR metadata. */
514
+ clearTokens(serverId) {
515
+ this.tokenCache.delete(serverId);
516
+ const store = loadTokenStore();
517
+ const prev = store[serverId];
518
+ if (!prev)
519
+ return;
520
+ const { token: _dropped, ...rest } = prev;
521
+ store[serverId] = rest;
522
+ if (!rest.client && !rest.config?.clientId)
523
+ delete store[serverId];
524
+ saveTokenStore(store);
525
+ }
366
526
  /**
367
527
  * Check if a token exists for a server (may be expired)
368
528
  */
529
+ /** Stored token and client id for a server, without refresh side effects. */
530
+ getStoredToken(serverId) {
531
+ const entry = loadTokenStore()[serverId];
532
+ if (!entry?.token?.accessToken)
533
+ return null;
534
+ return { token: entry.token, clientId: entry.config.clientId, ...(entry.client ? { client: entry.client } : {}) };
535
+ }
536
+ /** Persisted client id / DCR metadata, independent of whether a token exists. */
537
+ getStoredClientInformation(serverId) {
538
+ const entry = loadTokenStore()[serverId];
539
+ if (entry?.client?.client_id)
540
+ return entry.client;
541
+ if (entry?.config.clientId)
542
+ return { client_id: entry.config.clientId };
543
+ return null;
544
+ }
369
545
  hasToken(serverId) {
370
546
  const store = loadTokenStore();
371
- return serverId in store;
547
+ return Boolean(store[serverId]?.token?.accessToken);
372
548
  }
373
549
  }
374
550
  // ============================================================================
@@ -1,13 +1,19 @@
1
1
  import { Transport } from "@modelcontextprotocol/sdk/shared/transport.js";
2
+ import { type MCPTransportOAuthConfig } from "./mcp-oauth-provider.js";
2
3
  import { EventEmitter } from "events";
3
- export type TransportType = 'stdio' | 'http' | 'sse' | 'streamable_http';
4
+ export type TransportType = 'stdio' | 'http' | 'sse' | 'sse_sdk' | 'legacy_rpc' | 'streamable_http';
4
5
  export interface TransportConfig {
5
6
  type: TransportType;
6
7
  command?: string;
8
+ cwd?: string;
9
+ /** Imported stdio servers receive SDK baseline env plus explicit declarations only. */
10
+ inheritEnv?: boolean;
7
11
  args?: string[];
8
12
  env?: Record<string, string>;
9
13
  url?: string;
10
14
  headers?: Record<string, string>;
15
+ /** OAuth bearer for HTTP transports (SDK discovery + PKCE, tokens in .codebuddy/mcp-tokens.json). */
16
+ auth?: MCPTransportOAuthConfig;
11
17
  }
12
18
  export interface MCPTransport {
13
19
  connect(): Promise<Transport>;
@@ -31,9 +37,9 @@ export declare class HttpTransport extends EventEmitter implements MCPTransport
31
37
  disconnect(): Promise<void>;
32
38
  getType(): TransportType;
33
39
  }
34
- export declare class SSETransport extends EventEmitter implements MCPTransport {
40
+ export declare class SSETransport implements MCPTransport {
35
41
  private config;
36
- private connected;
42
+ private transport?;
37
43
  constructor(config: TransportConfig);
38
44
  connect(): Promise<Transport>;
39
45
  disconnect(): Promise<void>;
@@ -41,10 +47,13 @@ export declare class SSETransport extends EventEmitter implements MCPTransport {
41
47
  }
42
48
  export declare class StreamableHttpTransport extends EventEmitter implements MCPTransport {
43
49
  private config;
44
- private connected;
50
+ private transport?;
51
+ private oauthProvider?;
45
52
  constructor(config: TransportConfig);
46
53
  connect(): Promise<Transport>;
47
54
  disconnect(): Promise<void>;
48
55
  getType(): TransportType;
49
56
  }
50
- export declare function createTransport(config: TransportConfig): MCPTransport;
57
+ /** Resolve references only at connection time; missing credentials fail closed. */
58
+ export declare function resolveMCPTransport(config: TransportConfig): TransportConfig;
59
+ export declare function createTransport(input: TransportConfig): MCPTransport;