muonroi-cli 1.8.4 → 1.8.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +17 -5
- package/dist/packages/agent-harness-core/src/driver.d.ts +27 -1
- package/dist/packages/agent-harness-core/src/driver.js +46 -0
- package/dist/packages/agent-harness-core/src/event-tee.d.ts +48 -0
- package/dist/packages/agent-harness-core/src/event-tee.js +77 -0
- package/dist/packages/agent-harness-core/src/mcp-server.d.ts +11 -0
- package/dist/packages/agent-harness-core/src/mcp-server.js +87 -15
- package/dist/packages/agent-harness-core/src/protocol.d.ts +66 -2
- package/dist/packages/agent-harness-core/src/protocol.js +15 -0
- package/dist/packages/agent-harness-core/src/visual-quality.d.ts +58 -0
- package/dist/packages/agent-harness-core/src/visual-quality.js +141 -0
- package/dist/packages/agent-harness-opentui/src/agent-mode.d.ts +6 -0
- package/dist/packages/agent-harness-opentui/src/agent-mode.js +14 -1
- package/dist/packages/agent-harness-opentui/src/input-bridge.d.ts +2 -10
- package/dist/packages/agent-harness-opentui/src/input-bridge.js +103 -16
- package/dist/packages/agent-harness-opentui/src/install.d.ts +8 -0
- package/dist/packages/agent-harness-opentui/src/install.js +10 -0
- package/dist/packages/agent-harness-opentui/src/semantic.js +12 -10
- package/dist/packages/agent-harness-opentui/src/visual-capture.d.ts +56 -0
- package/dist/packages/agent-harness-opentui/src/visual-capture.js +103 -0
- package/dist/src/agent-harness/mock-model.d.ts +28 -0
- package/dist/src/agent-harness/mock-model.js +63 -1
- package/dist/src/agent-harness/test-spawn.js +31 -0
- package/dist/src/cli/config/screen-providers.js +1 -1
- package/dist/src/cli/cost-forensics.d.ts +10 -0
- package/dist/src/cli/cost-forensics.js +18 -3
- package/dist/src/cli/keys-bundle.d.ts +1 -1
- package/dist/src/cli/keys-bundle.js +1 -1
- package/dist/src/cli/keys.d.ts +2 -2
- package/dist/src/cli/keys.js +19 -81
- package/dist/src/council/clarifier.d.ts +28 -2
- package/dist/src/council/clarifier.js +81 -15
- package/dist/src/council/context.js +49 -15
- package/dist/src/council/debate-checkpoint.d.ts +129 -0
- package/dist/src/council/debate-checkpoint.js +176 -0
- package/dist/src/council/debate-planner.js +51 -3
- package/dist/src/council/debate-summary.d.ts +25 -0
- package/dist/src/council/debate-summary.js +85 -0
- package/dist/src/council/debate.d.ts +169 -2
- package/dist/src/council/debate.js +1210 -134
- package/dist/src/council/index.d.ts +85 -1
- package/dist/src/council/index.js +634 -196
- package/dist/src/council/leader.d.ts +26 -0
- package/dist/src/council/leader.js +150 -9
- package/dist/src/council/llm.d.ts +32 -0
- package/dist/src/council/llm.js +231 -38
- package/dist/src/council/panel-select.d.ts +30 -0
- package/dist/src/council/panel-select.js +72 -0
- package/dist/src/council/planner.js +23 -0
- package/dist/src/council/preflight.d.ts +7 -0
- package/dist/src/council/preflight.js +14 -2
- package/dist/src/council/prompts.d.ts +30 -3
- package/dist/src/council/prompts.js +234 -64
- package/dist/src/council/stance-recall.d.ts +42 -0
- package/dist/src/council/stance-recall.js +57 -0
- package/dist/src/council/strip-think.d.ts +17 -0
- package/dist/src/council/strip-think.js +33 -0
- package/dist/src/council/types.d.ts +128 -0
- package/dist/src/ee/artifact-cache.d.ts +16 -0
- package/dist/src/ee/artifact-cache.js +32 -0
- package/dist/src/ee/auth.d.ts +1 -0
- package/dist/src/ee/auth.js +15 -2
- package/dist/src/ee/bridge.d.ts +10 -0
- package/dist/src/ee/bridge.js +58 -0
- package/dist/src/ee/client.js +81 -18
- package/dist/src/ee/export-transcripts.d.ts +1 -0
- package/dist/src/ee/export-transcripts.js +8 -10
- package/dist/src/ee/extract-session.js +29 -0
- package/dist/src/ee/extract-style.d.ts +58 -0
- package/dist/src/ee/extract-style.js +270 -0
- package/dist/src/ee/recall-ledger.d.ts +9 -0
- package/dist/src/ee/recall-ledger.js +3 -0
- package/dist/src/ee/scope.d.ts +1 -0
- package/dist/src/ee/scope.js +26 -1
- package/dist/src/ee/search.d.ts +7 -0
- package/dist/src/ee/search.js +24 -0
- package/dist/src/ee/transcript-emit.js +2 -0
- package/dist/src/ee/types.d.ts +22 -0
- package/dist/src/ee/who-am-i-brain.d.ts +35 -0
- package/dist/src/ee/who-am-i-brain.js +220 -0
- package/dist/src/ee/who-am-i.d.ts +10 -3
- package/dist/src/ee/who-am-i.js +12 -0
- package/dist/src/ee/workflow-event.d.ts +48 -0
- package/dist/src/ee/workflow-event.js +81 -0
- package/dist/src/flow/compaction/compress.d.ts +3 -3
- package/dist/src/flow/compaction/compress.js +45 -8
- package/dist/src/flow/compaction/extract.d.ts +4 -7
- package/dist/src/flow/compaction/extract.js +50 -10
- package/dist/src/flow/compaction/index.d.ts +13 -1
- package/dist/src/flow/compaction/index.js +70 -3
- package/dist/src/flow/compaction/input-guard.d.ts +24 -0
- package/dist/src/flow/compaction/input-guard.js +43 -0
- package/dist/src/flow/fold-planning.d.ts +36 -0
- package/dist/src/flow/fold-planning.js +83 -0
- package/dist/src/flow/hierarchy.d.ts +146 -0
- package/dist/src/flow/hierarchy.js +427 -0
- package/dist/src/flow/index.d.ts +1 -0
- package/dist/src/flow/index.js +2 -0
- package/dist/src/flow/run-artifacts.d.ts +102 -0
- package/dist/src/flow/run-artifacts.js +208 -0
- package/dist/src/generated/version.d.ts +1 -1
- package/dist/src/generated/version.js +1 -1
- package/dist/src/gsd/assessment-schema.d.ts +44 -0
- package/dist/src/gsd/assessment-schema.js +134 -0
- package/dist/src/gsd/capability-registry.d.ts +45 -0
- package/dist/src/gsd/capability-registry.js +337 -0
- package/dist/src/gsd/complexity-assessor.d.ts +39 -0
- package/dist/src/gsd/complexity-assessor.js +152 -0
- package/dist/src/gsd/config-bridge.d.ts +7 -0
- package/dist/src/gsd/config-bridge.js +114 -0
- package/dist/src/gsd/config-loader.d.ts +27 -0
- package/dist/src/gsd/config-loader.js +50 -0
- package/dist/src/gsd/council-context.d.ts +44 -0
- package/dist/src/gsd/council-context.js +114 -0
- package/dist/src/gsd/ee-closure.d.ts +28 -0
- package/dist/src/gsd/ee-closure.js +49 -0
- package/dist/src/gsd/flags.d.ts +55 -0
- package/dist/src/gsd/flags.js +83 -0
- package/dist/src/gsd/gsd-dispatch.d.ts +58 -0
- package/dist/src/gsd/gsd-dispatch.js +131 -0
- package/dist/src/gsd/gsd-runtime.d.ts +22 -0
- package/dist/src/gsd/gsd-runtime.js +37 -0
- package/dist/src/gsd/host-adapter.d.ts +11 -0
- package/dist/src/gsd/host-adapter.js +29 -0
- package/dist/src/gsd/index.d.ts +24 -1
- package/dist/src/gsd/index.js +27 -0
- package/dist/src/gsd/loop-host-contract.d.ts +21 -0
- package/dist/src/gsd/loop-host-contract.js +39 -0
- package/dist/src/gsd/loop-host.d.ts +69 -0
- package/dist/src/gsd/loop-host.js +245 -0
- package/dist/src/gsd/loop-resolver.d.ts +36 -0
- package/dist/src/gsd/loop-resolver.js +79 -0
- package/dist/src/gsd/model-tier.d.ts +13 -0
- package/dist/src/gsd/model-tier.js +45 -0
- package/dist/src/gsd/mutation-gate.d.ts +16 -0
- package/dist/src/gsd/mutation-gate.js +41 -0
- package/dist/src/gsd/native-roadmap.d.ts +89 -0
- package/dist/src/gsd/native-roadmap.js +343 -0
- package/dist/src/gsd/native-state.d.ts +47 -0
- package/dist/src/gsd/native-state.js +220 -0
- package/dist/src/gsd/paths.d.ts +23 -0
- package/dist/src/gsd/paths.js +66 -0
- package/dist/src/gsd/phase-dag.d.ts +12 -0
- package/dist/src/gsd/phase-dag.js +94 -0
- package/dist/src/gsd/phase-sync.d.ts +42 -0
- package/dist/src/gsd/phase-sync.js +321 -0
- package/dist/src/gsd/pil-gate-context.d.ts +13 -0
- package/dist/src/gsd/pil-gate-context.js +64 -0
- package/dist/src/gsd/pil-gate-critic.d.ts +19 -0
- package/dist/src/gsd/pil-gate-critic.js +74 -0
- package/dist/src/gsd/plan-council-prompts.d.ts +25 -0
- package/dist/src/gsd/plan-council-prompts.js +79 -0
- package/dist/src/gsd/plan-council.d.ts +44 -0
- package/dist/src/gsd/plan-council.js +251 -0
- package/dist/src/gsd/plan-gate-vocabulary.d.ts +40 -0
- package/dist/src/gsd/plan-gate-vocabulary.js +64 -0
- package/dist/src/gsd/product-workspace.d.ts +13 -0
- package/dist/src/gsd/product-workspace.js +124 -0
- package/dist/src/gsd/ship-bridge.d.ts +25 -0
- package/dist/src/gsd/ship-bridge.js +65 -0
- package/dist/src/gsd/state-document.d.ts +40 -0
- package/dist/src/gsd/state-document.js +163 -0
- package/dist/src/gsd/verdict-schema.d.ts +39 -0
- package/dist/src/gsd/verdict-schema.js +144 -0
- package/dist/src/gsd/verify-context.d.ts +22 -0
- package/dist/src/gsd/verify-context.js +27 -0
- package/dist/src/gsd/verify-council-prompts.d.ts +19 -0
- package/dist/src/gsd/verify-council-prompts.js +85 -0
- package/dist/src/gsd/verify-council.d.ts +25 -0
- package/dist/src/gsd/verify-council.js +119 -0
- package/dist/src/gsd/verify-gate-vocabulary.d.ts +25 -0
- package/dist/src/gsd/verify-gate-vocabulary.js +46 -0
- package/dist/src/gsd/workflow-engine.d.ts +60 -0
- package/dist/src/gsd/workflow-engine.js +207 -0
- package/dist/src/gsd/workflow-tools.d.ts +13 -0
- package/dist/src/gsd/workflow-tools.js +277 -0
- package/dist/src/hooks/index.js +1 -1
- package/dist/src/index.js +44 -11
- package/dist/src/maintain/pr-builder.js +23 -13
- package/dist/src/mcp/auto-setup.js +57 -32
- package/dist/src/mcp/client-pool.js +1 -1
- package/dist/src/mcp/ee-tools.js +1 -0
- package/dist/src/mcp/research-onboarding.js +8 -7
- package/dist/src/mcp/runtime.js +34 -2
- package/dist/src/models/catalog-client.d.ts +87 -0
- package/dist/src/models/catalog-client.js +105 -38
- package/dist/src/models/catalog.json +528 -265
- package/dist/src/models/registry.d.ts +22 -7
- package/dist/src/models/registry.js +73 -10
- package/dist/src/ops/doctor.js +1 -1
- package/dist/src/orchestrator/auto-commit.js +1 -1
- package/dist/src/orchestrator/batch-turn-runner.js +2 -2
- package/dist/src/orchestrator/cache-prefix.d.ts +67 -0
- package/dist/src/orchestrator/cache-prefix.js +83 -0
- package/dist/src/orchestrator/compact-request.d.ts +32 -0
- package/dist/src/orchestrator/compact-request.js +41 -0
- package/dist/src/orchestrator/compaction.d.ts +10 -0
- package/dist/src/orchestrator/compaction.js +27 -7
- package/dist/src/orchestrator/council-manager.d.ts +12 -3
- package/dist/src/orchestrator/council-manager.js +65 -24
- package/dist/src/orchestrator/cross-turn-dedup.d.ts +6 -0
- package/dist/src/orchestrator/cross-turn-dedup.js +22 -1
- package/dist/src/orchestrator/error-utils.d.ts +29 -0
- package/dist/src/orchestrator/error-utils.js +132 -24
- package/dist/src/orchestrator/grounding-check.js +39 -1
- package/dist/src/orchestrator/message-processor.js +242 -33
- package/dist/src/orchestrator/orchestrator.d.ts +39 -3
- package/dist/src/orchestrator/orchestrator.js +651 -102
- package/dist/src/orchestrator/preprocessor.js +1 -1
- package/dist/src/orchestrator/proactive-compact-detector.d.ts +26 -0
- package/dist/src/orchestrator/proactive-compact-detector.js +36 -0
- package/dist/src/orchestrator/prompts.js +17 -17
- package/dist/src/orchestrator/reactive-delegation.d.ts +39 -0
- package/dist/src/orchestrator/reactive-delegation.js +59 -0
- package/dist/src/orchestrator/retry-classifier.d.ts +2 -1
- package/dist/src/orchestrator/retry-classifier.js +46 -2
- package/dist/src/orchestrator/safety-intercept.d.ts +45 -0
- package/dist/src/orchestrator/safety-intercept.js +55 -0
- package/dist/src/orchestrator/scope-reminder.js +1 -1
- package/dist/src/orchestrator/session-experience.d.ts +2 -1
- package/dist/src/orchestrator/session-experience.js +2 -1
- package/dist/src/orchestrator/should-run-gate.d.ts +5 -0
- package/dist/src/orchestrator/should-run-gate.js +18 -0
- package/dist/src/orchestrator/stall-watchdog.d.ts +24 -3
- package/dist/src/orchestrator/stall-watchdog.js +47 -13
- package/dist/src/orchestrator/stream-runner.js +62 -29
- package/dist/src/orchestrator/sub-agent-cap.d.ts +13 -1
- package/dist/src/orchestrator/sub-agent-cap.js +16 -1
- package/dist/src/orchestrator/sub-agent-model-tier.d.ts +13 -1
- package/dist/src/orchestrator/sub-agent-model-tier.js +16 -2
- package/dist/src/orchestrator/subagent-compactor.d.ts +53 -1
- package/dist/src/orchestrator/subagent-compactor.js +126 -15
- package/dist/src/orchestrator/tool-engine.d.ts +22 -0
- package/dist/src/orchestrator/tool-engine.js +620 -56
- package/dist/src/orchestrator/tool-limit-auto-recover.d.ts +22 -0
- package/dist/src/orchestrator/tool-limit-auto-recover.js +30 -0
- package/dist/src/orchestrator/turn-runner-deps.d.ts +19 -0
- package/dist/src/orchestrator/turn-watchdog.d.ts +37 -0
- package/dist/src/orchestrator/turn-watchdog.js +55 -0
- package/dist/src/pil/agent-operating-contract.d.ts +1 -1
- package/dist/src/pil/agent-operating-contract.js +1 -1
- package/dist/src/pil/cheap-model-playbook.d.ts +1 -1
- package/dist/src/pil/cheap-model-playbook.js +5 -1
- package/dist/src/pil/cheap-model-workbooks.d.ts +1 -1
- package/dist/src/pil/cheap-model-workbooks.js +1 -1
- package/dist/src/pil/discovery-types.d.ts +1 -0
- package/dist/src/pil/discovery.js +16 -11
- package/dist/src/pil/layer1-intent.d.ts +18 -6
- package/dist/src/pil/layer1-intent.js +66 -757
- package/dist/src/pil/layer15-context-scan.js +15 -1
- package/dist/src/pil/layer3-ee-injection.js +23 -8
- package/dist/src/pil/layer4-gsd.js +69 -16
- package/dist/src/pil/layer5-context.js +7 -3
- package/dist/src/pil/layer6-output.d.ts +23 -0
- package/dist/src/pil/layer6-output.js +5 -1
- package/dist/src/pil/llm-classify.d.ts +33 -2
- package/dist/src/pil/llm-classify.js +123 -131
- package/dist/src/pil/native-capabilities-workbook.d.ts +1 -1
- package/dist/src/pil/native-capabilities-workbook.js +1 -0
- package/dist/src/pil/pipeline.js +34 -2
- package/dist/src/pil/response-tools.js +5 -3
- package/dist/src/pil/schema.d.ts +1 -0
- package/dist/src/pil/schema.js +2 -0
- package/dist/src/pil/types.d.ts +18 -0
- package/dist/src/playbook/directives.d.ts +4 -0
- package/dist/src/playbook/directives.js +17 -5
- package/dist/src/product-loop/backlog-builder.d.ts +14 -1
- package/dist/src/product-loop/backlog-builder.js +30 -6
- package/dist/src/product-loop/discovery-context-format.js +3 -1
- package/dist/src/product-loop/discovery-ecosystem.js +4 -1
- package/dist/src/product-loop/discovery-interview.js +32 -3
- package/dist/src/product-loop/discovery-schema.js +5 -1
- package/dist/src/product-loop/ideal-trace.d.ts +7 -0
- package/dist/src/product-loop/ideal-trace.js +64 -0
- package/dist/src/product-loop/index.d.ts +13 -1
- package/dist/src/product-loop/index.js +333 -52
- package/dist/src/product-loop/loop-driver.d.ts +7 -0
- package/dist/src/product-loop/loop-driver.js +310 -99
- package/dist/src/product-loop/phase-plan.d.ts +5 -0
- package/dist/src/product-loop/phase-plan.js +39 -2
- package/dist/src/product-loop/phase-runner.js +9 -1
- package/dist/src/product-loop/sprint-runner.d.ts +111 -0
- package/dist/src/product-loop/sprint-runner.js +559 -16
- package/dist/src/product-loop/types.d.ts +36 -5
- package/dist/src/providers/adapter.d.ts +1 -1
- package/dist/src/providers/adapter.js +3 -4
- package/dist/src/providers/auth/browser-flow.d.ts +1 -1
- package/dist/src/providers/auth/browser-flow.js +1 -1
- package/dist/src/providers/auth/openai-oauth.js +1 -1
- package/dist/src/providers/auth/registry.js +0 -34
- package/dist/src/providers/auth/token-store.js +4 -1
- package/dist/src/providers/auth/types.d.ts +1 -1
- package/dist/src/providers/auth/types.js +1 -1
- package/dist/src/providers/capabilities.d.ts +24 -5
- package/dist/src/providers/capabilities.js +42 -24
- package/dist/src/providers/endpoints.d.ts +2 -2
- package/dist/src/providers/endpoints.js +11 -10
- package/dist/src/providers/keychain.d.ts +1 -1
- package/dist/src/providers/keychain.js +7 -9
- package/dist/src/providers/mcp-vision-bridge.js +56 -146
- package/dist/src/providers/openai-compatible.js +8 -1
- package/dist/src/providers/pricing.d.ts +2 -2
- package/dist/src/providers/pricing.js +3 -13
- package/dist/src/providers/runtime.d.ts +27 -2
- package/dist/src/providers/runtime.js +78 -15
- package/dist/src/providers/strategies/base.strategy.d.ts +16 -0
- package/dist/src/providers/strategies/base.strategy.js +24 -1
- package/dist/src/providers/strategies/{siliconflow.strategy.d.ts → opencode-go.strategy.d.ts} +3 -3
- package/dist/src/providers/strategies/opencode-go.strategy.js +83 -0
- package/dist/src/providers/strategies/registry.js +4 -4
- package/dist/src/providers/strategies/thinking-mode.d.ts +109 -0
- package/dist/src/providers/strategies/thinking-mode.js +280 -1
- package/dist/src/providers/strategies/zai.strategy.d.ts +14 -0
- package/dist/src/providers/strategies/zai.strategy.js +44 -0
- package/dist/src/providers/types.d.ts +5 -6
- package/dist/src/providers/types.js +2 -2
- package/dist/src/providers/vision-backend.d.ts +47 -0
- package/dist/src/providers/vision-backend.js +258 -0
- package/dist/src/providers/vision-proxy.d.ts +22 -9
- package/dist/src/providers/vision-proxy.js +63 -132
- package/dist/src/providers/wire-debug.js +95 -0
- package/dist/src/router/decide.d.ts +13 -0
- package/dist/src/router/decide.js +138 -36
- package/dist/src/router/peak-hour.d.ts +38 -0
- package/dist/src/router/peak-hour.js +107 -0
- package/dist/src/router/step-router.js +3 -2
- package/dist/src/router/warm.js +4 -5
- package/dist/src/scaffold/continuation-prompt.d.ts +11 -0
- package/dist/src/scaffold/continuation-prompt.js +26 -0
- package/dist/src/scaffold/point-to-existing.d.ts +21 -0
- package/dist/src/scaffold/point-to-existing.js +25 -0
- package/dist/src/self-qa/agentic-loop.js +3 -3
- package/dist/src/{ui/state → state}/active-run.d.ts +19 -0
- package/dist/src/{ui/state → state}/active-run.js +21 -0
- package/dist/src/{ui/status-bar/store.d.ts → state/status-bar-store.d.ts} +4 -1
- package/dist/src/{ui/status-bar/store.js → state/status-bar-store.js} +12 -9
- package/dist/src/state/turn-trace.d.ts +43 -0
- package/dist/src/state/turn-trace.js +32 -0
- package/dist/src/storage/db.js +2 -1
- package/dist/src/storage/index.d.ts +1 -1
- package/dist/src/storage/index.js +1 -1
- package/dist/src/storage/interaction-log.d.ts +1 -1
- package/dist/src/storage/migrations.js +71 -1
- package/dist/src/storage/sessions.d.ts +28 -10
- package/dist/src/storage/sessions.js +78 -21
- package/dist/src/storage/transcript-view.js +1 -1
- package/dist/src/storage/transcript.d.ts +51 -0
- package/dist/src/storage/transcript.js +284 -13
- package/dist/src/tools/file.d.ts +15 -0
- package/dist/src/tools/file.js +32 -0
- package/dist/src/tools/native-tools.js +5 -0
- package/dist/src/tools/registry.d.ts +3 -0
- package/dist/src/tools/registry.js +460 -22
- package/dist/src/tools/research.d.ts +29 -0
- package/dist/src/tools/research.js +233 -0
- package/dist/src/types/index.d.ts +118 -3
- package/dist/src/ui/app.js +0 -0
- package/dist/src/ui/cards/product-status-card.js +1 -1
- package/dist/src/ui/components/bubble-body-guard.d.ts +27 -0
- package/dist/src/ui/components/bubble-body-guard.js +50 -0
- package/dist/src/ui/components/context-rail.d.ts +26 -0
- package/dist/src/ui/components/context-rail.js +33 -0
- package/dist/src/ui/components/council-conclusion-card.d.ts +73 -0
- package/dist/src/ui/components/council-conclusion-card.js +420 -0
- package/dist/src/ui/components/council-debate-pill.d.ts +36 -0
- package/dist/src/ui/components/council-debate-pill.js +34 -0
- package/dist/src/ui/components/council-info-card.js +2 -2
- package/dist/src/ui/components/council-leader-bubble.d.ts +10 -3
- package/dist/src/ui/components/council-leader-bubble.js +21 -11
- package/dist/src/ui/components/council-message-bubble.d.ts +15 -2
- package/dist/src/ui/components/council-message-bubble.js +16 -15
- package/dist/src/ui/components/council-phase-timeline.d.ts +9 -1
- package/dist/src/ui/components/council-phase-timeline.js +49 -15
- package/dist/src/ui/components/council-placeholder-bubble.d.ts +16 -9
- package/dist/src/ui/components/council-placeholder-bubble.js +32 -29
- package/dist/src/ui/components/council-question-card.js +12 -12
- package/dist/src/ui/components/council-rail-rounds.d.ts +26 -0
- package/dist/src/ui/components/council-rail-rounds.js +57 -0
- package/dist/src/ui/components/council-round-group.d.ts +38 -0
- package/dist/src/ui/components/council-round-group.js +88 -0
- package/dist/src/ui/components/council-status-list.d.ts +3 -1
- package/dist/src/ui/components/council-status-list.js +36 -24
- package/dist/src/ui/components/council-synthesis-banner.d.ts +7 -2
- package/dist/src/ui/components/council-synthesis-banner.js +20 -5
- package/dist/src/ui/components/halt-recovery-card.js +9 -5
- package/dist/src/ui/components/jump-to-latest-pill.d.ts +11 -0
- package/dist/src/ui/components/jump-to-latest-pill.js +14 -0
- package/dist/src/ui/components/prompt-box.js +18 -16
- package/dist/src/ui/components/session-tree-card.d.ts +14 -0
- package/dist/src/ui/components/session-tree-card.js +46 -0
- package/dist/src/ui/components/slash-inline-menu.d.ts +12 -0
- package/dist/src/ui/components/slash-inline-menu.js +26 -5
- package/dist/src/ui/components/task-list-panel.d.ts +14 -1
- package/dist/src/ui/components/task-list-panel.js +22 -2
- package/dist/src/ui/containers/modals-layer.d.ts +2 -1
- package/dist/src/ui/hooks/use-session-picker.d.ts +3 -3
- package/dist/src/ui/mcp-modal.js +2 -4
- package/dist/src/ui/modals/api-key-modal.js +1 -1
- package/dist/src/ui/modals/connect-modal.js +4 -3
- package/dist/src/ui/modals/session-picker-modal.d.ts +2 -2
- package/dist/src/ui/modals/session-picker-modal.js +3 -5
- package/dist/src/ui/picker-providers.d.ts +1 -1
- package/dist/src/ui/picker-providers.js +1 -1
- package/dist/src/ui/primitives/index.d.ts +1 -0
- package/dist/src/ui/primitives/index.js +2 -0
- package/dist/src/ui/primitives/semantic-primitives.d.ts +76 -0
- package/dist/src/ui/primitives/semantic-primitives.js +81 -0
- package/dist/src/ui/slash/compact.js +5 -7
- package/dist/src/ui/slash/cost.js +1 -1
- package/dist/src/ui/slash/council.js +19 -1
- package/dist/src/ui/slash/debug.d.ts +3 -31
- package/dist/src/ui/slash/debug.js +9 -20
- package/dist/src/ui/slash/ideal.d.ts +6 -2
- package/dist/src/ui/slash/ideal.js +97 -7
- package/dist/src/ui/slash/menu-items.d.ts +7 -0
- package/dist/src/ui/slash/menu-items.js +12 -18
- package/dist/src/ui/slash/registry.d.ts +2 -0
- package/dist/src/ui/slash/registry.js +4 -0
- package/dist/src/ui/status-bar/cache-hit.d.ts +6 -0
- package/dist/src/ui/status-bar/cache-hit.js +9 -0
- package/dist/src/ui/status-bar/index.d.ts +1 -1
- package/dist/src/ui/status-bar/index.js +7 -3
- package/dist/src/ui/status-bar/usd-meter.d.ts +5 -4
- package/dist/src/ui/status-bar/usd-meter.js +6 -4
- package/dist/src/ui/theme.d.ts +1 -0
- package/dist/src/ui/theme.js +2 -0
- package/dist/src/ui/types.d.ts +7 -0
- package/dist/src/ui/use-app-logic.js +0 -0
- package/dist/src/ui/utils/format.d.ts +14 -0
- package/dist/src/ui/utils/format.js +23 -3
- package/dist/src/usage/downgrade.js +2 -2
- package/dist/src/usage/product-ledger.js +2 -2
- package/dist/src/utils/install-manager.js +2 -1
- package/dist/src/utils/logger.js +2 -2
- package/dist/src/utils/permission-mode.js +5 -3
- package/dist/src/utils/redactor.js +1 -1
- package/dist/src/utils/settings.d.ts +153 -5
- package/dist/src/utils/settings.js +233 -29
- package/dist/src/utils/visible-retry.d.ts +11 -0
- package/dist/src/utils/visible-retry.js +10 -1
- package/dist/src/verify/entrypoint.d.ts +1 -1
- package/dist/src/verify/entrypoint.js +1 -1
- package/dist/src/verify/recipes.d.ts +13 -0
- package/dist/src/verify/recipes.js +15 -0
- package/package.json +135 -132
- package/dist/src/providers/auth/gcloud.d.ts +0 -28
- package/dist/src/providers/auth/gcloud.js +0 -102
- package/dist/src/providers/auth/gemini-oauth.d.ts +0 -82
- package/dist/src/providers/auth/gemini-oauth.js +0 -472
- package/dist/src/providers/gemini.d.ts +0 -11
- package/dist/src/providers/gemini.js +0 -45
- package/dist/src/providers/siliconflow-sse-repair.d.ts +0 -58
- package/dist/src/providers/siliconflow-sse-repair.js +0 -177
- package/dist/src/providers/strategies/google.strategy.d.ts +0 -22
- package/dist/src/providers/strategies/google.strategy.js +0 -174
- package/dist/src/providers/strategies/siliconflow.strategy.js +0 -29
- package/dist/src/ui/containers/chat-feed.d.ts +0 -40
- package/dist/src/ui/containers/chat-feed.js +0 -66
|
@@ -2,16 +2,6 @@ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "@opentui/reac
|
|
|
2
2
|
import { useEffect, useState } from "react";
|
|
3
3
|
const SPINNER_FRAMES = ["⬒", "⬔", "⬓", "⬕"];
|
|
4
4
|
const DONE_HOLD_MS = 1500;
|
|
5
|
-
const PHASE_LABEL = {
|
|
6
|
-
clarify: "clarify",
|
|
7
|
-
plan_debate: "plan",
|
|
8
|
-
research: "research",
|
|
9
|
-
opening: "opening",
|
|
10
|
-
exchange: "exchange",
|
|
11
|
-
evaluate: "evaluate",
|
|
12
|
-
synthesis: "synthesis",
|
|
13
|
-
summary: "summary",
|
|
14
|
-
};
|
|
15
5
|
function Spinner() {
|
|
16
6
|
const [frame, setFrame] = useState(0);
|
|
17
7
|
useEffect(() => {
|
|
@@ -20,6 +10,20 @@ function Spinner() {
|
|
|
20
10
|
}, []);
|
|
21
11
|
return _jsx(_Fragment, { children: SPINNER_FRAMES[frame] });
|
|
22
12
|
}
|
|
13
|
+
/**
|
|
14
|
+
* Re-render every `tickMs` so active rows show a live-ticking elapsed counter.
|
|
15
|
+
* Without this the row freezes at the last emitter-sent elapsedMs (emitters
|
|
16
|
+
* only send on state transitions) — the same "im lìm" symptom the phase
|
|
17
|
+
* timeline fixed with its own heartbeat (council-phase-timeline.tsx).
|
|
18
|
+
*/
|
|
19
|
+
function useHeartbeat(tickMs = 1000) {
|
|
20
|
+
const [, force] = useState(0);
|
|
21
|
+
useEffect(() => {
|
|
22
|
+
const id = setInterval(() => force((n) => n + 1), tickMs);
|
|
23
|
+
return () => clearInterval(id);
|
|
24
|
+
}, [tickMs]);
|
|
25
|
+
return Date.now();
|
|
26
|
+
}
|
|
23
27
|
function formatElapsed(ms) {
|
|
24
28
|
if (!ms || ms < 0)
|
|
25
29
|
return "0s";
|
|
@@ -38,18 +42,22 @@ function formatTokens(s) {
|
|
|
38
42
|
parts.push(`↓ ${s.tokensOut}`);
|
|
39
43
|
return parts.length > 0 ? ` · ${parts.join(" · ")} tokens` : "";
|
|
40
44
|
}
|
|
41
|
-
export function CouncilStatusList({ statuses, theme: t }) {
|
|
42
|
-
|
|
45
|
+
export function CouncilStatusList({ statuses, theme: t, sessionId }) {
|
|
46
|
+
// Hook must run unconditionally — before the empty-list early return.
|
|
47
|
+
const now = useHeartbeat(1000);
|
|
48
|
+
if (statuses.length === 0 && !sessionId)
|
|
43
49
|
return null;
|
|
44
|
-
return (
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
50
|
+
return (_jsxs("box", { flexDirection: "column", paddingLeft: 2, paddingTop: 0, flexShrink: 0, children: [sessionId && (_jsx("box", { marginBottom: 1, children: _jsx("text", { fg: t.textDim, children: `session ${sessionId}` }) })), statuses.map((s) => {
|
|
51
|
+
const isError = s.state === "error";
|
|
52
|
+
const isDone = s.state === "done";
|
|
53
|
+
const marker = isError ? "✗" : isDone ? "✓" : _jsx(Spinner, {});
|
|
54
|
+
const markerColor = isError ? t.diffRemovedFg : isDone ? t.planOptionCheck : t.accent;
|
|
55
|
+
const labelColor = isError ? t.diffRemovedFg : t.text;
|
|
56
|
+
const isLive = s.state === "start" || s.state === "tick";
|
|
57
|
+
const liveElapsedMs = isLive && typeof s.startedAt === "number" ? Math.max(0, now - s.startedAt) : s.elapsedMs;
|
|
58
|
+
const meta = `(${formatElapsed(liveElapsedMs)}${formatTokens(s)})`;
|
|
59
|
+
return (_jsxs("box", { flexDirection: "column", children: [_jsxs("box", { children: [_jsx("text", { fg: markerColor, children: marker }), _jsx("text", { fg: labelColor, children: ` ${s.label}` }), _jsx("text", { fg: t.textMuted, children: ` ${meta}` })] }), s.detail && (_jsx("box", { paddingLeft: 2, children: _jsx("text", { fg: t.textMuted, children: `└ ${truncate(s.detail, 140)}` }) })), s.errorMessage && (_jsx("box", { paddingLeft: 2, children: _jsx("text", { fg: t.diffRemovedFg, children: `└ ${truncate(s.errorMessage, 140)}` }) }))] }, s.statusId));
|
|
60
|
+
})] }));
|
|
53
61
|
}
|
|
54
62
|
function truncate(s, max) {
|
|
55
63
|
if (s.length <= max)
|
|
@@ -63,10 +71,14 @@ function truncate(s, max) {
|
|
|
63
71
|
*/
|
|
64
72
|
export function upsertStatus(prev, next) {
|
|
65
73
|
const idx = prev.findIndex((s) => s.statusId === next.statusId);
|
|
66
|
-
if (idx === -1)
|
|
67
|
-
|
|
74
|
+
if (idx === -1) {
|
|
75
|
+
// Stamp a client-side start anchor so the row can live-tick between emitter
|
|
76
|
+
// updates (emitters only send elapsedMs on state transitions).
|
|
77
|
+
const startedAt = next.startedAt ?? Date.now() - (next.elapsedMs ?? 0);
|
|
78
|
+
return [...prev, { ...next, startedAt }];
|
|
79
|
+
}
|
|
68
80
|
const out = prev.slice();
|
|
69
|
-
out[idx] = next;
|
|
81
|
+
out[idx] = { ...next, startedAt: next.startedAt ?? out[idx].startedAt };
|
|
70
82
|
return out;
|
|
71
83
|
}
|
|
72
84
|
/** Remove `done` rows that finished more than DONE_HOLD_MS ago. */
|
|
@@ -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,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
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ResumeEntry } from "../../types/index.js";
|
|
1
2
|
export interface ModalsLayerProps {
|
|
2
3
|
agentRows: any;
|
|
3
4
|
agentsEditorDraft: any;
|
|
@@ -50,7 +51,7 @@ export interface ModalsLayerProps {
|
|
|
50
51
|
scheduleRows: any;
|
|
51
52
|
scheduleSearchQuery: any;
|
|
52
53
|
sessionPickerIndex: any;
|
|
53
|
-
sessionPickerList:
|
|
54
|
+
sessionPickerList: ResumeEntry[];
|
|
54
55
|
showAgentsEditor: any;
|
|
55
56
|
showAgentsModal: any;
|
|
56
57
|
showApiKeyModal: any;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ResumeEntry } from "../../types/index.js";
|
|
2
2
|
/**
|
|
3
3
|
* State for the /sessions picker modal. Sessions are loaded lazily when the
|
|
4
4
|
* picker is opened (the SQLite query is cheap — ORDER BY updated_at LIMIT 20
|
|
@@ -9,6 +9,6 @@ export declare function useSessionPicker(): {
|
|
|
9
9
|
setShowSessionPicker: import("react").Dispatch<import("react").SetStateAction<boolean>>;
|
|
10
10
|
sessionPickerIndex: number;
|
|
11
11
|
setSessionPickerIndex: import("react").Dispatch<import("react").SetStateAction<number>>;
|
|
12
|
-
sessions:
|
|
13
|
-
setSessions: import("react").Dispatch<import("react").SetStateAction<
|
|
12
|
+
sessions: ResumeEntry[];
|
|
13
|
+
setSessions: import("react").Dispatch<import("react").SetStateAction<ResumeEntry[]>>;
|
|
14
14
|
};
|
package/dist/src/ui/mcp-modal.js
CHANGED
|
@@ -53,8 +53,7 @@ export function McpBrowserModal({ t, width, height, selectedIndex, searchQuery,
|
|
|
53
53
|
const contentHeight = itemCount + 7;
|
|
54
54
|
const maxHeight = Math.floor(height * 0.68);
|
|
55
55
|
const panelHeight = Math.min(contentHeight, maxHeight);
|
|
56
|
-
|
|
57
|
-
return (_jsx(Semantic, { id: "mcp-modal", role: "dialog", name: "MCP Servers", isModal: true, children: _jsx("box", { position: "absolute", left: 0, top: 0, width: width, height: height, alignItems: "center", paddingTop: bottomAlignedModalTop(height, panelHeight), backgroundColor: overlayBg, children: _jsxs("box", { width: Math.min(96, width - 4), height: panelHeight, backgroundColor: t.backgroundPanel, paddingTop: 1, paddingBottom: 1, flexDirection: "column", children: [_jsxs("box", { flexShrink: 0, flexDirection: "row", justifyContent: "space-between", paddingLeft: 2, paddingRight: 2, children: [_jsx("text", { fg: t.primary, children: _jsx("b", { children: "MCP Servers" }) }), _jsx("text", { fg: t.textMuted, children: "esc" })] }), _jsx("box", { flexShrink: 0, paddingLeft: 2, paddingRight: 2, paddingTop: 1, paddingBottom: 1, children: _jsx("text", { fg: t.text, children: searchQuery || _jsx("span", { style: { fg: t.textMuted }, children: "Search servers..." }) }) }), _jsx(Semantic, { id: "mcp-list", role: "listbox", children: _jsx("scrollbox", { ref: listRef, flexGrow: 1, minHeight: 0, children: rows.map((row, idx) => {
|
|
56
|
+
return (_jsx(Semantic, { id: "mcp-modal", role: "dialog", name: "MCP Servers", isModal: true, children: _jsx("box", { position: "absolute", left: 0, top: 0, width: width, height: height, alignItems: "center", paddingTop: bottomAlignedModalTop(height, panelHeight), backgroundColor: t.overlay, children: _jsxs("box", { width: Math.min(96, width - 4), height: panelHeight, backgroundColor: t.backgroundPanel, paddingTop: 1, paddingBottom: 1, flexDirection: "column", children: [_jsxs("box", { flexShrink: 0, flexDirection: "row", justifyContent: "space-between", paddingLeft: 2, paddingRight: 2, children: [_jsx("text", { fg: t.primary, children: _jsx("b", { children: "MCP Servers" }) }), _jsx("text", { fg: t.textMuted, children: "esc" })] }), _jsx("box", { flexShrink: 0, paddingLeft: 2, paddingRight: 2, paddingTop: 1, paddingBottom: 1, children: _jsx("text", { fg: t.text, children: searchQuery || _jsx("span", { style: { fg: t.textMuted }, children: "Search servers..." }) }) }), _jsx(Semantic, { id: "mcp-list", role: "listbox", children: _jsx("scrollbox", { ref: listRef, flexGrow: 1, minHeight: 0, children: rows.map((row, idx) => {
|
|
58
57
|
const selected = idx === selectedIndex;
|
|
59
58
|
if (row.kind === "server") {
|
|
60
59
|
const enabledColor = row.server.enabled ? t.diffAddedFg : selected ? t.selected : t.text;
|
|
@@ -74,7 +73,6 @@ function syncRef(ref, value) {
|
|
|
74
73
|
}
|
|
75
74
|
export function McpEditorModal({ t, width, height, draft, focusedField, syncKey, error, title, labelRef, urlRef, headersRef, commandRef, argsRef, cwdRef, envRef, onSubmit, }) {
|
|
76
75
|
const panelHeight = Math.min(30, Math.floor(height * 0.82));
|
|
77
|
-
const overlayBg = "#000000cc";
|
|
78
76
|
const isRemote = draft.transport === "http" || draft.transport === "sse";
|
|
79
77
|
// biome-ignore lint/correctness/useExhaustiveDependencies: syncKey is an intentional cache-bust prop
|
|
80
78
|
useEffect(() => {
|
|
@@ -86,7 +84,7 @@ export function McpEditorModal({ t, width, height, draft, focusedField, syncKey,
|
|
|
86
84
|
syncRef(cwdRef, draft.cwd);
|
|
87
85
|
syncRef(envRef, draft.envText);
|
|
88
86
|
}, [draft, syncKey, labelRef, urlRef, headersRef, commandRef, argsRef, cwdRef, envRef]);
|
|
89
|
-
return (_jsx(Semantic, { id: "mcp-editor", role: "dialog", name: title, isModal: true, children: _jsx("box", { position: "absolute", left: 0, top: 0, width: width, height: height, alignItems: "center", paddingTop: bottomAlignedModalTop(height, panelHeight), backgroundColor:
|
|
87
|
+
return (_jsx(Semantic, { id: "mcp-editor", role: "dialog", name: title, isModal: true, children: _jsx("box", { position: "absolute", left: 0, top: 0, width: width, height: height, alignItems: "center", paddingTop: bottomAlignedModalTop(height, panelHeight), backgroundColor: t.overlay, children: _jsxs("box", { width: Math.min(86, width - 6), height: panelHeight, backgroundColor: t.backgroundPanel, paddingTop: 1, paddingBottom: 1, flexDirection: "column", children: [_jsxs("box", { flexShrink: 0, flexDirection: "row", justifyContent: "space-between", paddingLeft: 2, paddingRight: 2, children: [_jsx("text", { fg: t.primary, children: _jsx("b", { children: title }) }), _jsx("text", { fg: t.textMuted, children: "esc" })] }), _jsx("box", { flexShrink: 0, paddingLeft: 2, paddingRight: 2, paddingTop: 1, children: _jsxs("box", { flexDirection: "row", gap: 1, alignItems: "center", children: [_jsx("text", { fg: focusedField === "transport" ? t.primary : t.textMuted, children: "Transport" }), ["stdio", "http", "sse"].map((option) => {
|
|
90
88
|
const active = draft.transport === option;
|
|
91
89
|
const focused = focusedField === "transport";
|
|
92
90
|
return (_jsx("box", { backgroundColor: active ? (focused ? t.selectedBg : t.backgroundElement) : undefined, paddingLeft: 1, paddingRight: 1, children: _jsx("text", { fg: active ? (focused ? t.primary : t.text) : t.textMuted, children: option }) }, option));
|
|
@@ -10,6 +10,6 @@ export function ApiKeyModal({ t, width, height, inputRef, error, onSubmit, }) {
|
|
|
10
10
|
const panelWidth = Math.min(68, width - 6);
|
|
11
11
|
const panelHeight = 13;
|
|
12
12
|
const top = bottomAlignedModalTop(height, panelHeight);
|
|
13
|
-
return (_jsx(Semantic, { id: "api-key-modal", role: "dialog", name: "API Key", isModal: true, children: _jsx("box", { position: "absolute", left: 0, top: 0, width: width, height: height, alignItems: "center", paddingTop: top, backgroundColor: overlayBg, children: _jsxs("box", { width: panelWidth, height: panelHeight, backgroundColor: t.backgroundPanel, paddingTop: 1, paddingBottom: 1, flexDirection: "column", children: [_jsxs("box", { flexShrink: 0, flexDirection: "row", justifyContent: "space-between", paddingLeft: 2, paddingRight: 2, children: [_jsx("text", { fg: t.primary, children: _jsx("b", { children: "Add API key" }) }), _jsx("text", { fg: t.textMuted, children: "esc" })] }), _jsx("box", { paddingLeft: 2, paddingRight: 2, paddingTop: 1, children: _jsx("text", { fg: t.text, children: "Paste your DeepSeek
|
|
13
|
+
return (_jsx(Semantic, { id: "api-key-modal", role: "dialog", name: "API Key", isModal: true, children: _jsx("box", { position: "absolute", left: 0, top: 0, width: width, height: height, alignItems: "center", paddingTop: top, backgroundColor: overlayBg, children: _jsxs("box", { width: panelWidth, height: panelHeight, backgroundColor: t.backgroundPanel, paddingTop: 1, paddingBottom: 1, flexDirection: "column", children: [_jsxs("box", { flexShrink: 0, flexDirection: "row", justifyContent: "space-between", paddingLeft: 2, paddingRight: 2, children: [_jsx("text", { fg: t.primary, children: _jsx("b", { children: "Add API key" }) }), _jsx("text", { fg: t.textMuted, children: "esc" })] }), _jsx("box", { paddingLeft: 2, paddingRight: 2, paddingTop: 1, children: _jsx("text", { fg: t.text, children: "Paste your DeepSeek API key to unlock chat. Esc hides this prompt." }) }), _jsx("box", { paddingLeft: 2, paddingRight: 2, paddingTop: 1, children: _jsx("box", { backgroundColor: t.backgroundElement, paddingLeft: 1, paddingRight: 1, width: "100%", children: _jsx(Semantic, { id: "api-key-input", role: "textbox", children: _jsx("textarea", { ref: inputRef, focused: true, placeholder: "sk-...", textColor: t.text, backgroundColor: t.backgroundElement, placeholderColor: t.textMuted, minHeight: 1, maxHeight: 3, wrapMode: "word", keyBindings: TEXTAREA_KEYBINDINGS, onSubmit: onSubmit }) }) }) }), _jsx("box", { flexGrow: 1, minHeight: 0 }), _jsx("box", { paddingLeft: 2, paddingRight: 2, paddingTop: 2, paddingBottom: 1, children: error ? (_jsx("text", { fg: t.diffRemovedFg, children: error })) : (_jsxs("text", { children: [_jsx("span", { style: { fg: t.primary }, children: "enter " }), _jsx("span", { style: { fg: t.textMuted }, children: "save key · " }), _jsx("span", { style: { fg: t.primary }, children: "esc " }), _jsx("span", { style: { fg: t.textMuted }, children: "hide" })] })) })] }) }) }));
|
|
14
14
|
}
|
|
15
15
|
//# sourceMappingURL=api-key-modal.js.map
|