@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
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Router } from 'express';
|
|
2
2
|
import crypto from 'crypto';
|
|
3
|
+
import { EventEmitter } from 'events';
|
|
3
4
|
import path from 'path';
|
|
4
5
|
import fs from 'fs';
|
|
5
6
|
import { logger } from '../../utils/logger.js';
|
|
@@ -36,6 +37,11 @@ function rotatePairingCode() {
|
|
|
36
37
|
}
|
|
37
38
|
activePairingCode = nextCode;
|
|
38
39
|
activePairingCodeExpiresAt = Date.now() + getPairingCodeTtlMs();
|
|
40
|
+
mobileEventBus.emit('event', {
|
|
41
|
+
type: 'pairing_rotated',
|
|
42
|
+
pairingCodeExpiresAt: activePairingCodeExpiresAt,
|
|
43
|
+
timestamp: Date.now(),
|
|
44
|
+
});
|
|
39
45
|
return activePairingCode;
|
|
40
46
|
}
|
|
41
47
|
function ensureActivePairingCodeFresh() {
|
|
@@ -44,6 +50,15 @@ function ensureActivePairingCodeFresh() {
|
|
|
44
50
|
}
|
|
45
51
|
}
|
|
46
52
|
export const followupDrafts = [];
|
|
53
|
+
// ──────────────────────────────────────────────────────────────────────────
|
|
54
|
+
// Mobile event bus — emits SSE-pushed events for mobile clients.
|
|
55
|
+
// ──────────────────────────────────────────────────────────────────────────
|
|
56
|
+
export const mobileEventBus = new EventEmitter();
|
|
57
|
+
mobileEventBus.setMaxListeners(50);
|
|
58
|
+
/** Check whether dispatch is enabled via environment variable. */
|
|
59
|
+
export function isDispatchEnabled() {
|
|
60
|
+
return process.env.CODEBUDDY_MOBILE_ALLOW_DISPATCH === 'true';
|
|
61
|
+
}
|
|
47
62
|
function pruneExpiredTokens(now = Date.now()) {
|
|
48
63
|
for (const [token, tokenData] of activeTokens) {
|
|
49
64
|
if (now > tokenData.expiresAt) {
|
|
@@ -158,7 +173,8 @@ mobileRouter.get('/followup-drafts', loopbackOnlyMiddleware, (req, res) => {
|
|
|
158
173
|
res.json({ ok: true, drafts: followupDrafts });
|
|
159
174
|
});
|
|
160
175
|
// POST /api/mobile/followup-draft/:id/approve: local operator approves a draft.
|
|
161
|
-
//
|
|
176
|
+
// When CODEBUDDY_MOBILE_ALLOW_DISPATCH is OFF (default), approval is a
|
|
177
|
+
// review-gate marker only — it never dispatches or executes work.
|
|
162
178
|
mobileRouter.post('/followup-draft/:id/approve', loopbackOnlyMiddleware, (req, res) => {
|
|
163
179
|
const draft = followupDrafts.find((d) => d.id === req.params.id);
|
|
164
180
|
if (!draft) {
|
|
@@ -175,6 +191,12 @@ mobileRouter.post('/followup-draft/:id/approve', loopbackOnlyMiddleware, (req, r
|
|
|
175
191
|
draft.status = 'approved';
|
|
176
192
|
draft.approvedBy = reviewer;
|
|
177
193
|
draft.approvedAt = Date.now();
|
|
194
|
+
mobileEventBus.emit('event', {
|
|
195
|
+
type: 'draft_status_changed',
|
|
196
|
+
draftId: draft.id,
|
|
197
|
+
status: draft.status,
|
|
198
|
+
timestamp: Date.now(),
|
|
199
|
+
});
|
|
178
200
|
res.json({
|
|
179
201
|
ok: true,
|
|
180
202
|
message: 'Draft approved by local operator. No work is dispatched automatically — execution stays local and explicit.',
|
|
@@ -194,8 +216,52 @@ mobileRouter.post('/followup-draft/:id/cancel', loopbackOnlyMiddleware, (req, re
|
|
|
194
216
|
}
|
|
195
217
|
draft.status = 'cancelled';
|
|
196
218
|
draft.cancelledAt = Date.now();
|
|
219
|
+
mobileEventBus.emit('event', {
|
|
220
|
+
type: 'draft_status_changed',
|
|
221
|
+
draftId: draft.id,
|
|
222
|
+
status: draft.status,
|
|
223
|
+
timestamp: Date.now(),
|
|
224
|
+
});
|
|
197
225
|
res.json({ ok: true, message: 'Draft cancelled by local operator.', draft });
|
|
198
226
|
});
|
|
227
|
+
// POST /api/mobile/followup-draft/:id/dispatch: local operator dispatches an
|
|
228
|
+
// approved draft to the agent. Gated behind CODEBUDDY_MOBILE_ALLOW_DISPATCH.
|
|
229
|
+
mobileRouter.post('/followup-draft/:id/dispatch', loopbackOnlyMiddleware, (req, res) => {
|
|
230
|
+
if (!isDispatchEnabled()) {
|
|
231
|
+
res.status(403).json({
|
|
232
|
+
ok: false,
|
|
233
|
+
error: 'Dispatch is disabled. Set CODEBUDDY_MOBILE_ALLOW_DISPATCH=true to enable.',
|
|
234
|
+
});
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
const draft = followupDrafts.find((d) => d.id === req.params.id);
|
|
238
|
+
if (!draft) {
|
|
239
|
+
res.status(404).json({ ok: false, error: 'Draft not found' });
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
if (draft.status !== 'approved') {
|
|
243
|
+
res.status(409).json({
|
|
244
|
+
ok: false,
|
|
245
|
+
error: `Draft must be approved before dispatch (status: ${draft.status})`,
|
|
246
|
+
});
|
|
247
|
+
return;
|
|
248
|
+
}
|
|
249
|
+
draft.status = 'dispatched';
|
|
250
|
+
draft.dispatchedAt = Date.now();
|
|
251
|
+
mobileEventBus.emit('event', {
|
|
252
|
+
type: 'draft_status_changed',
|
|
253
|
+
draftId: draft.id,
|
|
254
|
+
status: draft.status,
|
|
255
|
+
timestamp: Date.now(),
|
|
256
|
+
});
|
|
257
|
+
// Emit a dispatch queue entry for the agent to pick up.
|
|
258
|
+
mobileEventBus.emit('dispatch', { draftId: draft.id, prompt: draft.prompt });
|
|
259
|
+
res.json({
|
|
260
|
+
ok: true,
|
|
261
|
+
message: 'Draft dispatched to agent for execution.',
|
|
262
|
+
draft,
|
|
263
|
+
});
|
|
264
|
+
});
|
|
199
265
|
// 1. POST /api/mobile/pair: Validate pairing request and issue short-lived token
|
|
200
266
|
mobileRouter.post('/pair', (req, res) => {
|
|
201
267
|
const code = typeof req.body?.code === 'string' ? req.body.code.trim() : '';
|
|
@@ -221,6 +287,49 @@ mobileRouter.post('/pair', (req, res) => {
|
|
|
221
287
|
expiresAt,
|
|
222
288
|
});
|
|
223
289
|
});
|
|
290
|
+
// ──────────────────────────────────────────────────────────────────────────
|
|
291
|
+
// SSE push endpoint — authenticated via mobile bearer token (query param
|
|
292
|
+
// fallback for EventSource API which doesn't support Authorization header).
|
|
293
|
+
// Pushes: draft_status_changed, snapshot_available, pairing_rotated.
|
|
294
|
+
// ──────────────────────────────────────────────────────────────────────────
|
|
295
|
+
const HEARTBEAT_INTERVAL_MS = 30_000;
|
|
296
|
+
mobileRouter.get('/events', (req, res) => {
|
|
297
|
+
// Auth: prefer Authorization header, fall back to ?token= query param.
|
|
298
|
+
const authHeader = req.headers.authorization;
|
|
299
|
+
let token;
|
|
300
|
+
if (authHeader && authHeader.startsWith('Bearer ')) {
|
|
301
|
+
token = authHeader.substring(7).trim();
|
|
302
|
+
}
|
|
303
|
+
else if (typeof req.query.token === 'string') {
|
|
304
|
+
token = req.query.token.trim();
|
|
305
|
+
}
|
|
306
|
+
if (!token || !isValidToken(token)) {
|
|
307
|
+
res.status(401).json({ ok: false, error: 'Unauthorized: Invalid or expired pairing token' });
|
|
308
|
+
return;
|
|
309
|
+
}
|
|
310
|
+
// SSE headers.
|
|
311
|
+
res.setHeader('Content-Type', 'text/event-stream');
|
|
312
|
+
res.setHeader('Cache-Control', 'no-cache');
|
|
313
|
+
res.setHeader('Connection', 'keep-alive');
|
|
314
|
+
res.flushHeaders();
|
|
315
|
+
const sendSSE = (payload) => {
|
|
316
|
+
res.write(`data: ${JSON.stringify(payload)}\n\n`);
|
|
317
|
+
};
|
|
318
|
+
// Heartbeat to keep the connection alive.
|
|
319
|
+
const heartbeat = setInterval(() => {
|
|
320
|
+
sendSSE({ type: 'heartbeat', timestamp: Date.now() });
|
|
321
|
+
}, HEARTBEAT_INTERVAL_MS);
|
|
322
|
+
// Forward bus events to this SSE client.
|
|
323
|
+
const onEvent = (payload) => {
|
|
324
|
+
sendSSE(payload);
|
|
325
|
+
};
|
|
326
|
+
mobileEventBus.on('event', onEvent);
|
|
327
|
+
// Cleanup on disconnect.
|
|
328
|
+
req.on('close', () => {
|
|
329
|
+
clearInterval(heartbeat);
|
|
330
|
+
mobileEventBus.off('event', onEvent);
|
|
331
|
+
});
|
|
332
|
+
});
|
|
224
333
|
// Apply mobile auth middleware to all remaining routes
|
|
225
334
|
mobileRouter.use(mobileAuthMiddleware);
|
|
226
335
|
// 2. GET /api/mobile/snapshot: Return active run snapshot summary
|
|
@@ -331,6 +440,12 @@ async function enqueuePendingFollowupDraft(prompt, query, source) {
|
|
|
331
440
|
createdAt: Date.now(),
|
|
332
441
|
};
|
|
333
442
|
followupDrafts.push(savedDraft);
|
|
443
|
+
mobileEventBus.emit('event', {
|
|
444
|
+
type: 'draft_status_changed',
|
|
445
|
+
draftId: savedDraft.id,
|
|
446
|
+
status: savedDraft.status,
|
|
447
|
+
timestamp: Date.now(),
|
|
448
|
+
});
|
|
334
449
|
return savedDraft;
|
|
335
450
|
}
|
|
336
451
|
// 5. POST /api/mobile/followup-draft: Save a local operator followup review draft
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Optional TLS for the API server.
|
|
3
|
+
*
|
|
4
|
+
* The mobile-supervision endpoint (`/api/mobile`) rides the main HTTP server.
|
|
5
|
+
* To expose it off-device securely it can be served over HTTPS. This is purely
|
|
6
|
+
* transport security — it does not change any product gate (the dispatch gate
|
|
7
|
+
* `CODEBUDDY_MOBILE_ALLOW_DISPATCH` is untouched).
|
|
8
|
+
*
|
|
9
|
+
* Behaviour, gated by env (HTTP stays the default — no env, no TLS):
|
|
10
|
+
* - `CODEBUDDY_HTTPS=1` (or `CODEBUDDY_MOBILE_TLS=1`) enables HTTPS.
|
|
11
|
+
* - `CODEBUDDY_TLS_CERT` / `CODEBUDDY_TLS_KEY` = paths to a PEM cert/key. This
|
|
12
|
+
* is the standard production approach (Let's Encrypt / reverse proxy / the
|
|
13
|
+
* operator provisions the cert).
|
|
14
|
+
* - If TLS is enabled but no cert is provided, a dev self-signed cert is
|
|
15
|
+
* generated via `openssl` (if on PATH) into `~/.codebuddy/tls/` and reused.
|
|
16
|
+
* - If TLS is enabled but it cannot be satisfied (cert unreadable, or openssl
|
|
17
|
+
* absent), this **throws** with a clear message. It never silently falls back
|
|
18
|
+
* to plain HTTP — an operator who asked for TLS must not be downgraded.
|
|
19
|
+
*
|
|
20
|
+
* Uses only Node built-ins (`https`, `fs`, `child_process`) — no new dependency.
|
|
21
|
+
*/
|
|
22
|
+
export interface ServerTlsOptions {
|
|
23
|
+
cert: string | Buffer;
|
|
24
|
+
key: string | Buffer;
|
|
25
|
+
}
|
|
26
|
+
/** Whether HTTPS is requested for the API server. */
|
|
27
|
+
export declare function isTlsEnabled(env?: NodeJS.ProcessEnv): boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Resolve TLS options for the server, or `null` when TLS is not requested.
|
|
30
|
+
*
|
|
31
|
+
* Returns `null` (HTTP, unchanged default) when neither `CODEBUDDY_HTTPS` nor
|
|
32
|
+
* `CODEBUDDY_MOBILE_TLS` is set. Throws a clear error if TLS is requested but
|
|
33
|
+
* cannot be satisfied — it never downgrades to HTTP behind the operator's back.
|
|
34
|
+
*/
|
|
35
|
+
export declare function resolveServerTlsOptions(env?: NodeJS.ProcessEnv): ServerTlsOptions | null;
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Optional TLS for the API server.
|
|
3
|
+
*
|
|
4
|
+
* The mobile-supervision endpoint (`/api/mobile`) rides the main HTTP server.
|
|
5
|
+
* To expose it off-device securely it can be served over HTTPS. This is purely
|
|
6
|
+
* transport security — it does not change any product gate (the dispatch gate
|
|
7
|
+
* `CODEBUDDY_MOBILE_ALLOW_DISPATCH` is untouched).
|
|
8
|
+
*
|
|
9
|
+
* Behaviour, gated by env (HTTP stays the default — no env, no TLS):
|
|
10
|
+
* - `CODEBUDDY_HTTPS=1` (or `CODEBUDDY_MOBILE_TLS=1`) enables HTTPS.
|
|
11
|
+
* - `CODEBUDDY_TLS_CERT` / `CODEBUDDY_TLS_KEY` = paths to a PEM cert/key. This
|
|
12
|
+
* is the standard production approach (Let's Encrypt / reverse proxy / the
|
|
13
|
+
* operator provisions the cert).
|
|
14
|
+
* - If TLS is enabled but no cert is provided, a dev self-signed cert is
|
|
15
|
+
* generated via `openssl` (if on PATH) into `~/.codebuddy/tls/` and reused.
|
|
16
|
+
* - If TLS is enabled but it cannot be satisfied (cert unreadable, or openssl
|
|
17
|
+
* absent), this **throws** with a clear message. It never silently falls back
|
|
18
|
+
* to plain HTTP — an operator who asked for TLS must not be downgraded.
|
|
19
|
+
*
|
|
20
|
+
* Uses only Node built-ins (`https`, `fs`, `child_process`) — no new dependency.
|
|
21
|
+
*/
|
|
22
|
+
import fs from 'fs';
|
|
23
|
+
import os from 'os';
|
|
24
|
+
import path from 'path';
|
|
25
|
+
import { execFileSync } from 'child_process';
|
|
26
|
+
import { logger } from '../utils/logger.js';
|
|
27
|
+
/** Truthy env flag check — accepts `1`, `true`, `yes`, `on` (case-insensitive). */
|
|
28
|
+
function isEnvTrue(value) {
|
|
29
|
+
if (!value)
|
|
30
|
+
return false;
|
|
31
|
+
const v = value.trim().toLowerCase();
|
|
32
|
+
return v === '1' || v === 'true' || v === 'yes' || v === 'on';
|
|
33
|
+
}
|
|
34
|
+
/** Whether HTTPS is requested for the API server. */
|
|
35
|
+
export function isTlsEnabled(env = process.env) {
|
|
36
|
+
return isEnvTrue(env.CODEBUDDY_HTTPS) || isEnvTrue(env.CODEBUDDY_MOBILE_TLS);
|
|
37
|
+
}
|
|
38
|
+
function tlsDir() {
|
|
39
|
+
const home = process.env.CODEBUDDY_HOME || os.homedir();
|
|
40
|
+
return path.join(home, '.codebuddy', 'tls');
|
|
41
|
+
}
|
|
42
|
+
function hasOpenssl() {
|
|
43
|
+
try {
|
|
44
|
+
execFileSync('openssl', ['version'], { stdio: 'ignore' });
|
|
45
|
+
return true;
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Generate (once) and return a dev self-signed cert/key under `~/.codebuddy/tls/`.
|
|
53
|
+
* Reuses an existing pair if both files are present. Throws if openssl is absent.
|
|
54
|
+
*/
|
|
55
|
+
function ensureDevSelfSignedCert() {
|
|
56
|
+
const dir = tlsDir();
|
|
57
|
+
const certPath = path.join(dir, 'dev-cert.pem');
|
|
58
|
+
const keyPath = path.join(dir, 'dev-key.pem');
|
|
59
|
+
if (fs.existsSync(certPath) && fs.existsSync(keyPath)) {
|
|
60
|
+
return { cert: fs.readFileSync(certPath), key: fs.readFileSync(keyPath) };
|
|
61
|
+
}
|
|
62
|
+
if (!hasOpenssl()) {
|
|
63
|
+
throw new Error('TLS is enabled (CODEBUDDY_HTTPS) but no cert/key was provided and `openssl` ' +
|
|
64
|
+
'is not available on PATH to generate a dev self-signed certificate. ' +
|
|
65
|
+
'Provide CODEBUDDY_TLS_CERT and CODEBUDDY_TLS_KEY (PEM paths), or install openssl.');
|
|
66
|
+
}
|
|
67
|
+
fs.mkdirSync(dir, { recursive: true, mode: 0o700 });
|
|
68
|
+
try {
|
|
69
|
+
execFileSync('openssl', [
|
|
70
|
+
'req',
|
|
71
|
+
'-x509',
|
|
72
|
+
'-newkey',
|
|
73
|
+
'rsa:2048',
|
|
74
|
+
'-nodes',
|
|
75
|
+
'-keyout',
|
|
76
|
+
keyPath,
|
|
77
|
+
'-out',
|
|
78
|
+
certPath,
|
|
79
|
+
'-subj',
|
|
80
|
+
'/CN=localhost',
|
|
81
|
+
'-days',
|
|
82
|
+
'365',
|
|
83
|
+
], { stdio: 'ignore' });
|
|
84
|
+
// Restrict the private key to the owner.
|
|
85
|
+
try {
|
|
86
|
+
fs.chmodSync(keyPath, 0o600);
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
/* best-effort on platforms without POSIX perms */
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
catch (err) {
|
|
93
|
+
throw new Error('TLS is enabled (CODEBUDDY_HTTPS) but generating a dev self-signed certificate ' +
|
|
94
|
+
`with openssl failed: ${err instanceof Error ? err.message : String(err)}. ` +
|
|
95
|
+
'Provide CODEBUDDY_TLS_CERT and CODEBUDDY_TLS_KEY (PEM paths) instead.');
|
|
96
|
+
}
|
|
97
|
+
logger.warn(`TLS: generated a dev self-signed certificate at ${certPath}. ` +
|
|
98
|
+
'This is for development/off-device testing only — use a real cert ' +
|
|
99
|
+
'(CODEBUDDY_TLS_CERT / CODEBUDDY_TLS_KEY) in production.');
|
|
100
|
+
return { cert: fs.readFileSync(certPath), key: fs.readFileSync(keyPath) };
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Resolve TLS options for the server, or `null` when TLS is not requested.
|
|
104
|
+
*
|
|
105
|
+
* Returns `null` (HTTP, unchanged default) when neither `CODEBUDDY_HTTPS` nor
|
|
106
|
+
* `CODEBUDDY_MOBILE_TLS` is set. Throws a clear error if TLS is requested but
|
|
107
|
+
* cannot be satisfied — it never downgrades to HTTP behind the operator's back.
|
|
108
|
+
*/
|
|
109
|
+
export function resolveServerTlsOptions(env = process.env) {
|
|
110
|
+
if (!isTlsEnabled(env)) {
|
|
111
|
+
return null;
|
|
112
|
+
}
|
|
113
|
+
const certPath = env.CODEBUDDY_TLS_CERT?.trim();
|
|
114
|
+
const keyPath = env.CODEBUDDY_TLS_KEY?.trim();
|
|
115
|
+
// One of the two paths set but not the other → operator misconfiguration.
|
|
116
|
+
if ((certPath && !keyPath) || (!certPath && keyPath)) {
|
|
117
|
+
throw new Error('TLS is enabled (CODEBUDDY_HTTPS) but only one of CODEBUDDY_TLS_CERT / ' +
|
|
118
|
+
'CODEBUDDY_TLS_KEY is set. Provide both, or neither (to use a dev self-signed cert).');
|
|
119
|
+
}
|
|
120
|
+
if (certPath && keyPath) {
|
|
121
|
+
let cert;
|
|
122
|
+
let key;
|
|
123
|
+
try {
|
|
124
|
+
cert = fs.readFileSync(certPath);
|
|
125
|
+
}
|
|
126
|
+
catch (err) {
|
|
127
|
+
throw new Error(`TLS is enabled but CODEBUDDY_TLS_CERT (${certPath}) could not be read: ` +
|
|
128
|
+
`${err instanceof Error ? err.message : String(err)}`);
|
|
129
|
+
}
|
|
130
|
+
try {
|
|
131
|
+
key = fs.readFileSync(keyPath);
|
|
132
|
+
}
|
|
133
|
+
catch (err) {
|
|
134
|
+
throw new Error(`TLS is enabled but CODEBUDDY_TLS_KEY (${keyPath}) could not be read: ` +
|
|
135
|
+
`${err instanceof Error ? err.message : String(err)}`);
|
|
136
|
+
}
|
|
137
|
+
return { cert, key };
|
|
138
|
+
}
|
|
139
|
+
// TLS requested with no explicit cert — generate/reuse a dev self-signed cert.
|
|
140
|
+
return ensureDevSelfSignedCert();
|
|
141
|
+
}
|
|
142
|
+
//# sourceMappingURL=tls-config.js.map
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export interface TunnelOptions {
|
|
2
|
+
port: number;
|
|
3
|
+
authtoken?: string;
|
|
4
|
+
domain?: string;
|
|
5
|
+
}
|
|
6
|
+
export declare class TunnelManager {
|
|
7
|
+
private static listener;
|
|
8
|
+
/**
|
|
9
|
+
* Start an ngrok tunnel forwarding to the specified port.
|
|
10
|
+
*/
|
|
11
|
+
static startTunnel(options: TunnelOptions): Promise<string>;
|
|
12
|
+
/**
|
|
13
|
+
* Stop the active ngrok tunnel.
|
|
14
|
+
*/
|
|
15
|
+
static stopTunnel(): Promise<void>;
|
|
16
|
+
/**
|
|
17
|
+
* Get the URL of the currently active tunnel, if any.
|
|
18
|
+
*/
|
|
19
|
+
static getActiveTunnelUrl(): string | null;
|
|
20
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import * as ngrok from '@ngrok/ngrok';
|
|
2
|
+
import { logger } from '../utils/logger.js';
|
|
3
|
+
export class TunnelManager {
|
|
4
|
+
static listener = null;
|
|
5
|
+
/**
|
|
6
|
+
* Start an ngrok tunnel forwarding to the specified port.
|
|
7
|
+
*/
|
|
8
|
+
static async startTunnel(options) {
|
|
9
|
+
if (this.listener) {
|
|
10
|
+
logger.warn('A tunnel is already running. Disconnecting existing tunnel.');
|
|
11
|
+
await this.stopTunnel();
|
|
12
|
+
}
|
|
13
|
+
try {
|
|
14
|
+
logger.info(`Starting ngrok tunnel for port ${options.port}...`);
|
|
15
|
+
const ngrokOptions = {
|
|
16
|
+
addr: options.port,
|
|
17
|
+
authtoken_from_env: true,
|
|
18
|
+
};
|
|
19
|
+
if (options.authtoken) {
|
|
20
|
+
ngrokOptions.authtoken = options.authtoken;
|
|
21
|
+
}
|
|
22
|
+
if (options.domain) {
|
|
23
|
+
ngrokOptions.domain = options.domain;
|
|
24
|
+
}
|
|
25
|
+
this.listener = await ngrok.forward(ngrokOptions);
|
|
26
|
+
const url = this.listener.url() ?? '';
|
|
27
|
+
logger.info(`ngrok tunnel established at: ${url}`);
|
|
28
|
+
return url;
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
logger.error('Failed to start ngrok tunnel', { error });
|
|
32
|
+
throw error;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Stop the active ngrok tunnel.
|
|
37
|
+
*/
|
|
38
|
+
static async stopTunnel() {
|
|
39
|
+
if (this.listener) {
|
|
40
|
+
try {
|
|
41
|
+
await this.listener.close();
|
|
42
|
+
this.listener = null;
|
|
43
|
+
logger.info('ngrok tunnel closed.');
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
logger.error('Failed to close ngrok tunnel', { error });
|
|
47
|
+
throw error;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Get the URL of the currently active tunnel, if any.
|
|
53
|
+
*/
|
|
54
|
+
static getActiveTunnelUrl() {
|
|
55
|
+
return this.listener ? this.listener.url() ?? null : null;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=tunnel-manager.js.map
|
|
@@ -178,4 +178,9 @@ export function broadcastChatSessionEnd(payload) {
|
|
|
178
178
|
export function broadcastChatSessionGoal(payload) {
|
|
179
179
|
broadcastFleetEvent('fleet:chat-session:goal', { ...payload });
|
|
180
180
|
}
|
|
181
|
+
// Wire up the agent runtime hooks (breaks circular dependency #2)
|
|
182
|
+
import { registerFleetBroadcaster } from '../../agent/execution/tool-hooks.js';
|
|
183
|
+
registerFleetBroadcaster(broadcastFleetEvent);
|
|
184
|
+
import { registerSessionFleetBroadcaster } from '../../agent/multi-agent/session-fleet-bridge.js';
|
|
185
|
+
registerSessionFleetBroadcaster(broadcastFleetEvent);
|
|
181
186
|
//# sourceMappingURL=fleet-bridge.js.map
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
import { EnhancedMemory, PersistentMemoryManager } from "../memory/index.js";
|
|
13
13
|
import { PromptCacheManager } from "../optimization/prompt-cache.js";
|
|
14
14
|
import { MoltbotHooksManager } from "../hooks/moltbot-hooks.js";
|
|
15
|
+
import { type ContextRegistry } from "../context/project-context.js";
|
|
15
16
|
import { type QueryComplexity } from "../agent/execution/query-classifier.js";
|
|
16
17
|
export interface PromptBuilderConfig {
|
|
17
18
|
yoloMode: boolean;
|
|
@@ -39,6 +40,7 @@ export interface BuildOptions {
|
|
|
39
40
|
includeWritingRules?: boolean;
|
|
40
41
|
includeCodingStyle?: boolean;
|
|
41
42
|
includeWorkflowRules?: boolean;
|
|
43
|
+
includeExecutionDiscipline?: boolean;
|
|
42
44
|
includeVariation?: boolean;
|
|
43
45
|
}
|
|
44
46
|
export declare class PromptBuilder {
|
|
@@ -47,7 +49,16 @@ export declare class PromptBuilder {
|
|
|
47
49
|
private memory?;
|
|
48
50
|
private moltbotHooksManager?;
|
|
49
51
|
private persistentMemory?;
|
|
52
|
+
/**
|
|
53
|
+
* Dedup registry for project-instruction files, recreated fresh at the start
|
|
54
|
+
* of each system-prompt build. The JIT context pass reads it (via
|
|
55
|
+
* `getContextRegistry()`) so files already injected at startup are not
|
|
56
|
+
* re-injected when a tool later touches a file in the same tree.
|
|
57
|
+
*/
|
|
58
|
+
private contextRegistry;
|
|
50
59
|
constructor(config: PromptBuilderConfig, promptCacheManager: PromptCacheManager, memory?: EnhancedMemory | undefined, moltbotHooksManager?: MoltbotHooksManager | undefined, persistentMemory?: PersistentMemoryManager | undefined);
|
|
60
|
+
/** The registry from the most recent system-prompt build (for the JIT pass). */
|
|
61
|
+
getContextRegistry(): ContextRegistry | null;
|
|
51
62
|
/**
|
|
52
63
|
* Build the system prompt for the agent. The optional `options`
|
|
53
64
|
* parameter gates per-block injection. All gates default to `true`
|