muonroi-cli 1.8.4 → 1.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +17 -5
- package/dist/packages/agent-harness-core/src/driver.d.ts +27 -1
- package/dist/packages/agent-harness-core/src/driver.js +46 -0
- package/dist/packages/agent-harness-core/src/event-filter.js +11 -0
- package/dist/packages/agent-harness-core/src/event-redact.js +7 -0
- package/dist/packages/agent-harness-core/src/event-tee.d.ts +64 -0
- package/dist/packages/agent-harness-core/src/event-tee.js +104 -0
- package/dist/packages/agent-harness-core/src/mcp-server.d.ts +25 -0
- package/dist/packages/agent-harness-core/src/mcp-server.js +169 -21
- package/dist/packages/agent-harness-core/src/predicate.d.ts +1 -1
- package/dist/packages/agent-harness-core/src/protocol.d.ts +90 -4
- package/dist/packages/agent-harness-core/src/protocol.js +15 -0
- package/dist/packages/agent-harness-core/src/visual-quality.d.ts +58 -0
- package/dist/packages/agent-harness-core/src/visual-quality.js +141 -0
- package/dist/packages/agent-harness-opentui/src/agent-mode.d.ts +6 -0
- package/dist/packages/agent-harness-opentui/src/agent-mode.js +14 -1
- package/dist/packages/agent-harness-opentui/src/input-bridge.d.ts +2 -10
- package/dist/packages/agent-harness-opentui/src/input-bridge.js +103 -16
- package/dist/packages/agent-harness-opentui/src/install.d.ts +8 -0
- package/dist/packages/agent-harness-opentui/src/install.js +10 -0
- package/dist/packages/agent-harness-opentui/src/semantic.js +12 -10
- package/dist/packages/agent-harness-opentui/src/visual-capture.d.ts +56 -0
- package/dist/packages/agent-harness-opentui/src/visual-capture.js +103 -0
- package/dist/src/agent-harness/mock-model.d.ts +38 -0
- package/dist/src/agent-harness/mock-model.js +69 -3
- package/dist/src/agent-harness/test-spawn.js +31 -0
- package/dist/src/chat/chat-keychain.d.ts +7 -12
- package/dist/src/chat/chat-keychain.js +19 -86
- package/dist/src/cli/config/screen-providers.js +1 -1
- package/dist/src/cli/cost-forensics.d.ts +10 -0
- package/dist/src/cli/cost-forensics.js +18 -3
- package/dist/src/cli/keys-bundle.d.ts +1 -1
- package/dist/src/cli/keys-bundle.js +1 -1
- package/dist/src/cli/keys.d.ts +10 -47
- package/dist/src/cli/keys.js +31 -399
- package/dist/src/council/clarifier.d.ts +31 -3
- package/dist/src/council/clarifier.js +220 -32
- package/dist/src/council/context.js +49 -15
- package/dist/src/council/debate-checkpoint.d.ts +129 -0
- package/dist/src/council/debate-checkpoint.js +176 -0
- package/dist/src/council/debate-planner.js +54 -5
- package/dist/src/council/debate-summary.d.ts +25 -0
- package/dist/src/council/debate-summary.js +85 -0
- package/dist/src/council/debate.d.ts +169 -2
- package/dist/src/council/debate.js +1265 -135
- package/dist/src/council/index.d.ts +108 -1
- package/dist/src/council/index.js +670 -197
- package/dist/src/council/leader.d.ts +26 -0
- package/dist/src/council/leader.js +150 -9
- package/dist/src/council/llm.d.ts +94 -0
- package/dist/src/council/llm.js +348 -55
- package/dist/src/council/panel-select.d.ts +30 -0
- package/dist/src/council/panel-select.js +82 -0
- package/dist/src/council/planner.js +40 -0
- package/dist/src/council/preflight.d.ts +17 -0
- package/dist/src/council/preflight.js +50 -2
- package/dist/src/council/prompts.d.ts +39 -4
- package/dist/src/council/prompts.js +256 -69
- package/dist/src/council/stance-recall.d.ts +42 -0
- package/dist/src/council/stance-recall.js +57 -0
- package/dist/src/council/strip-think.d.ts +17 -0
- package/dist/src/council/strip-think.js +33 -0
- package/dist/src/council/types.d.ts +138 -0
- package/dist/src/ee/artifact-cache.d.ts +16 -0
- package/dist/src/ee/artifact-cache.js +32 -0
- package/dist/src/ee/auth.d.ts +20 -0
- package/dist/src/ee/auth.js +54 -2
- package/dist/src/ee/bridge.d.ts +10 -0
- package/dist/src/ee/bridge.js +58 -0
- package/dist/src/ee/client.js +109 -21
- package/dist/src/ee/ee-onboarding.js +6 -26
- package/dist/src/ee/export-transcripts.d.ts +1 -0
- package/dist/src/ee/export-transcripts.js +8 -10
- package/dist/src/ee/extract-session.js +29 -0
- package/dist/src/ee/extract-style.d.ts +58 -0
- package/dist/src/ee/extract-style.js +270 -0
- package/dist/src/ee/recall-ledger.d.ts +9 -0
- package/dist/src/ee/recall-ledger.js +3 -0
- package/dist/src/ee/scope.d.ts +1 -0
- package/dist/src/ee/scope.js +26 -1
- package/dist/src/ee/search.d.ts +7 -0
- package/dist/src/ee/search.js +24 -0
- package/dist/src/ee/transcript-emit.js +2 -0
- package/dist/src/ee/types.d.ts +22 -0
- package/dist/src/ee/who-am-i-brain.d.ts +35 -0
- package/dist/src/ee/who-am-i-brain.js +220 -0
- package/dist/src/ee/who-am-i.d.ts +10 -3
- package/dist/src/ee/who-am-i.js +12 -0
- package/dist/src/ee/workflow-event.d.ts +48 -0
- package/dist/src/ee/workflow-event.js +81 -0
- package/dist/src/flow/compaction/compress.d.ts +3 -3
- package/dist/src/flow/compaction/compress.js +58 -8
- package/dist/src/flow/compaction/extract.d.ts +4 -7
- package/dist/src/flow/compaction/extract.js +50 -10
- package/dist/src/flow/compaction/index.d.ts +14 -1
- package/dist/src/flow/compaction/index.js +96 -3
- package/dist/src/flow/compaction/input-guard.d.ts +24 -0
- package/dist/src/flow/compaction/input-guard.js +43 -0
- package/dist/src/flow/compaction/progress.d.ts +35 -0
- package/dist/src/flow/compaction/progress.js +35 -0
- package/dist/src/flow/fold-planning.d.ts +36 -0
- package/dist/src/flow/fold-planning.js +83 -0
- package/dist/src/flow/hierarchy.d.ts +146 -0
- package/dist/src/flow/hierarchy.js +427 -0
- package/dist/src/flow/index.d.ts +1 -0
- package/dist/src/flow/index.js +2 -0
- package/dist/src/flow/run-artifacts.d.ts +102 -0
- package/dist/src/flow/run-artifacts.js +208 -0
- package/dist/src/generated/version.d.ts +1 -1
- package/dist/src/generated/version.js +1 -1
- package/dist/src/gsd/assessment-schema.d.ts +44 -0
- package/dist/src/gsd/assessment-schema.js +134 -0
- package/dist/src/gsd/capability-registry.d.ts +45 -0
- package/dist/src/gsd/capability-registry.js +337 -0
- package/dist/src/gsd/complexity-assessor.d.ts +39 -0
- package/dist/src/gsd/complexity-assessor.js +152 -0
- package/dist/src/gsd/config-bridge.d.ts +7 -0
- package/dist/src/gsd/config-bridge.js +114 -0
- package/dist/src/gsd/config-loader.d.ts +27 -0
- package/dist/src/gsd/config-loader.js +50 -0
- package/dist/src/gsd/council-context.d.ts +44 -0
- package/dist/src/gsd/council-context.js +114 -0
- package/dist/src/gsd/ee-closure.d.ts +28 -0
- package/dist/src/gsd/ee-closure.js +49 -0
- package/dist/src/gsd/flags.d.ts +66 -0
- package/dist/src/gsd/flags.js +102 -0
- package/dist/src/gsd/gsd-dispatch.d.ts +58 -0
- package/dist/src/gsd/gsd-dispatch.js +131 -0
- package/dist/src/gsd/gsd-runtime.d.ts +22 -0
- package/dist/src/gsd/gsd-runtime.js +37 -0
- package/dist/src/gsd/host-adapter.d.ts +11 -0
- package/dist/src/gsd/host-adapter.js +29 -0
- package/dist/src/gsd/index.d.ts +24 -1
- package/dist/src/gsd/index.js +27 -0
- package/dist/src/gsd/loop-host-contract.d.ts +21 -0
- package/dist/src/gsd/loop-host-contract.js +39 -0
- package/dist/src/gsd/loop-host.d.ts +69 -0
- package/dist/src/gsd/loop-host.js +245 -0
- package/dist/src/gsd/loop-resolver.d.ts +36 -0
- package/dist/src/gsd/loop-resolver.js +79 -0
- package/dist/src/gsd/model-tier.d.ts +13 -0
- package/dist/src/gsd/model-tier.js +45 -0
- package/dist/src/gsd/mutation-gate.d.ts +16 -0
- package/dist/src/gsd/mutation-gate.js +41 -0
- package/dist/src/gsd/native-roadmap.d.ts +89 -0
- package/dist/src/gsd/native-roadmap.js +343 -0
- package/dist/src/gsd/native-state.d.ts +47 -0
- package/dist/src/gsd/native-state.js +220 -0
- package/dist/src/gsd/paths.d.ts +23 -0
- package/dist/src/gsd/paths.js +66 -0
- package/dist/src/gsd/phase-dag.d.ts +12 -0
- package/dist/src/gsd/phase-dag.js +94 -0
- package/dist/src/gsd/phase-sync.d.ts +42 -0
- package/dist/src/gsd/phase-sync.js +321 -0
- package/dist/src/gsd/pil-gate-context.d.ts +13 -0
- package/dist/src/gsd/pil-gate-context.js +64 -0
- package/dist/src/gsd/pil-gate-critic.d.ts +19 -0
- package/dist/src/gsd/pil-gate-critic.js +74 -0
- package/dist/src/gsd/plan-council-prompts.d.ts +25 -0
- package/dist/src/gsd/plan-council-prompts.js +79 -0
- package/dist/src/gsd/plan-council.d.ts +44 -0
- package/dist/src/gsd/plan-council.js +283 -0
- package/dist/src/gsd/plan-gate-vocabulary.d.ts +40 -0
- package/dist/src/gsd/plan-gate-vocabulary.js +64 -0
- package/dist/src/gsd/product-workspace.d.ts +13 -0
- package/dist/src/gsd/product-workspace.js +124 -0
- package/dist/src/gsd/ship-bridge.d.ts +25 -0
- package/dist/src/gsd/ship-bridge.js +65 -0
- package/dist/src/gsd/state-document.d.ts +40 -0
- package/dist/src/gsd/state-document.js +163 -0
- package/dist/src/gsd/verdict-schema.d.ts +39 -0
- package/dist/src/gsd/verdict-schema.js +144 -0
- package/dist/src/gsd/verify-context.d.ts +22 -0
- package/dist/src/gsd/verify-context.js +27 -0
- package/dist/src/gsd/verify-council-prompts.d.ts +19 -0
- package/dist/src/gsd/verify-council-prompts.js +85 -0
- package/dist/src/gsd/verify-council.d.ts +25 -0
- package/dist/src/gsd/verify-council.js +119 -0
- package/dist/src/gsd/verify-gate-vocabulary.d.ts +25 -0
- package/dist/src/gsd/verify-gate-vocabulary.js +46 -0
- package/dist/src/gsd/workflow-engine.d.ts +60 -0
- package/dist/src/gsd/workflow-engine.js +207 -0
- package/dist/src/gsd/workflow-tools.d.ts +13 -0
- package/dist/src/gsd/workflow-tools.js +277 -0
- package/dist/src/headless/council-answers.js +4 -0
- package/dist/src/hooks/index.js +1 -1
- package/dist/src/index.js +172 -270
- package/dist/src/lsp/builtins.js +3 -1
- package/dist/src/lsp/manager.d.ts +5 -1
- package/dist/src/lsp/manager.js +249 -3
- package/dist/src/lsp/npm-cache.d.ts +11 -1
- package/dist/src/lsp/npm-cache.js +17 -1
- package/dist/src/lsp/runtime.d.ts +6 -1
- package/dist/src/lsp/runtime.js +17 -1
- package/dist/src/lsp/types.d.ts +83 -1
- package/dist/src/lsp/types.js +10 -0
- package/dist/src/maintain/pr-builder.js +23 -13
- package/dist/src/mcp/auto-setup.js +57 -32
- package/dist/src/mcp/client-pool.js +44 -16
- package/dist/src/mcp/lsp-tools.d.ts +5 -1
- package/dist/src/mcp/lsp-tools.js +93 -2
- package/dist/src/mcp/mcp-keychain.d.ts +3 -5
- package/dist/src/mcp/mcp-keychain.js +9 -49
- package/dist/src/mcp/research-onboarding.js +8 -7
- package/dist/src/mcp/runtime.js +34 -2
- package/dist/src/mcp/setup-guide-text.d.ts +1 -1
- package/dist/src/mcp/setup-guide-text.js +22 -2
- package/dist/src/mcp/tools-server.d.ts +10 -0
- package/dist/src/mcp/tools-server.js +10 -2
- package/dist/src/models/catalog-client.d.ts +87 -0
- package/dist/src/models/catalog-client.js +105 -38
- package/dist/src/models/catalog.json +528 -265
- package/dist/src/models/registry.d.ts +22 -7
- package/dist/src/models/registry.js +73 -10
- package/dist/src/ops/doctor.js +1 -1
- package/dist/src/orchestrator/ask-user.d.ts +61 -0
- package/dist/src/orchestrator/ask-user.js +65 -0
- package/dist/src/orchestrator/auto-commit.js +1 -1
- package/dist/src/orchestrator/batch-turn-runner.js +2 -2
- package/dist/src/orchestrator/cache-prefix.d.ts +67 -0
- package/dist/src/orchestrator/cache-prefix.js +83 -0
- package/dist/src/orchestrator/compact-request.d.ts +32 -0
- package/dist/src/orchestrator/compact-request.js +41 -0
- package/dist/src/orchestrator/compaction.d.ts +12 -3
- package/dist/src/orchestrator/compaction.js +35 -15
- package/dist/src/orchestrator/council-manager.d.ts +12 -3
- package/dist/src/orchestrator/council-manager.js +74 -32
- package/dist/src/orchestrator/council-request.d.ts +49 -0
- package/dist/src/orchestrator/council-request.js +62 -0
- package/dist/src/orchestrator/cross-turn-dedup.d.ts +6 -0
- package/dist/src/orchestrator/cross-turn-dedup.js +22 -1
- package/dist/src/orchestrator/error-utils.d.ts +29 -0
- package/dist/src/orchestrator/error-utils.js +132 -24
- package/dist/src/orchestrator/grounding-check.js +39 -1
- package/dist/src/orchestrator/interactive-pause.d.ts +26 -0
- package/dist/src/orchestrator/interactive-pause.js +36 -0
- package/dist/src/orchestrator/message-processor.d.ts +4 -0
- package/dist/src/orchestrator/message-processor.js +268 -41
- package/dist/src/orchestrator/orchestrator.d.ts +64 -3
- package/dist/src/orchestrator/orchestrator.js +823 -120
- package/dist/src/orchestrator/preprocessor.js +3 -3
- package/dist/src/orchestrator/proactive-compact-detector.d.ts +26 -0
- package/dist/src/orchestrator/proactive-compact-detector.js +36 -0
- package/dist/src/orchestrator/prompts.js +17 -17
- package/dist/src/orchestrator/reactive-delegation.d.ts +39 -0
- package/dist/src/orchestrator/reactive-delegation.js +59 -0
- package/dist/src/orchestrator/retry-classifier.d.ts +2 -1
- package/dist/src/orchestrator/retry-classifier.js +46 -2
- package/dist/src/orchestrator/safety-askcard.d.ts +1 -1
- package/dist/src/orchestrator/safety-askcard.js +5 -2
- package/dist/src/orchestrator/safety-intercept.d.ts +50 -0
- package/dist/src/orchestrator/safety-intercept.js +62 -0
- package/dist/src/orchestrator/scope-reminder.js +1 -1
- package/dist/src/orchestrator/session-experience.d.ts +2 -1
- package/dist/src/orchestrator/session-experience.js +2 -1
- package/dist/src/orchestrator/should-run-gate.d.ts +5 -0
- package/dist/src/orchestrator/should-run-gate.js +18 -0
- package/dist/src/orchestrator/stall-watchdog.d.ts +31 -3
- package/dist/src/orchestrator/stall-watchdog.js +65 -10
- package/dist/src/orchestrator/stream-runner.d.ts +13 -3
- package/dist/src/orchestrator/stream-runner.js +115 -49
- package/dist/src/orchestrator/sub-agent-cap.d.ts +13 -1
- package/dist/src/orchestrator/sub-agent-cap.js +16 -1
- package/dist/src/orchestrator/sub-agent-model-tier.d.ts +13 -1
- package/dist/src/orchestrator/sub-agent-model-tier.js +16 -2
- package/dist/src/orchestrator/subagent-compactor.d.ts +53 -1
- package/dist/src/orchestrator/subagent-compactor.js +126 -15
- package/dist/src/orchestrator/tool-engine.d.ts +41 -0
- package/dist/src/orchestrator/tool-engine.js +846 -66
- package/dist/src/orchestrator/tool-limit-auto-recover.d.ts +22 -0
- package/dist/src/orchestrator/tool-limit-auto-recover.js +30 -0
- package/dist/src/orchestrator/turn-runner-deps.d.ts +19 -0
- package/dist/src/orchestrator/turn-watchdog.d.ts +44 -0
- package/dist/src/orchestrator/turn-watchdog.js +84 -0
- package/dist/src/pil/agent-operating-contract.d.ts +1 -1
- package/dist/src/pil/agent-operating-contract.js +6 -4
- package/dist/src/pil/cheap-model-playbook.d.ts +1 -1
- package/dist/src/pil/cheap-model-playbook.js +5 -1
- package/dist/src/pil/cheap-model-workbooks.d.ts +1 -1
- package/dist/src/pil/cheap-model-workbooks.js +1 -1
- package/dist/src/pil/discovery-types.d.ts +1 -0
- package/dist/src/pil/discovery.d.ts +1 -1
- package/dist/src/pil/discovery.js +18 -13
- package/dist/src/pil/layer1-intent.d.ts +18 -6
- package/dist/src/pil/layer1-intent.js +66 -757
- package/dist/src/pil/layer15-context-scan.js +15 -1
- package/dist/src/pil/layer1_5-complexity-size.d.ts +7 -0
- package/dist/src/pil/layer1_5-complexity-size.js +31 -5
- package/dist/src/pil/layer3-ee-injection.js +23 -8
- package/dist/src/pil/layer4-gsd.js +69 -16
- package/dist/src/pil/layer5-context.js +7 -3
- package/dist/src/pil/layer6-output.d.ts +23 -0
- package/dist/src/pil/layer6-output.js +5 -1
- package/dist/src/pil/llm-classify.d.ts +111 -5
- package/dist/src/pil/llm-classify.js +421 -189
- package/dist/src/pil/native-capabilities-workbook.d.ts +1 -1
- package/dist/src/pil/native-capabilities-workbook.js +8 -0
- package/dist/src/pil/pipeline.js +36 -2
- package/dist/src/pil/repo-grounding-probe.d.ts +15 -0
- package/dist/src/pil/repo-grounding-probe.js +136 -0
- package/dist/src/pil/repo-structure-hints.d.ts +7 -0
- package/dist/src/pil/repo-structure-hints.js +45 -0
- package/dist/src/pil/response-tools.js +5 -3
- package/dist/src/pil/schema.d.ts +1 -0
- package/dist/src/pil/schema.js +2 -0
- package/dist/src/pil/types.d.ts +18 -0
- package/dist/src/playbook/directives.d.ts +4 -0
- package/dist/src/playbook/directives.js +17 -5
- package/dist/src/product-loop/artifact-io.js +4 -0
- package/dist/src/product-loop/backlog-builder.d.ts +14 -1
- package/dist/src/product-loop/backlog-builder.js +30 -6
- package/dist/src/product-loop/criteria-seed.d.ts +51 -0
- package/dist/src/product-loop/criteria-seed.js +200 -0
- package/dist/src/product-loop/discovery-context-format.js +3 -1
- package/dist/src/product-loop/discovery-ecosystem.js +4 -1
- package/dist/src/product-loop/discovery-interview.d.ts +9 -0
- package/dist/src/product-loop/discovery-interview.js +60 -12
- package/dist/src/product-loop/discovery-recommender.js +2 -1
- package/dist/src/product-loop/discovery-schema.js +19 -2
- package/dist/src/product-loop/discovery-triage.d.ts +23 -0
- package/dist/src/product-loop/discovery-triage.js +109 -0
- package/dist/src/product-loop/gather.js +150 -2
- package/dist/src/product-loop/ideal-trace.d.ts +7 -0
- package/dist/src/product-loop/ideal-trace.js +64 -0
- package/dist/src/product-loop/index.d.ts +13 -1
- package/dist/src/product-loop/index.js +340 -52
- package/dist/src/product-loop/loop-driver.d.ts +7 -0
- package/dist/src/product-loop/loop-driver.js +330 -106
- package/dist/src/product-loop/phase-plan.d.ts +21 -0
- package/dist/src/product-loop/phase-plan.js +81 -6
- package/dist/src/product-loop/phase-rituals.d.ts +3 -0
- package/dist/src/product-loop/phase-rituals.js +8 -3
- package/dist/src/product-loop/phase-runner.js +39 -12
- package/dist/src/product-loop/plan-adherence-review.d.ts +26 -0
- package/dist/src/product-loop/plan-adherence-review.js +144 -0
- package/dist/src/product-loop/sprint-runner.d.ts +173 -0
- package/dist/src/product-loop/sprint-runner.js +863 -19
- package/dist/src/product-loop/types.d.ts +61 -5
- package/dist/src/providers/adapter.d.ts +1 -1
- package/dist/src/providers/adapter.js +3 -4
- package/dist/src/providers/anthropic.d.ts +9 -8
- package/dist/src/providers/anthropic.js +13 -47
- package/dist/src/providers/auth/browser-flow.d.ts +1 -1
- package/dist/src/providers/auth/browser-flow.js +1 -1
- package/dist/src/providers/auth/grok-oauth.d.ts +1 -0
- package/dist/src/providers/auth/grok-oauth.js +30 -5
- package/dist/src/providers/auth/openai-oauth.d.ts +1 -0
- package/dist/src/providers/auth/openai-oauth.js +15 -1
- package/dist/src/providers/auth/registry.js +0 -34
- package/dist/src/providers/auth/token-store.d.ts +9 -9
- package/dist/src/providers/auth/token-store.js +8 -67
- package/dist/src/providers/auth/types.d.ts +9 -1
- package/dist/src/providers/auth/types.js +1 -1
- package/dist/src/providers/capabilities.d.ts +24 -5
- package/dist/src/providers/capabilities.js +42 -24
- package/dist/src/providers/endpoints.d.ts +2 -2
- package/dist/src/providers/endpoints.js +11 -10
- package/dist/src/providers/env-store.d.ts +17 -0
- package/dist/src/providers/env-store.js +228 -0
- package/dist/src/providers/keychain.d.ts +22 -18
- package/dist/src/providers/keychain.js +127 -140
- package/dist/src/providers/mcp-vision-bridge.js +56 -146
- package/dist/src/providers/openai-compatible.js +8 -1
- package/dist/src/providers/pricing.d.ts +2 -2
- package/dist/src/providers/pricing.js +3 -13
- package/dist/src/providers/runtime.d.ts +43 -3
- package/dist/src/providers/runtime.js +88 -14
- package/dist/src/providers/strategies/base.strategy.d.ts +16 -0
- package/dist/src/providers/strategies/base.strategy.js +24 -1
- package/dist/src/providers/strategies/{siliconflow.strategy.d.ts → opencode-go.strategy.d.ts} +3 -3
- package/dist/src/providers/strategies/opencode-go.strategy.js +83 -0
- package/dist/src/providers/strategies/registry.js +4 -4
- package/dist/src/providers/strategies/thinking-mode.d.ts +109 -0
- package/dist/src/providers/strategies/thinking-mode.js +288 -1
- package/dist/src/providers/strategies/xai.strategy.js +27 -0
- package/dist/src/providers/strategies/zai.strategy.d.ts +14 -0
- package/dist/src/providers/strategies/zai.strategy.js +44 -0
- package/dist/src/providers/types.d.ts +5 -6
- package/dist/src/providers/types.js +2 -2
- package/dist/src/providers/vision-backend.d.ts +47 -0
- package/dist/src/providers/vision-backend.js +258 -0
- package/dist/src/providers/vision-proxy.d.ts +22 -9
- package/dist/src/providers/vision-proxy.js +63 -132
- package/dist/src/providers/warm.d.ts +65 -0
- package/dist/src/providers/warm.js +145 -0
- package/dist/src/providers/wire-debug.js +95 -0
- package/dist/src/router/decide.d.ts +13 -0
- package/dist/src/router/decide.js +138 -36
- package/dist/src/router/peak-hour.d.ts +38 -0
- package/dist/src/router/peak-hour.js +107 -0
- package/dist/src/router/step-router.js +3 -2
- package/dist/src/router/warm.js +4 -5
- package/dist/src/scaffold/continuation-prompt.d.ts +11 -0
- package/dist/src/scaffold/continuation-prompt.js +26 -0
- package/dist/src/scaffold/point-to-existing.d.ts +21 -0
- package/dist/src/scaffold/point-to-existing.js +25 -0
- package/dist/src/self-qa/agentic-loop.js +6 -5
- package/dist/src/{ui/state → state}/active-run.d.ts +19 -0
- package/dist/src/{ui/state → state}/active-run.js +21 -0
- package/dist/src/{ui/status-bar/store.d.ts → state/status-bar-store.d.ts} +4 -1
- package/dist/src/{ui/status-bar/store.js → state/status-bar-store.js} +12 -9
- package/dist/src/state/turn-trace.d.ts +43 -0
- package/dist/src/state/turn-trace.js +32 -0
- package/dist/src/storage/db.js +2 -1
- package/dist/src/storage/index.d.ts +1 -1
- package/dist/src/storage/index.js +1 -1
- package/dist/src/storage/interaction-log.d.ts +1 -1
- package/dist/src/storage/migrations.js +71 -1
- package/dist/src/storage/sessions.d.ts +28 -10
- package/dist/src/storage/sessions.js +78 -21
- package/dist/src/storage/transcript-view.js +1 -1
- package/dist/src/storage/transcript.d.ts +51 -0
- package/dist/src/storage/transcript.js +340 -15
- package/dist/src/tools/file.d.ts +15 -0
- package/dist/src/tools/file.js +32 -0
- package/dist/src/tools/git-safety.d.ts +19 -0
- package/dist/src/tools/git-safety.js +168 -0
- package/dist/src/tools/native-tools.d.ts +1 -1
- package/dist/src/tools/native-tools.js +81 -1
- package/dist/src/tools/registry.d.ts +20 -0
- package/dist/src/tools/registry.js +576 -23
- package/dist/src/tools/research.d.ts +29 -0
- package/dist/src/tools/research.js +233 -0
- package/dist/src/types/index.d.ts +147 -4
- package/dist/src/ui/app.js +0 -0
- package/dist/src/ui/cards/product-status-card.js +1 -1
- package/dist/src/ui/components/agent-rail-activities.d.ts +26 -0
- package/dist/src/ui/components/agent-rail-activities.js +47 -0
- package/dist/src/ui/components/bubble-body-guard.d.ts +27 -0
- package/dist/src/ui/components/bubble-body-guard.js +50 -0
- package/dist/src/ui/components/compact-progress-card.d.ts +24 -0
- package/dist/src/ui/components/compact-progress-card.js +42 -0
- package/dist/src/ui/components/context-rail.d.ts +26 -0
- package/dist/src/ui/components/context-rail.js +33 -0
- package/dist/src/ui/components/council-conclusion-card.d.ts +73 -0
- package/dist/src/ui/components/council-conclusion-card.js +420 -0
- package/dist/src/ui/components/council-debate-pill.d.ts +36 -0
- package/dist/src/ui/components/council-debate-pill.js +34 -0
- package/dist/src/ui/components/council-info-card.js +2 -2
- package/dist/src/ui/components/council-leader-bubble.d.ts +10 -3
- package/dist/src/ui/components/council-leader-bubble.js +21 -11
- package/dist/src/ui/components/council-message-bubble.d.ts +15 -2
- package/dist/src/ui/components/council-message-bubble.js +16 -15
- package/dist/src/ui/components/council-phase-timeline.d.ts +9 -1
- package/dist/src/ui/components/council-phase-timeline.js +66 -17
- package/dist/src/ui/components/council-placeholder-bubble.d.ts +16 -9
- package/dist/src/ui/components/council-placeholder-bubble.js +32 -29
- package/dist/src/ui/components/council-question-card.js +13 -12
- package/dist/src/ui/components/council-rail-rounds.d.ts +26 -0
- package/dist/src/ui/components/council-rail-rounds.js +57 -0
- package/dist/src/ui/components/council-round-group.d.ts +38 -0
- package/dist/src/ui/components/council-round-group.js +88 -0
- package/dist/src/ui/components/council-status-list.d.ts +3 -1
- package/dist/src/ui/components/council-status-list.js +36 -24
- package/dist/src/ui/components/council-synthesis-banner.d.ts +7 -2
- package/dist/src/ui/components/council-synthesis-banner.js +20 -5
- package/dist/src/ui/components/halt-recovery-card.js +9 -5
- package/dist/src/ui/components/jump-to-latest-pill.d.ts +11 -0
- package/dist/src/ui/components/jump-to-latest-pill.js +14 -0
- package/dist/src/ui/components/message-view.d.ts +15 -0
- package/dist/src/ui/components/message-view.js +50 -1
- package/dist/src/ui/components/prompt-box.js +18 -16
- package/dist/src/ui/components/session-tree-card.d.ts +14 -0
- package/dist/src/ui/components/session-tree-card.js +46 -0
- package/dist/src/ui/components/slash-inline-menu.d.ts +12 -0
- package/dist/src/ui/components/slash-inline-menu.js +26 -5
- package/dist/src/ui/components/task-list-panel.d.ts +14 -1
- package/dist/src/ui/components/task-list-panel.js +22 -2
- package/dist/src/ui/components/tool-group.d.ts +15 -3
- package/dist/src/ui/components/tool-group.js +69 -11
- package/dist/src/ui/containers/modals-layer.d.ts +4 -2
- package/dist/src/ui/containers/modals-layer.js +2 -2
- package/dist/src/ui/council-harness-event.d.ts +57 -0
- package/dist/src/ui/council-harness-event.js +46 -0
- package/dist/src/ui/heartbeat-debug.d.ts +29 -0
- package/dist/src/ui/heartbeat-debug.js +45 -0
- package/dist/src/ui/hooks/use-session-picker.d.ts +3 -3
- package/dist/src/ui/mcp-modal.js +2 -4
- package/dist/src/ui/modals/api-key-modal.js +1 -1
- package/dist/src/ui/modals/connect-modal.js +4 -3
- package/dist/src/ui/modals/model-picker-modal.d.ts +8 -18
- package/dist/src/ui/modals/model-picker-modal.js +8 -10
- package/dist/src/ui/modals/session-picker-modal.d.ts +2 -2
- package/dist/src/ui/modals/session-picker-modal.js +3 -5
- package/dist/src/ui/picker-providers.d.ts +1 -1
- package/dist/src/ui/picker-providers.js +1 -1
- package/dist/src/ui/primitives/index.d.ts +1 -0
- package/dist/src/ui/primitives/index.js +2 -0
- package/dist/src/ui/primitives/semantic-primitives.d.ts +76 -0
- package/dist/src/ui/primitives/semantic-primitives.js +81 -0
- package/dist/src/ui/slash/compact.js +5 -7
- package/dist/src/ui/slash/cost.js +1 -1
- package/dist/src/ui/slash/council.js +19 -1
- package/dist/src/ui/slash/debug.d.ts +3 -31
- package/dist/src/ui/slash/debug.js +9 -20
- package/dist/src/ui/slash/ee.js +81 -0
- package/dist/src/ui/slash/ideal.d.ts +6 -2
- package/dist/src/ui/slash/ideal.js +97 -7
- package/dist/src/ui/slash/menu-items.d.ts +7 -0
- package/dist/src/ui/slash/menu-items.js +23 -20
- package/dist/src/ui/slash/registry.d.ts +2 -0
- package/dist/src/ui/slash/registry.js +4 -0
- package/dist/src/ui/status-bar/cache-hit.d.ts +6 -0
- package/dist/src/ui/status-bar/cache-hit.js +9 -0
- package/dist/src/ui/status-bar/index.d.ts +1 -1
- package/dist/src/ui/status-bar/index.js +7 -3
- package/dist/src/ui/status-bar/usd-meter.d.ts +5 -4
- package/dist/src/ui/status-bar/usd-meter.js +6 -4
- package/dist/src/ui/theme.d.ts +1 -0
- package/dist/src/ui/theme.js +2 -0
- package/dist/src/ui/types.d.ts +7 -0
- package/dist/src/ui/use-app-logic.js +0 -0
- package/dist/src/ui/utils/agent-activities.d.ts +39 -0
- package/dist/src/ui/utils/agent-activities.js +96 -0
- package/dist/src/ui/utils/format.d.ts +14 -0
- package/dist/src/ui/utils/format.js +23 -3
- package/dist/src/ui/utils/group-tool-entries.d.ts +26 -0
- package/dist/src/ui/utils/group-tool-entries.js +111 -0
- package/dist/src/ui/utils/tool-summary.d.ts +21 -0
- package/dist/src/ui/utils/tool-summary.js +91 -0
- package/dist/src/usage/downgrade.js +2 -2
- package/dist/src/usage/product-ledger.js +2 -2
- package/dist/src/utils/event-loop-monitor.d.ts +85 -0
- package/dist/src/utils/event-loop-monitor.js +107 -0
- package/dist/src/utils/install-manager.js +2 -1
- package/dist/src/utils/llm-deadline.d.ts +14 -0
- package/dist/src/utils/llm-deadline.js +19 -0
- package/dist/src/utils/logger.js +2 -2
- package/dist/src/utils/loop-profiler.d.ts +102 -0
- package/dist/src/utils/loop-profiler.js +202 -0
- package/dist/src/utils/permission-mode.js +5 -3
- package/dist/src/utils/redactor.js +1 -1
- package/dist/src/utils/settings.d.ts +180 -5
- package/dist/src/utils/settings.js +271 -31
- package/dist/src/utils/side-question.d.ts +1 -2
- package/dist/src/utils/side-question.js +2 -2
- package/dist/src/utils/visible-retry.d.ts +11 -0
- package/dist/src/utils/visible-retry.js +10 -1
- package/dist/src/verify/entrypoint.d.ts +1 -1
- package/dist/src/verify/entrypoint.js +52 -17
- package/dist/src/verify/orchestrator.d.ts +1 -1
- package/dist/src/verify/orchestrator.js +20 -3
- package/dist/src/verify/recipes.d.ts +13 -0
- package/dist/src/verify/recipes.js +15 -0
- package/package.json +134 -132
- package/dist/src/cli/bw-vault.d.ts +0 -55
- package/dist/src/cli/bw-vault.js +0 -133
- package/dist/src/mcp/ee-tools.d.ts +0 -46
- package/dist/src/mcp/ee-tools.js +0 -193
- package/dist/src/providers/auth/gcloud.d.ts +0 -28
- package/dist/src/providers/auth/gcloud.js +0 -102
- package/dist/src/providers/auth/gemini-oauth.d.ts +0 -82
- package/dist/src/providers/auth/gemini-oauth.js +0 -472
- package/dist/src/providers/gemini.d.ts +0 -11
- package/dist/src/providers/gemini.js +0 -45
- package/dist/src/providers/siliconflow-sse-repair.d.ts +0 -58
- package/dist/src/providers/siliconflow-sse-repair.js +0 -177
- package/dist/src/providers/strategies/google.strategy.d.ts +0 -22
- package/dist/src/providers/strategies/google.strategy.js +0 -174
- package/dist/src/providers/strategies/siliconflow.strategy.js +0 -29
- package/dist/src/ui/containers/chat-feed.d.ts +0 -40
- package/dist/src/ui/containers/chat-feed.js +0 -66
|
@@ -0,0 +1,420 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "@opentui/react/jsx-runtime";
|
|
2
|
+
function asStringArray(v) {
|
|
3
|
+
if (!Array.isArray(v))
|
|
4
|
+
return [];
|
|
5
|
+
return v.filter((x) => typeof x === "string" && x.trim().length > 0).map((x) => x.trim());
|
|
6
|
+
}
|
|
7
|
+
function firstString(obj, keys) {
|
|
8
|
+
for (const k of keys) {
|
|
9
|
+
const val = obj[k];
|
|
10
|
+
if (typeof val === "string" && val.trim().length > 0)
|
|
11
|
+
return val.trim();
|
|
12
|
+
}
|
|
13
|
+
return undefined;
|
|
14
|
+
}
|
|
15
|
+
function firstArray(obj, keys) {
|
|
16
|
+
for (const k of keys) {
|
|
17
|
+
const arr = asStringArray(obj[k]);
|
|
18
|
+
if (arr.length > 0)
|
|
19
|
+
return arr;
|
|
20
|
+
}
|
|
21
|
+
return [];
|
|
22
|
+
}
|
|
23
|
+
function coverageRows(obj) {
|
|
24
|
+
for (const k of ["coverage_matrix", "coverage", "criteria", "coverageMatrix"]) {
|
|
25
|
+
const raw = obj[k];
|
|
26
|
+
if (!Array.isArray(raw))
|
|
27
|
+
continue;
|
|
28
|
+
const rows = [];
|
|
29
|
+
for (const item of raw) {
|
|
30
|
+
if (item && typeof item === "object") {
|
|
31
|
+
const cells = Object.values(item)
|
|
32
|
+
.filter((c) => typeof c === "string" && c.trim().length > 0)
|
|
33
|
+
.map((c) => c.trim());
|
|
34
|
+
if (cells.length > 0)
|
|
35
|
+
rows.push(cells);
|
|
36
|
+
}
|
|
37
|
+
else if (typeof item === "string" && item.trim().length > 0) {
|
|
38
|
+
rows.push([item.trim()]);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
if (rows.length > 0)
|
|
42
|
+
return rows;
|
|
43
|
+
}
|
|
44
|
+
return [];
|
|
45
|
+
}
|
|
46
|
+
function parseDimensionScores(obj) {
|
|
47
|
+
const raw = obj.dimension_scores ?? obj.dimensionScores ?? obj.scores;
|
|
48
|
+
if (!Array.isArray(raw))
|
|
49
|
+
return [];
|
|
50
|
+
const out = [];
|
|
51
|
+
for (const item of raw) {
|
|
52
|
+
if (!item || typeof item !== "object")
|
|
53
|
+
continue;
|
|
54
|
+
const row = item;
|
|
55
|
+
const dimension = String(row.dimension ?? row.name ?? row.criteria ?? "").trim();
|
|
56
|
+
const scoreRaw = row.score ?? row.rating ?? row.value;
|
|
57
|
+
const score = typeof scoreRaw === "number" ? scoreRaw : Number.parseInt(String(scoreRaw), 10);
|
|
58
|
+
const justification = String(row.justification ?? row.reason ?? row.note ?? "").trim();
|
|
59
|
+
if (dimension && Number.isFinite(score)) {
|
|
60
|
+
out.push({ dimension, score, justification: justification || "(no justification)" });
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return out;
|
|
64
|
+
}
|
|
65
|
+
function parseOperationalRisks(obj) {
|
|
66
|
+
const raw = obj.operational_risks ?? obj.operationalRisks ?? obj.risks;
|
|
67
|
+
if (!Array.isArray(raw))
|
|
68
|
+
return [];
|
|
69
|
+
const out = [];
|
|
70
|
+
for (const item of raw) {
|
|
71
|
+
if (!item || typeof item !== "object")
|
|
72
|
+
continue;
|
|
73
|
+
const row = item;
|
|
74
|
+
const risk = String(row.risk ?? row.name ?? row.title ?? "").trim();
|
|
75
|
+
const severity = String(row.severity ?? row.level ?? row.impact ?? "").trim();
|
|
76
|
+
const trigger = String(row.trigger ?? row.when ?? row.condition ?? "").trim();
|
|
77
|
+
if (risk) {
|
|
78
|
+
out.push({ risk, severity: severity || "Unknown", trigger: trigger || "(not specified)" });
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return out;
|
|
82
|
+
}
|
|
83
|
+
function parsePriorityFixes(obj) {
|
|
84
|
+
const raw = obj.priority_fixes ?? obj.priorityFixes ?? obj.fixes ?? obj.action_items;
|
|
85
|
+
if (Array.isArray(raw)) {
|
|
86
|
+
const strings = asStringArray(raw);
|
|
87
|
+
if (strings.length > 0)
|
|
88
|
+
return strings;
|
|
89
|
+
const flat = [];
|
|
90
|
+
for (const item of raw) {
|
|
91
|
+
if (item && typeof item === "object") {
|
|
92
|
+
const cells = Object.entries(item)
|
|
93
|
+
.filter(([, cv]) => cv !== null && cv !== undefined && typeof cv !== "object")
|
|
94
|
+
.map(([ck, cv]) => `${ck}: ${String(cv)}`);
|
|
95
|
+
if (cells.length > 0)
|
|
96
|
+
flat.push(cells.join(" · "));
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
if (flat.length > 0)
|
|
100
|
+
return flat;
|
|
101
|
+
}
|
|
102
|
+
return [];
|
|
103
|
+
}
|
|
104
|
+
function parseNextActions(obj) {
|
|
105
|
+
const raw = obj.nextActions ?? obj.next_actions ?? obj.actions;
|
|
106
|
+
if (!Array.isArray(raw))
|
|
107
|
+
return [];
|
|
108
|
+
const out = [];
|
|
109
|
+
for (const item of raw) {
|
|
110
|
+
if (!item || typeof item !== "object")
|
|
111
|
+
continue;
|
|
112
|
+
const row = item;
|
|
113
|
+
const action = String(row.action ?? row.id ?? row.key ?? "").trim();
|
|
114
|
+
const label = String(row.label ?? row.title ?? row.summary ?? action).trim();
|
|
115
|
+
const reason = String(row.reason ?? row.why ?? row.explanation ?? "").trim();
|
|
116
|
+
if (label) {
|
|
117
|
+
out.push({ action: action || label, label, reason: reason || undefined });
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return out;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Best-effort parse of possibly-truncated JSON. Providers cut synthesis output
|
|
124
|
+
* at maxTokens mid-array (live-verified 2026-07-06: `"nextActions":[…"action":"ask`),
|
|
125
|
+
* which made the whole conclusion fall back to a raw-JSON text wall.
|
|
126
|
+
*
|
|
127
|
+
* Single scan tracking string/escape state and the open-bracket stack. A "safe
|
|
128
|
+
* point" is the index AFTER a complete VALUE (string close, bracket close, or a
|
|
129
|
+
* number/true/false/null character). A closed string is only tentatively safe:
|
|
130
|
+
* if the next structural char is `:` it was a KEY, so we roll back to the
|
|
131
|
+
* previous safe point (otherwise the cut would produce a dangling `{"key"` —
|
|
132
|
+
* invalid JSON). The bracket stack is snapshotted at each safe point so the
|
|
133
|
+
* appended closers match the cut position, not the ragged end.
|
|
134
|
+
*/
|
|
135
|
+
export function salvageJson(body) {
|
|
136
|
+
try {
|
|
137
|
+
const direct = JSON.parse(body);
|
|
138
|
+
return direct && typeof direct === "object" && !Array.isArray(direct) ? direct : null;
|
|
139
|
+
}
|
|
140
|
+
catch {
|
|
141
|
+
// fall through to salvage — expected branch for truncated output
|
|
142
|
+
}
|
|
143
|
+
const stack = [];
|
|
144
|
+
let inString = false;
|
|
145
|
+
let escaped = false;
|
|
146
|
+
let lastSafe = -1;
|
|
147
|
+
let stackAtSafe = [];
|
|
148
|
+
let prevSafe = -1;
|
|
149
|
+
let stackAtPrevSafe = [];
|
|
150
|
+
let lastStringEnd = -1; // safe point created by the most recent string close
|
|
151
|
+
const markSafe = (endExclusive) => {
|
|
152
|
+
if (endExclusive === lastSafe)
|
|
153
|
+
return;
|
|
154
|
+
prevSafe = lastSafe;
|
|
155
|
+
stackAtPrevSafe = stackAtSafe;
|
|
156
|
+
lastSafe = endExclusive;
|
|
157
|
+
stackAtSafe = stack.slice();
|
|
158
|
+
};
|
|
159
|
+
for (let i = 0; i < body.length; i++) {
|
|
160
|
+
const ch = body[i];
|
|
161
|
+
if (inString) {
|
|
162
|
+
if (escaped)
|
|
163
|
+
escaped = false;
|
|
164
|
+
else if (ch === "\\")
|
|
165
|
+
escaped = true;
|
|
166
|
+
else if (ch === '"') {
|
|
167
|
+
inString = false;
|
|
168
|
+
markSafe(i + 1);
|
|
169
|
+
lastStringEnd = i + 1;
|
|
170
|
+
}
|
|
171
|
+
continue;
|
|
172
|
+
}
|
|
173
|
+
if (ch === '"')
|
|
174
|
+
inString = true;
|
|
175
|
+
else if (ch === "{" || ch === "[")
|
|
176
|
+
stack.push(ch === "{" ? "}" : "]");
|
|
177
|
+
else if (ch === "}" || ch === "]") {
|
|
178
|
+
stack.pop();
|
|
179
|
+
markSafe(i + 1);
|
|
180
|
+
}
|
|
181
|
+
else if (ch === ":") {
|
|
182
|
+
// The string that just closed was a key, not a value — retract it.
|
|
183
|
+
if (lastSafe === lastStringEnd && prevSafe !== -1) {
|
|
184
|
+
lastSafe = prevSafe;
|
|
185
|
+
stackAtSafe = stackAtPrevSafe;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
else if (/[0-9el]/.test(ch)) {
|
|
189
|
+
// Number / true / false / null terminal characters (outside strings,
|
|
190
|
+
// JSON only allows literals here) — cheap approximation of a value end.
|
|
191
|
+
markSafe(i + 1);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
if (lastSafe <= 0)
|
|
195
|
+
return null;
|
|
196
|
+
const prefix = body.slice(0, lastSafe).replace(/,\s*$/, "") + stackAtSafe.reverse().join("");
|
|
197
|
+
try {
|
|
198
|
+
const parsed = JSON.parse(prefix);
|
|
199
|
+
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
|
|
200
|
+
}
|
|
201
|
+
catch {
|
|
202
|
+
// salvage failed — caller renders plain text; expected for hopeless input
|
|
203
|
+
return null;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
/** "agreed_architecture" → "Agreed Architecture"; "actionItems" → "Action Items". */
|
|
207
|
+
function titleCase(key) {
|
|
208
|
+
return key
|
|
209
|
+
.replace(/([a-z])([A-Z])/g, "$1 $2")
|
|
210
|
+
.replace(/[_-]+/g, " ")
|
|
211
|
+
.trim()
|
|
212
|
+
.replace(/\b\w/g, (c) => c.toUpperCase());
|
|
213
|
+
}
|
|
214
|
+
/** Keys never worth a generic section: routing/meta fields. */
|
|
215
|
+
const NOISE_KEYS = new Set([
|
|
216
|
+
"type",
|
|
217
|
+
"nextActions",
|
|
218
|
+
"next_actions",
|
|
219
|
+
"sections",
|
|
220
|
+
"kind",
|
|
221
|
+
"dimension_scores",
|
|
222
|
+
"dimensionScores",
|
|
223
|
+
"dimensions",
|
|
224
|
+
"operational_risks",
|
|
225
|
+
"operationalRisks",
|
|
226
|
+
"risk_matrix",
|
|
227
|
+
"priority_fixes",
|
|
228
|
+
"priorityFixes",
|
|
229
|
+
"fixes",
|
|
230
|
+
"action_items",
|
|
231
|
+
]);
|
|
232
|
+
/** Color a numeric score (1-5) by quality tier. */
|
|
233
|
+
function scoreColor(score, theme) {
|
|
234
|
+
if (score <= 2)
|
|
235
|
+
return theme.diffRemovedFg;
|
|
236
|
+
if (score === 3)
|
|
237
|
+
return theme.mdItalic;
|
|
238
|
+
return theme.diffAddedFg;
|
|
239
|
+
}
|
|
240
|
+
function severityColor(severity, theme) {
|
|
241
|
+
const s = severity.toLowerCase();
|
|
242
|
+
if (s.includes("critical") || s.includes("high"))
|
|
243
|
+
return theme.diffRemovedFg;
|
|
244
|
+
if (s.includes("medium") || s.includes("moderate"))
|
|
245
|
+
return theme.mdItalic;
|
|
246
|
+
return theme.diffAddedFg;
|
|
247
|
+
}
|
|
248
|
+
/** Compact ASCII bar for a 1-5 score: e.g. "[### ]". */
|
|
249
|
+
function scoreBar(score) {
|
|
250
|
+
const clamped = Math.max(1, Math.min(5, Math.round(score)));
|
|
251
|
+
const filled = "#".repeat(clamped);
|
|
252
|
+
const empty = " ".repeat(5 - clamped);
|
|
253
|
+
return `[${filled}${empty}]`;
|
|
254
|
+
}
|
|
255
|
+
/** Flatten one unknown top-level value into displayable bullet items. */
|
|
256
|
+
function flattenValue(v) {
|
|
257
|
+
if (typeof v === "string")
|
|
258
|
+
return v.trim().length > 0 ? [v.trim()] : [];
|
|
259
|
+
if (Array.isArray(v)) {
|
|
260
|
+
const items = [];
|
|
261
|
+
for (const el of v) {
|
|
262
|
+
if (typeof el === "string" && el.trim().length > 0)
|
|
263
|
+
items.push(el.trim());
|
|
264
|
+
else if (el && typeof el === "object") {
|
|
265
|
+
const cells = Object.entries(el)
|
|
266
|
+
.filter(([, cv]) => cv !== null && cv !== undefined && typeof cv !== "object")
|
|
267
|
+
.map(([ck, cv]) => `${ck}: ${String(cv)}`);
|
|
268
|
+
if (cells.length > 0)
|
|
269
|
+
items.push(cells.join(" · "));
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
return items;
|
|
273
|
+
}
|
|
274
|
+
return [];
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Best-effort parse of a synthesis body into a structured conclusion. Returns
|
|
278
|
+
* null when the text is not a JSON object with at least one recognizable section
|
|
279
|
+
* — the caller then renders it as plain text.
|
|
280
|
+
*/
|
|
281
|
+
export function parseConclusion(text) {
|
|
282
|
+
const trimmed = text.trim();
|
|
283
|
+
// A `---READABLE---` prose tail means the synthesizer already produced human
|
|
284
|
+
// copy; don't try to structure it — let the plain-text path render the prose.
|
|
285
|
+
if (trimmed.includes("---READABLE---"))
|
|
286
|
+
return null;
|
|
287
|
+
// Strip a leading ```json … ``` fence if present, then isolate the object.
|
|
288
|
+
const fenced = trimmed.match(/```(?:json)?\s*([\s\S]*?)```/);
|
|
289
|
+
const body = (fenced ? fenced[1] : trimmed).trim();
|
|
290
|
+
const start = body.indexOf("{");
|
|
291
|
+
if (start === -1)
|
|
292
|
+
return null;
|
|
293
|
+
const end = body.lastIndexOf("}");
|
|
294
|
+
// Truncated output may have NO balanced end — hand the raw tail to salvage.
|
|
295
|
+
const candidate = end > start ? body.slice(start, end + 1) : body.slice(start);
|
|
296
|
+
const parsed = salvageJson(candidate) ?? (end > start ? salvageJson(body.slice(start)) : null);
|
|
297
|
+
if (!parsed)
|
|
298
|
+
return null;
|
|
299
|
+
const summary = firstString(parsed, ["summary", "conclusion"]);
|
|
300
|
+
const recommendation = firstString(parsed, ["recommendation", "decision", "verdict"]);
|
|
301
|
+
const strengths = firstArray(parsed, ["strengths", "pros", "agreed"]);
|
|
302
|
+
const weaknesses = firstArray(parsed, ["weaknesses", "cons", "gaps"]);
|
|
303
|
+
const risks = firstArray(parsed, ["risks", "concerns"]);
|
|
304
|
+
const tradeoffs = firstArray(parsed, ["tradeoffs", "trade_offs", "trade-offs"]);
|
|
305
|
+
const coverage = coverageRows(parsed);
|
|
306
|
+
const dimensionScores = parseDimensionScores(parsed);
|
|
307
|
+
const operationalRisks = parseOperationalRisks(parsed);
|
|
308
|
+
const priorityFixes = parsePriorityFixes(parsed);
|
|
309
|
+
const nextActions = parseNextActions(parsed);
|
|
310
|
+
// Track which keys the named extractions actually consumed (a key only
|
|
311
|
+
// counts as consumed when it produced content — object-shaped `risks`
|
|
312
|
+
// yield [] above and must still reach the generic pass below).
|
|
313
|
+
const consumed = new Set();
|
|
314
|
+
if (summary)
|
|
315
|
+
for (const k of ["summary", "conclusion"])
|
|
316
|
+
if (firstString(parsed, [k]))
|
|
317
|
+
consumed.add(k);
|
|
318
|
+
if (recommendation)
|
|
319
|
+
for (const k of ["recommendation", "decision", "verdict"])
|
|
320
|
+
if (firstString(parsed, [k]))
|
|
321
|
+
consumed.add(k);
|
|
322
|
+
const arrayKeyGroups = [
|
|
323
|
+
[["strengths", "pros", "agreed"], strengths],
|
|
324
|
+
[["weaknesses", "cons", "gaps"], weaknesses],
|
|
325
|
+
[["risks", "concerns"], risks],
|
|
326
|
+
[["tradeoffs", "trade_offs", "trade-offs"], tradeoffs],
|
|
327
|
+
];
|
|
328
|
+
for (const [keys, extracted] of arrayKeyGroups) {
|
|
329
|
+
if (extracted.length > 0)
|
|
330
|
+
for (const k of keys)
|
|
331
|
+
if (asStringArray(parsed[k]).length > 0)
|
|
332
|
+
consumed.add(k);
|
|
333
|
+
}
|
|
334
|
+
if (coverage.length > 0)
|
|
335
|
+
for (const k of ["coverage_matrix", "coverage", "criteria", "coverageMatrix"])
|
|
336
|
+
if (Array.isArray(parsed[k]))
|
|
337
|
+
consumed.add(k);
|
|
338
|
+
if (dimensionScores.length > 0)
|
|
339
|
+
for (const k of ["dimension_scores", "dimensionScores", "dimensions", "scores"])
|
|
340
|
+
if (Array.isArray(parsed[k]))
|
|
341
|
+
consumed.add(k);
|
|
342
|
+
if (operationalRisks.length > 0)
|
|
343
|
+
for (const k of ["operational_risks", "operationalRisks", "risk_matrix"])
|
|
344
|
+
if (Array.isArray(parsed[k]))
|
|
345
|
+
consumed.add(k);
|
|
346
|
+
if (priorityFixes.length > 0)
|
|
347
|
+
for (const k of ["priority_fixes", "priorityFixes", "fixes", "action_items"])
|
|
348
|
+
if (Array.isArray(parsed[k]))
|
|
349
|
+
consumed.add(k);
|
|
350
|
+
if (nextActions.length > 0)
|
|
351
|
+
for (const k of ["nextActions", "next_actions"])
|
|
352
|
+
if (Array.isArray(parsed[k]))
|
|
353
|
+
consumed.add(k);
|
|
354
|
+
const sections = [];
|
|
355
|
+
for (const [key, value] of Object.entries(parsed)) {
|
|
356
|
+
if (consumed.has(key) || NOISE_KEYS.has(key))
|
|
357
|
+
continue;
|
|
358
|
+
const items = flattenValue(value);
|
|
359
|
+
if (items.length > 0)
|
|
360
|
+
sections.push({ title: titleCase(key), items });
|
|
361
|
+
}
|
|
362
|
+
const hasContent = !!summary ||
|
|
363
|
+
!!recommendation ||
|
|
364
|
+
strengths.length > 0 ||
|
|
365
|
+
weaknesses.length > 0 ||
|
|
366
|
+
risks.length > 0 ||
|
|
367
|
+
tradeoffs.length > 0 ||
|
|
368
|
+
coverage.length > 0 ||
|
|
369
|
+
dimensionScores.length > 0 ||
|
|
370
|
+
operationalRisks.length > 0 ||
|
|
371
|
+
priorityFixes.length > 0 ||
|
|
372
|
+
nextActions.length > 0 ||
|
|
373
|
+
sections.length > 0;
|
|
374
|
+
if (!hasContent)
|
|
375
|
+
return null;
|
|
376
|
+
return {
|
|
377
|
+
summary,
|
|
378
|
+
recommendation,
|
|
379
|
+
strengths,
|
|
380
|
+
weaknesses,
|
|
381
|
+
risks,
|
|
382
|
+
tradeoffs,
|
|
383
|
+
coverage,
|
|
384
|
+
dimensionScores,
|
|
385
|
+
operationalRisks,
|
|
386
|
+
priorityFixes,
|
|
387
|
+
nextActions,
|
|
388
|
+
sections,
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
function BulletSection({ title, items, color, theme: t, marker = "•" }) {
|
|
392
|
+
if (items.length === 0)
|
|
393
|
+
return null;
|
|
394
|
+
return (_jsxs("box", { flexDirection: "column", marginTop: 1, children: [_jsx("text", { fg: color, attributes: 1, children: title }), items.map((it, i) => (_jsxs("box", { flexDirection: "row", children: [_jsx("text", { fg: t.textMuted, children: ` ${marker} ` }), _jsx("text", { fg: t.text, children: it })] }, `${title}-${i}`)))] }));
|
|
395
|
+
}
|
|
396
|
+
function DimensionScoreTable({ scores, theme: t }) {
|
|
397
|
+
if (scores.length === 0)
|
|
398
|
+
return null;
|
|
399
|
+
return (_jsxs("box", { flexDirection: "column", marginTop: 1, children: [_jsx("text", { fg: t.accent, attributes: 1, children: "Dimension Scores" }), scores.map((s, i) => (_jsxs("box", { flexDirection: "column", marginTop: 1, children: [_jsxs("box", { flexDirection: "row", children: [_jsx("text", { fg: t.text, children: s.dimension }), _jsx("box", { flexGrow: 1 }), _jsx("text", { fg: scoreColor(s.score, t), attributes: 1, children: `${s.score}/5 ${scoreBar(s.score)}` })] }), _jsx("text", { fg: t.textMuted, children: ` ${s.justification}` })] }, `dim-${i}`)))] }));
|
|
400
|
+
}
|
|
401
|
+
function RiskTable({ risks, theme: t }) {
|
|
402
|
+
if (risks.length === 0)
|
|
403
|
+
return null;
|
|
404
|
+
return (_jsxs("box", { flexDirection: "column", marginTop: 1, children: [_jsx("text", { fg: t.diffRemovedFg, attributes: 1, children: "Operational Risks" }), risks.map((r, i) => (_jsxs("box", { flexDirection: "column", marginTop: 1, children: [_jsxs("box", { flexDirection: "row", children: [_jsx("text", { fg: t.text, attributes: 1, children: r.risk }), _jsx("box", { flexGrow: 1 }), _jsx("text", { fg: severityColor(r.severity, t), children: r.severity })] }), _jsx("text", { fg: t.textMuted, children: ` Trigger: ${r.trigger}` })] }, `risk-${i}`)))] }));
|
|
405
|
+
}
|
|
406
|
+
function PriorityFixList({ fixes, theme: t }) {
|
|
407
|
+
if (fixes.length === 0)
|
|
408
|
+
return null;
|
|
409
|
+
return (_jsxs("box", { flexDirection: "column", marginTop: 1, children: [_jsx("text", { fg: t.mdItalic, attributes: 1, children: "Priority Fixes" }), fixes.map((fix, i) => (_jsxs("box", { flexDirection: "row", children: [_jsx("text", { fg: t.textMuted, children: ` ${i + 1}. ` }), _jsx("text", { fg: t.text, children: fix })] }, `fix-${i}`)))] }));
|
|
410
|
+
}
|
|
411
|
+
function NextActionList({ actions, theme: t }) {
|
|
412
|
+
if (actions.length === 0)
|
|
413
|
+
return null;
|
|
414
|
+
return (_jsxs("box", { flexDirection: "column", marginTop: 1, children: [_jsx("text", { fg: t.planStepNum, attributes: 1, children: "Next Actions" }), actions.map((a, i) => (_jsxs("box", { flexDirection: "column", marginTop: 1, children: [_jsxs("box", { flexDirection: "row", children: [_jsx("text", { fg: t.textMuted, children: ` ${i + 1}. ` }), _jsx("text", { fg: t.text, attributes: 1, children: a.label })] }), a.reason && _jsx("text", { fg: t.textMuted, children: ` ${a.reason}` })] }, `act-${i}`)))] }));
|
|
415
|
+
}
|
|
416
|
+
export function CouncilConclusionCard({ conclusion, round, theme: t }) {
|
|
417
|
+
const title = round === undefined ? "Final Conclusion" : `Round ${round} Conclusion`;
|
|
418
|
+
return (_jsxs("box", { flexDirection: "column", marginBottom: 1, border: ["left"], borderColor: t.councilSynthesisBorder, paddingLeft: 2, children: [_jsx("text", { fg: t.councilSynthesisBorder, attributes: 1, children: title }), conclusion.summary && (_jsx("box", { marginTop: 1, children: _jsx("text", { fg: t.text, children: conclusion.summary }) })), conclusion.recommendation && (_jsxs("box", { flexDirection: "column", marginTop: 1, children: [_jsx("text", { fg: t.accent, attributes: 1, children: "Recommendation" }), _jsx("text", { fg: t.text, children: conclusion.recommendation })] })), _jsx(DimensionScoreTable, { scores: conclusion.dimensionScores, theme: t }), _jsx(BulletSection, { title: "Strengths", items: conclusion.strengths, color: t.diffAddedFg, theme: t }), _jsx(BulletSection, { title: "Weaknesses", items: conclusion.weaknesses, color: t.diffRemovedFg, theme: t }), _jsx(RiskTable, { risks: conclusion.operationalRisks, theme: t }), _jsx(BulletSection, { title: "Risks", items: conclusion.risks, color: t.diffRemovedFg, theme: t }), _jsx(BulletSection, { title: "Trade-offs", items: conclusion.tradeoffs, color: t.mdItalic, theme: t }), _jsx(PriorityFixList, { fixes: conclusion.priorityFixes, theme: t }), _jsx(NextActionList, { actions: conclusion.nextActions, theme: t }), conclusion.coverage.length > 0 && (_jsxs("box", { flexDirection: "column", marginTop: 1, children: [_jsx("text", { fg: t.textMuted, attributes: 1, children: "Coverage" }), conclusion.coverage.map((row, i) => (_jsxs("box", { flexDirection: "row", children: [_jsx("text", { fg: t.textMuted, children: " – " }), _jsx("text", { fg: t.text, children: row.join(" · ") })] }, `cov-${i}`)))] })), conclusion.sections.map((sec) => (_jsx(BulletSection, { title: sec.title, items: sec.items, color: t.accent, theme: t }, sec.title)))] }));
|
|
419
|
+
}
|
|
420
|
+
//# sourceMappingURL=council-conclusion-card.js.map
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
import type { Theme } from "../theme.js";
|
|
3
|
+
export interface CouncilDebatePillProps {
|
|
4
|
+
/** Number of debate turns folded into the pill (leader + debate + research). */
|
|
5
|
+
count: number;
|
|
6
|
+
/** Debate still running — show a spinner + live tail; false → done summary. */
|
|
7
|
+
active: boolean;
|
|
8
|
+
/** Expanded → render full transcript (children); collapsed → header + tail only. */
|
|
9
|
+
expanded: boolean;
|
|
10
|
+
/**
|
|
11
|
+
* Last few non-empty lines of the most recent debate turn, joined with " · ".
|
|
12
|
+
* Only shown while active + collapsed to mimic the "thinking" pill. Empty
|
|
13
|
+
* string = nothing to show yet.
|
|
14
|
+
*/
|
|
15
|
+
tailText: string;
|
|
16
|
+
theme: Theme;
|
|
17
|
+
/** Full debate bubbles, rendered only when `expanded` is true. */
|
|
18
|
+
children?: ReactNode;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Collapsible debate transcript, styled after the reasoning ("[Thought]") pill.
|
|
22
|
+
*
|
|
23
|
+
* The council debate can emit dozens of tall bubbles. Rendering them all inline
|
|
24
|
+
* buries the synthesis/deliverable and floods the scrollback. This pill folds
|
|
25
|
+
* the back-and-forth into a single line:
|
|
26
|
+
* - active + collapsed → spinner + "Debating… (N turns)" + a live tail of the
|
|
27
|
+
* latest turn (like the reasoning pill's last-3-lines preview).
|
|
28
|
+
* - done + collapsed → "Debated N turns" summary; detail is hidden.
|
|
29
|
+
* - expanded → full transcript in a left-bordered box.
|
|
30
|
+
* Toggle via Ctrl+O (wired in use-app-logic handleKey). Synthesis is rendered
|
|
31
|
+
* OUTSIDE this pill by the caller so the deliverable is always visible.
|
|
32
|
+
*
|
|
33
|
+
* ASCII-only strings on purpose: this file's siblings mangle non-ASCII glyphs
|
|
34
|
+
* to mojibake under the repo's encoding, so we mirror the "[Thought]" pill idiom.
|
|
35
|
+
*/
|
|
36
|
+
export declare function CouncilDebatePill({ count, active, expanded, tailText, theme: t, children }: CouncilDebatePillProps): ReactNode;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "@opentui/react/jsx-runtime";
|
|
2
|
+
import { useEffect, useState } from "react";
|
|
3
|
+
const SPINNER_FRAMES = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
|
|
4
|
+
function Spinner() {
|
|
5
|
+
const [frame, setFrame] = useState(0);
|
|
6
|
+
useEffect(() => {
|
|
7
|
+
const id = setInterval(() => setFrame((n) => (n + 1) % SPINNER_FRAMES.length), 100);
|
|
8
|
+
return () => clearInterval(id);
|
|
9
|
+
}, []);
|
|
10
|
+
return _jsx(_Fragment, { children: SPINNER_FRAMES[frame] });
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Collapsible debate transcript, styled after the reasoning ("[Thought]") pill.
|
|
14
|
+
*
|
|
15
|
+
* The council debate can emit dozens of tall bubbles. Rendering them all inline
|
|
16
|
+
* buries the synthesis/deliverable and floods the scrollback. This pill folds
|
|
17
|
+
* the back-and-forth into a single line:
|
|
18
|
+
* - active + collapsed → spinner + "Debating… (N turns)" + a live tail of the
|
|
19
|
+
* latest turn (like the reasoning pill's last-3-lines preview).
|
|
20
|
+
* - done + collapsed → "Debated N turns" summary; detail is hidden.
|
|
21
|
+
* - expanded → full transcript in a left-bordered box.
|
|
22
|
+
* Toggle via Ctrl+O (wired in use-app-logic handleKey). Synthesis is rendered
|
|
23
|
+
* OUTSIDE this pill by the caller so the deliverable is always visible.
|
|
24
|
+
*
|
|
25
|
+
* ASCII-only strings on purpose: this file's siblings mangle non-ASCII glyphs
|
|
26
|
+
* to mojibake under the repo's encoding, so we mirror the "[Thought]" pill idiom.
|
|
27
|
+
*/
|
|
28
|
+
export function CouncilDebatePill({ count, active, expanded, tailText, theme: t, children }) {
|
|
29
|
+
const turnLabel = count === 1 ? "turn" : "turns";
|
|
30
|
+
const header = active ? `[Council] Debating... (${count} ${turnLabel})` : `[Council] Debated ${count} ${turnLabel}`;
|
|
31
|
+
const hint = expanded ? "Ctrl+O to collapse" : "Ctrl+O to expand";
|
|
32
|
+
return (_jsxs("box", { paddingLeft: 3, marginTop: 1, flexShrink: 0, flexDirection: "column", children: [_jsxs("box", { children: [active ? (_jsx("text", { fg: t.accent, children: _jsx(Spinner, {}) })) : null, _jsx("text", { fg: t.textMuted, children: `${active ? " " : ""}${header} · ${hint}` })] }), expanded ? (_jsx("box", { border: ["left"], borderColor: t.textMuted, paddingLeft: 2, marginTop: 1, flexDirection: "column", children: children })) : active && tailText ? (_jsx("box", { border: ["left"], borderColor: t.textMuted, paddingLeft: 2, marginTop: 1, children: _jsx("text", { fg: t.textMuted, children: tailText }) })) : null] }));
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=council-debate-pill.js.map
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "@opentui/react/jsx-runtime";
|
|
2
|
-
import {
|
|
2
|
+
import { ListItem } from "../primitives/index.js";
|
|
3
3
|
const MAX_CARD_COLS = 100;
|
|
4
4
|
const FALLBACK_THRESHOLD = 70;
|
|
5
5
|
export function CouncilInfoCardView({ card, terminalCols, theme }) {
|
|
6
6
|
const fallback = terminalCols < FALLBACK_THRESHOLD;
|
|
7
7
|
const width = fallback ? terminalCols : Math.min(terminalCols - 2, MAX_CARD_COLS);
|
|
8
|
-
return (_jsx(
|
|
8
|
+
return (_jsx(ListItem, { id: "info-card", name: card.title, children: _jsx("box", { flexDirection: "column", marginBottom: 1, children: _jsxs("box", { width: width, borderStyle: "single", borderColor: theme.councilInfoCardBorder, flexDirection: "column", paddingLeft: 1, paddingRight: 1, children: [_jsx("text", { fg: theme.councilInfoCardTitle, attributes: 1, children: card.title }), card.sections.map((section, i) => (_jsxs("box", { flexDirection: "column", marginTop: 1, children: [_jsx("text", { fg: theme.councilInfoCardHeading, attributes: 1, children: section.heading }), _jsx("text", { fg: theme.text, children: section.body })] }, `${section.heading}-${i}`)))] }) }) }));
|
|
9
9
|
}
|
|
10
10
|
//# sourceMappingURL=council-info-card.js.map
|
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
import type { CouncilMessage } from "../../types/index.js";
|
|
2
|
+
import type { Theme } from "../theme.js";
|
|
2
3
|
export interface CouncilLeaderBubbleProps {
|
|
3
4
|
msg: CouncilMessage;
|
|
4
5
|
terminalCols: number;
|
|
6
|
+
theme: Theme;
|
|
5
7
|
}
|
|
6
|
-
export declare function buildLeaderHeader(round: number | undefined): string;
|
|
8
|
+
export declare function buildLeaderHeader(round: number | undefined, phase?: CouncilMessage["phase"]): string;
|
|
7
9
|
/**
|
|
8
|
-
*
|
|
10
|
+
* Leader evaluation, rendered as a linear group-chat row (matching the debate
|
|
11
|
+
* speakers) instead of a centered narrow bubble — a muted gray left bar marks
|
|
12
|
+
* it as the moderator's turn while keeping the single downward reading flow.
|
|
13
|
+
*
|
|
14
|
+
* B5: a pre-round `directive` steers the debate and is rendered with the accent
|
|
15
|
+
* color so the leader visibly LEADS each round; `verdict`/`eval` stay muted.
|
|
9
16
|
*/
|
|
10
|
-
export declare function CouncilLeaderBubble({ msg, terminalCols }: CouncilLeaderBubbleProps): import("react").ReactNode;
|
|
17
|
+
export declare function CouncilLeaderBubble({ msg, terminalCols, theme: t }: CouncilLeaderBubbleProps): import("react").ReactNode;
|
|
@@ -1,17 +1,27 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "@opentui/react/jsx-runtime";
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
import { capBubbleBody } from "./bubble-body-guard.js";
|
|
3
|
+
export function buildLeaderHeader(round, phase) {
|
|
4
|
+
// B5: distinguish the leader's pre-round steering from its post-round grading
|
|
5
|
+
// so the conductor role reads clearly in the transcript (not a faint "eval").
|
|
6
|
+
const suffix = phase === "directive" ? "directive" : phase === "verdict" ? "verdict" : "eval";
|
|
7
|
+
const label = phase === "directive" ? "▶ Leader" : "Leader";
|
|
8
|
+
return round !== undefined ? `${label} · round ${round} ${suffix}` : label;
|
|
6
9
|
}
|
|
7
10
|
/**
|
|
8
|
-
*
|
|
11
|
+
* Leader evaluation, rendered as a linear group-chat row (matching the debate
|
|
12
|
+
* speakers) instead of a centered narrow bubble — a muted gray left bar marks
|
|
13
|
+
* it as the moderator's turn while keeping the single downward reading flow.
|
|
14
|
+
*
|
|
15
|
+
* B5: a pre-round `directive` steers the debate and is rendered with the accent
|
|
16
|
+
* color so the leader visibly LEADS each round; `verdict`/`eval` stay muted.
|
|
9
17
|
*/
|
|
10
|
-
export function CouncilLeaderBubble({ msg, terminalCols }) {
|
|
11
|
-
const
|
|
12
|
-
const
|
|
13
|
-
const
|
|
14
|
-
const
|
|
15
|
-
|
|
18
|
+
export function CouncilLeaderBubble({ msg, terminalCols, theme: t }) {
|
|
19
|
+
const header = buildLeaderHeader(msg.round, msg.phase);
|
|
20
|
+
const isDirective = msg.phase === "directive";
|
|
21
|
+
const headerColor = isDirective ? t.accent : t.textMuted;
|
|
22
|
+
const borderColor = isDirective ? t.accent : t.councilLeaderBorder;
|
|
23
|
+
// Same unbounded-<text> guard as the speaker bubble (see bubble-body-guard.ts).
|
|
24
|
+
const bodyText = capBubbleBody(msg.text.trim(), terminalCols);
|
|
25
|
+
return (_jsxs("box", { flexDirection: "column", marginBottom: 1, border: ["left"], borderColor: borderColor, paddingLeft: 2, children: [_jsx("text", { fg: headerColor, attributes: 1, children: header }), _jsx("text", { fg: t.textMuted, children: bodyText })] }));
|
|
16
26
|
}
|
|
17
27
|
//# sourceMappingURL=council-leader-bubble.js.map
|
|
@@ -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
|