@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
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { readFile, stat } from 'node:fs/promises';
|
|
2
|
+
import { MCPManager } from '../mcp/client.js';
|
|
3
|
+
import { loadMCPConfig } from '../mcp/config.js';
|
|
4
|
+
import { getErrorMessage } from '../types/index.js';
|
|
5
|
+
const MAX_ARGUMENT_BYTES = 1024 * 1024;
|
|
6
|
+
export function registerMCPInvocationCommands(command) {
|
|
7
|
+
command.command('tools <server>')
|
|
8
|
+
.description('Print one configured MCP server tool catalog as JSON, without an LLM')
|
|
9
|
+
.option('--query <text>', 'Filter tool names and descriptions before printing schemas')
|
|
10
|
+
.action(async (server, options) => run(server, undefined, options));
|
|
11
|
+
command.command('call <server> <tool>')
|
|
12
|
+
.description('Invoke one MCP tool directly and print its result as JSON')
|
|
13
|
+
.option('--args <json>', 'JSON object of tool arguments')
|
|
14
|
+
.option('--args-file <path>', 'Read JSON arguments from a file (maximum 1 MiB)')
|
|
15
|
+
.action(async (server, tool, options) => {
|
|
16
|
+
await run(server, tool, options);
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
async function run(server, tool, options = {}) {
|
|
20
|
+
const manager = new MCPManager();
|
|
21
|
+
try {
|
|
22
|
+
if (options.args !== undefined && options.argsFile !== undefined) {
|
|
23
|
+
throw new Error('Use either --args or --args-file');
|
|
24
|
+
}
|
|
25
|
+
let raw = options.args ?? '{}';
|
|
26
|
+
if (options.argsFile !== undefined) {
|
|
27
|
+
const info = await stat(options.argsFile);
|
|
28
|
+
if (!info.isFile() || info.size > MAX_ARGUMENT_BYTES)
|
|
29
|
+
throw new Error('Arguments must be a regular file no larger than 1 MiB');
|
|
30
|
+
raw = await readFile(options.argsFile, 'utf8');
|
|
31
|
+
}
|
|
32
|
+
if (Buffer.byteLength(raw) > MAX_ARGUMENT_BYTES)
|
|
33
|
+
throw new Error('Arguments exceed 1 MiB');
|
|
34
|
+
let args;
|
|
35
|
+
try {
|
|
36
|
+
args = JSON.parse(raw);
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
throw new Error('Tool arguments must be valid JSON');
|
|
40
|
+
}
|
|
41
|
+
if (!args || typeof args !== 'object' || Array.isArray(args))
|
|
42
|
+
throw new Error('Tool arguments must be a JSON object');
|
|
43
|
+
const config = loadMCPConfig().servers.find(candidate => candidate.name === server);
|
|
44
|
+
if (!config)
|
|
45
|
+
throw new Error(`Enabled MCP server not found: ${server}`);
|
|
46
|
+
await manager.addServer(config);
|
|
47
|
+
if (!tool) {
|
|
48
|
+
const catalog = manager.getTools().filter(item => item.serverName === server);
|
|
49
|
+
const query = options.query?.toLowerCase();
|
|
50
|
+
const tools = query ? catalog.filter(item => `${item.name} ${item.description}`.toLowerCase().includes(query)) : catalog;
|
|
51
|
+
console.log(JSON.stringify({ server, totalTools: catalog.length, tools }));
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
const qualified = `mcp__${server}__${tool}`;
|
|
55
|
+
const result = await manager.callTool(qualified, args);
|
|
56
|
+
console.log(JSON.stringify(result));
|
|
57
|
+
if (result.isError)
|
|
58
|
+
process.exitCode = 1;
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
console.log(JSON.stringify({ isError: true, error: getErrorMessage(error) }));
|
|
62
|
+
process.exitCode = 1;
|
|
63
|
+
}
|
|
64
|
+
finally {
|
|
65
|
+
await manager.dispose();
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=mcp-invoke.js.map
|
package/dist/commands/mcp.d.ts
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
2
|
export declare function confirmPrompt(prompt: string): Promise<boolean>;
|
|
3
|
+
/**
|
|
4
|
+
* How to confirm a stdio MCP add. `--yes` skips the prompt.
|
|
5
|
+
* Without a TTY and without `--yes`, abort instead of hanging on readline.
|
|
6
|
+
*/
|
|
7
|
+
export declare function stdioAddConfirmMode(yes: boolean, stdinIsTTY?: boolean | undefined): 'skip' | 'prompt' | 'abort';
|
|
8
|
+
/**
|
|
9
|
+
* `mcp test` / add / add-json only probe the server then persist config.
|
|
10
|
+
* Tear down the live client so a stdio child cannot keep the CLI event loop open.
|
|
11
|
+
* Same path as `buddy mcp test` (removeServer → transport.disconnect → reap PID).
|
|
12
|
+
*/
|
|
13
|
+
export declare function releaseMcpProbe(manager: {
|
|
14
|
+
removeServer(name: string): Promise<void>;
|
|
15
|
+
}, name: string): Promise<void>;
|
|
3
16
|
export interface MCPServeOptions {
|
|
4
17
|
allowWrite?: boolean;
|
|
5
18
|
tools?: string;
|
package/dist/commands/mcp.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { registerMCPImportCommand } from './mcp-import.js';
|
|
2
|
+
import { registerMCPInvocationCommands } from './mcp-invoke.js';
|
|
1
3
|
import { Command } from 'commander';
|
|
2
4
|
import { addMCPServer, removeMCPServer, loadMCPConfig, PREDEFINED_SERVERS, setMCPServerEnabled, } from '../mcp/config.js';
|
|
3
5
|
import { getMCPManager } from '../codebuddy/tools.js';
|
|
@@ -35,6 +37,30 @@ export function confirmPrompt(prompt) {
|
|
|
35
37
|
});
|
|
36
38
|
});
|
|
37
39
|
}
|
|
40
|
+
/**
|
|
41
|
+
* How to confirm a stdio MCP add. `--yes` skips the prompt.
|
|
42
|
+
* Without a TTY and without `--yes`, abort instead of hanging on readline.
|
|
43
|
+
*/
|
|
44
|
+
export function stdioAddConfirmMode(yes, stdinIsTTY = process.stdin.isTTY) {
|
|
45
|
+
if (yes)
|
|
46
|
+
return 'skip';
|
|
47
|
+
if (stdinIsTTY)
|
|
48
|
+
return 'prompt';
|
|
49
|
+
return 'abort';
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* `mcp test` / add / add-json only probe the server then persist config.
|
|
53
|
+
* Tear down the live client so a stdio child cannot keep the CLI event loop open.
|
|
54
|
+
* Same path as `buddy mcp test` (removeServer → transport.disconnect → reap PID).
|
|
55
|
+
*/
|
|
56
|
+
export async function releaseMcpProbe(manager, name) {
|
|
57
|
+
try {
|
|
58
|
+
await manager.removeServer(name);
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
// Probe teardown must not mask the add/test result.
|
|
62
|
+
}
|
|
63
|
+
}
|
|
38
64
|
/** Start the distribution-facing stdio server. Logs stay on stderr via logger. */
|
|
39
65
|
export async function serveMCP(options = {}) {
|
|
40
66
|
const { CodeBuddyMCPServer } = await import('../mcp/mcp-server.js');
|
|
@@ -52,6 +78,7 @@ export async function serveMCP(options = {}) {
|
|
|
52
78
|
export function createMCPCommand() {
|
|
53
79
|
const mcpCommand = new Command('mcp');
|
|
54
80
|
mcpCommand.description('Manage MCP servers or expose Code Buddy over MCP');
|
|
81
|
+
registerMCPImportCommand(mcpCommand);
|
|
55
82
|
mcpCommand
|
|
56
83
|
.command('serve')
|
|
57
84
|
.description('Expose Code Buddy tools as an MCP server over stdio')
|
|
@@ -213,9 +240,9 @@ export function createMCPCommand() {
|
|
|
213
240
|
}
|
|
214
241
|
addMCPServer(preset);
|
|
215
242
|
console.log(chalk.green(`✓ Added predefined MCP server: ${name}`));
|
|
216
|
-
// Try to connect immediately
|
|
243
|
+
// Try to connect immediately, then drop the probe (same as `mcp test`).
|
|
244
|
+
const manager = getMCPManager();
|
|
217
245
|
try {
|
|
218
|
-
const manager = getMCPManager();
|
|
219
246
|
await manager.addServer(preset);
|
|
220
247
|
console.log(chalk.green(`✓ Connected to MCP server: ${name}`));
|
|
221
248
|
const tools = manager.getTools().filter(t => t.serverName === name);
|
|
@@ -225,6 +252,9 @@ export function createMCPCommand() {
|
|
|
225
252
|
console.log(chalk.yellow(`⚠ Server saved but connection failed: ${getErrorMessage(connectError)}`));
|
|
226
253
|
console.log(chalk.yellow(' Check your API key and try: buddy mcp test ' + name));
|
|
227
254
|
}
|
|
255
|
+
finally {
|
|
256
|
+
await releaseMcpProbe(manager, name);
|
|
257
|
+
}
|
|
228
258
|
return;
|
|
229
259
|
}
|
|
230
260
|
// Custom server
|
|
@@ -282,12 +312,16 @@ export function createMCPCommand() {
|
|
|
282
312
|
};
|
|
283
313
|
addMCPServer(config);
|
|
284
314
|
console.log(chalk.green(`✓ Added MCP server: ${name}`));
|
|
285
|
-
// Try to connect immediately
|
|
286
315
|
const manager = getMCPManager();
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
316
|
+
try {
|
|
317
|
+
await manager.addServer(config);
|
|
318
|
+
console.log(chalk.green(`✓ Connected to MCP server: ${name}`));
|
|
319
|
+
const tools = manager.getTools().filter(t => t.serverName === name);
|
|
320
|
+
console.log(chalk.blue(` Available tools: ${tools.length}`));
|
|
321
|
+
}
|
|
322
|
+
finally {
|
|
323
|
+
await releaseMcpProbe(manager, name);
|
|
324
|
+
}
|
|
291
325
|
}
|
|
292
326
|
catch (error) {
|
|
293
327
|
logger.error(chalk.red(`Error adding MCP server: ${getErrorMessage(error)}`));
|
|
@@ -298,7 +332,8 @@ export function createMCPCommand() {
|
|
|
298
332
|
mcpCommand
|
|
299
333
|
.command('add-json <name> <json>')
|
|
300
334
|
.description('Add an MCP server from JSON configuration')
|
|
301
|
-
.
|
|
335
|
+
.option('-y, --yes', 'skip confirmation for stdio MCP servers (required when stdin is not a TTY)')
|
|
336
|
+
.action(async (name, jsonConfig, options) => {
|
|
302
337
|
try {
|
|
303
338
|
let config;
|
|
304
339
|
try {
|
|
@@ -333,20 +368,31 @@ export function createMCPCommand() {
|
|
|
333
368
|
console.log(chalk.yellow('\nSecurity notice: This MCP server will execute a command on your system.'));
|
|
334
369
|
console.log(chalk.yellow(` Command: ${serverConfig.transport.command} ${(serverConfig.transport.args || []).join(' ')}`));
|
|
335
370
|
console.log(chalk.yellow(' Only add MCP servers from trusted sources.\n'));
|
|
336
|
-
const
|
|
337
|
-
if (
|
|
338
|
-
|
|
339
|
-
|
|
371
|
+
const mode = stdioAddConfirmMode(options.yes === true);
|
|
372
|
+
if (mode === 'abort') {
|
|
373
|
+
logger.error(chalk.red('Error: stdin is not a TTY. Re-run with --yes to confirm adding this stdio MCP server.'));
|
|
374
|
+
process.exit(1);
|
|
375
|
+
}
|
|
376
|
+
if (mode === 'prompt') {
|
|
377
|
+
const confirmed = await confirmPrompt('Do you want to proceed? (y/N): ');
|
|
378
|
+
if (!confirmed) {
|
|
379
|
+
console.log('MCP server addition cancelled.');
|
|
380
|
+
return;
|
|
381
|
+
}
|
|
340
382
|
}
|
|
341
383
|
}
|
|
342
384
|
addMCPServer(serverConfig);
|
|
343
385
|
console.log(chalk.green(`✓ Added MCP server: ${name}`));
|
|
344
|
-
// Try to connect immediately
|
|
345
386
|
const manager = getMCPManager();
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
387
|
+
try {
|
|
388
|
+
await manager.addServer(serverConfig);
|
|
389
|
+
console.log(chalk.green(`✓ Connected to MCP server: ${name}`));
|
|
390
|
+
const tools = manager.getTools().filter(t => t.serverName === name);
|
|
391
|
+
console.log(chalk.blue(` Available tools: ${tools.length}`));
|
|
392
|
+
}
|
|
393
|
+
finally {
|
|
394
|
+
await releaseMcpProbe(manager, name);
|
|
395
|
+
}
|
|
350
396
|
}
|
|
351
397
|
catch (error) {
|
|
352
398
|
logger.error(chalk.red(`Error adding MCP server: ${getErrorMessage(error)}`));
|
|
@@ -516,14 +562,13 @@ export function createMCPCommand() {
|
|
|
516
562
|
process.exit(1);
|
|
517
563
|
}
|
|
518
564
|
finally {
|
|
519
|
-
//
|
|
520
|
-
// transport so stdio children and their database/network handles do not
|
|
521
|
-
// keep the CLI process alive after a successful discovery.
|
|
565
|
+
// Probe only: drop the client/stdio child so the CLI can exit.
|
|
522
566
|
if (connected) {
|
|
523
|
-
await manager
|
|
567
|
+
await releaseMcpProbe(manager, name);
|
|
524
568
|
}
|
|
525
569
|
}
|
|
526
570
|
});
|
|
571
|
+
registerMCPInvocationCommands(mcpCommand);
|
|
527
572
|
return mcpCommand;
|
|
528
573
|
}
|
|
529
574
|
//# sourceMappingURL=mcp.js.map
|
|
@@ -5,6 +5,11 @@
|
|
|
5
5
|
* Supports running from YAML/JSON files, listing, validating, and status checks.
|
|
6
6
|
*/
|
|
7
7
|
import { Command } from 'commander';
|
|
8
|
+
import type { PipelineConfig, ApprovalGateConfig } from '../workflows/pipeline.js';
|
|
9
|
+
/** Standalone CLI bridge; tool policy, trust and confirmations stay in ToolHandler. */
|
|
10
|
+
export declare function createPipelineRuntime(): Pick<PipelineConfig, 'toolExecutor' | 'approvalHandler'> & {
|
|
11
|
+
dispose(): Promise<void>;
|
|
12
|
+
};
|
|
8
13
|
/**
|
|
9
14
|
* Pipeline definition loaded from a file (YAML/JSON)
|
|
10
15
|
*/
|
|
@@ -14,10 +19,11 @@ export interface PipelineFileDefinition {
|
|
|
14
19
|
version?: string;
|
|
15
20
|
steps: Array<{
|
|
16
21
|
name: string;
|
|
17
|
-
type?: 'tool' | 'skill' | 'function' | 'transform';
|
|
22
|
+
type?: 'tool' | 'skill' | 'function' | 'transform' | 'approval';
|
|
18
23
|
args?: Record<string, unknown>;
|
|
19
24
|
timeout?: number;
|
|
20
25
|
label?: string;
|
|
26
|
+
approvalGate?: Pick<ApprovalGateConfig, 'message' | 'timeoutMs'>;
|
|
21
27
|
}>;
|
|
22
28
|
config?: {
|
|
23
29
|
maxSteps?: number;
|
|
@@ -6,6 +6,90 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import { Command } from 'commander';
|
|
8
8
|
import { logger } from '../utils/logger.js';
|
|
9
|
+
/** Standalone CLI bridge; tool policy, trust and confirmations stay in ToolHandler. */
|
|
10
|
+
export function createPipelineRuntime() {
|
|
11
|
+
const controller = new AbortController();
|
|
12
|
+
let handler;
|
|
13
|
+
let marketplace;
|
|
14
|
+
let repair;
|
|
15
|
+
let service;
|
|
16
|
+
let readline;
|
|
17
|
+
let ownsListener = false;
|
|
18
|
+
const onConfirmation = (options) => {
|
|
19
|
+
void (async () => {
|
|
20
|
+
try {
|
|
21
|
+
const { createInterface } = await import('node:readline/promises');
|
|
22
|
+
readline = createInterface({ input: process.stdin, output: process.stderr });
|
|
23
|
+
process.stderr.write(`${JSON.stringify({ operation: options.operation, target: options.filename,
|
|
24
|
+
preview: options.diffPreview ?? options.content })}\n`);
|
|
25
|
+
const answer = await readline.question('Approve this operation? [y/N] ');
|
|
26
|
+
service?.confirmOperation(/^(y|yes|o|oui)$/i.test(answer.trim()));
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
service?.rejectOperation('Approval input closed');
|
|
30
|
+
}
|
|
31
|
+
finally {
|
|
32
|
+
readline?.close();
|
|
33
|
+
readline = undefined;
|
|
34
|
+
}
|
|
35
|
+
})();
|
|
36
|
+
};
|
|
37
|
+
const confirmations = async () => {
|
|
38
|
+
if (!service) {
|
|
39
|
+
const { ConfirmationService } = await import('../utils/confirmation-service.js');
|
|
40
|
+
service = ConfirmationService.getInstance();
|
|
41
|
+
if (process.stdin.isTTY && service.listenerCount('confirmation-requested') === 0) {
|
|
42
|
+
service.on('confirmation-requested', onConfirmation);
|
|
43
|
+
ownsListener = true;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return service;
|
|
47
|
+
};
|
|
48
|
+
return {
|
|
49
|
+
toolExecutor: async (name, args) => {
|
|
50
|
+
await confirmations();
|
|
51
|
+
if (!handler) {
|
|
52
|
+
const [{ ToolHandler }, { CheckpointManager }, { HooksManager }, { PluginMarketplace }, { RepairCoordinator }] = await Promise.all([
|
|
53
|
+
import('../agent/tool-handler.js'), import('../checkpoints/checkpoint-manager.js'),
|
|
54
|
+
import('../hooks/lifecycle-hooks.js'), import('../plugins/marketplace.js'),
|
|
55
|
+
import('../agent/execution/repair-coordinator.js'),
|
|
56
|
+
]);
|
|
57
|
+
marketplace = new PluginMarketplace({ autoUpdate: false });
|
|
58
|
+
repair = new RepairCoordinator({ enabled: false });
|
|
59
|
+
handler = new ToolHandler({ checkpointManager: new CheckpointManager(),
|
|
60
|
+
hooksManager: new HooksManager(process.cwd()), marketplace, repairCoordinator: repair });
|
|
61
|
+
handler.setWorkingDirectory(process.cwd());
|
|
62
|
+
}
|
|
63
|
+
const { randomUUID } = await import('node:crypto');
|
|
64
|
+
const result = await handler.executeTool({ id: `pipeline_${randomUUID()}`, type: 'function',
|
|
65
|
+
function: { name, arguments: JSON.stringify(args) } }, { surface: 'cli', abortSignal: controller.signal });
|
|
66
|
+
return { success: result.success, output: result.output ?? '', error: result.error };
|
|
67
|
+
},
|
|
68
|
+
approvalHandler: async (gate) => {
|
|
69
|
+
const confirmation = await confirmations();
|
|
70
|
+
const timer = setTimeout(() => {
|
|
71
|
+
confirmation.rejectOperation('Pipeline approval timed out');
|
|
72
|
+
readline?.close();
|
|
73
|
+
}, gate.timeoutMs);
|
|
74
|
+
try {
|
|
75
|
+
const result = await confirmation.requestConfirmation({ operation: 'Approve pipeline step',
|
|
76
|
+
filename: gate.message, toolName: 'pipeline_approval', forcePrompt: true }, 'tool');
|
|
77
|
+
return { approved: result.confirmed, timestamp: new Date(), comment: result.feedback };
|
|
78
|
+
}
|
|
79
|
+
finally {
|
|
80
|
+
clearTimeout(timer);
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
dispose: async () => {
|
|
84
|
+
controller.abort();
|
|
85
|
+
if (ownsListener)
|
|
86
|
+
service?.off('confirmation-requested', onConfirmation);
|
|
87
|
+
readline?.close();
|
|
88
|
+
repair?.dispose();
|
|
89
|
+
await marketplace?.dispose();
|
|
90
|
+
},
|
|
91
|
+
};
|
|
92
|
+
}
|
|
9
93
|
/**
|
|
10
94
|
* Load a pipeline definition from a YAML or JSON file.
|
|
11
95
|
* Uses lazy imports for yaml parsing.
|
|
@@ -86,8 +170,12 @@ export function validatePipelineDefinition(definition) {
|
|
|
86
170
|
warnings.push(`Step ${i + 1}: duplicate step name "${step.name}"`);
|
|
87
171
|
}
|
|
88
172
|
stepNames.add(step.name);
|
|
89
|
-
if (step.type && !['tool', 'skill', 'function', 'transform'].includes(step.type)) {
|
|
90
|
-
errors.push(`Step ${i + 1} ("${step.name}"): invalid type "${step.type}" (must be tool, skill, function, or
|
|
173
|
+
if (step.type && !['tool', 'skill', 'function', 'transform', 'approval'].includes(step.type)) {
|
|
174
|
+
errors.push(`Step ${i + 1} ("${step.name}"): invalid type "${step.type}" (must be tool, skill, function, transform, or approval)`);
|
|
175
|
+
}
|
|
176
|
+
if (step.approvalGate && (typeof step.approvalGate.message !== 'string' ||
|
|
177
|
+
!Number.isFinite(step.approvalGate.timeoutMs) || step.approvalGate.timeoutMs <= 0)) {
|
|
178
|
+
errors.push(`Step ${i + 1}: approvalGate requires a message and positive timeoutMs`);
|
|
91
179
|
}
|
|
92
180
|
if (step.timeout !== undefined && (typeof step.timeout !== 'number' || step.timeout <= 0)) {
|
|
93
181
|
warnings.push(`Step ${i + 1} ("${step.name}"): timeout should be a positive number`);
|
|
@@ -117,6 +205,8 @@ export function createPipelineCommand() {
|
|
|
117
205
|
.option('-t, --timeout <ms>', 'Override default step timeout in milliseconds')
|
|
118
206
|
.option('--dry-run', 'Validate and show steps without executing')
|
|
119
207
|
.action(async (file, options) => {
|
|
208
|
+
let runtime;
|
|
209
|
+
let compositor;
|
|
120
210
|
try {
|
|
121
211
|
console.log(`Loading pipeline from: ${file}`);
|
|
122
212
|
const definition = await loadPipelineFile(file);
|
|
@@ -164,7 +254,9 @@ export function createPipelineCommand() {
|
|
|
164
254
|
if (definition.config?.maxDurationMs) {
|
|
165
255
|
config.maxDurationMs = definition.config.maxDurationMs;
|
|
166
256
|
}
|
|
167
|
-
|
|
257
|
+
runtime = createPipelineRuntime();
|
|
258
|
+
compositor = new PipelineCompositor({ ...config, toolExecutor: runtime.toolExecutor,
|
|
259
|
+
approvalHandler: runtime.approvalHandler });
|
|
168
260
|
// Set up event listeners for progress
|
|
169
261
|
compositor.on('step:start', (step, index) => {
|
|
170
262
|
console.log(` [${index + 1}/${definition.steps.length}] Running: ${step.name}...`);
|
|
@@ -175,11 +267,13 @@ export function createPipelineCommand() {
|
|
|
175
267
|
});
|
|
176
268
|
// Convert file definition steps to PipelineStep format
|
|
177
269
|
const steps = definition.steps.map(step => ({
|
|
178
|
-
type:
|
|
270
|
+
type: step.type || 'tool',
|
|
179
271
|
name: step.name,
|
|
180
272
|
args: step.args || {},
|
|
181
273
|
timeout: step.timeout,
|
|
182
274
|
label: step.label,
|
|
275
|
+
approvalGate: step.type === 'approval' ? { message: step.approvalGate?.message ?? step.name,
|
|
276
|
+
timeoutMs: step.approvalGate?.timeoutMs ?? 300000, requireExplicit: true } : undefined,
|
|
183
277
|
}));
|
|
184
278
|
console.log(`\nRunning pipeline: ${definition.name} (${steps.length} steps)`);
|
|
185
279
|
const result = await compositor.execute(steps);
|
|
@@ -191,14 +285,17 @@ export function createPipelineCommand() {
|
|
|
191
285
|
}
|
|
192
286
|
else {
|
|
193
287
|
console.error(`\nPipeline failed: ${result.error || 'Unknown error'}`);
|
|
194
|
-
process.
|
|
288
|
+
process.exitCode = 1;
|
|
195
289
|
}
|
|
196
|
-
compositor.dispose();
|
|
197
290
|
}
|
|
198
291
|
catch (error) {
|
|
199
292
|
const msg = error instanceof Error ? error.message : String(error);
|
|
200
293
|
logger.error(`Pipeline error: ${msg}`);
|
|
201
|
-
process.
|
|
294
|
+
process.exitCode = 1;
|
|
295
|
+
}
|
|
296
|
+
finally {
|
|
297
|
+
compositor?.dispose();
|
|
298
|
+
await runtime?.dispose();
|
|
202
299
|
}
|
|
203
300
|
});
|
|
204
301
|
// List available pipeline definitions
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import fs from 'node:fs/promises';
|
|
2
|
+
import { Command } from 'commander';
|
|
3
|
+
import { ResourceCatalog, resourceSchema, selectionWarning } from '../fleet/resource-catalog.js';
|
|
4
|
+
export function createResourcesCommand() {
|
|
5
|
+
const command = new Command('resources').description('Explicit resource inventory and bounded read-only health probes (JSON output)');
|
|
6
|
+
const run = (action) => async () => {
|
|
7
|
+
try {
|
|
8
|
+
process.stdout.write(`${JSON.stringify(await action(), null, 2)}\n`);
|
|
9
|
+
}
|
|
10
|
+
catch (error) {
|
|
11
|
+
command.error(error instanceof Error ? error.message : 'RESOURCE_OPERATION_FAILED');
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
command.command('schema').description('Show the resource registration fields').action(() => {
|
|
15
|
+
process.stdout.write(`${JSON.stringify({ kinds: resourceSchema.shape.kind.options,
|
|
16
|
+
fields: ['id', 'kind', 'hostId', 'declaredCapabilities', 'endpointRef', 'healthPath', 'permissions', 'ttlMs', 'timeoutMs'],
|
|
17
|
+
endpointRef: 'Environment variable containing HTTP(S) origin; no embedded credentials, path, query or fragment',
|
|
18
|
+
permissions: { probe: false, use: false }, load: 'unknown (not collected)', usageConfirmed: false }, null, 2)}\n`);
|
|
19
|
+
});
|
|
20
|
+
command.command('add <file>').description('Register one explicit JSON resource; never scans the network').action(async (file) => {
|
|
21
|
+
await run(async () => {
|
|
22
|
+
const stat = await fs.stat(file);
|
|
23
|
+
if (!stat.isFile() || stat.size > 16384)
|
|
24
|
+
throw new Error('RESOURCE_INPUT_TOO_LARGE');
|
|
25
|
+
let input;
|
|
26
|
+
try {
|
|
27
|
+
input = JSON.parse(await fs.readFile(file, 'utf8'));
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
throw new Error('INVALID_RESOURCE_JSON');
|
|
31
|
+
}
|
|
32
|
+
return new ResourceCatalog().add(input);
|
|
33
|
+
})();
|
|
34
|
+
});
|
|
35
|
+
command.command('remove <id>').description('Remove an explicit registration and its observation').action(async (id) => {
|
|
36
|
+
await run(() => new ResourceCatalog().remove(id))();
|
|
37
|
+
});
|
|
38
|
+
command.command('list').description('List declarations and observation freshness; no network I/O').action(run(() => new ResourceCatalog().list()));
|
|
39
|
+
command.command('status <id>').description('Read one resource state; does not refresh observations').action(async (id) => {
|
|
40
|
+
await run(async () => {
|
|
41
|
+
const result = (await new ResourceCatalog().list()).find(e => e.resource.id === id);
|
|
42
|
+
if (!result)
|
|
43
|
+
throw new Error('RESOURCE_NOT_FOUND');
|
|
44
|
+
return result;
|
|
45
|
+
})();
|
|
46
|
+
});
|
|
47
|
+
command.command('probe <id>').description('Run one explicitly permitted, bounded GET health probe').action(async (id) => {
|
|
48
|
+
await run(() => new ResourceCatalog().probe(id))();
|
|
49
|
+
});
|
|
50
|
+
command.command('select <capability>').option('--kind <kind>', 'Required resource kind').description('Select fresh compatible resource; no task dispatch or automatic replay').action(async (capability, options) => {
|
|
51
|
+
await run(async () => {
|
|
52
|
+
const parsed = options.kind === undefined ? undefined : resourceSchema.shape.kind.safeParse(options.kind);
|
|
53
|
+
if (parsed && !parsed.success)
|
|
54
|
+
throw new Error('INVALID_RESOURCE_KIND');
|
|
55
|
+
const result = await new ResourceCatalog().select(capability, parsed?.data);
|
|
56
|
+
if (!result.selected)
|
|
57
|
+
process.exitCode = 2;
|
|
58
|
+
const warning = selectionWarning(result.selected);
|
|
59
|
+
return warning ? { ...result, warning } : result;
|
|
60
|
+
})();
|
|
61
|
+
});
|
|
62
|
+
return command;
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=resources.js.map
|
|
@@ -134,11 +134,24 @@ export function registerSkillsCommands(program) {
|
|
|
134
134
|
const all = hub.listWithIntegrity();
|
|
135
135
|
const shown = opts.all ? all : all.filter((s) => s.enabled !== false);
|
|
136
136
|
const health = buildSkillListHealth(all, shown);
|
|
137
|
-
const
|
|
137
|
+
const { readLocalSkillInventory } = await import('../../skills/local-inventory.js');
|
|
138
|
+
const inventory = await readLocalSkillInventory(all);
|
|
139
|
+
const availableSkills = inventory.entries.filter((skill) => skill.available);
|
|
140
|
+
const usableCount = availableSkills.filter((skill) => skill.source === 'hub').length;
|
|
138
141
|
if (opts.json) {
|
|
139
|
-
console.log(JSON.stringify({
|
|
142
|
+
console.log(JSON.stringify({ availableSkills, availableCount: availableSkills.length,
|
|
143
|
+
unavailableSkills: inventory.entries.filter((skill) => !skill.available),
|
|
144
|
+
discoveryErrors: inventory.errors,
|
|
145
|
+
count: shown.length, health, total: all.length, skills: shown }, null, 2));
|
|
140
146
|
return;
|
|
141
147
|
}
|
|
148
|
+
console.log(`\nAvailable local skills (${availableSkills.length}):`);
|
|
149
|
+
for (const skill of availableSkills) {
|
|
150
|
+
console.log(` + ${skill.name} (${skill.source})${skill.description ? ` — ${skill.description}` : ''}`);
|
|
151
|
+
}
|
|
152
|
+
if (inventory.errors.length > 0) {
|
|
153
|
+
console.log(`\n${inventory.errors.length} skill file(s) could not be loaded; use --json for details.`);
|
|
154
|
+
}
|
|
142
155
|
if (shown.length === 0) {
|
|
143
156
|
if (all.length === 0) {
|
|
144
157
|
const { getBundledSkillsPath } = await import('../../skills/index.js');
|
|
@@ -280,26 +293,36 @@ export function registerSkillsCommands(program) {
|
|
|
280
293
|
});
|
|
281
294
|
skills
|
|
282
295
|
.command('usage')
|
|
283
|
-
.description('Show local usage telemetry
|
|
296
|
+
.description('Show local usage telemetry: hub invocations and view/use activity of every skill')
|
|
284
297
|
.option('--json', 'output JSON')
|
|
285
298
|
.action(async (opts) => {
|
|
286
299
|
const { getSkillsHub } = await import('../../skills/hub.js');
|
|
300
|
+
const { listSkillActivity } = await import('../../skills/skill-usage-store.js');
|
|
287
301
|
const summary = getSkillsHub().usageSummary();
|
|
302
|
+
const activity = listSkillActivity();
|
|
288
303
|
if (opts.json) {
|
|
289
|
-
console.log(JSON.stringify({ count: summary.length, skills: summary }, null, 2));
|
|
304
|
+
console.log(JSON.stringify({ count: summary.length, skills: summary, activityCount: activity.length, activity }, null, 2));
|
|
290
305
|
return;
|
|
291
306
|
}
|
|
292
|
-
if (summary.length === 0) {
|
|
307
|
+
if (summary.length === 0 && activity.length === 0) {
|
|
293
308
|
console.log('No skill usage recorded yet.');
|
|
294
309
|
return;
|
|
295
310
|
}
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
const
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
311
|
+
if (summary.length > 0) {
|
|
312
|
+
console.log('\nSkill usage (most used first):');
|
|
313
|
+
for (const skill of summary) {
|
|
314
|
+
const u = skill.usage;
|
|
315
|
+
const avg = u.averageDurationMs !== undefined ? `, avg ${Math.round(u.averageDurationMs)}ms` : '';
|
|
316
|
+
console.log(` ${skill.name}: ${u.invocationCount} run(s), ${u.successCount} ok / ${u.failureCount} fail${avg}`);
|
|
317
|
+
if (u.lastError)
|
|
318
|
+
console.log(` last error: ${u.lastError}`);
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
if (activity.length > 0) {
|
|
322
|
+
console.log('\nSkill activity (most recent first):');
|
|
323
|
+
for (const entry of activity) {
|
|
324
|
+
console.log(` ${entry.skill}: ${entry.viewCount} view(s), ${entry.useCount} use(s), last ${entry.lastActivityAt}`);
|
|
325
|
+
}
|
|
303
326
|
}
|
|
304
327
|
console.log('');
|
|
305
328
|
});
|
|
@@ -342,9 +342,12 @@ const devCommands = [
|
|
|
342
342
|
{
|
|
343
343
|
name: 'debug-issue',
|
|
344
344
|
description: 'Help debug a code issue',
|
|
345
|
-
|
|
345
|
+
// A bare /debug-issue used to send "the described issue" with nothing
|
|
346
|
+
// described; the prompt now stands on its own with or without a symptom.
|
|
347
|
+
prompt: `Debug a problem in this project.
|
|
348
|
+
Reported symptom (empty if the user gave none): $ARGUMENTS
|
|
346
349
|
|
|
347
|
-
1. Gather information about the problem
|
|
350
|
+
1. Gather information about the problem. Without a reported symptom, start from the working tree: git status --short, git diff for unstaged changes, git diff --cached for staged changes, then run the project's test script if one exists
|
|
348
351
|
2. Analyze relevant code and logs
|
|
349
352
|
3. Identify potential causes
|
|
350
353
|
4. Suggest debugging steps
|
|
@@ -352,7 +355,10 @@ const devCommands = [
|
|
|
352
355
|
|
|
353
356
|
Be systematic and thorough in your analysis.`,
|
|
354
357
|
filePath: '',
|
|
355
|
-
isBuiltin: true
|
|
358
|
+
isBuiltin: true,
|
|
359
|
+
arguments: [
|
|
360
|
+
{ name: 'symptom', description: 'Error message or behaviour to debug (optional)', required: false }
|
|
361
|
+
]
|
|
356
362
|
},
|
|
357
363
|
{
|
|
358
364
|
name: 'refactor',
|
|
@@ -1309,6 +1315,13 @@ const agentControlCommands = [
|
|
|
1309
1315
|
filePath: '',
|
|
1310
1316
|
isBuiltin: true
|
|
1311
1317
|
},
|
|
1318
|
+
{
|
|
1319
|
+
name: 'resources',
|
|
1320
|
+
description: 'List declared resources (RagChat, GPU, storage…) and observation freshness — read-only, no probe',
|
|
1321
|
+
prompt: '__RESOURCES__',
|
|
1322
|
+
filePath: '',
|
|
1323
|
+
isBuiltin: true
|
|
1324
|
+
},
|
|
1312
1325
|
{
|
|
1313
1326
|
name: 'new',
|
|
1314
1327
|
description: 'Start a new conversation, optionally switching to a different model',
|
|
@@ -3,5 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Exports types, built-in commands, and utilities for the slash command system.
|
|
5
5
|
*/
|
|
6
|
-
export type { SlashCommand, SlashCommandArgument, SlashCommandResult, SlashCommandCategory, CategorizedSlashCommand } from './types.js';
|
|
6
|
+
export type { SlashCommand, SlashCommandArgument, SlashCommandResult, SlashCommandCategory, CategorizedSlashCommand, SlashSurface, SlashAvailability } from './types.js';
|
|
7
7
|
export { builtinCommands, getCommandsByCategory } from './builtin-commands.js';
|
|
8
|
+
export { CHANNEL_SLASH_SURFACES, channelPlatformsFor, COWORK_TOKEN_SURFACES, COWORK_UNAVAILABLE_REASON, coworkHeadlessAllowlist, coworkUiEffectTokens, isEngineToken, resolveSlashAvailability, withAvailability, } from './surfaces.js';
|
|
9
|
+
export type { ChannelSlashSpec, CoworkTokenMode, SlashCommandWithAvailability } from './surfaces.js';
|
|
@@ -5,4 +5,6 @@
|
|
|
5
5
|
*/
|
|
6
6
|
// Built-in commands
|
|
7
7
|
export { builtinCommands, getCommandsByCategory } from './builtin-commands.js';
|
|
8
|
+
// Per-surface availability (single declaration for CLI, Cowork and the wiki)
|
|
9
|
+
export { CHANNEL_SLASH_SURFACES, channelPlatformsFor, COWORK_TOKEN_SURFACES, COWORK_UNAVAILABLE_REASON, coworkHeadlessAllowlist, coworkUiEffectTokens, isEngineToken, resolveSlashAvailability, withAvailability, } from './surfaces.js';
|
|
8
10
|
//# sourceMappingURL=index.js.map
|