@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.
- package/README.fr.md +56 -0
- package/README.md +74 -16
- package/codebuddy-runtime.json +5 -5
- package/dist/agent/codebuddy-agent.d.ts +18 -0
- package/dist/agent/codebuddy-agent.js +45 -8
- package/dist/agent/execution/agent-executor.d.ts +0 -9
- package/dist/agent/execution/agent-executor.js +176 -12
- package/dist/agent/execution/context-pipeline.d.ts +9 -0
- package/dist/agent/execution/context-pipeline.js +64 -2
- package/dist/agent/execution/tool-loop-guard.d.ts +76 -0
- package/dist/agent/execution/tool-loop-guard.js +165 -0
- package/dist/agent/execution/tool-selection-strategy.d.ts +7 -0
- package/dist/agent/execution/tool-selection-strategy.js +32 -2
- package/dist/agent/facades/session-facade.d.ts +0 -6
- package/dist/agent/facades/session-facade.js +0 -45
- package/dist/agent/hermes-claw-migrate.d.ts +0 -21
- package/dist/agent/hermes-claw-migrate.js +9 -4
- package/dist/agent/hermes-protocol-gateways.js +8 -1
- package/dist/agent/repo-profiler.js +17 -4
- package/dist/agent/self-improvement/authored-tool-runtime.js +10 -2
- package/dist/agent/self-improvement/evolution/ast-novelty.d.ts +5 -0
- package/dist/agent/self-improvement/evolution/ast-novelty.js +58 -23
- package/dist/agent/self-improvement/evolution/code-variant-store.d.ts +3 -0
- package/dist/agent/self-improvement/evolution/evolution-engine.js +2 -0
- package/dist/agent/self-improvement/evolution/protected-paths.js +6 -0
- package/dist/agent/self-improvement/evolution/variant-fitness.d.ts +13 -2
- package/dist/agent/self-improvement/evolution/variant-fitness.js +184 -58
- package/dist/agent/self-improvement/evolution/worktree-scorer.d.ts +2 -0
- package/dist/agent/self-improvement/evolution/worktree-scorer.js +15 -0
- package/dist/agent/self-improvement/evolutionary-archive.d.ts +2 -1
- package/dist/agent/self-improvement/evolutionary-archive.js +34 -5
- package/dist/agent/self-improvement/proposal-store.d.ts +1 -0
- package/dist/agent/self-improvement/proposal-store.js +79 -17
- package/dist/agent/self-improvement/skill-apply-journal.d.ts +44 -0
- package/dist/agent/self-improvement/skill-apply-journal.js +178 -0
- package/dist/agent/self-improvement/skill-behavior-benchmark.d.ts +3 -0
- package/dist/agent/self-improvement/skill-behavior-benchmark.js +19 -0
- package/dist/agent/self-improvement/skill-behavior-gate.d.ts +34 -0
- package/dist/agent/self-improvement/skill-behavior-gate.js +96 -0
- package/dist/agent/self-improvement/skill-engine.d.ts +22 -0
- package/dist/agent/self-improvement/skill-engine.js +385 -13
- package/dist/agent/self-improvement/skill-gate.d.ts +2 -0
- package/dist/agent/self-improvement/skill-gate.js +17 -2
- package/dist/agent/self-improvement/skill-mutator.d.ts +6 -1
- package/dist/agent/self-improvement/skill-mutator.js +51 -15
- package/dist/agent/self-improvement/skill-types.d.ts +2 -1
- package/dist/agent/self-improvement/types.d.ts +11 -0
- package/dist/agent/tool-handler.d.ts +1 -1
- package/dist/agent/tool-handler.js +28 -9
- package/dist/auth/profile-manager.js +1 -1
- package/dist/channels/companion-channel-turn.d.ts +53 -4
- package/dist/channels/companion-channel-turn.js +218 -16
- package/dist/channels/slash-parity.d.ts +4 -6
- package/dist/channels/slash-parity.js +9 -44
- package/dist/cli/session-commands.d.ts +9 -0
- package/dist/cli/session-commands.js +45 -5
- package/dist/cli/session-picker.d.ts +43 -0
- package/dist/cli/session-picker.js +128 -0
- package/dist/codebuddy/a2a-call-tool-defs.d.ts +26 -0
- package/dist/codebuddy/a2a-call-tool-defs.js +12 -0
- package/dist/codebuddy/fleet-tool-defs.d.ts +2 -0
- package/dist/codebuddy/fleet-tool-defs.js +55 -0
- package/dist/codebuddy/providers/chatgpt-headers.d.ts +18 -0
- package/dist/codebuddy/providers/chatgpt-headers.js +37 -0
- package/dist/codebuddy/providers/provider-chatgpt-responses.d.ts +2 -1
- package/dist/codebuddy/providers/provider-chatgpt-responses.js +10 -23
- package/dist/codebuddy/providers/provider-openai-compat.d.ts +7 -0
- package/dist/codebuddy/providers/provider-openai-compat.js +29 -1
- package/dist/codebuddy/ragchat-tool-defs.d.ts +31 -0
- package/dist/codebuddy/ragchat-tool-defs.js +19 -0
- package/dist/codebuddy/resource-catalog-tool-defs.d.ts +28 -0
- package/dist/codebuddy/resource-catalog-tool-defs.js +18 -0
- package/dist/codebuddy/tool-definitions/agent-tools.js +2 -2
- package/dist/codebuddy/tool-definitions/code-exec-tools.js +5 -1
- package/dist/codebuddy/tool-definitions/cron-tools.js +6 -0
- package/dist/codebuddy/tool-definitions/self-describe-tools.js +6 -1
- package/dist/codebuddy/tools.d.ts +0 -6
- package/dist/codebuddy/tools.js +25 -3
- package/dist/commands/cli/daemon-commands.js +3 -1
- package/dist/commands/cli/evolve-command.js +21 -5
- package/dist/commands/cli/fleet-collaboration-commands.d.ts +2 -0
- package/dist/commands/cli/fleet-collaboration-commands.js +57 -0
- package/dist/commands/cli/fleet-commands.js +29 -0
- package/dist/commands/cli/fleet-mission-commands.d.ts +3 -0
- package/dist/commands/cli/fleet-mission-commands.js +72 -0
- package/dist/commands/cli/fleet-rooms-commands.d.ts +10 -0
- package/dist/commands/cli/fleet-rooms-commands.js +289 -0
- package/dist/commands/cli/tools-commands.js +2 -1
- package/dist/commands/cli/triage-command.d.ts +8 -0
- package/dist/commands/cli/triage-command.js +72 -0
- package/dist/commands/cli/utility-commands.js +25 -1
- package/dist/commands/client-dispatcher.d.ts +7 -0
- package/dist/commands/client-dispatcher.js +73 -21
- package/dist/commands/cron-cli/index.d.ts +3 -1
- package/dist/commands/cron-cli/index.js +25 -0
- package/dist/commands/device-auth.d.ts +10 -0
- package/dist/commands/device-auth.js +91 -0
- package/dist/commands/enhanced-command-handler.d.ts +9 -0
- package/dist/commands/enhanced-command-handler.js +28 -6
- package/dist/commands/handlers/agent-handlers.d.ts +1 -1
- package/dist/commands/handlers/agent-handlers.js +4 -4
- package/dist/commands/handlers/channel-handlers.js +53 -2
- package/dist/commands/handlers/export-handlers.d.ts +3 -2
- package/dist/commands/handlers/export-handlers.js +55 -28
- package/dist/commands/handlers/extra-handlers.js +5 -1
- package/dist/commands/handlers/grill-me-handler.js +26 -18
- package/dist/commands/handlers/memory-handlers.d.ts +6 -2
- package/dist/commands/handlers/memory-handlers.js +35 -15
- package/dist/commands/handlers/missing-handlers.d.ts +2 -2
- package/dist/commands/handlers/missing-handlers.js +12 -4
- package/dist/commands/handlers/resources-handler.d.ts +12 -0
- package/dist/commands/handlers/resources-handler.js +52 -0
- package/dist/commands/handlers/starter-handlers.d.ts +1 -1
- package/dist/commands/handlers/starter-handlers.js +32 -2
- package/dist/commands/handlers/switch-handler.d.ts +1 -1
- package/dist/commands/handlers/switch-handler.js +15 -0
- package/dist/commands/handlers/test-handlers.js +4 -86
- package/dist/commands/handlers/ui-handlers.js +11 -5
- package/dist/commands/login-chatgpt.d.ts +8 -0
- package/dist/commands/login-chatgpt.js +17 -0
- package/dist/commands/mcp-import.d.ts +11 -0
- package/dist/commands/mcp-import.js +67 -0
- package/dist/commands/mcp-invoke.d.ts +2 -0
- package/dist/commands/mcp-invoke.js +68 -0
- package/dist/commands/mcp.d.ts +13 -0
- package/dist/commands/mcp.js +66 -21
- package/dist/commands/pipeline.d.ts +7 -1
- package/dist/commands/pipeline.js +104 -7
- package/dist/commands/resources.d.ts +2 -0
- package/dist/commands/resources.js +64 -0
- package/dist/commands/skills-cli/index.js +35 -12
- package/dist/commands/slash/builtin-commands.js +16 -3
- package/dist/commands/slash/index.d.ts +3 -1
- package/dist/commands/slash/index.js +2 -0
- package/dist/commands/slash/surfaces.d.ts +53 -0
- package/dist/commands/slash/surfaces.js +177 -0
- package/dist/commands/slash/types.d.ts +17 -0
- package/dist/commands/try.d.ts +1 -1
- package/dist/commands/try.js +1 -1
- package/dist/companion/companion-identity.d.ts +43 -0
- package/dist/companion/companion-identity.js +136 -0
- package/dist/companion/companion-toolset.d.ts +66 -0
- package/dist/companion/companion-toolset.js +368 -0
- package/dist/companion/companion-turn.d.ts +10 -2
- package/dist/companion/companion-turn.js +38 -1
- package/dist/config/code-exec-policy.d.ts +25 -0
- package/dist/config/code-exec-policy.js +39 -0
- package/dist/config/model-tools.d.ts +9 -0
- package/dist/config/model-tools.js +103 -0
- package/dist/context/context-manager-v2.js +2 -2
- package/dist/context/lm-resizer-compressor.js +3 -2
- package/dist/context/lm-resizer-diagnostics.d.ts +9 -0
- package/dist/context/lm-resizer-diagnostics.js +30 -0
- package/dist/context/tool-output-masking.js +3 -4
- package/dist/curator/curator.d.ts +6 -0
- package/dist/curator/curator.js +53 -3
- package/dist/daemon/cron-agent-bridge.d.ts +6 -0
- package/dist/daemon/cron-agent-bridge.js +31 -4
- package/dist/doctor/index.d.ts +11 -2
- package/dist/doctor/index.js +84 -21
- package/dist/doctor/integrations.d.ts +197 -0
- package/dist/doctor/integrations.js +241 -0
- package/dist/doctor/triage.d.ts +108 -0
- package/dist/doctor/triage.js +304 -0
- package/dist/errors/crash-handler.js +2 -0
- package/dist/fleet/collaboration.d.ts +44 -0
- package/dist/fleet/collaboration.js +170 -0
- package/dist/fleet/fleet-listener.d.ts +1 -0
- package/dist/fleet/fleet-listener.js +87 -46
- package/dist/fleet/fleet-registry.d.ts +2 -0
- package/dist/fleet/resource-catalog.d.ts +245 -0
- package/dist/fleet/resource-catalog.js +211 -0
- package/dist/fleet/rooms/room-access.d.ts +138 -0
- package/dist/fleet/rooms/room-access.js +196 -0
- package/dist/fleet/rooms/room-client.d.ts +158 -0
- package/dist/fleet/rooms/room-client.js +685 -0
- package/dist/fleet/rooms/room-event.d.ts +139 -0
- package/dist/fleet/rooms/room-event.js +330 -0
- package/dist/fleet/rooms/room-filter.d.ts +48 -0
- package/dist/fleet/rooms/room-filter.js +152 -0
- package/dist/fleet/rooms/room-hub.d.ts +154 -0
- package/dist/fleet/rooms/room-hub.js +363 -0
- package/dist/fleet/rooms/room-identity.d.ts +26 -0
- package/dist/fleet/rooms/room-identity.js +82 -0
- package/dist/fleet/rooms/room-lock.d.ts +34 -0
- package/dist/fleet/rooms/room-lock.js +180 -0
- package/dist/fleet/rooms/room-observations.d.ts +7 -0
- package/dist/fleet/rooms/room-observations.js +61 -0
- package/dist/fleet/rooms/room-server.d.ts +28 -0
- package/dist/fleet/rooms/room-server.js +75 -0
- package/dist/fleet/rooms/room-store.d.ts +119 -0
- package/dist/fleet/rooms/room-store.js +448 -0
- package/dist/fleet/rooms/room-ws-bridge.d.ts +27 -0
- package/dist/fleet/rooms/room-ws-bridge.js +137 -0
- package/dist/fleet/sensory-mission-bridge.d.ts +42 -0
- package/dist/fleet/sensory-mission-bridge.js +136 -0
- package/dist/git/worktree-sessions.js +1 -0
- package/dist/harness/contract.d.ts +4 -4
- package/dist/harness/fleet-supervisor.d.ts +16 -0
- package/dist/harness/fleet-supervisor.js +64 -0
- package/dist/harness/index.d.ts +4 -0
- package/dist/harness/index.js +4 -0
- package/dist/harness/mission-runner.d.ts +3 -0
- package/dist/harness/mission-runner.js +53 -0
- package/dist/harness/mission-store.d.ts +93 -0
- package/dist/harness/mission-store.js +297 -0
- package/dist/harness/tool-harness.d.ts +56 -0
- package/dist/harness/tool-harness.js +153 -0
- package/dist/hooks/use-enhanced-input.js +48 -4
- package/dist/hooks/use-input-handler.d.ts +1 -0
- package/dist/hooks/use-input-handler.js +82 -22
- package/dist/hooks/use-input-history.js +1 -0
- package/dist/identity/lisa-introspection.js +5 -2
- package/dist/identity/operational-self-model.d.ts +2 -0
- package/dist/identity/operational-self-model.js +4 -0
- package/dist/index.js +52 -6
- package/dist/mcp/client.d.ts +11 -0
- package/dist/mcp/client.js +68 -3
- package/dist/mcp/config.d.ts +20 -0
- package/dist/mcp/config.js +121 -8
- package/dist/mcp/import-normalize.d.ts +12 -0
- package/dist/mcp/import-normalize.js +114 -0
- package/dist/mcp/mcp-oauth-constants.d.ts +8 -0
- package/dist/mcp/mcp-oauth-constants.js +9 -0
- package/dist/mcp/mcp-oauth-provider.d.ts +80 -0
- package/dist/mcp/mcp-oauth-provider.js +241 -0
- package/dist/mcp/mcp-oauth.d.ts +60 -1
- package/dist/mcp/mcp-oauth.js +241 -65
- package/dist/mcp/transports.d.ts +14 -5
- package/dist/mcp/transports.js +112 -101
- package/dist/mcp/types.d.ts +5 -0
- package/dist/media/comfyui-recipe-contract.d.ts +7 -7
- package/dist/memory/facts-memory.d.ts +11 -1
- package/dist/memory/facts-memory.js +47 -8
- package/dist/memory/memory-candidate-queue.d.ts +2 -2
- package/dist/memory/memory-candidate-queue.js +6 -6
- package/dist/memory/persistent-memory.d.ts +13 -8
- package/dist/memory/persistent-memory.js +77 -30
- package/dist/nodes/device-node.js +5 -9
- package/dist/observability/mobile-supervision-gateway-contract.js +20 -7
- package/dist/observability/run-event-writer.d.ts +21 -0
- package/dist/observability/run-event-writer.js +81 -0
- package/dist/observability/run-store.d.ts +5 -0
- package/dist/observability/run-store.js +18 -13
- package/dist/observability/run-trajectory.js +1 -1
- package/dist/optimization/prompt-cache.d.ts +19 -2
- package/dist/optimization/prompt-cache.js +41 -6
- package/dist/orchestration/orchestrator.d.ts +21 -0
- package/dist/orchestration/orchestrator.js +122 -15
- package/dist/persistence/session-content.d.ts +8 -0
- package/dist/persistence/session-content.js +76 -0
- package/dist/persistence/session-handoff.d.ts +64 -0
- package/dist/persistence/session-handoff.js +80 -0
- package/dist/persistence/session-history.d.ts +4 -0
- package/dist/persistence/session-history.js +38 -0
- package/dist/persistence/session-store.d.ts +9 -0
- package/dist/persistence/session-store.js +48 -20
- package/dist/personas/persona-manager.js +17 -1
- package/dist/plugins/code-explorer/CodeExplorerManager.d.ts +10 -4
- package/dist/plugins/code-explorer/CodeExplorerManager.js +69 -16
- package/dist/plugins/plugin-manager.js +10 -1
- package/dist/prompts/prompt-manager.js +11 -4
- package/dist/prompts/system-base.js +6 -2
- package/dist/protocols/a2a/codebuddy-executor.d.ts +11 -2
- package/dist/protocols/a2a/codebuddy-executor.js +9 -8
- package/dist/protocols/a2a/index.d.ts +1 -1
- package/dist/protocols/a2a/jsonrpc-v1.d.ts +41 -0
- package/dist/protocols/a2a/jsonrpc-v1.js +145 -0
- package/dist/protocols/a2a/peer-config.d.ts +20 -0
- package/dist/protocols/a2a/peer-config.js +55 -0
- package/dist/providers/codex-oauth.js +30 -6
- package/dist/providers/model-provider-compat.js +2 -1
- package/dist/sandbox/os-sandbox.d.ts +1 -1
- package/dist/scheduler/cron-scheduler.d.ts +15 -2
- package/dist/scheduler/cron-scheduler.js +35 -4
- package/dist/scheduler/job-notepad.d.ts +69 -0
- package/dist/scheduler/job-notepad.js +339 -0
- package/dist/security/audit-logger.d.ts +1 -1
- package/dist/security/compute-confinement.d.ts +4 -0
- package/dist/security/compute-confinement.js +89 -0
- package/dist/security/session-encryption.d.ts +4 -0
- package/dist/security/session-encryption.js +31 -0
- package/dist/sensory/voice-loop.d.ts +17 -0
- package/dist/sensory/voice-loop.js +72 -15
- package/dist/server/auth/device-session-context.d.ts +9 -0
- package/dist/server/auth/device-session-context.js +13 -0
- package/dist/server/auth/device-store.d.ts +89 -0
- package/dist/server/auth/device-store.js +261 -0
- package/dist/server/auth/device-token.d.ts +3 -0
- package/dist/server/auth/device-token.js +6 -0
- package/dist/server/auth/jwt.js +4 -0
- package/dist/server/index.d.ts +0 -10
- package/dist/server/index.js +28 -0
- package/dist/server/middleware/auth.js +3 -2
- package/dist/server/routes/a2a-jsonrpc.d.ts +9 -0
- package/dist/server/routes/a2a-jsonrpc.js +66 -0
- package/dist/server/routes/a2a-protocol.d.ts +12 -0
- package/dist/server/routes/a2a-protocol.js +1 -1
- package/dist/server/routes/device-auth.d.ts +4 -0
- package/dist/server/routes/device-auth.js +40 -0
- package/dist/server/types.d.ts +4 -0
- package/dist/server/websocket/handler.d.ts +13 -0
- package/dist/server/websocket/handler.js +102 -17
- package/dist/services/prompt-builder.d.ts +2 -0
- package/dist/services/prompt-builder.js +16 -6
- package/dist/services/runtime-settings-context.d.ts +81 -0
- package/dist/services/runtime-settings-context.js +79 -0
- package/dist/skills/executor.js +2 -0
- package/dist/skills/hub.js +16 -14
- package/dist/skills/local-inventory.d.ts +21 -0
- package/dist/skills/local-inventory.js +72 -0
- package/dist/skills/skill-loader.js +2 -2
- package/dist/skills/skill-usage-store.d.ts +49 -0
- package/dist/skills/skill-usage-store.js +121 -0
- package/dist/testing/ai-integration-tests.js +8 -5
- package/dist/themes/theme-manager.d.ts +12 -0
- package/dist/themes/theme-manager.js +29 -0
- package/dist/themes/theme-schema.d.ts +24 -24
- package/dist/tools/a2a-call-tool.d.ts +34 -0
- package/dist/tools/a2a-call-tool.js +75 -0
- package/dist/tools/bash/streaming-executor.d.ts +1 -0
- package/dist/tools/bash/streaming-executor.js +78 -90
- package/dist/tools/code-exec-preflight-runner.d.ts +41 -0
- package/dist/tools/code-exec-preflight-runner.js +254 -0
- package/dist/tools/code-exec-preflight.d.ts +44 -0
- package/dist/tools/code-exec-preflight.js +501 -0
- package/dist/tools/code-exec-tool.d.ts +48 -1
- package/dist/tools/code-exec-tool.js +191 -47
- package/dist/tools/comment-watcher.js +29 -12
- package/dist/tools/core-code-inspection.d.ts +56 -0
- package/dist/tools/core-code-inspection.js +86 -0
- package/dist/tools/create-skill-tool.d.ts +2 -3
- package/dist/tools/create-skill-tool.js +16 -75
- package/dist/tools/cronjob-tool.d.ts +1 -0
- package/dist/tools/cronjob-tool.js +1 -0
- package/dist/tools/env-doctor-tool.d.ts +2 -0
- package/dist/tools/env-doctor-tool.js +4 -3
- package/dist/tools/execute-code-rpc-invoker.d.ts +1 -1
- package/dist/tools/execute-code-rpc-invoker.js +35 -19
- package/dist/tools/execute-code-runner.d.ts +2 -0
- package/dist/tools/execute-code-runner.js +52 -17
- package/dist/tools/fleet-room-tool.d.ts +104 -0
- package/dist/tools/fleet-room-tool.js +124 -0
- package/dist/tools/integration-tool-hints.d.ts +4 -0
- package/dist/tools/integration-tool-hints.js +19 -0
- package/dist/tools/list-peers-tool.d.ts +3 -0
- package/dist/tools/list-peers-tool.js +11 -4
- package/dist/tools/media-generation-tool.d.ts +16 -1
- package/dist/tools/media-generation-tool.js +341 -9
- package/dist/tools/merge-conflict-tool.js +53 -25
- package/dist/tools/metadata.d.ts +1 -5
- package/dist/tools/metadata.js +30 -28
- package/dist/tools/peer-tool-invoke-tool.d.ts +61 -0
- package/dist/tools/peer-tool-invoke-tool.js +396 -0
- package/dist/tools/ragchat-tool.d.ts +39 -0
- package/dist/tools/ragchat-tool.js +105 -0
- package/dist/tools/registry/fleet-tools.d.ts +21 -3
- package/dist/tools/registry/fleet-tools.js +137 -4
- package/dist/tools/registry/index.d.ts +1 -1
- package/dist/tools/registry/index.js +2 -2
- package/dist/tools/registry/knowledge-tools.d.ts +2 -2
- package/dist/tools/registry/knowledge-tools.js +2 -2
- package/dist/tools/registry/lessons-tools.d.ts +7 -0
- package/dist/tools/registry/lessons-tools.js +43 -3
- package/dist/tools/registry/memory-tools.d.ts +1 -1
- package/dist/tools/registry/memory-tools.js +8 -8
- package/dist/tools/registry/research-tools.d.ts +1 -0
- package/dist/tools/registry/research-tools.js +4 -13
- package/dist/tools/registry/self-describe-tools.d.ts +1 -1
- package/dist/tools/registry/self-describe-tools.js +43 -30
- package/dist/tools/resource-catalog-tool.d.ts +38 -0
- package/dist/tools/resource-catalog-tool.js +46 -0
- package/dist/tools/skills-inspection-tool.js +30 -1
- package/dist/tools/stream-tool-output.d.ts +3 -0
- package/dist/tools/stream-tool-output.js +33 -0
- package/dist/tools/tool-call-scheduler.d.ts +10 -0
- package/dist/tools/tool-call-scheduler.js +58 -0
- package/dist/tools/tool-effect.d.ts +5 -0
- package/dist/tools/tool-effect.js +26 -0
- package/dist/tools/tool-search.d.ts +12 -11
- package/dist/tools/tool-search.js +67 -26
- package/dist/tools/types.d.ts +6 -0
- package/dist/ui/components/ChatHistory.d.ts +1 -1
- package/dist/ui/components/ChatHistory.js +2 -2
- package/dist/ui/components/ChatInput.d.ts +2 -1
- package/dist/ui/components/ChatInput.js +42 -88
- package/dist/ui/components/ChatInterface.d.ts +4 -2
- package/dist/ui/components/ChatInterface.js +27 -63
- package/dist/ui/components/CommandSuggestions.d.ts +0 -1
- package/dist/ui/components/CommandSuggestions.js +4 -6
- package/dist/ui/components/FileAutocomplete.js +1 -1
- package/dist/ui/components/KeyboardHelp.js +8 -6
- package/dist/ui/components/ModelSelection.js +6 -5
- package/dist/ui/components/StatusBar.d.ts +2 -1
- package/dist/ui/components/StatusBar.js +8 -7
- package/dist/ui/context/theme-context.js +3 -2
- package/dist/ui/index.d.ts +1 -1
- package/dist/ui/index.js +1 -1
- package/dist/ui/utils/markdown-renderer.js +4 -13
- package/dist/utils/atomic-write.d.ts +22 -0
- package/dist/utils/atomic-write.js +29 -0
- package/dist/utils/bounded-output.d.ts +16 -0
- package/dist/utils/bounded-output.js +63 -0
- package/dist/utils/config-validation/schema.d.ts +2 -2
- package/dist/utils/device-store-file.d.ts +4 -0
- package/dist/utils/device-store-file.js +40 -0
- package/dist/utils/export-manager.d.ts +9 -0
- package/dist/utils/export-manager.js +19 -0
- package/dist/utils/first-use-hints.d.ts +25 -0
- package/dist/utils/first-use-hints.js +58 -0
- package/dist/utils/graceful-shutdown.d.ts +8 -0
- package/dist/utils/graceful-shutdown.js +23 -7
- package/dist/utils/history-manager.js +1 -1
- package/dist/utils/update-notifier.js +16 -18
- package/dist/wizard/environment-detection.d.ts +5 -1
- package/dist/wizard/environment-detection.js +49 -7
- package/dist/wizard/onboarding.d.ts +5 -1
- package/dist/wizard/onboarding.js +90 -30
- package/dist/wizard/provider-onboarding.d.ts +2 -0
- package/dist/wizard/provider-onboarding.js +55 -17
- package/package.json +7 -3
package/dist/mcp/transports.js
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { SSEClientTransport as SDKSSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";
|
|
2
|
+
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
|
|
3
|
+
import { StdioClientTransport, getDefaultEnvironment } from "@modelcontextprotocol/sdk/client/stdio.js";
|
|
4
|
+
import { createOAuthProvider } from "./mcp-oauth-provider.js";
|
|
2
5
|
import { EventEmitter } from "events";
|
|
3
6
|
import axios from "axios";
|
|
4
7
|
import { logger } from '../utils/logger.js';
|
|
@@ -14,7 +17,7 @@ export class StdioTransport {
|
|
|
14
17
|
async connect() {
|
|
15
18
|
// Create transport with environment variables to suppress verbose output
|
|
16
19
|
const env = {
|
|
17
|
-
...process.env,
|
|
20
|
+
...(this.config.inheritEnv === false ? getDefaultEnvironment() : process.env),
|
|
18
21
|
...this.config.env,
|
|
19
22
|
// Try to suppress verbose output from mcp-remote
|
|
20
23
|
MCP_REMOTE_QUIET: '1',
|
|
@@ -25,6 +28,7 @@ export class StdioTransport {
|
|
|
25
28
|
const transportConfig = {
|
|
26
29
|
command: this.config.command,
|
|
27
30
|
args: this.config.args || [],
|
|
31
|
+
cwd: this.config.cwd,
|
|
28
32
|
env,
|
|
29
33
|
// The SDK default is stderr:'inherit', which lets a noisy MCP server
|
|
30
34
|
// (startup banners, progress logs) write raw bytes into the CLI's own
|
|
@@ -46,10 +50,14 @@ export class StdioTransport {
|
|
|
46
50
|
}
|
|
47
51
|
async disconnect() {
|
|
48
52
|
if (this.transport) {
|
|
49
|
-
|
|
50
|
-
|
|
53
|
+
try {
|
|
54
|
+
await this.transport.close();
|
|
55
|
+
}
|
|
56
|
+
finally {
|
|
57
|
+
this.transport = undefined;
|
|
58
|
+
}
|
|
51
59
|
}
|
|
52
|
-
//
|
|
60
|
+
// SDK close() ends stdin, then SIGTERM/SIGKILL the child it spawned.
|
|
53
61
|
}
|
|
54
62
|
getType() {
|
|
55
63
|
return 'stdio';
|
|
@@ -69,6 +77,7 @@ export class HttpTransport extends EventEmitter {
|
|
|
69
77
|
async connect() {
|
|
70
78
|
this.client = axios.create({
|
|
71
79
|
baseURL: this.config.url,
|
|
80
|
+
maxRedirects: 0,
|
|
72
81
|
headers: {
|
|
73
82
|
'Content-Type': 'application/json',
|
|
74
83
|
...this.config.headers
|
|
@@ -93,35 +102,28 @@ export class HttpTransport extends EventEmitter {
|
|
|
93
102
|
return 'http';
|
|
94
103
|
}
|
|
95
104
|
}
|
|
96
|
-
export class SSETransport
|
|
105
|
+
export class SSETransport {
|
|
97
106
|
config;
|
|
98
|
-
|
|
107
|
+
transport;
|
|
99
108
|
constructor(config) {
|
|
100
|
-
super();
|
|
101
109
|
this.config = config;
|
|
102
|
-
if (!config.url)
|
|
103
|
-
throw new Error('URL is required for SSE MCP transport
|
|
104
|
-
}
|
|
110
|
+
if (!config.url)
|
|
111
|
+
throw new Error('URL is required for SSE MCP transport');
|
|
105
112
|
}
|
|
106
113
|
async connect() {
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
reject(error);
|
|
116
|
-
}
|
|
114
|
+
this.transport = new SDKSSEClientTransport(new URL(this.config.url), {
|
|
115
|
+
requestInit: { headers: this.config.headers, redirect: 'error' },
|
|
116
|
+
eventSourceInit: { fetch: (url, init) => {
|
|
117
|
+
const headers = new Headers(init?.headers);
|
|
118
|
+
for (const [key, value] of Object.entries(this.config.headers ?? {}))
|
|
119
|
+
headers.set(key, value);
|
|
120
|
+
return fetch(url, { ...init, headers, redirect: 'error' });
|
|
121
|
+
} },
|
|
117
122
|
});
|
|
123
|
+
return this.transport;
|
|
118
124
|
}
|
|
119
|
-
async disconnect() {
|
|
120
|
-
|
|
121
|
-
}
|
|
122
|
-
getType() {
|
|
123
|
-
return 'sse';
|
|
124
|
-
}
|
|
125
|
+
async disconnect() { await this.transport?.close(); this.transport = undefined; }
|
|
126
|
+
getType() { return 'sse'; }
|
|
125
127
|
}
|
|
126
128
|
// Custom HTTP Transport implementation
|
|
127
129
|
class HttpClientTransport extends EventEmitter {
|
|
@@ -156,105 +158,114 @@ class HttpClientTransport extends EventEmitter {
|
|
|
156
158
|
}
|
|
157
159
|
}
|
|
158
160
|
}
|
|
159
|
-
// Custom SSE Transport implementation
|
|
160
|
-
class SSEClientTransport extends EventEmitter {
|
|
161
|
-
url;
|
|
162
|
-
onclose;
|
|
163
|
-
onerror;
|
|
164
|
-
onmessage;
|
|
165
|
-
sessionId;
|
|
166
|
-
constructor(url) {
|
|
167
|
-
super();
|
|
168
|
-
this.url = url;
|
|
169
|
-
}
|
|
170
|
-
async start() {
|
|
171
|
-
// SSE transport is event-driven, so we're always "started"
|
|
172
|
-
}
|
|
173
|
-
async close() {
|
|
174
|
-
// Nothing to close for basic SSE transport
|
|
175
|
-
}
|
|
176
|
-
async send(message, _options) {
|
|
177
|
-
// For bidirectional communication over SSE, we typically use HTTP POST
|
|
178
|
-
// for sending messages and SSE for receiving
|
|
179
|
-
try {
|
|
180
|
-
const response = await axios.post(this.url.replace('/sse', '/rpc'), message, {
|
|
181
|
-
headers: { 'Content-Type': 'application/json' }
|
|
182
|
-
});
|
|
183
|
-
if (this.onmessage && response.data) {
|
|
184
|
-
this.onmessage(response.data);
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
catch (error) {
|
|
188
|
-
const err = new Error(`SSE transport error: ${error}`);
|
|
189
|
-
if (this.onerror) {
|
|
190
|
-
this.onerror(err);
|
|
191
|
-
}
|
|
192
|
-
throw err;
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
161
|
export class StreamableHttpTransport extends EventEmitter {
|
|
197
162
|
config;
|
|
198
|
-
|
|
163
|
+
transport;
|
|
164
|
+
oauthProvider;
|
|
199
165
|
constructor(config) {
|
|
200
166
|
super();
|
|
201
167
|
this.config = config;
|
|
202
|
-
if (!config.url)
|
|
168
|
+
if (!config.url)
|
|
203
169
|
throw new Error('URL is required for streamable_http transport');
|
|
204
|
-
}
|
|
205
170
|
}
|
|
206
171
|
async connect() {
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
}
|
|
172
|
+
const url = new URL(this.config.url);
|
|
173
|
+
if (!['http:', 'https:'].includes(url.protocol)) {
|
|
174
|
+
throw new Error('Streamable HTTP MCP requires an HTTP(S) URL');
|
|
175
|
+
}
|
|
176
|
+
const provider = this.config.auth?.type === 'oauth' ? createOAuthProvider(this.config.url, this.config.auth) : undefined;
|
|
177
|
+
this.oauthProvider = provider;
|
|
178
|
+
this.transport = new StreamableHTTPClientTransport(url, {
|
|
179
|
+
requestInit: { headers: this.config.headers, redirect: 'error' },
|
|
180
|
+
...(provider ? { authProvider: provider } : {}),
|
|
215
181
|
});
|
|
182
|
+
provider?.attachTransport(this.transport);
|
|
183
|
+
return this.transport;
|
|
216
184
|
}
|
|
217
185
|
async disconnect() {
|
|
218
|
-
this.
|
|
186
|
+
this.oauthProvider?.abortAuthorization();
|
|
187
|
+
this.oauthProvider = undefined;
|
|
188
|
+
const transport = this.transport;
|
|
189
|
+
this.transport = undefined;
|
|
190
|
+
await transport?.close();
|
|
219
191
|
}
|
|
220
192
|
getType() {
|
|
221
193
|
return 'streamable_http';
|
|
222
194
|
}
|
|
223
195
|
}
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
196
|
+
/** Resolve references only at connection time; missing credentials fail closed. */
|
|
197
|
+
export function resolveMCPTransport(config) {
|
|
198
|
+
const resolve = (value) => value.replace(/\$\{([A-Za-z_][A-Za-z0-9_]*)\}/g, (_match, key) => {
|
|
199
|
+
const result = process.env[key];
|
|
200
|
+
if (!result)
|
|
201
|
+
throw new Error(`Missing MCP environment reference: ${key}`);
|
|
202
|
+
return result;
|
|
203
|
+
});
|
|
204
|
+
const map = (values) => values && Object.fromEntries(Object.entries(values).map(([k, v]) => [k, resolve(v)]));
|
|
205
|
+
const resolved = { ...config, command: config.command && resolve(config.command), cwd: config.cwd && resolve(config.cwd),
|
|
206
|
+
args: config.args?.map(resolve), env: map(config.env), headers: map(config.headers), url: config.url && resolve(config.url) };
|
|
207
|
+
if (resolved.url) {
|
|
208
|
+
let url;
|
|
209
|
+
try {
|
|
210
|
+
url = new URL(resolved.url);
|
|
211
|
+
}
|
|
212
|
+
catch {
|
|
213
|
+
throw new Error('Invalid MCP endpoint configuration');
|
|
214
|
+
}
|
|
215
|
+
if (!['http:', 'https:'].includes(url.protocol) || url.username || url.password || url.search || url.hash)
|
|
216
|
+
throw new Error('MCP requires HTTP(S) without embedded credentials, query or fragment');
|
|
242
217
|
}
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
218
|
+
if (config.auth) {
|
|
219
|
+
const auth = { ...config.auth,
|
|
220
|
+
serverId: config.auth.serverId && resolve(config.auth.serverId),
|
|
221
|
+
clientId: config.auth.clientId && resolve(config.auth.clientId),
|
|
222
|
+
clientMetadataUrl: config.auth.clientMetadataUrl && resolve(config.auth.clientMetadataUrl),
|
|
223
|
+
redirectUri: config.auth.redirectUri && resolve(config.auth.redirectUri) };
|
|
224
|
+
if (auth.redirectUri) {
|
|
225
|
+
// The authorization code must only ever come back to the local callback server.
|
|
226
|
+
let redirect;
|
|
227
|
+
try {
|
|
228
|
+
redirect = new URL(auth.redirectUri);
|
|
229
|
+
}
|
|
230
|
+
catch {
|
|
231
|
+
throw new Error('MCP OAuth redirectUri must be a loopback http URL');
|
|
232
|
+
}
|
|
233
|
+
// Hostname localhost is allowed so a CIMD document's redirect_uris can match.
|
|
234
|
+
// The callback server still binds 127.0.0.1 only — a browser that resolves
|
|
235
|
+
// localhost to ::1 will not hit it. Use 127.0.0.1 when the metadata says so.
|
|
236
|
+
if (redirect.protocol !== 'http:' || !['127.0.0.1', 'localhost'].includes(redirect.hostname))
|
|
237
|
+
throw new Error('MCP OAuth redirectUri must be a loopback http URL');
|
|
238
|
+
}
|
|
239
|
+
if (auth.clientMetadataUrl) {
|
|
240
|
+
let meta;
|
|
241
|
+
try {
|
|
242
|
+
meta = new URL(auth.clientMetadataUrl);
|
|
243
|
+
}
|
|
244
|
+
catch {
|
|
245
|
+
throw new Error('MCP OAuth clientMetadataUrl must be an https URL with a document path');
|
|
246
|
+
}
|
|
247
|
+
if (meta.protocol !== 'https:' || meta.pathname === '/')
|
|
248
|
+
throw new Error('MCP OAuth clientMetadataUrl must be an https URL with a document path');
|
|
249
|
+
}
|
|
250
|
+
return { ...resolved, auth };
|
|
249
251
|
}
|
|
252
|
+
return resolved;
|
|
250
253
|
}
|
|
251
|
-
export function createTransport(
|
|
254
|
+
export function createTransport(input) {
|
|
255
|
+
const config = resolveMCPTransport(input);
|
|
256
|
+
if (config.auth?.type === 'oauth' && config.type !== 'streamable_http') {
|
|
257
|
+
throw new Error(`MCP OAuth is only supported on streamable_http (got ${config.type}); refusing to connect without the authProvider.`);
|
|
258
|
+
}
|
|
252
259
|
switch (config.type) {
|
|
253
260
|
case 'stdio':
|
|
254
261
|
return new StdioTransport(config);
|
|
255
262
|
case 'http':
|
|
263
|
+
logger.warn('MCP http /rpc transport is deprecated; use legacy_rpc explicitly or streamable_http for MCP HTTP');
|
|
264
|
+
return new HttpTransport(config);
|
|
265
|
+
case 'legacy_rpc':
|
|
256
266
|
return new HttpTransport(config);
|
|
257
267
|
case 'sse':
|
|
268
|
+
case 'sse_sdk':
|
|
258
269
|
return new SSETransport(config);
|
|
259
270
|
case 'streamable_http':
|
|
260
271
|
return new StreamableHttpTransport(config);
|
package/dist/mcp/types.d.ts
CHANGED
|
@@ -15,6 +15,11 @@ export interface MCPServerConfig {
|
|
|
15
15
|
maxRetries?: number;
|
|
16
16
|
/** Optional: Enable/disable this server (default: true) */
|
|
17
17
|
enabled?: boolean;
|
|
18
|
+
/** Exact names and star globs; exclusions win. Empty include denies every tool. */
|
|
19
|
+
toolFilter?: {
|
|
20
|
+
include?: string[];
|
|
21
|
+
exclude?: string[];
|
|
22
|
+
};
|
|
18
23
|
}
|
|
19
24
|
export type ServerStatus = 'connecting' | 'connected' | 'disconnected' | 'error';
|
|
20
25
|
export interface MCPTool {
|
|
@@ -473,12 +473,6 @@ export declare const comfyUIRecipeSchema: z.ZodObject<{
|
|
|
473
473
|
name?: string | undefined;
|
|
474
474
|
url?: string | undefined;
|
|
475
475
|
};
|
|
476
|
-
schemaVersion: 1;
|
|
477
|
-
fallback: {
|
|
478
|
-
id: string;
|
|
479
|
-
reason?: string | undefined;
|
|
480
|
-
version?: string | undefined;
|
|
481
|
-
}[];
|
|
482
476
|
resources: {
|
|
483
477
|
tier: "high" | "low" | "balanced" | "extreme";
|
|
484
478
|
maxConcurrency: number;
|
|
@@ -486,6 +480,12 @@ export declare const comfyUIRecipeSchema: z.ZodObject<{
|
|
|
486
480
|
minRamMiB: number;
|
|
487
481
|
estimatedSeconds?: number | undefined;
|
|
488
482
|
};
|
|
483
|
+
schemaVersion: 1;
|
|
484
|
+
fallback: {
|
|
485
|
+
id: string;
|
|
486
|
+
reason?: string | undefined;
|
|
487
|
+
version?: string | undefined;
|
|
488
|
+
}[];
|
|
489
489
|
bindings: {
|
|
490
490
|
prompt: {
|
|
491
491
|
input: string;
|
|
@@ -573,7 +573,6 @@ export declare const comfyUIRecipeSchema: z.ZodObject<{
|
|
|
573
573
|
name?: string | undefined;
|
|
574
574
|
url?: string | undefined;
|
|
575
575
|
};
|
|
576
|
-
schemaVersion: 1;
|
|
577
576
|
resources: {
|
|
578
577
|
tier: "high" | "low" | "balanced" | "extreme";
|
|
579
578
|
minVramMiB: number;
|
|
@@ -581,6 +580,7 @@ export declare const comfyUIRecipeSchema: z.ZodObject<{
|
|
|
581
580
|
maxConcurrency?: number | undefined;
|
|
582
581
|
estimatedSeconds?: number | undefined;
|
|
583
582
|
};
|
|
583
|
+
schemaVersion: 1;
|
|
584
584
|
bindings: {
|
|
585
585
|
prompt: {
|
|
586
586
|
input: string;
|
|
@@ -63,8 +63,18 @@ export declare const ReconciliationActionSchema: z.ZodObject<{
|
|
|
63
63
|
} | undefined;
|
|
64
64
|
}>;
|
|
65
65
|
export type ReconciliationAction = z.infer<typeof ReconciliationActionSchema>;
|
|
66
|
+
/** Keep concurrent command sessions on their own provider, including an explicit offline scope. */
|
|
67
|
+
export declare function withFactsMemorySessionClient<T>(client: CodeBuddyClient | null, action: () => T): T;
|
|
68
|
+
/**
|
|
69
|
+
* Async generators execute on next/return/throw, not when they are created.
|
|
70
|
+
* Scope every resumption so model/tool/cleanup work belongs to this agent,
|
|
71
|
+
* while consumers outside a yielded event keep their own async context.
|
|
72
|
+
*/
|
|
73
|
+
export declare function bindFactsMemorySession<T>(client: CodeBuddyClient, iterator: AsyncGenerator<T, void, unknown>): AsyncGenerator<T, void, unknown>;
|
|
74
|
+
export declare function setFactsMemorySessionClient(client: CodeBuddyClient | null): void;
|
|
66
75
|
export declare class FactsMemoryService {
|
|
67
|
-
private
|
|
76
|
+
private readonly explicitClient;
|
|
77
|
+
private fallbackClient;
|
|
68
78
|
constructor(client?: CodeBuddyClient);
|
|
69
79
|
isAvailable(): Promise<boolean>;
|
|
70
80
|
private getClient;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
1
2
|
import { z } from 'zod';
|
|
2
3
|
import { logger } from '../utils/logger.js';
|
|
3
4
|
import { CodeBuddyClient } from '../codebuddy/client.js';
|
|
@@ -30,20 +31,58 @@ export const ReconciliationActionSchema = z.object({
|
|
|
30
31
|
targetIndex: z.number().optional(),
|
|
31
32
|
fact: FactSchema.optional()
|
|
32
33
|
});
|
|
34
|
+
/**
|
|
35
|
+
* Client of the live session (the provider and endpoint the user actually
|
|
36
|
+
* started with). Without it, reconciliation fell back to environment
|
|
37
|
+
* auto-detection and could send project memories to a different, cloud
|
|
38
|
+
* provider than the local session (e.g. xAI because GROK_API_KEY was set while
|
|
39
|
+
* the CLI ran on --base-url http://127.0.0.1:11434/v1).
|
|
40
|
+
*/
|
|
41
|
+
let sessionClient = null;
|
|
42
|
+
const sessionScope = new AsyncLocalStorage();
|
|
43
|
+
/** Keep concurrent command sessions on their own provider, including an explicit offline scope. */
|
|
44
|
+
export function withFactsMemorySessionClient(client, action) {
|
|
45
|
+
return sessionScope.run({ client }, action);
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Async generators execute on next/return/throw, not when they are created.
|
|
49
|
+
* Scope every resumption so model/tool/cleanup work belongs to this agent,
|
|
50
|
+
* while consumers outside a yielded event keep their own async context.
|
|
51
|
+
*/
|
|
52
|
+
export function bindFactsMemorySession(client, iterator) {
|
|
53
|
+
return {
|
|
54
|
+
next(...args) { return withFactsMemorySessionClient(client, () => iterator.next(...args)); },
|
|
55
|
+
return(value) { return withFactsMemorySessionClient(client, () => iterator.return(value)); },
|
|
56
|
+
throw(error) { return withFactsMemorySessionClient(client, () => iterator.throw(error)); },
|
|
57
|
+
[Symbol.asyncIterator]() { return this; },
|
|
58
|
+
async [Symbol.asyncDispose]() {
|
|
59
|
+
await withFactsMemorySessionClient(client, () => iterator.return());
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
export function setFactsMemorySessionClient(client) {
|
|
64
|
+
sessionClient = client;
|
|
65
|
+
}
|
|
33
66
|
export class FactsMemoryService {
|
|
34
|
-
|
|
67
|
+
explicitClient;
|
|
68
|
+
fallbackClient = null;
|
|
35
69
|
constructor(client) {
|
|
36
|
-
|
|
37
|
-
this.client = client;
|
|
38
|
-
}
|
|
70
|
+
this.explicitClient = client ?? null;
|
|
39
71
|
}
|
|
40
72
|
async isAvailable() {
|
|
41
73
|
const client = await this.getClient();
|
|
42
74
|
return client !== null;
|
|
43
75
|
}
|
|
44
76
|
async getClient() {
|
|
45
|
-
if (this.
|
|
46
|
-
return this.
|
|
77
|
+
if (this.explicitClient)
|
|
78
|
+
return this.explicitClient;
|
|
79
|
+
const scoped = sessionScope.getStore();
|
|
80
|
+
if (scoped)
|
|
81
|
+
return scoped.client;
|
|
82
|
+
if (sessionClient)
|
|
83
|
+
return sessionClient;
|
|
84
|
+
if (this.fallbackClient)
|
|
85
|
+
return this.fallbackClient;
|
|
47
86
|
// Skip auto-detecting client in unit tests to prevent timeouts/real API calls
|
|
48
87
|
if (process.env.NODE_ENV === 'test' || process.env.VITEST) {
|
|
49
88
|
return null;
|
|
@@ -53,8 +92,8 @@ export class FactsMemoryService {
|
|
|
53
92
|
logger.warn('[FactsMemory] No LLM provider configuration found.');
|
|
54
93
|
return null;
|
|
55
94
|
}
|
|
56
|
-
this.
|
|
57
|
-
return this.
|
|
95
|
+
this.fallbackClient = new CodeBuddyClient(detected.apiKey, detected.defaultModel, detected.baseURL);
|
|
96
|
+
return this.fallbackClient;
|
|
58
97
|
}
|
|
59
98
|
/**
|
|
60
99
|
* Extract atom facts from a conversation or context block.
|
|
@@ -72,7 +72,7 @@ export interface MemoryCandidateStats {
|
|
|
72
72
|
total: number;
|
|
73
73
|
byStatus: Record<MemoryCandidateStatus, number>;
|
|
74
74
|
}
|
|
75
|
-
export declare function getMemoryCandidateQueue(workDir?: string): MemoryCandidateQueue;
|
|
75
|
+
export declare function getMemoryCandidateQueue(workDir?: string, botId?: string): MemoryCandidateQueue;
|
|
76
76
|
export declare function resetMemoryCandidateQueues(): void;
|
|
77
77
|
export declare class MemoryCandidateQueue {
|
|
78
78
|
private workDir;
|
|
@@ -80,7 +80,7 @@ export declare class MemoryCandidateQueue {
|
|
|
80
80
|
private filePath;
|
|
81
81
|
private candidates;
|
|
82
82
|
private loaded;
|
|
83
|
-
constructor(workDir?: string, memoryManager?: PersistentMemoryManager | undefined);
|
|
83
|
+
constructor(workDir?: string, memoryManager?: PersistentMemoryManager | undefined, botId?: string);
|
|
84
84
|
propose(input: ProposeMemoryCandidateInput): ProposeMemoryCandidateResult;
|
|
85
85
|
list(status?: MemoryCandidateStatus): MemoryCandidate[];
|
|
86
86
|
get(id: string): MemoryCandidate | null;
|
|
@@ -22,10 +22,10 @@ const VALID_CATEGORIES = [
|
|
|
22
22
|
'custom',
|
|
23
23
|
];
|
|
24
24
|
const registry = new Map();
|
|
25
|
-
export function getMemoryCandidateQueue(workDir = process.cwd()) {
|
|
26
|
-
const key = path.resolve(workDir);
|
|
25
|
+
export function getMemoryCandidateQueue(workDir = process.cwd(), botId) {
|
|
26
|
+
const key = JSON.stringify([path.resolve(workDir), botId ?? '']);
|
|
27
27
|
if (!registry.has(key)) {
|
|
28
|
-
registry.set(key, new MemoryCandidateQueue(
|
|
28
|
+
registry.set(key, new MemoryCandidateQueue(path.resolve(workDir), botId ? getMemoryManager(undefined, botId, workDir) : undefined, botId));
|
|
29
29
|
if (registry.size > 20) {
|
|
30
30
|
const firstKey = registry.keys().next().value;
|
|
31
31
|
if (firstKey)
|
|
@@ -43,10 +43,10 @@ export class MemoryCandidateQueue {
|
|
|
43
43
|
filePath;
|
|
44
44
|
candidates = [];
|
|
45
45
|
loaded = false;
|
|
46
|
-
constructor(workDir = process.cwd(), memoryManager) {
|
|
46
|
+
constructor(workDir = process.cwd(), memoryManager, botId) {
|
|
47
47
|
this.workDir = workDir;
|
|
48
48
|
this.memoryManager = memoryManager;
|
|
49
|
-
this.filePath = path.join(workDir, '.codebuddy', 'memory-candidates.json');
|
|
49
|
+
this.filePath = path.join(workDir, '.codebuddy', botId ? `memory-candidates-${encodeURIComponent(botId)}.json` : 'memory-candidates.json');
|
|
50
50
|
}
|
|
51
51
|
propose(input) {
|
|
52
52
|
this.load();
|
|
@@ -122,7 +122,7 @@ export class MemoryCandidateQueue {
|
|
|
122
122
|
throw new Error('Accepted memory key cannot be empty.');
|
|
123
123
|
if (!value)
|
|
124
124
|
throw new Error('Accepted memory value cannot be empty.');
|
|
125
|
-
const manager = this.memoryManager ?? getMemoryManager();
|
|
125
|
+
const manager = this.memoryManager ?? getMemoryManager(undefined, undefined, this.workDir);
|
|
126
126
|
await manager.initialize();
|
|
127
127
|
const write = await manager.remember(key, value, {
|
|
128
128
|
scope,
|
|
@@ -53,6 +53,15 @@ export interface MemoryWriteResult {
|
|
|
53
53
|
category?: MemoryCategory;
|
|
54
54
|
usage: MemoryUsage;
|
|
55
55
|
message: string;
|
|
56
|
+
/**
|
|
57
|
+
* Outcome of the optional LLM fact reconciliation, separate from the primary
|
|
58
|
+
* write: `failed` means the memory was still written directly and existing
|
|
59
|
+
* memories were restored unchanged.
|
|
60
|
+
*/
|
|
61
|
+
reconciliation?: {
|
|
62
|
+
status: 'applied' | 'skipped' | 'failed';
|
|
63
|
+
reason?: string;
|
|
64
|
+
};
|
|
56
65
|
}
|
|
57
66
|
export declare class MemoryWriteRejectedError extends Error {
|
|
58
67
|
readonly code: 'memory_limit_exceeded' | 'memory_security_rejected';
|
|
@@ -164,6 +173,8 @@ export declare class PersistentMemoryManager extends EventEmitter {
|
|
|
164
173
|
* poking the private maps. Does NOT reinforce (unlike getRelevantMemories).
|
|
165
174
|
*/
|
|
166
175
|
listMemories(scope: MemoryScope): Memory[];
|
|
176
|
+
/** Guard the result, including model renames/omissions, rather than trusting DELETE alone. */
|
|
177
|
+
private guardReconciliation;
|
|
167
178
|
/**
|
|
168
179
|
* Ebbinghaus forgetting pass (recoverable): memories whose retention decayed
|
|
169
180
|
* below the threshold are appended to a sibling `*.archive.md`, then removed.
|
|
@@ -250,12 +261,6 @@ export declare class PersistentMemoryManager extends EventEmitter {
|
|
|
250
261
|
};
|
|
251
262
|
private assertScopeReadable;
|
|
252
263
|
}
|
|
253
|
-
|
|
254
|
-
* Get the memory manager. With no `botId`, returns the global singleton (default
|
|
255
|
-
* — CLI / desktop / server behavior unchanged). With a `botId` (multi-bot
|
|
256
|
-
* channels), returns a per-bot instance whose memory files live under
|
|
257
|
-
* `~/.codebuddy/bots/<botId>/`, so bots never share each other's `remember` facts.
|
|
258
|
-
*/
|
|
259
|
-
export declare function getMemoryManager(config?: Partial<MemoryConfig>, botId?: string): PersistentMemoryManager;
|
|
264
|
+
export declare function getMemoryManager(config?: Partial<MemoryConfig>, botId?: string, cwd?: string): PersistentMemoryManager;
|
|
260
265
|
export declare function resetMemoryManagerForTests(): void;
|
|
261
|
-
export declare function initializeMemory(config?: Partial<MemoryConfig
|
|
266
|
+
export declare function initializeMemory(config?: Partial<MemoryConfig>, cwd?: string): Promise<PersistentMemoryManager>;
|