@phuetz/code-buddy 1.1.0 → 1.3.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.md +211 -163
- package/dist/agent/autonomous/agentic-coding-contract.d.ts +12 -12
- package/dist/agent/base-agent.d.ts +4 -0
- package/dist/agent/base-agent.js +6 -0
- package/dist/agent/codebuddy-agent.d.ts +1 -1
- package/dist/agent/codebuddy-agent.js +69 -14
- package/dist/agent/execution/agent-executor.js +122 -12
- package/dist/agent/execution/tool-dependency-graph.js +7 -0
- package/dist/agent/execution/tool-hooks.d.ts +6 -0
- package/dist/agent/execution/tool-hooks.js +13 -5
- package/dist/agent/execution/tool-selection-strategy.d.ts +11 -2
- package/dist/agent/execution/tool-selection-strategy.js +67 -10
- package/dist/agent/extended-thinking.d.ts +8 -0
- package/dist/agent/extended-thinking.js +27 -0
- package/dist/agent/facades/infrastructure-facade.d.ts +9 -2
- package/dist/agent/facades/infrastructure-facade.js +15 -6
- package/dist/agent/hermes-browser-backends.js +151 -11
- package/dist/agent/hermes-claw-migrate.d.ts +59 -0
- package/dist/agent/hermes-claw-migrate.js +427 -26
- package/dist/agent/hermes-parity-manifest.js +78 -71
- package/dist/agent/hermes-runtime-lifecycle.d.ts +67 -0
- package/dist/agent/hermes-runtime-lifecycle.js +468 -0
- package/dist/agent/middleware/index.d.ts +1 -0
- package/dist/agent/middleware/index.js +1 -0
- package/dist/agent/middleware/visual-validation-middleware.d.ts +17 -0
- package/dist/agent/middleware/visual-validation-middleware.js +67 -0
- package/dist/agent/model-benchmark.d.ts +77 -0
- package/dist/agent/model-benchmark.js +309 -0
- package/dist/agent/model-tier.d.ts +14 -0
- package/dist/agent/model-tier.js +71 -0
- package/dist/agent/multi-agent/agents/orchestrator-agent.js +17 -6
- package/dist/agent/multi-agent/multi-agent-system.js +3 -1
- package/dist/agent/multi-agent/session-fleet-bridge.d.ts +2 -0
- package/dist/agent/multi-agent/session-fleet-bridge.js +9 -1
- package/dist/agent/multi-agent/session-tools.js +22 -5
- package/dist/agent/reasoning/mcts.js +20 -6
- package/dist/agent/self-improvement/authored-artifact-gate.d.ts +18 -0
- package/dist/agent/self-improvement/authored-artifact-gate.js +42 -0
- package/dist/agent/self-improvement/authored-tool-runtime.d.ts +27 -0
- package/dist/agent/self-improvement/authored-tool-runtime.js +57 -0
- package/dist/agent/self-improvement/authored-tool-store.d.ts +24 -0
- package/dist/agent/self-improvement/authored-tool-store.js +57 -0
- package/dist/agent/self-improvement/llm-tool-proposer.d.ts +41 -0
- package/dist/agent/self-improvement/llm-tool-proposer.js +136 -0
- package/dist/agent/self-improvement/sandbox-scorer.d.ts +17 -0
- package/dist/agent/self-improvement/sandbox-scorer.js +43 -0
- package/dist/agent/self-improvement/self-knowledge.d.ts +8 -0
- package/dist/agent/self-improvement/self-knowledge.js +24 -0
- package/dist/agent/self-improvement/skill-benchmark.d.ts +9 -0
- package/dist/agent/self-improvement/skill-benchmark.js +22 -0
- package/dist/agent/self-improvement/skill-consolidator.d.ts +71 -0
- package/dist/agent/self-improvement/skill-consolidator.js +137 -0
- package/dist/agent/self-improvement/skill-engine.d.ts +42 -0
- package/dist/agent/self-improvement/skill-engine.js +87 -0
- package/dist/agent/self-improvement/skill-gate.d.ts +19 -0
- package/dist/agent/self-improvement/skill-gate.js +62 -0
- package/dist/agent/self-improvement/skill-mutator.d.ts +74 -0
- package/dist/agent/self-improvement/skill-mutator.js +223 -0
- package/dist/agent/self-improvement/skill-proposer.d.ts +40 -0
- package/dist/agent/self-improvement/skill-proposer.js +82 -0
- package/dist/agent/self-improvement/skill-types.d.ts +41 -0
- package/dist/agent/self-improvement/skill-types.js +13 -0
- package/dist/agent/self-improvement/tool-benchmark.d.ts +10 -0
- package/dist/agent/self-improvement/tool-benchmark.js +37 -0
- package/dist/agent/self-improvement/tool-engine.d.ts +54 -0
- package/dist/agent/self-improvement/tool-engine.js +101 -0
- package/dist/agent/self-improvement/tool-gate.d.ts +20 -0
- package/dist/agent/self-improvement/tool-gate.js +78 -0
- package/dist/agent/self-improvement/tool-proposer.d.ts +31 -0
- package/dist/agent/self-improvement/tool-proposer.js +34 -0
- package/dist/agent/self-improvement/tool-skill-mutator.d.ts +40 -0
- package/dist/agent/self-improvement/tool-skill-mutator.js +79 -0
- package/dist/agent/self-improvement/tool-types.d.ts +48 -0
- package/dist/agent/self-improvement/tool-types.js +9 -0
- package/dist/agent/self-improvement/types.d.ts +3 -1
- package/dist/agent/session-end-flush.d.ts +6 -1
- package/dist/agent/session-end-flush.js +20 -4
- package/dist/agent/streaming/streaming-handler.d.ts +7 -0
- package/dist/agent/streaming/streaming-handler.js +8 -1
- package/dist/agent/tool-executor.js +1 -0
- package/dist/agent/tool-handler.d.ts +5 -0
- package/dist/agent/tool-handler.js +133 -4
- package/dist/browser-automation/browser-operator-executor.js +15 -0
- package/dist/browser-automation/browser-use-runner.d.ts +96 -0
- package/dist/browser-automation/browser-use-runner.js +492 -0
- package/dist/browser-automation/camofox-runner.d.ts +107 -0
- package/dist/browser-automation/camofox-runner.js +287 -0
- package/dist/channels/dingtalk/index.js +3 -0
- package/dist/channels/discord/client.d.ts +9 -0
- package/dist/channels/discord/client.js +12 -0
- package/dist/channels/feishu/index.d.ts +167 -1
- package/dist/channels/feishu/index.js +432 -7
- package/dist/channels/gateway-lifecycle.d.ts +132 -0
- package/dist/channels/gateway-lifecycle.js +219 -0
- package/dist/channels/google-chat/index.d.ts +5 -1
- package/dist/channels/google-chat/index.js +5 -1
- package/dist/channels/imessage/index.d.ts +14 -0
- package/dist/channels/imessage/index.js +64 -17
- package/dist/channels/index.d.ts +4 -0
- package/dist/channels/index.js +4 -0
- package/dist/channels/irc/index.d.ts +73 -3
- package/dist/channels/irc/index.js +446 -11
- package/dist/channels/line/index.js +3 -0
- package/dist/channels/mattermost/index.d.ts +51 -4
- package/dist/channels/mattermost/index.js +303 -20
- package/dist/channels/nextcloud-talk/index.d.ts +89 -8
- package/dist/channels/nextcloud-talk/index.js +367 -16
- package/dist/channels/nostr/index.d.ts +121 -1
- package/dist/channels/nostr/index.js +396 -8
- package/dist/channels/ntfy/index.js +3 -0
- package/dist/channels/qq/index.js +3 -0
- package/dist/channels/slash-parity.d.ts +117 -0
- package/dist/channels/slash-parity.js +185 -0
- package/dist/channels/synology-chat/index.js +3 -0
- package/dist/channels/teams/index.d.ts +3 -0
- package/dist/channels/teams/index.js +3 -0
- package/dist/channels/telegram/client.d.ts +9 -0
- package/dist/channels/telegram/client.js +12 -0
- package/dist/channels/twilio-voice/index.js +3 -0
- package/dist/channels/webchat/index.d.ts +7 -1
- package/dist/channels/webchat/index.js +7 -1
- package/dist/channels/wecom/index.js +3 -0
- package/dist/channels/weixin/index.js +3 -0
- package/dist/channels/zalo/index.js +3 -0
- package/dist/cli/config-loader.js +1 -1
- package/dist/codebuddy/client.d.ts +30 -1
- package/dist/codebuddy/client.js +167 -20
- package/dist/codebuddy/providers/provider-chatgpt-responses.d.ts +5 -0
- package/dist/codebuddy/providers/provider-chatgpt-responses.js +7 -1
- package/dist/codebuddy/providers/provider-gemini-native.js +1 -1
- package/dist/codebuddy/providers/provider-openai-compat.d.ts +5 -0
- package/dist/codebuddy/providers/provider-openai-compat.js +82 -2
- package/dist/codebuddy/tool-definitions/computer-control-tools.js +32 -2
- package/dist/codebuddy/tool-definitions/core-tools.js +3 -3
- package/dist/codebuddy/tool-definitions/index.d.ts +2 -1
- package/dist/codebuddy/tool-definitions/index.js +2 -1
- package/dist/codebuddy/tool-definitions/multimodal-tools.d.ts +1 -0
- package/dist/codebuddy/tool-definitions/multimodal-tools.js +44 -1
- package/dist/codebuddy/tool-definitions/windows-tools.d.ts +2 -0
- package/dist/codebuddy/tool-definitions/windows-tools.js +34 -0
- package/dist/codebuddy/tools.d.ts +8 -1
- package/dist/codebuddy/tools.js +67 -24
- package/dist/commands/cli/hermes-commands.js +108 -0
- package/dist/commands/cli/improve-command.js +123 -0
- package/dist/commands/cli/native-engine-commands.js +102 -3
- package/dist/commands/cli/utility-commands.js +45 -0
- package/dist/commands/enhanced-command-handler.js +2 -2
- package/dist/commands/goal-cli.d.ts +30 -0
- package/dist/commands/goal-cli.js +210 -27
- package/dist/commands/handlers/goal-handler.d.ts +9 -2
- package/dist/commands/handlers/goal-handler.js +36 -9
- package/dist/commands/handlers/infra-handlers.js +36 -0
- package/dist/commands/handlers/memory-handlers.js +96 -1
- package/dist/commands/handlers/missing-handlers.d.ts +1 -1
- package/dist/commands/handlers/missing-handlers.js +26 -3
- package/dist/commands/headless-slash.d.ts +2 -0
- package/dist/commands/headless-slash.js +12 -0
- package/dist/commands/llm-provider-resolution.d.ts +5 -3
- package/dist/commands/llm-provider-resolution.js +87 -33
- package/dist/commands/ollama.d.ts +25 -0
- package/dist/commands/ollama.js +100 -0
- package/dist/commands/provider.d.ts +5 -0
- package/dist/commands/provider.js +106 -55
- package/dist/commands/skills-cli/index.js +123 -0
- package/dist/commands/slash/builtin-commands.js +1 -1
- package/dist/commands/spec-next.js +2 -1
- package/dist/commands/spec-plan.js +5 -16
- package/dist/commands/tunnel.d.ts +2 -0
- package/dist/commands/tunnel.js +48 -0
- package/dist/companion/percepts.js +11 -1
- package/dist/config/config-resolver.d.ts +2 -1
- package/dist/config/config-resolver.js +54 -41
- package/dist/config/constants.d.ts +28 -0
- package/dist/config/constants.js +7 -0
- package/dist/config/env-schema.js +756 -0
- package/dist/config/model-tools.js +4 -4
- package/dist/config/toml-config.d.ts +16 -0
- package/dist/config/toml-config.js +3 -0
- package/dist/context/bootstrap-loader.js +6 -23
- package/dist/context/context-manager-v2.js +1 -0
- package/dist/context/import-directive-parser.d.ts +4 -0
- package/dist/context/import-directive-parser.js +51 -6
- package/dist/context/instruction-excludes.d.ts +30 -1
- package/dist/context/instruction-excludes.js +71 -1
- package/dist/context/jit-context.d.ts +8 -10
- package/dist/context/jit-context.js +28 -106
- package/dist/context/project-context.d.ts +90 -0
- package/dist/context/project-context.js +295 -0
- package/dist/daemon/autonomous-daemon.d.ts +1 -1
- package/dist/daemon/autonomous-daemon.js +3 -3
- package/dist/daemon/autonomous-loop.d.ts +31 -1
- package/dist/daemon/autonomous-loop.js +91 -4
- package/dist/daemon/colab-goal.js +9 -1
- package/dist/daemon/cron-agent-bridge.d.ts +12 -3
- package/dist/daemon/cron-agent-bridge.js +25 -9
- package/dist/desktop/codebuddy-engine-adapter.d.ts +32 -0
- package/dist/desktop/codebuddy-engine-adapter.js +257 -80
- package/dist/desktop/engine-adapter.d.ts +14 -0
- package/dist/desktop-automation/automation-manager.js +16 -0
- package/dist/desktop-automation/omniparser-runner.d.ts +63 -0
- package/dist/desktop-automation/omniparser-runner.js +115 -0
- package/dist/desktop-automation/smart-snapshot.d.ts +11 -0
- package/dist/desktop-automation/smart-snapshot.js +72 -5
- package/dist/doctor/index.js +40 -23
- package/dist/events/types.d.ts +11 -0
- package/dist/fleet/colab-store.js +14 -2
- package/dist/fleet/peer-session-bridge.js +50 -12
- package/dist/fleet/peer-tool-bridge.js +14 -0
- package/dist/goals/goal-decomposer.d.ts +27 -0
- package/dist/goals/goal-decomposer.js +293 -0
- package/dist/goals/goal-judge-client.d.ts +15 -0
- package/dist/goals/goal-judge-client.js +45 -0
- package/dist/goals/goal-judge.d.ts +2 -0
- package/dist/goals/goal-judge.js +35 -6
- package/dist/goals/goal-loop.d.ts +14 -0
- package/dist/goals/goal-loop.js +47 -2
- package/dist/goals/goal-manager.d.ts +6 -0
- package/dist/goals/goal-manager.js +67 -14
- package/dist/goals/goal-state.d.ts +13 -0
- package/dist/goals/goal-state.js +83 -13
- package/dist/goals/goal-store.d.ts +3 -0
- package/dist/goals/goal-store.js +31 -15
- package/dist/harness/contract.d.ts +28 -28
- package/dist/hooks/user-hooks.js +17 -3
- package/dist/identity/identity-manager.js +3 -2
- package/dist/index.js +481 -26
- package/dist/input/text-to-speech.d.ts +2 -6
- package/dist/input/text-to-speech.js +2 -27
- package/dist/integrations/screenpipe/screenpipe-client.d.ts +10 -0
- package/dist/integrations/screenpipe/screenpipe-client.js +12 -2
- package/dist/integrations/tailscale.d.ts +13 -0
- package/dist/integrations/tailscale.js +87 -34
- package/dist/knowledge/workspace-indexer.js +53 -9
- package/dist/mcp/client.js +1 -0
- package/dist/mcp/mcp-desktop-tools.d.ts +23 -0
- package/dist/mcp/mcp-desktop-tools.js +158 -0
- package/dist/mcp/mcp-resources.js +2 -3
- package/dist/mcp/mcp-server.js +2 -0
- package/dist/memory/enhanced-memory.d.ts +10 -0
- package/dist/memory/enhanced-memory.js +33 -2
- package/dist/memory/index.d.ts +3 -1
- package/dist/memory/index.js +4 -1
- package/dist/memory/memory-auto-proposer.d.ts +23 -0
- package/dist/memory/memory-auto-proposer.js +308 -0
- package/dist/memory/memory-candidate-queue.d.ts +92 -0
- package/dist/memory/memory-candidate-queue.js +261 -0
- package/dist/memory/persistent-memory.d.ts +45 -2
- package/dist/memory/persistent-memory.js +236 -40
- package/dist/ml/bayesian-qualifier.d.ts +1 -1
- package/dist/ml/bayesian-qualifier.js +35 -2
- package/dist/openclaw/gateway-bridge.js +5 -0
- package/dist/plugins/marketplace.d.ts +1 -0
- package/dist/plugins/marketplace.js +7 -0
- package/dist/prompts/execution-discipline.d.ts +14 -0
- package/dist/prompts/execution-discipline.js +29 -0
- package/dist/prompts/variation-injector.js +9 -2
- package/dist/protocols/acp/acp-agentic-runner.d.ts +7 -6
- package/dist/protocols/acp/acp-agentic-runner.js +115 -18
- package/dist/protocols/acp/acp-session-store.d.ts +23 -0
- package/dist/protocols/acp/acp-session-store.js +77 -0
- package/dist/protocols/acp/acp-stdio-server.d.ts +7 -0
- package/dist/protocols/acp/acp-stdio-server.js +71 -16
- package/dist/providers/active-llm-registry.d.ts +37 -0
- package/dist/providers/active-llm-registry.js +186 -0
- package/dist/providers/auxiliary-provider.d.ts +25 -0
- package/dist/providers/auxiliary-provider.js +192 -0
- package/dist/providers/codex-oauth.d.ts +1 -1
- package/dist/providers/codex-oauth.js +27 -4
- package/dist/providers/index.d.ts +3 -0
- package/dist/providers/index.js +4 -0
- package/dist/providers/provider-catalog.d.ts +70 -0
- package/dist/providers/provider-catalog.js +738 -0
- package/dist/providers/provider-fallback.d.ts +35 -0
- package/dist/providers/provider-fallback.js +171 -0
- package/dist/providers/xai-oauth.d.ts +128 -0
- package/dist/providers/xai-oauth.js +735 -0
- package/dist/scheduler/cron-scheduler.d.ts +15 -3
- package/dist/scheduler/cron-scheduler.js +53 -7
- package/dist/scheduler/script-runner.d.ts +2 -0
- package/dist/scheduler/script-runner.js +19 -4
- package/dist/scheduler/watchdog-handlers.js +7 -20
- package/dist/search/usearch-index.js +7 -2
- package/dist/security/tool-policy/tool-groups.js +2 -0
- package/dist/sensory/dreaming.d.ts +45 -0
- package/dist/sensory/dreaming.js +114 -0
- package/dist/sensory/heartbeat-scheduler.d.ts +38 -0
- package/dist/sensory/heartbeat-scheduler.js +72 -0
- package/dist/sensory/reactions.d.ts +24 -0
- package/dist/sensory/reactions.js +31 -0
- package/dist/sensory/screen-reaction.d.ts +23 -0
- package/dist/sensory/screen-reaction.js +59 -0
- package/dist/sensory/sensory-bridge.d.ts +23 -0
- package/dist/sensory/sensory-bridge.js +85 -0
- package/dist/sensory/sensory-memory.d.ts +20 -0
- package/dist/sensory/sensory-memory.js +39 -0
- package/dist/sensory/speech-reaction.d.ts +21 -0
- package/dist/sensory/speech-reaction.js +83 -0
- package/dist/sensory/vision-reaction.d.ts +31 -0
- package/dist/sensory/vision-reaction.js +74 -0
- package/dist/server/index.js +106 -2
- package/dist/server/routes/mobile.d.ts +12 -4
- package/dist/server/routes/mobile.js +116 -1
- package/dist/server/tls-config.d.ts +35 -0
- package/dist/server/tls-config.js +142 -0
- package/dist/server/tunnel-manager.d.ts +20 -0
- package/dist/server/tunnel-manager.js +58 -0
- package/dist/server/websocket/fleet-bridge.js +5 -0
- package/dist/services/prompt-builder.d.ts +11 -0
- package/dist/services/prompt-builder.js +124 -17
- package/dist/shared/engine-types.d.ts +15 -1
- package/dist/sidecar/sidecar-bridge.d.ts +1 -0
- package/dist/sidecar/sidecar-bridge.js +21 -10
- package/dist/skills/parser.js +3 -0
- package/dist/skills/skill-importer.d.ts +58 -0
- package/dist/skills/skill-importer.js +261 -0
- package/dist/skills/skill-sources.d.ts +20 -0
- package/dist/skills/skill-sources.js +102 -0
- package/dist/skills/types.d.ts +6 -0
- package/dist/spec/spec-store.js +8 -1
- package/dist/talk-mode/providers/audioreader-tts.d.ts +1 -1
- package/dist/talk-mode/providers/audioreader-tts.js +8 -8
- package/dist/templates/project-scaffolding.js +3 -2
- package/dist/themes/theme-schema.d.ts +10 -10
- package/dist/tools/application-profiles.js +38 -0
- package/dist/tools/bash/bash-tool.d.ts +1 -0
- package/dist/tools/bash/bash-tool.js +16 -2
- package/dist/tools/bash/command-validator.js +3 -0
- package/dist/tools/bash/rtk-rewrite.d.ts +16 -0
- package/dist/tools/bash/rtk-rewrite.js +100 -0
- package/dist/tools/bash/streaming-executor.js +14 -1
- package/dist/tools/computer-control-tool.d.ts +16 -1
- package/dist/tools/computer-control-tool.js +317 -5
- package/dist/tools/document-generator.d.ts +14 -0
- package/dist/tools/document-generator.js +79 -0
- package/dist/tools/execute-code-rpc-invoker.d.ts +26 -2
- package/dist/tools/execute-code-rpc-invoker.js +46 -5
- package/dist/tools/metadata.js +28 -0
- package/dist/tools/office-macro-tool.d.ts +10 -0
- package/dist/tools/office-macro-tool.js +93 -0
- package/dist/tools/register-tool-handler.d.ts +25 -0
- package/dist/tools/register-tool-handler.js +100 -0
- package/dist/tools/registry/index.d.ts +2 -1
- package/dist/tools/registry/index.js +2 -1
- package/dist/tools/registry/memory-tools.d.ts +20 -0
- package/dist/tools/registry/memory-tools.js +225 -3
- package/dist/tools/registry/multimodal-tools.js +2 -2
- package/dist/tools/registry/vision-tools.d.ts +33 -0
- package/dist/tools/registry/vision-tools.js +308 -6
- package/dist/tools/registry/windows-tools.d.ts +2 -0
- package/dist/tools/registry/windows-tools.js +47 -0
- package/dist/tools/registry.d.ts +6 -0
- package/dist/tools/registry.js +8 -0
- package/dist/tools/route-peer-tool.js +14 -0
- package/dist/tools/screenshot-tool.js +14 -2
- package/dist/tools/text-to-speech-tool.d.ts +1 -1
- package/dist/tools/text-to-speech-tool.js +2 -12
- package/dist/tools/tool-selector.js +3 -59
- package/dist/utils/config-validation/schema.d.ts +40 -7
- package/dist/utils/config-validation/schema.js +130 -1
- package/dist/utils/cost-tracker.js +21 -1
- package/dist/utils/disk-guard.d.ts +180 -0
- package/dist/utils/disk-guard.js +404 -0
- package/dist/utils/init-project.d.ts +7 -0
- package/dist/utils/init-project.js +37 -0
- package/dist/utils/interactive-setup.js +35 -2
- package/dist/utils/model-utils.js +11 -2
- package/dist/utils/output-sanitizer.js +11 -0
- package/dist/utils/provider-detector.d.ts +8 -7
- package/dist/utils/provider-detector.js +19 -77
- package/dist/utils/settings-manager.d.ts +19 -0
- package/dist/utils/token-display.d.ts +3 -3
- package/dist/utils/token-display.js +22 -4
- package/dist/wizard/onboarding.d.ts +39 -0
- package/dist/wizard/onboarding.js +433 -21
- package/dist/wizard/provider-onboarding.d.ts +8 -23
- package/dist/wizard/provider-onboarding.js +39 -158
- package/package.json +4 -2
- package/dist/plugins/provider-onboarding.d.ts +0 -23
- package/dist/plugins/provider-onboarding.js +0 -116
- package/dist/utils/kokoro-tts.d.ts +0 -8
- package/dist/utils/kokoro-tts.js +0 -67
|
@@ -405,13 +405,13 @@ const DEFAULT_MODEL_CONFIGS = [
|
|
|
405
405
|
patchFormat: 'full_file',
|
|
406
406
|
promptProfile: 'lite',
|
|
407
407
|
},
|
|
408
|
-
// Gemma 4 (Ollama, e2b/e4b) — local
|
|
409
|
-
// profile
|
|
410
|
-
//
|
|
408
|
+
// Gemma 4 (Ollama, e2b/e4b) — local model with tool support. Keep the
|
|
409
|
+
// lite prompt/tool profile, but do not gate off tool calls: real `buddy goal`
|
|
410
|
+
// smoke with gemma4:12b only succeeds when the selected tools are preserved.
|
|
411
411
|
{
|
|
412
412
|
model: 'gemma4*',
|
|
413
413
|
supportsReasoning: false,
|
|
414
|
-
supportsToolCalls:
|
|
414
|
+
supportsToolCalls: true,
|
|
415
415
|
supportsVision: false,
|
|
416
416
|
contextWindow: 8192,
|
|
417
417
|
maxOutputTokens: 2048,
|
|
@@ -122,6 +122,20 @@ export interface ModelPairsConfig {
|
|
|
122
122
|
/** Model used for code edits and execution (the "doer") */
|
|
123
123
|
editor?: string;
|
|
124
124
|
}
|
|
125
|
+
/** Active-LLM registry: auto-failover across the user's live logins + "together". */
|
|
126
|
+
export interface LlmFailoverConfig {
|
|
127
|
+
/** Master gate. OFF by default — single-provider behavior is unchanged. */
|
|
128
|
+
enabled?: boolean;
|
|
129
|
+
/** Fallback ordering: 'resilience' (capable/subscription first, local last),
|
|
130
|
+
* 'free-first' (cheapest first), or 'manual' (explicit `manualOrder`). */
|
|
131
|
+
order?: 'resilience' | 'free-first' | 'manual';
|
|
132
|
+
/** Provider ids in preferred order when `order: 'manual'`. */
|
|
133
|
+
manualOrder?: string[];
|
|
134
|
+
/** Restrict the active set to local runtimes (privacy). */
|
|
135
|
+
local_only?: boolean;
|
|
136
|
+
/** Default strategy for `/llm ensemble` (Phase 2). */
|
|
137
|
+
together_strategy?: 'ensemble' | 'consensus' | 'fastest' | 'cascade';
|
|
138
|
+
}
|
|
125
139
|
/**
|
|
126
140
|
* External integrations configuration
|
|
127
141
|
*/
|
|
@@ -497,6 +511,8 @@ export interface CodeBuddyConfig {
|
|
|
497
511
|
integrations: IntegrationsConfig;
|
|
498
512
|
/** Model pairs for architect/editor split */
|
|
499
513
|
model_pairs?: ModelPairsConfig;
|
|
514
|
+
/** Active-LLM registry: auto-failover across live logins + "together" */
|
|
515
|
+
llm?: LlmFailoverConfig;
|
|
500
516
|
/** Agent defaults (model preferences) — Native Engine v2026.3.14 */
|
|
501
517
|
agent_defaults?: AgentDefaultsConfig;
|
|
502
518
|
/** Advisor tool settings (second opinion model) — V4.1 */
|
|
@@ -540,6 +540,9 @@ class ConfigManager {
|
|
|
540
540
|
if (partial.model_pairs) {
|
|
541
541
|
this.config.model_pairs = { ...this.config.model_pairs, ...partial.model_pairs };
|
|
542
542
|
}
|
|
543
|
+
if (partial.llm) {
|
|
544
|
+
this.config.llm = { ...this.config.llm, ...partial.llm };
|
|
545
|
+
}
|
|
543
546
|
}
|
|
544
547
|
/**
|
|
545
548
|
* Get current config
|
|
@@ -15,10 +15,12 @@ import { logger } from '../utils/logger.js';
|
|
|
15
15
|
// ============================================================================
|
|
16
16
|
// Defaults
|
|
17
17
|
// ============================================================================
|
|
18
|
+
// AGENTS.md is intentionally NOT here — instruction files (AGENTS/CODEBUDDY/
|
|
19
|
+
// CONTEXT/INSTRUCTIONS) are owned by the unified project-context loader
|
|
20
|
+
// (src/context/project-context.ts). This loader covers soul/identity files.
|
|
18
21
|
const DEFAULT_BOOTSTRAP_FILES = [
|
|
19
22
|
'BOOT.md',
|
|
20
23
|
'BOOTSTRAP.md',
|
|
21
|
-
'AGENTS.md',
|
|
22
24
|
'SOUL.md',
|
|
23
25
|
// TOOLS.md excluded: tool descriptions are already sent as function definitions
|
|
24
26
|
'IDENTITY.md',
|
|
@@ -80,28 +82,9 @@ export class BootstrapLoader {
|
|
|
80
82
|
sources.push(content.source);
|
|
81
83
|
totalChars += text.length;
|
|
82
84
|
}
|
|
83
|
-
//
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
for (const entry of hierarchicalResult) {
|
|
87
|
-
if (totalChars >= this.config.maxChars) {
|
|
88
|
-
truncated = true;
|
|
89
|
-
break;
|
|
90
|
-
}
|
|
91
|
-
if (sources.includes(entry.source))
|
|
92
|
-
continue;
|
|
93
|
-
const remaining = this.config.maxChars - totalChars;
|
|
94
|
-
let text = entry.text;
|
|
95
|
-
if (text.length > remaining) {
|
|
96
|
-
text = text.slice(0, remaining) + '\n\n... (truncated)';
|
|
97
|
-
truncated = true;
|
|
98
|
-
}
|
|
99
|
-
const relSource = path.relative(cwd, entry.source) || entry.source;
|
|
100
|
-
sections.push(`## ${entry.fileName} (${relSource})\n\n${text}`);
|
|
101
|
-
sources.push(entry.source);
|
|
102
|
-
totalChars += text.length;
|
|
103
|
-
}
|
|
104
|
-
}
|
|
85
|
+
// (Instruction-file hierarchy — AGENTS/CODEBUDDY/CONTEXT/INSTRUCTIONS — is
|
|
86
|
+
// now handled by the unified project-context loader, injected before this
|
|
87
|
+
// block in prompt-builder. `loadHierarchical` below is retained but unused.)
|
|
105
88
|
// 3. Auto-generated project knowledge (from /docs generate --with-llm)
|
|
106
89
|
if (totalChars < this.config.maxChars) {
|
|
107
90
|
const knowledgePath = path.join(cwd, '.codebuddy', 'PROJECT_KNOWLEDGE.md');
|
|
@@ -27,6 +27,10 @@ export interface ImportResolveOptions {
|
|
|
27
27
|
depth?: number;
|
|
28
28
|
/** Set of already-visited absolute paths (cycle detection) */
|
|
29
29
|
visited?: Set<string>;
|
|
30
|
+
/** Max recursion depth for nested imports (default 5) */
|
|
31
|
+
maxDepth?: number;
|
|
32
|
+
/** Max total content size after imports, in chars (default 50000) */
|
|
33
|
+
maxBytes?: number;
|
|
30
34
|
}
|
|
31
35
|
/**
|
|
32
36
|
* Resolve all @import directives in the given content.
|
|
@@ -43,14 +43,23 @@ const IMPORT_DIRECTIVE_REGEX = /^@(~\/|\/\/|[^\s@].+?)$/gm;
|
|
|
43
43
|
* @returns Content with all imports resolved inline
|
|
44
44
|
*/
|
|
45
45
|
export function resolveImportDirectives(content, options) {
|
|
46
|
-
const { baseDir, projectRoot = process.cwd(), homeDir = process.env.HOME || process.env.USERPROFILE || '', depth = 0, visited = new Set(), } = options;
|
|
47
|
-
if (depth >=
|
|
48
|
-
logger.debug(`Import directive: max depth ${
|
|
46
|
+
const { baseDir, projectRoot = process.cwd(), homeDir = process.env.HOME || process.env.USERPROFILE || '', depth = 0, visited = new Set(), maxDepth = MAX_IMPORT_DEPTH, maxBytes = MAX_IMPORT_CONTENT, } = options;
|
|
47
|
+
if (depth >= maxDepth) {
|
|
48
|
+
logger.debug(`Import directive: max depth ${maxDepth} reached, skipping further imports`);
|
|
49
49
|
return content;
|
|
50
50
|
}
|
|
51
51
|
let result = content;
|
|
52
52
|
let totalSize = content.length;
|
|
53
|
-
|
|
53
|
+
// Mask code regions so an @path directive that sits inside a fenced block or
|
|
54
|
+
// inline code span is left as literal content, not resolved as an import.
|
|
55
|
+
// Matches Claude Code / Gemini CLI semantics (a code example that mentions
|
|
56
|
+
// `@./foo.md` must not trigger a file read).
|
|
57
|
+
const codeRegions = findCodeRegions(content);
|
|
58
|
+
result = result.replace(IMPORT_DIRECTIVE_REGEX, (fullMatch, importPath, offset) => {
|
|
59
|
+
// Leave directives inside code spans/fences untouched.
|
|
60
|
+
if (isInsideRegion(offset, codeRegions)) {
|
|
61
|
+
return fullMatch;
|
|
62
|
+
}
|
|
54
63
|
// Resolve the import path
|
|
55
64
|
const resolvedPath = resolveImportPath(importPath.trim(), baseDir, projectRoot, homeDir);
|
|
56
65
|
if (!resolvedPath) {
|
|
@@ -71,9 +80,9 @@ export function resolveImportDirectives(content, options) {
|
|
|
71
80
|
try {
|
|
72
81
|
let importedContent = fs.readFileSync(absolutePath, 'utf-8');
|
|
73
82
|
// Size guard
|
|
74
|
-
if (totalSize + importedContent.length >
|
|
83
|
+
if (totalSize + importedContent.length > maxBytes) {
|
|
75
84
|
logger.debug(`Import directive: size limit reached, truncating "${importPath}"`);
|
|
76
|
-
const remaining =
|
|
85
|
+
const remaining = maxBytes - totalSize;
|
|
77
86
|
if (remaining <= 0) {
|
|
78
87
|
return `<!-- import truncated: ${importPath} -->`;
|
|
79
88
|
}
|
|
@@ -88,6 +97,8 @@ export function resolveImportDirectives(content, options) {
|
|
|
88
97
|
homeDir,
|
|
89
98
|
depth: depth + 1,
|
|
90
99
|
visited: newVisited,
|
|
100
|
+
maxDepth,
|
|
101
|
+
maxBytes,
|
|
91
102
|
});
|
|
92
103
|
totalSize += resolved.length;
|
|
93
104
|
logger.debug(`Import directive: resolved "${importPath}" (${resolved.length} chars)`);
|
|
@@ -129,4 +140,38 @@ function resolveImportPath(importPath, baseDir, projectRoot, homeDir) {
|
|
|
129
140
|
return null;
|
|
130
141
|
}
|
|
131
142
|
}
|
|
143
|
+
// ============================================================================
|
|
144
|
+
// Code-region masking (so @imports inside code are inert)
|
|
145
|
+
// ============================================================================
|
|
146
|
+
/**
|
|
147
|
+
* Find all code spans/fences in the content as [start, end) ranges.
|
|
148
|
+
*
|
|
149
|
+
* Covers backtick code — inline `` `…` `` and fenced ```` ```…``` ```` (one or
|
|
150
|
+
* more backticks, closed by the same count) — plus `~~~` fenced blocks. An
|
|
151
|
+
* @import directive whose `@` falls inside any of these ranges is treated as
|
|
152
|
+
* literal text. Mirrors the gemini-cli memory import processor.
|
|
153
|
+
*/
|
|
154
|
+
function findCodeRegions(content) {
|
|
155
|
+
const regions = [];
|
|
156
|
+
// Backtick inline + fenced: one or more backticks, lazily to the same run.
|
|
157
|
+
const backtick = /(`+)([\s\S]*?)\1/g;
|
|
158
|
+
let m;
|
|
159
|
+
while ((m = backtick.exec(content)) !== null) {
|
|
160
|
+
regions.push([m.index, m.index + m[0].length]);
|
|
161
|
+
}
|
|
162
|
+
// Tilde fenced blocks: a line of >=3 tildes, content, closing tilde line.
|
|
163
|
+
const tilde = /^[^\S\n]*(~{3,})[^\n]*\n[\s\S]*?\n[^\S\n]*\1[^\S\n]*$/gm;
|
|
164
|
+
while ((m = tilde.exec(content)) !== null) {
|
|
165
|
+
regions.push([m.index, m.index + m[0].length]);
|
|
166
|
+
}
|
|
167
|
+
return regions;
|
|
168
|
+
}
|
|
169
|
+
/** True if `offset` lies within any [start, end) code region. */
|
|
170
|
+
function isInsideRegion(offset, regions) {
|
|
171
|
+
for (const [start, end] of regions) {
|
|
172
|
+
if (offset >= start && offset < end)
|
|
173
|
+
return true;
|
|
174
|
+
}
|
|
175
|
+
return false;
|
|
176
|
+
}
|
|
132
177
|
//# sourceMappingURL=import-directive-parser.js.map
|
|
@@ -7,9 +7,38 @@
|
|
|
7
7
|
* Advanced enterprise architecture for claudeMdExcludes setting.
|
|
8
8
|
*/
|
|
9
9
|
/**
|
|
10
|
-
* Clear the excludes cache (for testing).
|
|
10
|
+
* Clear the excludes cache (for testing / config reload).
|
|
11
11
|
*/
|
|
12
12
|
export declare function clearExcludesCache(): void;
|
|
13
|
+
/**
|
|
14
|
+
* Clear the context-config cache (for testing / `/context reload`).
|
|
15
|
+
*/
|
|
16
|
+
export declare function clearContextConfigCache(): void;
|
|
17
|
+
/**
|
|
18
|
+
* Accepted project-instruction filenames, in precedence order. `AGENTS.md` is
|
|
19
|
+
* the cross-CLI primary (read by Codex/Cursor/Copilot/Claude Code); the rest
|
|
20
|
+
* are read for interop. All present names compose within a directory.
|
|
21
|
+
*/
|
|
22
|
+
export declare const DEFAULT_CONTEXT_FILE_NAMES: readonly string[];
|
|
23
|
+
export interface ResolvedContextConfig {
|
|
24
|
+
/** Accepted instruction filenames, in precedence order. */
|
|
25
|
+
fileNames: string[];
|
|
26
|
+
/** Total byte budget for the startup hierarchy (Codex project_doc_max_bytes parity). */
|
|
27
|
+
maxBytes: number;
|
|
28
|
+
/** Per-touch incremental byte budget for JIT discovery. */
|
|
29
|
+
jitMaxBytes: number;
|
|
30
|
+
/** Byte budget passed to the @import resolver. */
|
|
31
|
+
importMaxBytes: number;
|
|
32
|
+
/** Max recursion depth for @import. */
|
|
33
|
+
importMaxDepth: number;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Load the `context` block from `.codebuddy/settings.json`, merged over
|
|
37
|
+
* defaults. Cached by settings path (cleared via `clearContextConfigCache()`).
|
|
38
|
+
* A missing `context` key returns the defaults, so existing projects are
|
|
39
|
+
* unaffected.
|
|
40
|
+
*/
|
|
41
|
+
export declare function loadContextConfig(projectRoot?: string): ResolvedContextConfig;
|
|
13
42
|
/**
|
|
14
43
|
* Load exclude patterns from settings.json.
|
|
15
44
|
* Returns an array of glob patterns (e.g., ["packages/legacy/**"]).
|
|
@@ -15,13 +15,83 @@ import { logger } from '../utils/logger.js';
|
|
|
15
15
|
// ============================================================================
|
|
16
16
|
let _excludePatterns = null;
|
|
17
17
|
let _excludeCachePath = null;
|
|
18
|
+
let _contextConfig = null;
|
|
19
|
+
let _contextConfigCachePath = null;
|
|
18
20
|
/**
|
|
19
|
-
* Clear the excludes cache (for testing).
|
|
21
|
+
* Clear the excludes cache (for testing / config reload).
|
|
20
22
|
*/
|
|
21
23
|
export function clearExcludesCache() {
|
|
22
24
|
_excludePatterns = null;
|
|
23
25
|
_excludeCachePath = null;
|
|
24
26
|
}
|
|
27
|
+
/**
|
|
28
|
+
* Clear the context-config cache (for testing / `/context reload`).
|
|
29
|
+
*/
|
|
30
|
+
export function clearContextConfigCache() {
|
|
31
|
+
_contextConfig = null;
|
|
32
|
+
_contextConfigCachePath = null;
|
|
33
|
+
}
|
|
34
|
+
// ============================================================================
|
|
35
|
+
// Context-file configuration (single source of truth for accepted filenames)
|
|
36
|
+
// ============================================================================
|
|
37
|
+
/**
|
|
38
|
+
* Accepted project-instruction filenames, in precedence order. `AGENTS.md` is
|
|
39
|
+
* the cross-CLI primary (read by Codex/Cursor/Copilot/Claude Code); the rest
|
|
40
|
+
* are read for interop. All present names compose within a directory.
|
|
41
|
+
*/
|
|
42
|
+
export const DEFAULT_CONTEXT_FILE_NAMES = [
|
|
43
|
+
'AGENTS.md',
|
|
44
|
+
'CODEBUDDY.md',
|
|
45
|
+
'CLAUDE.md',
|
|
46
|
+
'GEMINI.md',
|
|
47
|
+
'CONTEXT.md',
|
|
48
|
+
'INSTRUCTIONS.md',
|
|
49
|
+
];
|
|
50
|
+
const DEFAULT_CONTEXT_CONFIG = {
|
|
51
|
+
fileNames: [...DEFAULT_CONTEXT_FILE_NAMES],
|
|
52
|
+
maxBytes: 32_768,
|
|
53
|
+
jitMaxBytes: 4_096,
|
|
54
|
+
importMaxBytes: 50_000,
|
|
55
|
+
importMaxDepth: 5,
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* Load the `context` block from `.codebuddy/settings.json`, merged over
|
|
59
|
+
* defaults. Cached by settings path (cleared via `clearContextConfigCache()`).
|
|
60
|
+
* A missing `context` key returns the defaults, so existing projects are
|
|
61
|
+
* unaffected.
|
|
62
|
+
*/
|
|
63
|
+
export function loadContextConfig(projectRoot = process.cwd()) {
|
|
64
|
+
const settingsPath = path.join(projectRoot, '.codebuddy', 'settings.json');
|
|
65
|
+
if (_contextConfig && _contextConfigCachePath === settingsPath) {
|
|
66
|
+
return _contextConfig;
|
|
67
|
+
}
|
|
68
|
+
const cfg = { ...DEFAULT_CONTEXT_CONFIG, fileNames: [...DEFAULT_CONTEXT_FILE_NAMES] };
|
|
69
|
+
if (fs.existsSync(settingsPath)) {
|
|
70
|
+
try {
|
|
71
|
+
const raw = fs.readFileSync(settingsPath, 'utf-8');
|
|
72
|
+
const ctx = JSON.parse(raw)?.context;
|
|
73
|
+
if (ctx && typeof ctx === 'object') {
|
|
74
|
+
if (Array.isArray(ctx.fileNames) && ctx.fileNames.every((n) => typeof n === 'string') && ctx.fileNames.length > 0) {
|
|
75
|
+
cfg.fileNames = ctx.fileNames;
|
|
76
|
+
}
|
|
77
|
+
if (Number.isFinite(ctx.maxBytes) && ctx.maxBytes > 0)
|
|
78
|
+
cfg.maxBytes = ctx.maxBytes;
|
|
79
|
+
if (Number.isFinite(ctx.jitMaxBytes) && ctx.jitMaxBytes > 0)
|
|
80
|
+
cfg.jitMaxBytes = ctx.jitMaxBytes;
|
|
81
|
+
if (Number.isFinite(ctx.importMaxBytes) && ctx.importMaxBytes > 0)
|
|
82
|
+
cfg.importMaxBytes = ctx.importMaxBytes;
|
|
83
|
+
if (Number.isFinite(ctx.importMaxDepth) && ctx.importMaxDepth > 0)
|
|
84
|
+
cfg.importMaxDepth = ctx.importMaxDepth;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
catch (err) {
|
|
88
|
+
logger.debug(`Failed to load context config: ${err}`);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
_contextConfig = cfg;
|
|
92
|
+
_contextConfigCachePath = settingsPath;
|
|
93
|
+
return cfg;
|
|
94
|
+
}
|
|
25
95
|
// ============================================================================
|
|
26
96
|
// Loader
|
|
27
97
|
// ============================================================================
|
|
@@ -1,24 +1,22 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* JIT (Just-In-Time) Context Discovery
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* When a tool accesses a path, this loads the instruction files in that
|
|
5
|
+
* subtree that weren't already injected at startup (delegated to the unified
|
|
6
|
+
* `project-context` loader, sharing its dedup registry), plus two JIT-only
|
|
7
|
+
* concerns: auto-discovered doc pages (DOC_DIR_MAP) and path-scoped rules.
|
|
7
8
|
*
|
|
8
|
-
* Inspired by Gemini CLI's jit-context.
|
|
9
|
+
* Inspired by Gemini CLI's jit-context.
|
|
9
10
|
*/
|
|
10
11
|
export declare const JIT_CONTEXT_PREFIX = "\n\n--- Discovered Context ---\n";
|
|
11
12
|
export declare const JIT_CONTEXT_SUFFIX = "\n--- End Context ---";
|
|
12
13
|
/**
|
|
13
|
-
* Clear
|
|
14
|
+
* Clear caches (for testing / `/context reload`). Resets both the doc dedup set
|
|
15
|
+
* and the active context registry so the next pass re-scans from scratch.
|
|
14
16
|
*/
|
|
15
17
|
export declare function clearJitCache(): void;
|
|
16
18
|
/**
|
|
17
|
-
* Discover and load context
|
|
18
|
-
*
|
|
19
|
-
* Walks upward from the accessed file's directory to the project root,
|
|
20
|
-
* checking for context files at each level. Only loads files that
|
|
21
|
-
* haven't been loaded before in this session.
|
|
19
|
+
* Discover and load JIT context for a given accessed path.
|
|
22
20
|
*
|
|
23
21
|
* @param accessedPath - The file/directory path being accessed by a tool
|
|
24
22
|
* @param projectRoot - The project root directory (stop walking here)
|
|
@@ -1,28 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* JIT (Just-In-Time) Context Discovery
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* When a tool accesses a path, this loads the instruction files in that
|
|
5
|
+
* subtree that weren't already injected at startup (delegated to the unified
|
|
6
|
+
* `project-context` loader, sharing its dedup registry), plus two JIT-only
|
|
7
|
+
* concerns: auto-discovered doc pages (DOC_DIR_MAP) and path-scoped rules.
|
|
7
8
|
*
|
|
8
|
-
* Inspired by Gemini CLI's jit-context.
|
|
9
|
+
* Inspired by Gemini CLI's jit-context.
|
|
9
10
|
*/
|
|
10
11
|
import * as fs from 'fs';
|
|
11
12
|
import * as path from 'path';
|
|
12
13
|
import { logger } from '../utils/logger.js';
|
|
13
14
|
import { discoverRulesForPath } from './rules-loader.js';
|
|
14
|
-
import {
|
|
15
|
-
import { resolveImportDirectives } from './import-directive-parser.js';
|
|
16
|
-
/** Context file names to discover */
|
|
17
|
-
const CONTEXT_FILES = [
|
|
18
|
-
'CODEBUDDY.md',
|
|
19
|
-
'CONTEXT.md',
|
|
20
|
-
'INSTRUCTIONS.md',
|
|
21
|
-
'AGENTS.md',
|
|
22
|
-
'README.md',
|
|
23
|
-
];
|
|
24
|
-
/** Directories that may contain context files */
|
|
25
|
-
const CONTEXT_DIRS = ['.codebuddy', '.claude'];
|
|
15
|
+
import { resolveJitContext, getActiveContextRegistry } from './project-context.js';
|
|
26
16
|
/**
|
|
27
17
|
* Map of source directory prefixes → relevant doc page slugs.
|
|
28
18
|
* When a tool accesses a path under a key, the matching doc is auto-discovered.
|
|
@@ -45,26 +35,22 @@ const DOC_DIR_MAP = {
|
|
|
45
35
|
'src/checkpoints': ['architecture'],
|
|
46
36
|
'tests': ['testing'],
|
|
47
37
|
};
|
|
48
|
-
/** Set of already-loaded paths (
|
|
38
|
+
/** Set of already-loaded doc paths (instruction files dedup via the registry). */
|
|
49
39
|
const loadedPaths = new Set();
|
|
50
40
|
/** Maximum context size per discovery (chars) */
|
|
51
41
|
const MAX_JIT_CONTEXT_CHARS = 4000;
|
|
52
|
-
/** Maximum directory depth to traverse upward */
|
|
53
|
-
const MAX_UPWARD_DEPTH = 10;
|
|
54
42
|
export const JIT_CONTEXT_PREFIX = '\n\n--- Discovered Context ---\n';
|
|
55
43
|
export const JIT_CONTEXT_SUFFIX = '\n--- End Context ---';
|
|
56
44
|
/**
|
|
57
|
-
* Clear
|
|
45
|
+
* Clear caches (for testing / `/context reload`). Resets both the doc dedup set
|
|
46
|
+
* and the active context registry so the next pass re-scans from scratch.
|
|
58
47
|
*/
|
|
59
48
|
export function clearJitCache() {
|
|
60
49
|
loadedPaths.clear();
|
|
50
|
+
getActiveContextRegistry().clear();
|
|
61
51
|
}
|
|
62
52
|
/**
|
|
63
|
-
* Discover and load context
|
|
64
|
-
*
|
|
65
|
-
* Walks upward from the accessed file's directory to the project root,
|
|
66
|
-
* checking for context files at each level. Only loads files that
|
|
67
|
-
* haven't been loaded before in this session.
|
|
53
|
+
* Discover and load JIT context for a given accessed path.
|
|
68
54
|
*
|
|
69
55
|
* @param accessedPath - The file/directory path being accessed by a tool
|
|
70
56
|
* @param projectRoot - The project root directory (stop walking here)
|
|
@@ -74,84 +60,18 @@ export function discoverJitContext(accessedPath, projectRoot = process.cwd()) {
|
|
|
74
60
|
try {
|
|
75
61
|
const normalizedRoot = path.resolve(projectRoot);
|
|
76
62
|
const normalizedPath = path.resolve(accessedPath);
|
|
77
|
-
// Start from the accessed file's directory
|
|
78
|
-
let currentDir = fs.existsSync(normalizedPath) && fs.statSync(normalizedPath).isDirectory()
|
|
79
|
-
? normalizedPath
|
|
80
|
-
: path.dirname(normalizedPath);
|
|
81
63
|
const discoveredContent = [];
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
if (!loadedPaths.has(filePath) && fs.existsSync(filePath)) {
|
|
92
|
-
// CC10: Check instruction excludes
|
|
93
|
-
if (shouldExcludeInstructionFile(filePath, normalizedRoot)) {
|
|
94
|
-
logger.debug(`JIT context: excluded ${path.relative(normalizedRoot, filePath)}`);
|
|
95
|
-
loadedPaths.add(filePath); // Mark as "seen" to avoid re-checking
|
|
96
|
-
continue;
|
|
97
|
-
}
|
|
98
|
-
try {
|
|
99
|
-
let content = fs.readFileSync(filePath, 'utf-8');
|
|
100
|
-
if (content.trim()) {
|
|
101
|
-
// CC9: Resolve @import directives
|
|
102
|
-
content = resolveImportDirectives(content, {
|
|
103
|
-
baseDir: path.dirname(filePath),
|
|
104
|
-
projectRoot: normalizedRoot,
|
|
105
|
-
});
|
|
106
|
-
const relativePath = path.relative(normalizedRoot, filePath).replace(/\\/g, '/');
|
|
107
|
-
discoveredContent.push(`[${relativePath}]\n${content.trim()}`);
|
|
108
|
-
loadedPaths.add(filePath);
|
|
109
|
-
logger.debug(`JIT context: loaded ${relativePath}`);
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
catch { /* read error — skip */ }
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
// Also check .codebuddy/ and .claude/ subdirectories
|
|
116
|
-
for (const contextDir of CONTEXT_DIRS) {
|
|
117
|
-
const dirPath = path.join(currentDir, contextDir);
|
|
118
|
-
if (fs.existsSync(dirPath) && fs.statSync(dirPath).isDirectory()) {
|
|
119
|
-
for (const contextFile of CONTEXT_FILES) {
|
|
120
|
-
const filePath = path.join(dirPath, contextFile);
|
|
121
|
-
if (!loadedPaths.has(filePath) && fs.existsSync(filePath)) {
|
|
122
|
-
// CC10: Check instruction excludes
|
|
123
|
-
if (shouldExcludeInstructionFile(filePath, normalizedRoot)) {
|
|
124
|
-
logger.debug(`JIT context: excluded ${path.relative(normalizedRoot, filePath)}`);
|
|
125
|
-
loadedPaths.add(filePath);
|
|
126
|
-
continue;
|
|
127
|
-
}
|
|
128
|
-
try {
|
|
129
|
-
let content = fs.readFileSync(filePath, 'utf-8');
|
|
130
|
-
if (content.trim()) {
|
|
131
|
-
// CC9: Resolve @import directives
|
|
132
|
-
content = resolveImportDirectives(content, {
|
|
133
|
-
baseDir: path.dirname(filePath),
|
|
134
|
-
projectRoot: normalizedRoot,
|
|
135
|
-
});
|
|
136
|
-
const relativePath = path.relative(normalizedRoot, filePath).replace(/\\/g, '/');
|
|
137
|
-
discoveredContent.push(`[${relativePath}]\n${content.trim()}`);
|
|
138
|
-
loadedPaths.add(filePath);
|
|
139
|
-
logger.debug(`JIT context: loaded ${relativePath}`);
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
catch { /* read error — skip */ }
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
// Move up
|
|
148
|
-
const parent = path.dirname(currentDir);
|
|
149
|
-
if (parent === currentDir)
|
|
150
|
-
break; // reached filesystem root
|
|
151
|
-
currentDir = parent;
|
|
152
|
-
depth++;
|
|
64
|
+
// 1. Instruction files in the accessed subtree, via the unified loader.
|
|
65
|
+
// The shared active registry skips anything already injected at startup,
|
|
66
|
+
// so the same AGENTS.md/CODEBUDDY.md is never duplicated.
|
|
67
|
+
const ctx = resolveJitContext(accessedPath, {
|
|
68
|
+
projectRoot: normalizedRoot,
|
|
69
|
+
registry: getActiveContextRegistry(),
|
|
70
|
+
});
|
|
71
|
+
if (ctx.text) {
|
|
72
|
+
discoveredContent.push(ctx.text);
|
|
153
73
|
}
|
|
154
|
-
// Auto-discover relevant doc pages based on accessed path
|
|
74
|
+
// 2. Auto-discover relevant doc pages based on the accessed path.
|
|
155
75
|
const relativePath = path.relative(normalizedRoot, normalizedPath).replace(/\\/g, '/');
|
|
156
76
|
for (const [prefix, slugPatterns] of Object.entries(DOC_DIR_MAP)) {
|
|
157
77
|
if (!relativePath.startsWith(prefix))
|
|
@@ -160,16 +80,16 @@ export function discoverJitContext(accessedPath, projectRoot = process.cwd()) {
|
|
|
160
80
|
if (!fs.existsSync(docsDir))
|
|
161
81
|
break;
|
|
162
82
|
try {
|
|
163
|
-
const docFiles = fs.readdirSync(docsDir).filter(f => f.endsWith('.md'));
|
|
83
|
+
const docFiles = fs.readdirSync(docsDir).filter((f) => f.endsWith('.md'));
|
|
164
84
|
for (const pattern of slugPatterns) {
|
|
165
|
-
const match = docFiles.find(f => f.includes(pattern));
|
|
85
|
+
const match = docFiles.find((f) => f.includes(pattern));
|
|
166
86
|
if (!match)
|
|
167
87
|
continue;
|
|
168
88
|
const docPath = path.join(docsDir, match);
|
|
169
89
|
if (loadedPaths.has(docPath))
|
|
170
90
|
continue;
|
|
171
91
|
const content = fs.readFileSync(docPath, 'utf-8');
|
|
172
|
-
// Only inject the first 2 sections (title + first H2) to stay compact
|
|
92
|
+
// Only inject the first 2 sections (title + first H2) to stay compact.
|
|
173
93
|
const sections = content.split(/(?=^## )/m);
|
|
174
94
|
const compact = sections.slice(0, 2).join('').trim();
|
|
175
95
|
if (compact) {
|
|
@@ -181,10 +101,12 @@ export function discoverJitContext(accessedPath, projectRoot = process.cwd()) {
|
|
|
181
101
|
break; // One doc per prefix
|
|
182
102
|
}
|
|
183
103
|
}
|
|
184
|
-
catch {
|
|
104
|
+
catch {
|
|
105
|
+
/* docs dir not readable */
|
|
106
|
+
}
|
|
185
107
|
break; // One prefix match
|
|
186
108
|
}
|
|
187
|
-
//
|
|
109
|
+
// 3. Path-scoped rules matching this access.
|
|
188
110
|
const rulesContext = discoverRulesForPath(accessedPath, projectRoot);
|
|
189
111
|
if (rulesContext) {
|
|
190
112
|
discoveredContent.push(rulesContext);
|