muonroi-cli 1.8.4 → 1.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +17 -5
- package/dist/packages/agent-harness-core/src/driver.d.ts +27 -1
- package/dist/packages/agent-harness-core/src/driver.js +46 -0
- package/dist/packages/agent-harness-core/src/event-filter.js +11 -0
- package/dist/packages/agent-harness-core/src/event-redact.js +7 -0
- package/dist/packages/agent-harness-core/src/event-tee.d.ts +64 -0
- package/dist/packages/agent-harness-core/src/event-tee.js +104 -0
- package/dist/packages/agent-harness-core/src/mcp-server.d.ts +25 -0
- package/dist/packages/agent-harness-core/src/mcp-server.js +169 -21
- package/dist/packages/agent-harness-core/src/predicate.d.ts +1 -1
- package/dist/packages/agent-harness-core/src/protocol.d.ts +90 -4
- package/dist/packages/agent-harness-core/src/protocol.js +15 -0
- package/dist/packages/agent-harness-core/src/visual-quality.d.ts +58 -0
- package/dist/packages/agent-harness-core/src/visual-quality.js +141 -0
- package/dist/packages/agent-harness-opentui/src/agent-mode.d.ts +6 -0
- package/dist/packages/agent-harness-opentui/src/agent-mode.js +14 -1
- package/dist/packages/agent-harness-opentui/src/input-bridge.d.ts +2 -10
- package/dist/packages/agent-harness-opentui/src/input-bridge.js +103 -16
- package/dist/packages/agent-harness-opentui/src/install.d.ts +8 -0
- package/dist/packages/agent-harness-opentui/src/install.js +10 -0
- package/dist/packages/agent-harness-opentui/src/semantic.js +12 -10
- package/dist/packages/agent-harness-opentui/src/visual-capture.d.ts +56 -0
- package/dist/packages/agent-harness-opentui/src/visual-capture.js +103 -0
- package/dist/src/agent-harness/mock-model.d.ts +38 -0
- package/dist/src/agent-harness/mock-model.js +69 -3
- package/dist/src/agent-harness/test-spawn.js +31 -0
- package/dist/src/chat/chat-keychain.d.ts +7 -12
- package/dist/src/chat/chat-keychain.js +19 -86
- package/dist/src/cli/config/screen-providers.js +1 -1
- package/dist/src/cli/cost-forensics.d.ts +10 -0
- package/dist/src/cli/cost-forensics.js +18 -3
- package/dist/src/cli/keys-bundle.d.ts +1 -1
- package/dist/src/cli/keys-bundle.js +1 -1
- package/dist/src/cli/keys.d.ts +10 -47
- package/dist/src/cli/keys.js +31 -399
- package/dist/src/council/clarifier.d.ts +31 -3
- package/dist/src/council/clarifier.js +220 -32
- package/dist/src/council/context.js +49 -15
- package/dist/src/council/debate-checkpoint.d.ts +129 -0
- package/dist/src/council/debate-checkpoint.js +176 -0
- package/dist/src/council/debate-planner.js +54 -5
- package/dist/src/council/debate-summary.d.ts +25 -0
- package/dist/src/council/debate-summary.js +85 -0
- package/dist/src/council/debate.d.ts +169 -2
- package/dist/src/council/debate.js +1265 -135
- package/dist/src/council/index.d.ts +108 -1
- package/dist/src/council/index.js +670 -197
- package/dist/src/council/leader.d.ts +26 -0
- package/dist/src/council/leader.js +150 -9
- package/dist/src/council/llm.d.ts +94 -0
- package/dist/src/council/llm.js +348 -55
- package/dist/src/council/panel-select.d.ts +30 -0
- package/dist/src/council/panel-select.js +82 -0
- package/dist/src/council/planner.js +40 -0
- package/dist/src/council/preflight.d.ts +17 -0
- package/dist/src/council/preflight.js +50 -2
- package/dist/src/council/prompts.d.ts +39 -4
- package/dist/src/council/prompts.js +256 -69
- package/dist/src/council/stance-recall.d.ts +42 -0
- package/dist/src/council/stance-recall.js +57 -0
- package/dist/src/council/strip-think.d.ts +17 -0
- package/dist/src/council/strip-think.js +33 -0
- package/dist/src/council/types.d.ts +138 -0
- package/dist/src/ee/artifact-cache.d.ts +16 -0
- package/dist/src/ee/artifact-cache.js +32 -0
- package/dist/src/ee/auth.d.ts +20 -0
- package/dist/src/ee/auth.js +54 -2
- package/dist/src/ee/bridge.d.ts +10 -0
- package/dist/src/ee/bridge.js +58 -0
- package/dist/src/ee/client.js +109 -21
- package/dist/src/ee/ee-onboarding.js +6 -26
- package/dist/src/ee/export-transcripts.d.ts +1 -0
- package/dist/src/ee/export-transcripts.js +8 -10
- package/dist/src/ee/extract-session.js +29 -0
- package/dist/src/ee/extract-style.d.ts +58 -0
- package/dist/src/ee/extract-style.js +270 -0
- package/dist/src/ee/recall-ledger.d.ts +9 -0
- package/dist/src/ee/recall-ledger.js +3 -0
- package/dist/src/ee/scope.d.ts +1 -0
- package/dist/src/ee/scope.js +26 -1
- package/dist/src/ee/search.d.ts +7 -0
- package/dist/src/ee/search.js +24 -0
- package/dist/src/ee/transcript-emit.js +2 -0
- package/dist/src/ee/types.d.ts +22 -0
- package/dist/src/ee/who-am-i-brain.d.ts +35 -0
- package/dist/src/ee/who-am-i-brain.js +220 -0
- package/dist/src/ee/who-am-i.d.ts +10 -3
- package/dist/src/ee/who-am-i.js +12 -0
- package/dist/src/ee/workflow-event.d.ts +48 -0
- package/dist/src/ee/workflow-event.js +81 -0
- package/dist/src/flow/compaction/compress.d.ts +3 -3
- package/dist/src/flow/compaction/compress.js +58 -8
- package/dist/src/flow/compaction/extract.d.ts +4 -7
- package/dist/src/flow/compaction/extract.js +50 -10
- package/dist/src/flow/compaction/index.d.ts +14 -1
- package/dist/src/flow/compaction/index.js +96 -3
- package/dist/src/flow/compaction/input-guard.d.ts +24 -0
- package/dist/src/flow/compaction/input-guard.js +43 -0
- package/dist/src/flow/compaction/progress.d.ts +35 -0
- package/dist/src/flow/compaction/progress.js +35 -0
- package/dist/src/flow/fold-planning.d.ts +36 -0
- package/dist/src/flow/fold-planning.js +83 -0
- package/dist/src/flow/hierarchy.d.ts +146 -0
- package/dist/src/flow/hierarchy.js +427 -0
- package/dist/src/flow/index.d.ts +1 -0
- package/dist/src/flow/index.js +2 -0
- package/dist/src/flow/run-artifacts.d.ts +102 -0
- package/dist/src/flow/run-artifacts.js +208 -0
- package/dist/src/generated/version.d.ts +1 -1
- package/dist/src/generated/version.js +1 -1
- package/dist/src/gsd/assessment-schema.d.ts +44 -0
- package/dist/src/gsd/assessment-schema.js +134 -0
- package/dist/src/gsd/capability-registry.d.ts +45 -0
- package/dist/src/gsd/capability-registry.js +337 -0
- package/dist/src/gsd/complexity-assessor.d.ts +39 -0
- package/dist/src/gsd/complexity-assessor.js +152 -0
- package/dist/src/gsd/config-bridge.d.ts +7 -0
- package/dist/src/gsd/config-bridge.js +114 -0
- package/dist/src/gsd/config-loader.d.ts +27 -0
- package/dist/src/gsd/config-loader.js +50 -0
- package/dist/src/gsd/council-context.d.ts +44 -0
- package/dist/src/gsd/council-context.js +114 -0
- package/dist/src/gsd/ee-closure.d.ts +28 -0
- package/dist/src/gsd/ee-closure.js +49 -0
- package/dist/src/gsd/flags.d.ts +66 -0
- package/dist/src/gsd/flags.js +102 -0
- package/dist/src/gsd/gsd-dispatch.d.ts +58 -0
- package/dist/src/gsd/gsd-dispatch.js +131 -0
- package/dist/src/gsd/gsd-runtime.d.ts +22 -0
- package/dist/src/gsd/gsd-runtime.js +37 -0
- package/dist/src/gsd/host-adapter.d.ts +11 -0
- package/dist/src/gsd/host-adapter.js +29 -0
- package/dist/src/gsd/index.d.ts +24 -1
- package/dist/src/gsd/index.js +27 -0
- package/dist/src/gsd/loop-host-contract.d.ts +21 -0
- package/dist/src/gsd/loop-host-contract.js +39 -0
- package/dist/src/gsd/loop-host.d.ts +69 -0
- package/dist/src/gsd/loop-host.js +245 -0
- package/dist/src/gsd/loop-resolver.d.ts +36 -0
- package/dist/src/gsd/loop-resolver.js +79 -0
- package/dist/src/gsd/model-tier.d.ts +13 -0
- package/dist/src/gsd/model-tier.js +45 -0
- package/dist/src/gsd/mutation-gate.d.ts +16 -0
- package/dist/src/gsd/mutation-gate.js +41 -0
- package/dist/src/gsd/native-roadmap.d.ts +89 -0
- package/dist/src/gsd/native-roadmap.js +343 -0
- package/dist/src/gsd/native-state.d.ts +47 -0
- package/dist/src/gsd/native-state.js +220 -0
- package/dist/src/gsd/paths.d.ts +23 -0
- package/dist/src/gsd/paths.js +66 -0
- package/dist/src/gsd/phase-dag.d.ts +12 -0
- package/dist/src/gsd/phase-dag.js +94 -0
- package/dist/src/gsd/phase-sync.d.ts +42 -0
- package/dist/src/gsd/phase-sync.js +321 -0
- package/dist/src/gsd/pil-gate-context.d.ts +13 -0
- package/dist/src/gsd/pil-gate-context.js +64 -0
- package/dist/src/gsd/pil-gate-critic.d.ts +19 -0
- package/dist/src/gsd/pil-gate-critic.js +74 -0
- package/dist/src/gsd/plan-council-prompts.d.ts +25 -0
- package/dist/src/gsd/plan-council-prompts.js +79 -0
- package/dist/src/gsd/plan-council.d.ts +44 -0
- package/dist/src/gsd/plan-council.js +283 -0
- package/dist/src/gsd/plan-gate-vocabulary.d.ts +40 -0
- package/dist/src/gsd/plan-gate-vocabulary.js +64 -0
- package/dist/src/gsd/product-workspace.d.ts +13 -0
- package/dist/src/gsd/product-workspace.js +124 -0
- package/dist/src/gsd/ship-bridge.d.ts +25 -0
- package/dist/src/gsd/ship-bridge.js +65 -0
- package/dist/src/gsd/state-document.d.ts +40 -0
- package/dist/src/gsd/state-document.js +163 -0
- package/dist/src/gsd/verdict-schema.d.ts +39 -0
- package/dist/src/gsd/verdict-schema.js +144 -0
- package/dist/src/gsd/verify-context.d.ts +22 -0
- package/dist/src/gsd/verify-context.js +27 -0
- package/dist/src/gsd/verify-council-prompts.d.ts +19 -0
- package/dist/src/gsd/verify-council-prompts.js +85 -0
- package/dist/src/gsd/verify-council.d.ts +25 -0
- package/dist/src/gsd/verify-council.js +119 -0
- package/dist/src/gsd/verify-gate-vocabulary.d.ts +25 -0
- package/dist/src/gsd/verify-gate-vocabulary.js +46 -0
- package/dist/src/gsd/workflow-engine.d.ts +60 -0
- package/dist/src/gsd/workflow-engine.js +207 -0
- package/dist/src/gsd/workflow-tools.d.ts +13 -0
- package/dist/src/gsd/workflow-tools.js +277 -0
- package/dist/src/headless/council-answers.js +4 -0
- package/dist/src/hooks/index.js +1 -1
- package/dist/src/index.js +172 -270
- package/dist/src/lsp/builtins.js +3 -1
- package/dist/src/lsp/manager.d.ts +5 -1
- package/dist/src/lsp/manager.js +249 -3
- package/dist/src/lsp/npm-cache.d.ts +11 -1
- package/dist/src/lsp/npm-cache.js +17 -1
- package/dist/src/lsp/runtime.d.ts +6 -1
- package/dist/src/lsp/runtime.js +17 -1
- package/dist/src/lsp/types.d.ts +83 -1
- package/dist/src/lsp/types.js +10 -0
- package/dist/src/maintain/pr-builder.js +23 -13
- package/dist/src/mcp/auto-setup.js +57 -32
- package/dist/src/mcp/client-pool.js +44 -16
- package/dist/src/mcp/lsp-tools.d.ts +5 -1
- package/dist/src/mcp/lsp-tools.js +93 -2
- package/dist/src/mcp/mcp-keychain.d.ts +3 -5
- package/dist/src/mcp/mcp-keychain.js +9 -49
- package/dist/src/mcp/research-onboarding.js +8 -7
- package/dist/src/mcp/runtime.js +34 -2
- package/dist/src/mcp/setup-guide-text.d.ts +1 -1
- package/dist/src/mcp/setup-guide-text.js +22 -2
- package/dist/src/mcp/tools-server.d.ts +10 -0
- package/dist/src/mcp/tools-server.js +10 -2
- package/dist/src/models/catalog-client.d.ts +87 -0
- package/dist/src/models/catalog-client.js +105 -38
- package/dist/src/models/catalog.json +528 -265
- package/dist/src/models/registry.d.ts +22 -7
- package/dist/src/models/registry.js +73 -10
- package/dist/src/ops/doctor.js +1 -1
- package/dist/src/orchestrator/ask-user.d.ts +61 -0
- package/dist/src/orchestrator/ask-user.js +65 -0
- package/dist/src/orchestrator/auto-commit.js +1 -1
- package/dist/src/orchestrator/batch-turn-runner.js +2 -2
- package/dist/src/orchestrator/cache-prefix.d.ts +67 -0
- package/dist/src/orchestrator/cache-prefix.js +83 -0
- package/dist/src/orchestrator/compact-request.d.ts +32 -0
- package/dist/src/orchestrator/compact-request.js +41 -0
- package/dist/src/orchestrator/compaction.d.ts +12 -3
- package/dist/src/orchestrator/compaction.js +35 -15
- package/dist/src/orchestrator/council-manager.d.ts +12 -3
- package/dist/src/orchestrator/council-manager.js +74 -32
- package/dist/src/orchestrator/council-request.d.ts +49 -0
- package/dist/src/orchestrator/council-request.js +62 -0
- package/dist/src/orchestrator/cross-turn-dedup.d.ts +6 -0
- package/dist/src/orchestrator/cross-turn-dedup.js +22 -1
- package/dist/src/orchestrator/error-utils.d.ts +29 -0
- package/dist/src/orchestrator/error-utils.js +132 -24
- package/dist/src/orchestrator/grounding-check.js +39 -1
- package/dist/src/orchestrator/interactive-pause.d.ts +26 -0
- package/dist/src/orchestrator/interactive-pause.js +36 -0
- package/dist/src/orchestrator/message-processor.d.ts +4 -0
- package/dist/src/orchestrator/message-processor.js +268 -41
- package/dist/src/orchestrator/orchestrator.d.ts +64 -3
- package/dist/src/orchestrator/orchestrator.js +823 -120
- package/dist/src/orchestrator/preprocessor.js +3 -3
- package/dist/src/orchestrator/proactive-compact-detector.d.ts +26 -0
- package/dist/src/orchestrator/proactive-compact-detector.js +36 -0
- package/dist/src/orchestrator/prompts.js +17 -17
- package/dist/src/orchestrator/reactive-delegation.d.ts +39 -0
- package/dist/src/orchestrator/reactive-delegation.js +59 -0
- package/dist/src/orchestrator/retry-classifier.d.ts +2 -1
- package/dist/src/orchestrator/retry-classifier.js +46 -2
- package/dist/src/orchestrator/safety-askcard.d.ts +1 -1
- package/dist/src/orchestrator/safety-askcard.js +5 -2
- package/dist/src/orchestrator/safety-intercept.d.ts +50 -0
- package/dist/src/orchestrator/safety-intercept.js +62 -0
- package/dist/src/orchestrator/scope-reminder.js +1 -1
- package/dist/src/orchestrator/session-experience.d.ts +2 -1
- package/dist/src/orchestrator/session-experience.js +2 -1
- package/dist/src/orchestrator/should-run-gate.d.ts +5 -0
- package/dist/src/orchestrator/should-run-gate.js +18 -0
- package/dist/src/orchestrator/stall-watchdog.d.ts +31 -3
- package/dist/src/orchestrator/stall-watchdog.js +65 -10
- package/dist/src/orchestrator/stream-runner.d.ts +13 -3
- package/dist/src/orchestrator/stream-runner.js +115 -49
- package/dist/src/orchestrator/sub-agent-cap.d.ts +13 -1
- package/dist/src/orchestrator/sub-agent-cap.js +16 -1
- package/dist/src/orchestrator/sub-agent-model-tier.d.ts +13 -1
- package/dist/src/orchestrator/sub-agent-model-tier.js +16 -2
- package/dist/src/orchestrator/subagent-compactor.d.ts +53 -1
- package/dist/src/orchestrator/subagent-compactor.js +126 -15
- package/dist/src/orchestrator/tool-engine.d.ts +41 -0
- package/dist/src/orchestrator/tool-engine.js +846 -66
- package/dist/src/orchestrator/tool-limit-auto-recover.d.ts +22 -0
- package/dist/src/orchestrator/tool-limit-auto-recover.js +30 -0
- package/dist/src/orchestrator/turn-runner-deps.d.ts +19 -0
- package/dist/src/orchestrator/turn-watchdog.d.ts +44 -0
- package/dist/src/orchestrator/turn-watchdog.js +84 -0
- package/dist/src/pil/agent-operating-contract.d.ts +1 -1
- package/dist/src/pil/agent-operating-contract.js +6 -4
- package/dist/src/pil/cheap-model-playbook.d.ts +1 -1
- package/dist/src/pil/cheap-model-playbook.js +5 -1
- package/dist/src/pil/cheap-model-workbooks.d.ts +1 -1
- package/dist/src/pil/cheap-model-workbooks.js +1 -1
- package/dist/src/pil/discovery-types.d.ts +1 -0
- package/dist/src/pil/discovery.d.ts +1 -1
- package/dist/src/pil/discovery.js +18 -13
- package/dist/src/pil/layer1-intent.d.ts +18 -6
- package/dist/src/pil/layer1-intent.js +66 -757
- package/dist/src/pil/layer15-context-scan.js +15 -1
- package/dist/src/pil/layer1_5-complexity-size.d.ts +7 -0
- package/dist/src/pil/layer1_5-complexity-size.js +31 -5
- package/dist/src/pil/layer3-ee-injection.js +23 -8
- package/dist/src/pil/layer4-gsd.js +69 -16
- package/dist/src/pil/layer5-context.js +7 -3
- package/dist/src/pil/layer6-output.d.ts +23 -0
- package/dist/src/pil/layer6-output.js +5 -1
- package/dist/src/pil/llm-classify.d.ts +111 -5
- package/dist/src/pil/llm-classify.js +421 -189
- package/dist/src/pil/native-capabilities-workbook.d.ts +1 -1
- package/dist/src/pil/native-capabilities-workbook.js +8 -0
- package/dist/src/pil/pipeline.js +36 -2
- package/dist/src/pil/repo-grounding-probe.d.ts +15 -0
- package/dist/src/pil/repo-grounding-probe.js +136 -0
- package/dist/src/pil/repo-structure-hints.d.ts +7 -0
- package/dist/src/pil/repo-structure-hints.js +45 -0
- package/dist/src/pil/response-tools.js +5 -3
- package/dist/src/pil/schema.d.ts +1 -0
- package/dist/src/pil/schema.js +2 -0
- package/dist/src/pil/types.d.ts +18 -0
- package/dist/src/playbook/directives.d.ts +4 -0
- package/dist/src/playbook/directives.js +17 -5
- package/dist/src/product-loop/artifact-io.js +4 -0
- package/dist/src/product-loop/backlog-builder.d.ts +14 -1
- package/dist/src/product-loop/backlog-builder.js +30 -6
- package/dist/src/product-loop/criteria-seed.d.ts +51 -0
- package/dist/src/product-loop/criteria-seed.js +200 -0
- package/dist/src/product-loop/discovery-context-format.js +3 -1
- package/dist/src/product-loop/discovery-ecosystem.js +4 -1
- package/dist/src/product-loop/discovery-interview.d.ts +9 -0
- package/dist/src/product-loop/discovery-interview.js +60 -12
- package/dist/src/product-loop/discovery-recommender.js +2 -1
- package/dist/src/product-loop/discovery-schema.js +19 -2
- package/dist/src/product-loop/discovery-triage.d.ts +23 -0
- package/dist/src/product-loop/discovery-triage.js +109 -0
- package/dist/src/product-loop/gather.js +150 -2
- package/dist/src/product-loop/ideal-trace.d.ts +7 -0
- package/dist/src/product-loop/ideal-trace.js +64 -0
- package/dist/src/product-loop/index.d.ts +13 -1
- package/dist/src/product-loop/index.js +340 -52
- package/dist/src/product-loop/loop-driver.d.ts +7 -0
- package/dist/src/product-loop/loop-driver.js +330 -106
- package/dist/src/product-loop/phase-plan.d.ts +21 -0
- package/dist/src/product-loop/phase-plan.js +81 -6
- package/dist/src/product-loop/phase-rituals.d.ts +3 -0
- package/dist/src/product-loop/phase-rituals.js +8 -3
- package/dist/src/product-loop/phase-runner.js +39 -12
- package/dist/src/product-loop/plan-adherence-review.d.ts +26 -0
- package/dist/src/product-loop/plan-adherence-review.js +144 -0
- package/dist/src/product-loop/sprint-runner.d.ts +173 -0
- package/dist/src/product-loop/sprint-runner.js +863 -19
- package/dist/src/product-loop/types.d.ts +61 -5
- package/dist/src/providers/adapter.d.ts +1 -1
- package/dist/src/providers/adapter.js +3 -4
- package/dist/src/providers/anthropic.d.ts +9 -8
- package/dist/src/providers/anthropic.js +13 -47
- package/dist/src/providers/auth/browser-flow.d.ts +1 -1
- package/dist/src/providers/auth/browser-flow.js +1 -1
- package/dist/src/providers/auth/grok-oauth.d.ts +1 -0
- package/dist/src/providers/auth/grok-oauth.js +30 -5
- package/dist/src/providers/auth/openai-oauth.d.ts +1 -0
- package/dist/src/providers/auth/openai-oauth.js +15 -1
- package/dist/src/providers/auth/registry.js +0 -34
- package/dist/src/providers/auth/token-store.d.ts +9 -9
- package/dist/src/providers/auth/token-store.js +8 -67
- package/dist/src/providers/auth/types.d.ts +9 -1
- package/dist/src/providers/auth/types.js +1 -1
- package/dist/src/providers/capabilities.d.ts +24 -5
- package/dist/src/providers/capabilities.js +42 -24
- package/dist/src/providers/endpoints.d.ts +2 -2
- package/dist/src/providers/endpoints.js +11 -10
- package/dist/src/providers/env-store.d.ts +17 -0
- package/dist/src/providers/env-store.js +228 -0
- package/dist/src/providers/keychain.d.ts +22 -18
- package/dist/src/providers/keychain.js +127 -140
- package/dist/src/providers/mcp-vision-bridge.js +56 -146
- package/dist/src/providers/openai-compatible.js +8 -1
- package/dist/src/providers/pricing.d.ts +2 -2
- package/dist/src/providers/pricing.js +3 -13
- package/dist/src/providers/runtime.d.ts +43 -3
- package/dist/src/providers/runtime.js +88 -14
- package/dist/src/providers/strategies/base.strategy.d.ts +16 -0
- package/dist/src/providers/strategies/base.strategy.js +24 -1
- package/dist/src/providers/strategies/{siliconflow.strategy.d.ts → opencode-go.strategy.d.ts} +3 -3
- package/dist/src/providers/strategies/opencode-go.strategy.js +83 -0
- package/dist/src/providers/strategies/registry.js +4 -4
- package/dist/src/providers/strategies/thinking-mode.d.ts +109 -0
- package/dist/src/providers/strategies/thinking-mode.js +288 -1
- package/dist/src/providers/strategies/xai.strategy.js +27 -0
- package/dist/src/providers/strategies/zai.strategy.d.ts +14 -0
- package/dist/src/providers/strategies/zai.strategy.js +44 -0
- package/dist/src/providers/types.d.ts +5 -6
- package/dist/src/providers/types.js +2 -2
- package/dist/src/providers/vision-backend.d.ts +47 -0
- package/dist/src/providers/vision-backend.js +258 -0
- package/dist/src/providers/vision-proxy.d.ts +22 -9
- package/dist/src/providers/vision-proxy.js +63 -132
- package/dist/src/providers/warm.d.ts +65 -0
- package/dist/src/providers/warm.js +145 -0
- package/dist/src/providers/wire-debug.js +95 -0
- package/dist/src/router/decide.d.ts +13 -0
- package/dist/src/router/decide.js +138 -36
- package/dist/src/router/peak-hour.d.ts +38 -0
- package/dist/src/router/peak-hour.js +107 -0
- package/dist/src/router/step-router.js +3 -2
- package/dist/src/router/warm.js +4 -5
- package/dist/src/scaffold/continuation-prompt.d.ts +11 -0
- package/dist/src/scaffold/continuation-prompt.js +26 -0
- package/dist/src/scaffold/point-to-existing.d.ts +21 -0
- package/dist/src/scaffold/point-to-existing.js +25 -0
- package/dist/src/self-qa/agentic-loop.js +6 -5
- package/dist/src/{ui/state → state}/active-run.d.ts +19 -0
- package/dist/src/{ui/state → state}/active-run.js +21 -0
- package/dist/src/{ui/status-bar/store.d.ts → state/status-bar-store.d.ts} +4 -1
- package/dist/src/{ui/status-bar/store.js → state/status-bar-store.js} +12 -9
- package/dist/src/state/turn-trace.d.ts +43 -0
- package/dist/src/state/turn-trace.js +32 -0
- package/dist/src/storage/db.js +2 -1
- package/dist/src/storage/index.d.ts +1 -1
- package/dist/src/storage/index.js +1 -1
- package/dist/src/storage/interaction-log.d.ts +1 -1
- package/dist/src/storage/migrations.js +71 -1
- package/dist/src/storage/sessions.d.ts +28 -10
- package/dist/src/storage/sessions.js +78 -21
- package/dist/src/storage/transcript-view.js +1 -1
- package/dist/src/storage/transcript.d.ts +51 -0
- package/dist/src/storage/transcript.js +340 -15
- package/dist/src/tools/file.d.ts +15 -0
- package/dist/src/tools/file.js +32 -0
- package/dist/src/tools/git-safety.d.ts +19 -0
- package/dist/src/tools/git-safety.js +168 -0
- package/dist/src/tools/native-tools.d.ts +1 -1
- package/dist/src/tools/native-tools.js +81 -1
- package/dist/src/tools/registry.d.ts +20 -0
- package/dist/src/tools/registry.js +576 -23
- package/dist/src/tools/research.d.ts +29 -0
- package/dist/src/tools/research.js +233 -0
- package/dist/src/types/index.d.ts +147 -4
- package/dist/src/ui/app.js +0 -0
- package/dist/src/ui/cards/product-status-card.js +1 -1
- package/dist/src/ui/components/agent-rail-activities.d.ts +26 -0
- package/dist/src/ui/components/agent-rail-activities.js +47 -0
- package/dist/src/ui/components/bubble-body-guard.d.ts +27 -0
- package/dist/src/ui/components/bubble-body-guard.js +50 -0
- package/dist/src/ui/components/compact-progress-card.d.ts +24 -0
- package/dist/src/ui/components/compact-progress-card.js +42 -0
- package/dist/src/ui/components/context-rail.d.ts +26 -0
- package/dist/src/ui/components/context-rail.js +33 -0
- package/dist/src/ui/components/council-conclusion-card.d.ts +73 -0
- package/dist/src/ui/components/council-conclusion-card.js +420 -0
- package/dist/src/ui/components/council-debate-pill.d.ts +36 -0
- package/dist/src/ui/components/council-debate-pill.js +34 -0
- package/dist/src/ui/components/council-info-card.js +2 -2
- package/dist/src/ui/components/council-leader-bubble.d.ts +10 -3
- package/dist/src/ui/components/council-leader-bubble.js +21 -11
- package/dist/src/ui/components/council-message-bubble.d.ts +15 -2
- package/dist/src/ui/components/council-message-bubble.js +16 -15
- package/dist/src/ui/components/council-phase-timeline.d.ts +9 -1
- package/dist/src/ui/components/council-phase-timeline.js +66 -17
- package/dist/src/ui/components/council-placeholder-bubble.d.ts +16 -9
- package/dist/src/ui/components/council-placeholder-bubble.js +32 -29
- package/dist/src/ui/components/council-question-card.js +13 -12
- package/dist/src/ui/components/council-rail-rounds.d.ts +26 -0
- package/dist/src/ui/components/council-rail-rounds.js +57 -0
- package/dist/src/ui/components/council-round-group.d.ts +38 -0
- package/dist/src/ui/components/council-round-group.js +88 -0
- package/dist/src/ui/components/council-status-list.d.ts +3 -1
- package/dist/src/ui/components/council-status-list.js +36 -24
- package/dist/src/ui/components/council-synthesis-banner.d.ts +7 -2
- package/dist/src/ui/components/council-synthesis-banner.js +20 -5
- package/dist/src/ui/components/halt-recovery-card.js +9 -5
- package/dist/src/ui/components/jump-to-latest-pill.d.ts +11 -0
- package/dist/src/ui/components/jump-to-latest-pill.js +14 -0
- package/dist/src/ui/components/message-view.d.ts +15 -0
- package/dist/src/ui/components/message-view.js +50 -1
- package/dist/src/ui/components/prompt-box.js +18 -16
- package/dist/src/ui/components/session-tree-card.d.ts +14 -0
- package/dist/src/ui/components/session-tree-card.js +46 -0
- package/dist/src/ui/components/slash-inline-menu.d.ts +12 -0
- package/dist/src/ui/components/slash-inline-menu.js +26 -5
- package/dist/src/ui/components/task-list-panel.d.ts +14 -1
- package/dist/src/ui/components/task-list-panel.js +22 -2
- package/dist/src/ui/components/tool-group.d.ts +15 -3
- package/dist/src/ui/components/tool-group.js +69 -11
- package/dist/src/ui/containers/modals-layer.d.ts +4 -2
- package/dist/src/ui/containers/modals-layer.js +2 -2
- package/dist/src/ui/council-harness-event.d.ts +57 -0
- package/dist/src/ui/council-harness-event.js +46 -0
- package/dist/src/ui/heartbeat-debug.d.ts +29 -0
- package/dist/src/ui/heartbeat-debug.js +45 -0
- package/dist/src/ui/hooks/use-session-picker.d.ts +3 -3
- package/dist/src/ui/mcp-modal.js +2 -4
- package/dist/src/ui/modals/api-key-modal.js +1 -1
- package/dist/src/ui/modals/connect-modal.js +4 -3
- package/dist/src/ui/modals/model-picker-modal.d.ts +8 -18
- package/dist/src/ui/modals/model-picker-modal.js +8 -10
- package/dist/src/ui/modals/session-picker-modal.d.ts +2 -2
- package/dist/src/ui/modals/session-picker-modal.js +3 -5
- package/dist/src/ui/picker-providers.d.ts +1 -1
- package/dist/src/ui/picker-providers.js +1 -1
- package/dist/src/ui/primitives/index.d.ts +1 -0
- package/dist/src/ui/primitives/index.js +2 -0
- package/dist/src/ui/primitives/semantic-primitives.d.ts +76 -0
- package/dist/src/ui/primitives/semantic-primitives.js +81 -0
- package/dist/src/ui/slash/compact.js +5 -7
- package/dist/src/ui/slash/cost.js +1 -1
- package/dist/src/ui/slash/council.js +19 -1
- package/dist/src/ui/slash/debug.d.ts +3 -31
- package/dist/src/ui/slash/debug.js +9 -20
- package/dist/src/ui/slash/ee.js +81 -0
- package/dist/src/ui/slash/ideal.d.ts +6 -2
- package/dist/src/ui/slash/ideal.js +97 -7
- package/dist/src/ui/slash/menu-items.d.ts +7 -0
- package/dist/src/ui/slash/menu-items.js +23 -20
- package/dist/src/ui/slash/registry.d.ts +2 -0
- package/dist/src/ui/slash/registry.js +4 -0
- package/dist/src/ui/status-bar/cache-hit.d.ts +6 -0
- package/dist/src/ui/status-bar/cache-hit.js +9 -0
- package/dist/src/ui/status-bar/index.d.ts +1 -1
- package/dist/src/ui/status-bar/index.js +7 -3
- package/dist/src/ui/status-bar/usd-meter.d.ts +5 -4
- package/dist/src/ui/status-bar/usd-meter.js +6 -4
- package/dist/src/ui/theme.d.ts +1 -0
- package/dist/src/ui/theme.js +2 -0
- package/dist/src/ui/types.d.ts +7 -0
- package/dist/src/ui/use-app-logic.js +0 -0
- package/dist/src/ui/utils/agent-activities.d.ts +39 -0
- package/dist/src/ui/utils/agent-activities.js +96 -0
- package/dist/src/ui/utils/format.d.ts +14 -0
- package/dist/src/ui/utils/format.js +23 -3
- package/dist/src/ui/utils/group-tool-entries.d.ts +26 -0
- package/dist/src/ui/utils/group-tool-entries.js +111 -0
- package/dist/src/ui/utils/tool-summary.d.ts +21 -0
- package/dist/src/ui/utils/tool-summary.js +91 -0
- package/dist/src/usage/downgrade.js +2 -2
- package/dist/src/usage/product-ledger.js +2 -2
- package/dist/src/utils/event-loop-monitor.d.ts +85 -0
- package/dist/src/utils/event-loop-monitor.js +107 -0
- package/dist/src/utils/install-manager.js +2 -1
- package/dist/src/utils/llm-deadline.d.ts +14 -0
- package/dist/src/utils/llm-deadline.js +19 -0
- package/dist/src/utils/logger.js +2 -2
- package/dist/src/utils/loop-profiler.d.ts +102 -0
- package/dist/src/utils/loop-profiler.js +202 -0
- package/dist/src/utils/permission-mode.js +5 -3
- package/dist/src/utils/redactor.js +1 -1
- package/dist/src/utils/settings.d.ts +180 -5
- package/dist/src/utils/settings.js +271 -31
- package/dist/src/utils/side-question.d.ts +1 -2
- package/dist/src/utils/side-question.js +2 -2
- package/dist/src/utils/visible-retry.d.ts +11 -0
- package/dist/src/utils/visible-retry.js +10 -1
- package/dist/src/verify/entrypoint.d.ts +1 -1
- package/dist/src/verify/entrypoint.js +52 -17
- package/dist/src/verify/orchestrator.d.ts +1 -1
- package/dist/src/verify/orchestrator.js +20 -3
- package/dist/src/verify/recipes.d.ts +13 -0
- package/dist/src/verify/recipes.js +15 -0
- package/package.json +134 -132
- package/dist/src/cli/bw-vault.d.ts +0 -55
- package/dist/src/cli/bw-vault.js +0 -133
- package/dist/src/mcp/ee-tools.d.ts +0 -46
- package/dist/src/mcp/ee-tools.js +0 -193
- package/dist/src/providers/auth/gcloud.d.ts +0 -28
- package/dist/src/providers/auth/gcloud.js +0 -102
- package/dist/src/providers/auth/gemini-oauth.d.ts +0 -82
- package/dist/src/providers/auth/gemini-oauth.js +0 -472
- package/dist/src/providers/gemini.d.ts +0 -11
- package/dist/src/providers/gemini.js +0 -45
- package/dist/src/providers/siliconflow-sse-repair.d.ts +0 -58
- package/dist/src/providers/siliconflow-sse-repair.js +0 -177
- package/dist/src/providers/strategies/google.strategy.d.ts +0 -22
- package/dist/src/providers/strategies/google.strategy.js +0 -174
- package/dist/src/providers/strategies/siliconflow.strategy.js +0 -29
- package/dist/src/ui/containers/chat-feed.d.ts +0 -40
- package/dist/src/ui/containers/chat-feed.js +0 -66
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import type { CouncilMessage } from "../../types/index.js";
|
|
2
|
+
import type { Theme } from "../theme.js";
|
|
2
3
|
export interface CouncilSynthesisBannerProps {
|
|
3
4
|
msg: CouncilMessage;
|
|
5
|
+
theme: Theme;
|
|
4
6
|
}
|
|
5
7
|
export declare function buildSynthesisTitle(round: number | undefined): string;
|
|
6
8
|
/**
|
|
7
|
-
*
|
|
9
|
+
* Round / final synthesis, rendered as a linear group-chat row that closes the
|
|
10
|
+
* thread. A synthesis-colored left bar + bold title distinguishes the leader's
|
|
11
|
+
* verdict from the debate turns while staying in the same downward stream (no
|
|
12
|
+
* centered/full-width banner that broke the chat flow).
|
|
8
13
|
*/
|
|
9
|
-
export declare function CouncilSynthesisBanner({ msg }: CouncilSynthesisBannerProps): import("react").ReactNode;
|
|
14
|
+
export declare function CouncilSynthesisBanner({ msg, theme: t }: CouncilSynthesisBannerProps): import("react").ReactNode;
|
|
@@ -1,15 +1,30 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "@opentui/react/jsx-runtime";
|
|
2
|
-
import { dark } from "../theme.js";
|
|
3
2
|
import { truncateCodeBlocks } from "./code-block-truncate.js";
|
|
3
|
+
import { CouncilConclusionCard, parseConclusion } from "./council-conclusion-card.js";
|
|
4
4
|
export function buildSynthesisTitle(round) {
|
|
5
5
|
return round === undefined ? "Final Synthesis" : `Round ${round} Synthesis`;
|
|
6
6
|
}
|
|
7
7
|
/**
|
|
8
|
-
*
|
|
8
|
+
* Round / final synthesis, rendered as a linear group-chat row that closes the
|
|
9
|
+
* thread. A synthesis-colored left bar + bold title distinguishes the leader's
|
|
10
|
+
* verdict from the debate turns while staying in the same downward stream (no
|
|
11
|
+
* centered/full-width banner that broke the chat flow).
|
|
9
12
|
*/
|
|
10
|
-
export function CouncilSynthesisBanner({ msg }) {
|
|
11
|
-
|
|
13
|
+
export function CouncilSynthesisBanner({ msg, theme: t }) {
|
|
14
|
+
// When the synthesis is a structured evaluation/decision JSON, render it as a
|
|
15
|
+
// scannable conclusion card instead of dumping raw JSON as freetext. Prose
|
|
16
|
+
// syntheses (no parseable JSON object) fall through to the plain-text path.
|
|
17
|
+
const conclusion = parseConclusion(msg.text);
|
|
18
|
+
if (conclusion) {
|
|
19
|
+
return _jsx(CouncilConclusionCard, { conclusion: conclusion, round: msg.round, theme: t });
|
|
20
|
+
}
|
|
21
|
+
// A `---READABLE---` marker means the synthesizer already produced a human
|
|
22
|
+
// prose tail — show ONLY that tail, not the raw JSON above it. Empty tail
|
|
23
|
+
// (marker at the very end) falls back to the full text.
|
|
24
|
+
const raw = msg.text.trim();
|
|
25
|
+
const readableIdx = raw.indexOf("---READABLE---");
|
|
26
|
+
const bodyText = truncateCodeBlocks(readableIdx !== -1 ? raw.slice(readableIdx + "---READABLE---".length).trim() || raw : raw);
|
|
12
27
|
const title = buildSynthesisTitle(msg.round);
|
|
13
|
-
return (
|
|
28
|
+
return (_jsxs("box", { flexDirection: "column", marginBottom: 1, border: ["left"], borderColor: t.councilSynthesisBorder, paddingLeft: 2, children: [_jsx("text", { fg: t.councilSynthesisBorder, attributes: 1, children: title }), _jsx("text", { fg: t.text, children: bodyText })] }));
|
|
14
29
|
}
|
|
15
30
|
//# sourceMappingURL=council-synthesis-banner.js.map
|
|
@@ -14,14 +14,18 @@ import { Semantic } from "@muonroi/agent-harness-opentui";
|
|
|
14
14
|
const MAX_CARD_COLS = 100;
|
|
15
15
|
const FALLBACK_THRESHOLD = 70;
|
|
16
16
|
const REASON_LABELS = {
|
|
17
|
-
no_recipe: "No
|
|
18
|
-
zero_coverage: "
|
|
19
|
-
budget_exhausted: "Token budget
|
|
17
|
+
no_recipe: "No verification recipe found",
|
|
18
|
+
zero_coverage: "No test coverage found",
|
|
19
|
+
budget_exhausted: "Token budget used up",
|
|
20
|
+
sprint_failed: "Sprint failed",
|
|
20
21
|
};
|
|
21
22
|
export function HaltRecoveryCard({ halt, selectedIndex, terminalCols, theme }) {
|
|
22
23
|
const fallback = terminalCols < FALLBACK_THRESHOLD;
|
|
23
24
|
const width = fallback ? terminalCols : Math.min(terminalCols - 2, MAX_CARD_COLS);
|
|
24
|
-
|
|
25
|
-
|
|
25
|
+
// A — a sprint break titles with the failing sprint number ("Sprint 3 failed").
|
|
26
|
+
const title = halt.reason === "sprint_failed" && typeof halt.sprintN === "number"
|
|
27
|
+
? `Halted — Sprint ${halt.sprintN} failed`
|
|
28
|
+
: `Halted — ${REASON_LABELS[halt.reason] ?? halt.reason}`;
|
|
29
|
+
return (_jsx(Semantic, { id: "ideal-halt-card", role: "dialog", name: "Recovery options", isModal: true, children: _jsx("box", { flexDirection: "column", marginBottom: 1, children: _jsxs("box", { width: width, borderStyle: "single", borderColor: theme.haltCardBorder, flexDirection: "column", paddingLeft: 1, paddingRight: 1, children: [_jsx("text", { fg: theme.haltCardTitle, attributes: 1, children: title }), halt.detail && (_jsx("text", { fg: theme.haltCardDetail, marginTop: 1, children: halt.detail })), _jsx("box", { flexDirection: "column", marginTop: 1, children: halt.recovery_options.map((opt, i) => (_jsxs(Semantic, { id: `halt-option-${opt.id}`, role: "listitem", name: opt.label, selected: i === selectedIndex || undefined, children: [_jsx("box", { flexDirection: "row", marginBottom: 0, children: _jsxs("text", { fg: i === selectedIndex ? theme.haltCardOptionSelected : theme.haltCardOptionDefault, children: [i === selectedIndex ? "▶ " : " ", opt.label] }) }), _jsx("box", { flexDirection: "row", marginLeft: 2, children: _jsx("text", { fg: theme.haltCardOptionDesc, children: opt.description }) })] }, opt.id))) }), _jsx("text", { fg: theme.haltCardHint, marginTop: 1, children: "\u2191/\u2193 to browse \u00B7 Enter to select \u00B7 Esc to dismiss" })] }) }) }));
|
|
26
30
|
}
|
|
27
31
|
//# sourceMappingURL=halt-recovery-card.js.map
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface JumpToLatestPillProps {
|
|
2
|
+
/** Number of new appends suppressed since the user scrolled up. */
|
|
3
|
+
newSinceLock: number;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Scroll-lock affordance (MUONROI_SCROLL_LOCK): shown pinned to the bottom of
|
|
7
|
+
* the transcript when the user has scrolled up while new content is arriving.
|
|
8
|
+
* Pressing End re-pins to the live tail. Glyph-free (ASCII only) so it renders
|
|
9
|
+
* on every terminal — the debate pill work proved non-`● ✓` glyphs are unsafe.
|
|
10
|
+
*/
|
|
11
|
+
export declare function JumpToLatestPill({ newSinceLock }: JumpToLatestPillProps): import("react").ReactNode;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { jsx as _jsx } from "@opentui/react/jsx-runtime";
|
|
2
|
+
import { Semantic } from "@muonroi/agent-harness-opentui";
|
|
3
|
+
import { dark } from "../theme.js";
|
|
4
|
+
/**
|
|
5
|
+
* Scroll-lock affordance (MUONROI_SCROLL_LOCK): shown pinned to the bottom of
|
|
6
|
+
* the transcript when the user has scrolled up while new content is arriving.
|
|
7
|
+
* Pressing End re-pins to the live tail. Glyph-free (ASCII only) so it renders
|
|
8
|
+
* on every terminal — the debate pill work proved non-`● ✓` glyphs are unsafe.
|
|
9
|
+
*/
|
|
10
|
+
export function JumpToLatestPill({ newSinceLock }) {
|
|
11
|
+
const label = newSinceLock > 0 ? `${newSinceLock} new below - press End to jump` : "press End to jump to latest";
|
|
12
|
+
return (_jsx(Semantic, { id: "jump-to-latest", role: "region", props: { newSinceLock }, children: _jsx("box", { flexDirection: "row", alignSelf: "center", paddingLeft: 1, paddingRight: 1, backgroundColor: dark.accent, children: _jsx("text", { fg: "#ffffff", attributes: 1, children: label }) }) }));
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=jump-to-latest-pill.js.map
|
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
import type { ChatEntry } from "../../types/index.js";
|
|
2
2
|
import type { Theme } from "../theme.js";
|
|
3
|
+
/**
|
|
4
|
+
* Index of the newest entry that renders a `ctrl+e` affordance, or -1.
|
|
5
|
+
*
|
|
6
|
+
* The TUI has ONE global ctrl+e, so it must resolve to a single target. Every
|
|
7
|
+
* component that prints "ctrl+e expand" must be represented here, otherwise the
|
|
8
|
+
* affordance lies: it tells the user a key works while nothing is listening.
|
|
9
|
+
* Mirrors the collapse conditions in AssistantMessageContent / UserMessageContent
|
|
10
|
+
* / ReasoningContent / ToolGroupView — keep the two in sync.
|
|
11
|
+
*/
|
|
12
|
+
export declare function findLastCollapsibleIndex(messages: ChatEntry[]): number;
|
|
13
|
+
export declare function ReasoningContent({ content, t, expanded }: {
|
|
14
|
+
content: string;
|
|
15
|
+
t: Theme;
|
|
16
|
+
expanded: boolean;
|
|
17
|
+
}): import("react").ReactNode;
|
|
3
18
|
export declare function AssistantMessageContent({ content, t, expanded, isFinal, }: {
|
|
4
19
|
content: string;
|
|
5
20
|
t: Theme;
|
|
@@ -28,6 +28,55 @@ const USER_MSG_COLLAPSED_LINES = 5;
|
|
|
28
28
|
// to this many lines to stop the chat scroll wall and cut markdown re-render
|
|
29
29
|
// cost. 8 fits comfortably on a short terminal and conveys the gist.
|
|
30
30
|
const ASSISTANT_MSG_COLLAPSED_LINES = 8;
|
|
31
|
+
// Chain-of-thought is never the answer — it is the model talking to itself.
|
|
32
|
+
// Unlike the final assistant message (which must stay fully visible), reasoning
|
|
33
|
+
// collapses even on the final entry: once the turn is answered, a wall of
|
|
34
|
+
// "[Thought]" above the reply is pure noise. 3 lines keeps a gist visible.
|
|
35
|
+
const REASONING_COLLAPSED_LINES = 3;
|
|
36
|
+
/**
|
|
37
|
+
* Index of the newest entry that renders a `ctrl+e` affordance, or -1.
|
|
38
|
+
*
|
|
39
|
+
* The TUI has ONE global ctrl+e, so it must resolve to a single target. Every
|
|
40
|
+
* component that prints "ctrl+e expand" must be represented here, otherwise the
|
|
41
|
+
* affordance lies: it tells the user a key works while nothing is listening.
|
|
42
|
+
* Mirrors the collapse conditions in AssistantMessageContent / UserMessageContent
|
|
43
|
+
* / ReasoningContent / ToolGroupView — keep the two in sync.
|
|
44
|
+
*/
|
|
45
|
+
export function findLastCollapsibleIndex(messages) {
|
|
46
|
+
let lastAssistantIdx = -1;
|
|
47
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
48
|
+
if (messages[i]?.type === "assistant") {
|
|
49
|
+
lastAssistantIdx = i;
|
|
50
|
+
break;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
const lineCount = (s) => (s ? s.split("\n").length : 0);
|
|
54
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
55
|
+
const m = messages[i];
|
|
56
|
+
if (!m)
|
|
57
|
+
continue;
|
|
58
|
+
if (m.type === "user" && lineCount(m.content) > USER_MSG_COLLAPSED_LINES)
|
|
59
|
+
return i;
|
|
60
|
+
if (m.type === "assistant") {
|
|
61
|
+
if (lineCount(m.reasoning) > REASONING_COLLAPSED_LINES)
|
|
62
|
+
return i;
|
|
63
|
+
// The final assistant message never auto-collapses its body (F7), so it
|
|
64
|
+
// offers no body affordance to toggle.
|
|
65
|
+
if (i !== lastAssistantIdx && lineCount(m.content) > ASSISTANT_MSG_COLLAPSED_LINES)
|
|
66
|
+
return i;
|
|
67
|
+
}
|
|
68
|
+
if (m.type === "tool_group" && m.toolGroup?.state === "done" && (m.toolGroup?.items.length ?? 0) > 0)
|
|
69
|
+
return i;
|
|
70
|
+
}
|
|
71
|
+
return -1;
|
|
72
|
+
}
|
|
73
|
+
export function ReasoningContent({ content, t, expanded }) {
|
|
74
|
+
const lines = content.split("\n");
|
|
75
|
+
const isLong = lines.length > REASONING_COLLAPSED_LINES;
|
|
76
|
+
const body = !isLong || expanded ? content : lines.slice(0, REASONING_COLLAPSED_LINES).join("\n");
|
|
77
|
+
const hidden = lines.length - REASONING_COLLAPSED_LINES;
|
|
78
|
+
return (_jsxs("box", { paddingLeft: 0, marginBottom: 1, flexShrink: 0, flexDirection: "column", children: [_jsx("text", { fg: t.textMuted, children: "[Thought] Thought" }), _jsxs("box", { border: ["left"], borderColor: t.textMuted, paddingLeft: 2, marginTop: 1, flexDirection: "column", children: [_jsx(Markdown, { content: body, t: t }), isLong && (_jsxs("text", { fg: t.textDim, children: ["ctrl+e ", _jsx("span", { style: { fg: t.textMuted }, children: expanded ? "collapse" : `expand (${hidden} more lines)` })] }))] })] }));
|
|
79
|
+
}
|
|
31
80
|
export function AssistantMessageContent({ content, t, expanded, isFinal, }) {
|
|
32
81
|
// Strip stray model self-annotation macros (e.g. grok's trailing
|
|
33
82
|
// `\confidence{85}`) that leak into the answer — not instructed in the prompt.
|
|
@@ -142,7 +191,7 @@ function MessageViewImpl({ entry, index, t, modeColor, expandedMessages, mcpRun,
|
|
|
142
191
|
// ignore
|
|
143
192
|
}
|
|
144
193
|
}
|
|
145
|
-
return (_jsxs("box", { paddingLeft: 3, marginTop: 1, flexShrink: 0, flexDirection: "column", children: [entry.sourceLabel ? _jsx("text", { fg: t.textMuted, children: entry.sourceLabel }) : null, entry.reasoning ? (
|
|
194
|
+
return (_jsxs("box", { paddingLeft: 3, marginTop: 1, flexShrink: 0, flexDirection: "column", children: [entry.sourceLabel ? _jsx("text", { fg: t.textMuted, children: entry.sourceLabel }) : null, entry.reasoning ? (_jsx(ReasoningContent, { content: entry.reasoning, t: t, expanded: expandedMessages?.has(index) ?? false })) : null, fallbackSr ? (_jsx(StructuredResponseView, { t: t, sr: fallbackSr, modeColor: entry.modeColor || modeColor })) : (_jsx(AssistantMessageContent, { content: entry.content, t: t, expanded: expandedMessages?.has(index) ?? false, isFinal: isFinalAssistant === true }))] }));
|
|
146
195
|
}
|
|
147
196
|
case "tool_call":
|
|
148
197
|
return (_jsx("box", { paddingLeft: 3, marginTop: 1, children: _jsxs("text", { children: [_jsx("span", { style: { fg: entry.modeColor || modeColor }, children: "▣ " }), _jsx("span", { style: { fg: t.textMuted }, children: entry.content.replace("▣ ", "") })] }) }));
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs
|
|
2
|
-
import { Semantic } from "@muonroi/agent-harness-opentui";
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "@opentui/react/jsx-runtime";
|
|
3
2
|
import { useEffect, useState } from "react";
|
|
4
3
|
import { PROMPT_LOADING_FRAMES } from "../constants.js";
|
|
4
|
+
import { Menu, TextBox } from "../primitives/index.js";
|
|
5
5
|
import { withAlpha } from "../utils/color.js";
|
|
6
6
|
import { SuggestionOverlay } from "./SuggestionOverlay.js";
|
|
7
7
|
import { ContextMeter } from "./session-header.js";
|
|
@@ -40,27 +40,29 @@ export function PromptModeLabel({ t, modeInfo, isProcessing, }) {
|
|
|
40
40
|
export function PromptBox({ t, inputRef, isProcessing, showModelPicker, showSandboxPicker, showWalletPicker, showSlashMenu, showPlanQuestions, showApiKeyModal, blockPrompt, onSubmit, onPaste, pasteBlocks: _pasteBlocks, modeInfo, model, modelInfo, contextStats, placeholder, queuedCount, queuedMessages, typeahead, slashItems, slashSelectedIndex, slashInputIsMatched, composerValue, }) {
|
|
41
41
|
const hasQueue = (queuedMessages?.length ?? 0) > 0;
|
|
42
42
|
const showSuggestions = typeahead?.visible ?? false;
|
|
43
|
+
// Single source of truth for composer focus — mirrored to BOTH the OpenTUI
|
|
44
|
+
// textarea (`focused`) and the semantic node (via TextBox `focused`). Keeping
|
|
45
|
+
// one expression avoids the two drifting apart (the harness would otherwise
|
|
46
|
+
// report a focus state that disagrees with what the textarea actually has).
|
|
47
|
+
const composerFocused = !showModelPicker &&
|
|
48
|
+
!showSandboxPicker &&
|
|
49
|
+
!showWalletPicker &&
|
|
50
|
+
!showPlanQuestions &&
|
|
51
|
+
!showApiKeyModal &&
|
|
52
|
+
!blockPrompt;
|
|
43
53
|
return (_jsxs("box", { backgroundColor: t.backgroundPanel, children: [_jsxs("box", { children: [hasQueue && (_jsxs("box", { paddingLeft: 2, paddingRight: 2, paddingTop: 1, paddingBottom: 1, backgroundColor: t.queueBg, flexShrink: 0, children: [queuedMessages.map((msg, i) => (
|
|
44
54
|
// biome-ignore lint/suspicious/noArrayIndexKey: append-only queue of plain strings
|
|
45
|
-
_jsxs("text", { fg: t.text, children: ["→ ", msg] }, i))), _jsx("box", { height: 1 }), _jsxs("text", { children: [_jsx("span", { style: { fg: t.primary }, children: "enter " }), _jsx("span", { style: { fg: t.textMuted }, children: "send now" }), _jsx("span", { style: { fg: t.textDim }, children: " · " }), _jsx("span", { style: { fg: t.primary }, children: "↑ " }), _jsx("span", { style: { fg: t.textMuted }, children: "edit" }), _jsx("span", { style: { fg: t.textDim }, children: " · " }), _jsx("span", { style: { fg: t.primary }, children: "esc " }), _jsx("span", { style: { fg: t.textMuted }, children: "cancel" })] })] })), showSlashMenu && slashItems && (_jsx(
|
|
55
|
+
_jsxs("text", { fg: t.text, children: ["→ ", msg] }, i))), _jsx("box", { height: 1 }), _jsxs("text", { children: [_jsx("span", { style: { fg: t.primary }, children: "enter " }), _jsx("span", { style: { fg: t.textMuted }, children: "send now" }), _jsx("span", { style: { fg: t.textDim }, children: " · " }), _jsx("span", { style: { fg: t.primary }, children: "↑ " }), _jsx("span", { style: { fg: t.textMuted }, children: "edit" }), _jsx("span", { style: { fg: t.textDim }, children: " · " }), _jsx("span", { style: { fg: t.primary }, children: "esc " }), _jsx("span", { style: { fg: t.textMuted }, children: "cancel" })] })] })), showSlashMenu && slashItems && (_jsx(Menu, { id: "slash-menu", name: "Slash commands", children: _jsx(SlashInlineMenu, { t: t, items: slashItems, selectedIndex: slashSelectedIndex ?? 0 }) })), showSuggestions && typeahead && (_jsx(SuggestionOverlay, { t: t, suggestions: typeahead.suggestions, selectedIndex: typeahead.selectedIndex })), _jsxs("box", { paddingLeft: 2, paddingRight: 2, paddingTop: 1, paddingBottom: 1, backgroundColor: t.backgroundElement, flexDirection: "row", gap: 2, alignItems: "flex-start", flexShrink: 0, children: [_jsx(PromptModeLabel, { t: t, modeInfo: modeInfo, isProcessing: isProcessing }), _jsx("box", { flexGrow: 1, children: _jsx(TextBox, { id: "composer",
|
|
46
56
|
// Mirror current composer text so external harness drivers
|
|
47
57
|
// can read back what the user typed. Prefer the textarea's
|
|
48
58
|
// actual plainText (ground truth) over composerValue (derived
|
|
49
59
|
// from slashSearchQuery). This makes post-Tab state visible
|
|
50
60
|
// even while the slash menu is technically still open — was
|
|
51
61
|
// hiding the trailing space inserted by Tab autocomplete.
|
|
52
|
-
value: inputRef.current?.plainText ?? composerValue ?? "",
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
!blockPrompt
|
|
58
|
-
? true
|
|
59
|
-
: undefined, children: _jsx("textarea", { ref: inputRef, focused: !showModelPicker &&
|
|
60
|
-
!showSandboxPicker &&
|
|
61
|
-
!showWalletPicker &&
|
|
62
|
-
!showPlanQuestions &&
|
|
63
|
-
!showApiKeyModal &&
|
|
64
|
-
!blockPrompt, placeholder: isProcessing ? "Queue a follow-up... (esc to interrupt)" : placeholder || "Message muonroi-cli...", textColor: slashInputIsMatched ? "#3b82f6" : t.text, backgroundColor: t.backgroundElement, placeholderColor: t.textMuted, minHeight: 1, maxHeight: 10, wrapMode: "word", keyBindings: TEXTAREA_KEYBINDINGS, onSubmit: onSubmit, onPaste: onPaste }) }) })] })] }), _jsxs("box", { flexDirection: "row", justifyContent: "space-between", alignItems: "center", paddingLeft: 2, paddingRight: 2, height: 1, flexShrink: 0, children: [_jsxs("box", { flexDirection: "row", gap: 1, alignItems: "center", height: 1, children: [_jsx("text", { fg: t.text, children: modelInfo?.name || model }), contextStats ? _jsx(ContextMeter, { t: t, stats: contextStats }) : null] }), _jsx("box", { flexDirection: "row", gap: 1, alignItems: "center", height: 1, children: isProcessing ? (_jsxs("box", { flexDirection: "row", gap: 1, children: [_jsxs("text", { fg: t.text, children: ["enter ", _jsx("span", { style: { fg: t.textMuted }, children: "queue" })] }), _jsxs("text", { fg: t.text, children: ["esc ", _jsx("span", { style: { fg: t.textMuted }, children: (queuedCount ?? 0) > 0 ? "clear queue" : "interrupt" })] })] })) : showSlashMenu ? (_jsxs("box", { flexDirection: "row", gap: 1, children: [_jsxs("text", { fg: t.text, children: ["↑↓ ", _jsx("span", { style: { fg: t.textMuted }, children: "navigate" })] }), _jsxs("text", { fg: t.text, children: ["enter ", _jsx("span", { style: { fg: t.textMuted }, children: "select" })] }), _jsxs("text", { fg: t.text, children: ["esc ", _jsx("span", { style: { fg: t.textMuted }, children: "dismiss" })] })] })) : showSuggestions ? (_jsxs("box", { flexDirection: "row", gap: 1, children: [_jsxs("text", { fg: t.text, children: ["tab ", _jsx("span", { style: { fg: t.textMuted }, children: "accept" })] }), _jsxs("text", { fg: t.text, children: ["↑↓ ", _jsx("span", { style: { fg: t.textMuted }, children: "navigate" })] }), _jsxs("text", { fg: t.text, children: ["esc ", _jsx("span", { style: { fg: t.textMuted }, children: "dismiss" })] })] })) : (_jsxs(_Fragment, { children: [_jsxs("text", { fg: t.text, children: ["@ ", _jsx("span", { style: { fg: t.textMuted }, children: "files" })] }), _jsxs("text", { fg: t.text, children: ["shift+enter ", _jsx("span", { style: { fg: t.textMuted }, children: "new line" })] }), _jsxs("text", { fg: t.text, children: ["tab ", _jsx("span", { style: { fg: t.textMuted }, children: "modes" })] })] })) })] })] }));
|
|
62
|
+
value: inputRef.current?.plainText ?? composerValue ?? "", focused: composerFocused, children: _jsx("textarea", { ref: inputRef, focused: composerFocused, placeholder: isProcessing ? "Queue a follow-up... (esc to interrupt)" : placeholder || "Message muonroi-cli...", textColor: slashInputIsMatched ? "#3b82f6" : t.text, backgroundColor: t.backgroundElement, placeholderColor: t.textMuted, minHeight: 1, maxHeight: 10, wrapMode: "word", keyBindings: TEXTAREA_KEYBINDINGS, onSubmit: onSubmit, onPaste: onPaste }) }) })] })] }), _jsxs("box", { flexDirection: "row", justifyContent: "space-between", alignItems: "center", paddingLeft: 2, paddingRight: 2, height: 1, flexShrink: 0, children: [_jsxs("box", { flexDirection: "row", gap: 1, alignItems: "center", height: 1, children: [_jsx("text", { fg: t.text, children: modelInfo?.name || model }), contextStats ? _jsx(ContextMeter, { t: t, stats: contextStats }) : null] }), _jsx("box", { flexDirection: "row", gap: 1, alignItems: "center", height: 1, children: isProcessing ? (_jsxs("box", { flexDirection: "row", gap: 1, children: [_jsxs("text", { fg: t.text, children: ["enter ", _jsx("span", { style: { fg: t.textMuted }, children: "queue" })] }), _jsxs("text", { fg: t.text, children: ["esc ", _jsx("span", { style: { fg: t.textMuted }, children: (queuedCount ?? 0) > 0 ? "clear queue" : "interrupt" })] })] })) : showSlashMenu ? (_jsxs("box", { flexDirection: "row", gap: 1, children: [_jsxs("text", { fg: t.text, children: ["↑↓ ", _jsx("span", { style: { fg: t.textMuted }, children: "navigate" })] }), _jsxs("text", { fg: t.text, children: ["enter ", _jsx("span", { style: { fg: t.textMuted }, children: "select" })] }), _jsxs("text", { fg: t.text, children: ["esc ", _jsx("span", { style: { fg: t.textMuted }, children: "dismiss" })] })] })) : showSuggestions ? (_jsxs("box", { flexDirection: "row", gap: 1, children: [_jsxs("text", { fg: t.text, children: ["tab ", _jsx("span", { style: { fg: t.textMuted }, children: "accept" })] }), _jsxs("text", { fg: t.text, children: ["↑↓ ", _jsx("span", { style: { fg: t.textMuted }, children: "navigate" })] }), _jsxs("text", { fg: t.text, children: ["esc ", _jsx("span", { style: { fg: t.textMuted }, children: "dismiss" })] })] })) : (
|
|
63
|
+
// Wrap in a gap'd row like the other three hint branches — a bare
|
|
64
|
+
// fragment let the three hints run together ("@ filesshift+enter new
|
|
65
|
+
// linetab modes"); the inner box restores the 1-col separators.
|
|
66
|
+
_jsxs("box", { flexDirection: "row", gap: 1, children: [_jsxs("text", { fg: t.text, children: ["@ ", _jsx("span", { style: { fg: t.textMuted }, children: "files" })] }), _jsxs("text", { fg: t.text, children: ["shift+enter ", _jsx("span", { style: { fg: t.textMuted }, children: "new line" })] }), _jsxs("text", { fg: t.text, children: ["tab ", _jsx("span", { style: { fg: t.textMuted }, children: "modes" })] })] })) })] })] }));
|
|
65
67
|
}
|
|
66
68
|
//# sourceMappingURL=prompt-box.js.map
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { SessionChainNode } from "../../storage/transcript.js";
|
|
2
|
+
/**
|
|
3
|
+
* Rail "Sessions" block: the session tree this TUI hosts — the root
|
|
4
|
+
* conversation plus every rotation / sub-agent descendant. The children's
|
|
5
|
+
* message content is already merged into the transcript on resume; this makes
|
|
6
|
+
* the multi-session structure VISIBLE (which session produced what, how many
|
|
7
|
+
* messages, whether it is the current one) instead of a flat anonymous timeline.
|
|
8
|
+
*
|
|
9
|
+
* Renders nothing extra when the tree is a single conversation (no sub-sessions)
|
|
10
|
+
* — keeps a lean rail for the common single-session case.
|
|
11
|
+
*/
|
|
12
|
+
export declare function SessionTreeCard({ nodes }: {
|
|
13
|
+
nodes: SessionChainNode[];
|
|
14
|
+
}): import("react").ReactNode;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "@opentui/react/jsx-runtime";
|
|
2
|
+
import { Semantic } from "@muonroi/agent-harness-opentui";
|
|
3
|
+
import { dark } from "../theme.js";
|
|
4
|
+
/** Short kind badge for the rail — keeps rows narrow in a ~34-col panel. */
|
|
5
|
+
function kindBadge(kind) {
|
|
6
|
+
switch (kind) {
|
|
7
|
+
case "subagent":
|
|
8
|
+
return "sub";
|
|
9
|
+
case "rotation":
|
|
10
|
+
return "rot";
|
|
11
|
+
case "conversation":
|
|
12
|
+
return "conv";
|
|
13
|
+
default:
|
|
14
|
+
return "·";
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
/** Trim a model id to its last path segment so "deepseek/deepseek-v4-flash"
|
|
18
|
+
* reads as "deepseek-v4-flash" in the narrow rail. */
|
|
19
|
+
function shortModel(model) {
|
|
20
|
+
if (!model)
|
|
21
|
+
return "—";
|
|
22
|
+
const seg = model.includes("/") ? model.slice(model.lastIndexOf("/") + 1) : model;
|
|
23
|
+
return seg.length > 16 ? `${seg.slice(0, 15)}…` : seg;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Rail "Sessions" block: the session tree this TUI hosts — the root
|
|
27
|
+
* conversation plus every rotation / sub-agent descendant. The children's
|
|
28
|
+
* message content is already merged into the transcript on resume; this makes
|
|
29
|
+
* the multi-session structure VISIBLE (which session produced what, how many
|
|
30
|
+
* messages, whether it is the current one) instead of a flat anonymous timeline.
|
|
31
|
+
*
|
|
32
|
+
* Renders nothing extra when the tree is a single conversation (no sub-sessions)
|
|
33
|
+
* — keeps a lean rail for the common single-session case.
|
|
34
|
+
*/
|
|
35
|
+
export function SessionTreeCard({ nodes }) {
|
|
36
|
+
if (nodes.length <= 1)
|
|
37
|
+
return null;
|
|
38
|
+
return (_jsx(Semantic, { id: "session-tree", role: "listbox", name: "Sessions", props: { count: nodes.length, ids: nodes.map((n) => n.id.slice(0, 8)).join(",") }, children: _jsxs("box", { flexDirection: "column", flexShrink: 0, paddingTop: 1, children: [_jsx("text", { fg: dark.textMuted, attributes: 1, children: `Sessions (${nodes.length})` }), nodes.map((n) => {
|
|
39
|
+
const indent = " ".repeat(Math.min(n.depth, 3));
|
|
40
|
+
const marker = n.isCurrent ? "●" : n.depth > 0 ? "↳" : "○";
|
|
41
|
+
const badge = kindBadge(n.kind);
|
|
42
|
+
const done = n.status && n.status !== "active";
|
|
43
|
+
return (_jsx(Semantic, { id: `session-node-${n.id}`, role: "listitem", name: `${badge} ${n.id.slice(0, 8)}`, value: `${n.messageCount} msg`, selected: n.isCurrent ? true : undefined, props: { kind: n.kind ?? "", status: n.status ?? "", messageCount: n.messageCount, depth: n.depth }, children: _jsx("box", { flexDirection: "column", children: _jsxs("text", { children: [_jsx("span", { style: { fg: n.isCurrent ? dark.selected : dark.textMuted }, children: `${indent}${marker} ` }), _jsx("span", { style: { fg: n.isCurrent ? dark.selected : dark.text }, children: `${badge} ` }), _jsx("span", { style: { fg: dark.textMuted }, children: `${n.id.slice(0, 8)} ${shortModel(n.model)} ` }), _jsx("span", { style: { fg: dark.text }, children: `${n.messageCount} msg` }), done ? _jsx("span", { style: { fg: dark.textDim }, children: ` ${n.status}` }) : null] }) }) }, n.id));
|
|
44
|
+
})] }) }));
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=session-tree-card.js.map
|
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
import type { SlashMenuItem } from "../slash/menu-items.js";
|
|
2
2
|
import type { Theme } from "../theme.js";
|
|
3
|
+
/**
|
|
4
|
+
* Compute the scrolling viewport for the slash dropdown so the highlighted row
|
|
5
|
+
* stays visible when the filtered list exceeds the window. Pure + exported so
|
|
6
|
+
* the scroll behavior is unit-testable without a live TUI (the api-key modal
|
|
7
|
+
* blocks a clean greenfield harness drive of the menu).
|
|
8
|
+
*/
|
|
9
|
+
export declare function computeSlashMenuWindow(total: number, selectedIndex: number, maxVisible?: number): {
|
|
10
|
+
start: number;
|
|
11
|
+
end: number;
|
|
12
|
+
hiddenAbove: number;
|
|
13
|
+
hiddenBelow: number;
|
|
14
|
+
};
|
|
3
15
|
export declare function SlashInlineMenu({ t, items, selectedIndex, }: {
|
|
4
16
|
t: Theme;
|
|
5
17
|
items: SlashMenuItem[];
|
|
@@ -1,14 +1,35 @@
|
|
|
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 SLASH_MENU_MAX_VISIBLE = 8;
|
|
4
|
+
/**
|
|
5
|
+
* Compute the scrolling viewport for the slash dropdown so the highlighted row
|
|
6
|
+
* stays visible when the filtered list exceeds the window. Pure + exported so
|
|
7
|
+
* the scroll behavior is unit-testable without a live TUI (the api-key modal
|
|
8
|
+
* blocks a clean greenfield harness drive of the menu).
|
|
9
|
+
*/
|
|
10
|
+
export function computeSlashMenuWindow(total, selectedIndex, maxVisible = SLASH_MENU_MAX_VISIBLE) {
|
|
11
|
+
if (total <= 0)
|
|
12
|
+
return { start: 0, end: 0, hiddenAbove: 0, hiddenBelow: 0 };
|
|
13
|
+
const clamped = Math.min(Math.max(0, selectedIndex), total - 1);
|
|
14
|
+
const start = total <= maxVisible ? 0 : Math.min(Math.max(0, clamped - maxVisible + 1), total - maxVisible);
|
|
15
|
+
const end = Math.min(start + maxVisible, total);
|
|
16
|
+
return { start, end, hiddenAbove: start, hiddenBelow: total - end };
|
|
17
|
+
}
|
|
4
18
|
export function SlashInlineMenu({ t, items, selectedIndex, }) {
|
|
5
|
-
|
|
6
|
-
if (visible.length === 0) {
|
|
19
|
+
if (items.length === 0) {
|
|
7
20
|
return (_jsx("box", { paddingLeft: 2, paddingRight: 2, paddingTop: 1, flexShrink: 0, flexDirection: "column", children: _jsx("box", { height: 1, paddingLeft: 1, children: _jsx("text", { fg: t.textMuted, children: "No commands match" }) }) }));
|
|
8
21
|
}
|
|
9
|
-
|
|
10
|
-
|
|
22
|
+
// Scrolling viewport: keep the highlighted row in view when the filtered list
|
|
23
|
+
// exceeds the visible window. Without this the window was pinned to
|
|
24
|
+
// items.slice(0,8) and pressing Down past index 7 moved the selection
|
|
25
|
+
// off-screen — the list "wouldn't continue past the initial suggestions".
|
|
26
|
+
const clampedSelected = Math.min(Math.max(0, selectedIndex), items.length - 1);
|
|
27
|
+
const { start: windowStart, hiddenAbove, hiddenBelow } = computeSlashMenuWindow(items.length, clampedSelected);
|
|
28
|
+
const visible = items.slice(windowStart, windowStart + SLASH_MENU_MAX_VISIBLE);
|
|
29
|
+
return (_jsxs("box", { paddingLeft: 2, paddingRight: 2, paddingTop: 1, flexShrink: 0, flexDirection: "column", children: [hiddenAbove > 0 && _jsx("text", { fg: t.textDim, children: ` ▲ ${hiddenAbove} more` }), visible.map((item, i) => {
|
|
30
|
+
const absoluteIndex = windowStart + i;
|
|
31
|
+
const isSelected = absoluteIndex === clampedSelected;
|
|
11
32
|
return (_jsx(Semantic, { id: `slash-item-${item.id}`, role: "listitem", name: `/${item.label}`, value: item.description, selected: isSelected ? true : undefined, children: _jsxs("box", { height: 1, backgroundColor: isSelected ? t.selectedBg : undefined, flexDirection: "row", justifyContent: "space-between", paddingLeft: 1, paddingRight: 1, children: [_jsxs("text", { fg: isSelected ? t.selected : t.text, children: ["/", item.label] }), _jsx("text", { fg: t.textMuted, children: item.description })] }) }, item.id));
|
|
12
|
-
}),
|
|
33
|
+
}), hiddenBelow > 0 && _jsx("text", { fg: t.textDim, children: ` ▼ ${hiddenBelow} more` })] }));
|
|
13
34
|
}
|
|
14
35
|
//# sourceMappingURL=slash-inline-menu.js.map
|
|
@@ -19,14 +19,27 @@
|
|
|
19
19
|
import type { TaskListItem, TaskListSnapshot } from "../../types/index.js";
|
|
20
20
|
import type { Theme } from "../theme.js";
|
|
21
21
|
declare function sortItems(items: ReadonlyArray<TaskListItem>): TaskListItem[];
|
|
22
|
+
/**
|
|
23
|
+
* One-line summary used by the collapsed panel. Kept pure + exported so it can be
|
|
24
|
+
* unit-tested without rendering OpenTUI. Mirrors the expanded footer's bucket
|
|
25
|
+
* wording so the two views read consistently.
|
|
26
|
+
*/
|
|
27
|
+
declare function buildCollapsedLine(snapshot: TaskListSnapshot): string;
|
|
22
28
|
export interface TaskListPanelProps {
|
|
23
29
|
snapshot: TaskListSnapshot;
|
|
24
30
|
t: Theme;
|
|
25
31
|
expanded: boolean;
|
|
32
|
+
/**
|
|
33
|
+
* Render a single summary line instead of the full panel. Set while a council
|
|
34
|
+
* debate is active so the todo band stops eating the debate scrollbox's height
|
|
35
|
+
* (~11 rows → 1). `ctrl+e` flips it back to the full panel for a peek.
|
|
36
|
+
*/
|
|
37
|
+
collapsed?: boolean;
|
|
26
38
|
}
|
|
27
|
-
export declare function TaskListPanel({ snapshot, t, expanded }: TaskListPanelProps): import("react").ReactNode;
|
|
39
|
+
export declare function TaskListPanel({ snapshot, t, expanded, collapsed }: TaskListPanelProps): import("react").ReactNode;
|
|
28
40
|
export declare const __TEST_ONLY__: {
|
|
29
41
|
sortItems: typeof sortItems;
|
|
30
42
|
MAX_VISIBLE: number;
|
|
43
|
+
buildCollapsedLine: typeof buildCollapsedLine;
|
|
31
44
|
};
|
|
32
45
|
export {};
|
|
@@ -54,9 +54,29 @@ function ItemRow({ item, t }) {
|
|
|
54
54
|
}
|
|
55
55
|
return (_jsx(Semantic, { id: `task-${item.id}`, role: "listitem", name: label, state: item.status, children: _jsx("box", { width: "100%", children: _jsxs("text", { fg: textColor, children: [_jsx("span", { style: { fg: glyphColor }, children: `${glyph} ` }), trunc(label, 70)] }) }) }));
|
|
56
56
|
}
|
|
57
|
-
|
|
57
|
+
/**
|
|
58
|
+
* One-line summary used by the collapsed panel. Kept pure + exported so it can be
|
|
59
|
+
* unit-tested without rendering OpenTUI. Mirrors the expanded footer's bucket
|
|
60
|
+
* wording so the two views read consistently.
|
|
61
|
+
*/
|
|
62
|
+
function buildCollapsedLine(snapshot) {
|
|
63
|
+
const { completed, inProgress, pending } = snapshot.counts;
|
|
64
|
+
const parts = [];
|
|
65
|
+
if (completed > 0)
|
|
66
|
+
parts.push(`${completed} completed`);
|
|
67
|
+
if (inProgress > 0)
|
|
68
|
+
parts.push(`${inProgress} in progress`);
|
|
69
|
+
if (pending > 0)
|
|
70
|
+
parts.push(`${pending} queued`);
|
|
71
|
+
const body = parts.length > 0 ? parts.join(" · ") : "0 todos";
|
|
72
|
+
return `▸ Todos · ${body} (ctrl+e)`;
|
|
73
|
+
}
|
|
74
|
+
export function TaskListPanel({ snapshot, t, expanded, collapsed = false }) {
|
|
58
75
|
if (snapshot.items.length === 0)
|
|
59
76
|
return null;
|
|
77
|
+
if (collapsed) {
|
|
78
|
+
return (_jsx(Semantic, { id: "task-list", role: "listbox", name: "Todos", state: "collapsed", children: _jsx("box", { paddingLeft: 2, paddingRight: 2, marginBottom: 1, children: _jsx("text", { fg: t.textMuted, children: buildCollapsedLine(snapshot) }) }) }));
|
|
79
|
+
}
|
|
60
80
|
const sorted = sortItems(snapshot.items);
|
|
61
81
|
const overflow = !expanded && sorted.length > MAX_VISIBLE ? sorted.length - MAX_VISIBLE : 0;
|
|
62
82
|
const visible = overflow > 0 ? sorted.slice(0, MAX_VISIBLE) : sorted;
|
|
@@ -71,5 +91,5 @@ export function TaskListPanel({ snapshot, t, expanded }) {
|
|
|
71
91
|
const footer = footerParts.length > 0 ? footerParts.join(" · ") : "0 todos";
|
|
72
92
|
return (_jsx(Semantic, { id: "task-list", role: "listbox", name: "Todos", children: _jsxs("box", { border: true, borderColor: t.border, paddingLeft: 2, paddingRight: 2, paddingTop: 0, paddingBottom: 0, marginBottom: 1, flexDirection: "column", children: [_jsx("box", { paddingBottom: 1, children: _jsx("text", { fg: t.textMuted, children: _jsx("b", { children: "Todos" }) }) }), _jsx("box", { flexDirection: "column", children: visible.map((it) => (_jsx(ItemRow, { item: it, t: t }, it.id))) }), overflow > 0 && (_jsx("box", { marginTop: 1, children: _jsx("text", { fg: t.textMuted, children: `… +${overflow} more (ctrl+e to expand)` }) })), _jsx("box", { marginTop: 1, paddingTop: 1, border: ["top"], borderColor: t.border, children: _jsx("text", { fg: t.textDim, children: footer }) })] }) }));
|
|
73
93
|
}
|
|
74
|
-
export const __TEST_ONLY__ = { sortItems, MAX_VISIBLE };
|
|
94
|
+
export const __TEST_ONLY__ = { sortItems, MAX_VISIBLE, buildCollapsedLine };
|
|
75
95
|
//# sourceMappingURL=task-list-panel.js.map
|
|
@@ -3,16 +3,28 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Claude-Code-style "tool streak" panel — replaces the previous one-line-per-
|
|
5
5
|
* tool render. Lifecycle:
|
|
6
|
-
* - active → header "●
|
|
7
|
-
* - done → collapsed "●
|
|
6
|
+
* - active → header "● Reading 2 files… (N tools · Ms)" + indented item list
|
|
7
|
+
* - done → collapsed "● Read 2 files, ran 1 shell command ctrl+e to expand"
|
|
8
8
|
* - failed → always-expanded header + items, error item flagged red
|
|
9
9
|
*
|
|
10
|
+
* The header names the work per CATEGORY (see utils/tool-summary.ts) rather
|
|
11
|
+
* than saying "Done": once the group collapses that line is all the user has,
|
|
12
|
+
* so it has to carry the meaning. Items add the detail a glance needs — the
|
|
13
|
+
* full shell command for bash, "Wrote N lines to <path>" before a write diff.
|
|
14
|
+
*
|
|
10
15
|
* The active group lives at the tail of the message stream as a regular
|
|
11
16
|
* ChatEntry of type "tool_group"; closing the streak (assistant text arrives
|
|
12
17
|
* or stream ends) flips its state to done/failed in place.
|
|
13
18
|
*/
|
|
14
|
-
import type { ChatEntry } from "../../types/index.js";
|
|
19
|
+
import type { ChatEntry, FileDiff, ToolCall } from "../../types/index.js";
|
|
15
20
|
import type { Theme } from "../theme.js";
|
|
21
|
+
/** The command a bash item ran, split for multi-line display. Null when absent. */
|
|
22
|
+
export declare function bashCommandLines(tc: ToolCall): string[] | null;
|
|
23
|
+
/**
|
|
24
|
+
* One-line prose outcome for a write/edit, e.g. "Wrote 161 lines to a.ts" or
|
|
25
|
+
* "Edited a.ts (+12 -3)". Null when the tool isn't a file mutation.
|
|
26
|
+
*/
|
|
27
|
+
export declare function writeOutcomeLine(toolName: string, diff: FileDiff): string | null;
|
|
16
28
|
export interface ToolGroupViewProps {
|
|
17
29
|
entry: ChatEntry;
|
|
18
30
|
t: Theme;
|