@bubblebrain-ai/bubble 0.0.63 → 0.0.64
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 +437 -11
- package/dist/agent/abort-errors.d.ts +18 -0
- package/dist/agent/abort-errors.js +51 -0
- package/dist/agent/budget-ledger.d.ts +20 -0
- package/dist/agent/budget-ledger.js +45 -0
- package/dist/agent/categories.d.ts +100 -0
- package/dist/agent/categories.js +203 -0
- package/dist/agent/change-tracker.d.ts +40 -0
- package/dist/agent/change-tracker.js +89 -0
- package/dist/agent/child-runner.d.ts +64 -0
- package/dist/agent/child-runner.js +405 -0
- package/dist/agent/input-controller.d.ts +14 -0
- package/dist/agent/input-controller.js +43 -0
- package/dist/agent/internal-reminder-sanitizer.d.ts +25 -0
- package/dist/agent/internal-reminder-sanitizer.js +297 -0
- package/dist/agent/profiles.d.ts +76 -0
- package/dist/agent/profiles.js +526 -0
- package/dist/agent/provider-fingerprint.d.ts +6 -0
- package/dist/agent/provider-fingerprint.js +89 -0
- package/dist/agent/resident-history.d.ts +7 -0
- package/dist/agent/resident-history.js +61 -0
- package/dist/agent/result-integrator.d.ts +22 -0
- package/dist/agent/result-integrator.js +50 -0
- package/dist/agent/routing-catalog.d.ts +131 -0
- package/dist/agent/routing-catalog.js +260 -0
- package/dist/agent/structured-output.d.ts +37 -0
- package/dist/agent/structured-output.js +193 -0
- package/dist/agent/subagent/router.d.ts +65 -0
- package/dist/agent/subagent/router.js +203 -0
- package/dist/agent/subagent/runtime.d.ts +235 -0
- package/dist/agent/subagent/runtime.js +835 -0
- package/dist/agent/subagent-control.d.ts +100 -0
- package/dist/agent/subagent-control.js +70 -0
- package/dist/agent/subagent-lifecycle-reminder.d.ts +3 -0
- package/dist/agent/subagent-lifecycle-reminder.js +112 -0
- package/dist/agent/subagent-route-format.d.ts +8 -0
- package/dist/agent/subagent-route-format.js +18 -0
- package/dist/agent/subagent-scheduler.d.ts +105 -0
- package/dist/agent/subagent-scheduler.js +287 -0
- package/dist/agent/subagent-store.d.ts +57 -0
- package/dist/agent/subagent-store.js +180 -0
- package/dist/agent/subagent-summary.d.ts +30 -0
- package/dist/agent/subagent-summary.js +74 -0
- package/dist/agent/subagent-wait-guidance.d.ts +2 -0
- package/dist/agent/subagent-wait-guidance.js +8 -0
- package/dist/agent/subtask-policy.d.ts +13 -0
- package/dist/agent/subtask-policy.js +56 -0
- package/dist/agent/task-lifecycle-reminder.d.ts +26 -0
- package/dist/agent/task-lifecycle-reminder.js +59 -0
- package/dist/agent/tool-intent.d.ts +45 -0
- package/dist/agent/tool-intent.js +318 -0
- package/dist/agent/tool-visibility.d.ts +10 -0
- package/dist/agent/tool-visibility.js +6 -0
- package/dist/agent/transcript-helpers.d.ts +20 -0
- package/dist/agent/transcript-helpers.js +63 -0
- package/dist/agent/update-queue.d.ts +13 -0
- package/dist/agent/update-queue.js +69 -0
- package/dist/agent/workflow/control.d.ts +60 -0
- package/dist/agent/workflow/control.js +62 -0
- package/dist/agent/workflow/errors.d.ts +16 -0
- package/dist/agent/workflow/errors.js +24 -0
- package/dist/agent/workflow/runs.d.ts +73 -0
- package/dist/agent/workflow/runs.js +160 -0
- package/dist/agent/workflow/runtime.d.ts +88 -0
- package/dist/agent/workflow/runtime.js +319 -0
- package/dist/agent/worktree.d.ts +29 -0
- package/dist/agent/worktree.js +73 -0
- package/dist/agent.d.ts +460 -0
- package/dist/agent.js +2210 -0
- package/dist/anthropic-thinking.d.ts +4 -0
- package/dist/anthropic-thinking.js +11 -0
- package/dist/approval/controller.d.ts +71 -0
- package/dist/approval/controller.js +286 -0
- package/dist/approval/danger.d.ts +13 -0
- package/dist/approval/danger.js +55 -0
- package/dist/approval/diff-hunks.d.ts +12 -0
- package/dist/approval/diff-hunks.js +32 -0
- package/dist/approval/protected-paths.d.ts +1 -0
- package/dist/approval/protected-paths.js +35 -0
- package/dist/approval/session-cache.d.ts +21 -0
- package/dist/approval/session-cache.js +38 -0
- package/dist/approval/tool-helper.d.ts +14 -0
- package/dist/approval/tool-helper.js +47 -0
- package/dist/approval/types.d.ts +146 -0
- package/dist/approval/types.js +8 -0
- package/dist/bin.d.ts +2 -0
- package/dist/bin.js +3 -0
- package/dist/bubble-home.d.ts +8 -0
- package/dist/bubble-home.js +19 -0
- package/dist/checkpoints.d.ts +57 -0
- package/dist/checkpoints.js +0 -0
- package/dist/cli.d.ts +37 -0
- package/dist/cli.js +175 -0
- package/dist/clipboard.d.ts +14 -0
- package/dist/clipboard.js +132 -0
- package/dist/config.d.ts +96 -0
- package/dist/config.js +287 -0
- package/dist/context/budget.d.ts +28 -0
- package/dist/context/budget.js +130 -0
- package/dist/context/checkpoint.d.ts +18 -0
- package/dist/context/checkpoint.js +117 -0
- package/dist/context/compact-llm.d.ts +25 -0
- package/dist/context/compact-llm.js +175 -0
- package/dist/context/compact.d.ts +124 -0
- package/dist/context/compact.js +635 -0
- package/dist/context/compaction-files.d.ts +44 -0
- package/dist/context/compaction-files.js +148 -0
- package/dist/context/llm-compactor.d.ts +53 -0
- package/dist/context/llm-compactor.js +424 -0
- package/dist/context/overflow.d.ts +9 -0
- package/dist/context/overflow.js +50 -0
- package/dist/context/projector.d.ts +34 -0
- package/dist/context/projector.js +251 -0
- package/dist/context/prune.d.ts +26 -0
- package/dist/context/prune.js +171 -0
- package/dist/context/session-write-lock.d.ts +20 -0
- package/dist/context/session-write-lock.js +162 -0
- package/dist/context/token-estimator.d.ts +14 -0
- package/dist/context/token-estimator.js +106 -0
- package/dist/context/tool-images.d.ts +3 -0
- package/dist/context/tool-images.js +35 -0
- package/dist/context/tool-output-truncate.d.ts +24 -0
- package/dist/context/tool-output-truncate.js +181 -0
- package/dist/context/usage.d.ts +34 -0
- package/dist/context/usage.js +230 -0
- package/dist/debug-trace.d.ts +27 -0
- package/dist/debug-trace.js +401 -0
- package/dist/diff-stats.d.ts +5 -0
- package/dist/diff-stats.js +21 -0
- package/dist/external-runtime/grok-acp.d.ts +56 -0
- package/dist/external-runtime/grok-acp.js +386 -0
- package/dist/external-runtime/grok-binary.d.ts +25 -0
- package/dist/external-runtime/grok-binary.js +108 -0
- package/dist/external-runtime/grok-errors.d.ts +7 -0
- package/dist/external-runtime/grok-errors.js +15 -0
- package/dist/external-runtime/grok-input-policy.d.ts +58 -0
- package/dist/external-runtime/grok-input-policy.js +52 -0
- package/dist/external-runtime/grok-ndjson.d.ts +14 -0
- package/dist/external-runtime/grok-ndjson.js +193 -0
- package/dist/external-runtime/grok-network.d.ts +15 -0
- package/dist/external-runtime/grok-network.js +81 -0
- package/dist/external-runtime/grok-preflight.d.ts +28 -0
- package/dist/external-runtime/grok-preflight.js +194 -0
- package/dist/external-runtime/grok-process.d.ts +26 -0
- package/dist/external-runtime/grok-process.js +184 -0
- package/dist/external-runtime/grok-profile.d.ts +32 -0
- package/dist/external-runtime/grok-profile.js +419 -0
- package/dist/external-runtime/grok-provider.d.ts +31 -0
- package/dist/external-runtime/grok-provider.js +41 -0
- package/dist/external-runtime/grok-runtime.d.ts +91 -0
- package/dist/external-runtime/grok-runtime.js +882 -0
- package/dist/external-runtime/index.d.ts +13 -0
- package/dist/external-runtime/index.js +13 -0
- package/dist/external-runtime/session-policy.d.ts +11 -0
- package/dist/external-runtime/session-policy.js +30 -0
- package/dist/external-runtime/types.d.ts +65 -0
- package/dist/external-runtime/types.js +1 -0
- package/dist/feedback/collect.d.ts +7 -0
- package/dist/feedback/collect.js +119 -0
- package/dist/feedback/config.d.ts +14 -0
- package/dist/feedback/config.js +16 -0
- package/dist/feedback/redact.d.ts +1 -0
- package/dist/feedback/redact.js +25 -0
- package/dist/feedback/submit.d.ts +6 -0
- package/dist/feedback/submit.js +43 -0
- package/dist/feedback/types.d.ts +22 -0
- package/dist/feedback/types.js +1 -0
- package/dist/feishu/agent-host/approval-card.d.ts +11 -0
- package/dist/feishu/agent-host/approval-card.js +85 -0
- package/dist/feishu/agent-host/approval-ui.d.ts +59 -0
- package/dist/feishu/agent-host/approval-ui.js +214 -0
- package/dist/feishu/agent-host/run-driver.d.ts +51 -0
- package/dist/feishu/agent-host/run-driver.js +397 -0
- package/dist/feishu/agent-host/runtime-deps.d.ts +33 -0
- package/dist/feishu/agent-host/runtime-deps.js +8 -0
- package/dist/feishu/card/budget.d.ts +40 -0
- package/dist/feishu/card/budget.js +134 -0
- package/dist/feishu/card/renderer.d.ts +29 -0
- package/dist/feishu/card/renderer.js +245 -0
- package/dist/feishu/card/run-state-types.d.ts +49 -0
- package/dist/feishu/card/run-state-types.js +15 -0
- package/dist/feishu/card/run-state.d.ts +21 -0
- package/dist/feishu/card/run-state.js +223 -0
- package/dist/feishu/channel/channel.d.ts +52 -0
- package/dist/feishu/channel/channel.js +74 -0
- package/dist/feishu/config.d.ts +24 -0
- package/dist/feishu/config.js +97 -0
- package/dist/feishu/format.d.ts +6 -0
- package/dist/feishu/format.js +14 -0
- package/dist/feishu/index.d.ts +4 -0
- package/dist/feishu/index.js +4 -0
- package/dist/feishu/logger.d.ts +31 -0
- package/dist/feishu/logger.js +62 -0
- package/dist/feishu/paths.d.ts +12 -0
- package/dist/feishu/paths.js +38 -0
- package/dist/feishu/process-registry.d.ts +29 -0
- package/dist/feishu/process-registry.js +90 -0
- package/dist/feishu/router/commands.d.ts +38 -0
- package/dist/feishu/router/commands.js +286 -0
- package/dist/feishu/router/event-router.d.ts +40 -0
- package/dist/feishu/router/event-router.js +208 -0
- package/dist/feishu/router/whitelist.d.ts +23 -0
- package/dist/feishu/router/whitelist.js +20 -0
- package/dist/feishu/runtime/active-runs.d.ts +32 -0
- package/dist/feishu/runtime/active-runs.js +84 -0
- package/dist/feishu/runtime/pending-queue.d.ts +36 -0
- package/dist/feishu/runtime/pending-queue.js +98 -0
- package/dist/feishu/runtime/process-pool.d.ts +29 -0
- package/dist/feishu/runtime/process-pool.js +49 -0
- package/dist/feishu/schema.d.ts +17 -0
- package/dist/feishu/schema.js +252 -0
- package/dist/feishu/scope/scope-registry.d.ts +39 -0
- package/dist/feishu/scope/scope-registry.js +148 -0
- package/dist/feishu/scope/session-binder.d.ts +44 -0
- package/dist/feishu/scope/session-binder.js +100 -0
- package/dist/feishu/scope/session-store.d.ts +24 -0
- package/dist/feishu/scope/session-store.js +73 -0
- package/dist/feishu/secrets.d.ts +37 -0
- package/dist/feishu/secrets.js +129 -0
- package/dist/feishu/serve.d.ts +12 -0
- package/dist/feishu/serve.js +302 -0
- package/dist/feishu/types.d.ts +75 -0
- package/dist/feishu/types.js +23 -0
- package/dist/feishu/wizard.d.ts +24 -0
- package/dist/feishu/wizard.js +121 -0
- package/dist/goal/command.d.ts +20 -0
- package/dist/goal/command.js +76 -0
- package/dist/goal/engine.d.ts +33 -0
- package/dist/goal/engine.js +65 -0
- package/dist/goal/format.d.ts +18 -0
- package/dist/goal/format.js +112 -0
- package/dist/goal/prompts.d.ts +13 -0
- package/dist/goal/prompts.js +84 -0
- package/dist/goal/store.d.ts +64 -0
- package/dist/goal/store.js +174 -0
- package/dist/goal/tools.d.ts +13 -0
- package/dist/goal/tools.js +67 -0
- package/dist/goal/usage.d.ts +2 -0
- package/dist/goal/usage.js +3 -0
- package/dist/hooks/config.d.ts +9 -0
- package/dist/hooks/config.js +278 -0
- package/dist/hooks/controller.d.ts +24 -0
- package/dist/hooks/controller.js +254 -0
- package/dist/hooks/index.d.ts +6 -0
- package/dist/hooks/index.js +4 -0
- package/dist/hooks/log.d.ts +14 -0
- package/dist/hooks/log.js +54 -0
- package/dist/hooks/runner.d.ts +5 -0
- package/dist/hooks/runner.js +225 -0
- package/dist/hooks/trust.d.ts +37 -0
- package/dist/hooks/trust.js +143 -0
- package/dist/hooks/types.d.ts +173 -0
- package/dist/hooks/types.js +46 -0
- package/dist/loop/engine.d.ts +29 -0
- package/dist/loop/engine.js +63 -0
- package/dist/lsp/config.d.ts +18 -0
- package/dist/lsp/config.js +58 -0
- package/dist/lsp/diagnostics.d.ts +24 -0
- package/dist/lsp/diagnostics.js +103 -0
- package/dist/lsp/index.d.ts +3 -0
- package/dist/lsp/index.js +3 -0
- package/dist/lsp/service.d.ts +97 -0
- package/dist/lsp/service.js +815 -0
- package/dist/main.d.ts +5 -0
- package/dist/main.js +984 -0
- package/dist/mcp/client.d.ts +68 -0
- package/dist/mcp/client.js +177 -0
- package/dist/mcp/config.d.ts +30 -0
- package/dist/mcp/config.js +144 -0
- package/dist/mcp/manager.d.ts +67 -0
- package/dist/mcp/manager.js +328 -0
- package/dist/mcp/name.d.ts +26 -0
- package/dist/mcp/name.js +40 -0
- package/dist/mcp/transports.d.ts +54 -0
- package/dist/mcp/transports.js +267 -0
- package/dist/mcp/types.d.ts +111 -0
- package/dist/mcp/types.js +14 -0
- package/dist/memory/db.d.ts +65 -0
- package/dist/memory/db.js +332 -0
- package/dist/memory/index.d.ts +10 -0
- package/dist/memory/index.js +10 -0
- package/dist/memory/paths.d.ts +18 -0
- package/dist/memory/paths.js +38 -0
- package/dist/memory/phase1.d.ts +23 -0
- package/dist/memory/phase1.js +292 -0
- package/dist/memory/phase2.d.ts +19 -0
- package/dist/memory/phase2.js +119 -0
- package/dist/memory/prompts.d.ts +19 -0
- package/dist/memory/prompts.js +104 -0
- package/dist/memory/reset.d.ts +1 -0
- package/dist/memory/reset.js +13 -0
- package/dist/memory/session-policy.d.ts +25 -0
- package/dist/memory/session-policy.js +55 -0
- package/dist/memory/start.d.ts +24 -0
- package/dist/memory/start.js +50 -0
- package/dist/memory/storage.d.ts +11 -0
- package/dist/memory/storage.js +95 -0
- package/dist/memory/store.d.ts +43 -0
- package/dist/memory/store.js +193 -0
- package/dist/memory/usage.d.ts +1 -0
- package/dist/memory/usage.js +38 -0
- package/dist/model-catalog.d.ts +65 -0
- package/dist/model-catalog.js +387 -0
- package/dist/model-config.d.ts +40 -0
- package/dist/model-config.js +74 -0
- package/dist/model-data.generated.d.ts +16 -0
- package/dist/model-data.generated.js +275 -0
- package/dist/model-pricing.d.ts +54 -0
- package/dist/model-pricing.js +244 -0
- package/dist/model-selection.d.ts +7 -0
- package/dist/model-selection.js +18 -0
- package/dist/network/chatgpt-transport.d.ts +16 -0
- package/dist/network/chatgpt-transport.js +232 -0
- package/dist/network/errors.d.ts +47 -0
- package/dist/network/errors.js +48 -0
- package/dist/network/provider-transport-log.d.ts +12 -0
- package/dist/network/provider-transport-log.js +32 -0
- package/dist/network/provider-transport.d.ts +37 -0
- package/dist/network/provider-transport.js +256 -0
- package/dist/network/retry.d.ts +34 -0
- package/dist/network/retry.js +97 -0
- package/dist/network/system-proxy.d.ts +18 -0
- package/dist/network/system-proxy.js +175 -0
- package/dist/oauth/grok.d.ts +26 -0
- package/dist/oauth/grok.js +251 -0
- package/dist/oauth/index.d.ts +4 -0
- package/dist/oauth/index.js +3 -0
- package/dist/oauth/openai-codex.d.ts +15 -0
- package/dist/oauth/openai-codex.js +193 -0
- package/dist/oauth/refresh-control.d.ts +12 -0
- package/dist/oauth/refresh-control.js +42 -0
- package/dist/oauth/storage.d.ts +88 -0
- package/dist/oauth/storage.js +357 -0
- package/dist/oauth/types.d.ts +15 -0
- package/dist/oauth/types.js +1 -0
- package/dist/orchestrator/default-hooks.d.ts +22 -0
- package/dist/orchestrator/default-hooks.js +127 -0
- package/dist/orchestrator/hooks.d.ts +69 -0
- package/dist/orchestrator/hooks.js +52 -0
- package/dist/permission/mode.d.ts +19 -0
- package/dist/permission/mode.js +16 -0
- package/dist/permissions/rule.d.ts +42 -0
- package/dist/permissions/rule.js +293 -0
- package/dist/permissions/settings.d.ts +97 -0
- package/dist/permissions/settings.js +289 -0
- package/dist/permissions/shell-command.d.ts +36 -0
- package/dist/permissions/shell-command.js +226 -0
- package/dist/permissions/trust-prompt.d.ts +10 -0
- package/dist/permissions/trust-prompt.js +34 -0
- package/dist/permissions/trust.d.ts +26 -0
- package/dist/permissions/trust.js +113 -0
- package/dist/permissions/types.d.ts +61 -0
- package/dist/permissions/types.js +14 -0
- package/dist/print-output.d.ts +98 -0
- package/dist/print-output.js +117 -0
- package/dist/prompt/compose.d.ts +19 -0
- package/dist/prompt/compose.js +110 -0
- package/dist/prompt/delegation.d.ts +14 -0
- package/dist/prompt/delegation.js +100 -0
- package/dist/prompt/environment.d.ts +12 -0
- package/dist/prompt/environment.js +55 -0
- package/dist/prompt/provider-prompts/anthropic.d.ts +1 -0
- package/dist/prompt/provider-prompts/anthropic.js +5 -0
- package/dist/prompt/provider-prompts/codex.d.ts +1 -0
- package/dist/prompt/provider-prompts/codex.js +5 -0
- package/dist/prompt/provider-prompts/deepseek.d.ts +1 -0
- package/dist/prompt/provider-prompts/deepseek.js +7 -0
- package/dist/prompt/provider-prompts/default.d.ts +1 -0
- package/dist/prompt/provider-prompts/default.js +6 -0
- package/dist/prompt/provider-prompts/gemini.d.ts +1 -0
- package/dist/prompt/provider-prompts/gemini.js +5 -0
- package/dist/prompt/provider-prompts/glm.d.ts +1 -0
- package/dist/prompt/provider-prompts/glm.js +7 -0
- package/dist/prompt/provider-prompts/gpt.d.ts +1 -0
- package/dist/prompt/provider-prompts/gpt.js +5 -0
- package/dist/prompt/provider-prompts/kimi.d.ts +1 -0
- package/dist/prompt/provider-prompts/kimi.js +8 -0
- package/dist/prompt/reminders.d.ts +33 -0
- package/dist/prompt/reminders.js +135 -0
- package/dist/prompt/routing.d.ts +14 -0
- package/dist/prompt/routing.js +71 -0
- package/dist/prompt/runtime.d.ts +12 -0
- package/dist/prompt/runtime.js +40 -0
- package/dist/prompt/task-reminders.d.ts +12 -0
- package/dist/prompt/task-reminders.js +64 -0
- package/dist/provider-ai-sdk.d.ts +59 -0
- package/dist/provider-ai-sdk.js +541 -0
- package/dist/provider-anthropic.d.ts +126 -0
- package/dist/provider-anthropic.js +940 -0
- package/dist/provider-ark-responses.d.ts +29 -0
- package/dist/provider-ark-responses.js +518 -0
- package/dist/provider-artifacts.d.ts +7 -0
- package/dist/provider-artifacts.js +60 -0
- package/dist/provider-error-record.d.ts +43 -0
- package/dist/provider-error-record.js +213 -0
- package/dist/provider-grok.d.ts +50 -0
- package/dist/provider-grok.js +110 -0
- package/dist/provider-model-policy.d.ts +16 -0
- package/dist/provider-model-policy.js +33 -0
- package/dist/provider-openai-codex.d.ts +66 -0
- package/dist/provider-openai-codex.js +781 -0
- package/dist/provider-registry.d.ts +197 -0
- package/dist/provider-registry.js +1194 -0
- package/dist/provider-transform.d.ts +12 -0
- package/dist/provider-transform.js +293 -0
- package/dist/provider-zen-errors.d.ts +9 -0
- package/dist/provider-zen-errors.js +36 -0
- package/dist/provider.d.ts +85 -0
- package/dist/provider.js +925 -0
- package/dist/question/controller.d.ts +22 -0
- package/dist/question/controller.js +98 -0
- package/dist/question/index.d.ts +2 -0
- package/dist/question/index.js +2 -0
- package/dist/question/normalize.d.ts +6 -0
- package/dist/question/normalize.js +11 -0
- package/dist/question/types.d.ts +42 -0
- package/dist/question/types.js +6 -0
- package/dist/reasoning-debug.d.ts +7 -0
- package/dist/reasoning-debug.js +33 -0
- package/dist/rewind.d.ts +20 -0
- package/dist/rewind.js +29 -0
- package/dist/sdk/index.d.ts +319 -0
- package/dist/sdk/index.js +1068 -0
- package/dist/sdk/replay-event-log.d.ts +26 -0
- package/dist/sdk/replay-event-log.js +122 -0
- package/dist/sdk/session-turn-coordinator.d.ts +45 -0
- package/dist/sdk/session-turn-coordinator.js +227 -0
- package/dist/session-context-fence.d.ts +16 -0
- package/dist/session-context-fence.js +26 -0
- package/dist/session-log.d.ts +25 -0
- package/dist/session-log.js +444 -0
- package/dist/session-title.d.ts +16 -0
- package/dist/session-title.js +131 -0
- package/dist/session-types.d.ts +86 -0
- package/dist/session-types.js +1 -0
- package/dist/session.d.ts +135 -0
- package/dist/session.js +664 -0
- package/dist/skills/discovery.d.ts +12 -0
- package/dist/skills/discovery.js +166 -0
- package/dist/skills/format.d.ts +32 -0
- package/dist/skills/format.js +68 -0
- package/dist/skills/frontmatter.d.ts +5 -0
- package/dist/skills/frontmatter.js +60 -0
- package/dist/skills/invocation.d.ts +8 -0
- package/dist/skills/invocation.js +33 -0
- package/dist/skills/registry.d.ts +28 -0
- package/dist/skills/registry.js +79 -0
- package/dist/skills/types.d.ts +34 -0
- package/dist/skills/types.js +1 -0
- package/dist/slash-commands/commands.d.ts +10 -0
- package/dist/slash-commands/commands.js +1251 -0
- package/dist/slash-commands/feishu.d.ts +17 -0
- package/dist/slash-commands/feishu.js +400 -0
- package/dist/slash-commands/index.d.ts +4 -0
- package/dist/slash-commands/index.js +8 -0
- package/dist/slash-commands/registry.d.ts +32 -0
- package/dist/slash-commands/registry.js +73 -0
- package/dist/slash-commands/types.d.ts +109 -0
- package/dist/slash-commands/types.js +1 -0
- package/dist/slash-commands/unified.d.ts +38 -0
- package/dist/slash-commands/unified.js +38 -0
- package/dist/stats/usage.d.ts +59 -0
- package/dist/stats/usage.js +485 -0
- package/dist/stream-json.d.ts +13 -0
- package/dist/stream-json.js +74 -0
- package/dist/system-prompt.d.ts +40 -0
- package/dist/system-prompt.js +7 -0
- package/dist/tasks/manager.d.ts +145 -0
- package/dist/tasks/manager.js +634 -0
- package/dist/tasks/process-utils.d.ts +10 -0
- package/dist/tasks/process-utils.js +49 -0
- package/dist/tasks/promotion.d.ts +17 -0
- package/dist/tasks/promotion.js +30 -0
- package/dist/tasks/wake.d.ts +53 -0
- package/dist/tasks/wake.js +125 -0
- package/dist/text-display.d.ts +3 -0
- package/dist/text-display.js +25 -0
- package/dist/tools/agent-lifecycle.d.ts +30 -0
- package/dist/tools/agent-lifecycle.js +790 -0
- package/dist/tools/bash.d.ts +23 -0
- package/dist/tools/bash.js +443 -0
- package/dist/tools/child-tools.d.ts +41 -0
- package/dist/tools/child-tools.js +122 -0
- package/dist/tools/edit-apply.d.ts +25 -0
- package/dist/tools/edit-apply.js +274 -0
- package/dist/tools/edit.d.ts +18 -0
- package/dist/tools/edit.js +200 -0
- package/dist/tools/exa-mcp.d.ts +3 -0
- package/dist/tools/exa-mcp.js +74 -0
- package/dist/tools/exit-plan-mode.d.ts +22 -0
- package/dist/tools/exit-plan-mode.js +79 -0
- package/dist/tools/file-mutation-queue.d.ts +2 -0
- package/dist/tools/file-mutation-queue.js +43 -0
- package/dist/tools/file-state.d.ts +48 -0
- package/dist/tools/file-state.js +76 -0
- package/dist/tools/grep.d.ts +9 -0
- package/dist/tools/grep.js +387 -0
- package/dist/tools/index.d.ts +63 -0
- package/dist/tools/index.js +76 -0
- package/dist/tools/ls.d.ts +3 -0
- package/dist/tools/ls.js +85 -0
- package/dist/tools/lsp.d.ts +4 -0
- package/dist/tools/lsp.js +95 -0
- package/dist/tools/memory.d.ts +8 -0
- package/dist/tools/memory.js +77 -0
- package/dist/tools/path-utils.d.ts +8 -0
- package/dist/tools/path-utils.js +53 -0
- package/dist/tools/prompt-metadata.d.ts +3 -0
- package/dist/tools/prompt-metadata.js +17 -0
- package/dist/tools/question.d.ts +3 -0
- package/dist/tools/question.js +177 -0
- package/dist/tools/read.d.ts +8 -0
- package/dist/tools/read.js +309 -0
- package/dist/tools/sensitive-paths.d.ts +11 -0
- package/dist/tools/sensitive-paths.js +106 -0
- package/dist/tools/server-manager.d.ts +6 -0
- package/dist/tools/server-manager.js +6 -0
- package/dist/tools/server.d.ts +6 -0
- package/dist/tools/server.js +249 -0
- package/dist/tools/skill-search.d.ts +10 -0
- package/dist/tools/skill-search.js +134 -0
- package/dist/tools/skill.d.ts +7 -0
- package/dist/tools/skill.js +81 -0
- package/dist/tools/task-tools.d.ts +10 -0
- package/dist/tools/task-tools.js +133 -0
- package/dist/tools/tool-search.d.ts +23 -0
- package/dist/tools/tool-search.js +145 -0
- package/dist/tools/web-fetch.d.ts +6 -0
- package/dist/tools/web-fetch.js +76 -0
- package/dist/tools/web-search.d.ts +5 -0
- package/dist/tools/web-search.js +50 -0
- package/dist/tools/write.d.ts +10 -0
- package/dist/tools/write.js +155 -0
- package/dist/tui/animation-clock.d.ts +14 -0
- package/dist/tui/animation-clock.js +34 -0
- package/dist/tui/app.d.ts +176 -0
- package/dist/tui/app.js +1659 -0
- package/dist/tui/components/approval-dialog.d.ts +43 -0
- package/dist/tui/components/approval-dialog.js +212 -0
- package/dist/tui/components/bottom-sheet.d.ts +9 -0
- package/dist/tui/components/bottom-sheet.js +32 -0
- package/dist/tui/components/context-info.d.ts +54 -0
- package/dist/tui/components/context-info.js +388 -0
- package/dist/tui/components/feedback-dialog.d.ts +56 -0
- package/dist/tui/components/feedback-dialog.js +262 -0
- package/dist/tui/components/feishu-setup-dialog.d.ts +65 -0
- package/dist/tui/components/feishu-setup-dialog.js +332 -0
- package/dist/tui/components/image-preview.d.ts +32 -0
- package/dist/tui/components/image-preview.js +130 -0
- package/dist/tui/components/plan-dialog.d.ts +34 -0
- package/dist/tui/components/plan-dialog.js +196 -0
- package/dist/tui/components/provider-key-input.d.ts +18 -0
- package/dist/tui/components/provider-key-input.js +49 -0
- package/dist/tui/components/question-dialog.d.ts +25 -0
- package/dist/tui/components/question-dialog.js +263 -0
- package/dist/tui/components/responsive-transcript.d.ts +31 -0
- package/dist/tui/components/responsive-transcript.js +77 -0
- package/dist/tui/components/rewind-picker.d.ts +62 -0
- package/dist/tui/components/rewind-picker.js +317 -0
- package/dist/tui/components/session-picker.d.ts +49 -0
- package/dist/tui/components/session-picker.js +303 -0
- package/dist/tui/components/skills-panel.d.ts +63 -0
- package/dist/tui/components/skills-panel.js +582 -0
- package/dist/tui/components/stats-panel.d.ts +40 -0
- package/dist/tui/components/stats-panel.js +301 -0
- package/dist/tui/components/streaming-message.d.ts +69 -0
- package/dist/tui/components/streaming-message.js +398 -0
- package/dist/tui/components/subagent-inspector.d.ts +28 -0
- package/dist/tui/components/subagent-inspector.js +127 -0
- package/dist/tui/components/task-inspector.d.ts +26 -0
- package/dist/tui/components/task-inspector.js +70 -0
- package/dist/tui/components/tasks-pane.d.ts +126 -0
- package/dist/tui/components/tasks-pane.js +566 -0
- package/dist/tui/components/transcript.d.ts +103 -0
- package/dist/tui/components/transcript.js +858 -0
- package/dist/tui/components/welcome.d.ts +20 -0
- package/dist/tui/components/welcome.js +133 -0
- package/dist/tui/components/workflow-inspector.d.ts +30 -0
- package/dist/tui/components/workflow-inspector.js +136 -0
- package/dist/tui/composer-autocomplete.d.ts +76 -0
- package/dist/tui/composer-autocomplete.js +465 -0
- package/dist/tui/composer-style.d.ts +7 -0
- package/dist/tui/composer-style.js +29 -0
- package/dist/tui/controller/agent-event-reducer.d.ts +75 -0
- package/dist/tui/controller/agent-event-reducer.js +239 -0
- package/dist/tui/controller/composer-controller.d.ts +95 -0
- package/dist/tui/controller/composer-controller.js +502 -0
- package/dist/tui/controller/controller.d.ts +199 -0
- package/dist/tui/controller/controller.js +1034 -0
- package/dist/tui/controller/effects.d.ts +71 -0
- package/dist/tui/controller/effects.js +1 -0
- package/dist/tui/controller/goal-runtime-controller.d.ts +47 -0
- package/dist/tui/controller/goal-runtime-controller.js +202 -0
- package/dist/tui/controller/input-queue-machine.d.ts +71 -0
- package/dist/tui/controller/input-queue-machine.js +121 -0
- package/dist/tui/controller/intents.d.ts +56 -0
- package/dist/tui/controller/intents.js +6 -0
- package/dist/tui/controller/overlay-controller.d.ts +64 -0
- package/dist/tui/controller/overlay-controller.js +129 -0
- package/dist/tui/controller/ports.d.ts +57 -0
- package/dist/tui/controller/ports.js +9 -0
- package/dist/tui/controller/session-transition.d.ts +54 -0
- package/dist/tui/controller/session-transition.js +68 -0
- package/dist/tui/controller/state.d.ts +14 -0
- package/dist/tui/controller/state.js +36 -0
- package/dist/tui/controller/task-runtime-controller.d.ts +66 -0
- package/dist/tui/controller/task-runtime-controller.js +158 -0
- package/dist/tui/detect-theme.d.ts +4 -0
- package/dist/tui/detect-theme.js +116 -0
- package/dist/tui/display-history.d.ts +64 -0
- package/dist/tui/display-history.js +283 -0
- package/dist/tui/display-sanitizer.d.ts +3 -0
- package/dist/tui/display-sanitizer.js +38 -0
- package/dist/tui/edit-diff.d.ts +11 -0
- package/dist/tui/edit-diff.js +57 -0
- package/dist/tui/file-mentions.d.ts +29 -0
- package/dist/tui/file-mentions.js +174 -0
- package/dist/tui/footer.d.ts +37 -0
- package/dist/tui/footer.js +80 -0
- package/dist/tui/formatting/edit-diff.d.ts +11 -0
- package/dist/tui/formatting/edit-diff.js +52 -0
- package/dist/tui/formatting/summary.d.ts +43 -0
- package/dist/tui/formatting/summary.js +150 -0
- package/dist/tui/fullscreen.d.ts +48 -0
- package/dist/tui/fullscreen.js +256 -0
- package/dist/tui/image-display.d.ts +23 -0
- package/dist/tui/image-display.js +92 -0
- package/dist/tui/image-paste.d.ts +113 -0
- package/dist/tui/image-paste.js +565 -0
- package/dist/tui/input-history.d.ts +47 -0
- package/dist/tui/input-history.js +250 -0
- package/dist/tui/markdown-style.d.ts +5 -0
- package/dist/tui/markdown-style.js +23 -0
- package/dist/tui/model/composer-buffer.d.ts +55 -0
- package/dist/tui/model/composer-buffer.js +317 -0
- package/dist/tui/model/composer-types.d.ts +17 -0
- package/dist/tui/model/composer-types.js +1 -0
- package/dist/tui/model/display-history.d.ts +78 -0
- package/dist/tui/model/display-history.js +124 -0
- package/dist/tui/model/display-reconstruct.d.ts +3 -0
- package/dist/tui/model/display-reconstruct.js +130 -0
- package/dist/tui/model/file-mentions.d.ts +31 -0
- package/dist/tui/model/file-mentions.js +178 -0
- package/dist/tui/model/image-attachment.d.ts +15 -0
- package/dist/tui/model/image-attachment.js +1 -0
- package/dist/tui/model/image-paste.d.ts +119 -0
- package/dist/tui/model/image-paste.js +610 -0
- package/dist/tui/model/input-history.d.ts +1 -0
- package/dist/tui/model/input-history.js +1 -0
- package/dist/tui/model/input-queue.d.ts +12 -0
- package/dist/tui/model/input-queue.js +17 -0
- package/dist/tui/model/key-events.d.ts +9 -0
- package/dist/tui/model/key-events.js +8 -0
- package/dist/tui/model/paste-operation-tracker.d.ts +13 -0
- package/dist/tui/model/paste-operation-tracker.js +25 -0
- package/dist/tui/model/recent-activity.d.ts +8 -0
- package/dist/tui/model/recent-activity.js +71 -0
- package/dist/tui/model/subagent-view.d.ts +87 -0
- package/dist/tui/model/subagent-view.js +336 -0
- package/dist/tui/model/submit-dedupe.d.ts +5 -0
- package/dist/tui/model/submit-dedupe.js +25 -0
- package/dist/tui/model/sync-output.d.ts +17 -0
- package/dist/tui/model/sync-output.js +35 -0
- package/dist/tui/model/task-lifecycle.d.ts +57 -0
- package/dist/tui/model/task-lifecycle.js +124 -0
- package/dist/tui/model/terminal-env.d.ts +15 -0
- package/dist/tui/model/terminal-env.js +22 -0
- package/dist/tui/model/terminal-mouse.d.ts +28 -0
- package/dist/tui/model/terminal-mouse.js +82 -0
- package/dist/tui/model/theme-style.d.ts +10 -0
- package/dist/tui/model/theme-style.js +79 -0
- package/dist/tui/model/theme.d.ts +72 -0
- package/dist/tui/model/theme.js +121 -0
- package/dist/tui/model/trace-groups.d.ts +45 -0
- package/dist/tui/model/trace-groups.js +558 -0
- package/dist/tui/model/trace-interaction.d.ts +63 -0
- package/dist/tui/model/trace-interaction.js +87 -0
- package/dist/tui/model/width.d.ts +18 -0
- package/dist/tui/model/width.js +130 -0
- package/dist/tui/model-picker-data.d.ts +9 -0
- package/dist/tui/model-picker-data.js +39 -0
- package/dist/tui/model-switch.d.ts +49 -0
- package/dist/tui/model-switch.js +67 -0
- package/dist/tui/paste-placeholder.d.ts +11 -0
- package/dist/tui/paste-placeholder.js +52 -0
- package/dist/tui/recent-activity.d.ts +8 -0
- package/dist/tui/recent-activity.js +71 -0
- package/dist/tui/run-session-picker.d.ts +9 -0
- package/dist/tui/run-session-picker.js +64 -0
- package/dist/tui/run.d.ts +72 -0
- package/dist/tui/run.js +139 -0
- package/dist/tui/session-display.d.ts +6 -0
- package/dist/tui/session-display.js +12 -0
- package/dist/tui/session-picker-data.d.ts +18 -0
- package/dist/tui/session-picker-data.js +21 -0
- package/dist/tui/terminal/multiplexer.d.ts +5 -0
- package/dist/tui/terminal/multiplexer.js +14 -0
- package/dist/tui/testing/fake-agent.d.ts +24 -0
- package/dist/tui/testing/fake-agent.js +22 -0
- package/dist/tui/testing/spy-host.d.ts +21 -0
- package/dist/tui/testing/spy-host.js +55 -0
- package/dist/tui/trace-groups.d.ts +43 -0
- package/dist/tui/trace-groups.js +554 -0
- package/dist/tui/wordmark.d.ts +18 -0
- package/dist/tui/wordmark.js +208 -0
- package/dist/types.d.ts +503 -0
- package/dist/types.js +4 -0
- package/dist/update/index.d.ts +61 -0
- package/dist/update/index.js +267 -0
- package/dist/variant/thinking-level.d.ts +5 -0
- package/dist/variant/thinking-level.js +26 -0
- package/dist/variant/variant-resolver.d.ts +28 -0
- package/dist/variant/variant-resolver.js +62 -0
- package/node_modules/@bubblebrain-ai/pi-tui/LICENSE +21 -0
- package/node_modules/@bubblebrain-ai/pi-tui/README.md +854 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/alt-screen-search.d.ts +26 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/alt-screen-search.d.ts.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/alt-screen-search.js +121 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/alt-screen-search.js.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/autocomplete.d.ts +86 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/autocomplete.d.ts.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/autocomplete.js +649 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/autocomplete.js.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/alt-screen-flash.d.ts +13 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/alt-screen-flash.d.ts.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/alt-screen-flash.js +36 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/alt-screen-flash.js.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/box.d.ts +22 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/box.d.ts.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/box.js +99 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/box.js.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/cancellable-loader.d.ts +22 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/cancellable-loader.d.ts.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/cancellable-loader.js +36 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/cancellable-loader.js.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/editor.d.ts +330 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/editor.d.ts.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/editor.js +2344 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/editor.js.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/h-stack.d.ts +7 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/h-stack.d.ts.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/h-stack.js +43 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/h-stack.js.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/image.d.ts +28 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/image.d.ts.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/image.js +82 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/image.js.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/input.d.ts +48 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/input.d.ts.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/input.js +390 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/input.js.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/loader.d.ts +31 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/loader.d.ts.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/loader.js +67 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/loader.js.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/markdown.d.ts +103 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/markdown.d.ts.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/markdown.js +797 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/markdown.js.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/scroll-view.d.ts +56 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/scroll-view.d.ts.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/scroll-view.js +179 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/scroll-view.js.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/select-list.d.ts +53 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/select-list.d.ts.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/select-list.js +175 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/select-list.js.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/settings-list.d.ts +50 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/settings-list.d.ts.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/settings-list.js +174 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/settings-list.js.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/spacer.d.ts +12 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/spacer.d.ts.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/spacer.js +22 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/spacer.js.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/stack.d.ts +32 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/stack.d.ts.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/stack.js +109 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/stack.js.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/text.d.ts +19 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/text.d.ts.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/text.js +81 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/text.js.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/truncated-text.d.ts +13 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/truncated-text.d.ts.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/truncated-text.js +48 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/truncated-text.js.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/v-stack.d.ts +8 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/v-stack.d.ts.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/v-stack.js +26 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/v-stack.js.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/editor-component.d.ts +39 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/editor-component.d.ts.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/editor-component.js +2 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/editor-component.js.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/fuzzy.d.ts +16 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/fuzzy.d.ts.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/fuzzy.js +110 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/fuzzy.js.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/index.d.ts +31 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/index.d.ts.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/index.js +42 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/index.js.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/keybindings.d.ts +273 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/keybindings.d.ts.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/keybindings.js +231 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/keybindings.js.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/keys.d.ts +184 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/keys.d.ts.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/keys.js +1174 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/keys.js.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/kill-ring.d.ts +28 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/kill-ring.d.ts.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/kill-ring.js +46 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/kill-ring.js.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/latex.d.ts +10 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/latex.d.ts.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/latex.js +1268 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/latex.js.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/layout-node.d.ts +40 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/layout-node.d.ts.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/layout-node.js +6 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/layout-node.js.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/layout.d.ts +42 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/layout.d.ts.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/layout.js +335 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/layout.js.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/native-modifiers.d.ts +3 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/native-modifiers.d.ts.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/native-modifiers.js +60 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/native-modifiers.js.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/stdin-buffer.d.ts +56 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/stdin-buffer.d.ts.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/stdin-buffer.js +363 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/stdin-buffer.js.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/terminal-colors.d.ts +10 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/terminal-colors.d.ts.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/terminal-colors.js +59 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/terminal-colors.js.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/terminal-image.d.ts +116 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/terminal-image.d.ts.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/terminal-image.js +518 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/terminal-image.js.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/terminal.d.ts +142 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/terminal.d.ts.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/terminal.js +544 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/terminal.js.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/testing.d.ts +11 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/testing.d.ts.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/testing.js +11 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/testing.js.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/tui-alt-screen.d.ts +141 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/tui-alt-screen.d.ts.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/tui-alt-screen.js +1340 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/tui-alt-screen.js.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/tui-main-screen.d.ts +39 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/tui-main-screen.d.ts.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/tui-main-screen.js +536 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/tui-main-screen.js.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/tui.d.ts +340 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/tui.d.ts.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/tui.js +1020 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/tui.js.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/undo-stack.d.ts +17 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/undo-stack.d.ts.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/undo-stack.js +27 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/undo-stack.js.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/utils.d.ts +96 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/utils.d.ts.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/utils.js +1193 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/utils.js.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/word-navigation.d.ts +25 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/word-navigation.d.ts.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/word-navigation.js +96 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/src/word-navigation.js.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/test/virtual-terminal.d.ts +73 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/test/virtual-terminal.d.ts.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/test/virtual-terminal.js +188 -0
- package/node_modules/@bubblebrain-ai/pi-tui/dist/test/virtual-terminal.js.map +1 -0
- package/node_modules/@bubblebrain-ai/pi-tui/native/darwin/README.md +20 -0
- package/node_modules/@bubblebrain-ai/pi-tui/native/darwin/build.sh +62 -0
- package/node_modules/@bubblebrain-ai/pi-tui/native/darwin/prebuilds/darwin-arm64/darwin-modifiers.node +0 -0
- package/node_modules/@bubblebrain-ai/pi-tui/native/darwin/prebuilds/darwin-x64/darwin-modifiers.node +0 -0
- package/node_modules/@bubblebrain-ai/pi-tui/native/darwin/src/darwin-modifiers.c +70 -0
- package/node_modules/@bubblebrain-ai/pi-tui/native/win32/README.md +22 -0
- package/node_modules/@bubblebrain-ai/pi-tui/native/win32/build.mjs +229 -0
- package/node_modules/@bubblebrain-ai/pi-tui/native/win32/prebuilds/win32-arm64/win32-console-mode.node +0 -0
- package/node_modules/@bubblebrain-ai/pi-tui/native/win32/prebuilds/win32-x64/win32-console-mode.node +0 -0
- package/node_modules/@bubblebrain-ai/pi-tui/native/win32/src/win32-console-mode.c +119 -0
- package/node_modules/@bubblebrain-ai/pi-tui/package.json +66 -0
- package/node_modules/get-east-asian-width/index.d.ts +60 -0
- package/node_modules/get-east-asian-width/index.js +30 -0
- package/node_modules/get-east-asian-width/license +9 -0
- package/node_modules/get-east-asian-width/lookup-data.js +21 -0
- package/node_modules/get-east-asian-width/lookup.js +138 -0
- package/node_modules/get-east-asian-width/package.json +71 -0
- package/node_modules/get-east-asian-width/readme.md +65 -0
- package/node_modules/get-east-asian-width/utilities.js +24 -0
- package/node_modules/marked/LICENSE +44 -0
- package/node_modules/marked/README.md +115 -0
- package/node_modules/marked/bin/main.js +284 -0
- package/node_modules/marked/bin/marked.js +16 -0
- package/node_modules/marked/lib/marked.d.ts +760 -0
- package/node_modules/marked/lib/marked.esm.js +77 -0
- package/node_modules/marked/lib/marked.esm.js.map +7 -0
- package/node_modules/marked/lib/marked.umd.js +79 -0
- package/node_modules/marked/lib/marked.umd.js.map +7 -0
- package/node_modules/marked/man/marked.1 +113 -0
- package/node_modules/marked/man/marked.1.md +93 -0
- package/node_modules/marked/package.json +103 -0
- package/package.json +96 -17
- package/bin/bubble.js +0 -39
package/dist/main.js
ADDED
|
@@ -0,0 +1,984 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Main entry point - assembles all layers and runs the agent.
|
|
4
|
+
*/
|
|
5
|
+
import chalk from "chalk";
|
|
6
|
+
import { Agent } from "./agent.js";
|
|
7
|
+
import { BudgetLedger } from "./agent/budget-ledger.js";
|
|
8
|
+
import { enterWorkingDirectory, parseArgs, printHelp } from "./cli.js";
|
|
9
|
+
import { effectiveThemeModeForTerminal, shouldProbeTerminalTheme, UserConfig } from "./config.js";
|
|
10
|
+
import { createProviderInstance, createUnavailableProvider } from "./provider.js";
|
|
11
|
+
import { resolveConfiguredModel } from "./model-selection.js";
|
|
12
|
+
import { getAvailableThinkingLevels, getDefaultThinkingLevel, normalizeThinkingLevel } from "./provider-transform.js";
|
|
13
|
+
import { ProviderRegistry, displayModel, encodeModel, decodeModel } from "./provider-registry.js";
|
|
14
|
+
import { SessionManager } from "./session.js";
|
|
15
|
+
import { SessionContextFence } from "./session-context-fence.js";
|
|
16
|
+
import { createSessionTitleUpdater } from "./session-title.js";
|
|
17
|
+
import { buildSystemPrompt } from "./system-prompt.js";
|
|
18
|
+
import { createRoutableModelIndex, createRoutingSnapshotAccessor } from "./agent/routing-catalog.js";
|
|
19
|
+
import { buildModelRoutingPrompt } from "./prompt/routing.js";
|
|
20
|
+
/** Upper bound on blocking startup for OAuth catalog discovery (one HTTP round trip normally). */
|
|
21
|
+
const MODEL_DISCOVERY_STARTUP_WAIT_MS = 3_000;
|
|
22
|
+
import { SkillRegistry } from "./skills/registry.js";
|
|
23
|
+
import { buildToolPromptOptions, createAllTools } from "./tools/index.js";
|
|
24
|
+
import { getProcessManager } from "./tasks/manager.js";
|
|
25
|
+
import { PromotionChannel } from "./tasks/promotion.js";
|
|
26
|
+
import { runStreamJsonSession } from "./stream-json.js";
|
|
27
|
+
import { PrintRunCollector, formatPrintJson, formatPrintJsonError } from "./print-output.js";
|
|
28
|
+
import { FileStateTracker } from "./tools/file-state.js";
|
|
29
|
+
import { GoalStore } from "./goal/store.js";
|
|
30
|
+
import { PermissionAwareApprovalController } from "./approval/controller.js";
|
|
31
|
+
import { BashAllowlist } from "./approval/session-cache.js";
|
|
32
|
+
import { SettingsManager } from "./permissions/settings.js";
|
|
33
|
+
import { ExternalHookController } from "./hooks/index.js";
|
|
34
|
+
import { getLspService } from "./lsp/index.js";
|
|
35
|
+
import { loadMcpConfig } from "./mcp/config.js";
|
|
36
|
+
import { promptRepoTrust } from "./permissions/trust-prompt.js";
|
|
37
|
+
import { McpManager, gateMcpTools } from "./mcp/manager.js";
|
|
38
|
+
import { normalizeInheritedThinkingLevel } from "./variant/variant-resolver.js";
|
|
39
|
+
import { QuestionController } from "./question/index.js";
|
|
40
|
+
import { buildMemoryPrompt, formatMemoryStartupResult, purgeUnsafeMemorySources, recordMemoryCitations, runMemoryPhase2, runMemoryStartupPipeline, startMemoryStartupTask, } from "./memory/index.js";
|
|
41
|
+
import { basename } from "node:path";
|
|
42
|
+
import { normalizeSingleLine, truncateVisual } from "./text-display.js";
|
|
43
|
+
import { BUBBLE_WORDMARK } from "./tui/wordmark.js";
|
|
44
|
+
import { configureDebugTrace, summarizeAgentEventForTrace, summarizeTraceMessage, traceEvent, } from "./debug-trace.js";
|
|
45
|
+
import { shouldRejectGrokSessionInPrintMode } from "./external-runtime/session-policy.js";
|
|
46
|
+
import { rmSync } from "node:fs";
|
|
47
|
+
import { splitLeadingContext } from "./context/compact.js";
|
|
48
|
+
async function main() {
|
|
49
|
+
const args = parseArgs(process.argv.slice(2));
|
|
50
|
+
if (process.argv.includes("-h") || process.argv.includes("--help")) {
|
|
51
|
+
printHelp();
|
|
52
|
+
process.exit(0);
|
|
53
|
+
}
|
|
54
|
+
if (process.argv.includes("-v") || process.argv.includes("--version")) {
|
|
55
|
+
const { getCurrentVersion } = await import("./update/index.js");
|
|
56
|
+
console.log(`v${getCurrentVersion()}`);
|
|
57
|
+
process.exit(0);
|
|
58
|
+
}
|
|
59
|
+
// --cwd means "run as if launched there" (like git -C): every layer, including
|
|
60
|
+
// the TUI, shell children and relative paths, then sees the same directory.
|
|
61
|
+
const cwdError = enterWorkingDirectory(args.cwd);
|
|
62
|
+
if (cwdError) {
|
|
63
|
+
console.error(`bubble: ${cwdError}`);
|
|
64
|
+
process.exit(1);
|
|
65
|
+
}
|
|
66
|
+
if (args.command === "update") {
|
|
67
|
+
const { runUpdateCommand } = await import("./update/index.js");
|
|
68
|
+
const code = await runUpdateCommand({ checkOnly: args.checkOnly });
|
|
69
|
+
process.exit(code);
|
|
70
|
+
}
|
|
71
|
+
if (args.command === "serve") {
|
|
72
|
+
if (args.serveHost !== "feishu") {
|
|
73
|
+
console.error(chalk.red("Usage: bubble serve --feishu [--setup | --kill-old | --dry-run]"));
|
|
74
|
+
process.exit(2);
|
|
75
|
+
}
|
|
76
|
+
const { serveFeishu } = await import("./feishu/index.js");
|
|
77
|
+
await serveFeishu({
|
|
78
|
+
setup: args.setup,
|
|
79
|
+
killOld: args.killOld,
|
|
80
|
+
dryRun: args.dryRun,
|
|
81
|
+
});
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
const userConfig = new UserConfig();
|
|
85
|
+
const registry = new ProviderRegistry(userConfig);
|
|
86
|
+
const skillRegistry = new SkillRegistry({
|
|
87
|
+
cwd: args.cwd,
|
|
88
|
+
skillPaths: userConfig.getSkillPaths(),
|
|
89
|
+
disabledSkills: userConfig.getDisabledSkills(),
|
|
90
|
+
onDisabledSkillsChange: (disabledSkills) => userConfig.setDisabledSkills(disabledSkills),
|
|
91
|
+
});
|
|
92
|
+
const printMode = args.print || !!args.prompt;
|
|
93
|
+
// Resolve configured providers only; do not auto-inject OpenRouter as a startup default.
|
|
94
|
+
const providers = registry.getConfigured();
|
|
95
|
+
if (providers.length === 0) {
|
|
96
|
+
if (printMode) {
|
|
97
|
+
console.error(chalk.red("Error: No provider configured. Start interactive mode and use /login or /provider --add <id>."));
|
|
98
|
+
process.exit(1);
|
|
99
|
+
}
|
|
100
|
+
console.log(chalk.dim("No provider configured yet. Start with /login for ChatGPT or Grok, or /provider --add <id> for an API key."));
|
|
101
|
+
}
|
|
102
|
+
const defaultProvider = registry.getDefault();
|
|
103
|
+
const unavailableProviderMessage = "No provider configured. Use /login for ChatGPT or Grok, or /provider --add <id> before sending a prompt.";
|
|
104
|
+
let sessionPromptCacheKey;
|
|
105
|
+
const provider = defaultProvider
|
|
106
|
+
? createProviderInstance({
|
|
107
|
+
providerId: defaultProvider.id,
|
|
108
|
+
apiKey: defaultProvider.apiKey,
|
|
109
|
+
baseURL: defaultProvider.baseURL,
|
|
110
|
+
thinkingLevel: args.thinkingLevel,
|
|
111
|
+
promptCacheKey: sessionPromptCacheKey,
|
|
112
|
+
protocol: defaultProvider.protocol,
|
|
113
|
+
headers: defaultProvider.headers,
|
|
114
|
+
openAICodexAuth: registry.createOpenAICodexAuthAdapter(defaultProvider.id),
|
|
115
|
+
grokAuth: registry.createGrokAuthAdapter(defaultProvider.id),
|
|
116
|
+
})
|
|
117
|
+
: createUnavailableProvider(unavailableProviderMessage);
|
|
118
|
+
const createProvider = (providerId, apiKey, baseURL) => {
|
|
119
|
+
const profile = registry.getConfigured().find((provider) => provider.id === providerId);
|
|
120
|
+
return createProviderInstance({
|
|
121
|
+
providerId,
|
|
122
|
+
apiKey,
|
|
123
|
+
baseURL,
|
|
124
|
+
thinkingLevel: args.thinkingLevel,
|
|
125
|
+
promptCacheKey: sessionPromptCacheKey,
|
|
126
|
+
protocol: profile?.protocol,
|
|
127
|
+
headers: profile?.headers,
|
|
128
|
+
openAICodexAuth: registry.createOpenAICodexAuthAdapter(providerId),
|
|
129
|
+
grokAuth: registry.createGrokAuthAdapter(providerId),
|
|
130
|
+
});
|
|
131
|
+
};
|
|
132
|
+
const createProviderForRoute = async (route) => {
|
|
133
|
+
const providerId = route.providerId;
|
|
134
|
+
if (!providerId) {
|
|
135
|
+
throw new Error(`Subagent route for model "${route.model}" did not include a provider.`);
|
|
136
|
+
}
|
|
137
|
+
if (registry.supportsOAuth(providerId) && registry.getAuthStorage().has(providerId)) {
|
|
138
|
+
await registry.prepareProvider(providerId);
|
|
139
|
+
}
|
|
140
|
+
const target = registry.getConfigured().find((item) => item.id === providerId);
|
|
141
|
+
if (!target?.enabled || !target.apiKey) {
|
|
142
|
+
throw new Error(`Subagent route requires provider "${providerId}", but it is not configured or has no active credentials.`);
|
|
143
|
+
}
|
|
144
|
+
return createProvider(providerId, target.apiKey, target.baseURL);
|
|
145
|
+
};
|
|
146
|
+
let agentRef;
|
|
147
|
+
const planHandlerRef = {};
|
|
148
|
+
const planController = {
|
|
149
|
+
getMode: () => agentRef?.mode ?? "default",
|
|
150
|
+
requestApproval: (plan) => planHandlerRef.current
|
|
151
|
+
? planHandlerRef.current(plan)
|
|
152
|
+
: Promise.resolve({
|
|
153
|
+
action: "reject",
|
|
154
|
+
reason: "No interactive UI available to approve the plan.",
|
|
155
|
+
}),
|
|
156
|
+
setMode: (mode) => {
|
|
157
|
+
agentRef?.setMode(mode);
|
|
158
|
+
},
|
|
159
|
+
};
|
|
160
|
+
const approvalHandlerRef = {};
|
|
161
|
+
const questionController = new QuestionController();
|
|
162
|
+
const bashAllowlist = new BashAllowlist();
|
|
163
|
+
// Folder trust (Kimi Code style): the repository's .bubble settings may
|
|
164
|
+
// enable allow rules, MCP servers and LSP servers; ask before loading them.
|
|
165
|
+
if (!printMode && process.stdin.isTTY && process.stdout.isTTY) {
|
|
166
|
+
await promptRepoTrust(args.cwd);
|
|
167
|
+
}
|
|
168
|
+
const settingsManager = new SettingsManager(args.cwd);
|
|
169
|
+
for (const d of settingsManager.getMerged().diagnostics) {
|
|
170
|
+
console.error(chalk.yellow(`[settings:${d.scope}] ${d.path}: ${d.message}`));
|
|
171
|
+
}
|
|
172
|
+
const hookController = new ExternalHookController({ cwd: args.cwd });
|
|
173
|
+
for (const d of hookController.getConfig().diagnostics) {
|
|
174
|
+
console.error(chalk.yellow(`[hooks:${d.scope}] ${d.path}: ${d.message}`));
|
|
175
|
+
}
|
|
176
|
+
const approvalController = new PermissionAwareApprovalController({
|
|
177
|
+
getMode: () => agentRef?.mode ?? "default",
|
|
178
|
+
handlerRef: approvalHandlerRef,
|
|
179
|
+
bashAllowlist,
|
|
180
|
+
sessionGrants: new Set(),
|
|
181
|
+
cwd: args.cwd,
|
|
182
|
+
getRuleSet: () => settingsManager.getMerged().ruleSet,
|
|
183
|
+
externalHooks: hookController,
|
|
184
|
+
});
|
|
185
|
+
const toolSearchController = {
|
|
186
|
+
listDeferred: () => agentRef?.listDeferredTools() ?? [],
|
|
187
|
+
unlock: (names) => agentRef?.unlockDeferredTools(names),
|
|
188
|
+
};
|
|
189
|
+
const lspService = getLspService(args.cwd, settingsManager.getMerged().lsp);
|
|
190
|
+
const fileStateTracker = new FileStateTracker(args.cwd);
|
|
191
|
+
// Shared between the goal tool (model-facing update_goal) and the
|
|
192
|
+
// TUI's auto-continuation engine / status-line indicator.
|
|
193
|
+
const goalStore = new GoalStore();
|
|
194
|
+
// Background tasks are TUI-only (design §2.0): print mode exits (and reaps)
|
|
195
|
+
// right after the single run, so a backgrounded command would be killed
|
|
196
|
+
// immediately after the model was told it started. Feishu/desktop hosts
|
|
197
|
+
// never reach this call site and stay off until they wire wake seams.
|
|
198
|
+
const processManager = getProcessManager();
|
|
199
|
+
const allowBackgroundTasks = !printMode;
|
|
200
|
+
const promotionChannel = new PromotionChannel();
|
|
201
|
+
const tools = createAllTools(args.cwd, skillRegistry, {
|
|
202
|
+
planController,
|
|
203
|
+
approvalController,
|
|
204
|
+
questionController: printMode ? undefined : questionController,
|
|
205
|
+
toolSearchController,
|
|
206
|
+
lspService,
|
|
207
|
+
fileStateTracker,
|
|
208
|
+
goalStore,
|
|
209
|
+
processManager,
|
|
210
|
+
allowBackgroundTasks,
|
|
211
|
+
promotionChannel,
|
|
212
|
+
autoBackgroundAfterMs: userConfig.getTasksAutoBackgroundAfterMs(),
|
|
213
|
+
// Lazy: sessionManager is resolved after tools are created.
|
|
214
|
+
checkpoints: () => sessionManager?.getCheckpoints(),
|
|
215
|
+
});
|
|
216
|
+
// Bring up MCP servers (if any). Failures are captured per-server and never
|
|
217
|
+
// block the rest of startup; /mcp surfaces status at runtime.
|
|
218
|
+
const mcpLoaded = loadMcpConfig({ cwd: args.cwd });
|
|
219
|
+
for (const d of mcpLoaded.diagnostics) {
|
|
220
|
+
console.error(chalk.yellow(`[mcp:${d.scope}] ${d.path}: ${d.message}`));
|
|
221
|
+
}
|
|
222
|
+
// Silent diagnostics: connect failures are captured per-server and shown by
|
|
223
|
+
// /mcp on demand. Printing them at startup (or mid-session, where stderr
|
|
224
|
+
// writes corrupt the Ink display) only duplicates that surface.
|
|
225
|
+
const mcpManager = new McpManager({ servers: mcpLoaded.servers, onDiagnostic: () => { } });
|
|
226
|
+
let externalRuntime;
|
|
227
|
+
if (mcpLoaded.servers.length > 0) {
|
|
228
|
+
await mcpManager.start();
|
|
229
|
+
tools.push(...gateMcpTools(mcpManager.getToolEntries(), approvalController));
|
|
230
|
+
}
|
|
231
|
+
// Expose MCP prompts as slash commands. Queried live at each lookup so
|
|
232
|
+
// /mcp reconnect picks up new prompts without restarting the process.
|
|
233
|
+
{
|
|
234
|
+
const { registry: slashRegistry } = await import("./slash-commands/index.js");
|
|
235
|
+
slashRegistry.addDynamicSource(() => mcpManager.getPromptCommands());
|
|
236
|
+
}
|
|
237
|
+
// Signal-based shutdown for Ctrl-C / kill. Normal /quit cleanup happens after
|
|
238
|
+
// the TUI renderer has been destroyed, avoiding native teardown races.
|
|
239
|
+
const shutdownMcp = async () => {
|
|
240
|
+
try {
|
|
241
|
+
await mcpManager.shutdown();
|
|
242
|
+
}
|
|
243
|
+
catch {
|
|
244
|
+
// ignore — we're exiting anyway
|
|
245
|
+
}
|
|
246
|
+
};
|
|
247
|
+
const shutdownExternalRuntime = async () => {
|
|
248
|
+
try {
|
|
249
|
+
await externalRuntime?.dispose();
|
|
250
|
+
}
|
|
251
|
+
catch {
|
|
252
|
+
// ignore — we're exiting anyway
|
|
253
|
+
}
|
|
254
|
+
};
|
|
255
|
+
const shutdownSidecars = async () => {
|
|
256
|
+
// Signal path (design §2.2b layer 2): kill-only, no escalation wait —
|
|
257
|
+
// the process is about to exit and shutdownRuntime never runs here.
|
|
258
|
+
processManager.reapTasksSync();
|
|
259
|
+
await Promise.allSettled([shutdownMcp(), shutdownExternalRuntime()]);
|
|
260
|
+
};
|
|
261
|
+
process.once("SIGINT", () => { void shutdownSidecars().then(() => process.exit(130)); });
|
|
262
|
+
process.once("SIGTERM", () => { void shutdownSidecars().then(() => process.exit(143)); });
|
|
263
|
+
// Session management:
|
|
264
|
+
// - default: always start a fresh session
|
|
265
|
+
// - --resume --session <name>: restore the named session
|
|
266
|
+
// - --resume (no name): show interactive picker
|
|
267
|
+
let sessionManager;
|
|
268
|
+
let resumedExistingSession = false;
|
|
269
|
+
// Resolved before any TUI render so picker and main TUI share the same value
|
|
270
|
+
// and we only run OSC 11 once.
|
|
271
|
+
let preResolvedTheme;
|
|
272
|
+
if (args.resume && !args.sessionName) {
|
|
273
|
+
const currentSessions = SessionManager.summarizeSessionsForCwd(args.cwd);
|
|
274
|
+
const allSessions = SessionManager.listAllSessions();
|
|
275
|
+
if (currentSessions.length === 0 && allSessions.length === 0) {
|
|
276
|
+
console.log(chalk.dim("No previous sessions found — starting a fresh one."));
|
|
277
|
+
}
|
|
278
|
+
else {
|
|
279
|
+
const themeConfig = userConfig.getTheme();
|
|
280
|
+
if (shouldProbeTerminalTheme(themeConfig)) {
|
|
281
|
+
const { detectTerminalTheme } = await import("./tui/detect-theme.js");
|
|
282
|
+
preResolvedTheme = await detectTerminalTheme();
|
|
283
|
+
}
|
|
284
|
+
else {
|
|
285
|
+
preResolvedTheme = themeConfig.mode === "light" ? "light" : "dark";
|
|
286
|
+
}
|
|
287
|
+
const pickerThemeMode = effectiveThemeModeForTerminal(themeConfig, preResolvedTheme);
|
|
288
|
+
const pickerResolvedTheme = pickerThemeMode === "auto" ? preResolvedTheme : pickerThemeMode;
|
|
289
|
+
const { runSessionPicker } = await import("./tui/run-session-picker.js");
|
|
290
|
+
const { canvasBackgroundFor } = await import("./tui/model/theme.js");
|
|
291
|
+
// Same rule as the main TUI: a forced theme mismatching the terminal
|
|
292
|
+
// paints its canvas so its foregrounds stay readable.
|
|
293
|
+
const pickerCanvas = themeConfig.overrides?.background
|
|
294
|
+
? undefined
|
|
295
|
+
: canvasBackgroundFor(pickerThemeMode, pickerResolvedTheme, preResolvedTheme);
|
|
296
|
+
const picked = await runSessionPicker({
|
|
297
|
+
currentCwd: args.cwd,
|
|
298
|
+
currentSessions,
|
|
299
|
+
allSessions,
|
|
300
|
+
resolvedTheme: pickerResolvedTheme,
|
|
301
|
+
themeOverrides: pickerCanvas
|
|
302
|
+
? { ...themeConfig.overrides, background: pickerCanvas }
|
|
303
|
+
: themeConfig.overrides,
|
|
304
|
+
});
|
|
305
|
+
if (picked) {
|
|
306
|
+
sessionManager = new SessionManager(picked);
|
|
307
|
+
resumedExistingSession = true;
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
else if (args.resume) {
|
|
312
|
+
sessionManager = SessionManager.resume(args.cwd, args.sessionName);
|
|
313
|
+
resumedExistingSession = !!sessionManager;
|
|
314
|
+
}
|
|
315
|
+
if (!sessionManager) {
|
|
316
|
+
sessionManager = args.sessionName && !args.resume
|
|
317
|
+
? SessionManager.create(args.cwd, args.sessionName)
|
|
318
|
+
: SessionManager.createFresh(args.cwd);
|
|
319
|
+
resumedExistingSession = false;
|
|
320
|
+
}
|
|
321
|
+
sessionPromptCacheKey = sessionManager.getOrCreatePromptCacheKey();
|
|
322
|
+
// Model resolution:
|
|
323
|
+
// 1. CLI flag 2. Session metadata 3. User-configured default model
|
|
324
|
+
// No implicit built-in model fallback.
|
|
325
|
+
const fallbackProviderId = defaultProvider?.id || "";
|
|
326
|
+
const sessionModel = sessionManager?.getMetadata().model;
|
|
327
|
+
const defaultModel = userConfig.getDefaultModel();
|
|
328
|
+
const sessionThinkingLevel = sessionManager?.getMetadata().thinkingLevel;
|
|
329
|
+
const configuredThinkingLevel = userConfig.getDefaultThinkingLevel();
|
|
330
|
+
const normalizedConfiguredModel = resolveConfiguredModel({
|
|
331
|
+
cliModel: args.model,
|
|
332
|
+
sessionModel,
|
|
333
|
+
defaultModel,
|
|
334
|
+
fallbackProviderId,
|
|
335
|
+
});
|
|
336
|
+
const { providerId: effectiveProviderId, modelId: effectiveModelId } = normalizedConfiguredModel
|
|
337
|
+
? decodeModel(normalizedConfiguredModel)
|
|
338
|
+
: { providerId: undefined, modelId: "" };
|
|
339
|
+
let activeProviderId = effectiveProviderId || fallbackProviderId;
|
|
340
|
+
// getConfigured() resolves the legacy openai-codex auth alias; the raw
|
|
341
|
+
// auth key would skip token refresh and discovery for such logins.
|
|
342
|
+
if (registry.getConfigured().find((item) => item.id === activeProviderId)?.authType === "oauth") {
|
|
343
|
+
try {
|
|
344
|
+
await registry.prepareProvider(activeProviderId);
|
|
345
|
+
}
|
|
346
|
+
catch (error) {
|
|
347
|
+
// A dead login must not lock the user out: /login only exists inside the
|
|
348
|
+
// session, so start anyway and let the first request surface the error.
|
|
349
|
+
console.error(chalk.yellow(`[auth] ${error instanceof Error ? error.message : String(error)}`));
|
|
350
|
+
}
|
|
351
|
+
// The routing prompt below is composed once; give the account catalog a
|
|
352
|
+
// bounded chance to land first so the menu the model reads matches what a
|
|
353
|
+
// spawn will actually get (design §1.5).
|
|
354
|
+
await registry.waitForModelDiscovery(activeProviderId, MODEL_DISCOVERY_STARTUP_WAIT_MS);
|
|
355
|
+
}
|
|
356
|
+
const activeProvider = registry.getConfigured().find((p) => p.id === activeProviderId) || defaultProvider;
|
|
357
|
+
const activeModel = activeProvider && effectiveModelId
|
|
358
|
+
? encodeModel(activeProviderId, effectiveModelId)
|
|
359
|
+
: "";
|
|
360
|
+
if (!activeModel && !activeProvider) {
|
|
361
|
+
activeProviderId = "";
|
|
362
|
+
}
|
|
363
|
+
const initialThinkingLevel = activeModel
|
|
364
|
+
? args.thinkingLevel !== undefined
|
|
365
|
+
? normalizeThinkingLevel(args.thinkingLevel, getAvailableThinkingLevels(activeProviderId, effectiveModelId))
|
|
366
|
+
: sessionThinkingLevel !== undefined
|
|
367
|
+
? normalizeInheritedThinkingLevel(activeProviderId, effectiveModelId, sessionThinkingLevel)
|
|
368
|
+
: configuredThinkingLevel !== undefined
|
|
369
|
+
? normalizeThinkingLevel(configuredThinkingLevel, getAvailableThinkingLevels(activeProviderId, effectiveModelId))
|
|
370
|
+
: getDefaultThinkingLevel(activeProviderId, effectiveModelId)
|
|
371
|
+
: (args.thinkingLevel ?? sessionThinkingLevel ?? configuredThinkingLevel ?? "off");
|
|
372
|
+
const initialMode = args.mode ?? "default";
|
|
373
|
+
const skillSummaries = skillRegistry.summaries();
|
|
374
|
+
// This synchronous provenance gate must run before buildMemoryPrompt: the
|
|
375
|
+
// background startup pipeline is too late once text has entered the native
|
|
376
|
+
// provider's system prompt.
|
|
377
|
+
purgeUnsafeMemorySources(args.cwd);
|
|
378
|
+
const memoryPrompt = buildMemoryPrompt(args.cwd);
|
|
379
|
+
// Routing snapshot accessor (model-routing design §1.5): built before the
|
|
380
|
+
// system prompt because startup composes the prompt before the Agent exists;
|
|
381
|
+
// the same accessor is then handed to the Agent constructor.
|
|
382
|
+
const agentRouting = userConfig.getAgentRouting();
|
|
383
|
+
const routingSnapshotAccessor = createRoutingSnapshotAccessor(registry, () => userConfig.getAgentCategories(), () => agentRouting);
|
|
384
|
+
const initialRoutingParent = activeProviderId && activeModel
|
|
385
|
+
? { providerId: activeProviderId, model: decodeModel(activeModel).modelId }
|
|
386
|
+
: undefined;
|
|
387
|
+
const systemPrompt = buildSystemPrompt({
|
|
388
|
+
agentName: "Bubble",
|
|
389
|
+
skills: skillSummaries,
|
|
390
|
+
skillCatalogChars: userConfig.getSkillCatalogChars(),
|
|
391
|
+
configuredProvider: activeProviderId || "none",
|
|
392
|
+
configuredModel: activeModel ? displayModel(activeModel) : "none",
|
|
393
|
+
configuredModelId: activeModel || "none",
|
|
394
|
+
thinkingLevel: initialThinkingLevel,
|
|
395
|
+
mode: initialMode,
|
|
396
|
+
workingDir: args.cwd,
|
|
397
|
+
...buildToolPromptOptions(tools.filter((tool) => !tool.deferred)),
|
|
398
|
+
memoryPrompt,
|
|
399
|
+
modelRoutingPrompt: initialRoutingParent
|
|
400
|
+
? buildModelRoutingPrompt(routingSnapshotAccessor(initialRoutingParent), agentRouting)
|
|
401
|
+
: undefined,
|
|
402
|
+
});
|
|
403
|
+
const traceInfo = configureDebugTrace({
|
|
404
|
+
cwd: args.cwd,
|
|
405
|
+
sessionFile: sessionManager?.getSessionFile(),
|
|
406
|
+
provider: activeProviderId || "none",
|
|
407
|
+
model: activeModel || "none",
|
|
408
|
+
renderer: printMode ? "print" : "pi-tui",
|
|
409
|
+
});
|
|
410
|
+
if (traceInfo.enabled) {
|
|
411
|
+
traceEvent("run_start", {
|
|
412
|
+
tracePath: traceInfo.path,
|
|
413
|
+
rawEnabled: traceInfo.rawEnabled,
|
|
414
|
+
resumed: resumedExistingSession,
|
|
415
|
+
printMode,
|
|
416
|
+
mode: initialMode,
|
|
417
|
+
thinkingLevel: initialThinkingLevel,
|
|
418
|
+
tools: tools.length,
|
|
419
|
+
cwd: args.cwd,
|
|
420
|
+
});
|
|
421
|
+
}
|
|
422
|
+
const budgetLedger = new BudgetLedger();
|
|
423
|
+
let sessionTitleUpdater;
|
|
424
|
+
let contextFence = new SessionContextFence(sessionManager);
|
|
425
|
+
// A fence rejection means the durable log diverged from this host's resident
|
|
426
|
+
// history (a foreign append/clear/rewind landed while a turn was in flight).
|
|
427
|
+
// The write is refused — and the resident transcript must roll back to the
|
|
428
|
+
// file's truth, or the rejected message lingers in the TUI while every later
|
|
429
|
+
// fenced write keeps failing on the stale revision until a manual reload.
|
|
430
|
+
const persistFenced = (write) => {
|
|
431
|
+
try {
|
|
432
|
+
write();
|
|
433
|
+
}
|
|
434
|
+
catch (error) {
|
|
435
|
+
// Any refused write (fence rejection, busy lock, I/O) leaves the agent's
|
|
436
|
+
// already-pushed message unpersisted, so always restore the file's truth.
|
|
437
|
+
try {
|
|
438
|
+
const history = contextFence.reloadHistory();
|
|
439
|
+
const head = splitLeadingContext(agent.messages).leading;
|
|
440
|
+
agent.messages = [...head, ...history];
|
|
441
|
+
}
|
|
442
|
+
catch {
|
|
443
|
+
// Surface the original write failure; the next write retries the reload.
|
|
444
|
+
}
|
|
445
|
+
throw error;
|
|
446
|
+
}
|
|
447
|
+
};
|
|
448
|
+
const agent = new Agent({
|
|
449
|
+
provider: activeProvider
|
|
450
|
+
? createProvider(activeProviderId, activeProvider.apiKey, activeProvider.baseURL)
|
|
451
|
+
: provider,
|
|
452
|
+
providerId: activeProviderId || "",
|
|
453
|
+
model: activeModel,
|
|
454
|
+
sessionID: sessionManager?.getSessionFile(),
|
|
455
|
+
tools,
|
|
456
|
+
systemPrompt,
|
|
457
|
+
temperature: 0.2,
|
|
458
|
+
thinkingLevel: initialThinkingLevel,
|
|
459
|
+
mode: initialMode,
|
|
460
|
+
onMessageAppend: (message) => {
|
|
461
|
+
if (!sessionManager)
|
|
462
|
+
return;
|
|
463
|
+
if (message.role === "system")
|
|
464
|
+
return;
|
|
465
|
+
// Runtime meta messages are ephemeral; don't persist them —
|
|
466
|
+
// they will be re-injected as needed on resume based on the current mode.
|
|
467
|
+
if (message.role === "meta")
|
|
468
|
+
return;
|
|
469
|
+
const manager = sessionManager;
|
|
470
|
+
persistFenced(() => manager.appendMessage(message, contextFence.getRevision()));
|
|
471
|
+
traceEvent("session_message_persisted", {
|
|
472
|
+
message: summarizeTraceMessage(message),
|
|
473
|
+
});
|
|
474
|
+
sessionTitleUpdater?.handlePersistedMessage(message);
|
|
475
|
+
if (message.role === "assistant") {
|
|
476
|
+
recordMemoryCitations(args.cwd, message.content);
|
|
477
|
+
}
|
|
478
|
+
},
|
|
479
|
+
onProviderError: (error) => {
|
|
480
|
+
persistFenced(() => sessionManager?.appendProviderError(error, contextFence.getRevision()));
|
|
481
|
+
},
|
|
482
|
+
getContextRevision: () => contextFence.getRevision(),
|
|
483
|
+
onContextCheckpoint: (checkpoint) => {
|
|
484
|
+
if (!sessionManager)
|
|
485
|
+
throw new Error("No session available for context commit");
|
|
486
|
+
const manager = sessionManager;
|
|
487
|
+
persistFenced(() => manager.commitContextCheckpoint(checkpoint, contextFence.getRevision()));
|
|
488
|
+
},
|
|
489
|
+
onToolResult: (toolName, result) => {
|
|
490
|
+
if (!sessionManager)
|
|
491
|
+
return;
|
|
492
|
+
if (toolName !== "skill" || result.isError)
|
|
493
|
+
return;
|
|
494
|
+
const match = result.content.match(/^Skill:\s+([^\n]+)$/m);
|
|
495
|
+
if (match?.[1]) {
|
|
496
|
+
const manager = sessionManager;
|
|
497
|
+
persistFenced(() => manager.appendMarker("skill_activated", match[1].trim(), contextFence.getRevision()));
|
|
498
|
+
}
|
|
499
|
+
},
|
|
500
|
+
onModeUpdate: (mode) => {
|
|
501
|
+
persistFenced(() => sessionManager?.appendMarker("mode_switch", mode, contextFence.getRevision()));
|
|
502
|
+
},
|
|
503
|
+
budgetLedger,
|
|
504
|
+
skills: skillSummaries,
|
|
505
|
+
skillCatalogChars: userConfig.getSkillCatalogChars(),
|
|
506
|
+
memoryPrompt,
|
|
507
|
+
fileStateTracker,
|
|
508
|
+
agentCategories: userConfig.getAgentCategories(),
|
|
509
|
+
agentRouting,
|
|
510
|
+
routingSnapshot: routingSnapshotAccessor,
|
|
511
|
+
routableModels: createRoutableModelIndex(registry),
|
|
512
|
+
subagents: userConfig.getSubagents(),
|
|
513
|
+
providerFactory: createProviderForRoute,
|
|
514
|
+
externalHooks: hookController,
|
|
515
|
+
});
|
|
516
|
+
agentRef = agent;
|
|
517
|
+
if (allowBackgroundTasks) {
|
|
518
|
+
// Reminder bridge (design §2.3a): list() is owner-filtered at call time so
|
|
519
|
+
// the reminder never leaks another session's tasks after a switch.
|
|
520
|
+
agent.backgroundTasks = {
|
|
521
|
+
list: () => processManager.listTasks(agent.getSessionID()),
|
|
522
|
+
version: () => processManager.getTaskStateVersion(),
|
|
523
|
+
outputTail: (id) => processManager.taskOutputTail(id, 2000),
|
|
524
|
+
kill: (id) => processManager.killTask(id),
|
|
525
|
+
subscribe: (listener) => processManager.onChange(() => listener()),
|
|
526
|
+
};
|
|
527
|
+
}
|
|
528
|
+
if (sessionManager) {
|
|
529
|
+
sessionTitleUpdater = createSessionTitleUpdater({
|
|
530
|
+
sessionManager,
|
|
531
|
+
complete: (messages, completeOptions) => agent.complete(messages, completeOptions),
|
|
532
|
+
});
|
|
533
|
+
}
|
|
534
|
+
if (sessionManager) {
|
|
535
|
+
sessionManager.updateMetadata({
|
|
536
|
+
...(agent.model ? { model: agent.model } : {}),
|
|
537
|
+
cwd: args.cwd,
|
|
538
|
+
thinkingLevel: agent.thinking,
|
|
539
|
+
reasoningEffort: agent.thinking,
|
|
540
|
+
});
|
|
541
|
+
}
|
|
542
|
+
await hookController.runEvent({
|
|
543
|
+
eventName: "SessionStart",
|
|
544
|
+
cwd: args.cwd,
|
|
545
|
+
sessionId: sessionManager?.getSessionFile(),
|
|
546
|
+
agentRole: "driver",
|
|
547
|
+
target: "session",
|
|
548
|
+
payload: {
|
|
549
|
+
resumed: resumedExistingSession,
|
|
550
|
+
printMode,
|
|
551
|
+
providerId: agent.providerId,
|
|
552
|
+
model: agent.apiModel,
|
|
553
|
+
},
|
|
554
|
+
});
|
|
555
|
+
const flushMemory = async () => {
|
|
556
|
+
// Codex-style memory runs at startup over historical rollouts. Exit should
|
|
557
|
+
// not perform an ad-hoc extraction of the just-finished session.
|
|
558
|
+
};
|
|
559
|
+
const shutdownRuntime = async () => {
|
|
560
|
+
try {
|
|
561
|
+
await hookController.runEvent({
|
|
562
|
+
eventName: "SessionEnd",
|
|
563
|
+
cwd: args.cwd,
|
|
564
|
+
sessionId: sessionManager?.getSessionFile(),
|
|
565
|
+
agentRole: "driver",
|
|
566
|
+
target: "session",
|
|
567
|
+
payload: {
|
|
568
|
+
providerId: agent.providerId,
|
|
569
|
+
model: agent.apiModel,
|
|
570
|
+
},
|
|
571
|
+
});
|
|
572
|
+
}
|
|
573
|
+
catch {
|
|
574
|
+
// Shutdown must still release child processes when a hook fails.
|
|
575
|
+
}
|
|
576
|
+
const results = await Promise.allSettled([
|
|
577
|
+
flushMemory(),
|
|
578
|
+
shutdownMcp(),
|
|
579
|
+
shutdownExternalRuntime(),
|
|
580
|
+
lspService.shutdown(),
|
|
581
|
+
// Graceful task reaping (design §2.2b layer 1): SIGTERM → SIGKILL.
|
|
582
|
+
processManager.shutdownTasks(),
|
|
583
|
+
]);
|
|
584
|
+
for (const result of results) {
|
|
585
|
+
if (result.status === "rejected") {
|
|
586
|
+
// Shutdown is best-effort; never turn exit into a fatal error.
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
};
|
|
590
|
+
const runMemoryCompaction = async () => formatMemoryStartupResult(await runMemoryStartupPipeline({
|
|
591
|
+
cwd: args.cwd,
|
|
592
|
+
complete: (messages, completeOptions) => agent.complete(messages, completeOptions),
|
|
593
|
+
model: agent.apiModel,
|
|
594
|
+
}));
|
|
595
|
+
const runMemorySummary = async () => {
|
|
596
|
+
const result = await runMemoryPhase2({
|
|
597
|
+
cwd: args.cwd,
|
|
598
|
+
complete: (messages, completeOptions) => agent.complete(messages, completeOptions),
|
|
599
|
+
model: agent.apiModel,
|
|
600
|
+
});
|
|
601
|
+
return `Memory Phase 2 ${result.status}: selected ${result.selected}${result.reason ? ` (${result.reason})` : ""}.`;
|
|
602
|
+
};
|
|
603
|
+
const runMemoryRefresh = runMemoryCompaction;
|
|
604
|
+
startMemoryStartupTask({
|
|
605
|
+
cwd: args.cwd,
|
|
606
|
+
complete: (messages, completeOptions) => agent.complete(messages, completeOptions),
|
|
607
|
+
model: agent.apiModel,
|
|
608
|
+
});
|
|
609
|
+
if (activeModel && args.model && normalizedConfiguredModel === agent.model) {
|
|
610
|
+
userConfig.pushRecentModel(agent.model);
|
|
611
|
+
}
|
|
612
|
+
// Restore session if requested
|
|
613
|
+
if (resumedExistingSession && sessionManager) {
|
|
614
|
+
const history = contextFence.reloadHistory();
|
|
615
|
+
if (history.length > 0) {
|
|
616
|
+
agent.messages = [{ role: "system", content: systemPrompt }, ...history];
|
|
617
|
+
// Reassigning agent.messages drops any runtime meta reminder injected during
|
|
618
|
+
// construction. Re-inject if the agent is starting in plan mode.
|
|
619
|
+
if (agent.mode === "plan") {
|
|
620
|
+
agent.injectModeReminder();
|
|
621
|
+
}
|
|
622
|
+
agent.injectDeferredToolsReminder();
|
|
623
|
+
// JSON print mode reserves stdout for the single result object.
|
|
624
|
+
(args.outputFormat === "json" || args.outputFormat === "stream-json" ? console.error : console.log)(chalk.dim(`Resumed session: ${sessionManager.getSessionFile()}`));
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
try {
|
|
628
|
+
// Print mode: single prompt, then exit
|
|
629
|
+
if (args.print || args.prompt) {
|
|
630
|
+
if (shouldRejectGrokSessionInPrintMode(sessionManager?.getMetadata().externalRuntime, true)) {
|
|
631
|
+
console.error(chalk.red("Error: Grok subscription sessions are interactive. Resume this workspace session in the TUI, or start a fresh native session for --print."));
|
|
632
|
+
process.exitCode = 1;
|
|
633
|
+
return;
|
|
634
|
+
}
|
|
635
|
+
if (args.inputFormat === "stream-json") {
|
|
636
|
+
await runStreamJsonSession({
|
|
637
|
+
input: process.stdin,
|
|
638
|
+
write: (message) => { process.stdout.write(JSON.stringify(message) + "\n"); },
|
|
639
|
+
sessionId: basename(sessionManager.getSessionFile()),
|
|
640
|
+
model: agent.model,
|
|
641
|
+
run: (prompt) => agent.run(prompt, args.cwd),
|
|
642
|
+
onEvent: (event) => traceEvent("print_agent_event", summarizeAgentEventForTrace(event)),
|
|
643
|
+
});
|
|
644
|
+
return;
|
|
645
|
+
}
|
|
646
|
+
const prompt = args.prompt || (await readPipedStdin()) || "";
|
|
647
|
+
if (!prompt) {
|
|
648
|
+
console.error(chalk.red("Error: No prompt provided."));
|
|
649
|
+
process.exit(1);
|
|
650
|
+
}
|
|
651
|
+
// JSON mode (benchmark/CI adapters): stdout carries exactly ONE JSON
|
|
652
|
+
// object; streaming text and tool logs move to stderr-silence. Plain
|
|
653
|
+
// mode is byte-for-byte the previous behavior.
|
|
654
|
+
const jsonOutput = args.outputFormat === "json";
|
|
655
|
+
const collector = new PrintRunCollector();
|
|
656
|
+
// Harness-side change footprint (git ground truth) — printed by the
|
|
657
|
+
// harness so the run cannot omit or misstate what it touched.
|
|
658
|
+
const changeBaseline = jsonOutput
|
|
659
|
+
? await (await import("./agent/change-tracker.js")).captureGitBaseline(args.cwd)
|
|
660
|
+
: null;
|
|
661
|
+
const collectChanges = async () => {
|
|
662
|
+
if (!changeBaseline)
|
|
663
|
+
return undefined;
|
|
664
|
+
const { detectRunChanges } = await import("./agent/change-tracker.js");
|
|
665
|
+
const detected = await detectRunChanges(args.cwd, changeBaseline).catch(() => null);
|
|
666
|
+
if (!detected)
|
|
667
|
+
return undefined;
|
|
668
|
+
return {
|
|
669
|
+
changed_files: detected.changedFiles.length,
|
|
670
|
+
modified_existing_tests: detected.modifiedExistingTests.map((t) => ({
|
|
671
|
+
path: t.path,
|
|
672
|
+
deleted_lines: t.deletedLines,
|
|
673
|
+
})),
|
|
674
|
+
};
|
|
675
|
+
};
|
|
676
|
+
const printSessionId = sessionManager
|
|
677
|
+
? basename(sessionManager.getSessionFile())
|
|
678
|
+
: undefined;
|
|
679
|
+
try {
|
|
680
|
+
let printedTurnText = false;
|
|
681
|
+
for await (const event of agent.run(prompt, args.cwd)) {
|
|
682
|
+
traceEvent("print_agent_event", summarizeAgentEventForTrace(event));
|
|
683
|
+
collector.onEvent(event);
|
|
684
|
+
if (jsonOutput) {
|
|
685
|
+
if (event.type === "provider_retry") {
|
|
686
|
+
console.error(chalk.yellow(`[Stream interrupted; retrying (${event.attempt}/${event.maxAttempts})]`));
|
|
687
|
+
}
|
|
688
|
+
continue;
|
|
689
|
+
}
|
|
690
|
+
if (event.type === "turn_start") {
|
|
691
|
+
printedTurnText = false;
|
|
692
|
+
}
|
|
693
|
+
else if (event.type === "provider_retry") {
|
|
694
|
+
// The stream died mid-response and the agent re-issues the whole
|
|
695
|
+
// request. Text already on stdout cannot be un-printed, so at least
|
|
696
|
+
// separate the retried response and say what happened.
|
|
697
|
+
if (printedTurnText)
|
|
698
|
+
process.stdout.write("\n");
|
|
699
|
+
console.error(chalk.yellow(`[Stream interrupted; retrying (${event.attempt}/${event.maxAttempts}) — the partial text above is superseded by the retried response]`));
|
|
700
|
+
}
|
|
701
|
+
else if (event.type === "text_delta") {
|
|
702
|
+
printedTurnText = true;
|
|
703
|
+
process.stdout.write(event.content);
|
|
704
|
+
}
|
|
705
|
+
else if (event.type === "tool_start") {
|
|
706
|
+
console.log(chalk.cyan(`\n[Tool: ${event.name}]`));
|
|
707
|
+
}
|
|
708
|
+
else if (event.type === "tool_end") {
|
|
709
|
+
const color = event.result.isError ? chalk.red : chalk.dim;
|
|
710
|
+
console.log(color(`[Result: ${event.result.content.slice(0, 200)}${event.result.content.length > 200 ? "..." : ""}]`));
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
if (jsonOutput) {
|
|
714
|
+
process.stdout.write(formatPrintJson({
|
|
715
|
+
summary: collector.summary(),
|
|
716
|
+
sessionId: printSessionId,
|
|
717
|
+
compaction: agent.getCompactionStats(),
|
|
718
|
+
changes: await collectChanges(),
|
|
719
|
+
}) + "\n");
|
|
720
|
+
}
|
|
721
|
+
else {
|
|
722
|
+
console.log();
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
catch (error) {
|
|
726
|
+
if (!jsonOutput)
|
|
727
|
+
throw error;
|
|
728
|
+
// Structured failure: adapters distinguish agent errors from crashes
|
|
729
|
+
// by the JSON error object + non-zero exit.
|
|
730
|
+
process.stdout.write(formatPrintJsonError({
|
|
731
|
+
message: error instanceof Error ? error.message : String(error),
|
|
732
|
+
summary: collector.summary(),
|
|
733
|
+
sessionId: printSessionId,
|
|
734
|
+
compaction: agent.getCompactionStats(),
|
|
735
|
+
changes: await collectChanges(),
|
|
736
|
+
}) + "\n");
|
|
737
|
+
process.exitCode = 1;
|
|
738
|
+
}
|
|
739
|
+
return;
|
|
740
|
+
}
|
|
741
|
+
const themeConfig = userConfig.getTheme();
|
|
742
|
+
let detectedTheme = "dark";
|
|
743
|
+
if (preResolvedTheme) {
|
|
744
|
+
detectedTheme = preResolvedTheme;
|
|
745
|
+
}
|
|
746
|
+
else if (shouldProbeTerminalTheme(themeConfig)) {
|
|
747
|
+
// Probe before the renderer owns stdin. OSC 11 needs raw mode, and the
|
|
748
|
+
// runtime renderer can consume the reply before startup code sees it.
|
|
749
|
+
const { detectTerminalTheme } = await import("./tui/detect-theme.js");
|
|
750
|
+
detectedTheme = await detectTerminalTheme();
|
|
751
|
+
}
|
|
752
|
+
else {
|
|
753
|
+
detectedTheme = themeConfig.mode === "light" ? "light" : "dark";
|
|
754
|
+
}
|
|
755
|
+
const effectiveThemeMode = effectiveThemeModeForTerminal(themeConfig, detectedTheme);
|
|
756
|
+
// In-place session switch for the /session picker: rebind every closure
|
|
757
|
+
// that persists to the session (onMessageAppend, markers, title updater)
|
|
758
|
+
// by reassigning the outer `sessionManager`, then replace the agent's
|
|
759
|
+
// history the same way startup resume does.
|
|
760
|
+
const activateSession = (next) => {
|
|
761
|
+
try {
|
|
762
|
+
const history = next.getMessages();
|
|
763
|
+
const historyRevision = next.getRevision();
|
|
764
|
+
const nextPromptCacheKey = next.getOrCreatePromptCacheKey();
|
|
765
|
+
const nextTitleUpdater = createSessionTitleUpdater({
|
|
766
|
+
sessionManager: next,
|
|
767
|
+
complete: (messages, completeOptions) => agent.complete(messages, completeOptions),
|
|
768
|
+
});
|
|
769
|
+
next.updateMetadata({
|
|
770
|
+
...(agent.model ? { model: agent.model } : {}),
|
|
771
|
+
cwd: args.cwd,
|
|
772
|
+
thinkingLevel: agent.thinking,
|
|
773
|
+
reasoningEffort: agent.thinking,
|
|
774
|
+
});
|
|
775
|
+
// Keep the live system/meta head (mode reminders survive the switch),
|
|
776
|
+
// mirroring the /rewind history-replacement pattern.
|
|
777
|
+
const head = splitLeadingContext(agent.messages).leading;
|
|
778
|
+
const nextMessages = [...head, ...history];
|
|
779
|
+
// Commit only after every file read/write and reconstruction step has
|
|
780
|
+
// succeeded. Callers can safely prepare candidate sessions without a
|
|
781
|
+
// failed switch rebinding persistence or replacing the live history.
|
|
782
|
+
if (next.getRevision() !== historyRevision)
|
|
783
|
+
throw new Error("Session changed while switching; retry");
|
|
784
|
+
contextFence.dispose();
|
|
785
|
+
contextFence = new SessionContextFence(next);
|
|
786
|
+
sessionManager = next;
|
|
787
|
+
sessionPromptCacheKey = nextPromptCacheKey;
|
|
788
|
+
sessionTitleUpdater = nextTitleUpdater;
|
|
789
|
+
agent.messages = nextMessages;
|
|
790
|
+
// These update only live in-memory/UI mirrors after the persistence
|
|
791
|
+
// commit. A best-effort callback failure must not report the switch as
|
|
792
|
+
// rolled back after the outer session binding has already changed.
|
|
793
|
+
try {
|
|
794
|
+
agent.resetContextUsageAnchor();
|
|
795
|
+
}
|
|
796
|
+
catch { /* derived counter only */ }
|
|
797
|
+
return { manager: next };
|
|
798
|
+
}
|
|
799
|
+
catch (error) {
|
|
800
|
+
return { error: error instanceof Error ? error.message : String(error) };
|
|
801
|
+
}
|
|
802
|
+
};
|
|
803
|
+
const switchSession = (sessionFile) => {
|
|
804
|
+
try {
|
|
805
|
+
return activateSession(new SessionManager(sessionFile));
|
|
806
|
+
}
|
|
807
|
+
catch (error) {
|
|
808
|
+
return { error: error instanceof Error ? error.message : String(error) };
|
|
809
|
+
}
|
|
810
|
+
};
|
|
811
|
+
const createFreshSession = (cwd) => {
|
|
812
|
+
let fresh;
|
|
813
|
+
try {
|
|
814
|
+
fresh = SessionManager.createFresh(cwd);
|
|
815
|
+
const result = activateSession(fresh);
|
|
816
|
+
if ("error" in result)
|
|
817
|
+
rmSync(fresh.getSessionFile(), { force: true });
|
|
818
|
+
return result;
|
|
819
|
+
}
|
|
820
|
+
catch (error) {
|
|
821
|
+
if (fresh)
|
|
822
|
+
rmSync(fresh.getSessionFile(), { force: true });
|
|
823
|
+
return { error: error instanceof Error ? error.message : String(error) };
|
|
824
|
+
}
|
|
825
|
+
};
|
|
826
|
+
const commonOptions = {
|
|
827
|
+
sessionManager,
|
|
828
|
+
switchSession,
|
|
829
|
+
createFreshSession,
|
|
830
|
+
createProvider,
|
|
831
|
+
registry,
|
|
832
|
+
skillRegistry,
|
|
833
|
+
planHandlerRef,
|
|
834
|
+
approvalHandlerRef,
|
|
835
|
+
questionController,
|
|
836
|
+
bashAllowlist,
|
|
837
|
+
settingsManager,
|
|
838
|
+
lspService,
|
|
839
|
+
mcpManager,
|
|
840
|
+
goalStore,
|
|
841
|
+
hookController,
|
|
842
|
+
flushMemory,
|
|
843
|
+
runMemoryCompaction,
|
|
844
|
+
runMemorySummary,
|
|
845
|
+
runMemoryRefresh,
|
|
846
|
+
processManager,
|
|
847
|
+
tasksAutoResume: userConfig.getTasksAutoResume(),
|
|
848
|
+
promotionChannel,
|
|
849
|
+
};
|
|
850
|
+
// Grok Subscription is a first-class interactive provider target. Manager
|
|
851
|
+
// construction is deliberately lazy: it does not inspect, spawn, or reach
|
|
852
|
+
// the network until the user selects Grok or runs /login grok. Print,
|
|
853
|
+
// Feishu, help, and version paths return before this import.
|
|
854
|
+
const { createGrokRuntimeManager } = await import("./external-runtime/grok-runtime.js");
|
|
855
|
+
externalRuntime = createGrokRuntimeManager({
|
|
856
|
+
workspace: args.cwd,
|
|
857
|
+
approvalController,
|
|
858
|
+
getPermissionMode: () => agentRef?.mode ?? "default",
|
|
859
|
+
});
|
|
860
|
+
const { startStartupUpdateCheck } = await import("./update/index.js");
|
|
861
|
+
const updateCheck = await startStartupUpdateCheck();
|
|
862
|
+
const updateNotice = updateCheck.notice;
|
|
863
|
+
const { runTui } = await import("./tui/run.js");
|
|
864
|
+
const summary = await runTui(agent, args, {
|
|
865
|
+
...commonOptions,
|
|
866
|
+
themeMode: effectiveThemeMode,
|
|
867
|
+
themeOverrides: themeConfig.overrides,
|
|
868
|
+
detectedTheme,
|
|
869
|
+
onThemeModeChange: (mode) => userConfig.setThemeMode(mode),
|
|
870
|
+
updateNotice: updateNotice ?? undefined,
|
|
871
|
+
updateNoticeRefresh: updateCheck.refreshed,
|
|
872
|
+
externalRuntime,
|
|
873
|
+
});
|
|
874
|
+
const exitWallMs = summary?.wallMs;
|
|
875
|
+
if (sessionManager) {
|
|
876
|
+
printExitSummary(sessionManager, {
|
|
877
|
+
resumed: resumedExistingSession,
|
|
878
|
+
theme: detectedTheme,
|
|
879
|
+
wallMs: exitWallMs,
|
|
880
|
+
});
|
|
881
|
+
}
|
|
882
|
+
}
|
|
883
|
+
finally {
|
|
884
|
+
traceEvent("run_shutdown_start");
|
|
885
|
+
await shutdownRuntime();
|
|
886
|
+
traceEvent("run_shutdown_end");
|
|
887
|
+
}
|
|
888
|
+
}
|
|
889
|
+
function printExitSummary(sessionManager, options) {
|
|
890
|
+
if (!process.stdout.isTTY)
|
|
891
|
+
return;
|
|
892
|
+
const sessionName = basename(sessionManager.getSessionFile());
|
|
893
|
+
const sessionId = sessionName.replace(/\.jsonl$/, "");
|
|
894
|
+
const title = truncateVisual(normalizeSingleLine(sessionManager.getMetadata().title ?? ""), 64);
|
|
895
|
+
const sessionLabel = title || `${options.resumed ? "Session" : "New session"} - ${sessionId}`;
|
|
896
|
+
const continueCommand = `bubble --resume --session ${sessionName}`;
|
|
897
|
+
const colors = options.theme === "light"
|
|
898
|
+
? {
|
|
899
|
+
markMuted: chalk.hex("#8C8C8C"),
|
|
900
|
+
markStrong: chalk.hex("#1C1C1C"),
|
|
901
|
+
markBrand: chalk.hex("#8B4A00"),
|
|
902
|
+
label: chalk.hex("#6F7377"),
|
|
903
|
+
value: chalk.hex("#171717").bold,
|
|
904
|
+
}
|
|
905
|
+
: {
|
|
906
|
+
markMuted: chalk.hex("#9CA3AF"),
|
|
907
|
+
markStrong: chalk.hex("#F4F4F5"),
|
|
908
|
+
markBrand: chalk.hex("#F5A742"),
|
|
909
|
+
label: chalk.hex("#808080"),
|
|
910
|
+
value: chalk.hex("#EEEEEE").bold,
|
|
911
|
+
};
|
|
912
|
+
const label = (value) => colors.label(value.padEnd(10));
|
|
913
|
+
const logoColor = (tone) => {
|
|
914
|
+
switch (tone) {
|
|
915
|
+
case "brand": return colors.markBrand;
|
|
916
|
+
case "ink": return colors.markStrong;
|
|
917
|
+
case "stone": return colors.markMuted;
|
|
918
|
+
case "soft": return colors.label;
|
|
919
|
+
case "caption": return colors.label;
|
|
920
|
+
}
|
|
921
|
+
};
|
|
922
|
+
for (const line of BUBBLE_WORDMARK) {
|
|
923
|
+
if (line.segments) {
|
|
924
|
+
console.log(line.segments.map((segment) => logoColor(segment.tone)(segment.text)).join(""));
|
|
925
|
+
}
|
|
926
|
+
else {
|
|
927
|
+
console.log(logoColor(line.tone ?? "caption")(line.text ?? ""));
|
|
928
|
+
}
|
|
929
|
+
}
|
|
930
|
+
console.log();
|
|
931
|
+
console.log(`${label("Session")}${colors.value(sessionLabel)}`);
|
|
932
|
+
console.log(`${label("Continue")}${colors.value(continueCommand)}`);
|
|
933
|
+
if (options.wallMs !== undefined) {
|
|
934
|
+
console.log(`${label("Duration")}${colors.value(formatWallDuration(options.wallMs))}`);
|
|
935
|
+
}
|
|
936
|
+
}
|
|
937
|
+
function formatWallDuration(ms) {
|
|
938
|
+
const totalSeconds = Math.max(0, Math.round(ms / 1000));
|
|
939
|
+
if (totalSeconds < 60)
|
|
940
|
+
return `${totalSeconds}s`;
|
|
941
|
+
const minutes = Math.floor(totalSeconds / 60);
|
|
942
|
+
const seconds = totalSeconds % 60;
|
|
943
|
+
if (minutes < 60)
|
|
944
|
+
return `${minutes}m ${seconds}s`;
|
|
945
|
+
const hours = Math.floor(minutes / 60);
|
|
946
|
+
const minutesRest = minutes % 60;
|
|
947
|
+
return `${hours}h ${minutesRest}m ${seconds}s`;
|
|
948
|
+
}
|
|
949
|
+
async function readPipedStdin() {
|
|
950
|
+
if (process.stdin.isTTY)
|
|
951
|
+
return undefined;
|
|
952
|
+
return new Promise((resolve) => {
|
|
953
|
+
let data = "";
|
|
954
|
+
process.stdin.setEncoding("utf8");
|
|
955
|
+
process.stdin.on("data", (chunk) => (data += chunk));
|
|
956
|
+
process.stdin.on("end", () => resolve(data.trim() || undefined));
|
|
957
|
+
process.stdin.resume();
|
|
958
|
+
});
|
|
959
|
+
}
|
|
960
|
+
main()
|
|
961
|
+
.then(() => {
|
|
962
|
+
// Preserve an exit code set by a handled failure path (e.g. print-mode
|
|
963
|
+
// agent errors set exitCode = 1 and return normally) — exit(0) here
|
|
964
|
+
// would silently override it.
|
|
965
|
+
void exitAfterFlush(typeof process.exitCode === "number" ? process.exitCode : 0);
|
|
966
|
+
})
|
|
967
|
+
.catch((err) => {
|
|
968
|
+
console.error(chalk.red(`Fatal error: ${err.message}`));
|
|
969
|
+
void exitAfterFlush(1);
|
|
970
|
+
});
|
|
971
|
+
async function exitAfterFlush(code) {
|
|
972
|
+
await Promise.all([
|
|
973
|
+
flushStream(process.stdout),
|
|
974
|
+
flushStream(process.stderr),
|
|
975
|
+
]);
|
|
976
|
+
process.exit(code);
|
|
977
|
+
}
|
|
978
|
+
function flushStream(stream) {
|
|
979
|
+
if (stream.destroyed || stream.writableEnded)
|
|
980
|
+
return Promise.resolve();
|
|
981
|
+
return new Promise((resolve) => {
|
|
982
|
+
stream.write("", () => resolve());
|
|
983
|
+
});
|
|
984
|
+
}
|