@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
|
@@ -27,17 +27,37 @@ function formatTimeAgo(date, now = new Date()) {
|
|
|
27
27
|
const yr = Math.floor(day / 365);
|
|
28
28
|
return `${yr} year${yr === 1 ? "" : "s"} ago`;
|
|
29
29
|
}
|
|
30
|
+
/**
|
|
31
|
+
* Report a remember operation honestly: the persistent write is the primary
|
|
32
|
+
* result; fact reconciliation and the semantic index are secondary and their
|
|
33
|
+
* failures are shown without hiding (or overstating) the saved memory.
|
|
34
|
+
*/
|
|
35
|
+
async function describeRememberOutcome(write, requestedKey, scope, storeSemantic) {
|
|
36
|
+
const lines = [`ā
Remembered: "${write?.key ?? requestedKey}" in persistent ${scope} memory.`];
|
|
37
|
+
if (write?.reconciliation?.status === "failed") {
|
|
38
|
+
lines.push(`ā ļø Fact reconciliation failed (${write.reconciliation.reason ?? "unknown error"}); the memory was saved directly and existing memories were kept unchanged.`);
|
|
39
|
+
}
|
|
40
|
+
try {
|
|
41
|
+
await storeSemantic();
|
|
42
|
+
lines.push("Semantic index updated.");
|
|
43
|
+
}
|
|
44
|
+
catch (error) {
|
|
45
|
+
lines.push(`ā ļø Semantic index not updated: ${getErrorMessage(error)}`);
|
|
46
|
+
}
|
|
47
|
+
return lines.join("\n");
|
|
48
|
+
}
|
|
30
49
|
function clip(text, max = 180) {
|
|
31
50
|
return text.length > max ? text.slice(0, max - 1) + "ā¦" : text;
|
|
32
51
|
}
|
|
33
52
|
/**
|
|
34
53
|
* Memory - Manage persistent memory using PersistentMemoryManager (Markdown) and EnhancedMemory (SQLite/Vector)
|
|
35
54
|
*/
|
|
36
|
-
export async function handleMemory(args) {
|
|
55
|
+
export async function handleMemory(args, context) {
|
|
37
56
|
const enhancedMemory = getEnhancedMemory();
|
|
38
|
-
const persistentMemory = getMemoryManager();
|
|
57
|
+
const persistentMemory = getMemoryManager(undefined, context?.botId, context?.cwd);
|
|
39
58
|
const action = args[0]?.toLowerCase() || 'list';
|
|
40
59
|
try {
|
|
60
|
+
await persistentMemory.initialize();
|
|
41
61
|
let content;
|
|
42
62
|
switch (action) {
|
|
43
63
|
case "recall":
|
|
@@ -151,14 +171,13 @@ export async function handleMemory(args) {
|
|
|
151
171
|
: "project";
|
|
152
172
|
const value = args.slice(2).join(" ");
|
|
153
173
|
// Store in both for redundancy and better retrieval
|
|
154
|
-
await persistentMemory.remember(key, value, { scope, category: "custom" });
|
|
155
|
-
await enhancedMemory.store({
|
|
174
|
+
const write = await persistentMemory.remember(key, value, { scope, category: "custom" });
|
|
175
|
+
content = await describeRememberOutcome(write, key, scope, () => enhancedMemory.store({
|
|
156
176
|
type: 'fact',
|
|
157
177
|
content: `${key}: ${value}`,
|
|
158
178
|
tags: [key, scope],
|
|
159
179
|
importance: 0.8
|
|
160
|
-
});
|
|
161
|
-
content = `ā
Remembered: "${key}" in persistent ${scope} memory and semantic index.`;
|
|
180
|
+
}));
|
|
162
181
|
}
|
|
163
182
|
else {
|
|
164
183
|
content = `Usage: /memory remember <key> <content> [project|user]`;
|
|
@@ -231,7 +250,7 @@ export async function handleMemory(args) {
|
|
|
231
250
|
: undefined;
|
|
232
251
|
const rawLimit = parseInt(args[status ? 2 : 1] ?? "20", 10);
|
|
233
252
|
const limit = Math.min(50, Math.max(1, Number.isFinite(rawLimit) ? rawLimit : 20));
|
|
234
|
-
const candidates = getMemoryCandidateQueue(process.cwd()).list(status).slice(0, limit);
|
|
253
|
+
const candidates = getMemoryCandidateQueue(context?.cwd ?? process.cwd(), context?.botId).list(status).slice(0, limit);
|
|
235
254
|
if (candidates.length === 0) {
|
|
236
255
|
content = status ? `No ${status} memory candidates.` : "No memory candidates yet.";
|
|
237
256
|
}
|
|
@@ -268,7 +287,7 @@ export async function handleMemory(args) {
|
|
|
268
287
|
}
|
|
269
288
|
const reviewedBy = args.slice(2).join(" ").trim() || "user";
|
|
270
289
|
const { getMemoryCandidateQueue } = await import("../../memory/memory-candidate-queue.js");
|
|
271
|
-
const { candidate, write } = await getMemoryCandidateQueue(process.cwd()).accept(id, { reviewedBy });
|
|
290
|
+
const { candidate, write } = await getMemoryCandidateQueue(context?.cwd ?? process.cwd(), context?.botId).accept(id, { reviewedBy });
|
|
272
291
|
content = `ā
Accepted ${candidate.id} into ${candidate.scope} memory as "${candidate.key}".\n` +
|
|
273
292
|
`Write status: ${write.status}. Capacity: ${write.usage.used}/${write.usage.limit} chars (${write.usage.percent}%).`;
|
|
274
293
|
break;
|
|
@@ -282,7 +301,7 @@ export async function handleMemory(args) {
|
|
|
282
301
|
}
|
|
283
302
|
const reason = args.slice(2).join(" ").trim();
|
|
284
303
|
const { getMemoryCandidateQueue } = await import("../../memory/memory-candidate-queue.js");
|
|
285
|
-
const candidate = getMemoryCandidateQueue(process.cwd()).reject(id, {
|
|
304
|
+
const candidate = getMemoryCandidateQueue(context?.cwd ?? process.cwd(), context?.botId).reject(id, {
|
|
286
305
|
reviewedBy: "user",
|
|
287
306
|
...(reason ? { reason } : {}),
|
|
288
307
|
});
|
|
@@ -319,7 +338,7 @@ export async function handleMemory(args) {
|
|
|
319
338
|
/**
|
|
320
339
|
* Remember - Quick memory store using PersistentMemoryManager and EnhancedMemory
|
|
321
340
|
*/
|
|
322
|
-
export async function handleRemember(args) {
|
|
341
|
+
export async function handleRemember(args, context) {
|
|
323
342
|
if (args.length < 2) {
|
|
324
343
|
return {
|
|
325
344
|
handled: true,
|
|
@@ -346,20 +365,21 @@ export async function handleRemember(args) {
|
|
|
346
365
|
: "project";
|
|
347
366
|
const value = args.slice(1).join(" ");
|
|
348
367
|
try {
|
|
349
|
-
const persistentMemory = getMemoryManager();
|
|
368
|
+
const persistentMemory = getMemoryManager(undefined, context?.botId, context?.cwd);
|
|
350
369
|
const enhancedMemory = getEnhancedMemory();
|
|
351
|
-
await persistentMemory.
|
|
352
|
-
await
|
|
370
|
+
await persistentMemory.initialize();
|
|
371
|
+
const write = await persistentMemory.remember(key, value, { scope, category: "custom" });
|
|
372
|
+
const content = await describeRememberOutcome(write, key, scope, () => enhancedMemory.store({
|
|
353
373
|
type: 'fact',
|
|
354
374
|
content: `${key}: ${value}`,
|
|
355
375
|
tags: [key, scope],
|
|
356
376
|
importance: 0.8
|
|
357
|
-
});
|
|
377
|
+
}));
|
|
358
378
|
return {
|
|
359
379
|
handled: true,
|
|
360
380
|
entry: {
|
|
361
381
|
type: "assistant",
|
|
362
|
-
content
|
|
382
|
+
content,
|
|
363
383
|
timestamp: new Date(),
|
|
364
384
|
},
|
|
365
385
|
};
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* - __RESTORE_CHECKPOINT__ - /restore
|
|
15
15
|
*/
|
|
16
16
|
import type { CommandHandlerResult } from './branch-handlers.js';
|
|
17
|
-
export declare function handleChangeModel(args: string[]): Promise<CommandHandlerResult>;
|
|
17
|
+
export declare function handleChangeModel(args: string[], activeModel?: string): Promise<CommandHandlerResult>;
|
|
18
18
|
export declare function handleChangeMode(args: string[]): Promise<CommandHandlerResult>;
|
|
19
19
|
export declare function handleClearChat(): CommandHandlerResult;
|
|
20
20
|
export declare function handleColab(args: string[]): Promise<CommandHandlerResult>;
|
|
@@ -24,5 +24,5 @@ export declare function handleListCheckpoints(_args: string[]): Promise<CommandH
|
|
|
24
24
|
export declare function handleRestoreCheckpoint(args: string[]): Promise<CommandHandlerResult>;
|
|
25
25
|
export declare function handleInitGrok(args?: string[]): Promise<CommandHandlerResult>;
|
|
26
26
|
export declare function handleReinitGrok(): Promise<CommandHandlerResult>;
|
|
27
|
-
export declare function handleStatus(): Promise<CommandHandlerResult>;
|
|
27
|
+
export declare function handleStatus(activeModel?: string): Promise<CommandHandlerResult>;
|
|
28
28
|
export declare function handleNew(args: string[]): Promise<CommandHandlerResult>;
|
|
@@ -17,14 +17,14 @@ import { handleColabCommand } from './colab-handler.js';
|
|
|
17
17
|
// ============================================================================
|
|
18
18
|
// /model - Change Model
|
|
19
19
|
// ============================================================================
|
|
20
|
-
export async function handleChangeModel(args) {
|
|
20
|
+
export async function handleChangeModel(args, activeModel) {
|
|
21
21
|
const { getSupportedModels, getModelInfo, suggestModel } = await import('../../utils/model-utils.js');
|
|
22
22
|
const { getSettingsManager } = await import('../../utils/settings-manager.js');
|
|
23
23
|
const modelName = args[0];
|
|
24
24
|
const settingsManager = getSettingsManager();
|
|
25
25
|
// If no model specified, show current model and list available models
|
|
26
26
|
if (!modelName || modelName === 'list') {
|
|
27
|
-
const currentModel =
|
|
27
|
+
const currentModel = activeModel ?? settingsManager.getCurrentModel();
|
|
28
28
|
const supportedModels = getSupportedModels();
|
|
29
29
|
// Group models by provider
|
|
30
30
|
const modelsByProvider = {};
|
|
@@ -803,14 +803,22 @@ function formatStatusTimeAgo(date, now = new Date()) {
|
|
|
803
803
|
const day = Math.floor(hr / 24);
|
|
804
804
|
return `${day}d ago`;
|
|
805
805
|
}
|
|
806
|
-
export async function handleStatus() {
|
|
806
|
+
export async function handleStatus(activeModel) {
|
|
807
807
|
const lines = [];
|
|
808
808
|
lines.push('Status Dashboard');
|
|
809
809
|
lines.push('='.repeat(50));
|
|
810
810
|
lines.push('');
|
|
811
811
|
// Current model
|
|
812
|
-
const currentModel =
|
|
812
|
+
const currentModel = activeModel ?? (await import('../../utils/settings-manager.js')).getSettingsManager().getCurrentModel();
|
|
813
813
|
lines.push(` Model: ${currentModel}`);
|
|
814
|
+
try {
|
|
815
|
+
const { getThemeManager } = await import('../../themes/theme-manager.js');
|
|
816
|
+
const theme = getThemeManager().getCurrentTheme();
|
|
817
|
+
lines.push(` Theme: ${theme.name} (${theme.id})`);
|
|
818
|
+
}
|
|
819
|
+
catch (_err) {
|
|
820
|
+
lines.push(' Theme: unknown');
|
|
821
|
+
}
|
|
814
822
|
// Agent mode
|
|
815
823
|
try {
|
|
816
824
|
const { getOperatingModeManager } = await import('../../agent/operating-modes.js');
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* /resources ā read-only view of the explicit resource catalog (P8).
|
|
3
|
+
*
|
|
4
|
+
* Reads ~/.codebuddy/resources/catalog.json through ResourceCatalog.list():
|
|
5
|
+
* no probe, no network, no write, no dispatch. Shows endpoint REFERENCES
|
|
6
|
+
* (environment variable names), never resolved URLs or fingerprints.
|
|
7
|
+
*/
|
|
8
|
+
import type { CommandHandlerResult } from './branch-handlers.js';
|
|
9
|
+
import { ResourceCatalog, type PublicResourceStatus } from '../../fleet/resource-catalog.js';
|
|
10
|
+
export declare const RESOURCES_EMPTY_HINT: string;
|
|
11
|
+
export declare function formatResourcesTable(resources: PublicResourceStatus[], now?: number): string;
|
|
12
|
+
export declare function handleResources(catalog?: ResourceCatalog, now?: () => number): Promise<CommandHandlerResult>;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* /resources ā read-only view of the explicit resource catalog (P8).
|
|
3
|
+
*
|
|
4
|
+
* Reads ~/.codebuddy/resources/catalog.json through ResourceCatalog.list():
|
|
5
|
+
* no probe, no network, no write, no dispatch. Shows endpoint REFERENCES
|
|
6
|
+
* (environment variable names), never resolved URLs or fingerprints.
|
|
7
|
+
*/
|
|
8
|
+
import fs from 'node:fs';
|
|
9
|
+
import { publicResourceStatus, ResourceCatalog } from '../../fleet/resource-catalog.js';
|
|
10
|
+
export const RESOURCES_EMPTY_HINT = 'No resource catalog yet. Declare one with `buddy resources add <file.json>` (fields: `buddy resources schema`), '
|
|
11
|
+
+ 'then refresh its health explicitly with `buddy resources probe <id>`.';
|
|
12
|
+
function textResult(content) {
|
|
13
|
+
return { handled: true, entry: { type: 'assistant', content, timestamp: new Date() } };
|
|
14
|
+
}
|
|
15
|
+
function age(from, now) {
|
|
16
|
+
if (from === null)
|
|
17
|
+
return 'never';
|
|
18
|
+
const minutes = Math.max(0, Math.round((now - from) / 60_000));
|
|
19
|
+
if (minutes < 1)
|
|
20
|
+
return 'just now';
|
|
21
|
+
if (minutes < 120)
|
|
22
|
+
return `${minutes} min ago`;
|
|
23
|
+
return `${Math.round(minutes / 60)} h ago`;
|
|
24
|
+
}
|
|
25
|
+
export function formatResourcesTable(resources, now = Date.now()) {
|
|
26
|
+
const lines = [`Resources (${resources.length}) ā read-only, no probe`, ''];
|
|
27
|
+
for (const entry of resources) {
|
|
28
|
+
const r = entry.resource;
|
|
29
|
+
const use = r.permissions.use ? 'use' : 'no-use';
|
|
30
|
+
const probe = r.permissions.probe ? 'probe' : 'no-probe';
|
|
31
|
+
lines.push(` ${r.id} [${r.kind}] on ${r.hostId}`);
|
|
32
|
+
lines.push(` state: ${entry.state} (${entry.reason}), checked ${age(entry.checkedAt, now)}`);
|
|
33
|
+
lines.push(` capabilities: ${r.declaredCapabilities.join(', ')} Ā· endpoint ref: ${r.endpointRef} Ā· ${use}, ${probe}`);
|
|
34
|
+
}
|
|
35
|
+
lines.push('', 'Health is not proof of usage and load is unknown. Refresh with `buddy resources probe <id>`.');
|
|
36
|
+
return lines.join('\n');
|
|
37
|
+
}
|
|
38
|
+
export async function handleResources(catalog = new ResourceCatalog(), now = Date.now) {
|
|
39
|
+
let resources;
|
|
40
|
+
try {
|
|
41
|
+
resources = (await catalog.list()).map(publicResourceStatus);
|
|
42
|
+
}
|
|
43
|
+
catch (error) {
|
|
44
|
+
const code = error instanceof Error ? error.message : 'INVALID_CATALOG';
|
|
45
|
+
return textResult(`Resource catalog unreadable (${code}). Nothing was changed; inspect ${catalog.filename}.`);
|
|
46
|
+
}
|
|
47
|
+
if (resources.length === 0) {
|
|
48
|
+
return textResult(fs.existsSync(catalog.filename) ? `The resource catalog is empty. ${RESOURCES_EMPTY_HINT.replace(/^No resource catalog yet\. /, '')}` : RESOURCES_EMPTY_HINT);
|
|
49
|
+
}
|
|
50
|
+
return textResult(formatResourcesTable(resources, now()));
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=resources-handler.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Starter Pack Slash Command Handler
|
|
3
3
|
*
|
|
4
|
-
* /starter
|
|
4
|
+
* /starter, /starter list - List all starter packs grouped by language
|
|
5
5
|
* /starter <name> - Activate a specific starter pack (name or alias)
|
|
6
6
|
* /starter search <q> - Search starters by keyword
|
|
7
7
|
*/
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Starter Pack Slash Command Handler
|
|
3
3
|
*
|
|
4
|
-
* /starter
|
|
4
|
+
* /starter, /starter list - List all starter packs grouped by language
|
|
5
5
|
* /starter <name> - Activate a specific starter pack (name or alias)
|
|
6
6
|
* /starter search <q> - Search starters by keyword
|
|
7
7
|
*/
|
|
@@ -25,7 +25,16 @@ const LANGUAGE_FAMILIES = {
|
|
|
25
25
|
function formatStarterList() {
|
|
26
26
|
const starters = getStarterPacks();
|
|
27
27
|
if (starters.length === 0) {
|
|
28
|
-
|
|
28
|
+
// No starter pack ships with the package today: say where packs are found
|
|
29
|
+
// instead of implying a loading failure.
|
|
30
|
+
return [
|
|
31
|
+
'No starter packs are installed.',
|
|
32
|
+
'',
|
|
33
|
+
'Starter packs are SKILL.md skills tagged "starter", discovered in:',
|
|
34
|
+
' .codebuddy/skills/ (this project)',
|
|
35
|
+
' ~/.codebuddy/skills/ (user)',
|
|
36
|
+
' the bundled skills directory shipped with Code Buddy',
|
|
37
|
+
].join('\n');
|
|
29
38
|
}
|
|
30
39
|
const lines = [
|
|
31
40
|
`Starter Packs (${starters.length} available)`,
|
|
@@ -82,6 +91,27 @@ export async function handleStarter(args) {
|
|
|
82
91
|
};
|
|
83
92
|
}
|
|
84
93
|
const action = first.toLowerCase();
|
|
94
|
+
// /starter list ā documented alias of the bare command
|
|
95
|
+
if (action === 'list' && args.length === 1) {
|
|
96
|
+
return {
|
|
97
|
+
handled: true,
|
|
98
|
+
entry: {
|
|
99
|
+
type: 'assistant',
|
|
100
|
+
content: formatStarterList(),
|
|
101
|
+
timestamp: new Date(),
|
|
102
|
+
},
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
if (action === 'search' && args.length === 1) {
|
|
106
|
+
return {
|
|
107
|
+
handled: true,
|
|
108
|
+
entry: {
|
|
109
|
+
type: 'assistant',
|
|
110
|
+
content: 'Usage: /starter search <query>',
|
|
111
|
+
timestamp: new Date(),
|
|
112
|
+
},
|
|
113
|
+
};
|
|
114
|
+
}
|
|
85
115
|
// /starter search <query>
|
|
86
116
|
if (action === 'search' && args.length > 1) {
|
|
87
117
|
const query = args.slice(1).join(' ');
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
import type { CommandHandlerResult } from './branch-handlers.js';
|
|
10
10
|
/**
|
|
11
11
|
* Provider for model routing state.
|
|
12
|
-
* Set
|
|
12
|
+
* Set by the conversation-loop dispatcher from the live agent.
|
|
13
13
|
*/
|
|
14
14
|
export interface SwitchModelProvider {
|
|
15
15
|
/** Get list of available model names */
|
|
@@ -23,6 +23,21 @@ export function setSwitchModelProvider(provider) {
|
|
|
23
23
|
* /switch auto ā Return to auto-routing / default
|
|
24
24
|
*/
|
|
25
25
|
export async function handleSwitch(args) {
|
|
26
|
+
try {
|
|
27
|
+
return await runSwitch(args);
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
return {
|
|
31
|
+
handled: true,
|
|
32
|
+
entry: {
|
|
33
|
+
type: 'assistant',
|
|
34
|
+
content: `Model switch failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
35
|
+
timestamp: new Date(),
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
async function runSwitch(args) {
|
|
26
41
|
const modelName = args[0]?.trim();
|
|
27
42
|
// No provider set ā try to get models from config
|
|
28
43
|
if (!providerRef) {
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { CodeBuddyClient } from "../../codebuddy/client.js";
|
|
2
2
|
import { AITestRunner, createAITestRunner } from "../../testing/ai-integration-tests.js";
|
|
3
|
-
import stringWidth from "string-width";
|
|
4
3
|
/**
|
|
5
4
|
* Generate Tests - Create test scaffolds
|
|
6
5
|
*/
|
|
@@ -47,7 +46,7 @@ export async function handleAITest(args, codebuddyClient) {
|
|
|
47
46
|
const option = args[0]?.toLowerCase();
|
|
48
47
|
// Check for API key
|
|
49
48
|
const apiKey = process.env.GROK_API_KEY;
|
|
50
|
-
if (!apiKey) {
|
|
49
|
+
if (!codebuddyClient && !apiKey) {
|
|
51
50
|
return {
|
|
52
51
|
handled: true,
|
|
53
52
|
entry: {
|
|
@@ -66,9 +65,8 @@ Set your API key to run integration tests.`,
|
|
|
66
65
|
// Fallback: create client from environment variables
|
|
67
66
|
const model = process.env.GROK_MODEL || process.env.OPENAI_MODEL;
|
|
68
67
|
const baseURL = process.env.GROK_BASE_URL || process.env.OPENAI_BASE_URL;
|
|
69
|
-
client = new CodeBuddyClient(apiKey, model, baseURL);
|
|
68
|
+
client = new CodeBuddyClient(apiKey ?? '', model, baseURL);
|
|
70
69
|
}
|
|
71
|
-
const currentModel = client.getCurrentModel();
|
|
72
70
|
const currentBaseURL = client.getBaseURL();
|
|
73
71
|
// Detect local models (LM Studio, Ollama) and increase timeout
|
|
74
72
|
const isLocalModel = currentBaseURL.includes(':1234') ||
|
|
@@ -86,87 +84,11 @@ Set your API key to run integration tests.`,
|
|
|
86
84
|
testTools: option !== 'stream',
|
|
87
85
|
testStreaming: option !== 'tools',
|
|
88
86
|
};
|
|
89
|
-
//
|
|
90
|
-
|
|
91
|
-
'Basic Completion': 'š§ ',
|
|
92
|
-
'Simple Math': 'š¢',
|
|
93
|
-
'JSON Output': 'š',
|
|
94
|
-
'Code Generation': 'š»',
|
|
95
|
-
'Context Understanding': 'š§©',
|
|
96
|
-
'Streaming Response': 'š',
|
|
97
|
-
'Tool Calling': 'š§',
|
|
98
|
-
'Error Handling': 'š”ļø',
|
|
99
|
-
'Long Context': 'š',
|
|
100
|
-
};
|
|
101
|
-
const spinnerFrames = ['ā ', 'ā ', 'ā ¹', 'ā ø', 'ā ¼', 'ā “', 'ā ¦', 'ā §', 'ā ', 'ā '];
|
|
102
|
-
let spinnerIndex = 0;
|
|
103
|
-
let currentTest = '';
|
|
104
|
-
const completedTests = [];
|
|
105
|
-
let spinnerInterval = null;
|
|
106
|
-
// Create client and run tests
|
|
87
|
+
// Ink owns the terminal. Render the final report through the conversation
|
|
88
|
+
// instead of writing cursor-control sequences over the active UI.
|
|
107
89
|
try {
|
|
108
90
|
const runner = createAITestRunner(client, testOptions);
|
|
109
|
-
// Helper to pad string to width accounting for emoji visual width
|
|
110
|
-
const padEnd = (str, targetWidth) => {
|
|
111
|
-
const currentWidth = stringWidth(str);
|
|
112
|
-
if (currentWidth >= targetWidth)
|
|
113
|
-
return str;
|
|
114
|
-
return str + ' '.repeat(targetWidth - currentWidth);
|
|
115
|
-
};
|
|
116
|
-
const W = 60; // box width
|
|
117
|
-
// Build progress display with proper emoji width handling
|
|
118
|
-
const buildProgressDisplay = () => {
|
|
119
|
-
const lines = [];
|
|
120
|
-
lines.push('ā' + 'ā'.repeat(W - 2) + 'ā');
|
|
121
|
-
lines.push('ā' + padEnd(' š§Ŗ AI INTEGRATION TESTS IN PROGRESS', W - 2) + 'ā');
|
|
122
|
-
lines.push('ā' + 'ā'.repeat(W - 2) + 'ā¤');
|
|
123
|
-
lines.push('ā' + padEnd(` Model: ${currentModel}`, W - 2) + 'ā');
|
|
124
|
-
lines.push('ā' + 'ā'.repeat(W - 2) + 'ā¤');
|
|
125
|
-
// Show completed tests
|
|
126
|
-
for (const test of completedTests) {
|
|
127
|
-
lines.push('ā' + padEnd(` ${test}`, W - 2) + 'ā');
|
|
128
|
-
}
|
|
129
|
-
// Show current test with spinner
|
|
130
|
-
if (currentTest) {
|
|
131
|
-
const emoji = testEmojis[currentTest] || 'š¬';
|
|
132
|
-
const spinner = spinnerFrames[spinnerIndex % spinnerFrames.length];
|
|
133
|
-
lines.push('ā' + padEnd(` ${spinner} ${emoji} ${currentTest}...`, W - 2) + 'ā');
|
|
134
|
-
}
|
|
135
|
-
lines.push('ā' + 'ā'.repeat(W - 2) + 'ā');
|
|
136
|
-
return lines.join('\n');
|
|
137
|
-
};
|
|
138
|
-
// Track progress
|
|
139
|
-
runner.on('test:start', ({ name }) => {
|
|
140
|
-
currentTest = name;
|
|
141
|
-
});
|
|
142
|
-
runner.on('test:complete', (result) => {
|
|
143
|
-
const emoji = testEmojis[result.name] || 'š¬';
|
|
144
|
-
const status = result.passed ? 'ā
' : 'ā';
|
|
145
|
-
const duration = result.duration ? `${(result.duration / 1000).toFixed(1)}s` : '';
|
|
146
|
-
completedTests.push(`${status} ${emoji} ${result.name} ${duration}`);
|
|
147
|
-
currentTest = '';
|
|
148
|
-
});
|
|
149
|
-
runner.on('test:skipped', ({ name }) => {
|
|
150
|
-
const emoji = testEmojis[name] || 'š¬';
|
|
151
|
-
completedTests.push(`āļø ${emoji} ${name} (skipped)`);
|
|
152
|
-
});
|
|
153
|
-
// Start spinner animation (write to stderr to not interfere with output)
|
|
154
|
-
spinnerInterval = setInterval(() => {
|
|
155
|
-
spinnerIndex++;
|
|
156
|
-
// Clear and redraw progress (using ANSI escape codes)
|
|
157
|
-
const progress = buildProgressDisplay();
|
|
158
|
-
process.stderr.write(`\x1b[${completedTests.length + 7}A\x1b[0J${progress}\n`);
|
|
159
|
-
}, 100);
|
|
160
|
-
// Show initial progress
|
|
161
|
-
process.stderr.write('\n' + buildProgressDisplay() + '\n');
|
|
162
91
|
const suite = await runner.runAll();
|
|
163
|
-
// Stop spinner
|
|
164
|
-
if (spinnerInterval) {
|
|
165
|
-
clearInterval(spinnerInterval);
|
|
166
|
-
}
|
|
167
|
-
// Clear progress display
|
|
168
|
-
const clearLines = completedTests.length + 8;
|
|
169
|
-
process.stderr.write(`\x1b[${clearLines}A\x1b[0J`);
|
|
170
92
|
// Format final results
|
|
171
93
|
const resultContent = AITestRunner.formatResults(suite);
|
|
172
94
|
return {
|
|
@@ -179,10 +101,6 @@ Set your API key to run integration tests.`,
|
|
|
179
101
|
};
|
|
180
102
|
}
|
|
181
103
|
catch (error) {
|
|
182
|
-
// Stop spinner on error
|
|
183
|
-
if (spinnerInterval) {
|
|
184
|
-
clearInterval(spinnerInterval);
|
|
185
|
-
}
|
|
186
104
|
return {
|
|
187
105
|
handled: true,
|
|
188
106
|
entry: {
|
|
@@ -4,17 +4,17 @@ import { getThemeManager } from "../../themes/theme-manager.js";
|
|
|
4
4
|
*/
|
|
5
5
|
export function handleTheme(args) {
|
|
6
6
|
const themeManager = getThemeManager();
|
|
7
|
-
const action = args[0]?.toLowerCase();
|
|
7
|
+
const action = (args[0]?.toLowerCase() === "set" ? args[1] : args[0])?.toLowerCase();
|
|
8
8
|
let content;
|
|
9
|
-
if (!action || action === "list") {
|
|
9
|
+
if (!action || action === "list" || action === "status" || action === "current") {
|
|
10
10
|
const themes = themeManager.getAvailableThemes();
|
|
11
11
|
const currentTheme = themeManager.getCurrentTheme();
|
|
12
|
-
content = `šØ
|
|
12
|
+
content = `šØ Current theme: ${currentTheme.name} (${currentTheme.id})\nAvailable Themes\n${"ā".repeat(40)}\n\n`;
|
|
13
13
|
for (const theme of themes) {
|
|
14
14
|
const isCurrent = theme.id === currentTheme.id;
|
|
15
15
|
const marker = isCurrent ? "ā¶" : " ";
|
|
16
16
|
const builtinMarker = theme.isBuiltin ? "" : " (custom)";
|
|
17
|
-
content += `${marker} ${theme.name}${builtinMarker}\n`;
|
|
17
|
+
content += `${marker} ${theme.name} (${theme.id})${builtinMarker}\n`;
|
|
18
18
|
content += ` ${theme.description}\n\n`;
|
|
19
19
|
}
|
|
20
20
|
content += `\nš” Usage: /theme <name>\n`;
|
|
@@ -28,7 +28,13 @@ export function handleTheme(args) {
|
|
|
28
28
|
content = `šØ Theme Changed!\n\n`;
|
|
29
29
|
content += `Now using: ${theme.name}\n`;
|
|
30
30
|
content += `${theme.description}\n\n`;
|
|
31
|
-
content +=
|
|
31
|
+
content += `The theme is active immediately.`;
|
|
32
|
+
if (themeManager.getPreferenceSaveStatus() === false) {
|
|
33
|
+
content += `\nCould not save the preference; this change may be lost after restarting Buddy.`;
|
|
34
|
+
}
|
|
35
|
+
if (themeManager.getOverrideKeys().colors.length > 0) {
|
|
36
|
+
content += `\nCustom color overrides are still applied.`;
|
|
37
|
+
}
|
|
32
38
|
}
|
|
33
39
|
else {
|
|
34
40
|
const themes = themeManager.getAvailableThemes();
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type ChatGptAuth } from '../providers/codex-oauth.js';
|
|
2
|
+
interface LoginOutput {
|
|
3
|
+
stdout: (message: string) => unknown;
|
|
4
|
+
warn: (message: string) => unknown;
|
|
5
|
+
}
|
|
6
|
+
/** Keep the callback alive so a failed browser launch can be completed manually. */
|
|
7
|
+
export declare function loginChatGptWithBrowser(output: LoginOutput): Promise<ChatGptAuth>;
|
|
8
|
+
export {};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import open from 'open';
|
|
2
|
+
import { loginInteractive } from '../providers/codex-oauth.js';
|
|
3
|
+
/** Keep the callback alive so a failed browser launch can be completed manually. */
|
|
4
|
+
export function loginChatGptWithBrowser(output) {
|
|
5
|
+
return loginInteractive(async (url) => {
|
|
6
|
+
output.stdout('If the browser does not open, copy this entire URL into your browser:');
|
|
7
|
+
output.stdout(url);
|
|
8
|
+
output.stdout('Keep this terminal open until sign-in completes.\n');
|
|
9
|
+
try {
|
|
10
|
+
await open(url);
|
|
11
|
+
}
|
|
12
|
+
catch {
|
|
13
|
+
output.warn('Could not open the browser automatically. Open the URL above manually; login is still waiting.');
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=login-chatgpt.js.map
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Command } from 'commander';
|
|
2
|
+
export declare function importMCPFile(filename: string, source: 'hermes' | 'openclaw', options?: {
|
|
3
|
+
dryRun?: boolean;
|
|
4
|
+
output?: string;
|
|
5
|
+
}): {
|
|
6
|
+
written: boolean;
|
|
7
|
+
servers: import("../mcp/types.js").MCPServerConfig[];
|
|
8
|
+
warnings: string[];
|
|
9
|
+
rejected: string[];
|
|
10
|
+
};
|
|
11
|
+
export declare function registerMCPImportCommand(command: Command): void;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { parse } from 'yaml';
|
|
4
|
+
import { normalizeMCPImports } from '../mcp/import-normalize.js';
|
|
5
|
+
import { writeJsonAtomicSync } from '../utils/atomic-write.js';
|
|
6
|
+
const object = (value) => !!value && typeof value === 'object' && !Array.isArray(value);
|
|
7
|
+
export function importMCPFile(filename, source, options = {}) {
|
|
8
|
+
const stat = fs.statSync(filename);
|
|
9
|
+
if (!stat.isFile() || stat.size > 1024 * 1024)
|
|
10
|
+
throw new Error('MCP import file must be at most 1 MiB');
|
|
11
|
+
let input;
|
|
12
|
+
try {
|
|
13
|
+
input = parse(fs.readFileSync(filename, 'utf8'), { uniqueKeys: true });
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
throw new Error('Invalid MCP import JSON/YAML');
|
|
17
|
+
}
|
|
18
|
+
if (!object(input))
|
|
19
|
+
throw new Error('MCP import requires an object');
|
|
20
|
+
const map = input.mcpServers ?? input.mcp_servers ?? (object(input.mcp) ? input.mcp.servers : undefined) ?? input;
|
|
21
|
+
const normalized = normalizeMCPImports(map, source);
|
|
22
|
+
if (options.dryRun || normalized.servers.length === 0)
|
|
23
|
+
return { ...normalized, written: false };
|
|
24
|
+
const output = options.output ?? path.join(process.cwd(), '.codebuddy', 'mcp.json');
|
|
25
|
+
let existing = {};
|
|
26
|
+
if (fs.existsSync(output)) {
|
|
27
|
+
const target = fs.lstatSync(output);
|
|
28
|
+
if (!target.isFile() || target.isSymbolicLink() || target.size > 1024 * 1024)
|
|
29
|
+
throw new Error('Invalid existing MCP target');
|
|
30
|
+
try {
|
|
31
|
+
const parsed = JSON.parse(fs.readFileSync(output, 'utf8'));
|
|
32
|
+
if (!object(parsed) || (parsed.mcpServers !== undefined && !object(parsed.mcpServers)))
|
|
33
|
+
throw new Error();
|
|
34
|
+
existing = parsed;
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
throw new Error('Existing MCP configuration is invalid; not replaced');
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
const servers = object(existing.mcpServers) ? existing.mcpServers : {};
|
|
41
|
+
for (const server of normalized.servers) {
|
|
42
|
+
if (Object.hasOwn(servers, server.name))
|
|
43
|
+
normalized.warnings.push(`${server.name}: existing configuration preserved`);
|
|
44
|
+
else
|
|
45
|
+
servers[server.name] = server;
|
|
46
|
+
}
|
|
47
|
+
fs.mkdirSync(path.dirname(output), { recursive: true, mode: 0o700 });
|
|
48
|
+
writeJsonAtomicSync(output, { ...existing, mcpServers: servers }, { mode: 0o600 });
|
|
49
|
+
return { ...normalized, written: true };
|
|
50
|
+
}
|
|
51
|
+
export function registerMCPImportCommand(command) {
|
|
52
|
+
command.command('import <file>').requiredOption('--from <source>', 'hermes or openclaw')
|
|
53
|
+
.option('--dry-run', 'Show sanitized mapping without writing or connecting')
|
|
54
|
+
.option('--output <file>', 'Target MCP JSON file (default project .codebuddy/mcp.json)')
|
|
55
|
+
.description('Import MCP declarations; credentials become environment references and existing entries are preserved')
|
|
56
|
+
.action((file, options) => {
|
|
57
|
+
if (options.from !== 'hermes' && options.from !== 'openclaw')
|
|
58
|
+
command.error('Source must be hermes or openclaw');
|
|
59
|
+
try {
|
|
60
|
+
process.stdout.write(JSON.stringify(importMCPFile(file, options.from, options), null, 2) + '\n');
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
command.error('MCP import failed; check input/target configuration. No credentials are printed.');
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=mcp-import.js.map
|