@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
|
@@ -475,6 +475,35 @@ async function recoverJsonLines(filePath, fallback, isValid) {
|
|
|
475
475
|
export function resetAtomicReadWarningsForTests() {
|
|
476
476
|
warnedReadPaths.clear();
|
|
477
477
|
}
|
|
478
|
+
/**
|
|
479
|
+
* Strictly read-only JSON reader for diagnostics. Never restores, renames,
|
|
480
|
+
* chmods, creates, or writes anything — not the primary file, not `.bak`,
|
|
481
|
+
* not `.tmp.*`. Never consults recovery candidates. Callers that need the
|
|
482
|
+
* historical recovery policy must keep using `readJsonAtomicSync`.
|
|
483
|
+
*/
|
|
484
|
+
export function readJsonAtomicSyncReadOnly(filePath, isValid) {
|
|
485
|
+
let contents;
|
|
486
|
+
try {
|
|
487
|
+
contents = fs.readFileSync(filePath, 'utf8');
|
|
488
|
+
}
|
|
489
|
+
catch (error) {
|
|
490
|
+
return isMissing(error) ? { status: 'missing' } : { status: 'unreadable' };
|
|
491
|
+
}
|
|
492
|
+
if (!contents.trim()) {
|
|
493
|
+
return { status: 'corrupt' };
|
|
494
|
+
}
|
|
495
|
+
let value;
|
|
496
|
+
try {
|
|
497
|
+
value = JSON.parse(contents);
|
|
498
|
+
}
|
|
499
|
+
catch {
|
|
500
|
+
return { status: 'corrupt' };
|
|
501
|
+
}
|
|
502
|
+
if (isValid && !isValid(value)) {
|
|
503
|
+
return { status: 'corrupt' };
|
|
504
|
+
}
|
|
505
|
+
return { status: 'ok', value: value };
|
|
506
|
+
}
|
|
478
507
|
const warnedCleanupPaths = new Set();
|
|
479
508
|
/**
|
|
480
509
|
* Remove stale `<filePath>.tmp.*` (and legacy `<filePath>.tmp`) siblings left
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/** Bounded byte storage retaining the beginning and most recent end of output. */
|
|
2
|
+
export declare class BoundedOutput {
|
|
3
|
+
readonly capacity: number;
|
|
4
|
+
private head;
|
|
5
|
+
private tail;
|
|
6
|
+
private observed;
|
|
7
|
+
constructor(capacity?: number);
|
|
8
|
+
get retainedBytes(): number;
|
|
9
|
+
get omittedBytes(): number;
|
|
10
|
+
append(chunk: string | Buffer): void;
|
|
11
|
+
text(): string;
|
|
12
|
+
/** Consume the pending preview; producers can continue into a fresh bounded buffer. */
|
|
13
|
+
drain(): string;
|
|
14
|
+
}
|
|
15
|
+
/** A rendered byte budget, including the omission marker, for model context. */
|
|
16
|
+
export declare function truncateOutput(text: string, maxBytes: number): string;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { StringDecoder } from 'node:string_decoder';
|
|
2
|
+
/** Decode a retained UTF-8 segment without exposing a cut code point. */
|
|
3
|
+
function decode(bytes) {
|
|
4
|
+
let start = 0;
|
|
5
|
+
while (start < bytes.length && (bytes[start] & 0xc0) === 0x80)
|
|
6
|
+
start++;
|
|
7
|
+
return new StringDecoder('utf8').write(bytes.subarray(start));
|
|
8
|
+
}
|
|
9
|
+
/** Bounded byte storage retaining the beginning and most recent end of output. */
|
|
10
|
+
export class BoundedOutput {
|
|
11
|
+
capacity;
|
|
12
|
+
head = Buffer.alloc(0);
|
|
13
|
+
tail = Buffer.alloc(0);
|
|
14
|
+
observed = 0;
|
|
15
|
+
constructor(capacity = 256 * 1024) {
|
|
16
|
+
this.capacity = capacity;
|
|
17
|
+
if (!Number.isSafeInteger(capacity) || capacity < 1)
|
|
18
|
+
throw new Error('Output capacity must be a positive integer');
|
|
19
|
+
}
|
|
20
|
+
get retainedBytes() { return this.head.length + this.tail.length; }
|
|
21
|
+
get omittedBytes() { return this.observed - this.retainedBytes; }
|
|
22
|
+
append(chunk) {
|
|
23
|
+
let bytes = typeof chunk === 'string' ? Buffer.from(chunk) : chunk;
|
|
24
|
+
this.observed += bytes.length;
|
|
25
|
+
const headRemaining = Math.ceil(this.capacity / 2) - this.head.length;
|
|
26
|
+
if (headRemaining > 0) {
|
|
27
|
+
this.head = Buffer.concat([this.head, bytes.subarray(0, headRemaining)]);
|
|
28
|
+
bytes = bytes.subarray(headRemaining);
|
|
29
|
+
}
|
|
30
|
+
const tailCapacity = Math.floor(this.capacity / 2);
|
|
31
|
+
if (tailCapacity > 0 && bytes.length > 0) {
|
|
32
|
+
this.tail = bytes.length >= tailCapacity
|
|
33
|
+
? Buffer.from(bytes.subarray(-tailCapacity))
|
|
34
|
+
: Buffer.concat([this.tail.subarray(Math.max(0, this.tail.length + bytes.length - tailCapacity)), bytes]);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
text() {
|
|
38
|
+
if (!this.omittedBytes)
|
|
39
|
+
return decode(Buffer.concat([this.head, this.tail]));
|
|
40
|
+
return `${decode(this.head)}\n[... ${this.omittedBytes} bytes omitted ...]\n${decode(this.tail)}`;
|
|
41
|
+
}
|
|
42
|
+
/** Consume the pending preview; producers can continue into a fresh bounded buffer. */
|
|
43
|
+
drain() {
|
|
44
|
+
const result = this.text();
|
|
45
|
+
this.head = Buffer.alloc(0);
|
|
46
|
+
this.tail = Buffer.alloc(0);
|
|
47
|
+
this.observed = 0;
|
|
48
|
+
return result;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
/** A rendered byte budget, including the omission marker, for model context. */
|
|
52
|
+
export function truncateOutput(text, maxBytes) {
|
|
53
|
+
if (!Number.isSafeInteger(maxBytes) || maxBytes < 1)
|
|
54
|
+
throw new Error('Output budget must be a positive integer');
|
|
55
|
+
if (Buffer.byteLength(text) <= maxBytes)
|
|
56
|
+
return text;
|
|
57
|
+
if (maxBytes < 80)
|
|
58
|
+
return decode(Buffer.from(text).subarray(0, maxBytes));
|
|
59
|
+
const buffer = new BoundedOutput(maxBytes - 80);
|
|
60
|
+
buffer.append(text);
|
|
61
|
+
return buffer.text();
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=bounded-output.js.map
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/** Shared envelope: legacy SSH/ADB nodes and Android authentication coexist. */
|
|
2
|
+
export declare function readDeviceStoreFile(file: string): Record<string, unknown>;
|
|
3
|
+
/** Cross-process exclusion for the local CLI and server. Busy/crashed locks fail closed. */
|
|
4
|
+
export declare function updateDeviceStoreFile<T>(file: string, update: (data: Record<string, unknown>) => T): T;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { mkdirSync, readFileSync, rmdirSync } from 'node:fs';
|
|
2
|
+
import { dirname } from 'node:path';
|
|
3
|
+
import { writeJsonAtomicSync } from './atomic-write.js';
|
|
4
|
+
/** Shared envelope: legacy SSH/ADB nodes and Android authentication coexist. */
|
|
5
|
+
export function readDeviceStoreFile(file) {
|
|
6
|
+
try {
|
|
7
|
+
const value = JSON.parse(readFileSync(file, 'utf8'));
|
|
8
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
9
|
+
throw new Error('Invalid device store');
|
|
10
|
+
}
|
|
11
|
+
return value;
|
|
12
|
+
}
|
|
13
|
+
catch (error) {
|
|
14
|
+
if (error.code === 'ENOENT')
|
|
15
|
+
return {};
|
|
16
|
+
// Never recover a stale backup: that could resurrect a revoked key.
|
|
17
|
+
throw new Error('Device store unavailable');
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
/** Cross-process exclusion for the local CLI and server. Busy/crashed locks fail closed. */
|
|
21
|
+
export function updateDeviceStoreFile(file, update) {
|
|
22
|
+
mkdirSync(dirname(file), { recursive: true, mode: 0o700 });
|
|
23
|
+
const lock = `${file}.lock`;
|
|
24
|
+
try {
|
|
25
|
+
mkdirSync(lock, { mode: 0o700 });
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
throw new Error('Device store unavailable');
|
|
29
|
+
}
|
|
30
|
+
try {
|
|
31
|
+
const data = readDeviceStoreFile(file);
|
|
32
|
+
const result = update(data);
|
|
33
|
+
writeJsonAtomicSync(file, data, { mode: 0o600 });
|
|
34
|
+
return result;
|
|
35
|
+
}
|
|
36
|
+
finally {
|
|
37
|
+
rmdirSync(lock);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=device-store-file.js.map
|
|
@@ -94,6 +94,15 @@ export declare class ExportManager extends EventEmitter {
|
|
|
94
94
|
filePath?: string;
|
|
95
95
|
error?: string;
|
|
96
96
|
}>;
|
|
97
|
+
/**
|
|
98
|
+
* Export an in-memory conversation (e.g. the live CLI transcript) to a file,
|
|
99
|
+
* with the same redaction and formatting as session exports.
|
|
100
|
+
*/
|
|
101
|
+
exportConversationData(data: ConversationExport, format: ExportFormat, options?: Partial<ExportOptions>, prefix?: string): Promise<{
|
|
102
|
+
success: boolean;
|
|
103
|
+
filePath?: string;
|
|
104
|
+
error?: string;
|
|
105
|
+
}>;
|
|
97
106
|
/**
|
|
98
107
|
* Export session to string
|
|
99
108
|
*/
|
|
@@ -511,6 +511,25 @@ export class ExportManager extends EventEmitter {
|
|
|
511
511
|
return { success: false, error: errorMsg };
|
|
512
512
|
}
|
|
513
513
|
}
|
|
514
|
+
/**
|
|
515
|
+
* Export an in-memory conversation (e.g. the live CLI transcript) to a file,
|
|
516
|
+
* with the same redaction and formatting as session exports.
|
|
517
|
+
*/
|
|
518
|
+
async exportConversationData(data, format, options = {}, prefix = 'conversation') {
|
|
519
|
+
try {
|
|
520
|
+
const content = this.formatExport(data, format, options);
|
|
521
|
+
const filePath = path.join(this.outputDir, this.generateFilename(prefix, format));
|
|
522
|
+
await this.ensureOutputDir();
|
|
523
|
+
await fs.writeFile(filePath, content, 'utf-8');
|
|
524
|
+
this.emit('conversation:exported', { filePath, format });
|
|
525
|
+
return { success: true, filePath };
|
|
526
|
+
}
|
|
527
|
+
catch (error) {
|
|
528
|
+
const errorMsg = error instanceof Error ? error.message : 'Unknown error';
|
|
529
|
+
this.emit('error', error);
|
|
530
|
+
return { success: false, error: errorMsg };
|
|
531
|
+
}
|
|
532
|
+
}
|
|
514
533
|
/**
|
|
515
534
|
* Export session to string
|
|
516
535
|
*/
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* First-use hints (comparatif plan P4, optional part).
|
|
3
|
+
*
|
|
4
|
+
* A short contextual tip shown ONCE per profile, the first time the user meets
|
|
5
|
+
* a surprising behaviour: a command unavailable on this surface, a message
|
|
6
|
+
* queued behind a running turn, a tool output shortened for the model (exact
|
|
7
|
+
* output recoverable through restore_context).
|
|
8
|
+
*
|
|
9
|
+
* Persistence: one marker file per hint under ~/.codebuddy/hints/ created with
|
|
10
|
+
* O_EXCL, so concurrent processes (CLI + Cowork) show a hint at most once.
|
|
11
|
+
* `CODEBUDDY_HINTS=off` disables every hint. Never throws: an unwritable
|
|
12
|
+
* profile means no hint rather than a repeated one.
|
|
13
|
+
*/
|
|
14
|
+
export type FirstUseHintId = 'surface_unavailable' | 'message_queued' | 'restore_context';
|
|
15
|
+
export declare const FIRST_USE_HINTS: Readonly<Record<FirstUseHintId, {
|
|
16
|
+
en: string;
|
|
17
|
+
fr: string;
|
|
18
|
+
}>>;
|
|
19
|
+
export declare function firstUseHintsDir(): string;
|
|
20
|
+
/**
|
|
21
|
+
* Return the hint text the first time `id` is requested in this profile, then
|
|
22
|
+
* null forever. The marker is created before the text is returned.
|
|
23
|
+
*/
|
|
24
|
+
export declare function takeFirstUseHint(id: FirstUseHintId, lang?: 'en' | 'fr', dir?: string): string | null;
|
|
25
|
+
export declare function resetFirstUseHints(dir?: string): void;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* First-use hints (comparatif plan P4, optional part).
|
|
3
|
+
*
|
|
4
|
+
* A short contextual tip shown ONCE per profile, the first time the user meets
|
|
5
|
+
* a surprising behaviour: a command unavailable on this surface, a message
|
|
6
|
+
* queued behind a running turn, a tool output shortened for the model (exact
|
|
7
|
+
* output recoverable through restore_context).
|
|
8
|
+
*
|
|
9
|
+
* Persistence: one marker file per hint under ~/.codebuddy/hints/ created with
|
|
10
|
+
* O_EXCL, so concurrent processes (CLI + Cowork) show a hint at most once.
|
|
11
|
+
* `CODEBUDDY_HINTS=off` disables every hint. Never throws: an unwritable
|
|
12
|
+
* profile means no hint rather than a repeated one.
|
|
13
|
+
*/
|
|
14
|
+
import fs from 'node:fs';
|
|
15
|
+
import os from 'node:os';
|
|
16
|
+
import path from 'node:path';
|
|
17
|
+
export const FIRST_USE_HINTS = Object.freeze({
|
|
18
|
+
surface_unavailable: {
|
|
19
|
+
en: 'Tip: greyed-out commands are not available on this surface yet; run them in the terminal with `buddy`.',
|
|
20
|
+
fr: 'Astuce : les commandes grisées ne sont pas encore pilotables ici ; lance-les dans un terminal avec `buddy`.',
|
|
21
|
+
},
|
|
22
|
+
message_queued: {
|
|
23
|
+
en: 'Tip: this message was queued while Buddy was busy and runs now; messages sent during a turn always run in order.',
|
|
24
|
+
fr: 'Astuce : un message envoyé pendant un tour est mis en file et partira à la fin du tour en cours.',
|
|
25
|
+
},
|
|
26
|
+
restore_context: {
|
|
27
|
+
en: 'Tip: long tool outputs are shortened for the model; the exact output stays recoverable with restore_context.',
|
|
28
|
+
fr: 'Astuce : les longues sorties d’outils sont raccourcies pour le modèle ; la sortie exacte reste récupérable avec restore_context.',
|
|
29
|
+
},
|
|
30
|
+
});
|
|
31
|
+
export function firstUseHintsDir() {
|
|
32
|
+
return process.env.CODEBUDDY_HINTS_DIR || path.join(os.homedir(), '.codebuddy', 'hints');
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Return the hint text the first time `id` is requested in this profile, then
|
|
36
|
+
* null forever. The marker is created before the text is returned.
|
|
37
|
+
*/
|
|
38
|
+
export function takeFirstUseHint(id, lang = 'en', dir = firstUseHintsDir()) {
|
|
39
|
+
if ((process.env.CODEBUDDY_HINTS ?? '').toLowerCase() === 'off')
|
|
40
|
+
return null;
|
|
41
|
+
const hint = FIRST_USE_HINTS[id];
|
|
42
|
+
if (!hint)
|
|
43
|
+
return null;
|
|
44
|
+
try {
|
|
45
|
+
fs.mkdirSync(dir, { recursive: true, mode: 0o700 });
|
|
46
|
+
fs.writeFileSync(path.join(dir, id), `${new Date().toISOString()}\n`, { flag: 'wx', mode: 0o600 });
|
|
47
|
+
return hint[lang];
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
export function resetFirstUseHints(dir = firstUseHintsDir()) {
|
|
54
|
+
for (const id of Object.keys(FIRST_USE_HINTS)) {
|
|
55
|
+
fs.rmSync(path.join(dir, id), { force: true });
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=first-use-hints.js.map
|
|
@@ -29,7 +29,7 @@ export class HistoryManager {
|
|
|
29
29
|
};
|
|
30
30
|
static DEFAULT_CONFIG = {
|
|
31
31
|
maxEntries: 1000, // Increased default limit
|
|
32
|
-
historyFile
|
|
32
|
+
get historyFile() { return path.join(os.homedir(), '.codebuddy', 'history.json'); },
|
|
33
33
|
excludePrefixes: [], // Include all commands by default
|
|
34
34
|
includeSlashCommands: true, // Include slash commands
|
|
35
35
|
};
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Checks for new versions and notifies users (mistral-vibe style).
|
|
5
5
|
*/
|
|
6
|
-
import {
|
|
6
|
+
import { readFileSync } from 'fs';
|
|
7
7
|
import { join } from 'path';
|
|
8
8
|
import { homedir } from 'os';
|
|
9
9
|
import https from 'https';
|
|
@@ -24,27 +24,17 @@ const DEFAULT_CONFIG = {
|
|
|
24
24
|
*/
|
|
25
25
|
function getCurrentVersion() {
|
|
26
26
|
try {
|
|
27
|
-
//
|
|
28
|
-
//
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
// npm global install (node_modules/@phuetz/code-buddy/package.json)
|
|
33
|
-
join(process.execPath, '..', '..', 'lib', 'node_modules', '@phuetz', 'code-buddy', 'package.json'),
|
|
34
|
-
];
|
|
35
|
-
for (const pkgPath of possiblePaths) {
|
|
36
|
-
if (existsSync(pkgPath)) {
|
|
37
|
-
const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
|
|
38
|
-
if (pkg.name?.includes('code-buddy')) {
|
|
39
|
-
return pkg.version || '0.0.0';
|
|
40
|
-
}
|
|
41
|
-
}
|
|
27
|
+
// Resolve our own manifest in both src/utils and dist/utils. The caller's
|
|
28
|
+
// working directory and Node executable do not identify a global npm install.
|
|
29
|
+
const pkg = JSON.parse(readFileSync(new URL('../../package.json', import.meta.url), 'utf-8'));
|
|
30
|
+
if (pkg.name === '@phuetz/code-buddy' && typeof pkg.version === 'string' && pkg.version.trim()) {
|
|
31
|
+
return pkg.version;
|
|
42
32
|
}
|
|
43
|
-
return '0.0.0';
|
|
44
33
|
}
|
|
45
34
|
catch {
|
|
46
|
-
|
|
35
|
+
// An unknown installed version must never produce a fictitious upgrade.
|
|
47
36
|
}
|
|
37
|
+
return null;
|
|
48
38
|
}
|
|
49
39
|
/**
|
|
50
40
|
* Fetch latest version from npm registry
|
|
@@ -147,6 +137,10 @@ export class UpdateNotifier {
|
|
|
147
137
|
return null;
|
|
148
138
|
}
|
|
149
139
|
const currentVersion = getCurrentVersion();
|
|
140
|
+
if (!currentVersion) {
|
|
141
|
+
this.updateInfo = null;
|
|
142
|
+
return null;
|
|
143
|
+
}
|
|
150
144
|
// Check cache first
|
|
151
145
|
const cache = loadCache();
|
|
152
146
|
if (cache && !shouldCheckForUpdates(this.config)) {
|
|
@@ -184,6 +178,10 @@ export class UpdateNotifier {
|
|
|
184
178
|
*/
|
|
185
179
|
async forceCheck() {
|
|
186
180
|
const currentVersion = getCurrentVersion();
|
|
181
|
+
if (!currentVersion) {
|
|
182
|
+
this.updateInfo = null;
|
|
183
|
+
return null;
|
|
184
|
+
}
|
|
187
185
|
const latestVersion = await fetchLatestVersion(this.config.packageName, this.config.registryUrl);
|
|
188
186
|
if (!latestVersion) {
|
|
189
187
|
return null;
|
|
@@ -54,6 +54,8 @@ export declare function detectOllama(): Promise<DetectedCapability>;
|
|
|
54
54
|
export declare function detectLmStudio(): Promise<DetectedCapability>;
|
|
55
55
|
/** Check the ChatGPT (Codex) OAuth credential file. */
|
|
56
56
|
export declare function detectChatGptOAuth(): Promise<DetectedCapability>;
|
|
57
|
+
/** Offline variant: credential presence only, never refreshes tokens. */
|
|
58
|
+
export declare function detectChatGptOAuthOffline(): Promise<DetectedCapability>;
|
|
57
59
|
/** Check the xAI (Grok) OAuth credential file. */
|
|
58
60
|
export declare function detectXaiOAuth(): Promise<DetectedCapability>;
|
|
59
61
|
/** Report API keys present in the environment (not billed to us, so free:false). */
|
|
@@ -62,6 +64,8 @@ export declare function detectApiKeys(): DetectedCapability[];
|
|
|
62
64
|
* One call to learn everything the setup surfaces need. Free local/OAuth probes
|
|
63
65
|
* run in parallel; the API-key scan is synchronous.
|
|
64
66
|
*/
|
|
65
|
-
export declare function detectEnvironment(
|
|
67
|
+
export declare function detectEnvironment(options?: {
|
|
68
|
+
offline?: boolean;
|
|
69
|
+
}): Promise<EnvironmentSnapshot>;
|
|
66
70
|
/** Compact human summary of what was detected — used by wizard + doctor. */
|
|
67
71
|
export declare function renderDetectionSummary(snapshot: EnvironmentSnapshot): string;
|
|
@@ -121,6 +121,40 @@ export async function detectChatGptOAuth() {
|
|
|
121
121
|
return base;
|
|
122
122
|
}
|
|
123
123
|
}
|
|
124
|
+
/** Offline variant: credential presence only, never refreshes tokens. */
|
|
125
|
+
export async function detectChatGptOAuthOffline() {
|
|
126
|
+
const base = {
|
|
127
|
+
id: 'chatgpt',
|
|
128
|
+
label: 'ChatGPT subscription (OAuth, $0)',
|
|
129
|
+
kind: 'oauth',
|
|
130
|
+
free: true,
|
|
131
|
+
available: false,
|
|
132
|
+
detail: 'not signed in',
|
|
133
|
+
setupCommand: 'buddy login',
|
|
134
|
+
};
|
|
135
|
+
try {
|
|
136
|
+
const { hasCodexCredentials } = await import('../providers/codex-oauth.js');
|
|
137
|
+
if (!hasCodexCredentials())
|
|
138
|
+
return base;
|
|
139
|
+
return { ...base, available: true, detail: 'credentials present (not verified offline)', setupCommand: undefined };
|
|
140
|
+
}
|
|
141
|
+
catch {
|
|
142
|
+
return base;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
function notProbedLocalRuntime(id, label, rawHost, setupCommand) {
|
|
146
|
+
const host = normalizeHost(rawHost);
|
|
147
|
+
return Promise.resolve({
|
|
148
|
+
id,
|
|
149
|
+
label,
|
|
150
|
+
kind: 'local',
|
|
151
|
+
free: true,
|
|
152
|
+
available: false,
|
|
153
|
+
detail: 'not probed (--offline)',
|
|
154
|
+
baseURL: `${host}/v1`,
|
|
155
|
+
setupCommand,
|
|
156
|
+
});
|
|
157
|
+
}
|
|
124
158
|
/** Check the xAI (Grok) OAuth credential file. */
|
|
125
159
|
export async function detectXaiOAuth() {
|
|
126
160
|
const base = {
|
|
@@ -167,13 +201,21 @@ export function detectApiKeys() {
|
|
|
167
201
|
* One call to learn everything the setup surfaces need. Free local/OAuth probes
|
|
168
202
|
* run in parallel; the API-key scan is synchronous.
|
|
169
203
|
*/
|
|
170
|
-
export async function detectEnvironment() {
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
204
|
+
export async function detectEnvironment(options = {}) {
|
|
205
|
+
// Offline: no HTTP probe and no OAuth refresh — only local credential files are read.
|
|
206
|
+
const [ollama, lmstudio, chatgpt, xai] = await Promise.all(options.offline
|
|
207
|
+
? [
|
|
208
|
+
notProbedLocalRuntime('ollama', 'Ollama (local, $0)', process.env.OLLAMA_HOST || OLLAMA_DEFAULT_HOST, 'ollama serve'),
|
|
209
|
+
notProbedLocalRuntime('lmstudio', 'LM Studio (local, $0)', process.env.LMSTUDIO_HOST || LMSTUDIO_DEFAULT_HOST, 'Start the LM Studio local server'),
|
|
210
|
+
detectChatGptOAuthOffline(),
|
|
211
|
+
detectXaiOAuth(),
|
|
212
|
+
]
|
|
213
|
+
: [
|
|
214
|
+
detectOllama(),
|
|
215
|
+
detectLmStudio(),
|
|
216
|
+
detectChatGptOAuth(),
|
|
217
|
+
detectXaiOAuth(),
|
|
218
|
+
]);
|
|
177
219
|
const apiKeys = detectApiKeys();
|
|
178
220
|
const capabilities = [ollama, lmstudio, chatgpt, xai, ...apiKeys];
|
|
179
221
|
// Free path priority: a local Ollama that actually has a model → ChatGPT
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import * as readline from 'readline';
|
|
1
2
|
import { type EnvironmentSnapshot } from './environment-detection.js';
|
|
2
3
|
export interface OnboardingResult {
|
|
3
4
|
provider: string;
|
|
@@ -47,7 +48,7 @@ export declare const ONBOARDING_PHASES: OnboardingPhase[];
|
|
|
47
48
|
* - an entered API key → encrypted credential store (never plaintext in settings),
|
|
48
49
|
* plus `process.env[envVar]` so the current process resolves immediately.
|
|
49
50
|
* - ollama → default `OLLAMA_HOST` so auto-detection picks it up.
|
|
50
|
-
*
|
|
51
|
+
* Persistence errors propagate so the wizard cannot report a false success.
|
|
51
52
|
*/
|
|
52
53
|
export declare function persistProviderSelection(guide: OnboardingProviderGuide, model: string, apiKey: string): Promise<void>;
|
|
53
54
|
export declare const PROJECT_FOLDER_QUESTION = "Which project folder should Code Buddy use?";
|
|
@@ -67,4 +68,7 @@ export declare function renderCapabilitiesFooter(): string;
|
|
|
67
68
|
* recommended free path at index 0. Availability annotations are appended to
|
|
68
69
|
* the label so the newcomer sees "(detected)" without extra prose. */
|
|
69
70
|
export declare function orderGuidesByDetection(snapshot: EnvironmentSnapshot): OnboardingProviderGuide[];
|
|
71
|
+
/** Offer to run the isolated 60-second demo right after setup — ending the
|
|
72
|
+
* wizard on proof (a green test), not prose. */
|
|
73
|
+
export declare function offerOnboardingDemo(rl: readline.Interface, result: OnboardingResult): Promise<void>;
|
|
70
74
|
export declare function runOnboarding(): Promise<OnboardingResult | null>;
|