muonroi-cli 1.8.4 → 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 +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-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 +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 +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 +234 -64
- 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/research-onboarding.js +8 -7
- package/dist/src/mcp/runtime.js +34 -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/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 +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-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 +22 -0
- package/dist/src/orchestrator/tool-engine.js +620 -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/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/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 +310 -99
- 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/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 +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 +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/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 +3 -3
- 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 +284 -13
- 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.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/install-manager.js +2 -1
- 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/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
|
@@ -4,7 +4,11 @@ import type { RoleStyle } from "./role-palette.js";
|
|
|
4
4
|
export interface CouncilMessageBubbleProps {
|
|
5
5
|
msg: CouncilMessage;
|
|
6
6
|
terminalCols: number;
|
|
7
|
-
/**
|
|
7
|
+
/**
|
|
8
|
+
* Legacy left/right pairing hint. The debate now renders as a single linear
|
|
9
|
+
* group-chat stream (WhatsApp-style), so this is ignored — kept only for
|
|
10
|
+
* call-site/back-compat. Do not reintroduce side-based alignment.
|
|
11
|
+
*/
|
|
8
12
|
side: "left" | "right";
|
|
9
13
|
/** Stable role → style resolver from useRolePalette */
|
|
10
14
|
resolveStyle: (role: string) => RoleStyle;
|
|
@@ -17,4 +21,13 @@ export interface CouncilMessageBubbleProps {
|
|
|
17
21
|
export declare function buildFooter(msg: CouncilMessage): string;
|
|
18
22
|
export declare function buildHeader(msg: CouncilMessage, style: RoleStyle): string;
|
|
19
23
|
export declare function buildQuoteLine(partnerLastText: string, partnerRole: string): string;
|
|
20
|
-
|
|
24
|
+
/**
|
|
25
|
+
* Linear group-chat message row. Every speaker renders the same way — a
|
|
26
|
+
* role-colored left bar + a bold role-colored header (`● Role · model`), the
|
|
27
|
+
* body, and a muted footer — appended in chronological order like a WhatsApp
|
|
28
|
+
* group chat. No left/right/bubble alignment: the reader follows one downward
|
|
29
|
+
* stream instead of a two-column ping-pong. The role color (from the shared
|
|
30
|
+
* palette) is the sole visual identity per speaker, so a long debate stays
|
|
31
|
+
* easy to track.
|
|
32
|
+
*/
|
|
33
|
+
export declare function CouncilMessageBubble({ msg, terminalCols, resolveStyle, partnerLastText, partnerRole, theme, }: CouncilMessageBubbleProps): import("react").ReactNode;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "@opentui/react/jsx-runtime";
|
|
2
|
-
import {
|
|
2
|
+
import { capBubbleBody } from "./bubble-body-guard.js";
|
|
3
3
|
import { truncateCodeBlocks } from "./code-block-truncate.js";
|
|
4
4
|
const MAX_QUOTE_CHARS = 80;
|
|
5
5
|
export function buildFooter(msg) {
|
|
@@ -25,23 +25,24 @@ export function buildQuoteLine(partnerLastText, partnerRole) {
|
|
|
25
25
|
const ellipsis = flat.length > MAX_QUOTE_CHARS ? "…" : "";
|
|
26
26
|
return `↪ ${partnerRole}: "${excerpt}${ellipsis}"`;
|
|
27
27
|
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
28
|
+
/**
|
|
29
|
+
* Linear group-chat message row. Every speaker renders the same way — a
|
|
30
|
+
* role-colored left bar + a bold role-colored header (`● Role · model`), the
|
|
31
|
+
* body, and a muted footer — appended in chronological order like a WhatsApp
|
|
32
|
+
* group chat. No left/right/bubble alignment: the reader follows one downward
|
|
33
|
+
* stream instead of a two-column ping-pong. The role color (from the shared
|
|
34
|
+
* palette) is the sole visual identity per speaker, so a long debate stays
|
|
35
|
+
* easy to track.
|
|
36
|
+
*/
|
|
37
|
+
export function CouncilMessageBubble({ msg, terminalCols, resolveStyle, partnerLastText, partnerRole, theme, }) {
|
|
35
38
|
const style = resolveStyle(msg.speaker.role);
|
|
36
|
-
if (layout.fallback) {
|
|
37
|
-
return _jsx(FlatDebateBubble, { msg: msg, style: style, theme: theme });
|
|
38
|
-
}
|
|
39
|
-
const isRight = side === "right";
|
|
40
|
-
const indent = isRight ? layout.rightIndent : 0;
|
|
41
39
|
const header = buildHeader(msg, style);
|
|
42
40
|
const footer = buildFooter(msg);
|
|
43
|
-
|
|
41
|
+
// Guard the terminal wrapper against a pathological body (mega single-line /
|
|
42
|
+
// 100KB+ blob) that hard-freezes the shared render+loop thread. See
|
|
43
|
+
// bubble-body-guard.ts for the live root-cause trace.
|
|
44
|
+
const bodyText = capBubbleBody(truncateCodeBlocks(msg.text.trim()), terminalCols);
|
|
44
45
|
const roundLabel = msg.round !== undefined ? `Round ${msg.round} · ` : "";
|
|
45
|
-
return (_jsxs("box", { flexDirection: "column", marginBottom: 1,
|
|
46
|
+
return (_jsxs("box", { flexDirection: "column", marginBottom: 1, border: ["left"], borderColor: style.color, paddingLeft: 2, children: [partnerLastText && partnerRole && (_jsx("text", { fg: theme.textMuted, children: buildQuoteLine(partnerLastText, partnerRole) })), _jsx("text", { fg: style.color, attributes: 1, children: header }), _jsx("text", { fg: theme.text, children: bodyText }), _jsx("text", { fg: theme.textMuted, children: `${roundLabel}${footer}` })] }));
|
|
46
47
|
}
|
|
47
48
|
//# sourceMappingURL=council-message-bubble.js.map
|
|
@@ -3,8 +3,16 @@ import type { Theme } from "../theme.js";
|
|
|
3
3
|
export interface CouncilPhaseTimelineProps {
|
|
4
4
|
phases: CouncilPhaseEvent[];
|
|
5
5
|
theme: Theme;
|
|
6
|
+
/**
|
|
7
|
+
* When false (default), completed phases fold into a single "N steps done"
|
|
8
|
+
* summary line and only the live (active/error) phase is shown — the
|
|
9
|
+
* aggressive-collapse UX. When true (Ctrl+O), the full done-trail is shown.
|
|
10
|
+
* Shares the council transcript's expand state so one toggle controls all
|
|
11
|
+
* council detail.
|
|
12
|
+
*/
|
|
13
|
+
expanded?: boolean;
|
|
6
14
|
}
|
|
7
|
-
export declare function CouncilPhaseTimeline({ phases, theme: t }: CouncilPhaseTimelineProps): import("react").ReactNode;
|
|
15
|
+
export declare function CouncilPhaseTimeline({ phases, theme: t, expanded }: CouncilPhaseTimelineProps): import("react").ReactNode;
|
|
8
16
|
/**
|
|
9
17
|
* Reducer-friendly upsert: returns the next phase array given an incoming event.
|
|
10
18
|
* Matches by phaseId; preserves insertion order for new phases. The first event
|
|
@@ -36,23 +36,57 @@ function useHeartbeat(tickMs = 1000) {
|
|
|
36
36
|
}, [tickMs]);
|
|
37
37
|
return Date.now();
|
|
38
38
|
}
|
|
39
|
-
export function CouncilPhaseTimeline({ phases, theme: t }) {
|
|
39
|
+
export function CouncilPhaseTimeline({ phases, theme: t, expanded = false }) {
|
|
40
40
|
const now = useHeartbeat(1000);
|
|
41
|
-
|
|
41
|
+
// Collapse per-round brackets: the "Clarification round N" / "Round N" phases
|
|
42
|
+
// duplicate the live status line ("Generating clarification questions (round
|
|
43
|
+
// N)"), stacking 3-4 near-identical spinner rows at council start. Keep only
|
|
44
|
+
// the coarse lifecycle phases here; round detail already rides on the status
|
|
45
|
+
// line label. Errors are always shown so a failed round stays visible.
|
|
46
|
+
const visible = phases.filter((p) => !((p.kind === "clarification_round" || p.kind === "round") && p.state !== "error"));
|
|
47
|
+
if (visible.length === 0)
|
|
42
48
|
return null;
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
49
|
+
// Aggressive collapse (default): show only the live (active/error) phases as
|
|
50
|
+
// full rows; fold every completed phase into one "N steps done" summary line.
|
|
51
|
+
// Ctrl+O (expanded=true) restores the full done-trail. Errors are never
|
|
52
|
+
// folded — a failed phase always stays visible.
|
|
53
|
+
const live = visible.filter((p) => p.state === "active" || p.state === "error");
|
|
54
|
+
const doneCount = visible.length - live.length;
|
|
55
|
+
const rows = expanded ? visible : live;
|
|
56
|
+
// Split off error phases so identical provider failures can be folded into one
|
|
57
|
+
// row instead of N repeated blocks. A flaky proxy (Console Go glm/kimi) makes
|
|
58
|
+
// clarify + spec-infer + eval all fail with the SAME message — rendered raw
|
|
59
|
+
// that spammed the (narrow) context rail. Non-error rows keep their order.
|
|
60
|
+
const nonErrorRows = rows.filter((p) => p.state !== "error");
|
|
61
|
+
const errorRows = rows.filter((p) => p.state === "error");
|
|
62
|
+
const errorGroups = [];
|
|
63
|
+
for (const p of errorRows) {
|
|
64
|
+
const message = p.errorMessage ?? "(failed)";
|
|
65
|
+
const existing = errorGroups.find((g) => g.message === message);
|
|
66
|
+
if (existing)
|
|
67
|
+
existing.phases.push(p);
|
|
68
|
+
else
|
|
69
|
+
errorGroups.push({ message, phases: [p] });
|
|
70
|
+
}
|
|
71
|
+
const renderRow = (p) => {
|
|
72
|
+
const isDone = p.state === "done";
|
|
73
|
+
const marker = isDone ? "✓" : _jsx(Spinner, {});
|
|
74
|
+
const markerColor = isDone ? t.planOptionCheck : t.accent;
|
|
75
|
+
const labelColor = isDone ? t.textMuted : t.text;
|
|
76
|
+
const liveElapsedMs = p.state === "active" && typeof p.startedAt === "number" ? Math.max(0, now - p.startedAt) : p.elapsedMs;
|
|
77
|
+
const elapsed = formatElapsed(liveElapsedMs);
|
|
78
|
+
const meta = elapsed ? ` (${elapsed})` : isDone ? "" : " …";
|
|
79
|
+
return (_jsxs("box", { flexDirection: "column", children: [_jsxs("box", { children: [_jsx("text", { fg: markerColor, children: marker }), _jsx("text", { fg: labelColor, children: ` ${p.label}` }), meta && _jsx("text", { fg: t.textDim, children: meta })] }), p.detail && (_jsx("box", { paddingLeft: 2, children: _jsx("text", { fg: t.textMuted, children: `└ ${truncate(p.detail, 100)}` }) }))] }, p.phaseId));
|
|
80
|
+
};
|
|
81
|
+
return (_jsxs("box", { flexDirection: "column", paddingLeft: 2, paddingTop: 0, flexShrink: 0, children: [!expanded && doneCount > 0 && (_jsxs("box", { children: [_jsx("text", { fg: t.planOptionCheck, children: "\u2713" }), _jsx("text", { fg: t.textDim, children: ` ${doneCount} step${doneCount === 1 ? "" : "s"} done` }), _jsx("text", { fg: t.textMuted, children: " · Ctrl+O to expand" })] })), nonErrorRows.map(renderRow), errorGroups.map((g) => {
|
|
82
|
+
// One header per unique error; when >1 phase shares it, name the count
|
|
83
|
+
// and list the affected steps compactly instead of repeating the message.
|
|
84
|
+
const first = g.phases[0];
|
|
85
|
+
const label = g.phases.length === 1
|
|
86
|
+
? first.label
|
|
87
|
+
: `${g.phases.length} steps failed: ${g.phases.map((p) => p.label).join(", ")}`;
|
|
88
|
+
return (_jsxs("box", { flexDirection: "column", children: [_jsxs("box", { children: [_jsx("text", { fg: t.diffRemovedFg, children: "\u2717" }), _jsx("text", { fg: t.diffRemovedFg, children: ` ${truncate(label, 100)}` })] }), _jsx("box", { paddingLeft: 2, children: _jsx("text", { fg: t.diffRemovedFg, children: `└ ${truncate(g.message, 100)}` }) })] }, `err-${first.phaseId}`));
|
|
89
|
+
})] }));
|
|
56
90
|
}
|
|
57
91
|
function truncate(s, max) {
|
|
58
92
|
if (s.length <= max)
|
|
@@ -2,20 +2,27 @@ import type { Theme } from "../theme.js";
|
|
|
2
2
|
export type PlaceholderVariant = "participant" | "leader";
|
|
3
3
|
export interface CouncilPlaceholderBubbleProps {
|
|
4
4
|
role: string;
|
|
5
|
+
/** Legacy pair-side hint — ignored in the linear group-chat layout. */
|
|
5
6
|
side: "left" | "right";
|
|
6
7
|
terminalCols: number;
|
|
7
8
|
color: string;
|
|
8
9
|
theme: Theme;
|
|
9
10
|
variant?: PlaceholderVariant;
|
|
11
|
+
/**
|
|
12
|
+
* Optional per-speaker context shown as muted sub-lines while composing, so the
|
|
13
|
+
* main console is not a bare spinner during the 20–60s atomic generateText
|
|
14
|
+
* window. Newline-separated "Name — lens" entries emitted by the engine in the
|
|
15
|
+
* opening/exchange `council_status.detail`. Empty/undefined → label-only.
|
|
16
|
+
*/
|
|
17
|
+
detail?: string;
|
|
10
18
|
}
|
|
11
|
-
export declare function buildPlaceholderLabel(role: string): string;
|
|
19
|
+
export declare function buildPlaceholderLabel(role: string, elapsedSec?: number): string;
|
|
12
20
|
/**
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* Swapped for the real CouncilMessageBubble
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
* - "leader": centered, leader-gray border, 40% width — matches the real leader bubble
|
|
21
|
+
* "Typing…" indicator for a speaker whose turn is in flight — a spinner + a
|
|
22
|
+
* role-colored line (`⠋ Role · composing… · 12s`) in the same linear stream as
|
|
23
|
+
* the real messages, WhatsApp-style. Swapped for the real CouncilMessageBubble
|
|
24
|
+
* when the council_message arrives. The spinner + ticking elapsed distinguish
|
|
25
|
+
* a live provider from a hung one (a static line looked identical at 2s and
|
|
26
|
+
* 2min — live-verified 2026-07-06).
|
|
20
27
|
*/
|
|
21
|
-
export declare function CouncilPlaceholderBubble({ role,
|
|
28
|
+
export declare function CouncilPlaceholderBubble({ role, color, detail, theme: t }: CouncilPlaceholderBubbleProps): import("react").ReactNode;
|
|
@@ -1,37 +1,40 @@
|
|
|
1
|
-
import { jsx as _jsx } from "@opentui/react/jsx-runtime";
|
|
2
|
-
import {
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "@opentui/react/jsx-runtime";
|
|
2
|
+
import { useEffect, useState } from "react";
|
|
3
3
|
const FALLBACK_ROLE = "Speaker";
|
|
4
|
-
const
|
|
5
|
-
export function buildPlaceholderLabel(role) {
|
|
4
|
+
const SPINNER_FRAMES = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
|
|
5
|
+
export function buildPlaceholderLabel(role, elapsedSec) {
|
|
6
6
|
const trimmed = role.trim();
|
|
7
7
|
const display = trimmed.length > 0 ? trimmed : FALLBACK_ROLE;
|
|
8
|
-
|
|
8
|
+
const elapsed = elapsedSec !== undefined && elapsedSec >= 1 ? ` · ${elapsedSec}s` : "";
|
|
9
|
+
return `${display} · composing…${elapsed}`;
|
|
9
10
|
}
|
|
10
11
|
/**
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* Swapped for the real CouncilMessageBubble
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* - "leader": centered, leader-gray border, 40% width — matches the real leader bubble
|
|
12
|
+
* "Typing…" indicator for a speaker whose turn is in flight — a spinner + a
|
|
13
|
+
* role-colored line (`⠋ Role · composing… · 12s`) in the same linear stream as
|
|
14
|
+
* the real messages, WhatsApp-style. Swapped for the real CouncilMessageBubble
|
|
15
|
+
* when the council_message arrives. The spinner + ticking elapsed distinguish
|
|
16
|
+
* a live provider from a hung one (a static line looked identical at 2s and
|
|
17
|
+
* 2min — live-verified 2026-07-06).
|
|
18
18
|
*/
|
|
19
|
-
export function CouncilPlaceholderBubble({ role,
|
|
20
|
-
const
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
19
|
+
export function CouncilPlaceholderBubble({ role, color, detail, theme: t }) {
|
|
20
|
+
const [startedAt] = useState(() => Date.now());
|
|
21
|
+
const [frame, setFrame] = useState(0);
|
|
22
|
+
useEffect(() => {
|
|
23
|
+
// The 100ms spinner interval doubles as the elapsed re-render tick — no
|
|
24
|
+
// second timer needed. Braille frames match the timeline/pill spinner
|
|
25
|
+
// vocabulary rather than adding a third glyph set.
|
|
26
|
+
const id = setInterval(() => setFrame((n) => n + 1), 100);
|
|
27
|
+
return () => clearInterval(id);
|
|
28
|
+
}, []);
|
|
29
|
+
const elapsedSec = Math.floor((Date.now() - startedAt) / 1000);
|
|
30
|
+
// Split the engine-emitted roster ("Name — lens" per line) into muted preview
|
|
31
|
+
// rows. Trimmed + non-empty only so a trailing newline never renders a blank.
|
|
32
|
+
const detailLines = detail
|
|
33
|
+
? detail
|
|
34
|
+
.split("\n")
|
|
35
|
+
.map((l) => l.trim())
|
|
36
|
+
.filter((l) => l.length > 0)
|
|
37
|
+
: [];
|
|
38
|
+
return (_jsxs("box", { marginBottom: 1, paddingLeft: 2, flexDirection: "column", children: [_jsxs("box", { children: [_jsx("text", { fg: t.accent, children: `${SPINNER_FRAMES[frame % SPINNER_FRAMES.length]} ` }), _jsx("text", { fg: color, children: buildPlaceholderLabel(role, elapsedSec) })] }), detailLines.map((line, i) => (_jsx("text", { fg: t.textMuted, children: ` ↳ ${line}` }, i)))] }));
|
|
36
39
|
}
|
|
37
40
|
//# sourceMappingURL=council-placeholder-bubble.js.map
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "@opentui/react/jsx-runtime";
|
|
2
2
|
import { Semantic } from "@muonroi/agent-harness-opentui";
|
|
3
3
|
const PHASE_LABEL = {
|
|
4
|
-
clarify: "
|
|
5
|
-
preflight: "Pre-flight",
|
|
6
|
-
"plan-confirm": "Plan",
|
|
7
|
-
"post-debate": "
|
|
8
|
-
"pil-interview": "Understanding",
|
|
9
|
-
"pil-acceptance": "Confirm
|
|
10
|
-
"tool-loop-cap": "Tool-loop
|
|
11
|
-
"safety-override": "Safety
|
|
4
|
+
clarify: "Quick question",
|
|
5
|
+
preflight: "Pre-flight check",
|
|
6
|
+
"plan-confirm": "Plan review",
|
|
7
|
+
"post-debate": "Debate wrap-up",
|
|
8
|
+
"pil-interview": "Understanding your idea",
|
|
9
|
+
"pil-acceptance": "Confirm the goal",
|
|
10
|
+
"tool-loop-cap": "Tool-loop checkpoint",
|
|
11
|
+
"safety-override": "Safety check",
|
|
12
12
|
};
|
|
13
13
|
/**
|
|
14
14
|
* AskUserQuestion-style card. Controlled component — parent owns the state
|
|
@@ -32,8 +32,8 @@ export function CouncilQuestionCard({ question, theme: t, state, freetextInputWi
|
|
|
32
32
|
const cursor = selected ? "›" : " ";
|
|
33
33
|
const numberColor = selected ? t.accent : t.textMuted;
|
|
34
34
|
const labelColor = selected ? t.accent : t.text;
|
|
35
|
-
return (_jsx(Semantic, { id: `askcard-option-${opt.value ?? i}`, role: "button", name: opt.label, selected: selected || undefined, children: _jsxs("box", { flexDirection: "column", children: [_jsxs("box", { flexDirection: "row", children: [_jsx("text", { fg: numberColor, children: `${cursor} ${i + 1}. ` }), _jsx("text", { fg: labelColor, children: opt.label }), isRecommended && _jsx("text", { fg: t.planOptionCheck, children: " (
|
|
36
|
-
}), freetext !== null && (_jsxs("box", { flexDirection: "column", paddingTop: 1, children: [_jsx("text", { fg: t.textMuted, children: "Type your answer · Enter to
|
|
35
|
+
return (_jsx(Semantic, { id: `askcard-option-${opt.value ?? i}`, role: "button", name: opt.label, selected: selected || undefined, children: _jsxs("box", { flexDirection: "column", children: [_jsxs("box", { flexDirection: "row", children: [_jsx("text", { fg: numberColor, children: `${cursor} ${i + 1}. ` }), _jsx("text", { fg: labelColor, children: opt.label }), isRecommended && _jsx("text", { fg: t.planOptionCheck, children: " (recommended)" })] }), opt.description && (_jsx("box", { paddingLeft: 5, children: _jsx("text", { fg: t.textMuted, children: opt.description }) }))] }) }, i));
|
|
36
|
+
}), freetext !== null && (_jsxs("box", { flexDirection: "column", paddingTop: 1, children: [_jsx("text", { fg: t.textMuted, children: "Type your answer · Enter to send · Esc to go back" }), _jsx(Semantic, { id: "askcard-input", role: "textbox", value: freetext, children: _jsx("box", { paddingLeft: 1, paddingRight: 1, width: freetextInputWidth, children: _jsx("text", { fg: t.planInputText, bg: t.planInputBg, children: freetext.length > 0 ? freetext : " " }) }) })] })), _jsx("box", { paddingTop: 1, children: _jsx("text", { fg: t.textDim, children: "↑/↓ to browse · Enter to select · Esc to cancel" }) })] }) }));
|
|
37
37
|
}
|
|
38
38
|
export function clampIndex(i, len) {
|
|
39
39
|
if (len <= 0)
|
|
@@ -50,7 +50,7 @@ function legacyFallback(q) {
|
|
|
50
50
|
.filter((s) => typeof s === "string" && s.trim().length > 0)
|
|
51
51
|
.map((s) => ({ label: s.trim(), value: s.trim(), kind: "choice" }));
|
|
52
52
|
if (choices.length === 0) {
|
|
53
|
-
choices.push({ label: "Answer", value: "", kind: "freetext", description: "
|
|
53
|
+
choices.push({ label: "Answer", value: "", kind: "freetext", description: "Type your answer here" });
|
|
54
54
|
}
|
|
55
55
|
return choices;
|
|
56
56
|
}
|
|
@@ -116,7 +116,7 @@ export function reduceCardKey(question, state, key) {
|
|
|
116
116
|
// Sentinel-ish text: caller may special-case this prefix to pause
|
|
117
117
|
// the council loop. For now we ship a clear default that records a
|
|
118
118
|
// meaningful answer so the run keeps moving.
|
|
119
|
-
text: "
|
|
119
|
+
text: "I'd like to talk this through a bit more before answering.",
|
|
120
120
|
kind: "chat",
|
|
121
121
|
},
|
|
122
122
|
},
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { CouncilRoundRecord } from "../../types/index.js";
|
|
2
|
+
import type { Theme } from "../theme.js";
|
|
3
|
+
/**
|
|
4
|
+
* Selectable round list in the context rail (P2 / feature D). The rail keeps its
|
|
5
|
+
* GLOBAL overview; this list lets the user scope the MAIN transcript pane to a
|
|
6
|
+
* single round's debate turns without hiding the overview — reconciling the
|
|
7
|
+
* documented "never re-scope the rail" constraint (context-rail.tsx) with the
|
|
8
|
+
* "click a round → see its debate" request.
|
|
9
|
+
*
|
|
10
|
+
* Selection is driven by keyboard (Ctrl+←/→ when the composer is empty) and by
|
|
11
|
+
* mouse (OpenTUI onMouseDown per row). `null` = global view (all/live rounds).
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* Pure selection-cycle used by the keyboard handler. Stepping before the first
|
|
15
|
+
* round returns to the global view (null); stepping past the last clamps.
|
|
16
|
+
*/
|
|
17
|
+
export declare function cycleRoundSelection(roundNumbers: number[], current: number | null, dir: 1 | -1): number | null;
|
|
18
|
+
export interface CouncilRailRoundsProps {
|
|
19
|
+
rounds: CouncilRoundRecord[];
|
|
20
|
+
/** Selected round number, or null for the global (all-rounds) view. */
|
|
21
|
+
selected: number | null;
|
|
22
|
+
onSelect: (round: number | null) => void;
|
|
23
|
+
width: number;
|
|
24
|
+
theme: Theme;
|
|
25
|
+
}
|
|
26
|
+
export declare function CouncilRailRounds({ rounds, selected, onSelect, width, theme }: CouncilRailRoundsProps): import("react").ReactNode;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "@opentui/react/jsx-runtime";
|
|
2
|
+
import { Semantic } from "@muonroi/agent-harness-opentui";
|
|
3
|
+
/**
|
|
4
|
+
* Selectable round list in the context rail (P2 / feature D). The rail keeps its
|
|
5
|
+
* GLOBAL overview; this list lets the user scope the MAIN transcript pane to a
|
|
6
|
+
* single round's debate turns without hiding the overview — reconciling the
|
|
7
|
+
* documented "never re-scope the rail" constraint (context-rail.tsx) with the
|
|
8
|
+
* "click a round → see its debate" request.
|
|
9
|
+
*
|
|
10
|
+
* Selection is driven by keyboard (Ctrl+←/→ when the composer is empty) and by
|
|
11
|
+
* mouse (OpenTUI onMouseDown per row). `null` = global view (all/live rounds).
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* Pure selection-cycle used by the keyboard handler. Stepping before the first
|
|
15
|
+
* round returns to the global view (null); stepping past the last clamps.
|
|
16
|
+
*/
|
|
17
|
+
export function cycleRoundSelection(roundNumbers, current, dir) {
|
|
18
|
+
if (roundNumbers.length === 0)
|
|
19
|
+
return null;
|
|
20
|
+
if (current === null)
|
|
21
|
+
return dir === 1 ? roundNumbers[0] : null;
|
|
22
|
+
const i = roundNumbers.indexOf(current);
|
|
23
|
+
if (i === -1)
|
|
24
|
+
return dir === 1 ? roundNumbers[0] : null;
|
|
25
|
+
const j = i + dir;
|
|
26
|
+
if (j < 0)
|
|
27
|
+
return null; // step before first → global
|
|
28
|
+
if (j >= roundNumbers.length)
|
|
29
|
+
return roundNumbers[roundNumbers.length - 1]; // clamp at last
|
|
30
|
+
return roundNumbers[j];
|
|
31
|
+
}
|
|
32
|
+
function roundLabel(rec, maxWidth) {
|
|
33
|
+
const base = `Round ${rec.round}`;
|
|
34
|
+
if (!rec.topic)
|
|
35
|
+
return base;
|
|
36
|
+
const budget = Math.max(6, maxWidth - base.length - 3);
|
|
37
|
+
const topic = rec.topic.length > budget ? `${rec.topic.slice(0, budget - 1)}…` : rec.topic;
|
|
38
|
+
return `${base}: ${topic}`;
|
|
39
|
+
}
|
|
40
|
+
export function CouncilRailRounds({ rounds, selected, onSelect, width, theme }) {
|
|
41
|
+
if (rounds.length === 0)
|
|
42
|
+
return null;
|
|
43
|
+
const rows = [
|
|
44
|
+
{ key: "all", label: "All rounds", round: null, running: false },
|
|
45
|
+
...rounds.map((rec) => ({
|
|
46
|
+
key: `round-${rec.round}`,
|
|
47
|
+
label: roundLabel(rec, width),
|
|
48
|
+
round: rec.round,
|
|
49
|
+
running: rec.state === "running",
|
|
50
|
+
})),
|
|
51
|
+
];
|
|
52
|
+
return (_jsx(Semantic, { id: "rail-rounds", role: "listbox", name: "Debate rounds", props: { selected: selected ?? -1, count: rounds.length }, children: _jsxs("box", { flexDirection: "column", flexShrink: 0, marginTop: 1, children: [_jsx("text", { fg: theme.textMuted, attributes: 1, children: "Rounds" }), _jsx("text", { fg: theme.textDim, children: "ctrl+\u2190/\u2192 scope" }), rows.map((row) => {
|
|
53
|
+
const isSel = row.round === selected || (row.round === null && selected === null);
|
|
54
|
+
return (_jsx(Semantic, { id: row.round === null ? "rail-round-all" : `rail-round-${row.round}`, role: "listitem", name: row.label, selected: isSel || undefined, children: _jsxs("box", { flexDirection: "row", onMouseDown: () => onSelect(row.round), children: [_jsx("text", { fg: isSel ? theme.accent : theme.textMuted, children: isSel ? "› " : " " }), _jsx("text", { fg: isSel ? theme.accent : theme.text, attributes: isSel ? 1 : 0, children: row.label }), row.running ? _jsx("text", { fg: theme.accent, children: " ·live" }) : null] }) }, row.key));
|
|
55
|
+
})] }) }));
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=council-rail-rounds.js.map
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
import type { CouncilRoundRecord } from "../../types/index.js";
|
|
3
|
+
import type { Theme } from "../theme.js";
|
|
4
|
+
export interface CouncilRoundGroupProps {
|
|
5
|
+
record: CouncilRoundRecord;
|
|
6
|
+
/**
|
|
7
|
+
* Turn nodes for this round. Rendered while the round is running (live stream)
|
|
8
|
+
* OR when the round is selected in the rail (inspect a finished round's debate).
|
|
9
|
+
*/
|
|
10
|
+
children?: ReactNode;
|
|
11
|
+
/** True when this round is the one selected in the rail — highlight + expand. */
|
|
12
|
+
selected?: boolean;
|
|
13
|
+
theme: Theme;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* F2 — header that frames a DONE round's persisted directive as its *opening*
|
|
17
|
+
* brief. Without it the directive's "Unmet (n/m)" line reads as current state and
|
|
18
|
+
* contradicts the "✓ Outcome: m/m met" line below on a converged round. When the
|
|
19
|
+
* round met everything, say so ("resolved below") so brief + outcome cohere.
|
|
20
|
+
*/
|
|
21
|
+
export declare function openingBriefHeader(allMet: boolean): string;
|
|
22
|
+
/**
|
|
23
|
+
* One debate round in the round-grouped transcript (P6). The running round auto-
|
|
24
|
+
* opens and streams its turns live; a done round collapses to an expanded-inline
|
|
25
|
+
* summary — input (topic + members), outcome (criteria met/total), and the
|
|
26
|
+
* leader's decision — so a finished round always shows what it achieved instead
|
|
27
|
+
* of a bare "done". When `selected` (P2/D — the round chosen in the rail), a
|
|
28
|
+
* finished round also expands its debate turns and highlights.
|
|
29
|
+
*/
|
|
30
|
+
export declare function CouncilRoundGroup({ record, children, selected, theme }: CouncilRoundGroupProps): ReactNode;
|
|
31
|
+
export interface CouncilRoundsOverviewProps {
|
|
32
|
+
rounds: CouncilRoundRecord[];
|
|
33
|
+
theme: Theme;
|
|
34
|
+
/** Optional session id appended to the overview so it stays visible above the debate transcript. */
|
|
35
|
+
sessionId?: string;
|
|
36
|
+
}
|
|
37
|
+
/** One-line overview above the round groups: totals + emergent count + session id. */
|
|
38
|
+
export declare function CouncilRoundsOverview({ rounds, theme, sessionId }: CouncilRoundsOverviewProps): ReactNode;
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "@opentui/react/jsx-runtime";
|
|
2
|
+
import { Semantic } from "@muonroi/agent-harness-opentui";
|
|
3
|
+
const DECISION_LABEL = {
|
|
4
|
+
continue: "continue",
|
|
5
|
+
stop: "sufficient — stop",
|
|
6
|
+
extend: "extend (emergent round)",
|
|
7
|
+
aborted: "aborted",
|
|
8
|
+
"circuit-break": "circuit breaker",
|
|
9
|
+
"eval-unavailable": "evaluation unavailable",
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* F2 — header that frames a DONE round's persisted directive as its *opening*
|
|
13
|
+
* brief. Without it the directive's "Unmet (n/m)" line reads as current state and
|
|
14
|
+
* contradicts the "✓ Outcome: m/m met" line below on a converged round. When the
|
|
15
|
+
* round met everything, say so ("resolved below") so brief + outcome cohere.
|
|
16
|
+
*/
|
|
17
|
+
export function openingBriefHeader(allMet) {
|
|
18
|
+
return `Opening brief${allMet ? " — resolved below" : ""}:`;
|
|
19
|
+
}
|
|
20
|
+
/** Color the leader's decision by whether the round landed well. */
|
|
21
|
+
function decisionColor(decision, theme) {
|
|
22
|
+
switch (decision) {
|
|
23
|
+
case "stop":
|
|
24
|
+
return theme.diffAddedFg; // sufficient — a clean landing
|
|
25
|
+
case "aborted":
|
|
26
|
+
case "circuit-break":
|
|
27
|
+
case "eval-unavailable":
|
|
28
|
+
return theme.diffRemovedFg; // ended abnormally
|
|
29
|
+
default:
|
|
30
|
+
return theme.accent; // continue / extend — still in progress
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* One debate round in the round-grouped transcript (P6). The running round auto-
|
|
35
|
+
* opens and streams its turns live; a done round collapses to an expanded-inline
|
|
36
|
+
* summary — input (topic + members), outcome (criteria met/total), and the
|
|
37
|
+
* leader's decision — so a finished round always shows what it achieved instead
|
|
38
|
+
* of a bare "done". When `selected` (P2/D — the round chosen in the rail), a
|
|
39
|
+
* finished round also expands its debate turns and highlights.
|
|
40
|
+
*/
|
|
41
|
+
export function CouncilRoundGroup({ record, children, selected = false, theme }) {
|
|
42
|
+
const running = record.state === "running";
|
|
43
|
+
const headParts = [`Round ${record.round}`];
|
|
44
|
+
if (record.topic)
|
|
45
|
+
headParts.push(record.topic);
|
|
46
|
+
if (record.emergent)
|
|
47
|
+
headParts.push("(emergent)");
|
|
48
|
+
// Outcome verdict: how many acceptance criteria the round met. Colored + marked
|
|
49
|
+
// so a scan of the transcript shows at a glance which rounds landed cleanly.
|
|
50
|
+
const total = record.criteriaTotal ?? -1;
|
|
51
|
+
const met = record.criteriaMet ?? 0;
|
|
52
|
+
const hasCriteria = total > 0;
|
|
53
|
+
const allMet = hasCriteria && met >= total;
|
|
54
|
+
const noneMet = hasCriteria && met === 0;
|
|
55
|
+
const outcomeColor = allMet ? theme.diffAddedFg : noneMet ? theme.diffRemovedFg : theme.mdItalic;
|
|
56
|
+
const outcomeMark = allMet ? "✓" : noneMet ? "✗" : "◐";
|
|
57
|
+
return (_jsx(Semantic, { id: `council-round-${record.round}`, role: "region", name: `Round ${record.round}`, props: {
|
|
58
|
+
state: record.state,
|
|
59
|
+
emergent: record.emergent,
|
|
60
|
+
selected,
|
|
61
|
+
criteriaMet: record.criteriaMet ?? -1,
|
|
62
|
+
criteriaTotal: record.criteriaTotal ?? -1,
|
|
63
|
+
decision: record.leaderDecision ?? "",
|
|
64
|
+
directive: record.directive ?? "",
|
|
65
|
+
}, children: _jsxs("box", { flexDirection: "column", marginBottom: 1, border: ["left"], borderColor: running || selected ? theme.accent : theme.councilLeaderBorder, paddingLeft: 2, children: [_jsx("text", { fg: running || selected ? theme.accent : theme.textMuted, attributes: 1, children: `${running ? "> " : selected ? "› " : "✓ "}${headParts.join(" · ")}` }), record.participants.length > 0 && (_jsx("text", { fg: theme.textMuted, children: `${record.participants.length} members: ${record.participants.join(", ")}` })), running ? (
|
|
66
|
+
// Running round streams its turns live.
|
|
67
|
+
_jsx("box", { flexDirection: "column", marginTop: 1, children: children })) : (
|
|
68
|
+
// Done round: expanded debate turns (when selected in the rail) followed
|
|
69
|
+
// by the outcome verdict + leader decision summary.
|
|
70
|
+
_jsxs("box", { flexDirection: "column", children: [children ? (_jsx("box", { flexDirection: "column", marginTop: 1, marginBottom: 1, children: children })) : null, record.directive && _jsx("text", { fg: theme.textMuted, children: openingBriefHeader(allMet) }), record.directive &&
|
|
71
|
+
record.directive.split("\n").map((line, i) => (_jsx("text", { fg: theme.accent, attributes: i === 0 ? 1 : 0, children: i === 0 ? `▶ ${line}` : ` ${line}` }, `dir-${i}`))), hasCriteria && (_jsx("text", { fg: outcomeColor, attributes: 1, children: `${outcomeMark} Outcome: ${met}/${total} criteria met` })), record.leaderDecision && (_jsx("text", { fg: decisionColor(record.leaderDecision, theme), attributes: 1, children: `Decision: ${DECISION_LABEL[record.leaderDecision]}` })), record.leaderReason && _jsx("text", { fg: theme.textMuted, children: record.leaderReason }), record.nextRoundFocus && _jsx("text", { fg: theme.textMuted, children: `Next focus: ${record.nextRoundFocus}` })] }))] }) }));
|
|
72
|
+
}
|
|
73
|
+
/** One-line overview above the round groups: totals + emergent count + session id. */
|
|
74
|
+
export function CouncilRoundsOverview({ rounds, theme, sessionId }) {
|
|
75
|
+
const total = rounds.length;
|
|
76
|
+
const emergent = rounds.filter((r) => r.emergent).length;
|
|
77
|
+
const members = new Set();
|
|
78
|
+
for (const r of rounds)
|
|
79
|
+
for (const p of r.participants)
|
|
80
|
+
members.add(p);
|
|
81
|
+
const parts = [`Debate: ${total} round${total === 1 ? "" : "s"}`, `${members.size} members`];
|
|
82
|
+
if (emergent > 0)
|
|
83
|
+
parts.push(`${emergent} emergent`);
|
|
84
|
+
if (sessionId)
|
|
85
|
+
parts.push(`session ${sessionId}`);
|
|
86
|
+
return (_jsx(Semantic, { id: "council-rounds-overview", role: "region", props: { total, emergent, members: members.size, sessionId }, children: _jsx("text", { fg: theme.textMuted, attributes: 1, children: parts.join(" · ") }) }));
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=council-round-group.js.map
|
|
@@ -3,8 +3,10 @@ import type { Theme } from "../theme.js";
|
|
|
3
3
|
export interface CouncilStatusListProps {
|
|
4
4
|
statuses: CouncilStatusData[];
|
|
5
5
|
theme: Theme;
|
|
6
|
+
/** Optional session id rendered as a pinned header so the user can correlate a council run with its session. */
|
|
7
|
+
sessionId?: string;
|
|
6
8
|
}
|
|
7
|
-
export declare function CouncilStatusList({ statuses, theme: t }: CouncilStatusListProps): import("react").ReactNode;
|
|
9
|
+
export declare function CouncilStatusList({ statuses, theme: t, sessionId }: CouncilStatusListProps): import("react").ReactNode;
|
|
8
10
|
/**
|
|
9
11
|
* Reducer-friendly upsert: returns the next status array given an incoming
|
|
10
12
|
* status chunk. Done statuses are kept until DONE_HOLD_MS expires (caller
|