muonroi-cli 1.8.4 → 1.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +17 -5
- package/dist/packages/agent-harness-core/src/driver.d.ts +27 -1
- package/dist/packages/agent-harness-core/src/driver.js +46 -0
- package/dist/packages/agent-harness-core/src/event-filter.js +11 -0
- package/dist/packages/agent-harness-core/src/event-redact.js +7 -0
- package/dist/packages/agent-harness-core/src/event-tee.d.ts +64 -0
- package/dist/packages/agent-harness-core/src/event-tee.js +104 -0
- package/dist/packages/agent-harness-core/src/mcp-server.d.ts +25 -0
- package/dist/packages/agent-harness-core/src/mcp-server.js +169 -21
- package/dist/packages/agent-harness-core/src/predicate.d.ts +1 -1
- package/dist/packages/agent-harness-core/src/protocol.d.ts +90 -4
- package/dist/packages/agent-harness-core/src/protocol.js +15 -0
- package/dist/packages/agent-harness-core/src/visual-quality.d.ts +58 -0
- package/dist/packages/agent-harness-core/src/visual-quality.js +141 -0
- package/dist/packages/agent-harness-opentui/src/agent-mode.d.ts +6 -0
- package/dist/packages/agent-harness-opentui/src/agent-mode.js +14 -1
- package/dist/packages/agent-harness-opentui/src/input-bridge.d.ts +2 -10
- package/dist/packages/agent-harness-opentui/src/input-bridge.js +103 -16
- package/dist/packages/agent-harness-opentui/src/install.d.ts +8 -0
- package/dist/packages/agent-harness-opentui/src/install.js +10 -0
- package/dist/packages/agent-harness-opentui/src/semantic.js +12 -10
- package/dist/packages/agent-harness-opentui/src/visual-capture.d.ts +56 -0
- package/dist/packages/agent-harness-opentui/src/visual-capture.js +103 -0
- package/dist/src/agent-harness/mock-model.d.ts +38 -0
- package/dist/src/agent-harness/mock-model.js +69 -3
- package/dist/src/agent-harness/test-spawn.js +31 -0
- package/dist/src/chat/chat-keychain.d.ts +7 -12
- package/dist/src/chat/chat-keychain.js +19 -86
- package/dist/src/cli/config/screen-providers.js +1 -1
- package/dist/src/cli/cost-forensics.d.ts +10 -0
- package/dist/src/cli/cost-forensics.js +18 -3
- package/dist/src/cli/keys-bundle.d.ts +1 -1
- package/dist/src/cli/keys-bundle.js +1 -1
- package/dist/src/cli/keys.d.ts +10 -47
- package/dist/src/cli/keys.js +31 -399
- package/dist/src/council/clarifier.d.ts +31 -3
- package/dist/src/council/clarifier.js +220 -32
- package/dist/src/council/context.js +49 -15
- package/dist/src/council/debate-checkpoint.d.ts +129 -0
- package/dist/src/council/debate-checkpoint.js +176 -0
- package/dist/src/council/debate-planner.js +54 -5
- package/dist/src/council/debate-summary.d.ts +25 -0
- package/dist/src/council/debate-summary.js +85 -0
- package/dist/src/council/debate.d.ts +169 -2
- package/dist/src/council/debate.js +1265 -135
- package/dist/src/council/index.d.ts +108 -1
- package/dist/src/council/index.js +670 -197
- package/dist/src/council/leader.d.ts +26 -0
- package/dist/src/council/leader.js +150 -9
- package/dist/src/council/llm.d.ts +94 -0
- package/dist/src/council/llm.js +348 -55
- package/dist/src/council/panel-select.d.ts +30 -0
- package/dist/src/council/panel-select.js +82 -0
- package/dist/src/council/planner.js +40 -0
- package/dist/src/council/preflight.d.ts +17 -0
- package/dist/src/council/preflight.js +50 -2
- package/dist/src/council/prompts.d.ts +39 -4
- package/dist/src/council/prompts.js +256 -69
- package/dist/src/council/stance-recall.d.ts +42 -0
- package/dist/src/council/stance-recall.js +57 -0
- package/dist/src/council/strip-think.d.ts +17 -0
- package/dist/src/council/strip-think.js +33 -0
- package/dist/src/council/types.d.ts +138 -0
- package/dist/src/ee/artifact-cache.d.ts +16 -0
- package/dist/src/ee/artifact-cache.js +32 -0
- package/dist/src/ee/auth.d.ts +20 -0
- package/dist/src/ee/auth.js +54 -2
- package/dist/src/ee/bridge.d.ts +10 -0
- package/dist/src/ee/bridge.js +58 -0
- package/dist/src/ee/client.js +109 -21
- package/dist/src/ee/ee-onboarding.js +6 -26
- package/dist/src/ee/export-transcripts.d.ts +1 -0
- package/dist/src/ee/export-transcripts.js +8 -10
- package/dist/src/ee/extract-session.js +29 -0
- package/dist/src/ee/extract-style.d.ts +58 -0
- package/dist/src/ee/extract-style.js +270 -0
- package/dist/src/ee/recall-ledger.d.ts +9 -0
- package/dist/src/ee/recall-ledger.js +3 -0
- package/dist/src/ee/scope.d.ts +1 -0
- package/dist/src/ee/scope.js +26 -1
- package/dist/src/ee/search.d.ts +7 -0
- package/dist/src/ee/search.js +24 -0
- package/dist/src/ee/transcript-emit.js +2 -0
- package/dist/src/ee/types.d.ts +22 -0
- package/dist/src/ee/who-am-i-brain.d.ts +35 -0
- package/dist/src/ee/who-am-i-brain.js +220 -0
- package/dist/src/ee/who-am-i.d.ts +10 -3
- package/dist/src/ee/who-am-i.js +12 -0
- package/dist/src/ee/workflow-event.d.ts +48 -0
- package/dist/src/ee/workflow-event.js +81 -0
- package/dist/src/flow/compaction/compress.d.ts +3 -3
- package/dist/src/flow/compaction/compress.js +58 -8
- package/dist/src/flow/compaction/extract.d.ts +4 -7
- package/dist/src/flow/compaction/extract.js +50 -10
- package/dist/src/flow/compaction/index.d.ts +14 -1
- package/dist/src/flow/compaction/index.js +96 -3
- package/dist/src/flow/compaction/input-guard.d.ts +24 -0
- package/dist/src/flow/compaction/input-guard.js +43 -0
- package/dist/src/flow/compaction/progress.d.ts +35 -0
- package/dist/src/flow/compaction/progress.js +35 -0
- package/dist/src/flow/fold-planning.d.ts +36 -0
- package/dist/src/flow/fold-planning.js +83 -0
- package/dist/src/flow/hierarchy.d.ts +146 -0
- package/dist/src/flow/hierarchy.js +427 -0
- package/dist/src/flow/index.d.ts +1 -0
- package/dist/src/flow/index.js +2 -0
- package/dist/src/flow/run-artifacts.d.ts +102 -0
- package/dist/src/flow/run-artifacts.js +208 -0
- package/dist/src/generated/version.d.ts +1 -1
- package/dist/src/generated/version.js +1 -1
- package/dist/src/gsd/assessment-schema.d.ts +44 -0
- package/dist/src/gsd/assessment-schema.js +134 -0
- package/dist/src/gsd/capability-registry.d.ts +45 -0
- package/dist/src/gsd/capability-registry.js +337 -0
- package/dist/src/gsd/complexity-assessor.d.ts +39 -0
- package/dist/src/gsd/complexity-assessor.js +152 -0
- package/dist/src/gsd/config-bridge.d.ts +7 -0
- package/dist/src/gsd/config-bridge.js +114 -0
- package/dist/src/gsd/config-loader.d.ts +27 -0
- package/dist/src/gsd/config-loader.js +50 -0
- package/dist/src/gsd/council-context.d.ts +44 -0
- package/dist/src/gsd/council-context.js +114 -0
- package/dist/src/gsd/ee-closure.d.ts +28 -0
- package/dist/src/gsd/ee-closure.js +49 -0
- package/dist/src/gsd/flags.d.ts +66 -0
- package/dist/src/gsd/flags.js +102 -0
- package/dist/src/gsd/gsd-dispatch.d.ts +58 -0
- package/dist/src/gsd/gsd-dispatch.js +131 -0
- package/dist/src/gsd/gsd-runtime.d.ts +22 -0
- package/dist/src/gsd/gsd-runtime.js +37 -0
- package/dist/src/gsd/host-adapter.d.ts +11 -0
- package/dist/src/gsd/host-adapter.js +29 -0
- package/dist/src/gsd/index.d.ts +24 -1
- package/dist/src/gsd/index.js +27 -0
- package/dist/src/gsd/loop-host-contract.d.ts +21 -0
- package/dist/src/gsd/loop-host-contract.js +39 -0
- package/dist/src/gsd/loop-host.d.ts +69 -0
- package/dist/src/gsd/loop-host.js +245 -0
- package/dist/src/gsd/loop-resolver.d.ts +36 -0
- package/dist/src/gsd/loop-resolver.js +79 -0
- package/dist/src/gsd/model-tier.d.ts +13 -0
- package/dist/src/gsd/model-tier.js +45 -0
- package/dist/src/gsd/mutation-gate.d.ts +16 -0
- package/dist/src/gsd/mutation-gate.js +41 -0
- package/dist/src/gsd/native-roadmap.d.ts +89 -0
- package/dist/src/gsd/native-roadmap.js +343 -0
- package/dist/src/gsd/native-state.d.ts +47 -0
- package/dist/src/gsd/native-state.js +220 -0
- package/dist/src/gsd/paths.d.ts +23 -0
- package/dist/src/gsd/paths.js +66 -0
- package/dist/src/gsd/phase-dag.d.ts +12 -0
- package/dist/src/gsd/phase-dag.js +94 -0
- package/dist/src/gsd/phase-sync.d.ts +42 -0
- package/dist/src/gsd/phase-sync.js +321 -0
- package/dist/src/gsd/pil-gate-context.d.ts +13 -0
- package/dist/src/gsd/pil-gate-context.js +64 -0
- package/dist/src/gsd/pil-gate-critic.d.ts +19 -0
- package/dist/src/gsd/pil-gate-critic.js +74 -0
- package/dist/src/gsd/plan-council-prompts.d.ts +25 -0
- package/dist/src/gsd/plan-council-prompts.js +79 -0
- package/dist/src/gsd/plan-council.d.ts +44 -0
- package/dist/src/gsd/plan-council.js +283 -0
- package/dist/src/gsd/plan-gate-vocabulary.d.ts +40 -0
- package/dist/src/gsd/plan-gate-vocabulary.js +64 -0
- package/dist/src/gsd/product-workspace.d.ts +13 -0
- package/dist/src/gsd/product-workspace.js +124 -0
- package/dist/src/gsd/ship-bridge.d.ts +25 -0
- package/dist/src/gsd/ship-bridge.js +65 -0
- package/dist/src/gsd/state-document.d.ts +40 -0
- package/dist/src/gsd/state-document.js +163 -0
- package/dist/src/gsd/verdict-schema.d.ts +39 -0
- package/dist/src/gsd/verdict-schema.js +144 -0
- package/dist/src/gsd/verify-context.d.ts +22 -0
- package/dist/src/gsd/verify-context.js +27 -0
- package/dist/src/gsd/verify-council-prompts.d.ts +19 -0
- package/dist/src/gsd/verify-council-prompts.js +85 -0
- package/dist/src/gsd/verify-council.d.ts +25 -0
- package/dist/src/gsd/verify-council.js +119 -0
- package/dist/src/gsd/verify-gate-vocabulary.d.ts +25 -0
- package/dist/src/gsd/verify-gate-vocabulary.js +46 -0
- package/dist/src/gsd/workflow-engine.d.ts +60 -0
- package/dist/src/gsd/workflow-engine.js +207 -0
- package/dist/src/gsd/workflow-tools.d.ts +13 -0
- package/dist/src/gsd/workflow-tools.js +277 -0
- package/dist/src/headless/council-answers.js +4 -0
- package/dist/src/hooks/index.js +1 -1
- package/dist/src/index.js +172 -270
- package/dist/src/lsp/builtins.js +3 -1
- package/dist/src/lsp/manager.d.ts +5 -1
- package/dist/src/lsp/manager.js +249 -3
- package/dist/src/lsp/npm-cache.d.ts +11 -1
- package/dist/src/lsp/npm-cache.js +17 -1
- package/dist/src/lsp/runtime.d.ts +6 -1
- package/dist/src/lsp/runtime.js +17 -1
- package/dist/src/lsp/types.d.ts +83 -1
- package/dist/src/lsp/types.js +10 -0
- package/dist/src/maintain/pr-builder.js +23 -13
- package/dist/src/mcp/auto-setup.js +57 -32
- package/dist/src/mcp/client-pool.js +44 -16
- package/dist/src/mcp/lsp-tools.d.ts +5 -1
- package/dist/src/mcp/lsp-tools.js +93 -2
- package/dist/src/mcp/mcp-keychain.d.ts +3 -5
- package/dist/src/mcp/mcp-keychain.js +9 -49
- package/dist/src/mcp/research-onboarding.js +8 -7
- package/dist/src/mcp/runtime.js +34 -2
- package/dist/src/mcp/setup-guide-text.d.ts +1 -1
- package/dist/src/mcp/setup-guide-text.js +22 -2
- package/dist/src/mcp/tools-server.d.ts +10 -0
- package/dist/src/mcp/tools-server.js +10 -2
- package/dist/src/models/catalog-client.d.ts +87 -0
- package/dist/src/models/catalog-client.js +105 -38
- package/dist/src/models/catalog.json +528 -265
- package/dist/src/models/registry.d.ts +22 -7
- package/dist/src/models/registry.js +73 -10
- package/dist/src/ops/doctor.js +1 -1
- package/dist/src/orchestrator/ask-user.d.ts +61 -0
- package/dist/src/orchestrator/ask-user.js +65 -0
- package/dist/src/orchestrator/auto-commit.js +1 -1
- package/dist/src/orchestrator/batch-turn-runner.js +2 -2
- package/dist/src/orchestrator/cache-prefix.d.ts +67 -0
- package/dist/src/orchestrator/cache-prefix.js +83 -0
- package/dist/src/orchestrator/compact-request.d.ts +32 -0
- package/dist/src/orchestrator/compact-request.js +41 -0
- package/dist/src/orchestrator/compaction.d.ts +12 -3
- package/dist/src/orchestrator/compaction.js +35 -15
- package/dist/src/orchestrator/council-manager.d.ts +12 -3
- package/dist/src/orchestrator/council-manager.js +74 -32
- package/dist/src/orchestrator/council-request.d.ts +49 -0
- package/dist/src/orchestrator/council-request.js +62 -0
- package/dist/src/orchestrator/cross-turn-dedup.d.ts +6 -0
- package/dist/src/orchestrator/cross-turn-dedup.js +22 -1
- package/dist/src/orchestrator/error-utils.d.ts +29 -0
- package/dist/src/orchestrator/error-utils.js +132 -24
- package/dist/src/orchestrator/grounding-check.js +39 -1
- package/dist/src/orchestrator/interactive-pause.d.ts +26 -0
- package/dist/src/orchestrator/interactive-pause.js +36 -0
- package/dist/src/orchestrator/message-processor.d.ts +4 -0
- package/dist/src/orchestrator/message-processor.js +268 -41
- package/dist/src/orchestrator/orchestrator.d.ts +64 -3
- package/dist/src/orchestrator/orchestrator.js +823 -120
- package/dist/src/orchestrator/preprocessor.js +3 -3
- package/dist/src/orchestrator/proactive-compact-detector.d.ts +26 -0
- package/dist/src/orchestrator/proactive-compact-detector.js +36 -0
- package/dist/src/orchestrator/prompts.js +17 -17
- package/dist/src/orchestrator/reactive-delegation.d.ts +39 -0
- package/dist/src/orchestrator/reactive-delegation.js +59 -0
- package/dist/src/orchestrator/retry-classifier.d.ts +2 -1
- package/dist/src/orchestrator/retry-classifier.js +46 -2
- package/dist/src/orchestrator/safety-askcard.d.ts +1 -1
- package/dist/src/orchestrator/safety-askcard.js +5 -2
- package/dist/src/orchestrator/safety-intercept.d.ts +50 -0
- package/dist/src/orchestrator/safety-intercept.js +62 -0
- package/dist/src/orchestrator/scope-reminder.js +1 -1
- package/dist/src/orchestrator/session-experience.d.ts +2 -1
- package/dist/src/orchestrator/session-experience.js +2 -1
- package/dist/src/orchestrator/should-run-gate.d.ts +5 -0
- package/dist/src/orchestrator/should-run-gate.js +18 -0
- package/dist/src/orchestrator/stall-watchdog.d.ts +31 -3
- package/dist/src/orchestrator/stall-watchdog.js +65 -10
- package/dist/src/orchestrator/stream-runner.d.ts +13 -3
- package/dist/src/orchestrator/stream-runner.js +115 -49
- package/dist/src/orchestrator/sub-agent-cap.d.ts +13 -1
- package/dist/src/orchestrator/sub-agent-cap.js +16 -1
- package/dist/src/orchestrator/sub-agent-model-tier.d.ts +13 -1
- package/dist/src/orchestrator/sub-agent-model-tier.js +16 -2
- package/dist/src/orchestrator/subagent-compactor.d.ts +53 -1
- package/dist/src/orchestrator/subagent-compactor.js +126 -15
- package/dist/src/orchestrator/tool-engine.d.ts +41 -0
- package/dist/src/orchestrator/tool-engine.js +846 -66
- package/dist/src/orchestrator/tool-limit-auto-recover.d.ts +22 -0
- package/dist/src/orchestrator/tool-limit-auto-recover.js +30 -0
- package/dist/src/orchestrator/turn-runner-deps.d.ts +19 -0
- package/dist/src/orchestrator/turn-watchdog.d.ts +44 -0
- package/dist/src/orchestrator/turn-watchdog.js +84 -0
- package/dist/src/pil/agent-operating-contract.d.ts +1 -1
- package/dist/src/pil/agent-operating-contract.js +6 -4
- package/dist/src/pil/cheap-model-playbook.d.ts +1 -1
- package/dist/src/pil/cheap-model-playbook.js +5 -1
- package/dist/src/pil/cheap-model-workbooks.d.ts +1 -1
- package/dist/src/pil/cheap-model-workbooks.js +1 -1
- package/dist/src/pil/discovery-types.d.ts +1 -0
- package/dist/src/pil/discovery.d.ts +1 -1
- package/dist/src/pil/discovery.js +18 -13
- package/dist/src/pil/layer1-intent.d.ts +18 -6
- package/dist/src/pil/layer1-intent.js +66 -757
- package/dist/src/pil/layer15-context-scan.js +15 -1
- package/dist/src/pil/layer1_5-complexity-size.d.ts +7 -0
- package/dist/src/pil/layer1_5-complexity-size.js +31 -5
- package/dist/src/pil/layer3-ee-injection.js +23 -8
- package/dist/src/pil/layer4-gsd.js +69 -16
- package/dist/src/pil/layer5-context.js +7 -3
- package/dist/src/pil/layer6-output.d.ts +23 -0
- package/dist/src/pil/layer6-output.js +5 -1
- package/dist/src/pil/llm-classify.d.ts +111 -5
- package/dist/src/pil/llm-classify.js +421 -189
- package/dist/src/pil/native-capabilities-workbook.d.ts +1 -1
- package/dist/src/pil/native-capabilities-workbook.js +8 -0
- package/dist/src/pil/pipeline.js +36 -2
- package/dist/src/pil/repo-grounding-probe.d.ts +15 -0
- package/dist/src/pil/repo-grounding-probe.js +136 -0
- package/dist/src/pil/repo-structure-hints.d.ts +7 -0
- package/dist/src/pil/repo-structure-hints.js +45 -0
- package/dist/src/pil/response-tools.js +5 -3
- package/dist/src/pil/schema.d.ts +1 -0
- package/dist/src/pil/schema.js +2 -0
- package/dist/src/pil/types.d.ts +18 -0
- package/dist/src/playbook/directives.d.ts +4 -0
- package/dist/src/playbook/directives.js +17 -5
- package/dist/src/product-loop/artifact-io.js +4 -0
- package/dist/src/product-loop/backlog-builder.d.ts +14 -1
- package/dist/src/product-loop/backlog-builder.js +30 -6
- package/dist/src/product-loop/criteria-seed.d.ts +51 -0
- package/dist/src/product-loop/criteria-seed.js +200 -0
- package/dist/src/product-loop/discovery-context-format.js +3 -1
- package/dist/src/product-loop/discovery-ecosystem.js +4 -1
- package/dist/src/product-loop/discovery-interview.d.ts +9 -0
- package/dist/src/product-loop/discovery-interview.js +60 -12
- package/dist/src/product-loop/discovery-recommender.js +2 -1
- package/dist/src/product-loop/discovery-schema.js +19 -2
- package/dist/src/product-loop/discovery-triage.d.ts +23 -0
- package/dist/src/product-loop/discovery-triage.js +109 -0
- package/dist/src/product-loop/gather.js +150 -2
- package/dist/src/product-loop/ideal-trace.d.ts +7 -0
- package/dist/src/product-loop/ideal-trace.js +64 -0
- package/dist/src/product-loop/index.d.ts +13 -1
- package/dist/src/product-loop/index.js +340 -52
- package/dist/src/product-loop/loop-driver.d.ts +7 -0
- package/dist/src/product-loop/loop-driver.js +330 -106
- package/dist/src/product-loop/phase-plan.d.ts +21 -0
- package/dist/src/product-loop/phase-plan.js +81 -6
- package/dist/src/product-loop/phase-rituals.d.ts +3 -0
- package/dist/src/product-loop/phase-rituals.js +8 -3
- package/dist/src/product-loop/phase-runner.js +39 -12
- package/dist/src/product-loop/plan-adherence-review.d.ts +26 -0
- package/dist/src/product-loop/plan-adherence-review.js +144 -0
- package/dist/src/product-loop/sprint-runner.d.ts +173 -0
- package/dist/src/product-loop/sprint-runner.js +863 -19
- package/dist/src/product-loop/types.d.ts +61 -5
- package/dist/src/providers/adapter.d.ts +1 -1
- package/dist/src/providers/adapter.js +3 -4
- package/dist/src/providers/anthropic.d.ts +9 -8
- package/dist/src/providers/anthropic.js +13 -47
- package/dist/src/providers/auth/browser-flow.d.ts +1 -1
- package/dist/src/providers/auth/browser-flow.js +1 -1
- package/dist/src/providers/auth/grok-oauth.d.ts +1 -0
- package/dist/src/providers/auth/grok-oauth.js +30 -5
- package/dist/src/providers/auth/openai-oauth.d.ts +1 -0
- package/dist/src/providers/auth/openai-oauth.js +15 -1
- package/dist/src/providers/auth/registry.js +0 -34
- package/dist/src/providers/auth/token-store.d.ts +9 -9
- package/dist/src/providers/auth/token-store.js +8 -67
- package/dist/src/providers/auth/types.d.ts +9 -1
- package/dist/src/providers/auth/types.js +1 -1
- package/dist/src/providers/capabilities.d.ts +24 -5
- package/dist/src/providers/capabilities.js +42 -24
- package/dist/src/providers/endpoints.d.ts +2 -2
- package/dist/src/providers/endpoints.js +11 -10
- package/dist/src/providers/env-store.d.ts +17 -0
- package/dist/src/providers/env-store.js +228 -0
- package/dist/src/providers/keychain.d.ts +22 -18
- package/dist/src/providers/keychain.js +127 -140
- package/dist/src/providers/mcp-vision-bridge.js +56 -146
- package/dist/src/providers/openai-compatible.js +8 -1
- package/dist/src/providers/pricing.d.ts +2 -2
- package/dist/src/providers/pricing.js +3 -13
- package/dist/src/providers/runtime.d.ts +43 -3
- package/dist/src/providers/runtime.js +88 -14
- package/dist/src/providers/strategies/base.strategy.d.ts +16 -0
- package/dist/src/providers/strategies/base.strategy.js +24 -1
- package/dist/src/providers/strategies/{siliconflow.strategy.d.ts → opencode-go.strategy.d.ts} +3 -3
- package/dist/src/providers/strategies/opencode-go.strategy.js +83 -0
- package/dist/src/providers/strategies/registry.js +4 -4
- package/dist/src/providers/strategies/thinking-mode.d.ts +109 -0
- package/dist/src/providers/strategies/thinking-mode.js +288 -1
- package/dist/src/providers/strategies/xai.strategy.js +27 -0
- package/dist/src/providers/strategies/zai.strategy.d.ts +14 -0
- package/dist/src/providers/strategies/zai.strategy.js +44 -0
- package/dist/src/providers/types.d.ts +5 -6
- package/dist/src/providers/types.js +2 -2
- package/dist/src/providers/vision-backend.d.ts +47 -0
- package/dist/src/providers/vision-backend.js +258 -0
- package/dist/src/providers/vision-proxy.d.ts +22 -9
- package/dist/src/providers/vision-proxy.js +63 -132
- package/dist/src/providers/warm.d.ts +65 -0
- package/dist/src/providers/warm.js +145 -0
- package/dist/src/providers/wire-debug.js +95 -0
- package/dist/src/router/decide.d.ts +13 -0
- package/dist/src/router/decide.js +138 -36
- package/dist/src/router/peak-hour.d.ts +38 -0
- package/dist/src/router/peak-hour.js +107 -0
- package/dist/src/router/step-router.js +3 -2
- package/dist/src/router/warm.js +4 -5
- package/dist/src/scaffold/continuation-prompt.d.ts +11 -0
- package/dist/src/scaffold/continuation-prompt.js +26 -0
- package/dist/src/scaffold/point-to-existing.d.ts +21 -0
- package/dist/src/scaffold/point-to-existing.js +25 -0
- package/dist/src/self-qa/agentic-loop.js +6 -5
- package/dist/src/{ui/state → state}/active-run.d.ts +19 -0
- package/dist/src/{ui/state → state}/active-run.js +21 -0
- package/dist/src/{ui/status-bar/store.d.ts → state/status-bar-store.d.ts} +4 -1
- package/dist/src/{ui/status-bar/store.js → state/status-bar-store.js} +12 -9
- package/dist/src/state/turn-trace.d.ts +43 -0
- package/dist/src/state/turn-trace.js +32 -0
- package/dist/src/storage/db.js +2 -1
- package/dist/src/storage/index.d.ts +1 -1
- package/dist/src/storage/index.js +1 -1
- package/dist/src/storage/interaction-log.d.ts +1 -1
- package/dist/src/storage/migrations.js +71 -1
- package/dist/src/storage/sessions.d.ts +28 -10
- package/dist/src/storage/sessions.js +78 -21
- package/dist/src/storage/transcript-view.js +1 -1
- package/dist/src/storage/transcript.d.ts +51 -0
- package/dist/src/storage/transcript.js +340 -15
- package/dist/src/tools/file.d.ts +15 -0
- package/dist/src/tools/file.js +32 -0
- package/dist/src/tools/git-safety.d.ts +19 -0
- package/dist/src/tools/git-safety.js +168 -0
- package/dist/src/tools/native-tools.d.ts +1 -1
- package/dist/src/tools/native-tools.js +81 -1
- package/dist/src/tools/registry.d.ts +20 -0
- package/dist/src/tools/registry.js +576 -23
- package/dist/src/tools/research.d.ts +29 -0
- package/dist/src/tools/research.js +233 -0
- package/dist/src/types/index.d.ts +147 -4
- package/dist/src/ui/app.js +0 -0
- package/dist/src/ui/cards/product-status-card.js +1 -1
- package/dist/src/ui/components/agent-rail-activities.d.ts +26 -0
- package/dist/src/ui/components/agent-rail-activities.js +47 -0
- package/dist/src/ui/components/bubble-body-guard.d.ts +27 -0
- package/dist/src/ui/components/bubble-body-guard.js +50 -0
- package/dist/src/ui/components/compact-progress-card.d.ts +24 -0
- package/dist/src/ui/components/compact-progress-card.js +42 -0
- package/dist/src/ui/components/context-rail.d.ts +26 -0
- package/dist/src/ui/components/context-rail.js +33 -0
- package/dist/src/ui/components/council-conclusion-card.d.ts +73 -0
- package/dist/src/ui/components/council-conclusion-card.js +420 -0
- package/dist/src/ui/components/council-debate-pill.d.ts +36 -0
- package/dist/src/ui/components/council-debate-pill.js +34 -0
- package/dist/src/ui/components/council-info-card.js +2 -2
- package/dist/src/ui/components/council-leader-bubble.d.ts +10 -3
- package/dist/src/ui/components/council-leader-bubble.js +21 -11
- package/dist/src/ui/components/council-message-bubble.d.ts +15 -2
- package/dist/src/ui/components/council-message-bubble.js +16 -15
- package/dist/src/ui/components/council-phase-timeline.d.ts +9 -1
- package/dist/src/ui/components/council-phase-timeline.js +66 -17
- package/dist/src/ui/components/council-placeholder-bubble.d.ts +16 -9
- package/dist/src/ui/components/council-placeholder-bubble.js +32 -29
- package/dist/src/ui/components/council-question-card.js +13 -12
- package/dist/src/ui/components/council-rail-rounds.d.ts +26 -0
- package/dist/src/ui/components/council-rail-rounds.js +57 -0
- package/dist/src/ui/components/council-round-group.d.ts +38 -0
- package/dist/src/ui/components/council-round-group.js +88 -0
- package/dist/src/ui/components/council-status-list.d.ts +3 -1
- package/dist/src/ui/components/council-status-list.js +36 -24
- package/dist/src/ui/components/council-synthesis-banner.d.ts +7 -2
- package/dist/src/ui/components/council-synthesis-banner.js +20 -5
- package/dist/src/ui/components/halt-recovery-card.js +9 -5
- package/dist/src/ui/components/jump-to-latest-pill.d.ts +11 -0
- package/dist/src/ui/components/jump-to-latest-pill.js +14 -0
- package/dist/src/ui/components/message-view.d.ts +15 -0
- package/dist/src/ui/components/message-view.js +50 -1
- package/dist/src/ui/components/prompt-box.js +18 -16
- package/dist/src/ui/components/session-tree-card.d.ts +14 -0
- package/dist/src/ui/components/session-tree-card.js +46 -0
- package/dist/src/ui/components/slash-inline-menu.d.ts +12 -0
- package/dist/src/ui/components/slash-inline-menu.js +26 -5
- package/dist/src/ui/components/task-list-panel.d.ts +14 -1
- package/dist/src/ui/components/task-list-panel.js +22 -2
- package/dist/src/ui/components/tool-group.d.ts +15 -3
- package/dist/src/ui/components/tool-group.js +69 -11
- package/dist/src/ui/containers/modals-layer.d.ts +4 -2
- package/dist/src/ui/containers/modals-layer.js +2 -2
- package/dist/src/ui/council-harness-event.d.ts +57 -0
- package/dist/src/ui/council-harness-event.js +46 -0
- package/dist/src/ui/heartbeat-debug.d.ts +29 -0
- package/dist/src/ui/heartbeat-debug.js +45 -0
- package/dist/src/ui/hooks/use-session-picker.d.ts +3 -3
- package/dist/src/ui/mcp-modal.js +2 -4
- package/dist/src/ui/modals/api-key-modal.js +1 -1
- package/dist/src/ui/modals/connect-modal.js +4 -3
- package/dist/src/ui/modals/model-picker-modal.d.ts +8 -18
- package/dist/src/ui/modals/model-picker-modal.js +8 -10
- package/dist/src/ui/modals/session-picker-modal.d.ts +2 -2
- package/dist/src/ui/modals/session-picker-modal.js +3 -5
- package/dist/src/ui/picker-providers.d.ts +1 -1
- package/dist/src/ui/picker-providers.js +1 -1
- package/dist/src/ui/primitives/index.d.ts +1 -0
- package/dist/src/ui/primitives/index.js +2 -0
- package/dist/src/ui/primitives/semantic-primitives.d.ts +76 -0
- package/dist/src/ui/primitives/semantic-primitives.js +81 -0
- package/dist/src/ui/slash/compact.js +5 -7
- package/dist/src/ui/slash/cost.js +1 -1
- package/dist/src/ui/slash/council.js +19 -1
- package/dist/src/ui/slash/debug.d.ts +3 -31
- package/dist/src/ui/slash/debug.js +9 -20
- package/dist/src/ui/slash/ee.js +81 -0
- package/dist/src/ui/slash/ideal.d.ts +6 -2
- package/dist/src/ui/slash/ideal.js +97 -7
- package/dist/src/ui/slash/menu-items.d.ts +7 -0
- package/dist/src/ui/slash/menu-items.js +23 -20
- package/dist/src/ui/slash/registry.d.ts +2 -0
- package/dist/src/ui/slash/registry.js +4 -0
- package/dist/src/ui/status-bar/cache-hit.d.ts +6 -0
- package/dist/src/ui/status-bar/cache-hit.js +9 -0
- package/dist/src/ui/status-bar/index.d.ts +1 -1
- package/dist/src/ui/status-bar/index.js +7 -3
- package/dist/src/ui/status-bar/usd-meter.d.ts +5 -4
- package/dist/src/ui/status-bar/usd-meter.js +6 -4
- package/dist/src/ui/theme.d.ts +1 -0
- package/dist/src/ui/theme.js +2 -0
- package/dist/src/ui/types.d.ts +7 -0
- package/dist/src/ui/use-app-logic.js +0 -0
- package/dist/src/ui/utils/agent-activities.d.ts +39 -0
- package/dist/src/ui/utils/agent-activities.js +96 -0
- package/dist/src/ui/utils/format.d.ts +14 -0
- package/dist/src/ui/utils/format.js +23 -3
- package/dist/src/ui/utils/group-tool-entries.d.ts +26 -0
- package/dist/src/ui/utils/group-tool-entries.js +111 -0
- package/dist/src/ui/utils/tool-summary.d.ts +21 -0
- package/dist/src/ui/utils/tool-summary.js +91 -0
- package/dist/src/usage/downgrade.js +2 -2
- package/dist/src/usage/product-ledger.js +2 -2
- package/dist/src/utils/event-loop-monitor.d.ts +85 -0
- package/dist/src/utils/event-loop-monitor.js +107 -0
- package/dist/src/utils/install-manager.js +2 -1
- package/dist/src/utils/llm-deadline.d.ts +14 -0
- package/dist/src/utils/llm-deadline.js +19 -0
- package/dist/src/utils/logger.js +2 -2
- package/dist/src/utils/loop-profiler.d.ts +102 -0
- package/dist/src/utils/loop-profiler.js +202 -0
- package/dist/src/utils/permission-mode.js +5 -3
- package/dist/src/utils/redactor.js +1 -1
- package/dist/src/utils/settings.d.ts +180 -5
- package/dist/src/utils/settings.js +271 -31
- package/dist/src/utils/side-question.d.ts +1 -2
- package/dist/src/utils/side-question.js +2 -2
- package/dist/src/utils/visible-retry.d.ts +11 -0
- package/dist/src/utils/visible-retry.js +10 -1
- package/dist/src/verify/entrypoint.d.ts +1 -1
- package/dist/src/verify/entrypoint.js +52 -17
- package/dist/src/verify/orchestrator.d.ts +1 -1
- package/dist/src/verify/orchestrator.js +20 -3
- package/dist/src/verify/recipes.d.ts +13 -0
- package/dist/src/verify/recipes.js +15 -0
- package/package.json +134 -132
- package/dist/src/cli/bw-vault.d.ts +0 -55
- package/dist/src/cli/bw-vault.js +0 -133
- package/dist/src/mcp/ee-tools.d.ts +0 -46
- package/dist/src/mcp/ee-tools.js +0 -193
- package/dist/src/providers/auth/gcloud.d.ts +0 -28
- package/dist/src/providers/auth/gcloud.js +0 -102
- package/dist/src/providers/auth/gemini-oauth.d.ts +0 -82
- package/dist/src/providers/auth/gemini-oauth.js +0 -472
- package/dist/src/providers/gemini.d.ts +0 -11
- package/dist/src/providers/gemini.js +0 -45
- package/dist/src/providers/siliconflow-sse-repair.d.ts +0 -58
- package/dist/src/providers/siliconflow-sse-repair.js +0 -177
- package/dist/src/providers/strategies/google.strategy.d.ts +0 -22
- package/dist/src/providers/strategies/google.strategy.js +0 -174
- package/dist/src/providers/strategies/siliconflow.strategy.js +0 -29
- package/dist/src/ui/containers/chat-feed.d.ts +0 -40
- package/dist/src/ui/containers/chat-feed.js +0 -66
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { getModelByTier, getModelInfo, getProviderPeakHourRule, SWITCH_PROVIDER_ORDER } from "../models/registry.js";
|
|
2
|
+
import { detectProviderForModel } from "../providers/runtime.js";
|
|
3
|
+
import { getPeakHourPolicy, isProviderDisabled } from "../utils/settings.js";
|
|
4
|
+
export function hourInTimezone(now, timezone) {
|
|
5
|
+
const parts = new Intl.DateTimeFormat("en-US", {
|
|
6
|
+
timeZone: timezone,
|
|
7
|
+
hour: "numeric",
|
|
8
|
+
hour12: false,
|
|
9
|
+
}).formatToParts(now);
|
|
10
|
+
const hour = parts.find((p) => p.type === "hour")?.value;
|
|
11
|
+
return hour ? Number(hour) : 0;
|
|
12
|
+
}
|
|
13
|
+
/** @deprecated Use hourInTimezone — kept for tests referencing UTC+8. */
|
|
14
|
+
export function hourUtc8(now) {
|
|
15
|
+
return hourInTimezone(now, "Asia/Shanghai");
|
|
16
|
+
}
|
|
17
|
+
export function peakHourWindows(rule) {
|
|
18
|
+
if (rule.windows?.length)
|
|
19
|
+
return rule.windows;
|
|
20
|
+
if (rule.start_hour != null && rule.end_hour != null) {
|
|
21
|
+
return [{ start_hour: rule.start_hour, end_hour: rule.end_hour }];
|
|
22
|
+
}
|
|
23
|
+
return [];
|
|
24
|
+
}
|
|
25
|
+
export function isPeakHourForProvider(provider, now, userPolicy = getPeakHourPolicy()) {
|
|
26
|
+
if (userPolicy.enabled === false)
|
|
27
|
+
return false;
|
|
28
|
+
const rule = getProviderPeakHourRule(provider);
|
|
29
|
+
if (!rule)
|
|
30
|
+
return false;
|
|
31
|
+
const h = hourInTimezone(now, rule.timezone);
|
|
32
|
+
return peakHourWindows(rule).some((w) => h >= w.start_hour && h < w.end_hour);
|
|
33
|
+
}
|
|
34
|
+
/** @deprecated Use isPeakHourForProvider(provider, ...) — window is per-provider from catalog. */
|
|
35
|
+
export function isPeakHourUtc8(now, userPolicy) {
|
|
36
|
+
return isPeakHourForProvider("zai", now, userPolicy) || isPeakHourForProvider("deepseek", now, userPolicy);
|
|
37
|
+
}
|
|
38
|
+
function sameProviderDowngrade(modelId, provider) {
|
|
39
|
+
const rule = getProviderPeakHourRule(provider);
|
|
40
|
+
if (!rule)
|
|
41
|
+
return null;
|
|
42
|
+
if (!rule.sensitive_model_ids.includes(modelId))
|
|
43
|
+
return null;
|
|
44
|
+
return rule.fallback_model_id;
|
|
45
|
+
}
|
|
46
|
+
function pickSwitchFallback(excludeProvider) {
|
|
47
|
+
const rule = getProviderPeakHourRule(excludeProvider);
|
|
48
|
+
const order = rule?.switch_fallback_providers ?? SWITCH_PROVIDER_ORDER;
|
|
49
|
+
for (const p of order) {
|
|
50
|
+
if (p === excludeProvider)
|
|
51
|
+
continue;
|
|
52
|
+
if (isProviderDisabled(p))
|
|
53
|
+
continue;
|
|
54
|
+
const m = getModelByTier("fast", p) ?? getModelByTier("balanced", p);
|
|
55
|
+
if (m && m.provider === p)
|
|
56
|
+
return m;
|
|
57
|
+
}
|
|
58
|
+
return undefined;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Adjust a concrete model id for peak-hour policy. No-op outside the provider's
|
|
62
|
+
* catalog-defined window or when user policy is disabled.
|
|
63
|
+
*/
|
|
64
|
+
export function adjustPeakHourModel(modelId, opts) {
|
|
65
|
+
const userPolicy = opts?.policy ?? getPeakHourPolicy();
|
|
66
|
+
const now = opts?.now ?? new Date();
|
|
67
|
+
const provider = detectProviderForModel(modelId);
|
|
68
|
+
if (!isPeakHourForProvider(provider, now, userPolicy)) {
|
|
69
|
+
return { modelId, provider, adjusted: false };
|
|
70
|
+
}
|
|
71
|
+
const downgraded = sameProviderDowngrade(modelId, provider);
|
|
72
|
+
if (downgraded) {
|
|
73
|
+
if (userPolicy.mode === "switch") {
|
|
74
|
+
const alt = pickSwitchFallback(provider);
|
|
75
|
+
if (alt && alt.id !== modelId) {
|
|
76
|
+
return {
|
|
77
|
+
modelId: alt.id,
|
|
78
|
+
provider: alt.provider,
|
|
79
|
+
adjusted: true,
|
|
80
|
+
reason: `peak-hour(${provider}→${alt.provider}:${alt.id})`,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
const info = getModelInfo(downgraded);
|
|
85
|
+
if (info?.provider === provider) {
|
|
86
|
+
return {
|
|
87
|
+
modelId: downgraded,
|
|
88
|
+
provider,
|
|
89
|
+
adjusted: true,
|
|
90
|
+
reason: `peak-hour(${modelId}→${downgraded})`,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return { modelId, provider, adjusted: false };
|
|
95
|
+
}
|
|
96
|
+
/** Tier lookup with peak-hour adjustment applied to the resolved model. */
|
|
97
|
+
export function getRoutedModelByTier(tier, preferProvider, opts) {
|
|
98
|
+
const base = getModelByTier(tier, preferProvider);
|
|
99
|
+
if (!base)
|
|
100
|
+
return undefined;
|
|
101
|
+
const adj = adjustPeakHourModel(base.id, opts);
|
|
102
|
+
if (!adj.adjusted)
|
|
103
|
+
return base;
|
|
104
|
+
const info = getModelInfo(adj.modelId);
|
|
105
|
+
return info ?? base;
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=peak-hour.js.map
|
|
@@ -28,6 +28,7 @@ import { getModelByTier } from "../models/registry.js";
|
|
|
28
28
|
import { detectProviderForModel } from "../providers/runtime.js";
|
|
29
29
|
import { readTimeoutEnv } from "../utils/ee-logger.js";
|
|
30
30
|
import { isModelDisabled, isProviderDisabled, loadUserSettings } from "../utils/settings.js";
|
|
31
|
+
import { getRoutedModelByTier } from "./peak-hour.js";
|
|
31
32
|
// ─── EE-guided SAMR override ─────────────────────────────────────────────────
|
|
32
33
|
// EE_SAMR_TIMEOUT: per-call budget for consulting the EE brain about SAMR.
|
|
33
34
|
// Default 2s, range 500ms..5s. Falls back to heuristics on timeout/error.
|
|
@@ -187,7 +188,7 @@ export function decideStepRouting(phase1ModelId, defaultProvider, config) {
|
|
|
187
188
|
// ─── Internal helpers ────────────────────────────────────────────────────────
|
|
188
189
|
function resolveExecutionModel(provider, tier, excludeModelId) {
|
|
189
190
|
// Try same provider first
|
|
190
|
-
const sameProvider =
|
|
191
|
+
const sameProvider = getRoutedModelByTier(tier, provider);
|
|
191
192
|
if (sameProvider && sameProvider.id !== excludeModelId) {
|
|
192
193
|
// Guard: check provider-disabled and model-disabled (mirrors cross-provider branch)
|
|
193
194
|
if (!isProviderDisabled(sameProvider.provider) && !isModelDisabled(sameProvider.id)) {
|
|
@@ -195,7 +196,7 @@ function resolveExecutionModel(provider, tier, excludeModelId) {
|
|
|
195
196
|
}
|
|
196
197
|
}
|
|
197
198
|
// If no same-provider model in this tier, try any provider
|
|
198
|
-
const anyProvider =
|
|
199
|
+
const anyProvider = getRoutedModelByTier(tier);
|
|
199
200
|
if (anyProvider && anyProvider.id !== excludeModelId) {
|
|
200
201
|
// Only use cross-provider if the provider and model aren't disabled
|
|
201
202
|
if (!isProviderDisabled(anyProvider.provider) && !isModelDisabled(anyProvider.id)) {
|
package/dist/src/router/warm.js
CHANGED
|
@@ -6,13 +6,13 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import { routeModel as bridgeRouteModel } from "../ee/bridge.js";
|
|
8
8
|
import { getDefaultEEClient } from "../ee/intercept.js";
|
|
9
|
-
import {
|
|
9
|
+
import { getRoutedModelByTier } from "./peak-hour.js";
|
|
10
10
|
import { PROVIDER_INHERIT } from "./provider-sentinel.js";
|
|
11
11
|
/**
|
|
12
12
|
* Map the session's provider to the EE runtime whose tier ladder the EE serves.
|
|
13
13
|
* EE keys its `getModelTiers()` ladders by agent runtime, not provider, and only
|
|
14
|
-
* the catalog-backed runtimes (claude/codex
|
|
15
|
-
* Providers without an EE runtime (deepseek/
|
|
14
|
+
* the catalog-backed runtimes (claude/codex) resolve to a non-null model.
|
|
15
|
+
* Providers without an EE runtime (deepseek/xai) map to "" — EE then
|
|
16
16
|
* returns the routing TIER with a null model and we resolve the concrete model
|
|
17
17
|
* from the shared catalog for the session provider. This removes the old
|
|
18
18
|
* hardcoded `runtime:"claude"`, which leaked EE's stale `claude-*` ids into the
|
|
@@ -21,7 +21,6 @@ import { PROVIDER_INHERIT } from "./provider-sentinel.js";
|
|
|
21
21
|
const PROVIDER_TO_EE_RUNTIME = Object.freeze({
|
|
22
22
|
anthropic: "claude",
|
|
23
23
|
openai: "codex",
|
|
24
|
-
google: "gemini",
|
|
25
24
|
});
|
|
26
25
|
function eeRuntimeForProvider(provider) {
|
|
27
26
|
return (provider && PROVIDER_TO_EE_RUNTIME[provider]) || "";
|
|
@@ -36,7 +35,7 @@ export async function callWarmRoute(prompt, opts) {
|
|
|
36
35
|
// EE returns a model only for catalog-backed runtimes; otherwise resolve the
|
|
37
36
|
// concrete model from the catalog for the session provider + decided tier.
|
|
38
37
|
const catalogTier = TIER_TO_CATALOG_TIER[bridgeResult.tier] ?? "balanced";
|
|
39
|
-
const model = bridgeResult.model ||
|
|
38
|
+
const model = bridgeResult.model || getRoutedModelByTier(catalogTier, opts.defaultProvider)?.id;
|
|
40
39
|
if (model) {
|
|
41
40
|
return {
|
|
42
41
|
tier: bridgeResult.tier === "fast" ? "hot" : bridgeResult.tier === "premium" ? "cold" : "warm",
|
|
@@ -10,3 +10,14 @@ export interface ContinuationPromptInput {
|
|
|
10
10
|
installedPackages?: readonly string[];
|
|
11
11
|
}
|
|
12
12
|
export declare function buildIdealContinuationPrompt(input: ContinuationPromptInput): string;
|
|
13
|
+
export interface AdoptExistingPromptInput {
|
|
14
|
+
originalPrompt: string;
|
|
15
|
+
projectDir: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Build the continuation prompt fed to the LLM after the user adopts an EXISTING
|
|
19
|
+
* project via the CB-3 "Point to existing" recovery option. Unlike the init_new
|
|
20
|
+
* variant this makes no template/BB assumptions — the target is an arbitrary
|
|
21
|
+
* repo the user already has, with a verify recipe already detected there.
|
|
22
|
+
*/
|
|
23
|
+
export declare function buildAdoptExistingContinuationPrompt(input: AdoptExistingPromptInput): string;
|
|
@@ -63,4 +63,30 @@ Constraints:
|
|
|
63
63
|
- Don't ask "do you want me to continue?" — proceed end-to-end.
|
|
64
64
|
- If you hit a blocker that genuinely needs the user, state EXACTLY which decision is blocking and stop.`;
|
|
65
65
|
}
|
|
66
|
+
/**
|
|
67
|
+
* Build the continuation prompt fed to the LLM after the user adopts an EXISTING
|
|
68
|
+
* project via the CB-3 "Point to existing" recovery option. Unlike the init_new
|
|
69
|
+
* variant this makes no template/BB assumptions — the target is an arbitrary
|
|
70
|
+
* repo the user already has, with a verify recipe already detected there.
|
|
71
|
+
*/
|
|
72
|
+
export function buildAdoptExistingContinuationPrompt(input) {
|
|
73
|
+
const { originalPrompt, projectDir } = input;
|
|
74
|
+
return `You are continuing a /ideal product loop in an EXISTING project the user pointed to at ${projectDir}. A verify recipe was detected there, so the project already has a runnable test/build setup — adopt it, do NOT re-scaffold.
|
|
75
|
+
|
|
76
|
+
User's original request:
|
|
77
|
+
"${originalPrompt}"
|
|
78
|
+
|
|
79
|
+
Implement this now against the existing codebase. Do NOT ask the user to restate the request.
|
|
80
|
+
|
|
81
|
+
1. Discover structure (1-2 tool calls max): list the project directory, then read the manifest that exists (package.json / pyproject.toml / go.mod / Cargo.toml / *.csproj) and any README/AGENTS.md to learn the stack, entry point, and conventions. Do NOT assume files — skip whatever is absent.
|
|
82
|
+
2. Design briefly (5-10 lines): the entities/modules/endpoints to add, matching the conventions you observed (naming, error-handling, DI, folder layout).
|
|
83
|
+
3. Implement: create/edit files in the EXISTING layout; mirror the surrounding patterns. Never hardcode secrets or URLs — read config from the project's existing mechanism.
|
|
84
|
+
4. Verify: run the project's OWN detected test/build command; it must pass. Report the exact command + an output excerpt as evidence.
|
|
85
|
+
5. Summarize in 3-5 bullets: what was added, where, and how to run/test it.
|
|
86
|
+
|
|
87
|
+
Constraints:
|
|
88
|
+
- Your working directory is already ${projectDir}; do NOT cd into it and do NOT re-scaffold.
|
|
89
|
+
- Don't ask "do you want me to continue?" — proceed end-to-end.
|
|
90
|
+
- If a genuine blocker needs the user (missing API key, ambiguous requirement), state EXACTLY which decision is blocking and stop.`;
|
|
91
|
+
}
|
|
66
92
|
//# sourceMappingURL=continuation-prompt.js.map
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* Designed for testability: callers inject detectVerifyRecipe so unit tests
|
|
6
6
|
* never hit the real orchestrator.
|
|
7
7
|
*/
|
|
8
|
+
import type { VerifyRecipe } from "../types/index.js";
|
|
8
9
|
import { detectBBFramework } from "./init-new.js";
|
|
9
10
|
export interface PointToExistingOptions {
|
|
10
11
|
/** Raw path string entered by the user. May be relative or absolute. */
|
|
@@ -26,6 +27,26 @@ export interface PointToExistingResult {
|
|
|
26
27
|
targetFramework?: "muonroi-building-block" | string;
|
|
27
28
|
}
|
|
28
29
|
export { detectBBFramework };
|
|
30
|
+
/**
|
|
31
|
+
* Deterministic, filesystem-only verify-recipe detection for an existing project
|
|
32
|
+
* the user pointed to via the CB-3 recovery card.
|
|
33
|
+
*
|
|
34
|
+
* WHY NOT the orchestrator's detectVerifyRecipe: that path runs an LLM
|
|
35
|
+
* verify-detect sub-agent against the orchestrator's OWN (session) cwd via
|
|
36
|
+
* `this.bash.getCwd()` — it cannot inspect an arbitrary pointed-to directory, so
|
|
37
|
+
* wiring it here was deferred and the handler stubbed to `null` (point-to-existing
|
|
38
|
+
* therefore ALWAYS reported "no recipe", making the recovery option inert).
|
|
39
|
+
* `inferVerifyProjectProfile` reads the target dir's manifest/build files
|
|
40
|
+
* directly (package.json test/check/lint, Makefile, pyproject, go.mod, cargo,
|
|
41
|
+
* maven/gradle, *.csproj) — the correct detector for adopting an existing repo.
|
|
42
|
+
*
|
|
43
|
+
* Returns the recipe only when it is actually RUNNABLE (has a test/build/start
|
|
44
|
+
* command). The bare "unknown" fallback that `inferVerifyProjectProfile` emits
|
|
45
|
+
* for a directory with no recognizable project files carries empty commands →
|
|
46
|
+
* we return null so point-to-existing correctly reports `no_recipe` instead of
|
|
47
|
+
* falsely adopting an empty directory.
|
|
48
|
+
*/
|
|
49
|
+
export declare function detectExistingProjectRecipe(cwd: string): VerifyRecipe | null;
|
|
29
50
|
/**
|
|
30
51
|
* Resolve and validate a user-provided path for sprint re-entry.
|
|
31
52
|
*
|
|
@@ -7,8 +7,33 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import { realpathSync, statSync } from "node:fs";
|
|
9
9
|
import * as path from "node:path";
|
|
10
|
+
import { inferVerifyProjectProfile } from "../verify/recipes.js";
|
|
10
11
|
import { detectBBFramework } from "./init-new.js";
|
|
11
12
|
export { detectBBFramework };
|
|
13
|
+
/**
|
|
14
|
+
* Deterministic, filesystem-only verify-recipe detection for an existing project
|
|
15
|
+
* the user pointed to via the CB-3 recovery card.
|
|
16
|
+
*
|
|
17
|
+
* WHY NOT the orchestrator's detectVerifyRecipe: that path runs an LLM
|
|
18
|
+
* verify-detect sub-agent against the orchestrator's OWN (session) cwd via
|
|
19
|
+
* `this.bash.getCwd()` — it cannot inspect an arbitrary pointed-to directory, so
|
|
20
|
+
* wiring it here was deferred and the handler stubbed to `null` (point-to-existing
|
|
21
|
+
* therefore ALWAYS reported "no recipe", making the recovery option inert).
|
|
22
|
+
* `inferVerifyProjectProfile` reads the target dir's manifest/build files
|
|
23
|
+
* directly (package.json test/check/lint, Makefile, pyproject, go.mod, cargo,
|
|
24
|
+
* maven/gradle, *.csproj) — the correct detector for adopting an existing repo.
|
|
25
|
+
*
|
|
26
|
+
* Returns the recipe only when it is actually RUNNABLE (has a test/build/start
|
|
27
|
+
* command). The bare "unknown" fallback that `inferVerifyProjectProfile` emits
|
|
28
|
+
* for a directory with no recognizable project files carries empty commands →
|
|
29
|
+
* we return null so point-to-existing correctly reports `no_recipe` instead of
|
|
30
|
+
* falsely adopting an empty directory.
|
|
31
|
+
*/
|
|
32
|
+
export function detectExistingProjectRecipe(cwd) {
|
|
33
|
+
const { recipe } = inferVerifyProjectProfile(cwd);
|
|
34
|
+
const runnable = recipe.testCommands.length > 0 || recipe.buildCommands.length > 0 || Boolean(recipe.startCommand);
|
|
35
|
+
return runnable ? recipe : null;
|
|
36
|
+
}
|
|
12
37
|
// ---------------------------------------------------------------------------
|
|
13
38
|
// Implementation
|
|
14
39
|
// ---------------------------------------------------------------------------
|
|
@@ -141,15 +141,16 @@ export async function createLLMBrain(opts) {
|
|
|
141
141
|
const apiKey = await loadKeyForProvider(provider);
|
|
142
142
|
if (!apiKey)
|
|
143
143
|
throw new Error(`No API key found for provider '${provider}'`);
|
|
144
|
-
|
|
145
|
-
|
|
144
|
+
// Registers the factory so resolveModelRuntime can derive it from the model.
|
|
145
|
+
createProviderFactory(provider, { apiKey });
|
|
146
|
+
const runtime = resolveModelRuntime(opts.modelId);
|
|
146
147
|
const systemPrompt = opts.systemPrompt ?? DEFAULT_SYSTEM_PROMPT;
|
|
147
148
|
const maxTokens = opts.maxTokens ?? 1024;
|
|
148
149
|
const retryOnEmpty = opts.retryOnEmpty !== false;
|
|
149
150
|
// @ai-sdk/openai-compatible's chat schema exposes `strictJsonSchema: false`
|
|
150
151
|
// for providers that don't honour OpenAI's strict JSON schema mode.
|
|
151
|
-
// DeepSeek
|
|
152
|
-
//
|
|
152
|
+
// DeepSeek only supports `response_format: {type: "json_object"}` — it
|
|
153
|
+
// rejects the full
|
|
153
154
|
// schema response_format. Setting strictJsonSchema=false makes AI SDK fall
|
|
154
155
|
// back to lenient json_object mode silently (no "responseFormat not
|
|
155
156
|
// supported" warning) while still steering the model toward JSON output.
|
|
@@ -161,7 +162,7 @@ export async function createLLMBrain(opts) {
|
|
|
161
162
|
const mergedProviderOptions = {
|
|
162
163
|
...(runtime.providerOptions ?? {}),
|
|
163
164
|
};
|
|
164
|
-
if (provider === "deepseek"
|
|
165
|
+
if (provider === "deepseek") {
|
|
165
166
|
mergedProviderOptions[provider] = {
|
|
166
167
|
...(mergedProviderOptions[provider] ?? {}),
|
|
167
168
|
strictJsonSchema: false,
|
|
@@ -21,6 +21,25 @@ export declare const activeRunStore: {
|
|
|
21
21
|
clearActiveRun: () => void;
|
|
22
22
|
subscribe: (fn: Listener) => (() => void);
|
|
23
23
|
};
|
|
24
|
+
/**
|
|
25
|
+
* Single canonical writer for "which run is the workspace focused on".
|
|
26
|
+
* Writes the durable pointer (`state.md` `Active Run`) AND the in-memory cache
|
|
27
|
+
* atomically, so disk and StatusBar/reporter never drift (F8 follow-up).
|
|
28
|
+
*
|
|
29
|
+
* The disk write is idempotent with `ensureRunScoped`'s earlier write for the
|
|
30
|
+
* same runId — routing the focus moment through here just guarantees they agree.
|
|
31
|
+
*/
|
|
32
|
+
export declare function setWorkspaceFocus(flowDir: string, focus: {
|
|
33
|
+
runId: string;
|
|
34
|
+
productSlug: string;
|
|
35
|
+
reason?: string;
|
|
36
|
+
}): Promise<void>;
|
|
37
|
+
/**
|
|
38
|
+
* Clear the workspace focus cache when a run ends (shipped / halted).
|
|
39
|
+
* Cache-only by design: the durable `Active Run` pointer is left intact as a
|
|
40
|
+
* historical marker so `/ideal phases` still resolves the last run post-ship.
|
|
41
|
+
*/
|
|
42
|
+
export declare function clearWorkspaceFocus(): void;
|
|
24
43
|
/** Test helper: reset to initial state. */
|
|
25
44
|
export declare function __resetActiveRunStoreForTests(): void;
|
|
26
45
|
export {};
|
|
@@ -37,6 +37,27 @@ function makeActiveRunStore() {
|
|
|
37
37
|
};
|
|
38
38
|
}
|
|
39
39
|
export const activeRunStore = makeActiveRunStore();
|
|
40
|
+
/**
|
|
41
|
+
* Single canonical writer for "which run is the workspace focused on".
|
|
42
|
+
* Writes the durable pointer (`state.md` `Active Run`) AND the in-memory cache
|
|
43
|
+
* atomically, so disk and StatusBar/reporter never drift (F8 follow-up).
|
|
44
|
+
*
|
|
45
|
+
* The disk write is idempotent with `ensureRunScoped`'s earlier write for the
|
|
46
|
+
* same runId — routing the focus moment through here just guarantees they agree.
|
|
47
|
+
*/
|
|
48
|
+
export async function setWorkspaceFocus(flowDir, focus) {
|
|
49
|
+
const { setActiveRunId } = await import("../flow/run-manager.js");
|
|
50
|
+
await setActiveRunId(flowDir, focus.runId);
|
|
51
|
+
activeRunStore.setActiveRun(focus.runId, flowDir, focus.productSlug);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Clear the workspace focus cache when a run ends (shipped / halted).
|
|
55
|
+
* Cache-only by design: the durable `Active Run` pointer is left intact as a
|
|
56
|
+
* historical marker so `/ideal phases` still resolves the last run post-ship.
|
|
57
|
+
*/
|
|
58
|
+
export function clearWorkspaceFocus() {
|
|
59
|
+
activeRunStore.clearActiveRun();
|
|
60
|
+
}
|
|
40
61
|
/** Test helper: reset to initial state. */
|
|
41
62
|
export function __resetActiveRunStoreForTests() {
|
|
42
63
|
activeRunStore.clearActiveRun();
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* src/
|
|
2
|
+
* src/state/status-bar-store.ts
|
|
3
3
|
*
|
|
4
4
|
* Status bar store: subscribable atom holding model/provider/tier/tokens/USD/degraded.
|
|
5
5
|
* wireStatusBar() connects to routerStore (Plan 03), subscribeThresholds (Plan 04),
|
|
6
6
|
* and subscribeDowngrade (Plan 05).
|
|
7
|
+
*
|
|
8
|
+
* Presentation-agnostic state — lives outside src/ui so the headless core
|
|
9
|
+
* (orchestrator/tool-engine/stream-runner) can read it without importing ui/.
|
|
7
10
|
*/
|
|
8
11
|
export interface SprintProgressSegment {
|
|
9
12
|
/** Active sprint index (1-based). */
|
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* src/
|
|
2
|
+
* src/state/status-bar-store.ts
|
|
3
3
|
*
|
|
4
4
|
* Status bar store: subscribable atom holding model/provider/tier/tokens/USD/degraded.
|
|
5
5
|
* wireStatusBar() connects to routerStore (Plan 03), subscribeThresholds (Plan 04),
|
|
6
6
|
* and subscribeDowngrade (Plan 05).
|
|
7
|
+
*
|
|
8
|
+
* Presentation-agnostic state — lives outside src/ui so the headless core
|
|
9
|
+
* (orchestrator/tool-engine/stream-runner) can read it without importing ui/.
|
|
7
10
|
*/
|
|
8
|
-
import { getCircuitState } from "
|
|
9
|
-
import { routerStore } from "
|
|
10
|
-
import { subscribeDowngrade } from "
|
|
11
|
-
import { subscribeThresholds } from "
|
|
12
|
-
import { activeRunStore } from "
|
|
11
|
+
import { getCircuitState } from "../ee/client.js";
|
|
12
|
+
import { routerStore } from "../router/store.js";
|
|
13
|
+
import { subscribeDowngrade } from "../usage/downgrade.js";
|
|
14
|
+
import { subscribeThresholds } from "../usage/thresholds.js";
|
|
15
|
+
import { activeRunStore } from "./active-run.js";
|
|
13
16
|
function makeStore() {
|
|
14
17
|
let state = {
|
|
15
18
|
provider: "",
|
|
@@ -141,8 +144,8 @@ export function wireStatusBar() {
|
|
|
141
144
|
}
|
|
142
145
|
try {
|
|
143
146
|
// Lazy import to avoid circular dependency at module load time.
|
|
144
|
-
const { readBacklog } = await import("
|
|
145
|
-
const { readSprintPlan } = await import("
|
|
147
|
+
const { readBacklog } = await import("../product-loop/backlog-store.js");
|
|
148
|
+
const { readSprintPlan } = await import("../product-loop/sprint-store.js");
|
|
146
149
|
const [backlog, sprintPlan] = await Promise.all([
|
|
147
150
|
readBacklog(run.flowDir, run.runId).catch(() => null),
|
|
148
151
|
readSprintPlan(run.flowDir, run.runId).catch(() => null),
|
|
@@ -276,4 +279,4 @@ export function __resetStatusBarStoreForTests() {
|
|
|
276
279
|
});
|
|
277
280
|
wired = false;
|
|
278
281
|
}
|
|
279
|
-
//# sourceMappingURL=store.js.map
|
|
282
|
+
//# sourceMappingURL=status-bar-store.js.map
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/state/turn-trace.ts
|
|
3
|
+
*
|
|
4
|
+
* Pipeline debug-trace state — the toggle flag + recorded per-turn traces.
|
|
5
|
+
*
|
|
6
|
+
* Presentation-agnostic: the headless core (tool-engine, message-processor)
|
|
7
|
+
* records traces here without importing src/ui. The /debug slash command
|
|
8
|
+
* (src/ui/slash/debug.ts) owns the human formatting and toggling on top of
|
|
9
|
+
* this state.
|
|
10
|
+
*/
|
|
11
|
+
export interface PipelineStep {
|
|
12
|
+
name: string;
|
|
13
|
+
duration_ms: number;
|
|
14
|
+
input_summary: string;
|
|
15
|
+
output_summary: string;
|
|
16
|
+
tokens_saved?: number;
|
|
17
|
+
}
|
|
18
|
+
export interface TurnTrace {
|
|
19
|
+
turn_id: number;
|
|
20
|
+
timestamp: number;
|
|
21
|
+
raw_prompt: string;
|
|
22
|
+
steps: PipelineStep[];
|
|
23
|
+
model_requested: string;
|
|
24
|
+
model_used: string;
|
|
25
|
+
routed: boolean;
|
|
26
|
+
input_tokens: number;
|
|
27
|
+
output_tokens: number;
|
|
28
|
+
cache_read_tokens: number;
|
|
29
|
+
cost_usd: number;
|
|
30
|
+
estimated_savings: SavingsEstimate;
|
|
31
|
+
}
|
|
32
|
+
export interface SavingsEstimate {
|
|
33
|
+
pil_tokens_saved: number;
|
|
34
|
+
cache_tokens_saved: number;
|
|
35
|
+
router_cost_saved_usd: number;
|
|
36
|
+
total_tokens_saved: number;
|
|
37
|
+
total_cost_saved_usd: number;
|
|
38
|
+
}
|
|
39
|
+
export declare function isDebugEnabled(): boolean;
|
|
40
|
+
export declare function setDebugEnabled(value: boolean): void;
|
|
41
|
+
export declare function recordTurnTrace(trace: TurnTrace): void;
|
|
42
|
+
export declare function getLastTrace(): TurnTrace | null;
|
|
43
|
+
export declare function getAllTraces(): readonly TurnTrace[];
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/state/turn-trace.ts
|
|
3
|
+
*
|
|
4
|
+
* Pipeline debug-trace state — the toggle flag + recorded per-turn traces.
|
|
5
|
+
*
|
|
6
|
+
* Presentation-agnostic: the headless core (tool-engine, message-processor)
|
|
7
|
+
* records traces here without importing src/ui. The /debug slash command
|
|
8
|
+
* (src/ui/slash/debug.ts) owns the human formatting and toggling on top of
|
|
9
|
+
* this state.
|
|
10
|
+
*/
|
|
11
|
+
let debugEnabled = false;
|
|
12
|
+
const turnTraces = [];
|
|
13
|
+
export function isDebugEnabled() {
|
|
14
|
+
return debugEnabled;
|
|
15
|
+
}
|
|
16
|
+
export function setDebugEnabled(value) {
|
|
17
|
+
debugEnabled = value;
|
|
18
|
+
}
|
|
19
|
+
export function recordTurnTrace(trace) {
|
|
20
|
+
if (!debugEnabled)
|
|
21
|
+
return;
|
|
22
|
+
turnTraces.push(trace);
|
|
23
|
+
if (turnTraces.length > 50)
|
|
24
|
+
turnTraces.shift();
|
|
25
|
+
}
|
|
26
|
+
export function getLastTrace() {
|
|
27
|
+
return turnTraces[turnTraces.length - 1] ?? null;
|
|
28
|
+
}
|
|
29
|
+
export function getAllTraces() {
|
|
30
|
+
return turnTraces;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=turn-trace.js.map
|
package/dist/src/storage/db.js
CHANGED
|
@@ -9,7 +9,8 @@ let db = null;
|
|
|
9
9
|
// async would be a much larger refactor.
|
|
10
10
|
const requireSync = createRequire(import.meta.url);
|
|
11
11
|
export function getDatabasePath() {
|
|
12
|
-
const
|
|
12
|
+
const home = process.env.HOME ?? process.env.USERPROFILE ?? os.homedir();
|
|
13
|
+
const dir = path.join(home, ".muonroi-cli");
|
|
13
14
|
fs.mkdirSync(dir, { recursive: true, mode: 0o700 });
|
|
14
15
|
return path.join(dir, "muonroi.db");
|
|
15
16
|
}
|
|
@@ -3,7 +3,7 @@ export { loadConfig, type MuonroiConfig } from "./config.js";
|
|
|
3
3
|
export { getDatabasePath } from "./db.js";
|
|
4
4
|
export { type InteractionEventType, logInteraction } from "./interaction-log.js";
|
|
5
5
|
export { SessionStore } from "./sessions.js";
|
|
6
|
-
export { appendCompaction, appendMessages, appendSystemMessage, buildChatEntries, getLastTodoWriteArgs, getNextMessageSequence, getSessionChain, loadLatestCompaction, loadRawTranscript, loadTranscript, loadTranscriptState, markMessageCompleted, markMessageErrored, markToolCallErrored, persistMessageWriteAhead, persistToolCallWriteAhead, revertLatestCompaction, } from "./transcript.js";
|
|
6
|
+
export { appendCompaction, appendMessages, appendSystemMessage, buildChatEntries, getLastApprovedPlan, getLastTodoWriteArgs, getNextMessageSequence, getSessionChain, getSessionChainInfos, loadLatestCompaction, loadRawTranscript, loadSessionChainTranscriptState, loadTranscript, loadTranscriptState, markMessageCompleted, markMessageErrored, markToolCallErrored, persistApprovedPlan, persistMessageWriteAhead, persistToolCallWriteAhead, revertLatestCompaction, type SessionChainNode, } from "./transcript.js";
|
|
7
7
|
export { buildEffectiveTranscript, type LoadedTranscriptState, type PersistedCompaction } from "./transcript-view.js";
|
|
8
8
|
export { logUIInteraction, type UIInteractionSubtype } from "./ui-interaction-log.js";
|
|
9
9
|
export { getSessionTotalTokens, listSessionUsage, recordUsageEvent, type TokenUsageLike } from "./usage.js";
|
|
@@ -4,7 +4,7 @@ export { loadConfig } from "./config.js";
|
|
|
4
4
|
export { getDatabasePath } from "./db.js";
|
|
5
5
|
export { logInteraction } from "./interaction-log.js";
|
|
6
6
|
export { SessionStore } from "./sessions.js";
|
|
7
|
-
export { appendCompaction, appendMessages, appendSystemMessage, buildChatEntries, getLastTodoWriteArgs, getNextMessageSequence, getSessionChain, loadLatestCompaction, loadRawTranscript, loadTranscript, loadTranscriptState, markMessageCompleted, markMessageErrored, markToolCallErrored, persistMessageWriteAhead, persistToolCallWriteAhead, revertLatestCompaction, } from "./transcript.js";
|
|
7
|
+
export { appendCompaction, appendMessages, appendSystemMessage, buildChatEntries, getLastApprovedPlan, getLastTodoWriteArgs, getNextMessageSequence, getSessionChain, getSessionChainInfos, loadLatestCompaction, loadRawTranscript, loadSessionChainTranscriptState, loadTranscript, loadTranscriptState, markMessageCompleted, markMessageErrored, markToolCallErrored, persistApprovedPlan, persistMessageWriteAhead, persistToolCallWriteAhead, revertLatestCompaction, } from "./transcript.js";
|
|
8
8
|
export { buildEffectiveTranscript } from "./transcript-view.js";
|
|
9
9
|
export { logUIInteraction } from "./ui-interaction-log.js";
|
|
10
10
|
export { getSessionTotalTokens, listSessionUsage, recordUsageEvent } from "./usage.js";
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Fire-and-forget interaction logging for detailed user-agent event tracking.
|
|
5
5
|
* All calls are fail-open — logging never breaks the main flow.
|
|
6
6
|
*/
|
|
7
|
-
export type InteractionEventType = "user_message" | "agent_response" | "tool_call" | "tool_result" | "compaction" | "routing" | "pil" | "error" | "model_switch" | "council" | "ee_intercept" | "ee_judge" | "ee_injection" | "ui_interaction" | "stream_retry" | "f6_synthesis" | "grounding_flag" | "stall_rescue" | "stream_start" | "text_tool_resteer" | "session_experience";
|
|
7
|
+
export type InteractionEventType = "user_message" | "agent_response" | "tool_call" | "tool_result" | "compaction" | "routing" | "pil" | "error" | "model_switch" | "council" | "ee_intercept" | "ee_judge" | "ee_injection" | "ui_interaction" | "stream_retry" | "f6_synthesis" | "grounding_flag" | "stall_rescue" | "stream_start" | "text_tool_resteer" | "turn_tool_load" | "session_experience";
|
|
8
8
|
export interface EEInjectionRow {
|
|
9
9
|
session_id: string;
|
|
10
10
|
event_subtype: string | null;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const LATEST_DB_VERSION =
|
|
1
|
+
const LATEST_DB_VERSION = 10;
|
|
2
2
|
export function applyMigrations(db) {
|
|
3
3
|
const version = Number(db.pragma("user_version", { simple: true })) || 0;
|
|
4
4
|
if (version >= LATEST_DB_VERSION)
|
|
@@ -96,9 +96,79 @@ export function applyMigrations(db) {
|
|
|
96
96
|
db.exec("CREATE INDEX IF NOT EXISTS idx_sessions_parent_id ON sessions(parent_session_id)");
|
|
97
97
|
db.pragma("user_version = 8");
|
|
98
98
|
}
|
|
99
|
+
if (version < 9) {
|
|
100
|
+
db.exec(`
|
|
101
|
+
CREATE VIRTUAL TABLE IF NOT EXISTS session_history_fts USING fts5(
|
|
102
|
+
session_id UNINDEXED,
|
|
103
|
+
seq UNINDEXED,
|
|
104
|
+
role UNINDEXED,
|
|
105
|
+
tool_name UNINDEXED,
|
|
106
|
+
content,
|
|
107
|
+
tool_args,
|
|
108
|
+
tool_output
|
|
109
|
+
);
|
|
110
|
+
|
|
111
|
+
CREATE TRIGGER IF NOT EXISTS t_sessions_delete_fts
|
|
112
|
+
AFTER DELETE ON sessions
|
|
113
|
+
BEGIN
|
|
114
|
+
DELETE FROM session_history_fts WHERE session_id = old.id;
|
|
115
|
+
END;
|
|
116
|
+
`);
|
|
117
|
+
db.pragma("user_version = 9");
|
|
118
|
+
}
|
|
119
|
+
if (version < 10) {
|
|
120
|
+
// Thread-aware resume. The resume picker groups sessions by conversation
|
|
121
|
+
// tree; `kind` distinguishes the two kinds of child (both previously only
|
|
122
|
+
// set parent_session_id, indistinguishable) and `root_session_id`
|
|
123
|
+
// denormalizes the tree root so the picker groups without a recursive CTE.
|
|
124
|
+
const cols = db.prepare("PRAGMA table_info(sessions)").all();
|
|
125
|
+
const colNames = new Set(cols.map((c) => c.name));
|
|
126
|
+
if (!colNames.has("kind")) {
|
|
127
|
+
db.exec("ALTER TABLE sessions ADD COLUMN kind TEXT NOT NULL DEFAULT 'conversation'");
|
|
128
|
+
}
|
|
129
|
+
if (!colNames.has("root_session_id")) {
|
|
130
|
+
db.exec("ALTER TABLE sessions ADD COLUMN root_session_id TEXT");
|
|
131
|
+
}
|
|
132
|
+
db.exec("CREATE INDEX IF NOT EXISTS idx_sessions_root ON sessions(workspace_id, root_session_id)");
|
|
133
|
+
backfillSessionTrees(db);
|
|
134
|
+
db.pragma("user_version = 10");
|
|
135
|
+
}
|
|
99
136
|
});
|
|
100
137
|
migrate();
|
|
101
138
|
}
|
|
139
|
+
/**
|
|
140
|
+
* Backfill kind + root_session_id for pre-v10 rows.
|
|
141
|
+
*
|
|
142
|
+
* - Rows with no parent become their own root (kind 'conversation').
|
|
143
|
+
* - Rows WITH a parent are marked 'rotation' — historical data cannot tell
|
|
144
|
+
* rotation apart from sub-agent spawns, and marking them 'rotation' collapses
|
|
145
|
+
* them under their root rather than risking hiding a real conversation.
|
|
146
|
+
* - root_session_id propagates down the parent chain via a bounded fixpoint
|
|
147
|
+
* loop (chains are shallow; the bound also guards against FK cycles).
|
|
148
|
+
*/
|
|
149
|
+
function backfillSessionTrees(db) {
|
|
150
|
+
// Roots: own id, keep default kind 'conversation'.
|
|
151
|
+
db.exec("UPDATE sessions SET root_session_id = id WHERE parent_session_id IS NULL AND root_session_id IS NULL");
|
|
152
|
+
// Children of a real parent → rotation (default kind was 'conversation').
|
|
153
|
+
db.exec("UPDATE sessions SET kind = 'rotation' WHERE parent_session_id IS NOT NULL");
|
|
154
|
+
// Propagate root down the chain until no row changes (bounded to 100 passes).
|
|
155
|
+
for (let i = 0; i < 100; i++) {
|
|
156
|
+
db.exec(`
|
|
157
|
+
UPDATE sessions
|
|
158
|
+
SET root_session_id = (SELECT p.root_session_id FROM sessions p WHERE p.id = sessions.parent_session_id)
|
|
159
|
+
WHERE root_session_id IS NULL
|
|
160
|
+
AND parent_session_id IS NOT NULL
|
|
161
|
+
AND (SELECT p.root_session_id FROM sessions p WHERE p.id = sessions.parent_session_id) IS NOT NULL
|
|
162
|
+
`);
|
|
163
|
+
const remaining = db
|
|
164
|
+
.prepare("SELECT COUNT(*) AS c FROM sessions WHERE root_session_id IS NULL AND parent_session_id IS NOT NULL")
|
|
165
|
+
.get();
|
|
166
|
+
if (!remaining || remaining.c === 0)
|
|
167
|
+
break;
|
|
168
|
+
}
|
|
169
|
+
// Any leftover (orphaned/cyclic parent chains) → treat as its own root.
|
|
170
|
+
db.exec("UPDATE sessions SET root_session_id = id WHERE root_session_id IS NULL");
|
|
171
|
+
}
|
|
102
172
|
function createInitialSchema(db) {
|
|
103
173
|
db.exec(`
|
|
104
174
|
CREATE TABLE IF NOT EXISTS workspaces (
|