muonroi-cli 1.8.3 → 1.8.5
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 +21 -21
- package/README.md +133 -122
- 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-tee.d.ts +48 -0
- package/dist/packages/agent-harness-core/src/event-tee.js +77 -0
- package/dist/packages/agent-harness-core/src/mcp-server.d.ts +11 -0
- package/dist/packages/agent-harness-core/src/mcp-server.js +87 -15
- package/dist/packages/agent-harness-core/src/protocol.d.ts +66 -2
- 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 +28 -0
- package/dist/src/agent-harness/mock-model.js +63 -1
- package/dist/src/agent-harness/test-spawn.js +31 -0
- 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 +30 -15
- 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 +2 -2
- package/dist/src/cli/keys.js +19 -81
- package/dist/src/council/clarifier.d.ts +28 -2
- package/dist/src/council/clarifier.js +81 -15
- 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 +51 -3
- 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 +1210 -134
- package/dist/src/council/index.d.ts +85 -1
- package/dist/src/council/index.js +634 -196
- package/dist/src/council/leader.d.ts +26 -0
- package/dist/src/council/leader.js +150 -9
- package/dist/src/council/llm.d.ts +32 -0
- package/dist/src/council/llm.js +231 -38
- package/dist/src/council/panel-select.d.ts +30 -0
- package/dist/src/council/panel-select.js +72 -0
- package/dist/src/council/planner.js +23 -0
- package/dist/src/council/preflight.d.ts +7 -0
- package/dist/src/council/preflight.js +14 -2
- package/dist/src/council/prompts.d.ts +30 -3
- package/dist/src/council/prompts.js +254 -84
- 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 +128 -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 +1 -0
- package/dist/src/ee/auth.js +15 -2
- package/dist/src/ee/bridge.d.ts +10 -0
- package/dist/src/ee/bridge.js +58 -0
- package/dist/src/ee/client.js +81 -18
- 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 +45 -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 +13 -1
- package/dist/src/flow/compaction/index.js +70 -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/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 +55 -0
- package/dist/src/gsd/flags.js +83 -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 +251 -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/hooks/index.js +1 -1
- package/dist/src/index.js +44 -11
- 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 +1 -1
- package/dist/src/mcp/ee-tools.js +1 -0
- package/dist/src/mcp/oauth-callback.js +2 -2
- 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 +77 -76
- 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 +8 -8
- 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 +10 -0
- package/dist/src/orchestrator/compaction.js +27 -7
- package/dist/src/orchestrator/council-manager.d.ts +12 -3
- package/dist/src/orchestrator/council-manager.js +65 -24
- 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/message-processor.js +242 -33
- package/dist/src/orchestrator/orchestrator.d.ts +39 -3
- package/dist/src/orchestrator/orchestrator.js +651 -102
- package/dist/src/orchestrator/preprocessor.js +1 -1
- 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 +159 -159
- 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-intercept.d.ts +45 -0
- package/dist/src/orchestrator/safety-intercept.js +55 -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 +24 -3
- package/dist/src/orchestrator/stall-watchdog.js +47 -13
- package/dist/src/orchestrator/stream-runner.js +62 -29
- 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 +26 -0
- package/dist/src/orchestrator/tool-engine.js +669 -56
- 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 +37 -0
- package/dist/src/orchestrator/turn-watchdog.js +55 -0
- package/dist/src/pil/agent-operating-contract.d.ts +1 -1
- package/dist/src/pil/agent-operating-contract.js +1 -1
- 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.js +16 -11
- 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/layer2_5-ponytail.js +8 -8
- 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 +33 -2
- package/dist/src/pil/llm-classify.js +123 -131
- package/dist/src/pil/native-capabilities-workbook.d.ts +1 -1
- package/dist/src/pil/native-capabilities-workbook.js +1 -0
- package/dist/src/pil/pipeline.js +34 -2
- 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/backlog-builder.d.ts +14 -1
- package/dist/src/product-loop/backlog-builder.js +30 -6
- 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.js +32 -3
- package/dist/src/product-loop/discovery-schema.js +5 -1
- package/dist/src/product-loop/done-gate.js +3 -3
- 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 +333 -52
- package/dist/src/product-loop/loop-driver.d.ts +7 -0
- package/dist/src/product-loop/loop-driver.js +327 -116
- package/dist/src/product-loop/phase-plan.d.ts +5 -0
- package/dist/src/product-loop/phase-plan.js +39 -2
- package/dist/src/product-loop/phase-runner.js +9 -1
- package/dist/src/product-loop/progress-snapshot.js +4 -4
- package/dist/src/product-loop/sprint-runner.d.ts +111 -0
- package/dist/src/product-loop/sprint-runner.js +559 -16
- package/dist/src/product-loop/types.d.ts +36 -5
- package/dist/src/providers/adapter.d.ts +1 -1
- package/dist/src/providers/adapter.js +3 -4
- 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/openai-oauth.js +1 -1
- package/dist/src/providers/auth/registry.js +0 -34
- package/dist/src/providers/auth/token-store.js +4 -1
- package/dist/src/providers/auth/types.d.ts +1 -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/keychain.d.ts +1 -1
- package/dist/src/providers/keychain.js +7 -9
- package/dist/src/providers/mcp-vision-bridge.js +82 -172
- 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 +27 -2
- package/dist/src/providers/runtime.js +78 -15
- 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 +280 -1
- 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/wire-debug.js +95 -0
- package/dist/src/reporter/index.js +1 -1
- 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/bb-ecosystem-apply.js +47 -47
- package/dist/src/scaffold/bb-quality-gate.js +5 -5
- package/dist/src/scaffold/continuation-prompt.d.ts +11 -0
- package/dist/src/scaffold/continuation-prompt.js +86 -60
- package/dist/src/scaffold/init-new.js +453 -453
- 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 +22 -22
- 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/interaction-log.js +5 -5
- package/dist/src/storage/migrations.js +196 -126
- package/dist/src/storage/session-experience-store.js +4 -4
- package/dist/src/storage/sessions.d.ts +28 -10
- package/dist/src/storage/sessions.js +112 -55
- package/dist/src/storage/transcript-view.js +1 -1
- package/dist/src/storage/transcript.d.ts +51 -0
- package/dist/src/storage/transcript.js +383 -112
- package/dist/src/storage/usage.js +14 -14
- package/dist/src/storage/workspaces.js +12 -12
- package/dist/src/tools/file.d.ts +15 -0
- package/dist/src/tools/file.js +32 -0
- package/dist/src/tools/native-tools.js +5 -0
- package/dist/src/tools/registry.d.ts +3 -0
- package/dist/src/tools/registry.js +460 -22
- package/dist/src/tools/research.d.ts +29 -0
- package/dist/src/tools/research.js +233 -0
- package/dist/src/types/index.d.ts +118 -3
- package/dist/src/ui/app.js +0 -0
- package/dist/src/ui/cards/product-status-card.js +1 -1
- 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/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 +49 -15
- 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 +12 -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/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/containers/modals-layer.d.ts +2 -1
- 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/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-inspect.js +4 -4
- 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/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 +12 -18
- 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/format.d.ts +14 -0
- package/dist/src/ui/utils/format.js +23 -3
- package/dist/src/usage/downgrade.js +2 -2
- package/dist/src/usage/product-ledger.js +2 -2
- package/dist/src/utils/clipboard-image.js +23 -23
- package/dist/src/utils/install-manager.js +14 -11
- package/dist/src/utils/logger.js +2 -2
- package/dist/src/utils/permission-mode.js +5 -3
- package/dist/src/utils/redactor.js +1 -1
- package/dist/src/utils/settings.d.ts +153 -5
- package/dist/src/utils/settings.js +233 -29
- package/dist/src/utils/side-question.js +2 -2
- package/dist/src/utils/skills.js +3 -3
- 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 +1 -1
- package/dist/src/verify/recipes.d.ts +13 -0
- package/dist/src/verify/recipes.js +15 -0
- package/package.json +135 -132
- 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,129 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/council/debate-checkpoint.ts
|
|
3
|
+
*
|
|
4
|
+
* C (mid-debate checkpoint) — persist the CB-1 council debate's per-round state
|
|
5
|
+
* so a break mid-debate (provider 5xx on round 5, host crash, cap breach) can
|
|
6
|
+
* resume from the last completed round instead of re-running the whole debate.
|
|
7
|
+
*
|
|
8
|
+
* The debate accumulates all state in RAM (`exchangeLogs`, `active`,
|
|
9
|
+
* `runningSummary`, `archive`, convergence trackers). Without a checkpoint a
|
|
10
|
+
* break loses every round — a 5-round multi-provider debate must restart from
|
|
11
|
+
* round 1. This module owns the on-disk snapshot: `runDebate` writes it after
|
|
12
|
+
* each completed round and deletes it on normal completion; the resume path
|
|
13
|
+
* reads it and seeds `runDebate` so it skips research + openings + completed
|
|
14
|
+
* rounds.
|
|
15
|
+
*
|
|
16
|
+
* File: `<checkpointDir>/debate-checkpoint.json` (checkpointDir = the run dir,
|
|
17
|
+
* `.muonroi-flow/runs/<runId>`). Written atomically (tmp + rename) so a crash
|
|
18
|
+
* mid-write can never leave a half-JSON file.
|
|
19
|
+
*/
|
|
20
|
+
import type { ClarifiedSpec, CouncilParticipant, DebateArchiveEntry } from "./types.js";
|
|
21
|
+
/** Bump when the checkpoint shape changes incompatibly so stale files are ignored. */
|
|
22
|
+
export declare const DEBATE_CHECKPOINT_VERSION: 1;
|
|
23
|
+
export declare const DEBATE_CHECKPOINT_FILE = "debate-checkpoint.json";
|
|
24
|
+
/**
|
|
25
|
+
* Serializable snapshot of an in-flight debate, written after each completed
|
|
26
|
+
* discussion round. `exchangeLogs` (a `Map`) is stored as entry tuples since
|
|
27
|
+
* JSON has no Map; everything else in the payload is already JSON-native.
|
|
28
|
+
*/
|
|
29
|
+
export interface DebateCheckpoint {
|
|
30
|
+
version: typeof DEBATE_CHECKPOINT_VERSION;
|
|
31
|
+
/**
|
|
32
|
+
* Identity guard — the checkpoint is only restored when it matches the debate
|
|
33
|
+
* about to run. `problemStatement` pins the spec; `participantModels` pins the
|
|
34
|
+
* panel. A mismatch (spec changed, panel re-resolved differently) => ignore
|
|
35
|
+
* the stale checkpoint and run the debate fresh rather than splice wrong state.
|
|
36
|
+
*/
|
|
37
|
+
problemStatement: string;
|
|
38
|
+
participantModels: string[];
|
|
39
|
+
/** Rounds fully completed (transcript + summary persisted). Resume starts at roundCount+1. */
|
|
40
|
+
roundCount: number;
|
|
41
|
+
/** Current round budget after any leader/user extensions. */
|
|
42
|
+
maxRounds: number;
|
|
43
|
+
/** Accumulated per-pair transcript (Map<pairKey, turns[]> serialized as entries). */
|
|
44
|
+
exchangeLogs: Array<[string, string[]]>;
|
|
45
|
+
/** Latest inter-round summary. */
|
|
46
|
+
runningSummary: string;
|
|
47
|
+
/** Research findings (so the research phase is not re-run on resume). */
|
|
48
|
+
researchFindings?: string;
|
|
49
|
+
/** Surviving participants with their latest position + stance (so openings are not re-run). */
|
|
50
|
+
active: CouncilParticipant[];
|
|
51
|
+
/** Citation archive accumulated so far. */
|
|
52
|
+
archive: DebateArchiveEntry[];
|
|
53
|
+
/** Convergence continuity: last round's per-criterion met flags. */
|
|
54
|
+
lastCriteriaMet: boolean[];
|
|
55
|
+
/** B4 auto-remedy high-water mark of pinned criteria met. */
|
|
56
|
+
bestCriteriaMetCount: number;
|
|
57
|
+
/** B4 consecutive evaluated rounds with no new met criterion. */
|
|
58
|
+
roundsSinceProgress: number;
|
|
59
|
+
/** Topic carried into the next round from the prior leader nextRoundFocus. */
|
|
60
|
+
nextTopic?: string;
|
|
61
|
+
/** Wall-clock the checkpoint was written (ISO). Diagnostics only. */
|
|
62
|
+
savedAt: string;
|
|
63
|
+
}
|
|
64
|
+
/** Input to {@link buildDebateCheckpoint} — the live round-loop locals. */
|
|
65
|
+
export interface DebateCheckpointInput {
|
|
66
|
+
problemStatement: string;
|
|
67
|
+
roundCount: number;
|
|
68
|
+
maxRounds: number;
|
|
69
|
+
exchangeLogs: Map<string, string[]>;
|
|
70
|
+
runningSummary: string;
|
|
71
|
+
researchFindings?: string;
|
|
72
|
+
active: CouncilParticipant[];
|
|
73
|
+
archive: DebateArchiveEntry[];
|
|
74
|
+
lastCriteriaMet: boolean[];
|
|
75
|
+
bestCriteriaMetCount: number;
|
|
76
|
+
roundsSinceProgress: number;
|
|
77
|
+
nextTopic?: string;
|
|
78
|
+
/** ISO timestamp; the caller supplies it (Date.now is unavailable in some sandboxes). */
|
|
79
|
+
savedAt: string;
|
|
80
|
+
}
|
|
81
|
+
/** Build the serializable checkpoint payload from live debate state. */
|
|
82
|
+
export declare function buildDebateCheckpoint(input: DebateCheckpointInput): DebateCheckpoint;
|
|
83
|
+
/** Rehydrate `exchangeLogs` from the serialized entry tuples. */
|
|
84
|
+
export declare function restoreExchangeLogs(cp: DebateCheckpoint): Map<string, string[]>;
|
|
85
|
+
/**
|
|
86
|
+
* Whether `cp` describes the debate that is about to run. Guards against
|
|
87
|
+
* splicing a stale checkpoint (different question, re-resolved panel) into a
|
|
88
|
+
* fresh debate. Participant order is not significant; the model SET must match.
|
|
89
|
+
*/
|
|
90
|
+
export declare function checkpointMatches(cp: DebateCheckpoint, problemStatement: string, participantModels: string[]): boolean;
|
|
91
|
+
/**
|
|
92
|
+
* Atomically write the checkpoint to `<dir>/debate-checkpoint.json`.
|
|
93
|
+
* Non-fatal: a checkpoint write failure must never break the live debate — it
|
|
94
|
+
* only forfeits resumability for that round. Logs with context (No-Silent-Catch).
|
|
95
|
+
*/
|
|
96
|
+
export declare function writeDebateCheckpoint(dir: string, cp: DebateCheckpoint): Promise<void>;
|
|
97
|
+
/**
|
|
98
|
+
* Read + parse the checkpoint. Returns null when absent or unparseable (a
|
|
99
|
+
* corrupt checkpoint must not crash resume — the debate just runs fresh).
|
|
100
|
+
*/
|
|
101
|
+
export declare function readDebateCheckpoint(dir: string): Promise<DebateCheckpoint | null>;
|
|
102
|
+
/**
|
|
103
|
+
* Delete the checkpoint (debate completed normally, or the run was aborted).
|
|
104
|
+
* Non-fatal — a leftover checkpoint is only re-validated (and discarded on
|
|
105
|
+
* mismatch) on the next resume, never silently mis-applied.
|
|
106
|
+
*/
|
|
107
|
+
export declare function deleteDebateCheckpoint(dir: string): Promise<void>;
|
|
108
|
+
export declare const DEBATE_INPUTS_FILE = "debate-inputs.json";
|
|
109
|
+
/**
|
|
110
|
+
* C-v2 — the minimal gather-stage outputs needed to re-enter the council debate
|
|
111
|
+
* on a fresh session (cross-process resume) WITHOUT re-running the interactive
|
|
112
|
+
* discovery + interview. Persisted once at debate start; the loop-driver resume
|
|
113
|
+
* entry restores `clarifiedSpec` + `conversationContext` and jumps straight to
|
|
114
|
+
* the research/debate stage (participants + leader are re-resolved from the
|
|
115
|
+
* session model deterministically, then matched against the checkpoint panel).
|
|
116
|
+
*/
|
|
117
|
+
export interface DebateInputs {
|
|
118
|
+
version: typeof DEBATE_CHECKPOINT_VERSION;
|
|
119
|
+
problemStatement: string;
|
|
120
|
+
clarifiedSpec: ClarifiedSpec;
|
|
121
|
+
conversationContext: string;
|
|
122
|
+
savedAt: string;
|
|
123
|
+
}
|
|
124
|
+
/** Atomically persist the debate inputs. Non-fatal on failure (forfeits cross-session resume only). */
|
|
125
|
+
export declare function writeDebateInputs(dir: string, inputs: DebateInputs): Promise<void>;
|
|
126
|
+
/** Read the debate inputs. Returns null when absent/unparseable/version-mismatched. */
|
|
127
|
+
export declare function readDebateInputs(dir: string): Promise<DebateInputs | null>;
|
|
128
|
+
/** Delete the debate inputs (debate + scoping finished, or run aborted). Non-fatal. */
|
|
129
|
+
export declare function deleteDebateInputs(dir: string): Promise<void>;
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/council/debate-checkpoint.ts
|
|
3
|
+
*
|
|
4
|
+
* C (mid-debate checkpoint) — persist the CB-1 council debate's per-round state
|
|
5
|
+
* so a break mid-debate (provider 5xx on round 5, host crash, cap breach) can
|
|
6
|
+
* resume from the last completed round instead of re-running the whole debate.
|
|
7
|
+
*
|
|
8
|
+
* The debate accumulates all state in RAM (`exchangeLogs`, `active`,
|
|
9
|
+
* `runningSummary`, `archive`, convergence trackers). Without a checkpoint a
|
|
10
|
+
* break loses every round — a 5-round multi-provider debate must restart from
|
|
11
|
+
* round 1. This module owns the on-disk snapshot: `runDebate` writes it after
|
|
12
|
+
* each completed round and deletes it on normal completion; the resume path
|
|
13
|
+
* reads it and seeds `runDebate` so it skips research + openings + completed
|
|
14
|
+
* rounds.
|
|
15
|
+
*
|
|
16
|
+
* File: `<checkpointDir>/debate-checkpoint.json` (checkpointDir = the run dir,
|
|
17
|
+
* `.muonroi-flow/runs/<runId>`). Written atomically (tmp + rename) so a crash
|
|
18
|
+
* mid-write can never leave a half-JSON file.
|
|
19
|
+
*/
|
|
20
|
+
import { promises as fs } from "node:fs";
|
|
21
|
+
import * as path from "node:path";
|
|
22
|
+
/** Bump when the checkpoint shape changes incompatibly so stale files are ignored. */
|
|
23
|
+
export const DEBATE_CHECKPOINT_VERSION = 1;
|
|
24
|
+
export const DEBATE_CHECKPOINT_FILE = "debate-checkpoint.json";
|
|
25
|
+
/** Build the serializable checkpoint payload from live debate state. */
|
|
26
|
+
export function buildDebateCheckpoint(input) {
|
|
27
|
+
return {
|
|
28
|
+
version: DEBATE_CHECKPOINT_VERSION,
|
|
29
|
+
problemStatement: input.problemStatement,
|
|
30
|
+
participantModels: input.active.map((p) => p.model),
|
|
31
|
+
roundCount: input.roundCount,
|
|
32
|
+
maxRounds: input.maxRounds,
|
|
33
|
+
exchangeLogs: [...input.exchangeLogs.entries()].map(([k, v]) => [k, [...v]]),
|
|
34
|
+
runningSummary: input.runningSummary,
|
|
35
|
+
researchFindings: input.researchFindings,
|
|
36
|
+
active: input.active,
|
|
37
|
+
archive: input.archive,
|
|
38
|
+
lastCriteriaMet: [...input.lastCriteriaMet],
|
|
39
|
+
bestCriteriaMetCount: input.bestCriteriaMetCount,
|
|
40
|
+
roundsSinceProgress: input.roundsSinceProgress,
|
|
41
|
+
nextTopic: input.nextTopic,
|
|
42
|
+
savedAt: input.savedAt,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
/** Rehydrate `exchangeLogs` from the serialized entry tuples. */
|
|
46
|
+
export function restoreExchangeLogs(cp) {
|
|
47
|
+
return new Map(cp.exchangeLogs.map(([k, v]) => [k, [...v]]));
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Whether `cp` describes the debate that is about to run. Guards against
|
|
51
|
+
* splicing a stale checkpoint (different question, re-resolved panel) into a
|
|
52
|
+
* fresh debate. Participant order is not significant; the model SET must match.
|
|
53
|
+
*/
|
|
54
|
+
export function checkpointMatches(cp, problemStatement, participantModels) {
|
|
55
|
+
if (cp.version !== DEBATE_CHECKPOINT_VERSION)
|
|
56
|
+
return false;
|
|
57
|
+
if (cp.roundCount < 1)
|
|
58
|
+
return false; // nothing useful to resume from
|
|
59
|
+
if (cp.problemStatement !== problemStatement)
|
|
60
|
+
return false;
|
|
61
|
+
const a = [...cp.participantModels].sort();
|
|
62
|
+
const b = [...participantModels].sort();
|
|
63
|
+
if (a.length !== b.length)
|
|
64
|
+
return false;
|
|
65
|
+
return a.every((m, i) => m === b[i]);
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Atomically write the checkpoint to `<dir>/debate-checkpoint.json`.
|
|
69
|
+
* Non-fatal: a checkpoint write failure must never break the live debate — it
|
|
70
|
+
* only forfeits resumability for that round. Logs with context (No-Silent-Catch).
|
|
71
|
+
*/
|
|
72
|
+
export async function writeDebateCheckpoint(dir, cp) {
|
|
73
|
+
const finalPath = path.join(dir, DEBATE_CHECKPOINT_FILE);
|
|
74
|
+
const tmpPath = `${finalPath}.${process.pid}.tmp`;
|
|
75
|
+
try {
|
|
76
|
+
await fs.mkdir(dir, { recursive: true });
|
|
77
|
+
await fs.writeFile(tmpPath, JSON.stringify(cp), "utf8");
|
|
78
|
+
await fs.rename(tmpPath, finalPath);
|
|
79
|
+
}
|
|
80
|
+
catch (err) {
|
|
81
|
+
console.error(`[debate-checkpoint] write failed (dir=${dir}, round=${cp.roundCount}): ${err?.message}`);
|
|
82
|
+
// Best-effort cleanup of the temp file; ignore if it never got created.
|
|
83
|
+
await fs.rm(tmpPath, { force: true }).catch(() => { });
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Read + parse the checkpoint. Returns null when absent or unparseable (a
|
|
88
|
+
* corrupt checkpoint must not crash resume — the debate just runs fresh).
|
|
89
|
+
*/
|
|
90
|
+
export async function readDebateCheckpoint(dir) {
|
|
91
|
+
const finalPath = path.join(dir, DEBATE_CHECKPOINT_FILE);
|
|
92
|
+
let raw;
|
|
93
|
+
try {
|
|
94
|
+
raw = await fs.readFile(finalPath, "utf8");
|
|
95
|
+
}
|
|
96
|
+
catch (err) {
|
|
97
|
+
if (err?.code !== "ENOENT") {
|
|
98
|
+
console.error(`[debate-checkpoint] read failed (dir=${dir}): ${err?.message}`);
|
|
99
|
+
}
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
try {
|
|
103
|
+
const parsed = JSON.parse(raw);
|
|
104
|
+
if (parsed?.version !== DEBATE_CHECKPOINT_VERSION)
|
|
105
|
+
return null;
|
|
106
|
+
return parsed;
|
|
107
|
+
}
|
|
108
|
+
catch (err) {
|
|
109
|
+
console.error(`[debate-checkpoint] parse failed (dir=${dir}): ${err?.message}`);
|
|
110
|
+
return null;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Delete the checkpoint (debate completed normally, or the run was aborted).
|
|
115
|
+
* Non-fatal — a leftover checkpoint is only re-validated (and discarded on
|
|
116
|
+
* mismatch) on the next resume, never silently mis-applied.
|
|
117
|
+
*/
|
|
118
|
+
export async function deleteDebateCheckpoint(dir) {
|
|
119
|
+
const finalPath = path.join(dir, DEBATE_CHECKPOINT_FILE);
|
|
120
|
+
try {
|
|
121
|
+
await fs.rm(finalPath, { force: true });
|
|
122
|
+
}
|
|
123
|
+
catch (err) {
|
|
124
|
+
console.error(`[debate-checkpoint] delete failed (dir=${dir}): ${err?.message}`);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
// ── Debate inputs (C-v2 cross-session resume) ────────────────────────────────
|
|
128
|
+
export const DEBATE_INPUTS_FILE = "debate-inputs.json";
|
|
129
|
+
/** Atomically persist the debate inputs. Non-fatal on failure (forfeits cross-session resume only). */
|
|
130
|
+
export async function writeDebateInputs(dir, inputs) {
|
|
131
|
+
const finalPath = path.join(dir, DEBATE_INPUTS_FILE);
|
|
132
|
+
const tmpPath = `${finalPath}.${process.pid}.tmp`;
|
|
133
|
+
try {
|
|
134
|
+
await fs.mkdir(dir, { recursive: true });
|
|
135
|
+
await fs.writeFile(tmpPath, JSON.stringify(inputs), "utf8");
|
|
136
|
+
await fs.rename(tmpPath, finalPath);
|
|
137
|
+
}
|
|
138
|
+
catch (err) {
|
|
139
|
+
console.error(`[debate-checkpoint] inputs write failed (dir=${dir}): ${err?.message}`);
|
|
140
|
+
await fs.rm(tmpPath, { force: true }).catch(() => { });
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
/** Read the debate inputs. Returns null when absent/unparseable/version-mismatched. */
|
|
144
|
+
export async function readDebateInputs(dir) {
|
|
145
|
+
const finalPath = path.join(dir, DEBATE_INPUTS_FILE);
|
|
146
|
+
let raw;
|
|
147
|
+
try {
|
|
148
|
+
raw = await fs.readFile(finalPath, "utf8");
|
|
149
|
+
}
|
|
150
|
+
catch (err) {
|
|
151
|
+
if (err?.code !== "ENOENT") {
|
|
152
|
+
console.error(`[debate-checkpoint] inputs read failed (dir=${dir}): ${err?.message}`);
|
|
153
|
+
}
|
|
154
|
+
return null;
|
|
155
|
+
}
|
|
156
|
+
try {
|
|
157
|
+
const parsed = JSON.parse(raw);
|
|
158
|
+
if (parsed?.version !== DEBATE_CHECKPOINT_VERSION)
|
|
159
|
+
return null;
|
|
160
|
+
return parsed;
|
|
161
|
+
}
|
|
162
|
+
catch (err) {
|
|
163
|
+
console.error(`[debate-checkpoint] inputs parse failed (dir=${dir}): ${err?.message}`);
|
|
164
|
+
return null;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
/** Delete the debate inputs (debate + scoping finished, or run aborted). Non-fatal. */
|
|
168
|
+
export async function deleteDebateInputs(dir) {
|
|
169
|
+
try {
|
|
170
|
+
await fs.rm(path.join(dir, DEBATE_INPUTS_FILE), { force: true });
|
|
171
|
+
}
|
|
172
|
+
catch (err) {
|
|
173
|
+
console.error(`[debate-checkpoint] inputs delete failed (dir=${dir}): ${err?.message}`);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
//# sourceMappingURL=debate-checkpoint.js.map
|
|
@@ -3,6 +3,7 @@ import { z } from "zod";
|
|
|
3
3
|
import { loadKeyForProvider } from "../providers/keychain.js";
|
|
4
4
|
import { createProviderFactory, detectProviderForModel, resolveModelRuntime } from "../providers/runtime.js";
|
|
5
5
|
import { withDeadlineRace, withTimeoutSignal } from "../utils/llm-deadline.js";
|
|
6
|
+
import { logger } from "../utils/logger.js";
|
|
6
7
|
import { getProviderStallTimeoutMs } from "../utils/settings.js";
|
|
7
8
|
import { tracedGenerate } from "./llm.js";
|
|
8
9
|
import { buildDebatePlanPrompt } from "./prompts.js";
|
|
@@ -94,6 +95,37 @@ function injectAuditorStance(plan, eeWarnings, experienceMode) {
|
|
|
94
95
|
}
|
|
95
96
|
return { ...plan, stances };
|
|
96
97
|
}
|
|
98
|
+
/**
|
|
99
|
+
* PIL task types whose deliverable is understanding/evaluation of something that
|
|
100
|
+
* already exists — never a build. The user asked to assess, not to implement.
|
|
101
|
+
*/
|
|
102
|
+
const ANALYSIS_TASK_TYPES = new Set(["analyze"]);
|
|
103
|
+
function isAnalysisTaskType(taskType) {
|
|
104
|
+
return !!taskType && ANALYSIS_TASK_TYPES.has(taskType);
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Deterministic backstop for post-debate drift (session c4f78752a316).
|
|
108
|
+
*
|
|
109
|
+
* PIL is the authoritative intent classifier. When it says the request is
|
|
110
|
+
* analysis/evaluation, the leader LLM must not be allowed to silently reshape the
|
|
111
|
+
* debate into an `implementation_plan` — that shape makes the post-debate AskCard
|
|
112
|
+
* default to "generate_plan" (build a plan) via pickPostDebateRecommendation,
|
|
113
|
+
* which is the wrong next step for a request that only wanted an assessment.
|
|
114
|
+
*
|
|
115
|
+
* The prompt already asks the leader to honor the intent (soft), but LLMs drift;
|
|
116
|
+
* this coerces a drifted shape back to "evaluation" so the synthesis stays the
|
|
117
|
+
* deliverable and the default action becomes save_exit. Non-implementation shapes
|
|
118
|
+
* are left untouched.
|
|
119
|
+
*/
|
|
120
|
+
function enforceAnalysisIntentShape(plan, taskType) {
|
|
121
|
+
if (!isAnalysisTaskType(taskType))
|
|
122
|
+
return plan;
|
|
123
|
+
if (plan.outputShape.kind !== "implementation_plan")
|
|
124
|
+
return plan;
|
|
125
|
+
logger.info("orchestrator", `[debate-planner] PIL taskType=${taskType} (analysis) but leader chose implementation_plan; ` +
|
|
126
|
+
"coercing outputShape.kind→evaluation to honor analysis intent");
|
|
127
|
+
return { ...plan, outputShape: { ...plan.outputShape, kind: "evaluation" } };
|
|
128
|
+
}
|
|
97
129
|
export async function* planDebate(spec, leaderModelId, llm, eeWarnings, // CQ-13: experience snippets to seed prompt
|
|
98
130
|
experienceMode, // CQ-14: controls Experience Auditor injection
|
|
99
131
|
taskType, // CQ-11: task type from PIL (e.g. "architecture", "bugfix")
|
|
@@ -101,6 +133,10 @@ complexityTier, // CQ-11: complexity tier from PIL (e.g. "heavy", "medium", "lig
|
|
|
101
133
|
signal) {
|
|
102
134
|
const eeSnippets = eeWarnings?.map((w) => w.text).filter(Boolean) ?? [];
|
|
103
135
|
const { system: baseSystem, prompt } = buildDebatePlanPrompt(spec);
|
|
136
|
+
// Every return path funnels through here: auditor + product-stance injection,
|
|
137
|
+
// plus the deterministic analysis-intent backstop (applied first so a coerced
|
|
138
|
+
// shape doesn't get a spurious product stance injected for it).
|
|
139
|
+
const finalizePlan = (plan) => ensureProductStance(injectAuditorStance(enforceAnalysisIntentShape(plan, taskType), eeWarnings, experienceMode));
|
|
104
140
|
// Build calibration context from PIL metadata
|
|
105
141
|
const pilCalibration = [];
|
|
106
142
|
if (taskType)
|
|
@@ -111,6 +147,18 @@ signal) {
|
|
|
111
147
|
if (pilCalibration.length > 0) {
|
|
112
148
|
system += `\n\n## Task Context (from PIL)\n${pilCalibration.join("\n")}`;
|
|
113
149
|
}
|
|
150
|
+
// Hard intent lock (steers stances AND shape). PIL already classified this as
|
|
151
|
+
// analysis; the deterministic backstop in finalizePlan enforces it regardless,
|
|
152
|
+
// but steering the leader here keeps the whole roster/synthesis on-intent.
|
|
153
|
+
if (isAnalysisTaskType(taskType)) {
|
|
154
|
+
system +=
|
|
155
|
+
`\n\n## INTENT LOCK (authoritative)\n` +
|
|
156
|
+
`PIL classified this request as ANALYSIS/EVALUATION (taskType=${taskType}). The user wants to ` +
|
|
157
|
+
`understand and assess what ALREADY exists — not to build anything. ` +
|
|
158
|
+
`outputShape.kind MUST be "evaluation" or "investigation" — NEVER "implementation_plan". ` +
|
|
159
|
+
`Do NOT propose building, implementing, scaffolding, or "I'll spec that in vN". ` +
|
|
160
|
+
`Stances must be analyst/critic/investigator voices, not implementers.`;
|
|
161
|
+
}
|
|
114
162
|
if (eeSnippets.length > 0) {
|
|
115
163
|
system += `\n\n## Experience Warnings (from brain)\nNote these past mistakes when designing debate stances:\n${eeSnippets.map((s) => `- ${s}`).join("\n")}`;
|
|
116
164
|
}
|
|
@@ -158,7 +206,7 @@ signal) {
|
|
|
158
206
|
outputShape,
|
|
159
207
|
plannedRounds,
|
|
160
208
|
};
|
|
161
|
-
return
|
|
209
|
+
return finalizePlan(plan);
|
|
162
210
|
}
|
|
163
211
|
// Invalid even with schema — fall through to retry with a sanitize-failure message
|
|
164
212
|
throw new Error("Sanitize check failed: stances.length < 2 or outputShape is null");
|
|
@@ -180,7 +228,7 @@ signal) {
|
|
|
180
228
|
});
|
|
181
229
|
const retryParsed = parsePlan(retryRaw);
|
|
182
230
|
if (retryParsed)
|
|
183
|
-
return
|
|
231
|
+
return finalizePlan(retryParsed);
|
|
184
232
|
}
|
|
185
233
|
catch (retryErr) {
|
|
186
234
|
yield {
|
|
@@ -190,7 +238,7 @@ signal) {
|
|
|
190
238
|
}
|
|
191
239
|
}
|
|
192
240
|
// All attempts exhausted — return fallback
|
|
193
|
-
return
|
|
241
|
+
return finalizePlan(FALLBACK_PLAN);
|
|
194
242
|
}
|
|
195
243
|
function parsePlan(raw) {
|
|
196
244
|
try {
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/council/debate-summary.ts
|
|
3
|
+
*
|
|
4
|
+
* Fallback debate-summary synthesis.
|
|
5
|
+
*
|
|
6
|
+
* The /ideal research phase persists the debate into `research.md` +
|
|
7
|
+
* `delegations.md` from `DebateState.runningSummary`. But a debate that returns
|
|
8
|
+
* after opening statements (e.g. the leader routes straight to the preflight
|
|
9
|
+
* gate without evaluation rounds) leaves `runningSummary` empty — and the whole
|
|
10
|
+
* debate (opening positions, design/impl reasoning) was silently dropped from
|
|
11
|
+
* the canonical artifacts, surviving only in TUI scrollback.
|
|
12
|
+
*
|
|
13
|
+
* This builds a faithful fallback from the participants' latest positions
|
|
14
|
+
* (`active[]`), falling back to per-round archive excerpts, so the research
|
|
15
|
+
* artifact ALWAYS captures the debate. Pure + synchronous → unit-testable.
|
|
16
|
+
*/
|
|
17
|
+
import type { DebateState } from "./types.js";
|
|
18
|
+
/**
|
|
19
|
+
* Return a markdown summary of the debate suitable for `research.md` /
|
|
20
|
+
* `delegations.md`. Prefers `state.runningSummary` when present; otherwise
|
|
21
|
+
* synthesizes one from `active[]` positions, then `archive[]` excerpts. Returns
|
|
22
|
+
* "" only when there is genuinely nothing to show (no summary, no positions, no
|
|
23
|
+
* archive) — callers keep their existing "(no summary produced)" placeholder.
|
|
24
|
+
*/
|
|
25
|
+
export declare function resolveDebateSummary(state: Pick<DebateState, "runningSummary" | "active" | "archive">): string;
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/council/debate-summary.ts
|
|
3
|
+
*
|
|
4
|
+
* Fallback debate-summary synthesis.
|
|
5
|
+
*
|
|
6
|
+
* The /ideal research phase persists the debate into `research.md` +
|
|
7
|
+
* `delegations.md` from `DebateState.runningSummary`. But a debate that returns
|
|
8
|
+
* after opening statements (e.g. the leader routes straight to the preflight
|
|
9
|
+
* gate without evaluation rounds) leaves `runningSummary` empty — and the whole
|
|
10
|
+
* debate (opening positions, design/impl reasoning) was silently dropped from
|
|
11
|
+
* the canonical artifacts, surviving only in TUI scrollback.
|
|
12
|
+
*
|
|
13
|
+
* This builds a faithful fallback from the participants' latest positions
|
|
14
|
+
* (`active[]`), falling back to per-round archive excerpts, so the research
|
|
15
|
+
* artifact ALWAYS captures the debate. Pure + synchronous → unit-testable.
|
|
16
|
+
*/
|
|
17
|
+
/** Cap so the fallback can't balloon the artifact; per-position + overall. */
|
|
18
|
+
const PER_POSITION_CHARS = 4000;
|
|
19
|
+
const TOTAL_CHARS = 16000;
|
|
20
|
+
/**
|
|
21
|
+
* Return a markdown summary of the debate suitable for `research.md` /
|
|
22
|
+
* `delegations.md`. Prefers `state.runningSummary` when present; otherwise
|
|
23
|
+
* synthesizes one from `active[]` positions, then `archive[]` excerpts. Returns
|
|
24
|
+
* "" only when there is genuinely nothing to show (no summary, no positions, no
|
|
25
|
+
* archive) — callers keep their existing "(no summary produced)" placeholder.
|
|
26
|
+
*/
|
|
27
|
+
export function resolveDebateSummary(state) {
|
|
28
|
+
const running = state.runningSummary?.trim();
|
|
29
|
+
if (running)
|
|
30
|
+
return running;
|
|
31
|
+
const fromPositions = summarizeFromActive(state.active);
|
|
32
|
+
if (fromPositions)
|
|
33
|
+
return fromPositions;
|
|
34
|
+
return summarizeFromArchive(state.archive);
|
|
35
|
+
}
|
|
36
|
+
function speakerLabel(role, stanceName) {
|
|
37
|
+
return stanceName?.trim() ? `${stanceName} (${role})` : role;
|
|
38
|
+
}
|
|
39
|
+
function summarizeFromActive(active) {
|
|
40
|
+
if (!Array.isArray(active) || active.length === 0)
|
|
41
|
+
return "";
|
|
42
|
+
const parts = [
|
|
43
|
+
"_(Synthesized from participants' final positions — the debate produced no running summary.)_",
|
|
44
|
+
"",
|
|
45
|
+
];
|
|
46
|
+
let total = 0;
|
|
47
|
+
for (const p of active) {
|
|
48
|
+
const position = (p.position ?? "").trim();
|
|
49
|
+
if (!position)
|
|
50
|
+
continue;
|
|
51
|
+
const clipped = position.length > PER_POSITION_CHARS ? `${position.slice(0, PER_POSITION_CHARS)}…` : position;
|
|
52
|
+
const block = `### ${speakerLabel(p.role, p.stance?.name)}\n\n${clipped}`;
|
|
53
|
+
if (total + block.length > TOTAL_CHARS) {
|
|
54
|
+
parts.push("_(remaining positions truncated)_");
|
|
55
|
+
break;
|
|
56
|
+
}
|
|
57
|
+
parts.push(block, "");
|
|
58
|
+
total += block.length;
|
|
59
|
+
}
|
|
60
|
+
// Only the header + no real positions → nothing worth persisting.
|
|
61
|
+
return parts.length > 2 ? parts.join("\n").trimEnd() : "";
|
|
62
|
+
}
|
|
63
|
+
function summarizeFromArchive(archive) {
|
|
64
|
+
if (!Array.isArray(archive) || archive.length === 0)
|
|
65
|
+
return "";
|
|
66
|
+
const parts = [
|
|
67
|
+
"_(Synthesized from per-round debate excerpts — the debate produced no running summary.)_",
|
|
68
|
+
"",
|
|
69
|
+
];
|
|
70
|
+
let total = 0;
|
|
71
|
+
for (const e of archive) {
|
|
72
|
+
const excerpt = (e.excerpt ?? "").trim();
|
|
73
|
+
if (!excerpt)
|
|
74
|
+
continue;
|
|
75
|
+
const block = `### Round ${e.round} — ${speakerLabel(e.role, e.stanceName)}\n\n${excerpt}`;
|
|
76
|
+
if (total + block.length > TOTAL_CHARS) {
|
|
77
|
+
parts.push("_(remaining excerpts truncated)_");
|
|
78
|
+
break;
|
|
79
|
+
}
|
|
80
|
+
parts.push(block, "");
|
|
81
|
+
total += block.length;
|
|
82
|
+
}
|
|
83
|
+
return parts.length > 2 ? parts.join("\n").trimEnd() : "";
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=debate-summary.js.map
|