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
|
@@ -4,17 +4,23 @@ import { jsx as _jsx, jsxs as _jsxs } from "@opentui/react/jsx-runtime";
|
|
|
4
4
|
*
|
|
5
5
|
* Claude-Code-style "tool streak" panel — replaces the previous one-line-per-
|
|
6
6
|
* tool render. Lifecycle:
|
|
7
|
-
* - active → header "●
|
|
8
|
-
* - done → collapsed "●
|
|
7
|
+
* - active → header "● Reading 2 files… (N tools · Ms)" + indented item list
|
|
8
|
+
* - done → collapsed "● Read 2 files, ran 1 shell command ctrl+e to expand"
|
|
9
9
|
* - failed → always-expanded header + items, error item flagged red
|
|
10
10
|
*
|
|
11
|
+
* The header names the work per CATEGORY (see utils/tool-summary.ts) rather
|
|
12
|
+
* than saying "Done": once the group collapses that line is all the user has,
|
|
13
|
+
* so it has to carry the meaning. Items add the detail a glance needs — the
|
|
14
|
+
* full shell command for bash, "Wrote N lines to <path>" before a write diff.
|
|
15
|
+
*
|
|
11
16
|
* The active group lives at the tail of the message stream as a regular
|
|
12
17
|
* ChatEntry of type "tool_group"; closing the streak (assistant text arrives
|
|
13
18
|
* or stream ends) flips its state to done/failed in place.
|
|
14
19
|
*/
|
|
15
20
|
import { Semantic } from "@muonroi/agent-harness-opentui";
|
|
16
21
|
import { trunc } from "../utils/text.js";
|
|
17
|
-
import {
|
|
22
|
+
import { activeToolGroupHeader, doneToolGroupSummary } from "../utils/tool-summary.js";
|
|
23
|
+
import { toolLabel } from "../utils/tools.js";
|
|
18
24
|
import { DiffView } from "./diff-view.js";
|
|
19
25
|
// Tools whose result carries a FileDiff worth rendering inline under the item
|
|
20
26
|
// line. Mirrors the per-tool branch in message-view.tsx so grouped edits show
|
|
@@ -33,6 +39,42 @@ function fmtElapsed(ms) {
|
|
|
33
39
|
const remS = Math.floor(s % 60);
|
|
34
40
|
return `${m}m ${remS.toString().padStart(2, "0")}s`;
|
|
35
41
|
}
|
|
42
|
+
// Max command lines rendered inline for a bash item; the rest are elided so a
|
|
43
|
+
// 40-line heredoc can't take over the transcript.
|
|
44
|
+
const BASH_INLINE_LINES = 8;
|
|
45
|
+
/** The command a bash item ran, split for multi-line display. Null when absent. */
|
|
46
|
+
export function bashCommandLines(tc) {
|
|
47
|
+
let cmd;
|
|
48
|
+
try {
|
|
49
|
+
cmd = JSON.parse(tc.function.arguments)?.command;
|
|
50
|
+
}
|
|
51
|
+
catch (err) {
|
|
52
|
+
// Arguments stream in as partial JSON while the call is still assembling —
|
|
53
|
+
// an unparseable value here is expected, not an error worth surfacing.
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
if (typeof cmd !== "string" || !cmd.trim())
|
|
57
|
+
return null;
|
|
58
|
+
const lines = cmd.replace(/\r\n/g, "\n").split("\n");
|
|
59
|
+
if (lines.length <= BASH_INLINE_LINES)
|
|
60
|
+
return lines;
|
|
61
|
+
const hidden = lines.length - BASH_INLINE_LINES;
|
|
62
|
+
return [...lines.slice(0, BASH_INLINE_LINES), `… +${hidden} more line${hidden > 1 ? "s" : ""}`];
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* One-line prose outcome for a write/edit, e.g. "Wrote 161 lines to a.ts" or
|
|
66
|
+
* "Edited a.ts (+12 -3)". Null when the tool isn't a file mutation.
|
|
67
|
+
*/
|
|
68
|
+
export function writeOutcomeLine(toolName, diff) {
|
|
69
|
+
if (toolName === "write_file") {
|
|
70
|
+
const n = diff.additions;
|
|
71
|
+
return `Wrote ${n} line${n === 1 ? "" : "s"} to ${diff.filePath}`;
|
|
72
|
+
}
|
|
73
|
+
if (toolName === "edit_file") {
|
|
74
|
+
return `Edited ${diff.filePath} (+${diff.additions} -${diff.removals})`;
|
|
75
|
+
}
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
36
78
|
function itemGlyph(item) {
|
|
37
79
|
if (item.failed)
|
|
38
80
|
return "✗";
|
|
@@ -51,21 +93,23 @@ export function ToolGroupView({ entry, t, expanded, modeColor }) {
|
|
|
51
93
|
const g = entry.toolGroup;
|
|
52
94
|
if (!g)
|
|
53
95
|
return null;
|
|
54
|
-
const
|
|
96
|
+
const toolNames = g.items.map((it) => it.toolCall.function.name);
|
|
55
97
|
const elapsed = (g.finishedAt ?? Date.now()) - g.startedAt;
|
|
56
98
|
const errorCount = g.items.filter((it) => it.failed).length;
|
|
57
99
|
const total = g.items.length;
|
|
58
100
|
// Decide whether the items list is visible. Active and failed always show
|
|
59
101
|
// items; done collapses unless user expanded with ctrl+e.
|
|
60
102
|
const showItems = g.state === "active" || g.state === "failed" || expanded;
|
|
61
|
-
// Header
|
|
62
|
-
// active: "Reading…"
|
|
63
|
-
// done: "
|
|
103
|
+
// Header names the actual work, counted per category:
|
|
104
|
+
// active: "Reading 2 files…"
|
|
105
|
+
// done: "Read 2 files, ran 1 shell command"
|
|
64
106
|
// failed: "Failed (k errors)"
|
|
107
|
+
// A bare "Done" told the user nothing about what just happened; the recap is
|
|
108
|
+
// the only line left once the group collapses, so it carries the meaning.
|
|
65
109
|
let headerVerb;
|
|
66
110
|
let headerColor;
|
|
67
111
|
if (g.state === "active") {
|
|
68
|
-
headerVerb =
|
|
112
|
+
headerVerb = activeToolGroupHeader(toolNames);
|
|
69
113
|
headerColor = entry.modeColor || modeColor || t.accent;
|
|
70
114
|
}
|
|
71
115
|
else if (g.state === "failed") {
|
|
@@ -73,10 +117,14 @@ export function ToolGroupView({ entry, t, expanded, modeColor }) {
|
|
|
73
117
|
headerColor = t.diffRemovedFg;
|
|
74
118
|
}
|
|
75
119
|
else {
|
|
76
|
-
headerVerb =
|
|
120
|
+
headerVerb = doneToolGroupSummary(toolNames);
|
|
77
121
|
headerColor = t.diffAddedFg;
|
|
78
122
|
}
|
|
79
|
-
|
|
123
|
+
// A restored group's timestamps are write-time, not a measured span — print
|
|
124
|
+
// the count only rather than a fabricated duration.
|
|
125
|
+
const stats = g.restored
|
|
126
|
+
? `${total} tool${total !== 1 ? "s" : ""}`
|
|
127
|
+
: `${total} tool${total !== 1 ? "s" : ""} · ${fmtElapsed(elapsed)}`;
|
|
80
128
|
// Items to render: active capped at ACTIVE_INLINE_LIMIT (overflow line);
|
|
81
129
|
// expanded done/failed shows everything.
|
|
82
130
|
const overflow = g.state === "active" && total > ACTIVE_INLINE_LIMIT ? total - ACTIVE_INLINE_LIMIT : 0;
|
|
@@ -85,7 +133,17 @@ export function ToolGroupView({ entry, t, expanded, modeColor }) {
|
|
|
85
133
|
const label = trunc(toolLabel(it.toolCall), 90);
|
|
86
134
|
const errSuffix = it.failed && it.result?.error ? ` — ${trunc(it.result.error.replace(/\s+/g, " "), 60)}` : "";
|
|
87
135
|
const diff = !it.failed && DIFF_TOOLS.has(it.toolCall.function.name) ? it.result?.diff : undefined;
|
|
88
|
-
|
|
136
|
+
// A bash call's whole point is WHICH command ran; truncating it to
|
|
137
|
+
// one elided line hides that. Show every line, indented under the
|
|
138
|
+
// item, the way a shell transcript reads.
|
|
139
|
+
const bashLines = it.toolCall.function.name === "bash" ? bashCommandLines(it.toolCall) : null;
|
|
140
|
+
// Shell transcript shape: "$ <first line>" on the item line, any
|
|
141
|
+
// continuation lines aligned under it.
|
|
142
|
+
const headLine = bashLines ? `$ ${bashLines[0]}` : label;
|
|
143
|
+
const restLines = bashLines ? bashLines.slice(1) : [];
|
|
144
|
+
return (_jsxs("box", { flexDirection: "column", children: [_jsxs("text", { children: [_jsx("span", { style: { fg: itemColor(it, t) }, children: `${itemGlyph(it)} ` }), _jsx("span", { style: { fg: t.textMuted }, children: trunc(headLine, 100) }), errSuffix && _jsx("span", { style: { fg: t.diffRemovedFg }, children: errSuffix })] }), restLines.map((line, li) => (
|
|
145
|
+
// biome-ignore lint/suspicious/noArrayIndexKey: command lines are positional and immutable
|
|
146
|
+
_jsx("box", { paddingLeft: 2, children: _jsx("text", { fg: t.textMuted, children: trunc(line, 100) }) }, `${it.toolCall.id}-cmd-${li}`))), diff && writeOutcomeLine(it.toolCall.function.name, diff) && (_jsx("box", { paddingLeft: 2, children: _jsx("text", { fg: t.textMuted, children: writeOutcomeLine(it.toolCall.function.name, diff) }) })), diff && _jsx(DiffView, { t: t, diff: diff })] }, it.toolCall.id));
|
|
89
147
|
})] })), g.state === "done" && !expanded && total > 0 && (_jsx("box", { paddingLeft: 2, children: _jsx("text", { fg: t.textDim, children: "ctrl+e to expand" }) }))] }) }));
|
|
90
148
|
}
|
|
91
149
|
//# sourceMappingURL=tool-group.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;
|
|
@@ -10,7 +11,8 @@ export interface ModalsLayerProps {
|
|
|
10
11
|
apiKeyError: any;
|
|
11
12
|
apiKeyInputRef: any;
|
|
12
13
|
apiKeyPrompt: any;
|
|
13
|
-
|
|
14
|
+
oauthProviders: any;
|
|
15
|
+
oauthLogin: any;
|
|
14
16
|
configuredProviders: any;
|
|
15
17
|
connectModalIndex: any;
|
|
16
18
|
defaultProvider: any;
|
|
@@ -50,7 +52,7 @@ export interface ModalsLayerProps {
|
|
|
50
52
|
scheduleRows: any;
|
|
51
53
|
scheduleSearchQuery: any;
|
|
52
54
|
sessionPickerIndex: any;
|
|
53
|
-
sessionPickerList:
|
|
55
|
+
sessionPickerList: ResumeEntry[];
|
|
54
56
|
showAgentsEditor: any;
|
|
55
57
|
showAgentsModal: any;
|
|
56
58
|
showApiKeyModal: any;
|
|
@@ -12,7 +12,7 @@ import { UpdateModal } from "../modals/update-modal.js";
|
|
|
12
12
|
import { WalletPickerModal } from "../modals/wallet-picker-modal.js";
|
|
13
13
|
import { ScheduleBrowserModal } from "../schedule-modal.js";
|
|
14
14
|
export function ModalsLayer(props) {
|
|
15
|
-
const { agentRows, agentsEditorDraft, agentsEditorError, agentsEditorField, agentsEditorModelIndex, agentsEditorSyncKey, agentsModalIndex, agentsSearchQuery, apiKeyError, apiKeyInputRef, apiKeyPrompt,
|
|
16
|
-
return (_jsxs(_Fragment, { children: [showApiKeyModal && (_jsx(ApiKeyModal, { t: t, width: width, height: height, inputRef: apiKeyInputRef, error: apiKeyError, onSubmit: submitApiKey })), showUpdateModal && updateInfo && (_jsx(UpdateModal, { t: t, width: width, height: height, currentVersion: startupConfig.version, latestVersion: updateInfo.latestVersion })), showMcpModal && !showMcpEditor && (_jsx(McpBrowserModal, { t: t, width: width, height: height, selectedIndex: mcpModalIndex, searchQuery: mcpSearchQuery, rows: mcpRows })), showMcpEditor && (_jsx(McpEditorModal, { t: t, width: width, height: height, draft: mcpEditorDraft, focusedField: mcpEditorField, syncKey: mcpEditorSyncKey, error: mcpEditorError, title: editingMcpId ? "Edit MCP Server" : "Add MCP Server", labelRef: mcpLabelRef, urlRef: mcpUrlRef, headersRef: mcpHeadersRef, commandRef: mcpCommandRef, argsRef: mcpArgsRef, cwdRef: mcpCwdRef, envRef: mcpEnvRef, onSubmit: submitMcpEditor })), showScheduleModal && (_jsx(ScheduleBrowserModal, { t: t, width: width, height: height, selectedIndex: scheduleModalIndex, searchQuery: scheduleSearchQuery, rows: scheduleRows })), showAgentsModal && !showAgentsEditor && (_jsx(SubagentsBrowserModal, { t: t, width: width, height: height, selectedIndex: agentsModalIndex, searchQuery: agentsSearchQuery, rows: agentRows })), showAgentsEditor && (_jsx(SubagentEditorModal, { t: t, width: width, height: height, draft: agentsEditorDraft, focusedField: agentsEditorField, modelIndex: agentsEditorModelIndex, error: agentsEditorError, title: editingSubagent ? `Edit sub-agent: ${formatSubagentName(editingSubagent.name)}` : "Add sub-agent", nameRef: subagentNameRef, instructionRef: subagentInstructionRef, onSubmit: submitSubagentEditor, showRemoveHint: !!editingSubagent }, `subagent-editor-${agentsEditorSyncKey}`)), showModelPicker && (_jsx(ModelPickerModal, { t: t, currentModel: model, selectedIndex: modelPickerIndex, width: width, height: height, searchQuery: modelSearchQuery, filteredModels: filteredModels, reasoningEffortByModel: reasoningEffortByModel, configuredProviders: configuredProviders, disabledProviders: disabledProviders, disabledModels: disabledModels, defaultProvider: defaultProvider, focus: modelPickerFocus, providerChipIndex: providerChipIndex, providersWithKey: providersWithKey, apiKeyPrompt: apiKeyPrompt,
|
|
15
|
+
const { agentRows, agentsEditorDraft, agentsEditorError, agentsEditorField, agentsEditorModelIndex, agentsEditorSyncKey, agentsModalIndex, agentsSearchQuery, apiKeyError, apiKeyInputRef, apiKeyPrompt, oauthProviders, oauthLogin, configuredProviders, connectModalIndex, defaultProvider, disabledModels, disabledProviders, editingMcpId, editingSubagent, filteredModels, height, mcpArgsRef, mcpCommandRef, mcpCwdRef, mcpEditorDraft, mcpEditorError, mcpEditorField, mcpEditorSyncKey, mcpEnvRef, mcpHeadersRef, mcpLabelRef, mcpModalIndex, mcpRows, mcpSearchQuery, mcpUrlRef, model, modelPickerFocus, modelPickerIndex, modelSearchQuery, providerChipIndex, providersWithKey, reasoningEffortByModel, sandboxMode, sandboxSettings, sandboxSettingsEditBuffer, sandboxSettingsEditing, sandboxSettingsFocusIndex, scheduleModalIndex, scheduleRows, scheduleSearchQuery, sessionPickerIndex, sessionPickerList, showAgentsEditor, showAgentsModal, showApiKeyModal, showConnectModal, showMcpEditor, showMcpModal, showModelPicker, showSandboxPicker, showScheduleModal, showSessionPicker, showTelegramPairModal, showTelegramTokenModal, showUpdateModal, showWalletPicker, startupConfig, subagentInstructionRef, subagentNameRef, submitApiKey, submitMcpEditor, submitSubagentEditor, submitTelegramPair, submitTelegramToken, t, telegramPairError, telegramPairInputRef, telegramTokenError, telegramTokenInputRef, updateInfo, walletDisplayInfo, walletFocusIndex, walletSettings, width, } = props;
|
|
16
|
+
return (_jsxs(_Fragment, { children: [showApiKeyModal && (_jsx(ApiKeyModal, { t: t, width: width, height: height, inputRef: apiKeyInputRef, error: apiKeyError, onSubmit: submitApiKey })), showUpdateModal && updateInfo && (_jsx(UpdateModal, { t: t, width: width, height: height, currentVersion: startupConfig.version, latestVersion: updateInfo.latestVersion })), showMcpModal && !showMcpEditor && (_jsx(McpBrowserModal, { t: t, width: width, height: height, selectedIndex: mcpModalIndex, searchQuery: mcpSearchQuery, rows: mcpRows })), showMcpEditor && (_jsx(McpEditorModal, { t: t, width: width, height: height, draft: mcpEditorDraft, focusedField: mcpEditorField, syncKey: mcpEditorSyncKey, error: mcpEditorError, title: editingMcpId ? "Edit MCP Server" : "Add MCP Server", labelRef: mcpLabelRef, urlRef: mcpUrlRef, headersRef: mcpHeadersRef, commandRef: mcpCommandRef, argsRef: mcpArgsRef, cwdRef: mcpCwdRef, envRef: mcpEnvRef, onSubmit: submitMcpEditor })), showScheduleModal && (_jsx(ScheduleBrowserModal, { t: t, width: width, height: height, selectedIndex: scheduleModalIndex, searchQuery: scheduleSearchQuery, rows: scheduleRows })), showAgentsModal && !showAgentsEditor && (_jsx(SubagentsBrowserModal, { t: t, width: width, height: height, selectedIndex: agentsModalIndex, searchQuery: agentsSearchQuery, rows: agentRows })), showAgentsEditor && (_jsx(SubagentEditorModal, { t: t, width: width, height: height, draft: agentsEditorDraft, focusedField: agentsEditorField, modelIndex: agentsEditorModelIndex, error: agentsEditorError, title: editingSubagent ? `Edit sub-agent: ${formatSubagentName(editingSubagent.name)}` : "Add sub-agent", nameRef: subagentNameRef, instructionRef: subagentInstructionRef, onSubmit: submitSubagentEditor, showRemoveHint: !!editingSubagent }, `subagent-editor-${agentsEditorSyncKey}`)), showModelPicker && (_jsx(ModelPickerModal, { t: t, currentModel: model, selectedIndex: modelPickerIndex, width: width, height: height, searchQuery: modelSearchQuery, filteredModels: filteredModels, reasoningEffortByModel: reasoningEffortByModel, configuredProviders: configuredProviders, disabledProviders: disabledProviders, disabledModels: disabledModels, defaultProvider: defaultProvider, focus: modelPickerFocus, providerChipIndex: providerChipIndex, providersWithKey: providersWithKey, apiKeyPrompt: apiKeyPrompt, oauthProviders: oauthProviders, oauthLogin: oauthLogin })), showSessionPicker && (_jsx(SessionPickerModal, { t: t, sessions: sessionPickerList, focusIndex: sessionPickerIndex, width: width, height: height })), showWalletPicker && (_jsx(WalletPickerModal, { t: t, settings: walletSettings, walletInfo: walletDisplayInfo, focusIndex: walletFocusIndex, width: width, height: height })), showSandboxPicker && (_jsx(SandboxPickerModal, { t: t, currentMode: sandboxMode, settings: sandboxSettings, focusIndex: sandboxSettingsFocusIndex, editing: sandboxSettingsEditing, editBuffer: sandboxSettingsEditBuffer, width: width, height: height })), showConnectModal && (_jsx(ConnectModal, { t: t, width: width, height: height, selectedIndex: connectModalIndex, channels: CONNECT_CHANNELS })), showTelegramTokenModal && (_jsx(TelegramTokenModal, { t: t, width: width, height: height, inputRef: telegramTokenInputRef, error: telegramTokenError, onSubmit: submitTelegramToken })), showTelegramPairModal && (_jsx(TelegramPairModal, { t: t, width: width, height: height, inputRef: telegramPairInputRef, error: telegramPairError, onSubmit: () => void submitTelegramPair() }))] }));
|
|
17
17
|
}
|
|
18
18
|
//# sourceMappingURL=modals-layer.js.map
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/ui/council-harness-event.ts
|
|
3
|
+
*
|
|
4
|
+
* Pure mapping from a council `CouncilStatusData` chunk to the harness
|
|
5
|
+
* `council-speaker` LiveEvent payload.
|
|
6
|
+
*
|
|
7
|
+
* Why this exists. The long research phase (`llm.research`, up to ~10 min /
|
|
8
|
+
* 15 tool steps) runs as a single internal `generateText` — the MAIN stream is
|
|
9
|
+
* quiet the whole time, so `tui_wait_for(idle)` reports a FALSE idle and an
|
|
10
|
+
* agent driving the TUI misjudges the run as hung. The only signal during that
|
|
11
|
+
* window is the 1s `council_status` heartbeat (`state:"tick"`, advancing
|
|
12
|
+
* `elapsedMs`) emitted by `tracedAsync`. Previously the emit site collapsed
|
|
13
|
+
* every non-start state to `status:"done"` and DROPPED `elapsedMs`, so a poller
|
|
14
|
+
* reading `tui_last_event("council-speaker")` saw a frozen "done" event and
|
|
15
|
+
* concluded the speaker had finished — the exact false-stall this fixes.
|
|
16
|
+
*
|
|
17
|
+
* Carrying `state:"tick"` + `elapsedMs` through lets a harness monitor
|
|
18
|
+
* distinguish ALIVE (elapsedMs advancing across polls) from HUNG (elapsedMs
|
|
19
|
+
* frozen past a threshold) with a single `tui_last_event` call.
|
|
20
|
+
*/
|
|
21
|
+
import type { CouncilStatusState } from "../types/index.js";
|
|
22
|
+
/** Harness `council-speaker` status: adds "tick" progress heartbeat to start/done. */
|
|
23
|
+
export type CouncilSpeakerStatus = "start" | "tick" | "done";
|
|
24
|
+
export interface CouncilStatusLike {
|
|
25
|
+
state: CouncilStatusState;
|
|
26
|
+
statusId: string;
|
|
27
|
+
role?: string;
|
|
28
|
+
label?: string;
|
|
29
|
+
elapsedMs?: number;
|
|
30
|
+
streamedChars?: number;
|
|
31
|
+
lastDeltaAgeMs?: number;
|
|
32
|
+
}
|
|
33
|
+
export interface CouncilSpeakerEvent {
|
|
34
|
+
t: "event";
|
|
35
|
+
kind: "council-speaker";
|
|
36
|
+
role: string;
|
|
37
|
+
status: CouncilSpeakerStatus;
|
|
38
|
+
correlationId: string;
|
|
39
|
+
elapsedMs?: number;
|
|
40
|
+
/** Chars (text + reasoning deltas) streamed since this phase began. */
|
|
41
|
+
streamedChars?: number;
|
|
42
|
+
/** Age of the most recent stream delta, in ms. */
|
|
43
|
+
lastDeltaAgeMs?: number;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Map a council status chunk to the `council-speaker` harness event payload.
|
|
47
|
+
* `start`→"start", `tick`→"tick" (progress heartbeat), `done`/`error`→"done".
|
|
48
|
+
* `elapsedMs` is passed through unchanged so a poller can measure progress.
|
|
49
|
+
*
|
|
50
|
+
* `streamedChars` / `lastDeltaAgeMs` ride along when the council emitted them.
|
|
51
|
+
* `elapsedMs` can freeze even on a healthy call — the tick generator only
|
|
52
|
+
* advances when its consumer pulls, and a round awaiting pairs via Promise.all
|
|
53
|
+
* does not pull. These two are pushed from the token stream itself, so they
|
|
54
|
+
* separate SLOW-BUT-ALIVE (chars growing, small delta age) from STUCK (chars
|
|
55
|
+
* static, delta age growing) without depending on generator pumping.
|
|
56
|
+
*/
|
|
57
|
+
export declare function mapCouncilStatusToSpeakerEvent(cs: CouncilStatusLike): CouncilSpeakerEvent;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/ui/council-harness-event.ts
|
|
3
|
+
*
|
|
4
|
+
* Pure mapping from a council `CouncilStatusData` chunk to the harness
|
|
5
|
+
* `council-speaker` LiveEvent payload.
|
|
6
|
+
*
|
|
7
|
+
* Why this exists. The long research phase (`llm.research`, up to ~10 min /
|
|
8
|
+
* 15 tool steps) runs as a single internal `generateText` — the MAIN stream is
|
|
9
|
+
* quiet the whole time, so `tui_wait_for(idle)` reports a FALSE idle and an
|
|
10
|
+
* agent driving the TUI misjudges the run as hung. The only signal during that
|
|
11
|
+
* window is the 1s `council_status` heartbeat (`state:"tick"`, advancing
|
|
12
|
+
* `elapsedMs`) emitted by `tracedAsync`. Previously the emit site collapsed
|
|
13
|
+
* every non-start state to `status:"done"` and DROPPED `elapsedMs`, so a poller
|
|
14
|
+
* reading `tui_last_event("council-speaker")` saw a frozen "done" event and
|
|
15
|
+
* concluded the speaker had finished — the exact false-stall this fixes.
|
|
16
|
+
*
|
|
17
|
+
* Carrying `state:"tick"` + `elapsedMs` through lets a harness monitor
|
|
18
|
+
* distinguish ALIVE (elapsedMs advancing across polls) from HUNG (elapsedMs
|
|
19
|
+
* frozen past a threshold) with a single `tui_last_event` call.
|
|
20
|
+
*/
|
|
21
|
+
/**
|
|
22
|
+
* Map a council status chunk to the `council-speaker` harness event payload.
|
|
23
|
+
* `start`→"start", `tick`→"tick" (progress heartbeat), `done`/`error`→"done".
|
|
24
|
+
* `elapsedMs` is passed through unchanged so a poller can measure progress.
|
|
25
|
+
*
|
|
26
|
+
* `streamedChars` / `lastDeltaAgeMs` ride along when the council emitted them.
|
|
27
|
+
* `elapsedMs` can freeze even on a healthy call — the tick generator only
|
|
28
|
+
* advances when its consumer pulls, and a round awaiting pairs via Promise.all
|
|
29
|
+
* does not pull. These two are pushed from the token stream itself, so they
|
|
30
|
+
* separate SLOW-BUT-ALIVE (chars growing, small delta age) from STUCK (chars
|
|
31
|
+
* static, delta age growing) without depending on generator pumping.
|
|
32
|
+
*/
|
|
33
|
+
export function mapCouncilStatusToSpeakerEvent(cs) {
|
|
34
|
+
const status = cs.state === "start" ? "start" : cs.state === "tick" ? "tick" : "done";
|
|
35
|
+
return {
|
|
36
|
+
t: "event",
|
|
37
|
+
kind: "council-speaker",
|
|
38
|
+
role: cs.role ?? cs.label ?? "unknown",
|
|
39
|
+
status,
|
|
40
|
+
correlationId: cs.statusId,
|
|
41
|
+
...(typeof cs.elapsedMs === "number" ? { elapsedMs: cs.elapsedMs } : {}),
|
|
42
|
+
...(typeof cs.streamedChars === "number" ? { streamedChars: cs.streamedChars } : {}),
|
|
43
|
+
...(typeof cs.lastDeltaAgeMs === "number" ? { lastDeltaAgeMs: cs.lastDeltaAgeMs } : {}),
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=council-harness-event.js.map
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/ui/heartbeat-debug.ts
|
|
3
|
+
*
|
|
4
|
+
* Env-gated instrumentation to pinpoint the council rail "frozen elapsed / static
|
|
5
|
+
* spinner" during long phases. Live evidence (harness 60Hz dedup frames identical
|
|
6
|
+
* for 110s + braille spinner not rotating) shows a real in-phase render/paint
|
|
7
|
+
* freeze, but NOT which link starves: (T) the setInterval TIMER not firing, (R)
|
|
8
|
+
* the timer fires but React does not re-render/commit, or (P) React commits but
|
|
9
|
+
* OpenTUI does not repaint.
|
|
10
|
+
*
|
|
11
|
+
* When `MUONROI_HEARTBEAT_DEBUG` is set to a file path, we append one JSONL line
|
|
12
|
+
* per event so a single instrumented council run answers T/R/P:
|
|
13
|
+
* - kind:"timer" → a setInterval callback actually fired (rules in/out T)
|
|
14
|
+
* - kind:"render" → a component's render body ran (rules in/out R)
|
|
15
|
+
* Compare timestamps against the sidechannel council-step timeline: if `timer`
|
|
16
|
+
* lines keep landing every ~100/1000ms through a phase but the harness frame is
|
|
17
|
+
* frozen, the starve is at paint (P); if `timer` lines STOP during the phase, the
|
|
18
|
+
* event loop / timer is starved (T).
|
|
19
|
+
*
|
|
20
|
+
* Unset → a single boolean check per call, zero file I/O, zero behaviour change.
|
|
21
|
+
*/
|
|
22
|
+
export declare function heartbeatDebugEnabled(): boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Append one instrumentation record. No-op unless MUONROI_HEARTBEAT_DEBUG points
|
|
25
|
+
* at a file. `kind` is "timer" (a setInterval callback fired) or "render" (a
|
|
26
|
+
* component render body executed). `extra` carries component-specific detail
|
|
27
|
+
* (frame index, computed elapsedMs, phase label).
|
|
28
|
+
*/
|
|
29
|
+
export declare function heartbeatDebug(component: string, kind: "timer" | "render", extra?: Record<string, unknown>): void;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/ui/heartbeat-debug.ts
|
|
3
|
+
*
|
|
4
|
+
* Env-gated instrumentation to pinpoint the council rail "frozen elapsed / static
|
|
5
|
+
* spinner" during long phases. Live evidence (harness 60Hz dedup frames identical
|
|
6
|
+
* for 110s + braille spinner not rotating) shows a real in-phase render/paint
|
|
7
|
+
* freeze, but NOT which link starves: (T) the setInterval TIMER not firing, (R)
|
|
8
|
+
* the timer fires but React does not re-render/commit, or (P) React commits but
|
|
9
|
+
* OpenTUI does not repaint.
|
|
10
|
+
*
|
|
11
|
+
* When `MUONROI_HEARTBEAT_DEBUG` is set to a file path, we append one JSONL line
|
|
12
|
+
* per event so a single instrumented council run answers T/R/P:
|
|
13
|
+
* - kind:"timer" → a setInterval callback actually fired (rules in/out T)
|
|
14
|
+
* - kind:"render" → a component's render body ran (rules in/out R)
|
|
15
|
+
* Compare timestamps against the sidechannel council-step timeline: if `timer`
|
|
16
|
+
* lines keep landing every ~100/1000ms through a phase but the harness frame is
|
|
17
|
+
* frozen, the starve is at paint (P); if `timer` lines STOP during the phase, the
|
|
18
|
+
* event loop / timer is starved (T).
|
|
19
|
+
*
|
|
20
|
+
* Unset → a single boolean check per call, zero file I/O, zero behaviour change.
|
|
21
|
+
*/
|
|
22
|
+
import { appendFileSync } from "node:fs";
|
|
23
|
+
const SINK = process.env.MUONROI_HEARTBEAT_DEBUG?.trim() || null;
|
|
24
|
+
export function heartbeatDebugEnabled() {
|
|
25
|
+
return SINK !== null;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Append one instrumentation record. No-op unless MUONROI_HEARTBEAT_DEBUG points
|
|
29
|
+
* at a file. `kind` is "timer" (a setInterval callback fired) or "render" (a
|
|
30
|
+
* component render body executed). `extra` carries component-specific detail
|
|
31
|
+
* (frame index, computed elapsedMs, phase label).
|
|
32
|
+
*/
|
|
33
|
+
export function heartbeatDebug(component, kind, extra) {
|
|
34
|
+
if (SINK === null)
|
|
35
|
+
return;
|
|
36
|
+
try {
|
|
37
|
+
const rec = { ts: Date.now(), component, kind, ...(extra ?? {}) };
|
|
38
|
+
appendFileSync(SINK, `${JSON.stringify(rec)}\n`);
|
|
39
|
+
}
|
|
40
|
+
catch (err) {
|
|
41
|
+
// Instrumentation must never break the UI; surface once at debug level.
|
|
42
|
+
console.error(`[heartbeat-debug] append failed: ${err?.message}`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=heartbeat-debug.js.map
|
|
@@ -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
|
|
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 a provider API key, or press Esc and use /providers to sign in (OAuth)." }) }), _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
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "@opentui/react/jsx-runtime";
|
|
2
2
|
import { useEffect, useRef } from "react";
|
|
3
|
+
import { Dialog } from "../primitives/index.js";
|
|
3
4
|
import { bottomAlignedModalTop } from "../utils/modal.js";
|
|
4
5
|
const TEXTAREA_KEYBINDINGS = [
|
|
5
6
|
{ name: "return", action: "submit" },
|
|
@@ -15,20 +16,20 @@ export function ConnectModal({ t, width, height, selectedIndex, channels, }) {
|
|
|
15
16
|
const panelHeight = Math.min(channels.length + 9, Math.floor(height * 0.5));
|
|
16
17
|
const top = bottomAlignedModalTop(height, panelHeight);
|
|
17
18
|
const overlayBg = "#000000cc";
|
|
18
|
-
return (_jsx("box", { position: "absolute", left: 0, top: 0, width: width, height: height, alignItems: "center", paddingTop: top, backgroundColor: overlayBg, children: _jsxs("box", { width: Math.min(56, 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: "Connect" }) }), _jsx("text", { fg: t.textMuted, children: "esc" })] }), _jsx("box", { flexShrink: 0, paddingLeft: 2, paddingRight: 2, paddingTop: 1, paddingBottom: 1, children: _jsx("text", { fg: t.textMuted, children: "Choose a channel" }) }), _jsx("scrollbox", { ref: listRef, flexGrow: 1, minHeight: 0, children: channels.map((ch, idx) => (_jsx("box", { id: `connect-${ch.id}`, backgroundColor: idx === selectedIndex ? t.selectedBg : undefined, paddingLeft: 2, paddingRight: 2, children: _jsxs("box", { flexDirection: "row", justifyContent: "space-between", children: [_jsx("text", { fg: idx === selectedIndex ? t.selected : t.text, children: ch.label }), _jsx("text", { fg: t.textMuted, children: ch.description })] }) }, ch.id))) }), _jsx("box", { flexShrink: 0, paddingLeft: 2, paddingRight: 2, paddingTop: 2, paddingBottom: 1, children: _jsxs("text", { children: [_jsx("span", { style: { fg: t.primary }, children: "enter " }), _jsx("span", { style: { fg: t.textMuted }, children: "select · " }), _jsx("span", { style: { fg: t.primary }, children: "↑↓ " }), _jsx("span", { style: { fg: t.textMuted }, children: "navigate · " }), _jsx("span", { style: { fg: t.primary }, children: "esc " }), _jsx("span", { style: { fg: t.textMuted }, children: "close" })] }) })] }) }));
|
|
19
|
+
return (_jsx(Dialog, { id: "connect-modal", name: "Connect", children: _jsx("box", { position: "absolute", left: 0, top: 0, width: width, height: height, alignItems: "center", paddingTop: top, backgroundColor: overlayBg, children: _jsxs("box", { width: Math.min(56, 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: "Connect" }) }), _jsx("text", { fg: t.textMuted, children: "esc" })] }), _jsx("box", { flexShrink: 0, paddingLeft: 2, paddingRight: 2, paddingTop: 1, paddingBottom: 1, children: _jsx("text", { fg: t.textMuted, children: "Choose a channel" }) }), _jsx("scrollbox", { ref: listRef, flexGrow: 1, minHeight: 0, children: channels.map((ch, idx) => (_jsx("box", { id: `connect-${ch.id}`, backgroundColor: idx === selectedIndex ? t.selectedBg : undefined, paddingLeft: 2, paddingRight: 2, children: _jsxs("box", { flexDirection: "row", justifyContent: "space-between", children: [_jsx("text", { fg: idx === selectedIndex ? t.selected : t.text, children: ch.label }), _jsx("text", { fg: t.textMuted, children: ch.description })] }) }, ch.id))) }), _jsx("box", { flexShrink: 0, paddingLeft: 2, paddingRight: 2, paddingTop: 2, paddingBottom: 1, children: _jsxs("text", { children: [_jsx("span", { style: { fg: t.primary }, children: "enter " }), _jsx("span", { style: { fg: t.textMuted }, children: "select · " }), _jsx("span", { style: { fg: t.primary }, children: "↑↓ " }), _jsx("span", { style: { fg: t.textMuted }, children: "navigate · " }), _jsx("span", { style: { fg: t.primary }, children: "esc " }), _jsx("span", { style: { fg: t.textMuted }, children: "close" })] }) })] }) }) }));
|
|
19
20
|
}
|
|
20
21
|
export function TelegramTokenModal({ t, width, height, inputRef, error, onSubmit, }) {
|
|
21
22
|
const overlayBg = "#000000cc";
|
|
22
23
|
const panelWidth = Math.min(68, width - 6);
|
|
23
24
|
const panelHeight = 14;
|
|
24
25
|
const top = bottomAlignedModalTop(height, panelHeight);
|
|
25
|
-
return (_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: "Telegram bot token" }) }), _jsx("text", { fg: t.textMuted, children: "esc" })] }), _jsx("box", { paddingLeft: 2, paddingRight: 2, paddingTop: 1, children: _jsx("text", { fg: t.text, children: "From @BotFather: /newbot, then paste the token here. Stored in ~/.muonroi-cli/user-settings.json." }) }), _jsx("box", { paddingLeft: 2, paddingRight: 2, paddingTop: 1, children: _jsx("box", { backgroundColor: t.backgroundElement, paddingLeft: 1, paddingRight: 1, width: "100%", children: _jsx("textarea", { ref: inputRef, focused: true, placeholder: "123456:ABC...", 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 token · " }), _jsx("span", { style: { fg: t.primary }, children: "esc " }), _jsx("span", { style: { fg: t.textMuted }, children: "close" })] })) })] }) }));
|
|
26
|
+
return (_jsx(Dialog, { id: "telegram-token-modal", name: "Telegram bot token", 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: "Telegram bot token" }) }), _jsx("text", { fg: t.textMuted, children: "esc" })] }), _jsx("box", { paddingLeft: 2, paddingRight: 2, paddingTop: 1, children: _jsx("text", { fg: t.text, children: "From @BotFather: /newbot, then paste the token here. Stored in ~/.muonroi-cli/user-settings.json." }) }), _jsx("box", { paddingLeft: 2, paddingRight: 2, paddingTop: 1, children: _jsx("box", { backgroundColor: t.backgroundElement, paddingLeft: 1, paddingRight: 1, width: "100%", children: _jsx("textarea", { ref: inputRef, focused: true, placeholder: "123456:ABC...", 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 token · " }), _jsx("span", { style: { fg: t.primary }, children: "esc " }), _jsx("span", { style: { fg: t.textMuted }, children: "close" })] })) })] }) }) }));
|
|
26
27
|
}
|
|
27
28
|
export function TelegramPairModal({ t, width, height, inputRef, error, onSubmit, }) {
|
|
28
29
|
const overlayBg = "#000000cc";
|
|
29
30
|
const panelWidth = Math.min(68, width - 6);
|
|
30
31
|
const panelHeight = 13;
|
|
31
32
|
const top = bottomAlignedModalTop(height, panelHeight);
|
|
32
|
-
return (_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: "Pairing code" }) }), _jsx("text", { fg: t.textMuted, children: "esc" })] }), _jsx("box", { paddingLeft: 2, paddingRight: 2, paddingTop: 1, children: _jsx("text", { fg: t.text, children: "DM your bot with /pair, then paste the 6-character code." }) }), _jsx("box", { paddingLeft: 2, paddingRight: 2, paddingTop: 1, children: _jsx("box", { backgroundColor: t.backgroundElement, paddingLeft: 1, paddingRight: 1, width: "100%", children: _jsx("textarea", { ref: inputRef, focused: true, placeholder: "ABC123", textColor: t.text, backgroundColor: t.backgroundElement, placeholderColor: t.textMuted, minHeight: 1, maxHeight: 2, 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: "approve pairing · " }), _jsx("span", { style: { fg: t.primary }, children: "esc " }), _jsx("span", { style: { fg: t.textMuted }, children: "close" })] })) })] }) }));
|
|
33
|
+
return (_jsx(Dialog, { id: "telegram-pair-modal", name: "Pairing code", 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: "Pairing code" }) }), _jsx("text", { fg: t.textMuted, children: "esc" })] }), _jsx("box", { paddingLeft: 2, paddingRight: 2, paddingTop: 1, children: _jsx("text", { fg: t.text, children: "DM your bot with /pair, then paste the 6-character code." }) }), _jsx("box", { paddingLeft: 2, paddingRight: 2, paddingTop: 1, children: _jsx("box", { backgroundColor: t.backgroundElement, paddingLeft: 1, paddingRight: 1, width: "100%", children: _jsx("textarea", { ref: inputRef, focused: true, placeholder: "ABC123", textColor: t.text, backgroundColor: t.backgroundElement, placeholderColor: t.textMuted, minHeight: 1, maxHeight: 2, 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: "approve pairing · " }), _jsx("span", { style: { fg: t.primary }, children: "esc " }), _jsx("span", { style: { fg: t.textMuted }, children: "close" })] })) })] }) }) }));
|
|
33
34
|
}
|
|
34
35
|
//# sourceMappingURL=connect-modal.js.map
|
|
@@ -14,24 +14,12 @@ export interface ApiKeyPromptState {
|
|
|
14
14
|
/** When true the field shows the raw key instead of mask dots (Ctrl+R). */
|
|
15
15
|
reveal?: boolean;
|
|
16
16
|
}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
error: string | null;
|
|
21
|
-
loading: boolean;
|
|
22
|
-
} | {
|
|
23
|
-
phase: "picker";
|
|
24
|
-
session: string;
|
|
25
|
-
items: Array<{
|
|
26
|
-
provider: ProviderId;
|
|
27
|
-
key: string;
|
|
28
|
-
}>;
|
|
29
|
-
selected: Set<ProviderId>;
|
|
30
|
-
focusIndex: number;
|
|
31
|
-
loading: boolean;
|
|
17
|
+
/** In-progress OAuth login overlay state (browser-based subscription sign-in). */
|
|
18
|
+
export interface OAuthLoginState {
|
|
19
|
+
provider: ProviderId;
|
|
32
20
|
error: string | null;
|
|
33
|
-
}
|
|
34
|
-
export declare function ModelPickerModal({ t, width, height, configuredProviders, disabledProviders, defaultProvider, providerChipIndex, providersWithKey, apiKeyPrompt,
|
|
21
|
+
}
|
|
22
|
+
export declare function ModelPickerModal({ t, width, height, configuredProviders, disabledProviders, defaultProvider, providerChipIndex, providersWithKey, apiKeyPrompt, oauthProviders, oauthLogin, }: {
|
|
35
23
|
t: Theme;
|
|
36
24
|
currentModel?: string;
|
|
37
25
|
selectedIndex?: number;
|
|
@@ -48,5 +36,7 @@ export declare function ModelPickerModal({ t, width, height, configuredProviders
|
|
|
48
36
|
providerChipIndex: number;
|
|
49
37
|
providersWithKey?: ReadonlySet<ProviderId>;
|
|
50
38
|
apiKeyPrompt?: ApiKeyPromptState | null;
|
|
51
|
-
|
|
39
|
+
/** Providers that support OAuth subscription login (openai, xai). */
|
|
40
|
+
oauthProviders?: ReadonlySet<ProviderId>;
|
|
41
|
+
oauthLogin?: OAuthLoginState | null;
|
|
52
42
|
}): import("react").ReactNode;
|
|
@@ -21,9 +21,10 @@ export function groupModelsByTier(models) {
|
|
|
21
21
|
const order = ["premium", "balanced", "fast", "other"];
|
|
22
22
|
return order.filter((t) => map.has(t)).map((t) => ({ tier: t, items: map.get(t) }));
|
|
23
23
|
}
|
|
24
|
-
export function ModelPickerModal({ t, width, height, configuredProviders, disabledProviders, defaultProvider, providerChipIndex, providersWithKey, apiKeyPrompt,
|
|
24
|
+
export function ModelPickerModal({ t, width, height, configuredProviders, disabledProviders, defaultProvider, providerChipIndex, providersWithKey, apiKeyPrompt, oauthProviders, oauthLogin, }) {
|
|
25
25
|
const disabledSet = new Set(disabledProviders);
|
|
26
26
|
const keyedSet = providersWithKey ?? new Set();
|
|
27
|
+
const oauthSet = oauthProviders ?? new Set();
|
|
27
28
|
const panelWidth = Math.min(64, width - 6);
|
|
28
29
|
const rowCount = Math.max(configuredProviders.length, 1);
|
|
29
30
|
const contentHeight = rowCount + 7;
|
|
@@ -32,13 +33,9 @@ export function ModelPickerModal({ t, width, height, configuredProviders, disabl
|
|
|
32
33
|
const top = bottomAlignedModalTop(height, panelHeight);
|
|
33
34
|
const overlayBg = "#000000cc";
|
|
34
35
|
// Sub-modal: API key prompt overlay (rendered on top of the picker).
|
|
35
|
-
const subModal = apiKeyPrompt ? (_jsx(Semantic, { id: "provider-key-prompt", role: "dialog", isModal: true, name: `Set ${apiKeyPrompt.provider} key`, children: _jsx("box", { position: "absolute", left: 0, top: 0, width: width, height: height, alignItems: "center", paddingTop: Math.floor(height / 3), backgroundColor: "#000000dd", children: _jsxs("box", { width: Math.min(60, width - 8), backgroundColor: t.backgroundPanel, paddingTop: 1, paddingBottom: 1, paddingLeft: 2, paddingRight: 2, flexDirection: "column", children: [_jsx("text", { fg: t.primary, children: _jsx("b", { children: `Set API key — ${apiKeyPrompt.provider}` }) }), _jsx("box", { paddingTop: 1, children: _jsx("text", { fg: t.textMuted, children: "Key is
|
|
36
|
-
// Sub-modal:
|
|
37
|
-
const
|
|
38
|
-
const focused = i === bwSync.focusIndex;
|
|
39
|
-
const checked = bwSync.selected.has(item.provider);
|
|
40
|
-
return (_jsx("box", { paddingLeft: 1, paddingRight: 1, backgroundColor: focused ? t.selectedBg : undefined, children: _jsx("text", { fg: focused ? t.accent : t.text, children: `${focused ? "›" : " "} [${checked ? "x" : " "}] ${item.provider}` }) }, item.provider));
|
|
41
|
-
}) }), bwSync.error ? (_jsx("box", { paddingTop: 1, children: _jsx("text", { fg: t.initFormError, children: bwSync.error }) })) : null, _jsx("box", { paddingTop: 1, children: _jsx("text", { fg: t.textMuted, children: bwSync.loading ? "importing..." : "↑↓ nav Space toggle Enter import Esc cancel" }) })] })) }) }) })) : null;
|
|
36
|
+
const subModal = apiKeyPrompt ? (_jsx(Semantic, { id: "provider-key-prompt", role: "dialog", isModal: true, name: `Set ${apiKeyPrompt.provider} key`, children: _jsx("box", { position: "absolute", left: 0, top: 0, width: width, height: height, alignItems: "center", paddingTop: Math.floor(height / 3), backgroundColor: "#000000dd", children: _jsxs("box", { width: Math.min(60, width - 8), backgroundColor: t.backgroundPanel, paddingTop: 1, paddingBottom: 1, paddingLeft: 2, paddingRight: 2, flexDirection: "column", children: [_jsx("text", { fg: t.primary, children: _jsx("b", { children: `Set API key — ${apiKeyPrompt.provider}` }) }), _jsx("box", { paddingTop: 1, children: _jsx("text", { fg: t.textMuted, children: "Key is stored as an environment variable (~/.muonroi-cli/.env, mirrored to your OS env)." }) }), _jsx(Semantic, { id: "provider-key-input", role: "textbox", name: `${apiKeyPrompt.provider} API key`, focus: true, value: apiKeyPrompt.value, children: _jsxs("box", { paddingTop: 1, backgroundColor: t.backgroundElement, paddingLeft: 1, paddingRight: 1, flexDirection: "row", justifyContent: "space-between", children: [apiKeyPrompt.value.length > 0 ? (_jsx("text", { fg: t.text, children: `${apiKeyPrompt.reveal ? apiKeyPrompt.value.slice(0, 40) : "•".repeat(Math.min(apiKeyPrompt.value.length, 40))}▏` })) : (_jsx("text", { fg: t.textDim, children: "▏(type or paste key)" })), apiKeyPrompt.value.length > 0 ? (_jsx("text", { fg: t.textMuted, children: `${apiKeyPrompt.reveal ? "shown" : "hidden"} · ${apiKeyPrompt.value.length} chars` })) : null] }) }), apiKeyPrompt.error ? (_jsx("box", { paddingTop: 1, children: _jsx("text", { fg: t.initFormError, children: apiKeyPrompt.error }) })) : null, _jsx("box", { paddingTop: 1, children: _jsx("text", { fg: t.textMuted, children: "Enter save · Esc cancel · Ctrl+R reveal · paste works" }) })] }) }) })) : null;
|
|
37
|
+
// Sub-modal: OAuth subscription login (browser-based) for openai / xai.
|
|
38
|
+
const oauthModal = oauthLogin ? (_jsx(Semantic, { id: "provider-oauth-login", role: "dialog", isModal: true, name: `Sign in to ${oauthLogin.provider}`, children: _jsx("box", { position: "absolute", left: 0, top: 0, width: width, height: height, alignItems: "center", paddingTop: Math.floor(height / 3), backgroundColor: "#000000dd", children: _jsxs("box", { width: Math.min(60, width - 8), backgroundColor: t.backgroundPanel, paddingTop: 1, paddingBottom: 1, paddingLeft: 2, paddingRight: 2, flexDirection: "column", children: [_jsx("text", { fg: t.primary, children: _jsx("b", { children: `Sign in to ${oauthLogin.provider} (OAuth)` }) }), _jsx("box", { paddingTop: 1, children: _jsx("text", { fg: t.textMuted, children: "A browser window is opening. Complete the sign-in there; this returns automatically." }) }), oauthLogin.error ? (_jsx("box", { paddingTop: 1, children: _jsx("text", { fg: t.initFormError, children: oauthLogin.error }) })) : (_jsx("box", { paddingTop: 1, children: _jsx("text", { fg: t.textMuted, children: "Waiting for authorization… Esc cancel" }) }))] }) }) })) : null;
|
|
42
39
|
return (_jsxs(_Fragment, { children: [_jsx(Semantic, { id: "model-picker", role: "dialog", isModal: true, name: "Providers", 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: "Providers" }) }), _jsx("text", { fg: t.textMuted, children: "esc" })] }), _jsx("box", { flexShrink: 0, paddingLeft: 2, paddingRight: 2, paddingTop: 1, flexDirection: "column", children: configuredProviders.length === 0 ? (_jsx("text", { fg: t.textMuted, children: "No providers configured" })) : (configuredProviders.map((p, i) => {
|
|
43
40
|
const hasKey = keyedSet.has(p);
|
|
44
41
|
const enabled = hasKey && !disabledSet.has(p);
|
|
@@ -48,8 +45,9 @@ export function ModelPickerModal({ t, width, height, configuredProviders, disabl
|
|
|
48
45
|
const star = isDefault ? "★" : " ";
|
|
49
46
|
const fg = focused ? t.accent : enabled ? t.text : t.textMuted;
|
|
50
47
|
const starFg = isDefault ? t.primary : t.textDim;
|
|
51
|
-
const
|
|
48
|
+
const canOAuth = oauthSet.has(p);
|
|
49
|
+
const suffix = !hasKey ? (canOAuth ? " (Enter sign in · K key)" : " (no key — press K)") : "";
|
|
52
50
|
return (_jsx(Semantic, { id: `provider-chip-${p}`, role: "button", selected: enabled ? true : undefined, disabled: !hasKey ? true : undefined, name: p, children: _jsxs("box", { paddingLeft: 1, paddingRight: 1, backgroundColor: focused ? t.selectedBg : undefined, width: "100%", flexDirection: "row", children: [_jsx("text", { fg: fg, children: `${focused ? "›" : " "} ${mark} ` }), _jsx("text", { fg: starFg, children: `${star} ` }), _jsx("text", { fg: fg, children: p }), suffix ? _jsx("text", { fg: t.textMuted, children: suffix }) : null] }) }, p));
|
|
53
|
-
})) }), _jsx("box", { flexGrow: 1, minHeight: 0 }), _jsx("box", { flexShrink: 0, paddingLeft: 2, paddingRight: 2, paddingTop: 1, children: _jsx("text", { fg: t.textMuted, children: "↑↓ nav Space toggle D default K set key
|
|
51
|
+
})) }), _jsx("box", { flexGrow: 1, minHeight: 0 }), _jsx("box", { flexShrink: 0, paddingLeft: 2, paddingRight: 2, paddingTop: 1, children: _jsx("text", { fg: t.textMuted, children: "↑↓ nav Space toggle D default O sign in K set key Esc close" }) })] }) }) }), subModal, oauthModal] }));
|
|
54
52
|
}
|
|
55
53
|
//# sourceMappingURL=model-picker-modal.js.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ResumeEntry } from "../../types/index.js";
|
|
2
2
|
import type { Theme } from "../theme.js";
|
|
3
3
|
/**
|
|
4
4
|
* Recent-sessions picker. Opened by `/sessions` or `/session`. Selecting a
|
|
@@ -7,7 +7,7 @@ import type { Theme } from "../theme.js";
|
|
|
7
7
|
*/
|
|
8
8
|
export declare function SessionPickerModal({ t, sessions, focusIndex, width, height, }: {
|
|
9
9
|
t: Theme;
|
|
10
|
-
sessions:
|
|
10
|
+
sessions: ResumeEntry[];
|
|
11
11
|
focusIndex: number;
|
|
12
12
|
width: number;
|
|
13
13
|
height: number;
|