@phuetz/code-buddy 2.0.0 → 2.1.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 +73 -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 +165 -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.js +19 -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 +1 -0
- package/dist/codebuddy/fleet-tool-defs.js +24 -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.js +1 -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 +4 -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.js +4 -0
- 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 +4 -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 +179 -0
- package/dist/doctor/integrations.js +227 -0
- package/dist/doctor/triage.d.ts +108 -0
- package/dist/doctor/triage.js +304 -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.js +6 -0
- 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/transports.d.ts +10 -5
- package/dist/mcp/transports.js +61 -99
- 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 +13 -5
- package/dist/services/runtime-settings-context.d.ts +73 -0
- package/dist/services/runtime-settings-context.js +69 -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 +21 -28
- 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 +9 -0
- package/dist/tools/registry/fleet-tools.js +22 -1
- 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/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/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
|
@@ -8,7 +8,8 @@ import { buildDispatchToolFilter, getDispatchToolPolicy, normalizeDispatchProfil
|
|
|
8
8
|
import { getBuiltinToolNames } from '../../codebuddy/tools.js';
|
|
9
9
|
import { buildBrowserOperatorSessionDraft, buildInternetScoutPlan, renderBrowserOperatorSessionDraft, renderInternetScoutPlan, } from '../../browser-automation/index.js';
|
|
10
10
|
import { installResearchScriptSkillCandidate, listMaterializedResearchScriptSkillCandidates, readMaterializedResearchScriptSkillCandidate, } from '../../agent/research-script-skill-candidate.js';
|
|
11
|
-
import { getActiveToolMetadata
|
|
11
|
+
import { getActiveToolMetadata } from '../../tools/metadata.js';
|
|
12
|
+
import { resolveToolEffect } from '../../tools/tool-effect.js';
|
|
12
13
|
function formatList(values) {
|
|
13
14
|
return values.length > 0 ? values.join(', ') : 'none';
|
|
14
15
|
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* buddy triage — write a local, redacted support bundle (src/doctor/triage.ts).
|
|
3
|
+
*
|
|
4
|
+
* Never sends anything and never launches an agent: the command to hand the
|
|
5
|
+
* prompt to a local agent is printed for the user to review and run.
|
|
6
|
+
*/
|
|
7
|
+
import type { Command } from 'commander';
|
|
8
|
+
export declare function registerTriageCommand(program: Command): void;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* buddy triage — write a local, redacted support bundle (src/doctor/triage.ts).
|
|
3
|
+
*
|
|
4
|
+
* Never sends anything and never launches an agent: the command to hand the
|
|
5
|
+
* prompt to a local agent is printed for the user to review and run.
|
|
6
|
+
*/
|
|
7
|
+
import { readFileSync } from 'node:fs';
|
|
8
|
+
import { dirname, join, resolve } from 'node:path';
|
|
9
|
+
import { fileURLToPath } from 'node:url';
|
|
10
|
+
function buddyVersion() {
|
|
11
|
+
try {
|
|
12
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
13
|
+
for (const candidate of [join(here, '..', '..', '..', 'package.json'), join(here, '..', '..', 'package.json')]) {
|
|
14
|
+
try {
|
|
15
|
+
const pkg = JSON.parse(readFileSync(candidate, 'utf8'));
|
|
16
|
+
if (pkg.version && pkg.name?.includes('buddy'))
|
|
17
|
+
return pkg.version;
|
|
18
|
+
}
|
|
19
|
+
catch { /* try next */ }
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
catch { /* fall through */ }
|
|
23
|
+
return 'unknown';
|
|
24
|
+
}
|
|
25
|
+
export function registerTriageCommand(program) {
|
|
26
|
+
program
|
|
27
|
+
.command('triage')
|
|
28
|
+
.description('Write a local redacted support bundle and a ≤ 8 KiB prompt (no network, launches nothing)')
|
|
29
|
+
.option('--json', 'Print a JSON summary on stdout')
|
|
30
|
+
.option('--out <dir>', 'Parent directory for the bundle (default ~/.codebuddy/triage)')
|
|
31
|
+
.option('--log-lines <n>', 'Maximum log lines to include', '200')
|
|
32
|
+
.action(async (options) => {
|
|
33
|
+
const { writeTriageBundle } = await import('../../doctor/triage.js');
|
|
34
|
+
const directory = program.opts().directory;
|
|
35
|
+
const cwd = resolve(process.cwd(), directory || process.cwd());
|
|
36
|
+
const logLines = Math.max(0, Math.min(2000, Number.parseInt(options.logLines ?? '200', 10) || 0));
|
|
37
|
+
try {
|
|
38
|
+
const result = await writeTriageBundle({
|
|
39
|
+
cwd,
|
|
40
|
+
...(options.out ? { outParent: resolve(process.cwd(), options.out) } : {}),
|
|
41
|
+
logLines,
|
|
42
|
+
buddyVersion: buddyVersion(),
|
|
43
|
+
});
|
|
44
|
+
if (options.json) {
|
|
45
|
+
console.log(JSON.stringify({
|
|
46
|
+
dir: result.dir,
|
|
47
|
+
files: { json: result.jsonPath, prompt: result.promptPath },
|
|
48
|
+
promptBytes: result.promptBytes,
|
|
49
|
+
redactions: result.redactions,
|
|
50
|
+
withheld: result.withheld,
|
|
51
|
+
networkUsed: false,
|
|
52
|
+
agentLaunched: false,
|
|
53
|
+
suggestedCommand: result.suggestedCommand,
|
|
54
|
+
}, null, 2));
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
console.log('\nCode Buddy triage (local only — nothing was sent, no agent was started)\n');
|
|
58
|
+
console.log(` Bundle : ${result.dir}`);
|
|
59
|
+
console.log(` Prompt : ${result.promptPath} (${result.promptBytes} bytes)`);
|
|
60
|
+
console.log(` Redactions : ${result.redactions}`);
|
|
61
|
+
if (result.withheld.length > 0)
|
|
62
|
+
console.log(` Withheld : ${result.withheld.join(', ')} (secret scan still matched)`);
|
|
63
|
+
console.log('\nReview prompt.md, then hand it to a local agent yourself:');
|
|
64
|
+
console.log(` ${result.suggestedCommand}\n`);
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
console.error(`triage failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
68
|
+
process.exitCode = 1;
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=triage-command.js.map
|
|
@@ -19,9 +19,31 @@ export function registerUtilityCommands(program) {
|
|
|
19
19
|
.description('Diagnose Code Buddy environment, dependencies, and configuration')
|
|
20
20
|
.option('-v, --verbose', 'Show all checks including passing ones')
|
|
21
21
|
.option('--fix', 'Auto-fix issues that can be resolved automatically')
|
|
22
|
+
.option('--json', 'Print a stable JSON report (includes the Integrations section)')
|
|
23
|
+
.option('--offline', 'Skip every network call (live key checks, OAuth refresh, local runtime probes)')
|
|
24
|
+
.option('--integrations', 'Also check LM Resizer, Code Explorer, MCP config, resource catalog and skills (no network)')
|
|
22
25
|
.action(async (options) => {
|
|
23
26
|
const { runDoctorChecks, runFixes, summarizeDoctorChecks } = await import('../../doctor/index.js');
|
|
24
|
-
const
|
|
27
|
+
const cwd = resolveCommandDirectory(program);
|
|
28
|
+
const offline = options.offline === true;
|
|
29
|
+
const coreChecks = await runDoctorChecks(cwd, { offline });
|
|
30
|
+
const withIntegrations = options.json === true || options.integrations === true;
|
|
31
|
+
const integrationChecks = withIntegrations
|
|
32
|
+
? await (await import('../../doctor/integrations.js')).runIntegrationChecks(cwd)
|
|
33
|
+
: [];
|
|
34
|
+
const checks = [...coreChecks, ...integrationChecks];
|
|
35
|
+
if (options.json) {
|
|
36
|
+
const { buildDoctorJsonReport } = await import('../../doctor/integrations.js');
|
|
37
|
+
const fixes = options.fix ? await runFixes(checks.filter((c) => c.fixable)) : undefined;
|
|
38
|
+
const summary = summarizeDoctorChecks(checks);
|
|
39
|
+
const report = buildDoctorJsonReport(checks, summary, { offline, ...(fixes ? { fixes } : {}) });
|
|
40
|
+
console.log(JSON.stringify(report, null, 2));
|
|
41
|
+
const readinessJson = checks.find((c) => c.name === 'AI provider ready');
|
|
42
|
+
if (summary.errors > 0 || (readinessJson && readinessJson.status !== 'ok') || fixes?.some((f) => !f.success)) {
|
|
43
|
+
process.exitCode = 1;
|
|
44
|
+
}
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
25
47
|
console.log('\n🔍 Code Buddy Doctor\n');
|
|
26
48
|
const icons = { ok: '✅', warn: '⚠️', error: '❌' };
|
|
27
49
|
// Headline verdict: the first question a newcomer has is "can I chat yet?"
|
|
@@ -39,6 +61,8 @@ export function registerUtilityCommands(program) {
|
|
|
39
61
|
for (const check of checks) {
|
|
40
62
|
if (check.name === 'AI provider ready')
|
|
41
63
|
continue; // already shown as the headline
|
|
64
|
+
if (integrationChecks.length > 0 && check === integrationChecks[0])
|
|
65
|
+
console.log('\n Integrations (no network):');
|
|
42
66
|
if (options.verbose || check.status !== 'ok') {
|
|
43
67
|
const fixTag = check.fixable ? ' [fixable]' : '';
|
|
44
68
|
console.log(` ${icons[check.status]} ${check.name}: ${check.message}${fixTag}`);
|
|
@@ -37,6 +37,13 @@ export declare class ClientCommandDispatcher {
|
|
|
37
37
|
* result handling (add entry to chat, pass prompt to AI, clear input).
|
|
38
38
|
*/
|
|
39
39
|
private static delegateToEnhanced;
|
|
40
|
+
/** Session-only /switch overrides, keyed by the live agent. */
|
|
41
|
+
private static readonly switchState;
|
|
42
|
+
/**
|
|
43
|
+
* Back /switch with the running agent so it changes the model used by the
|
|
44
|
+
* next turns (session only, unlike /model which also saves the preference).
|
|
45
|
+
*/
|
|
46
|
+
private static createSwitchModelProvider;
|
|
40
47
|
private static handleEnhancedCommand;
|
|
41
48
|
private static handleModelSwitch;
|
|
42
49
|
private static handleShellBypass;
|
|
@@ -3,7 +3,9 @@ import { getEnhancedCommandHandler } from "./enhanced-command-handler.js";
|
|
|
3
3
|
import { GitWorkflowHandler } from "./workflow/git-workflow.js";
|
|
4
4
|
import { getErrorMessage } from "../types/index.js";
|
|
5
5
|
import { ConfirmationService } from "../utils/confirmation-service.js";
|
|
6
|
+
import { isModelCompatibleWithProvider } from "../providers/model-provider-compat.js";
|
|
6
7
|
import { updateCurrentModel } from "../utils/model-config.js";
|
|
8
|
+
import { setSwitchModelProvider } from "./handlers/switch-handler.js";
|
|
7
9
|
export class ClientCommandDispatcher {
|
|
8
10
|
/**
|
|
9
11
|
* Dispatches a command input to the appropriate handler.
|
|
@@ -48,6 +50,8 @@ export class ClientCommandDispatcher {
|
|
|
48
50
|
context.clearInput();
|
|
49
51
|
}
|
|
50
52
|
static async handleSlashCommand(input, context) {
|
|
53
|
+
// Keep the historical plural spelling on the same live-agent path.
|
|
54
|
+
input = input.replace(/^\/models(?=\s|$)/, '/model');
|
|
51
55
|
const slashManager = getSlashCommandManager();
|
|
52
56
|
const result = slashManager.execute(input);
|
|
53
57
|
if (result.success && result.prompt) {
|
|
@@ -108,18 +112,22 @@ export class ClientCommandDispatcher {
|
|
|
108
112
|
const args = originalInput.trim().split(/\s+/).slice(1);
|
|
109
113
|
if (args.length === 0) {
|
|
110
114
|
context.setShowModelSelection(true);
|
|
111
|
-
context.setSelectedModelIndex(0);
|
|
115
|
+
context.setSelectedModelIndex(Math.max(0, context.availableModels.findIndex(option => option.model === context.agent.getCurrentModel())));
|
|
112
116
|
context.clearInput();
|
|
113
117
|
return true;
|
|
114
118
|
}
|
|
115
|
-
|
|
116
|
-
|
|
119
|
+
if (args[0] === 'auto' || args[0] === 'list') {
|
|
120
|
+
return await this.delegateToEnhanced(token, originalInput, context);
|
|
121
|
+
}
|
|
122
|
+
await this.handleModelSwitch(originalInput, context);
|
|
123
|
+
return true;
|
|
117
124
|
}
|
|
118
125
|
// __CLEAR_CHAT__ needs UI state resets beyond what the handler provides
|
|
119
126
|
if (token === "__CLEAR_CHAT__") {
|
|
120
127
|
const handled = await this.delegateToEnhanced(token, originalInput, context);
|
|
121
128
|
if (handled) {
|
|
122
129
|
// Apply UI-specific side effects
|
|
130
|
+
context.agent.clearChat();
|
|
123
131
|
context.setChatHistory([]);
|
|
124
132
|
context.setIsProcessing(false);
|
|
125
133
|
context.setIsStreaming(false);
|
|
@@ -149,11 +157,13 @@ export class ClientCommandDispatcher {
|
|
|
149
157
|
getContextStats: () => context.agent.getContextStats(),
|
|
150
158
|
formatContextStats: () => context.agent.formatContextStats(),
|
|
151
159
|
getCurrentModel: () => context.agent.getCurrentModel(),
|
|
160
|
+
getMemoryScope: () => context.agent.getMemoryScope(),
|
|
152
161
|
getCurrentSessionId: () => context.agent.getCurrentSessionId?.() ?? null,
|
|
153
162
|
getContextMemoryMetrics: () => context.agent.getContextMemoryMetrics(),
|
|
154
163
|
getCompressionStats: () => context.agent.getCompressionStats(),
|
|
155
164
|
getContextBudgetBreakdown: () => context.agent.getContextBudgetBreakdown(),
|
|
156
165
|
});
|
|
166
|
+
setSwitchModelProvider(this.createSwitchModelProvider(context));
|
|
157
167
|
const args = overrideArgs ?? originalInput.trim().split(" ").slice(1);
|
|
158
168
|
const handlerResult = await enhancedHandler.handleCommand(token, args, originalInput);
|
|
159
169
|
if (handlerResult.handled) {
|
|
@@ -173,30 +183,72 @@ export class ClientCommandDispatcher {
|
|
|
173
183
|
this.finishCommandWithMessage(context, `Command ${commandName} is registered but has no conversation-loop handler yet. Use /help to see working commands.`);
|
|
174
184
|
return true;
|
|
175
185
|
}
|
|
186
|
+
/** Session-only /switch overrides, keyed by the live agent. */
|
|
187
|
+
static switchState = new WeakMap();
|
|
188
|
+
/**
|
|
189
|
+
* Back /switch with the running agent so it changes the model used by the
|
|
190
|
+
* next turns (session only, unlike /model which also saves the preference).
|
|
191
|
+
*/
|
|
192
|
+
static createSwitchModelProvider(context) {
|
|
193
|
+
const agent = context.agent;
|
|
194
|
+
const state = () => {
|
|
195
|
+
let current = this.switchState.get(agent);
|
|
196
|
+
if (!current) {
|
|
197
|
+
current = { baseModel: agent.getCurrentModel(), switched: null };
|
|
198
|
+
this.switchState.set(agent, current);
|
|
199
|
+
}
|
|
200
|
+
return current;
|
|
201
|
+
};
|
|
202
|
+
return {
|
|
203
|
+
getAvailableModels: () => context.availableModels.map(option => option.model),
|
|
204
|
+
getCurrentModel: () => agent.getCurrentModel(),
|
|
205
|
+
getSwitchedModel: () => this.switchState.get(agent)?.switched ?? null,
|
|
206
|
+
setSwitchedModel: (model) => {
|
|
207
|
+
const current = state();
|
|
208
|
+
if (model === null) {
|
|
209
|
+
if (current.switched !== null)
|
|
210
|
+
agent.setModel(current.baseModel);
|
|
211
|
+
this.switchState.delete(agent);
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
const provider = agent.getClient().getCurrentProvider?.();
|
|
215
|
+
if (!isModelCompatibleWithProvider(model, provider)) {
|
|
216
|
+
throw new Error(`Model ${model} is incompatible with the active provider ${provider}. Choose a model for this connection.`);
|
|
217
|
+
}
|
|
218
|
+
agent.setModel(model);
|
|
219
|
+
current.switched = model;
|
|
220
|
+
},
|
|
221
|
+
};
|
|
222
|
+
}
|
|
176
223
|
static async handleEnhancedCommand(token, originalInput, context) {
|
|
177
224
|
return await this.delegateToEnhanced(token, originalInput, context);
|
|
178
225
|
}
|
|
179
226
|
static async handleModelSwitch(input, context) {
|
|
180
|
-
const
|
|
181
|
-
const
|
|
182
|
-
if (
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
const confirmEntry = {
|
|
186
|
-
type: "assistant",
|
|
187
|
-
content: `✓ Switched to model: ${modelArg}`,
|
|
188
|
-
timestamp: new Date(),
|
|
189
|
-
};
|
|
190
|
-
context.setChatHistory((prev) => [...prev, confirmEntry]);
|
|
227
|
+
const args = input.trim().split(/\s+/).slice(1);
|
|
228
|
+
const model = args[0];
|
|
229
|
+
if (!model || args.length !== 1) {
|
|
230
|
+
this.finishCommandWithMessage(context, 'Usage: /model <model-name>');
|
|
231
|
+
return;
|
|
191
232
|
}
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
233
|
+
const provider = context.agent.getClient().getCurrentProvider?.();
|
|
234
|
+
if (!isModelCompatibleWithProvider(model, provider)) {
|
|
235
|
+
this.finishCommandWithMessage(context, `Model ${model} is incompatible with the active provider ${provider}. Choose a model for this connection.`);
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
// Change the running client and its context/token limits before announcing success.
|
|
239
|
+
context.agent.setModel(model);
|
|
240
|
+
// An explicit /model choice becomes the new base for later /switch auto.
|
|
241
|
+
this.switchState.delete(context.agent);
|
|
242
|
+
try {
|
|
243
|
+
updateCurrentModel(model);
|
|
244
|
+
}
|
|
245
|
+
catch (error) {
|
|
246
|
+
this.finishCommandWithMessage(context, `Model active for this session: ${model}. Could not save the preference: ${getErrorMessage(error)}`);
|
|
247
|
+
return;
|
|
199
248
|
}
|
|
249
|
+
context.setChatHistory(prev => [...prev, {
|
|
250
|
+
type: 'assistant', content: `Switched to model: ${model}`, timestamp: new Date(),
|
|
251
|
+
}]);
|
|
200
252
|
context.clearInput();
|
|
201
253
|
}
|
|
202
254
|
static async handleShellBypass(command, context) {
|
|
@@ -38,6 +38,7 @@ export interface CronAddOptions {
|
|
|
38
38
|
/** Job-level chain target: id (or id prefix) to run on successful completion. */
|
|
39
39
|
then?: string;
|
|
40
40
|
preCheck?: string;
|
|
41
|
+
continuity?: string;
|
|
41
42
|
deliver?: string[];
|
|
42
43
|
format?: string;
|
|
43
44
|
}
|
|
@@ -56,9 +57,10 @@ export interface CronJobSpec {
|
|
|
56
57
|
task: CronJob['task'];
|
|
57
58
|
delivery?: CronJob['delivery'];
|
|
58
59
|
preCheck?: CronJob['preCheck'];
|
|
60
|
+
continuity?: CronJob['continuity'];
|
|
59
61
|
then?: string;
|
|
60
62
|
}
|
|
61
|
-
export type CronJobUpdates = Partial<Pick<CronJob, 'name' | 'type' | 'schedule' | 'task' | 'delivery' | 'preCheck' | 'then'>>;
|
|
63
|
+
export type CronJobUpdates = Partial<Pick<CronJob, 'name' | 'type' | 'schedule' | 'task' | 'delivery' | 'preCheck' | 'then' | 'continuity'>>;
|
|
62
64
|
export type CronJobSpecResult = {
|
|
63
65
|
spec: CronJobSpec;
|
|
64
66
|
} | {
|
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
* Commander actions stay thin wrappers around the scheduler singleton.
|
|
23
23
|
*/
|
|
24
24
|
import * as fs from 'fs';
|
|
25
|
+
import { validateContinuity } from '../../scheduler/job-notepad.js';
|
|
25
26
|
/**
|
|
26
27
|
* Build (and validate) a CronJob spec from CLI options. Pure: no side effects,
|
|
27
28
|
* fully unit-testable. Returns either a spec or a human-readable error.
|
|
@@ -77,6 +78,17 @@ export function buildCronJobSpec(name, opts) {
|
|
|
77
78
|
}
|
|
78
79
|
spec.then = opts.then.trim();
|
|
79
80
|
}
|
|
81
|
+
if (opts.continuity !== undefined) {
|
|
82
|
+
const parsed = parseJsonOption(opts.continuity, '--continuity');
|
|
83
|
+
if ('error' in parsed)
|
|
84
|
+
return parsed;
|
|
85
|
+
try {
|
|
86
|
+
spec.continuity = validateContinuity(parsed.value);
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
return { error: `Invalid --continuity: ${String(error)}` };
|
|
90
|
+
}
|
|
91
|
+
}
|
|
80
92
|
// Optional pre-check gate.
|
|
81
93
|
if (opts.preCheck !== undefined) {
|
|
82
94
|
const parsed = parseJsonOption(opts.preCheck, '--pre-check');
|
|
@@ -159,6 +171,17 @@ export function buildCronJobUpdates(job, opts) {
|
|
|
159
171
|
}
|
|
160
172
|
updates.then = opts.then.trim();
|
|
161
173
|
}
|
|
174
|
+
if (opts.continuity !== undefined) {
|
|
175
|
+
const parsed = parseJsonOption(opts.continuity, '--continuity');
|
|
176
|
+
if ('error' in parsed)
|
|
177
|
+
return parsed;
|
|
178
|
+
try {
|
|
179
|
+
updates.continuity = validateContinuity(parsed.value);
|
|
180
|
+
}
|
|
181
|
+
catch (error) {
|
|
182
|
+
return { error: `Invalid --continuity: ${String(error)}` };
|
|
183
|
+
}
|
|
184
|
+
}
|
|
162
185
|
if (opts.preCheck !== undefined && opts.clearPreCheck) {
|
|
163
186
|
return { error: 'cron update: --pre-check and --clear-pre-check are mutually exclusive' };
|
|
164
187
|
}
|
|
@@ -394,6 +417,7 @@ export function registerCronCommands(program) {
|
|
|
394
417
|
.option('--skill-request <text>', 'request string passed to the skill executor')
|
|
395
418
|
.option('--then <jobId>', 'chain: run this job id (or prefix) on successful completion')
|
|
396
419
|
.option('--clear-then', 'remove the chain target')
|
|
420
|
+
.option('--continuity <json>', 'per-job continuity: true, false, or {enabled, notes}; inline JSON or @file')
|
|
397
421
|
.option('--pre-check <json>', 'replace pre-check gate as inline JSON or @file')
|
|
398
422
|
.option('--clear-pre-check', 'remove the pre-check gate')
|
|
399
423
|
.option('--deliver <target>', 'replace delivery targets type:id (repeatable)', collectOption, [])
|
|
@@ -433,6 +457,7 @@ export function registerCronCommands(program) {
|
|
|
433
457
|
.option('--skill <id>', 'no-agent skill run by registered skill name')
|
|
434
458
|
.option('--skill-request <text>', 'request string passed to the skill executor')
|
|
435
459
|
.option('--then <jobId>', 'chain: run this job id (or prefix) on successful completion')
|
|
460
|
+
.option('--continuity <json>', 'per-job continuity: true, false, or {enabled, notes}; inline JSON or @file')
|
|
436
461
|
.option('--pre-check <json>', 'pre-check gate as inline JSON or @file')
|
|
437
462
|
.option('--deliver <target>', 'delivery target type:id (repeatable)', collectOption, [])
|
|
438
463
|
.option('--format <fmt>', 'delivery body format: full|summary')
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { DeviceAuthStore } from '../server/auth/device-store.js';
|
|
3
|
+
import { type SpawnSyncFn } from './token.js';
|
|
4
|
+
export interface DeviceCommandDependencies {
|
|
5
|
+
store?: DeviceAuthStore;
|
|
6
|
+
env?: NodeJS.ProcessEnv;
|
|
7
|
+
spawn?: SpawnSyncFn;
|
|
8
|
+
}
|
|
9
|
+
export declare function createPairCommand(deps?: DeviceCommandDependencies): Command;
|
|
10
|
+
export declare function createDevicesCommand(deps?: DeviceCommandDependencies): Command;
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { getDeviceAuthStore } from '../server/auth/device-store.js';
|
|
3
|
+
import { renderQrAnsi } from './token.js';
|
|
4
|
+
function pairingUrl(raw) {
|
|
5
|
+
try {
|
|
6
|
+
const url = new URL(raw);
|
|
7
|
+
if (!['http:', 'https:'].includes(url.protocol) || url.username || url.password || url.search || url.hash)
|
|
8
|
+
throw new Error();
|
|
9
|
+
return url.toString().replace(/\/+$/, '');
|
|
10
|
+
}
|
|
11
|
+
catch {
|
|
12
|
+
throw new Error('Use a valid HTTP(S) server URL without credentials, query or fragment');
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
export function createPairCommand(deps = {}) {
|
|
16
|
+
return new Command('pair')
|
|
17
|
+
.description('Pair an Android authenticator with this server (local one-time code, 10 minutes)')
|
|
18
|
+
.option('--url <url>', 'Server URL reachable from the phone')
|
|
19
|
+
.option('--json', 'Print the QR payload as JSON')
|
|
20
|
+
.action((options) => {
|
|
21
|
+
try {
|
|
22
|
+
const env = deps.env ?? process.env;
|
|
23
|
+
const url = pairingUrl(options.url || env.CODEBUDDY_SERVER_URL || `http://127.0.0.1:${env.CODEBUDDY_SERVER_PORT || env.PORT || '3000'}`);
|
|
24
|
+
const { pairingCode, expiresAt } = (deps.store ?? getDeviceAuthStore()).createPairing();
|
|
25
|
+
const payload = JSON.stringify({ url, pairingCode });
|
|
26
|
+
if (options.json) {
|
|
27
|
+
console.log(payload);
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
console.log(`Pairing code: ${pairingCode}`);
|
|
31
|
+
console.log(`Expires: ${expiresAt} (10 minutes, one use)`);
|
|
32
|
+
console.log(payload);
|
|
33
|
+
const qr = renderQrAnsi(payload, deps.spawn);
|
|
34
|
+
if (qr.ok)
|
|
35
|
+
console.log(qr.output);
|
|
36
|
+
else
|
|
37
|
+
console.error(qr.hint);
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
console.error(error instanceof Error && error.message.startsWith('Use a valid')
|
|
41
|
+
? error.message : 'Device pairing unavailable');
|
|
42
|
+
process.exitCode = 1;
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
export function createDevicesCommand(deps = {}) {
|
|
47
|
+
const command = new Command('devices').description('Manage Android authentication devices (local only)');
|
|
48
|
+
const getStore = () => deps.store ?? getDeviceAuthStore();
|
|
49
|
+
command.command('list').option('--json', 'Print public device metadata as JSON')
|
|
50
|
+
.action((options) => {
|
|
51
|
+
try {
|
|
52
|
+
const devices = getStore().list().map(({ publicKeyJwk: _key, ...metadata }) => metadata);
|
|
53
|
+
if (options.json)
|
|
54
|
+
console.log(JSON.stringify(devices, null, 2));
|
|
55
|
+
else if (devices.length === 0)
|
|
56
|
+
console.log('No Android devices paired. Run buddy pair.');
|
|
57
|
+
else
|
|
58
|
+
for (const device of devices) {
|
|
59
|
+
console.log(`${device.deviceId} ${device.deviceName} ${device.revokedAt ? 'revoked' : 'active'} ${device.createdAt}`);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
console.error('Device store unavailable');
|
|
64
|
+
process.exitCode = 1;
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
command.command('revoke <id>').description('Revoke an Android authentication device')
|
|
68
|
+
.action((id) => {
|
|
69
|
+
try {
|
|
70
|
+
getStore().revoke(id);
|
|
71
|
+
console.log('Device revoked');
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
console.error('Unable to revoke device');
|
|
75
|
+
process.exitCode = 1;
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
command.command('rename <id> <name>').description('Rename an Android device')
|
|
79
|
+
.action((id, name) => {
|
|
80
|
+
try {
|
|
81
|
+
getStore().rename(id, name);
|
|
82
|
+
console.log('Device renamed');
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
console.error('Unable to rename device');
|
|
86
|
+
process.exitCode = 1;
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
return command;
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=device-auth.js.map
|
|
@@ -2,10 +2,19 @@ import { ChatEntry } from "../agent/codebuddy-agent.js";
|
|
|
2
2
|
import { CodeBuddyClient } from "../codebuddy/client.js";
|
|
3
3
|
import type { CommandHandlerResult } from "./handlers/index.js";
|
|
4
4
|
export type { CommandHandlerResult };
|
|
5
|
+
/**
|
|
6
|
+
* Give every handled result a visible `entry` when the handler only produced
|
|
7
|
+
* legacy text fields. Results that already carry an entry are left untouched.
|
|
8
|
+
*/
|
|
9
|
+
export declare function normalizeHandlerResult(result: CommandHandlerResult): CommandHandlerResult;
|
|
5
10
|
/**
|
|
6
11
|
* Proxy interface for agent context stats used by the /context stats command.
|
|
7
12
|
*/
|
|
8
13
|
export interface AgentContextProxy {
|
|
14
|
+
getMemoryScope?: () => {
|
|
15
|
+
cwd: string;
|
|
16
|
+
botId?: string;
|
|
17
|
+
};
|
|
9
18
|
getContextStats: () => unknown;
|
|
10
19
|
formatContextStats: () => string;
|
|
11
20
|
getCurrentModel: () => string;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { handleGrillMe } from './handlers/grill-me-handler.js';
|
|
2
2
|
import { handleDeepthink } from './handlers/deepthink-handler.js';
|
|
3
|
+
import { withFactsMemorySessionClient } from "../memory/facts-memory.js";
|
|
3
4
|
// Import all handlers from modular files
|
|
4
5
|
import {
|
|
5
6
|
// Branch handlers
|
|
@@ -116,6 +117,7 @@ handleInfra,
|
|
|
116
117
|
handleRedo, handleTimeline, handleKnowledgeGraph, handleApprovals, } from "./handlers/index.js";
|
|
117
118
|
import { handleLessonsCommand } from "./handlers/index.js";
|
|
118
119
|
import { handleContextStats } from "./handlers/extra-handlers.js";
|
|
120
|
+
import { handleResources } from "./handlers/resources-handler.js";
|
|
119
121
|
import { handleLogin, handleLogout, handleWhoami } from "./handlers/auth-handlers.js";
|
|
120
122
|
import { handlePromptCommand as handlePromptCommandRaw } from "./slash/prompt-commands.js";
|
|
121
123
|
import { handleShortcuts, handleDebugMode, handleToolAnalytics, handleSecurityReview, handleIdentity, handlePairing, handleElevated, handlePolicy, } from "./handlers/index.js";
|
|
@@ -183,6 +185,25 @@ async function handlePromptCommand(args) {
|
|
|
183
185
|
entry: { type: 'assistant', content: output, timestamp: new Date() },
|
|
184
186
|
};
|
|
185
187
|
}
|
|
188
|
+
/**
|
|
189
|
+
* Give every handled result a visible `entry` when the handler only produced
|
|
190
|
+
* legacy text fields. Results that already carry an entry are left untouched.
|
|
191
|
+
*/
|
|
192
|
+
export function normalizeHandlerResult(result) {
|
|
193
|
+
if (!result.handled || result.entry) {
|
|
194
|
+
return result;
|
|
195
|
+
}
|
|
196
|
+
const legacy = result;
|
|
197
|
+
const text = [legacy.output, legacy.response, legacy.message, legacy.error]
|
|
198
|
+
.find((value) => typeof value === 'string' && value.trim().length > 0);
|
|
199
|
+
if (!text) {
|
|
200
|
+
return result;
|
|
201
|
+
}
|
|
202
|
+
return {
|
|
203
|
+
...result,
|
|
204
|
+
entry: { type: 'assistant', content: text, timestamp: new Date() },
|
|
205
|
+
};
|
|
206
|
+
}
|
|
186
207
|
/**
|
|
187
208
|
* Enhanced Command Handler.
|
|
188
209
|
*
|
|
@@ -225,8 +246,8 @@ export class EnhancedCommandHandler {
|
|
|
225
246
|
['__MERGE__', (args) => handleMerge(args)],
|
|
226
247
|
['__BRANCH__', (args) => handleBranch(args)],
|
|
227
248
|
// Memory & TODOs
|
|
228
|
-
['__MEMORY__', (args) => handleMemory(args)],
|
|
229
|
-
['__REMEMBER__', (args) => handleRemember(args)],
|
|
249
|
+
['__MEMORY__', (args) => this.agentProxy?.getMemoryScope ? handleMemory(args, this.agentProxy.getMemoryScope()) : handleMemory(args)],
|
|
250
|
+
['__REMEMBER__', (args) => this.agentProxy?.getMemoryScope ? handleRemember(args, this.agentProxy.getMemoryScope()) : handleRemember(args)],
|
|
230
251
|
['__SCAN_TODOS__', () => handleScanTodos()],
|
|
231
252
|
['__ADDRESS_TODO__', (args) => handleAddressTodo(args)],
|
|
232
253
|
// Context & Workspace
|
|
@@ -237,7 +258,7 @@ export class EnhancedCommandHandler {
|
|
|
237
258
|
: handleContext(args)],
|
|
238
259
|
// Export (context-dependent: conversationHistory)
|
|
239
260
|
['__SAVE_CONVERSATION__', (args) => handleSaveConversation(args, this.conversationHistory)],
|
|
240
|
-
['__EXPORT__', (args) => handleExport(args)],
|
|
261
|
+
['__EXPORT__', (args) => handleExport(args, this.conversationHistory, this.agentProxy?.getCurrentModel())],
|
|
241
262
|
['__EXPORT_LIST__', () => handleExportList()],
|
|
242
263
|
['__EXPORT_FORMATS__', () => handleExportFormats()],
|
|
243
264
|
// Testing (context-dependent: codebuddyClient)
|
|
@@ -306,10 +327,11 @@ export class EnhancedCommandHandler {
|
|
|
306
327
|
['__BATCH__', (args) => handleBatchSlashCommand(args, this.createBatchChatFn(), this.createBatchSpawnFn())],
|
|
307
328
|
// Commands previously handled inline in client-dispatcher
|
|
308
329
|
['__CLEAR_CHAT__', () => handleClearChat()],
|
|
309
|
-
['__CHANGE_MODEL__', (args) => handleChangeModel(args)],
|
|
330
|
+
['__CHANGE_MODEL__', (args) => handleChangeModel(args, this.agentProxy?.getCurrentModel())],
|
|
310
331
|
['__CHANGE_MODE__', (args) => handleChangeMode(args)],
|
|
311
332
|
['__PLAN_MODE__', () => handleChangeMode(['plan'])],
|
|
312
|
-
['__STATUS__', () => handleStatus()],
|
|
333
|
+
['__STATUS__', () => handleStatus(this.agentProxy?.getCurrentModel())],
|
|
334
|
+
['__RESOURCES__', () => handleResources()],
|
|
313
335
|
['__NEW__', (args) => handleNew(args)],
|
|
314
336
|
['__ULTRAPLAN__', (args) => handleUltraplan(args)],
|
|
315
337
|
['__LIST_CHECKPOINTS__', (args) => handleListCheckpoints(args)],
|
|
@@ -541,7 +563,7 @@ export class EnhancedCommandHandler {
|
|
|
541
563
|
async handleCommand(token, args, _fullInput) {
|
|
542
564
|
const handler = this.handlerMap.get(token);
|
|
543
565
|
if (handler) {
|
|
544
|
-
return handler(args);
|
|
566
|
+
return withFactsMemorySessionClient(this.codebuddyClient ?? null, async () => normalizeHandlerResult(await handler(args)));
|
|
545
567
|
}
|
|
546
568
|
return { handled: false };
|
|
547
569
|
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Agent command handlers
|
|
3
3
|
*
|
|
4
4
|
* Handles /agent commands for custom agent management:
|
|
5
|
-
* - /agent - List all agents
|
|
5
|
+
* - /agent, /agent list - List all agents
|
|
6
6
|
* - /agent <id> - Activate an agent
|
|
7
7
|
* - /agent create <name> - Create a new agent
|
|
8
8
|
* - /agent info <id> - Show agent details
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Agent command handlers
|
|
3
3
|
*
|
|
4
4
|
* Handles /agent commands for custom agent management:
|
|
5
|
-
* - /agent - List all agents
|
|
5
|
+
* - /agent, /agent list - List all agents
|
|
6
6
|
* - /agent <id> - Activate an agent
|
|
7
7
|
* - /agent create <name> - Create a new agent
|
|
8
8
|
* - /agent info <id> - Show agent details
|
|
@@ -14,14 +14,14 @@ import { setActiveCustomAgentRuntime } from '../../agent/custom/custom-agent-run
|
|
|
14
14
|
*/
|
|
15
15
|
export function handleAgent(args) {
|
|
16
16
|
const loader = getCustomAgentLoader();
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
const subcommand = args[0]?.toLowerCase() ?? '';
|
|
18
|
+
// No args or the documented `list` action - list agents
|
|
19
|
+
if (args.length === 0 || (subcommand === 'list' && args.length === 1)) {
|
|
19
20
|
return {
|
|
20
21
|
handled: true,
|
|
21
22
|
output: loader.formatAgentList(),
|
|
22
23
|
};
|
|
23
24
|
}
|
|
24
|
-
const subcommand = args[0]?.toLowerCase() ?? '';
|
|
25
25
|
// Create new agent
|
|
26
26
|
if (subcommand === 'create') {
|
|
27
27
|
return handleAgentCreate(args.slice(1));
|