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
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as fs from "fs";
|
|
2
2
|
import * as os from "os";
|
|
3
3
|
import * as path from "path";
|
|
4
|
-
import { getEffectiveReasoningEffort, getFirstCatalogModel, getFirstCatalogProvider, getModelByTier, getModelIds, getModelInfo, MODELS, normalizeModelId, } from "../models/registry.js";
|
|
4
|
+
import { getCatalogCouncilRouting, getEffectiveReasoningEffort, getFirstCatalogModel, getFirstCatalogProvider, getModelByTier, getModelIds, getModelInfo, MODELS, normalizeModelId, } from "../models/registry.js";
|
|
5
5
|
import { apiBaseFor, PROVIDER_ENDPOINTS } from "../providers/endpoints.js";
|
|
6
6
|
import { ALL_PROVIDER_IDS } from "../providers/types.js";
|
|
7
7
|
import { logger } from "./logger.js";
|
|
@@ -72,8 +72,9 @@ export function parseSubAgentsRawList(raw) {
|
|
|
72
72
|
export function loadValidSubAgents() {
|
|
73
73
|
return parseSubAgentsRawList(loadUserSettings().subAgents);
|
|
74
74
|
}
|
|
75
|
-
|
|
76
|
-
|
|
75
|
+
function getUserSettingsPath() {
|
|
76
|
+
return path.join(os.homedir(), ".muonroi-cli", "user-settings.json");
|
|
77
|
+
}
|
|
77
78
|
function ensureDir(dir) {
|
|
78
79
|
if (!fs.existsSync(dir)) {
|
|
79
80
|
fs.mkdirSync(dir, { recursive: true, mode: 0o700 });
|
|
@@ -179,7 +180,7 @@ export function ensureFootprintGitignored(cwd = process.cwd()) {
|
|
|
179
180
|
}
|
|
180
181
|
}
|
|
181
182
|
export function loadUserSettings() {
|
|
182
|
-
return readJson(
|
|
183
|
+
return readJson(getUserSettingsPath()) || {};
|
|
183
184
|
}
|
|
184
185
|
export function saveUserSettings(partial) {
|
|
185
186
|
const current = loadUserSettings();
|
|
@@ -248,7 +249,7 @@ export function saveUserSettings(partial) {
|
|
|
248
249
|
}
|
|
249
250
|
: {}),
|
|
250
251
|
};
|
|
251
|
-
writeJson(
|
|
252
|
+
writeJson(getUserSettingsPath(), next);
|
|
252
253
|
}
|
|
253
254
|
export function loadProjectSettings() {
|
|
254
255
|
const projectPath = path.join(process.cwd(), ".muonroi-cli", "settings.json");
|
|
@@ -274,10 +275,12 @@ export function saveProjectSettings(partial) {
|
|
|
274
275
|
}
|
|
275
276
|
export function getApiKey() {
|
|
276
277
|
// Test escape hatch (api-key harness spec): suppress all key sources so the
|
|
277
|
-
// boot flow reaches the
|
|
278
|
+
// boot flow reaches the provider picker. See src/index.ts resolveKeyForModel.
|
|
278
279
|
if (process.env.MUONROI_TEST_NO_KEYCHAIN === "1")
|
|
279
280
|
return undefined;
|
|
280
|
-
|
|
281
|
+
// Env-only: the legacy plaintext `settings.apiKey` is migrated to the
|
|
282
|
+
// env-store on first run (migrateLegacyKeysToEnv) and no longer read here.
|
|
283
|
+
return process.env.MUONROI_API_KEY || undefined;
|
|
281
284
|
}
|
|
282
285
|
export function getBaseURL(provider) {
|
|
283
286
|
if (process.env.MUONROI_BASE_URL)
|
|
@@ -310,11 +313,6 @@ export function getProviderConfigs(mainApiKey) {
|
|
|
310
313
|
if (openaiKey) {
|
|
311
314
|
configs.openai = { apiKey: openaiKey, baseURL: p.openai?.baseURL };
|
|
312
315
|
}
|
|
313
|
-
// Google Gemini
|
|
314
|
-
const googleKey = process.env.GOOGLE_API_KEY ?? p.google?.apiKey;
|
|
315
|
-
if (googleKey) {
|
|
316
|
-
configs.google = { apiKey: googleKey, baseURL: p.google?.baseURL };
|
|
317
|
-
}
|
|
318
316
|
// DeepSeek
|
|
319
317
|
const deepseekKey = process.env.DEEPSEEK_API_KEY ?? p.deepseek?.apiKey;
|
|
320
318
|
if (deepseekKey) {
|
|
@@ -323,14 +321,6 @@ export function getProviderConfigs(mainApiKey) {
|
|
|
323
321
|
baseURL: p.deepseek?.baseURL ?? apiBaseFor("deepseek"),
|
|
324
322
|
};
|
|
325
323
|
}
|
|
326
|
-
// SiliconFlow
|
|
327
|
-
const siliconflowKey = process.env.SILICONFLOW_API_KEY ?? p.siliconflow?.apiKey;
|
|
328
|
-
if (siliconflowKey) {
|
|
329
|
-
configs.siliconflow = {
|
|
330
|
-
apiKey: siliconflowKey,
|
|
331
|
-
baseURL: p.siliconflow?.baseURL ?? apiBaseFor("siliconflow"),
|
|
332
|
-
};
|
|
333
|
-
}
|
|
334
324
|
// xAI / Grok (OpenAI-compatible)
|
|
335
325
|
const xaiKey = process.env.XAI_API_KEY ?? p.xai?.apiKey;
|
|
336
326
|
if (xaiKey) {
|
|
@@ -339,6 +329,22 @@ export function getProviderConfigs(mainApiKey) {
|
|
|
339
329
|
baseURL: p.xai?.baseURL ?? apiBaseFor("xai"),
|
|
340
330
|
};
|
|
341
331
|
}
|
|
332
|
+
// Z.ai (OpenAI-compatible)
|
|
333
|
+
const zaiKey = process.env.ZAI_API_KEY ?? p.zai?.apiKey;
|
|
334
|
+
if (zaiKey) {
|
|
335
|
+
configs.zai = {
|
|
336
|
+
apiKey: zaiKey,
|
|
337
|
+
baseURL: p.zai?.baseURL ?? apiBaseFor("zai"),
|
|
338
|
+
};
|
|
339
|
+
}
|
|
340
|
+
// OpenCode Go (OpenAI-compatible)
|
|
341
|
+
const opencodeGoKey = process.env.OPENCODE_GO_API_KEY ?? p["opencode-go"]?.apiKey;
|
|
342
|
+
if (opencodeGoKey) {
|
|
343
|
+
configs["opencode-go"] = {
|
|
344
|
+
apiKey: opencodeGoKey,
|
|
345
|
+
baseURL: p["opencode-go"]?.baseURL ?? apiBaseFor("opencode-go"),
|
|
346
|
+
};
|
|
347
|
+
}
|
|
342
348
|
// Ollama — no key needed, just baseURL
|
|
343
349
|
const ollamaURL = process.env.OLLAMA_URL ?? p.ollama?.baseURL ?? "http://localhost:11434";
|
|
344
350
|
configs.ollama = { baseURL: ollamaURL };
|
|
@@ -591,6 +597,12 @@ export function getAutoCompactThresholdPct() {
|
|
|
591
597
|
return val;
|
|
592
598
|
return 0.4; // default 40% — Reduced from 25% after session bf58d0f46b51 analysis: 13 compacts in 43min generated 1.3M uncached tokens. Higher threshold = fewer compacts = less compaction overhead. For DeepSeek 128K context: fires at 51K instead of 32K.
|
|
593
599
|
}
|
|
600
|
+
export function getAutoCompactMinNewTokens() {
|
|
601
|
+
const val = loadUserSettings().autoCompactMinNewTokens;
|
|
602
|
+
if (typeof val === "number" && val >= 0 && val <= 200_000)
|
|
603
|
+
return val;
|
|
604
|
+
return 20_000; // Observed thrash: re-compact after ~14K new tokens (session ff932f8568e8).
|
|
605
|
+
}
|
|
594
606
|
/**
|
|
595
607
|
* Per-invocation cap on cumulative tool-output chars inside a `task`
|
|
596
608
|
* sub-agent. See orchestrator/sub-agent-cap.ts for the tiered compression
|
|
@@ -627,6 +639,65 @@ export function getProviderStallTimeoutMs() {
|
|
|
627
639
|
}
|
|
628
640
|
return 120_000;
|
|
629
641
|
}
|
|
642
|
+
/**
|
|
643
|
+
* No-forward-progress watchdog timeout (ms) for streaming model calls. Distinct
|
|
644
|
+
* from the stall watchdog: the stall watchdog re-arms on ANY stream chunk —
|
|
645
|
+
* including a reasoning model's `reasoning-delta` chunks — so a model stuck in an
|
|
646
|
+
* endless chain-of-thought keeps petting it and it NEVER fires (observed live
|
|
647
|
+
* 2026-07-10: a deepseek-v4-flash sub-agent churned reasoning for 30+ min, 1.4M
|
|
648
|
+
* input tokens, ZERO text/tool output, and the 2-min stall watchdog never tripped
|
|
649
|
+
* because reasoning chunks kept arriving). This second watchdog is petted ONLY on
|
|
650
|
+
* REAL forward progress (a text-delta or a tool-call), so a runaway-reasoning /
|
|
651
|
+
* no-output loop is aborted while a legitimately long reasoning burst that DOES
|
|
652
|
+
* eventually emit text/tools survives. Set generously above a normal reasoning
|
|
653
|
+
* burst. Range 30_000–1_800_000; 0 disables. Default 300_000 (5 min). Env
|
|
654
|
+
* override: MUONROI_PROVIDER_PROGRESS_TIMEOUT_MS.
|
|
655
|
+
*/
|
|
656
|
+
export function getProviderProgressTimeoutMs() {
|
|
657
|
+
const envRaw = process.env.MUONROI_PROVIDER_PROGRESS_TIMEOUT_MS;
|
|
658
|
+
if (envRaw !== undefined && envRaw !== "") {
|
|
659
|
+
const n = Number(envRaw);
|
|
660
|
+
if (Number.isFinite(n) && n === 0)
|
|
661
|
+
return 0; // explicit disable
|
|
662
|
+
if (Number.isFinite(n) && n >= 30_000 && n <= 1_800_000)
|
|
663
|
+
return Math.floor(n);
|
|
664
|
+
}
|
|
665
|
+
return 300_000;
|
|
666
|
+
}
|
|
667
|
+
/**
|
|
668
|
+
* Event-loop block reporting threshold (ms). The monitor
|
|
669
|
+
* (`src/utils/event-loop-monitor.ts`) reports a block when its own tick runs at
|
|
670
|
+
* least this late — evidence that the JS thread was stuck and NO timer could
|
|
671
|
+
* fire, which is why the provider stall watchdogs above cannot see this class
|
|
672
|
+
* of freeze (measured live 2026-07-16: a 304.5s TUI freeze that the 120s stall
|
|
673
|
+
* watchdog only rescued 6.7s AFTER the loop recovered).
|
|
674
|
+
*
|
|
675
|
+
* 2s is well clear of ordinary GC pauses and heavy renders while still catching
|
|
676
|
+
* anything a user would call a freeze. Range 250–60_000; 0 disables.
|
|
677
|
+
* Default 2_000. Env override: MUONROI_LOOP_BLOCK_THRESHOLD_MS.
|
|
678
|
+
*/
|
|
679
|
+
export function getLoopBlockThresholdMs() {
|
|
680
|
+
const envRaw = process.env.MUONROI_LOOP_BLOCK_THRESHOLD_MS;
|
|
681
|
+
if (envRaw !== undefined && envRaw !== "") {
|
|
682
|
+
const n = Number(envRaw);
|
|
683
|
+
if (Number.isFinite(n) && n === 0)
|
|
684
|
+
return 0; // explicit disable
|
|
685
|
+
if (Number.isFinite(n) && n >= 250 && n <= 60_000)
|
|
686
|
+
return Math.floor(n);
|
|
687
|
+
}
|
|
688
|
+
return 2_000;
|
|
689
|
+
}
|
|
690
|
+
/**
|
|
691
|
+
* Whether to run the rolling CPU profiler (`src/utils/loop-profiler.ts`) so a
|
|
692
|
+
* reported event-loop block comes with the culprit's stack rather than just a
|
|
693
|
+
* duration. OFF by default: continuous V8 sampling costs a little on every
|
|
694
|
+
* session, and this is a diagnostic for a sporadic bug, not a feature. Arm it
|
|
695
|
+
* when hunting a freeze. Env: MUONROI_LOOP_PROFILE=1 (0/unset disables).
|
|
696
|
+
*/
|
|
697
|
+
export function isLoopProfileEnabled() {
|
|
698
|
+
const raw = process.env.MUONROI_LOOP_PROFILE?.trim().toLowerCase();
|
|
699
|
+
return raw === "1" || raw === "true" || raw === "yes" || raw === "on";
|
|
700
|
+
}
|
|
630
701
|
/**
|
|
631
702
|
* Number of times to AUTOMATICALLY re-issue a streaming model call after the
|
|
632
703
|
* stall watchdog fires WITHOUT any chunk having arrived (a time-to-first-byte
|
|
@@ -702,17 +773,50 @@ export function getSubAgentCompactKeepLast() {
|
|
|
702
773
|
* top-level loops typically carry more useful early context.
|
|
703
774
|
* Env override: MUONROI_TOP_LEVEL_COMPACT_THRESHOLD_CHARS.
|
|
704
775
|
*/
|
|
705
|
-
export function getTopLevelCompactThresholdChars() {
|
|
776
|
+
export function getTopLevelCompactThresholdChars(contextWindowTokens) {
|
|
706
777
|
const envRaw = process.env.MUONROI_TOP_LEVEL_COMPACT_THRESHOLD_CHARS;
|
|
707
778
|
if (envRaw) {
|
|
708
779
|
const n = Number(envRaw);
|
|
709
|
-
if (Number.isFinite(n) && n >=
|
|
780
|
+
if (Number.isFinite(n) && n >= 10_000 && n <= 1_500_000)
|
|
710
781
|
return Math.floor(n);
|
|
711
782
|
}
|
|
712
|
-
//
|
|
713
|
-
//
|
|
714
|
-
//
|
|
715
|
-
|
|
783
|
+
// For small-context models (e.g. DeepSeek 64K), scale threshold proportionally
|
|
784
|
+
// to prevent linear token growth during tool loops. A model with 64K context
|
|
785
|
+
// gets threshold = 64000 * 4 * 0.35 = 89,600 chars (~22K tokens = 35% of window).
|
|
786
|
+
// Large-context models (128K+) keep the original 200K default.
|
|
787
|
+
if (contextWindowTokens && contextWindowTokens > 0) {
|
|
788
|
+
const dynamicThreshold = Math.floor(contextWindowTokens * 4 * 0.35);
|
|
789
|
+
return Math.min(200_000, dynamicThreshold);
|
|
790
|
+
}
|
|
791
|
+
return 200_000;
|
|
792
|
+
}
|
|
793
|
+
/**
|
|
794
|
+
* Compaction hysteresis factor for the top-level loop. Once B4 compaction has
|
|
795
|
+
* fired within a turn, the compacted prefix is FROZEN and only new messages are
|
|
796
|
+
* appended (keeping the provider prompt-cache prefix byte-stable) until the
|
|
797
|
+
* cumulative size grows past `lastTriggerChars * factor` — then it re-compacts.
|
|
798
|
+
*
|
|
799
|
+
* Why: measured on session 1afb2728e67a — a 24-step turn re-ran compaction every
|
|
800
|
+
* step, and each step's sliding keepLast boundary flipped one more tool result
|
|
801
|
+
* verbatim→stub, breaking the cache prefix at that position. 63% of that
|
|
802
|
+
* session's FRESH input came from 5 such compaction-induced cache breaks.
|
|
803
|
+
* Holding the boundary between compactions trades a higher peak input for far
|
|
804
|
+
* fewer cache-break re-bills.
|
|
805
|
+
*
|
|
806
|
+
* Range 1.0–3.0. Default 1.15 (re-compact at +15% growth). `1.0` or env `0`
|
|
807
|
+
* disables hysteresis → legacy per-step compaction.
|
|
808
|
+
* Env override: MUONROI_COMPACT_HYSTERESIS.
|
|
809
|
+
*/
|
|
810
|
+
export function getTopLevelCompactHysteresis() {
|
|
811
|
+
const envRaw = process.env.MUONROI_COMPACT_HYSTERESIS;
|
|
812
|
+
if (envRaw !== undefined && envRaw.trim() !== "") {
|
|
813
|
+
const n = Number(envRaw);
|
|
814
|
+
if (Number.isFinite(n) && n === 0)
|
|
815
|
+
return 1.0; // explicit disable
|
|
816
|
+
if (Number.isFinite(n) && n >= 1.0 && n <= 3.0)
|
|
817
|
+
return n;
|
|
818
|
+
}
|
|
819
|
+
return 1.15;
|
|
716
820
|
}
|
|
717
821
|
/**
|
|
718
822
|
* Phase B4 — number of trailing tool turns kept verbatim during top-level
|
|
@@ -720,22 +824,59 @@ export function getTopLevelCompactThresholdChars() {
|
|
|
720
824
|
* decisions across longer horizons.
|
|
721
825
|
* Env override: MUONROI_TOP_LEVEL_COMPACT_KEEP_LAST.
|
|
722
826
|
*/
|
|
723
|
-
export function getTopLevelCompactKeepLast() {
|
|
827
|
+
export function getTopLevelCompactKeepLast(contextWindowTokens) {
|
|
724
828
|
const envRaw = process.env.MUONROI_TOP_LEVEL_COMPACT_KEEP_LAST;
|
|
725
829
|
if (envRaw) {
|
|
726
830
|
const n = Number(envRaw);
|
|
727
831
|
if (Number.isFinite(n) && n >= 1 && n <= 30)
|
|
728
832
|
return Math.floor(n);
|
|
729
833
|
}
|
|
834
|
+
// Small-context models (< 100K tokens) benefit from keeping fewer trailing
|
|
835
|
+
// turns — each verbatim turn with tool results + reasoning tokens costs
|
|
836
|
+
// 5-15K tokens. Reduce from 5 to 3 for small windows.
|
|
837
|
+
if (contextWindowTokens && contextWindowTokens < 100_000) {
|
|
838
|
+
return 3;
|
|
839
|
+
}
|
|
730
840
|
return 5;
|
|
731
841
|
}
|
|
842
|
+
/**
|
|
843
|
+
* O2 — byte budget for the verbatim tail (last keepLast turns) in top-level B4
|
|
844
|
+
* compaction. The keepLast shrink is otherwise fill-ratio based, so on a
|
|
845
|
+
* large-context model a read-heavy tail stays verbatim at ~50% fill, pinning
|
|
846
|
+
* each tool round at 60-80K input (measured on July-8 sessions). This caps the
|
|
847
|
+
* tail's actual chars, shrinking keepLast further (floor 2) when the kept tool
|
|
848
|
+
* results are large. 0 disables. Env: MUONROI_TOP_LEVEL_COMPACT_TAIL_BUDGET_CHARS.
|
|
849
|
+
*/
|
|
850
|
+
export function getTopLevelCompactTailBudgetChars(contextWindowTokens) {
|
|
851
|
+
const envRaw = process.env.MUONROI_TOP_LEVEL_COMPACT_TAIL_BUDGET_CHARS;
|
|
852
|
+
if (envRaw !== undefined && envRaw.trim() !== "") {
|
|
853
|
+
const n = Number(envRaw);
|
|
854
|
+
// 0 = explicit disable; otherwise clamp to a sane floor so a fat-fingered
|
|
855
|
+
// tiny value can't stub away all recent context.
|
|
856
|
+
if (Number.isFinite(n) && n === 0)
|
|
857
|
+
return 0;
|
|
858
|
+
if (Number.isFinite(n) && n >= 20_000 && n <= 1_000_000)
|
|
859
|
+
return Math.floor(n);
|
|
860
|
+
}
|
|
861
|
+
// Default 50K chars (~12.5K tokens). Chosen from a deterministic measurement:
|
|
862
|
+
// on a realistic read-heavy turn the keepLast=5 verbatim tail is ~70-100K
|
|
863
|
+
// chars, so a looser budget (e.g. 120K) never bites (no-op). 50K shrinks the
|
|
864
|
+
// effective tail to ~3 turns on heavy turns (matching the sub-agent keepLast
|
|
865
|
+
// default) — ~7K tokens/call saved — while high-value results stay verbatim
|
|
866
|
+
// and light turns (below the 200K compaction threshold) are untouched. For
|
|
867
|
+
// small windows, scale to ~20% of the window so the tail can't dominate.
|
|
868
|
+
if (contextWindowTokens && contextWindowTokens > 0) {
|
|
869
|
+
return Math.min(50_000, Math.floor(contextWindowTokens * 4 * 0.2));
|
|
870
|
+
}
|
|
871
|
+
return 50_000;
|
|
872
|
+
}
|
|
732
873
|
/**
|
|
733
874
|
* Per-turn cap on cumulative tool-output chars inside the top-level
|
|
734
875
|
* orchestrator agentic loop. Same tiered compression as the sub-agent cap,
|
|
735
876
|
* higher default so single-tool turns are unaffected. Env override:
|
|
736
877
|
* MUONROI_TOP_LEVEL_TOOL_BUDGET_CHARS.
|
|
737
878
|
*/
|
|
738
|
-
export function getTopLevelToolBudgetChars(maxRounds) {
|
|
879
|
+
export function getTopLevelToolBudgetChars(maxRounds, contextWindowTokens) {
|
|
739
880
|
const envRaw = process.env.MUONROI_TOP_LEVEL_TOOL_BUDGET_CHARS;
|
|
740
881
|
if (envRaw) {
|
|
741
882
|
const n = Number(envRaw);
|
|
@@ -748,10 +889,35 @@ export function getTopLevelToolBudgetChars(maxRounds) {
|
|
|
748
889
|
// Dynamically scale default based on maxRounds relative to default base (40)
|
|
749
890
|
const baseRounds = 40;
|
|
750
891
|
const scale = maxRounds && maxRounds > baseRounds ? maxRounds / baseRounds : 1;
|
|
751
|
-
|
|
892
|
+
const baseDefault = Math.floor(400_000 * scale);
|
|
893
|
+
// For small-context models (e.g. DeepSeek 64K), scale the budget to 60% of
|
|
894
|
+
// the context window in chars so tiered compression kicks in before the
|
|
895
|
+
// cumulative tool output exceeds what the model can hold in context.
|
|
896
|
+
if (contextWindowTokens && contextWindowTokens > 0 && contextWindowTokens < 200_000) {
|
|
897
|
+
const windowBudget = Math.floor(contextWindowTokens * 4 * 0.6);
|
|
898
|
+
return Math.min(baseDefault, Math.max(50_000, windowBudget));
|
|
899
|
+
}
|
|
900
|
+
return baseDefault;
|
|
752
901
|
}
|
|
753
902
|
export function getRoleModel(role) {
|
|
754
|
-
|
|
903
|
+
const configured = loadUserSettings().roleModels?.[role];
|
|
904
|
+
if (!configured)
|
|
905
|
+
return undefined;
|
|
906
|
+
// Graceful staleness guard (mirrors getCurrentModel's pickValid): a role model
|
|
907
|
+
// persisted before a catalog rename/drop (e.g. "grok-build-0.1" after it was
|
|
908
|
+
// dropped in favor of grok-composer-2.5-fast) must NOT leak a dead id to the
|
|
909
|
+
// runtime, where resolveModelRuntime throws "not found in catalog — cannot
|
|
910
|
+
// determine provider" and takes down the whole council speaker (observed:
|
|
911
|
+
// Experience Auditor on the research role). If the catalog hasn't loaded yet,
|
|
912
|
+
// trust the normalized id; otherwise drop unresolved ids so the caller falls
|
|
913
|
+
// back to its own default instead of crashing.
|
|
914
|
+
const normalized = normalizeModelId(configured);
|
|
915
|
+
if (MODELS.length === 0)
|
|
916
|
+
return normalized;
|
|
917
|
+
if (getModelInfo(normalized))
|
|
918
|
+
return normalized;
|
|
919
|
+
logger.warn("cli", `roleModels.${role} = "${configured}" is not in the catalog (renamed or removed); ignoring so the caller falls back to its default. Update it via /config.`);
|
|
920
|
+
return undefined;
|
|
755
921
|
}
|
|
756
922
|
export function getRoleModels() {
|
|
757
923
|
return loadUserSettings().roleModels ?? {};
|
|
@@ -778,18 +944,92 @@ export function normalizeAutoCouncilMinRoles(val) {
|
|
|
778
944
|
export function getAutoCouncilConfidence() {
|
|
779
945
|
return normalizeAutoCouncilConfidence(loadUserSettings().autoCouncilConfidence);
|
|
780
946
|
}
|
|
947
|
+
/**
|
|
948
|
+
* Whether the auto-council path runs the pre-debate clarification interview
|
|
949
|
+
* (model-designed askcards) before debating. Default true so a broadly-scoped
|
|
950
|
+
* "debate mode" request is clarified first. Env override wins over the user
|
|
951
|
+
* setting for quick dev toggling; env "0"/"false" disables, "1"/"true" enables.
|
|
952
|
+
*/
|
|
953
|
+
export function isAutoCouncilClarifyEnabled() {
|
|
954
|
+
const env = process.env.MUONROI_AUTOCOUNCIL_CLARIFY?.trim().toLowerCase();
|
|
955
|
+
if (env === "0" || env === "false")
|
|
956
|
+
return false;
|
|
957
|
+
if (env === "1" || env === "true")
|
|
958
|
+
return true;
|
|
959
|
+
return loadUserSettings().autoCouncilClarify ?? true;
|
|
960
|
+
}
|
|
961
|
+
/**
|
|
962
|
+
* Whether auto-council should be skipped when the session model is a reasoning
|
|
963
|
+
* model. Default true. Env override wins over the user setting for quick dev
|
|
964
|
+
* toggling; env "0"/"false" disables the skip (forces council), "1"/"true"
|
|
965
|
+
* enables the skip.
|
|
966
|
+
*/
|
|
967
|
+
export function isAutoCouncilSkipReasoning() {
|
|
968
|
+
const env = process.env.MUONROI_AUTOCOUNCIL_SKIP_REASONING?.trim().toLowerCase();
|
|
969
|
+
if (env === "0" || env === "false")
|
|
970
|
+
return false;
|
|
971
|
+
if (env === "1" || env === "true")
|
|
972
|
+
return true;
|
|
973
|
+
return loadUserSettings().autoCouncilSkipReasoning ?? true;
|
|
974
|
+
}
|
|
781
975
|
export function getAutoCouncilMinRoles() {
|
|
782
976
|
return normalizeAutoCouncilMinRoles(loadUserSettings().autoCouncilMinRoles);
|
|
783
977
|
}
|
|
784
978
|
export function isCouncilMultiProviderPreferred() {
|
|
785
|
-
|
|
979
|
+
const user = loadUserSettings().councilPreferMultiProvider;
|
|
980
|
+
if (user !== undefined)
|
|
981
|
+
return user;
|
|
982
|
+
return getCatalogCouncilRouting()?.prefer_multi_provider ?? true;
|
|
786
983
|
}
|
|
787
984
|
export function getCouncilExperienceMode() {
|
|
788
985
|
return loadUserSettings().councilExperienceMode ?? "advisory";
|
|
789
986
|
}
|
|
987
|
+
export function normalizePeakHourPolicy(raw) {
|
|
988
|
+
if (!raw || typeof raw !== "object") {
|
|
989
|
+
return { enabled: true, mode: "switch" };
|
|
990
|
+
}
|
|
991
|
+
const p = raw;
|
|
992
|
+
return {
|
|
993
|
+
enabled: p.enabled !== false,
|
|
994
|
+
mode: p.mode === "downgrade" ? "downgrade" : "switch",
|
|
995
|
+
};
|
|
996
|
+
}
|
|
997
|
+
export function getPeakHourPolicy() {
|
|
998
|
+
return normalizePeakHourPolicy(loadUserSettings().peakHourPolicy);
|
|
999
|
+
}
|
|
790
1000
|
export function isCouncilCostAware() {
|
|
791
1001
|
return loadUserSettings().councilCostAware ?? true;
|
|
792
1002
|
}
|
|
1003
|
+
/**
|
|
1004
|
+
* Normalize a raw councilLanguage value (Feature B). Trims + lowercases the two
|
|
1005
|
+
* reserved modes ("auto", "english"); any other non-empty string is preserved
|
|
1006
|
+
* as-is (trimmed) so locale labels keep the user's exact casing (e.g. "日本語").
|
|
1007
|
+
* Empty / non-string → "auto".
|
|
1008
|
+
*/
|
|
1009
|
+
export function normalizeCouncilLanguage(raw) {
|
|
1010
|
+
if (typeof raw !== "string")
|
|
1011
|
+
return "auto";
|
|
1012
|
+
const trimmed = raw.trim();
|
|
1013
|
+
if (trimmed.length === 0)
|
|
1014
|
+
return "auto";
|
|
1015
|
+
const lower = trimmed.toLowerCase();
|
|
1016
|
+
if (lower === "auto" || lower === "english")
|
|
1017
|
+
return lower;
|
|
1018
|
+
return trimmed;
|
|
1019
|
+
}
|
|
1020
|
+
export function getCouncilLanguage() {
|
|
1021
|
+
return normalizeCouncilLanguage(loadUserSettings().councilLanguage);
|
|
1022
|
+
}
|
|
1023
|
+
/**
|
|
1024
|
+
* Router tier-promotion ceiling. See UserSettings.routingPromoteMax.
|
|
1025
|
+
* Default "balanced" — router may promote up to balanced but never silently
|
|
1026
|
+
* to premium. Validated to the three allowed values; any unknown value
|
|
1027
|
+
* falls back to the default.
|
|
1028
|
+
*/
|
|
1029
|
+
export function getRoutingPromoteMax() {
|
|
1030
|
+
const raw = loadUserSettings().routingPromoteMax;
|
|
1031
|
+
return raw === "off" || raw === "balanced" || raw === "any" ? raw : "balanced";
|
|
1032
|
+
}
|
|
793
1033
|
export function getDisabledProviders() {
|
|
794
1034
|
const raw = loadUserSettings().disabledProviders;
|
|
795
1035
|
if (!Array.isArray(raw))
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type { ProviderFactory as LegacyProvider } from "../providers/runtime.js";
|
|
2
1
|
export interface SideQuestionResult {
|
|
3
2
|
response: string;
|
|
4
3
|
usage?: {
|
|
@@ -7,4 +6,4 @@ export interface SideQuestionResult {
|
|
|
7
6
|
outputTokens?: number;
|
|
8
7
|
};
|
|
9
8
|
}
|
|
10
|
-
export declare function runSideQuestion(question: string,
|
|
9
|
+
export declare function runSideQuestion(question: string, modelId: string, conversationContext: string, signal?: AbortSignal): Promise<SideQuestionResult>;
|
|
@@ -3,8 +3,8 @@ import { resolveModelRuntime } from "../providers/runtime.js";
|
|
|
3
3
|
const SIDE_QUESTION_SYSTEM = `You are a helpful coding assistant answering a quick side question. The user is in the middle of a coding session and needs a fast, concise answer. Keep your response short and focused — this is a side question, not the main task.
|
|
4
4
|
|
|
5
5
|
If conversation context is provided below, use it to give a more relevant answer.`;
|
|
6
|
-
export async function runSideQuestion(question,
|
|
7
|
-
const runtime = resolveModelRuntime(
|
|
6
|
+
export async function runSideQuestion(question, modelId, conversationContext, signal) {
|
|
7
|
+
const runtime = resolveModelRuntime(modelId);
|
|
8
8
|
const system = conversationContext
|
|
9
9
|
? `${SIDE_QUESTION_SYSTEM}\n\n<conversation_context>\n${conversationContext}\n</conversation_context>`
|
|
10
10
|
: SIDE_QUESTION_SYSTEM;
|
|
@@ -17,4 +17,15 @@ export interface VisibleRetryOpts {
|
|
|
17
17
|
/** Hook called before each delay; default writes to stderr. */
|
|
18
18
|
onRetry?: (attempt: number, totalAttempts: number, delayMs: number, error: Error) => void;
|
|
19
19
|
}
|
|
20
|
+
/**
|
|
21
|
+
* Optional UI sink for retry progress. The TUI registers one via
|
|
22
|
+
* {@link setRetryReporter}; without it (headless/CLI, tests) retries fall back
|
|
23
|
+
* to stderr. This exists because a raw `process.stderr.write` under OpenTUI's
|
|
24
|
+
* raw-mode alt-screen paints over wherever the cursor sits — the retry line was
|
|
25
|
+
* bleeding into the composer input frame (user-reported). Routing through a
|
|
26
|
+
* toast keeps it in the proper surface.
|
|
27
|
+
*/
|
|
28
|
+
type RetryReporter = (message: string, level: "warn" | "info") => void;
|
|
29
|
+
export declare function setRetryReporter(fn: RetryReporter | null): void;
|
|
20
30
|
export declare function withVisibleRetry<T>(fn: () => Promise<T>, opts?: VisibleRetryOpts): Promise<T>;
|
|
31
|
+
export {};
|
|
@@ -6,9 +6,18 @@ function isRetryableError(err) {
|
|
|
6
6
|
const msg = (e?.message ?? "").toLowerCase();
|
|
7
7
|
return msg.includes("rate limit") || msg.includes("too many requests") || msg.includes("timeout");
|
|
8
8
|
}
|
|
9
|
+
let retryReporter = null;
|
|
10
|
+
export function setRetryReporter(fn) {
|
|
11
|
+
retryReporter = fn;
|
|
12
|
+
}
|
|
9
13
|
function defaultOnRetry(attempt, total, delayMs, error) {
|
|
10
14
|
const reason = error.statusCode === 429 ? "rate-limited (429)" : error.message.slice(0, 80);
|
|
11
|
-
|
|
15
|
+
const message = `[retry] ${reason} — waiting ${Math.round(delayMs / 1000)}s before attempt ${attempt + 1}/${total}`;
|
|
16
|
+
if (retryReporter) {
|
|
17
|
+
retryReporter(message, "warn");
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
process.stderr.write(`${message}\n`);
|
|
12
21
|
}
|
|
13
22
|
export async function withVisibleRetry(fn, opts = {}) {
|
|
14
23
|
const delays = opts.delaysMs ?? [2000, 4000, 8000, 16000, 32000];
|
|
@@ -27,4 +27,4 @@ export declare function getVerifyCliError(options: {
|
|
|
27
27
|
hasPrompt?: boolean;
|
|
28
28
|
hasMessageArgs?: boolean;
|
|
29
29
|
}): string | null;
|
|
30
|
-
export { defaultShellInit, inferVerifyProjectProfile, inferVerifySmokeUrl, normalizeVerifyRecipe, type VerifyProjectProfile, } from "./recipes.js";
|
|
30
|
+
export { defaultShellInit, inferVerifyProjectProfile, inferVerifySmokeUrl, normalizeVerifyRecipe, shouldTrustDeterministicRecipe, type VerifyProjectProfile, } from "./recipes.js";
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { VERIFY_FAIL_MARKER, VERIFY_PASS_MARKER } from "../product-loop/verify-result.js";
|
|
1
2
|
import { ensureVerifyCheckpoint } from "./checkpoint.js";
|
|
2
3
|
import { loadVerifyEnvironment } from "./environment.js";
|
|
3
4
|
import { buildBrowserGuidance, buildEvidenceGuidance, buildReadinessGuidance } from "./evidence.js";
|
|
@@ -69,6 +70,51 @@ export function buildVerifyTaskPrompt(cwd, settings, recipeOverride, sandboxMode
|
|
|
69
70
|
"Phase 1 — Setup:",
|
|
70
71
|
"- Probe the host for runtimes. If missing, attempt to install them or report as blockers.",
|
|
71
72
|
];
|
|
73
|
+
// Does this project actually expose a long-running app to start + smoke-test in
|
|
74
|
+
// a browser? Only then are Phase 3 (start app) / Phase 4 (browser QA) applicable.
|
|
75
|
+
// A CLI/library/script project (pytest-only Python, a Go/Rust binary, a plain
|
|
76
|
+
// script) has smokeKind "cli"/"none" and no startCommand — forcing "Start the
|
|
77
|
+
// app (REQUIRED)" + "browser QA (REQUIRED)" there is contradictory: the sub-agent
|
|
78
|
+
// cannot satisfy them, so it emits NEITHER verdict marker → parseVerifyResult →
|
|
79
|
+
// UNKNOWN → engineering-floor fails → the sprint retries forever on a passing
|
|
80
|
+
// build. Gate the runtime/browser phases and the verdict rule on this flag.
|
|
81
|
+
const hasRuntimeSmoke = profile.recipe.smokeKind === "http" && Boolean(profile.recipe.startCommand);
|
|
82
|
+
const runtimePhases = hasRuntimeSmoke
|
|
83
|
+
? [
|
|
84
|
+
"Phase 3 — Start the app (REQUIRED, do not skip):",
|
|
85
|
+
"- Start the app using startCommand from the recipe, running it in the background.",
|
|
86
|
+
"- Wait for the app to be ready: use a curl readiness loop or `agent-browser wait --load networkidle`.",
|
|
87
|
+
"- If the app fails to start, report the error but still attempt to capture evidence (logs, screenshots).",
|
|
88
|
+
"",
|
|
89
|
+
"Phase 4 — Browser QA testing (REQUIRED, do not skip):",
|
|
90
|
+
"- You are a QA tester. Open the app in the browser and test it like a human would.",
|
|
91
|
+
`- agent-browser commands run on the HOST${sandboxMode === "shuru" ? ", not the sandbox" : ""}. They WILL work. Do not skip them.`,
|
|
92
|
+
"- Record a video of the entire browser session.",
|
|
93
|
+
"- Navigate the app: click links, buttons, menus. Verify pages load correctly.",
|
|
94
|
+
"- Check for JavaScript console errors.",
|
|
95
|
+
"- Spend 3-5 interactions testing the critical path. Take screenshots after each.",
|
|
96
|
+
"- This is the most important phase. Build/lint passing means nothing if the app doesn't actually work.",
|
|
97
|
+
"",
|
|
98
|
+
"Phase 5 — Teardown:",
|
|
99
|
+
"- Stop recording, close browser, THEN stop the dev server.",
|
|
100
|
+
]
|
|
101
|
+
: [
|
|
102
|
+
"Phase 3 — Runtime smoke (CLI / library / script — there is NO long-running app to start):",
|
|
103
|
+
'- This project exposes no HTTP server or startable app (smokeKind is not "http"), so there is NOTHING to start in the background and NO browser QA to run.',
|
|
104
|
+
"- Do the equivalent CLI smoke instead: run the built binary / script (or the recipe's smoke command) once and confirm it produces the expected output and a zero exit code.",
|
|
105
|
+
"- Capture the exact command and its output as evidence.",
|
|
106
|
+
"- Browser and app-start phases are NOT APPLICABLE here — skipping them is CORRECT and is NOT a failure. Do NOT treat their absence as a blocker.",
|
|
107
|
+
];
|
|
108
|
+
const verdictRule = hasRuntimeSmoke
|
|
109
|
+
? [
|
|
110
|
+
`- After the report, emit the verdict on its own final line: exactly \`${VERIFY_PASS_MARKER}\` if install/build/test and the smoke/QA phases all succeeded, otherwise exactly \`${VERIFY_FAIL_MARKER}\`.`,
|
|
111
|
+
`- Emit \`${VERIFY_FAIL_MARKER}\` on ANY failed or skipped required phase (build error, failing test, app did not start, blocking console error). Do NOT emit \`${VERIFY_PASS_MARKER}\` if you could not actually run the recipe.`,
|
|
112
|
+
]
|
|
113
|
+
: [
|
|
114
|
+
`- After the report, emit the verdict on its own final line: exactly \`${VERIFY_PASS_MARKER}\` if install/build/test (and the CLI smoke, if any) all succeeded, otherwise exactly \`${VERIFY_FAIL_MARKER}\`.`,
|
|
115
|
+
`- This is a CLI/library/script project with no app to start: the browser and app-start phases are N/A, NOT failures. Do NOT withhold \`${VERIFY_PASS_MARKER}\` merely because they were not run.`,
|
|
116
|
+
`- Emit \`${VERIFY_FAIL_MARKER}\` ONLY on a real failure: an install/build error, a failing test, or a CLI smoke that produced the wrong result. Do NOT emit \`${VERIFY_PASS_MARKER}\` if you could not actually run the recipe's tests.`,
|
|
117
|
+
];
|
|
72
118
|
return [
|
|
73
119
|
"Run a local verification pass for the current workspace.",
|
|
74
120
|
"",
|
|
@@ -90,22 +136,7 @@ export function buildVerifyTaskPrompt(cwd, settings, recipeOverride, sandboxMode
|
|
|
90
136
|
"Phase 2 — Build and test:",
|
|
91
137
|
"- Run installCommands, buildCommands, and testCommands from the recipe.",
|
|
92
138
|
"",
|
|
93
|
-
|
|
94
|
-
"- Start the app using startCommand from the recipe, running it in the background.",
|
|
95
|
-
"- Wait for the app to be ready: use a curl readiness loop or `agent-browser wait --load networkidle`.",
|
|
96
|
-
"- If the app fails to start, report the error but still attempt to capture evidence (logs, screenshots).",
|
|
97
|
-
"",
|
|
98
|
-
"Phase 4 — Browser QA testing (REQUIRED, do not skip):",
|
|
99
|
-
"- You are a QA tester. Open the app in the browser and test it like a human would.",
|
|
100
|
-
`- agent-browser commands run on the HOST${sandboxMode === "shuru" ? ", not the sandbox" : ""}. They WILL work. Do not skip them.`,
|
|
101
|
-
"- Record a video of the entire browser session.",
|
|
102
|
-
"- Navigate the app: click links, buttons, menus. Verify pages load correctly.",
|
|
103
|
-
"- Check for JavaScript console errors.",
|
|
104
|
-
"- Spend 3-5 interactions testing the critical path. Take screenshots after each.",
|
|
105
|
-
"- This is the most important phase. Build/lint passing means nothing if the app doesn't actually work.",
|
|
106
|
-
"",
|
|
107
|
-
"Phase 5 — Teardown:",
|
|
108
|
-
"- Stop recording, close browser, THEN stop the dev server.",
|
|
139
|
+
...runtimePhases,
|
|
109
140
|
...buildReadinessGuidance(profile),
|
|
110
141
|
...buildBrowserGuidance(profile),
|
|
111
142
|
...buildRetryGuidance(profile),
|
|
@@ -122,6 +153,10 @@ export function buildVerifyTaskPrompt(cwd, settings, recipeOverride, sandboxMode
|
|
|
122
153
|
"- The Summary must say what recipe/source of truth you used and whether you changed the inferred/default one.",
|
|
123
154
|
"- Evidence is mandatory even on failure. If you captured screenshots, video, or logs, include their exact workspace-relative file paths in the Evidence section.",
|
|
124
155
|
"- Use markdown links for artifact paths when practical, otherwise include the plain relative paths.",
|
|
156
|
+
"",
|
|
157
|
+
"Verdict marker (MANDATORY — the loop parses this, an absent marker scores the sprint 0.00):",
|
|
158
|
+
...verdictRule,
|
|
159
|
+
"- The marker is the last line, nothing after it.",
|
|
125
160
|
].join("\n");
|
|
126
161
|
}
|
|
127
162
|
export function createVerifyTaskRequest(cwd, settings, recipeOverride, sandboxMode = "shuru") {
|
|
@@ -382,5 +417,5 @@ export function getVerifyCliError(options) {
|
|
|
382
417
|
}
|
|
383
418
|
return null;
|
|
384
419
|
}
|
|
385
|
-
export { defaultShellInit, inferVerifyProjectProfile, inferVerifySmokeUrl, normalizeVerifyRecipe, } from "./recipes.js";
|
|
420
|
+
export { defaultShellInit, inferVerifyProjectProfile, inferVerifySmokeUrl, normalizeVerifyRecipe, shouldTrustDeterministicRecipe, } from "./recipes.js";
|
|
386
421
|
//# sourceMappingURL=entrypoint.js.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { TaskRequest, ToolResult, VerifyRecipe } from "../types/index.js";
|
|
2
|
-
import type
|
|
2
|
+
import { type SandboxSettings } from "../utils/settings.js";
|
|
3
3
|
import { type PreparedVerifyCheckpoint } from "./checkpoint.js";
|
|
4
4
|
import { type VerifyProjectProfile } from "./recipes.js";
|
|
5
5
|
export interface VerifyAgentLike {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { getCurrentSandboxMode } from "../utils/settings.js";
|
|
1
2
|
import { ensureVerifyCheckpoint } from "./checkpoint.js";
|
|
2
3
|
import { buildVerifyTaskPrompt } from "./entrypoint.js";
|
|
3
4
|
import { loadVerifyEnvironment, saveVerifyEnvironment } from "./environment.js";
|
|
@@ -39,8 +40,21 @@ export async function prepareVerifyRun(agent, options = {}) {
|
|
|
39
40
|
}
|
|
40
41
|
}
|
|
41
42
|
const sandboxSettings = buildRuntimeSandboxSettings(profile);
|
|
42
|
-
|
|
43
|
-
|
|
43
|
+
// Sandbox "off" → run the recipe directly on the host; do NOT bootstrap a
|
|
44
|
+
// `shuru` checkpoint. ensureVerifyCheckpoint spawns `shuru checkpoint …`
|
|
45
|
+
// whenever the recipe has installCommands, regardless of mode — on a host
|
|
46
|
+
// without shuru installed that throws "Executable not found in $PATH: shuru",
|
|
47
|
+
// which parseVerifyResult maps to ERROR (never PASS), pinning the sprint score
|
|
48
|
+
// at 0.00. Skip it when the sole source of truth (getCurrentSandboxMode) is off.
|
|
49
|
+
const checkpoint = getCurrentSandboxMode() === "off"
|
|
50
|
+
? { created: false }
|
|
51
|
+
: await (async () => {
|
|
52
|
+
options.onProgress?.("Preparing verify checkpoint");
|
|
53
|
+
return ensureVerifyCheckpoint(cwd, profile, sandboxSettings);
|
|
54
|
+
})();
|
|
55
|
+
if (getCurrentSandboxMode() === "off") {
|
|
56
|
+
options.onProgress?.("Sandbox off — running verify on host (no shuru checkpoint)");
|
|
57
|
+
}
|
|
44
58
|
if (checkpoint.checkpointName) {
|
|
45
59
|
sandboxSettings.from = checkpoint.checkpointName;
|
|
46
60
|
if (checkpoint.guestWorkdir) {
|
|
@@ -57,7 +71,10 @@ export async function prepareVerifyRun(agent, options = {}) {
|
|
|
57
71
|
const taskRequest = {
|
|
58
72
|
agent: "verify",
|
|
59
73
|
description: "Run local verification",
|
|
60
|
-
prompt
|
|
74
|
+
// Thread the resolved mode so the prompt tells the sub-agent to run "on the
|
|
75
|
+
// host" instead of "inside the active Shuru sandbox" when sandbox is off
|
|
76
|
+
// (the param defaults to "shuru", which was wrong for an off host).
|
|
77
|
+
prompt: buildVerifyTaskPrompt(cwd, sandboxSettings, profile.recipe, getCurrentSandboxMode()),
|
|
61
78
|
};
|
|
62
79
|
return {
|
|
63
80
|
profile,
|