@wrongstack/cli 0.295.0 → 0.296.2
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/data/providers.json +0 -24
- package/dist/acp-A5OSIU2P.js +824 -0
- package/dist/acp-A5OSIU2P.js.map +7 -0
- package/dist/acp-server-agent.d.ts.map +1 -1
- package/dist/arg-parser.d.ts.map +1 -1
- package/dist/audit-2ZSFGNIF.js +102 -0
- package/dist/audit-2ZSFGNIF.js.map +7 -0
- package/dist/auth-CJWQJVRH.js +504 -0
- package/dist/auth-CJWQJVRH.js.map +7 -0
- package/dist/auth-menu/auth-menu-audit.d.ts +1 -5
- package/dist/auth-menu/auth-menu-audit.d.ts.map +1 -1
- package/dist/auth-menu/local.d.ts +1 -1
- package/dist/auth-menu/local.d.ts.map +1 -1
- package/dist/auth-menu/shared.d.ts +1 -1
- package/dist/auth-menu/shared.d.ts.map +1 -1
- package/dist/bench-7ZDWSNEF.js +278 -0
- package/dist/bench-7ZDWSNEF.js.map +7 -0
- package/dist/boot/brain-decision-log.d.ts +7 -5
- package/dist/boot/brain-decision-log.d.ts.map +1 -1
- package/dist/boot/dispatch-webui.d.ts +4 -8
- package/dist/boot/dispatch-webui.d.ts.map +1 -1
- package/dist/boot/launch-menu.d.ts +1 -1
- package/dist/boot/launch-menu.d.ts.map +1 -1
- package/dist/boot/system-prompt-builder.d.ts +4 -1
- package/dist/boot/system-prompt-builder.d.ts.map +1 -1
- package/dist/boot/tui-coordinator-callbacks.d.ts +45 -0
- package/dist/boot/tui-coordinator-callbacks.d.ts.map +1 -0
- package/dist/boot/tui-coordinator-setup.d.ts +2 -2
- package/dist/boot/tui-coordinator-setup.d.ts.map +1 -1
- package/dist/boot/tui-project-picker-callback.d.ts +1 -1
- package/dist/boot/tui-project-picker-callback.d.ts.map +1 -1
- package/dist/boot/tui-project-switch.d.ts +3 -4
- package/dist/boot/tui-project-switch.d.ts.map +1 -1
- package/dist/boot/tui-runtime-state.d.ts +5 -6
- package/dist/boot/tui-runtime-state.d.ts.map +1 -1
- package/dist/boot/tui-session-resume.d.ts.map +1 -1
- package/dist/boot/tui-settings-adapter.d.ts +2 -3
- package/dist/boot/tui-settings-adapter.d.ts.map +1 -1
- package/dist/boot-config.d.ts +2 -2
- package/dist/boot-config.d.ts.map +1 -1
- package/dist/boot.d.ts +1 -1
- package/dist/boot.d.ts.map +1 -1
- package/dist/brain-menu/panel-service.d.ts.map +1 -1
- package/dist/chimera-review-task.d.ts +6 -0
- package/dist/chimera-review-task.d.ts.map +1 -0
- package/dist/chimera-reviewer-policy.d.ts +34 -0
- package/dist/chimera-reviewer-policy.d.ts.map +1 -0
- package/dist/chronicle-QQEQFSSE.js +256 -0
- package/dist/chronicle-QQEQFSSE.js.map +7 -0
- package/dist/chunk-5N34EWJR.js +418 -0
- package/dist/chunk-5N34EWJR.js.map +7 -0
- package/dist/chunk-66T43Q4Y.js +90 -0
- package/dist/chunk-66T43Q4Y.js.map +7 -0
- package/dist/chunk-7OCVIDC7.js +11 -0
- package/dist/chunk-7OCVIDC7.js.map +7 -0
- package/dist/chunk-ABXK4VVY.js +84 -0
- package/dist/chunk-ABXK4VVY.js.map +7 -0
- package/dist/chunk-AXVZMEWG.js +306 -0
- package/dist/chunk-AXVZMEWG.js.map +7 -0
- package/dist/chunk-AZESNNIC.js +216 -0
- package/dist/chunk-AZESNNIC.js.map +7 -0
- package/dist/chunk-BGFM3PD7.js +41 -0
- package/dist/chunk-BGFM3PD7.js.map +7 -0
- package/dist/chunk-DPJZQCVP.js +13 -0
- package/dist/chunk-DPJZQCVP.js.map +7 -0
- package/dist/chunk-F4PEGAJZ.js +176 -0
- package/dist/chunk-F4PEGAJZ.js.map +7 -0
- package/dist/chunk-IHBYBYGA.js +443 -0
- package/dist/chunk-IHBYBYGA.js.map +7 -0
- package/dist/chunk-IN4GXGYW.js +425 -0
- package/dist/chunk-IN4GXGYW.js.map +7 -0
- package/dist/chunk-JBSQ7ONN.js +1023 -0
- package/dist/chunk-JBSQ7ONN.js.map +7 -0
- package/dist/chunk-JBTFWWKV.js +1325 -0
- package/dist/chunk-JBTFWWKV.js.map +7 -0
- package/dist/chunk-JUHRI6OV.js +100 -0
- package/dist/chunk-JUHRI6OV.js.map +7 -0
- package/dist/chunk-OP47B3IX.js +142 -0
- package/dist/chunk-OP47B3IX.js.map +7 -0
- package/dist/chunk-PJHET45A.js +158 -0
- package/dist/chunk-PJHET45A.js.map +7 -0
- package/dist/chunk-Q5GTM25S.js +17 -0
- package/dist/chunk-Q5GTM25S.js.map +7 -0
- package/dist/chunk-QD544J2B.js +19 -0
- package/dist/chunk-QD544J2B.js.map +7 -0
- package/dist/chunk-QUNHS6O3.js +258 -0
- package/dist/chunk-QUNHS6O3.js.map +7 -0
- package/dist/chunk-TADVX644.js +480 -0
- package/dist/chunk-TADVX644.js.map +7 -0
- package/dist/chunk-TGDHN4LM.js +81 -0
- package/dist/chunk-TGDHN4LM.js.map +7 -0
- package/dist/chunk-TYO2OVAD.js +50 -0
- package/dist/chunk-TYO2OVAD.js.map +7 -0
- package/dist/chunk-VCYZ3WZV.js +14 -0
- package/dist/chunk-VCYZ3WZV.js.map +7 -0
- package/dist/chunk-VJUEZZYB.js +29 -0
- package/dist/chunk-VJUEZZYB.js.map +7 -0
- package/dist/chunk-WHOIR577.js +1 -0
- package/dist/chunk-WHOIR577.js.map +7 -0
- package/dist/chunk-WY7KKOUK.js +460 -0
- package/dist/chunk-WY7KKOUK.js.map +7 -0
- package/dist/chunk-X5DQTPXT.js +3059 -0
- package/dist/chunk-X5DQTPXT.js.map +7 -0
- package/dist/chunk-XJXDOF63.js +28 -0
- package/dist/chunk-XJXDOF63.js.map +7 -0
- package/dist/chunk-XWEGWYDU.js +560 -0
- package/dist/chunk-XWEGWYDU.js.map +7 -0
- package/dist/chunk-YWUPHRGB.js +346 -0
- package/dist/chunk-YWUPHRGB.js.map +7 -0
- package/dist/chunk-Z7YGASQP.js +313 -0
- package/dist/chunk-Z7YGASQP.js.map +7 -0
- package/dist/cli-entry-main.d.ts +2 -0
- package/dist/cli-entry-main.d.ts.map +1 -0
- package/dist/cli-entry-point.d.ts +3 -3
- package/dist/cli-entry-point.d.ts.map +1 -1
- package/dist/cli-eternal-flag.d.ts +2 -2
- package/dist/cli-eternal-flag.d.ts.map +1 -1
- package/dist/cli-main-6AU6E4XZ.js +29126 -0
- package/dist/cli-main-6AU6E4XZ.js.map +7 -0
- package/dist/cli-main-helpers.d.ts +21 -0
- package/dist/cli-main-helpers.d.ts.map +1 -0
- package/dist/cli-main.d.ts +25 -1
- package/dist/cli-main.d.ts.map +1 -1
- package/dist/context-limit.d.ts +48 -0
- package/dist/context-limit.d.ts.map +1 -1
- package/dist/diag-doctor-OQ3AA63O.js +170 -0
- package/dist/diag-doctor-OQ3AA63O.js.map +7 -0
- package/dist/execute-deps.d.ts +10 -12
- package/dist/execute-deps.d.ts.map +1 -1
- package/dist/execution-V26SE52F.js +4656 -0
- package/dist/execution-V26SE52F.js.map +7 -0
- package/dist/execution-chimera-ask.d.ts +10 -0
- package/dist/execution-chimera-ask.d.ts.map +1 -0
- package/dist/execution-chimera-cascade.d.ts +15 -0
- package/dist/execution-chimera-cascade.d.ts.map +1 -0
- package/dist/execution-cleanup.d.ts +23 -0
- package/dist/execution-cleanup.d.ts.map +1 -0
- package/dist/execution-kanban-dispatch.d.ts +10 -0
- package/dist/execution-kanban-dispatch.d.ts.map +1 -0
- package/dist/execution-repl-fleet-callbacks.d.ts +11 -0
- package/dist/execution-repl-fleet-callbacks.d.ts.map +1 -0
- package/dist/execution-storage-observability.d.ts +3 -0
- package/dist/execution-storage-observability.d.ts.map +1 -0
- package/dist/execution-tui-next-step-callbacks.d.ts +20 -0
- package/dist/execution-tui-next-step-callbacks.d.ts.map +1 -0
- package/dist/execution.d.ts +2 -139
- package/dist/execution.d.ts.map +1 -1
- package/dist/export-TPORYVRZ.js +64 -0
- package/dist/export-TPORYVRZ.js.map +7 -0
- package/dist/fleet/host-acp-runner-cache.d.ts +9 -0
- package/dist/fleet/host-acp-runner-cache.d.ts.map +1 -0
- package/dist/fleet/host-acp.d.ts +3 -0
- package/dist/fleet/host-acp.d.ts.map +1 -0
- package/dist/fleet/host-concurrency.d.ts +2 -0
- package/dist/fleet/host-concurrency.d.ts.map +1 -0
- package/dist/fleet/host-context.d.ts +5 -0
- package/dist/fleet/host-context.d.ts.map +1 -0
- package/dist/fleet/host-director-builder.d.ts +24 -0
- package/dist/fleet/host-director-builder.d.ts.map +1 -0
- package/dist/fleet/host-director-event-bridges.d.ts +37 -0
- package/dist/fleet/host-director-event-bridges.d.ts.map +1 -0
- package/dist/fleet/host-director-services.d.ts +20 -0
- package/dist/fleet/host-director-services.d.ts.map +1 -0
- package/dist/fleet/host-event-bridge.d.ts +17 -0
- package/dist/fleet/host-event-bridge.d.ts.map +1 -0
- package/dist/fleet/host-helpers.d.ts +22 -0
- package/dist/fleet/host-helpers.d.ts.map +1 -0
- package/dist/fleet/host-learning-tracker.d.ts +11 -0
- package/dist/fleet/host-learning-tracker.d.ts.map +1 -0
- package/dist/fleet/host-learning.d.ts +4 -0
- package/dist/fleet/host-learning.d.ts.map +1 -0
- package/dist/fleet/host-lifecycle-events.d.ts +4 -0
- package/dist/fleet/host-lifecycle-events.d.ts.map +1 -0
- package/dist/fleet/host-paths.d.ts +3 -0
- package/dist/fleet/host-paths.d.ts.map +1 -0
- package/dist/fleet/host-provider.d.ts +22 -0
- package/dist/fleet/host-provider.d.ts.map +1 -0
- package/dist/fleet/host-session-writer.d.ts +3 -0
- package/dist/fleet/host-session-writer.d.ts.map +1 -0
- package/dist/fleet/host-shadow-pass.d.ts +21 -0
- package/dist/fleet/host-shadow-pass.d.ts.map +1 -0
- package/dist/fleet/host-spawn-types.d.ts +25 -0
- package/dist/fleet/host-spawn-types.d.ts.map +1 -0
- package/dist/fleet/host-status.d.ts +48 -0
- package/dist/fleet/host-status.d.ts.map +1 -0
- package/dist/fleet/host-subagent-factory.d.ts +16 -0
- package/dist/fleet/host-subagent-factory.d.ts.map +1 -0
- package/dist/fleet/host-supervisor.d.ts +16 -0
- package/dist/fleet/host-supervisor.d.ts.map +1 -0
- package/dist/fleet/host-task-result-report.d.ts +11 -0
- package/dist/fleet/host-task-result-report.d.ts.map +1 -0
- package/dist/fleet/host-types.d.ts +89 -0
- package/dist/fleet/host-types.d.ts.map +1 -0
- package/dist/fleet/host.d.ts +10 -357
- package/dist/fleet/host.d.ts.map +1 -1
- package/dist/fleet/routing.d.ts +1 -1
- package/dist/fleet/routing.d.ts.map +1 -1
- package/dist/fleet/status-broadcast.d.ts.map +1 -1
- package/dist/goal-host.d.ts +2 -2
- package/dist/goal-host.d.ts.map +1 -1
- package/dist/hq-BECGICEZ.js +547 -0
- package/dist/hq-BECGICEZ.js.map +7 -0
- package/dist/hq-command-controller.d.ts +2 -2
- package/dist/hq-command-controller.d.ts.map +1 -1
- package/dist/hq-publisher.d.ts +2 -2
- package/dist/hq-publisher.d.ts.map +1 -1
- package/dist/hq-server/auth-state.d.ts +1 -1
- package/dist/hq-server/auth-state.d.ts.map +1 -1
- package/dist/hq-server/project-root.d.ts +5 -0
- package/dist/hq-server/project-root.d.ts.map +1 -0
- package/dist/hq-server/routes/auth-handlers.d.ts +32 -0
- package/dist/hq-server/routes/auth-handlers.d.ts.map +1 -0
- package/dist/hq-server/routes/session-handlers.d.ts +8 -0
- package/dist/hq-server/routes/session-handlers.d.ts.map +1 -0
- package/dist/hq-server/routes/system-handlers.d.ts +16 -0
- package/dist/hq-server/routes/system-handlers.d.ts.map +1 -0
- package/dist/hq-server/routes.d.ts +6 -6
- package/dist/hq-server/routes.d.ts.map +1 -1
- package/dist/hq-server/ws.d.ts +1 -1
- package/dist/hq-server/ws.d.ts.map +1 -1
- package/dist/hq-server-FJOVOERO.js +39 -0
- package/dist/hq-server-FJOVOERO.js.map +7 -0
- package/dist/hq-server.d.ts.map +1 -1
- package/dist/hq-ttl-U2FAYFAT.js +8 -0
- package/dist/hq-ttl-U2FAYFAT.js.map +7 -0
- package/dist/hq-tunnel-YZLRONPV.js +111 -0
- package/dist/hq-tunnel-YZLRONPV.js.map +7 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2507 -52632
- package/dist/index.js.map +4 -4
- package/dist/init-E2NDDOHI.js +27 -0
- package/dist/init-E2NDDOHI.js.map +7 -0
- package/dist/input-reader.d.ts +1 -1
- package/dist/input-reader.d.ts.map +1 -1
- package/dist/kanban-dispatch-route.d.ts +14 -0
- package/dist/kanban-dispatch-route.d.ts.map +1 -0
- package/dist/kanban-hq-sync.d.ts +2 -0
- package/dist/kanban-hq-sync.d.ts.map +1 -1
- package/dist/kanban-run-mirror-EKVNGXWW.js +12 -0
- package/dist/kanban-run-mirror-EKVNGXWW.js.map +7 -0
- package/dist/live-settings-input.d.ts +69 -0
- package/dist/live-settings-input.d.ts.map +1 -0
- package/dist/mailbox-serve-2UWHEN3M.js +302 -0
- package/dist/mailbox-serve-2UWHEN3M.js.map +7 -0
- package/dist/mcp-CYLPUEHC.js +413 -0
- package/dist/mcp-CYLPUEHC.js.map +7 -0
- package/dist/mcp-serve.d.ts +1 -1
- package/dist/mcp-serve.d.ts.map +1 -1
- package/dist/modeldiag-HENYJ4N7.js +1290 -0
- package/dist/modeldiag-HENYJ4N7.js.map +7 -0
- package/dist/next-task-predictor.d.ts +1 -1
- package/dist/next-task-predictor.d.ts.map +1 -1
- package/dist/permissions-FNYLZIL4.js +115 -0
- package/dist/permissions-FNYLZIL4.js.map +7 -0
- package/dist/picker-key-state.d.ts +7 -0
- package/dist/picker-key-state.d.ts.map +1 -0
- package/dist/picker-model-picker.d.ts +6 -0
- package/dist/picker-model-picker.d.ts.map +1 -0
- package/dist/picker-ui.d.ts +17 -0
- package/dist/picker-ui.d.ts.map +1 -0
- package/dist/picker.d.ts +4 -37
- package/dist/picker.d.ts.map +1 -1
- package/dist/plugin-management.d.ts +1 -1
- package/dist/plugin-management.d.ts.map +1 -1
- package/dist/plugin-usage-OU6X6LM3.js +40 -0
- package/dist/plugin-usage-OU6X6LM3.js.map +7 -0
- package/dist/plugins-4LJ5IUBI.js +24 -0
- package/dist/plugins-4LJ5IUBI.js.map +7 -0
- package/dist/pre-launch.d.ts +0 -1
- package/dist/pre-launch.d.ts.map +1 -1
- package/dist/project-BLQ3ALVL.js +76 -0
- package/dist/project-BLQ3ALVL.js.map +7 -0
- package/dist/project-manifest-GE25PW4S.js +18 -0
- package/dist/project-manifest-GE25PW4S.js.map +7 -0
- package/dist/project-picker-BOCWHBXP.js +17 -0
- package/dist/project-picker-BOCWHBXP.js.map +7 -0
- package/dist/projects-XE76NFNZ.js +38 -0
- package/dist/projects-XE76NFNZ.js.map +7 -0
- package/dist/provider-helpers.d.ts +22 -6
- package/dist/provider-helpers.d.ts.map +1 -1
- package/dist/providers-models-GDELBHZK.js +589 -0
- package/dist/providers-models-GDELBHZK.js.map +7 -0
- package/dist/quick-VIO2BEHS.js +10 -0
- package/dist/quick-VIO2BEHS.js.map +7 -0
- package/dist/repl-auto-proceed.d.ts +19 -0
- package/dist/repl-auto-proceed.d.ts.map +1 -0
- package/dist/repl-client-registration.d.ts +7 -0
- package/dist/repl-client-registration.d.ts.map +1 -0
- package/dist/repl-input.d.ts +11 -0
- package/dist/repl-input.d.ts.map +1 -0
- package/dist/repl-options.d.ts +54 -0
- package/dist/repl-options.d.ts.map +1 -0
- package/dist/repl-rendering.d.ts +4 -0
- package/dist/repl-rendering.d.ts.map +1 -0
- package/dist/repl-suggestions.d.ts +21 -0
- package/dist/repl-suggestions.d.ts.map +1 -0
- package/dist/repl.d.ts +3 -162
- package/dist/repl.d.ts.map +1 -1
- package/dist/replay-KCTXNMZQ.js +75 -0
- package/dist/replay-KCTXNMZQ.js.map +7 -0
- package/dist/rewind-EJMVFVLS.js +185 -0
- package/dist/rewind-EJMVFVLS.js.map +7 -0
- package/dist/sdd-runtime-IKPROVV2.js +54 -0
- package/dist/sdd-runtime-IKPROVV2.js.map +7 -0
- package/dist/services/dispatch-classifier.d.ts +1 -1
- package/dist/services/dispatch-classifier.d.ts.map +1 -1
- package/dist/services/project-facts.d.ts.map +1 -1
- package/dist/services/sdd/project-context.d.ts +1 -1
- package/dist/services/sdd/project-context.d.ts.map +1 -1
- package/dist/services/sdd/task-manager.d.ts +1 -1
- package/dist/services/sdd/task-manager.d.ts.map +1 -1
- package/dist/services/statusline-config.d.ts +1 -1
- package/dist/services/statusline-config.d.ts.map +1 -1
- package/dist/session-event-wiring.d.ts +5 -2
- package/dist/session-event-wiring.d.ts.map +1 -1
- package/dist/sessions-config-NLCMK3BY.js +409 -0
- package/dist/sessions-config-NLCMK3BY.js.map +7 -0
- package/dist/settings-menu.d.ts +4 -19
- package/dist/settings-menu.d.ts.map +1 -1
- package/dist/simpleui-dist-JIFGUJO7.js +93 -0
- package/dist/simpleui-dist-JIFGUJO7.js.map +7 -0
- package/dist/slash-commands/agent-improve.d.ts +6 -5
- package/dist/slash-commands/agent-improve.d.ts.map +1 -1
- package/dist/slash-commands/brain.d.ts.map +1 -1
- package/dist/slash-commands/btw.d.ts +1 -1
- package/dist/slash-commands/btw.d.ts.map +1 -1
- package/dist/slash-commands/clear.d.ts +1 -1
- package/dist/slash-commands/clear.d.ts.map +1 -1
- package/dist/slash-commands/fallback.d.ts.map +1 -1
- package/dist/slash-commands/goal-refiner.d.ts +2 -2
- package/dist/slash-commands/goal-refiner.d.ts.map +1 -1
- package/dist/slash-commands/interrupt.d.ts +1 -1
- package/dist/slash-commands/interrupt.d.ts.map +1 -1
- package/dist/slash-commands/kanban-agent-helpers.d.ts +18 -0
- package/dist/slash-commands/kanban-agent-helpers.d.ts.map +1 -0
- package/dist/slash-commands/kanban-format.d.ts +16 -0
- package/dist/slash-commands/kanban-format.d.ts.map +1 -0
- package/dist/slash-commands/kanban-help.d.ts +2 -0
- package/dist/slash-commands/kanban-help.d.ts.map +1 -0
- package/dist/slash-commands/kanban.d.ts +1 -1
- package/dist/slash-commands/kanban.d.ts.map +1 -1
- package/dist/slash-commands/mailbox-demo.d.ts.map +1 -1
- package/dist/slash-commands/mailbox.d.ts +3 -2
- package/dist/slash-commands/mailbox.d.ts.map +1 -1
- package/dist/slash-commands/memory-compact.d.ts +5 -0
- package/dist/slash-commands/memory-compact.d.ts.map +1 -0
- package/dist/slash-commands/memory-flags.d.ts +36 -0
- package/dist/slash-commands/memory-flags.d.ts.map +1 -0
- package/dist/slash-commands/memory-formatters.d.ts +16 -0
- package/dist/slash-commands/memory-formatters.d.ts.map +1 -0
- package/dist/slash-commands/memory.d.ts.map +1 -1
- package/dist/slash-commands/mouse.d.ts +2 -2
- package/dist/slash-commands/refiner.d.ts +1 -1
- package/dist/slash-commands/refiner.d.ts.map +1 -1
- package/dist/slash-commands/review.d.ts.map +1 -1
- package/dist/slash-commands/sdd-command-helpers.d.ts +23 -0
- package/dist/slash-commands/sdd-command-helpers.d.ts.map +1 -0
- package/dist/slash-commands/sdd-format.d.ts +32 -0
- package/dist/slash-commands/sdd-format.d.ts.map +1 -0
- package/dist/slash-commands/sdd.d.ts +1 -1
- package/dist/slash-commands/sdd.d.ts.map +1 -1
- package/dist/slash-commands/tool.d.ts +1 -1
- package/dist/slash-commands/tool.d.ts.map +1 -1
- package/dist/slash-commands/working-dir.d.ts +1 -1
- package/dist/slash-commands/working-dir.d.ts.map +1 -1
- package/dist/subcommands/handlers/chronicle.d.ts.map +1 -1
- package/dist/subcommands/handlers/mailbox-serve.d.ts.map +1 -1
- package/dist/subcommands/handlers/model-smoke-test.d.ts +51 -0
- package/dist/subcommands/handlers/model-smoke-test.d.ts.map +1 -0
- package/dist/subcommands/handlers/modeldiag-profiles.d.ts +64 -0
- package/dist/subcommands/handlers/modeldiag-profiles.d.ts.map +1 -0
- package/dist/subcommands/handlers/modeldiag.d.ts.map +1 -1
- package/dist/subcommands/handlers/per-subcommand-deep-help-table.d.ts +3 -0
- package/dist/subcommands/handlers/per-subcommand-deep-help-table.d.ts.map +1 -0
- package/dist/subcommands/handlers/per-subcommand-help-data.d.ts +3 -0
- package/dist/subcommands/handlers/per-subcommand-help-data.d.ts.map +1 -0
- package/dist/subcommands/handlers/per-subcommand-help-table.d.ts +36 -0
- package/dist/subcommands/handlers/per-subcommand-help-table.d.ts.map +1 -0
- package/dist/subcommands/handlers/per-subcommand-help-types.d.ts +18 -0
- package/dist/subcommands/handlers/per-subcommand-help-types.d.ts.map +1 -0
- package/dist/subcommands/handlers/per-subcommand-help.d.ts +2 -80
- package/dist/subcommands/handlers/per-subcommand-help.d.ts.map +1 -1
- package/dist/subcommands/handlers/rewind.d.ts.map +1 -1
- package/dist/subcommands/index.d.ts +7 -0
- package/dist/subcommands/index.d.ts.map +1 -1
- package/dist/tools-skills-UNKLOB7M.js +29 -0
- package/dist/tools-skills-UNKLOB7M.js.map +7 -0
- package/dist/update-YC4TYW2Y.js +16 -0
- package/dist/update-YC4TYW2Y.js.map +7 -0
- package/dist/update-check-UMYTOH7Z.js +18 -0
- package/dist/update-check-UMYTOH7Z.js.map +7 -0
- package/dist/version-help-DROHZRW6.js +11 -0
- package/dist/version-help-DROHZRW6.js.map +7 -0
- package/dist/webui-server/connection-handler.d.ts +2 -1
- package/dist/webui-server/connection-handler.d.ts.map +1 -1
- package/dist/webui-server/kanban-host-adapter.d.ts +9 -5
- package/dist/webui-server/kanban-host-adapter.d.ts.map +1 -1
- package/dist/webui-server/listen-helpers.d.ts +18 -0
- package/dist/webui-server/listen-helpers.d.ts.map +1 -0
- package/dist/webui-server/node-pty-loader.d.ts +6 -0
- package/dist/webui-server/node-pty-loader.d.ts.map +1 -0
- package/dist/webui-server/prefs-seeding.d.ts.map +1 -1
- package/dist/webui-server/terminal-log-view.d.ts +30 -0
- package/dist/webui-server/terminal-log-view.d.ts.map +1 -0
- package/dist/webui-server-G3TISUIY.js +1459 -0
- package/dist/webui-server-G3TISUIY.js.map +7 -0
- package/dist/webui-server-options.d.ts +189 -0
- package/dist/webui-server-options.d.ts.map +1 -0
- package/dist/webui-server.d.ts +2 -178
- package/dist/webui-server.d.ts.map +1 -1
- package/dist/wiring/brain-and-orchestration.d.ts +2 -2
- package/dist/wiring/brain-and-orchestration.d.ts.map +1 -1
- package/dist/wiring/codebase-index.d.ts.map +1 -1
- package/dist/wiring/command-host-adapters.d.ts +2 -2
- package/dist/wiring/command-host-adapters.d.ts.map +1 -1
- package/dist/wiring/command-host-state.d.ts +7 -7
- package/dist/wiring/command-host-state.d.ts.map +1 -1
- package/dist/wiring/dep-watcher-bridge.d.ts +23 -0
- package/dist/wiring/dep-watcher-bridge.d.ts.map +1 -0
- package/dist/wiring/dep-watcher.d.ts +1 -1
- package/dist/wiring/dep-watcher.d.ts.map +1 -1
- package/dist/wiring/director-setup.d.ts +4 -4
- package/dist/wiring/director-setup.d.ts.map +1 -1
- package/dist/wiring/eternal-command-handlers.d.ts +5 -5
- package/dist/wiring/eternal-command-handlers.d.ts.map +1 -1
- package/dist/wiring/fleet-command-handlers.d.ts +2 -2
- package/dist/wiring/fleet-command-handlers.d.ts.map +1 -1
- package/dist/wiring/hq-telemetry.d.ts +5 -5
- package/dist/wiring/hq-telemetry.d.ts.map +1 -1
- package/dist/wiring/lifecycle-plugins.d.ts +9 -8
- package/dist/wiring/lifecycle-plugins.d.ts.map +1 -1
- package/dist/wiring/mailbox-bridge-bootstrap.d.ts +1 -1
- package/dist/wiring/management-tools.d.ts +15 -0
- package/dist/wiring/management-tools.d.ts.map +1 -0
- package/dist/wiring/pipeline.d.ts +4 -3
- package/dist/wiring/pipeline.d.ts.map +1 -1
- package/dist/wiring/plugins.d.ts +1 -1
- package/dist/wiring/plugins.d.ts.map +1 -1
- package/dist/wiring/provider-runtime-setup.d.ts +18 -5
- package/dist/wiring/provider-runtime-setup.d.ts.map +1 -1
- package/dist/wiring/provider-status.d.ts +3 -3
- package/dist/wiring/provider-status.d.ts.map +1 -1
- package/dist/wiring/provider-utility-tools.d.ts +4 -4
- package/dist/wiring/provider-utility-tools.d.ts.map +1 -1
- package/dist/wiring/provider.d.ts.map +1 -1
- package/dist/wiring/replay.d.ts +2 -2
- package/dist/wiring/replay.d.ts.map +1 -1
- package/dist/wiring/runtime-controller-deps.d.ts +4 -4
- package/dist/wiring/runtime-controller-deps.d.ts.map +1 -1
- package/dist/wiring/runtime-dispatch-state.d.ts +5 -5
- package/dist/wiring/runtime-dispatch-state.d.ts.map +1 -1
- package/dist/wiring/runtime-picker-deps.d.ts +3 -3
- package/dist/wiring/runtime-picker-deps.d.ts.map +1 -1
- package/dist/wiring/sage.d.ts.map +1 -1
- package/dist/wiring/sdd-handlers.d.ts.map +1 -1
- package/dist/wiring/session-command-handlers.d.ts +5 -5
- package/dist/wiring/session-command-handlers.d.ts.map +1 -1
- package/dist/wiring/session-registry.d.ts +38 -0
- package/dist/wiring/session-registry.d.ts.map +1 -0
- package/dist/wiring/session.d.ts +7 -5
- package/dist/wiring/session.d.ts.map +1 -1
- package/dist/wiring/tools.d.ts +2 -2
- package/dist/wiring/tools.d.ts.map +1 -1
- package/package.json +22 -22
- package/dist/cli-recovery-prompt.d.ts +0 -19
- package/dist/cli-recovery-prompt.d.ts.map +0 -1
- package/dist/first-run-auth-gate.d.ts +0 -20
- package/dist/first-run-auth-gate.d.ts.map +0 -1
- package/dist/pre-launch/indexing-question.d.ts +0 -28
- package/dist/pre-launch/indexing-question.d.ts.map +0 -1
|
@@ -0,0 +1,1023 @@
|
|
|
1
|
+
import {
|
|
2
|
+
hasApiKey,
|
|
3
|
+
isKeylessLocalProvider,
|
|
4
|
+
visibleModelIds
|
|
5
|
+
} from "./chunk-66T43Q4Y.js";
|
|
6
|
+
import {
|
|
7
|
+
appendHistory,
|
|
8
|
+
backupCurrent
|
|
9
|
+
} from "./chunk-YWUPHRGB.js";
|
|
10
|
+
|
|
11
|
+
// src/arg-parser.ts
|
|
12
|
+
var BOOLEAN_FLAGS = /* @__PURE__ */ new Set([
|
|
13
|
+
"yolo",
|
|
14
|
+
"no-yolo",
|
|
15
|
+
"yolo-destructive",
|
|
16
|
+
"confirm-destructive",
|
|
17
|
+
"force-all-yolo",
|
|
18
|
+
"verbose",
|
|
19
|
+
"trace",
|
|
20
|
+
"help",
|
|
21
|
+
"version",
|
|
22
|
+
"yes",
|
|
23
|
+
"no-banner",
|
|
24
|
+
"no-features",
|
|
25
|
+
"tui",
|
|
26
|
+
"no-tui",
|
|
27
|
+
// Legacy no-ops: every surface now starts fresh unless an explicit
|
|
28
|
+
// `--resume <id>` is supplied. Keep parsing these as booleans so old
|
|
29
|
+
// launch scripts do not accidentally consume the next positional token.
|
|
30
|
+
"no-recovery",
|
|
31
|
+
"recover",
|
|
32
|
+
"output-json",
|
|
33
|
+
"prompt",
|
|
34
|
+
"metrics",
|
|
35
|
+
"webui",
|
|
36
|
+
"simpleui",
|
|
37
|
+
"full-auto",
|
|
38
|
+
"desktop",
|
|
39
|
+
"open",
|
|
40
|
+
"webui-require-token",
|
|
41
|
+
"require-token",
|
|
42
|
+
"no-check",
|
|
43
|
+
"no-models-refresh",
|
|
44
|
+
// (removed: 'director' and 'no-director' — Director Mode is always on)
|
|
45
|
+
"no-autonomy",
|
|
46
|
+
"no-hints",
|
|
47
|
+
"hints",
|
|
48
|
+
"no-menu",
|
|
49
|
+
"no-hooks",
|
|
50
|
+
"skip",
|
|
51
|
+
"skip-index",
|
|
52
|
+
"mouse",
|
|
53
|
+
"no-interactive",
|
|
54
|
+
"token-saving-mode",
|
|
55
|
+
"system-lite",
|
|
56
|
+
"system-pro",
|
|
57
|
+
"hq",
|
|
58
|
+
"hq-allow-exec",
|
|
59
|
+
"tunnel",
|
|
60
|
+
// Opt-in to a non-loopback HQ bind with no token/password configured.
|
|
61
|
+
"insecure-open",
|
|
62
|
+
"strict-port",
|
|
63
|
+
"client",
|
|
64
|
+
// `wstack update` booleans. Keeping these here prevents parseArgs from
|
|
65
|
+
// consuming a following positional token as an accidental flag value.
|
|
66
|
+
"check-only",
|
|
67
|
+
"allow-scripts",
|
|
68
|
+
"lifecycle-scripts",
|
|
69
|
+
"npm",
|
|
70
|
+
"pnpm",
|
|
71
|
+
"yarn",
|
|
72
|
+
"bun",
|
|
73
|
+
// `wstack acp` booleans. Without these, parseArgs treats the value after
|
|
74
|
+
// `--fs`/`--echo` as the flag's value and eats a following positional
|
|
75
|
+
// (e.g. the agent list in `acp bench --fs gemini-cli,codex-cli`).
|
|
76
|
+
"echo",
|
|
77
|
+
"fs",
|
|
78
|
+
// `wstack modeldiag test` booleans. Keep a following positional token from
|
|
79
|
+
// being consumed as the value of one of these switches.
|
|
80
|
+
"all-models",
|
|
81
|
+
"plan",
|
|
82
|
+
"json"
|
|
83
|
+
]);
|
|
84
|
+
function parseArgs(argv) {
|
|
85
|
+
const flags = {};
|
|
86
|
+
const positional = [];
|
|
87
|
+
for (let i = 0; i < argv.length; i++) {
|
|
88
|
+
const a = argv[i];
|
|
89
|
+
if (!a) continue;
|
|
90
|
+
if (a === "--") {
|
|
91
|
+
positional.push(...argv.slice(i + 1));
|
|
92
|
+
break;
|
|
93
|
+
}
|
|
94
|
+
if (a.startsWith("--")) {
|
|
95
|
+
const eq = a.indexOf("=");
|
|
96
|
+
if (eq !== -1) {
|
|
97
|
+
flags[a.slice(2, eq)] = a.slice(eq + 1);
|
|
98
|
+
continue;
|
|
99
|
+
}
|
|
100
|
+
const name = a.slice(2);
|
|
101
|
+
if (BOOLEAN_FLAGS.has(name)) {
|
|
102
|
+
flags[name] = true;
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
if (i + 1 < argv.length && !(argv[i + 1] ?? "").startsWith("-")) {
|
|
106
|
+
flags[name] = argv[++i] ?? "";
|
|
107
|
+
} else {
|
|
108
|
+
flags[name] = true;
|
|
109
|
+
}
|
|
110
|
+
} else if (a.startsWith("-") && a.length === 2) {
|
|
111
|
+
const short = a.slice(1);
|
|
112
|
+
const expand = { v: "verbose", y: "yes" };
|
|
113
|
+
flags[expand[short] ?? short] = true;
|
|
114
|
+
} else {
|
|
115
|
+
positional.push(a);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
normalizeSurfaceAliases(flags, positional);
|
|
119
|
+
return { flags, positional };
|
|
120
|
+
}
|
|
121
|
+
function normalizeSurfaceAliases(flags, positional) {
|
|
122
|
+
if (flags["simpleui"]) flags["webui"] = true;
|
|
123
|
+
const first = positional[0];
|
|
124
|
+
if (first === "simpleui") {
|
|
125
|
+
flags["simpleui"] = true;
|
|
126
|
+
flags["webui"] = true;
|
|
127
|
+
positional.splice(0, 1);
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
if (first === "webui" || first === "desktop") {
|
|
131
|
+
flags[first] = true;
|
|
132
|
+
positional.splice(0, 1);
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
if (first === "hq" && (positional.length === 1 || positional[1] === "serve")) {
|
|
136
|
+
flags["hq"] = true;
|
|
137
|
+
positional.splice(0, positional[1] === "serve" ? 2 : 1);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
function parseAuthFlags(args) {
|
|
141
|
+
const out = { positional: [] };
|
|
142
|
+
for (let i = 0; i < args.length; i++) {
|
|
143
|
+
const a = args[i];
|
|
144
|
+
if (a === "--label") {
|
|
145
|
+
const v = args[++i];
|
|
146
|
+
if (v) out.label = v;
|
|
147
|
+
} else if (a === "--family") {
|
|
148
|
+
const v = args[++i];
|
|
149
|
+
if (v) out.family = v;
|
|
150
|
+
} else if (a === "--base-url") {
|
|
151
|
+
const v = args[++i];
|
|
152
|
+
if (v) out.baseUrl = v;
|
|
153
|
+
} else if (a === "--env") {
|
|
154
|
+
const v = args[++i];
|
|
155
|
+
if (v)
|
|
156
|
+
out.envVars = v.split(",").map((s) => s.trim()).filter(Boolean);
|
|
157
|
+
} else if (a && !a.startsWith("--")) {
|
|
158
|
+
out.positional.push(a);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
return out;
|
|
162
|
+
}
|
|
163
|
+
function parseSpawnFlags(input) {
|
|
164
|
+
const opts = {};
|
|
165
|
+
let rest = input;
|
|
166
|
+
const consume = (re) => {
|
|
167
|
+
const m = rest.match(re);
|
|
168
|
+
if (m) {
|
|
169
|
+
rest = rest.slice(m[0].length).replace(/^\s+/, "");
|
|
170
|
+
return m;
|
|
171
|
+
}
|
|
172
|
+
return null;
|
|
173
|
+
};
|
|
174
|
+
while (rest.length > 0) {
|
|
175
|
+
let m;
|
|
176
|
+
m = consume(/^--provider=(\S+)\s*/);
|
|
177
|
+
if (m) opts.provider = m[1];
|
|
178
|
+
else {
|
|
179
|
+
m = consume(/^--model=(\S+)\s*/);
|
|
180
|
+
if (m) opts.model = m[1];
|
|
181
|
+
else {
|
|
182
|
+
m = consume(/^--name=("([^"]+)"|(\S+))\s*/);
|
|
183
|
+
if (m) opts.name = m[2] ?? m[3];
|
|
184
|
+
else {
|
|
185
|
+
m = consume(/^--tools=(\S+)\s*/);
|
|
186
|
+
if (m)
|
|
187
|
+
opts.tools = m[1]?.split(",").map((t) => t.trim()).filter(Boolean);
|
|
188
|
+
else {
|
|
189
|
+
m = consume(/^-p\s+(\S+)\s*/);
|
|
190
|
+
if (m) opts.provider = m[1];
|
|
191
|
+
else {
|
|
192
|
+
m = consume(/^-m\s+(\S+)\s*/);
|
|
193
|
+
if (m) opts.model = m[1];
|
|
194
|
+
else {
|
|
195
|
+
m = consume(/^-n\s+("([^"]+)"|(\S+))\s*/);
|
|
196
|
+
if (m) opts.name = m[2] ?? m[3];
|
|
197
|
+
else break;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
return { description: rest.trim(), opts };
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// src/auth-menu/local-presets.ts
|
|
209
|
+
import { projectLocalProviderPresets } from "@wrongstack/providers/definitions";
|
|
210
|
+
var LOCAL_LLM_PRESETS = projectLocalProviderPresets();
|
|
211
|
+
|
|
212
|
+
// src/picker.ts
|
|
213
|
+
import os from "node:os";
|
|
214
|
+
import { color as color3, expectDefined as expectDefined2, setOutputLineGuard as setOutputLineGuard2, setRawMode as setRawMode2, stripAnsi as stripAnsi2, writeOut as writeOut2 } from "@wrongstack/core/utils";
|
|
215
|
+
import { toErrorMessage } from "@wrongstack/core/utils";
|
|
216
|
+
|
|
217
|
+
// src/picker-key-state.ts
|
|
218
|
+
function applyPickerKey(state, chunk, matchCount) {
|
|
219
|
+
if (chunk === "\x1B[A") return { ...state, selected: Math.max(0, state.selected - 1) };
|
|
220
|
+
if (chunk === "\x1B[B")
|
|
221
|
+
return { ...state, selected: Math.min(Math.max(0, matchCount - 1), state.selected + 1) };
|
|
222
|
+
if (chunk === "\x1B") return { ...state, query: "", selected: 0, status: "typing" };
|
|
223
|
+
if (chunk.charCodeAt(0) === 27) return state;
|
|
224
|
+
let query = state.query;
|
|
225
|
+
let selected = state.selected;
|
|
226
|
+
const status = "typing";
|
|
227
|
+
for (const ch of chunk) {
|
|
228
|
+
if (ch === "\r" || ch === "\n") {
|
|
229
|
+
return { ...state, status: matchCount > 0 ? "submitted" : "typing" };
|
|
230
|
+
}
|
|
231
|
+
if (ch === "") return { ...state, status: "cancelled" };
|
|
232
|
+
if (ch === "") {
|
|
233
|
+
query = "";
|
|
234
|
+
selected = 0;
|
|
235
|
+
continue;
|
|
236
|
+
}
|
|
237
|
+
if (ch === "\x7F" || ch === "\b") {
|
|
238
|
+
query = query.slice(0, -1);
|
|
239
|
+
selected = 0;
|
|
240
|
+
continue;
|
|
241
|
+
}
|
|
242
|
+
if (ch >= " " && ch !== "\x7F") {
|
|
243
|
+
query += ch;
|
|
244
|
+
selected = 0;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
return { query, selected, status };
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
// src/picker-model-picker.ts
|
|
251
|
+
import { color as color2, expectDefined, setOutputLineGuard, setRawMode, writeOut } from "@wrongstack/core/utils";
|
|
252
|
+
|
|
253
|
+
// src/picker-ui.ts
|
|
254
|
+
import { color, stripAnsi } from "@wrongstack/core/utils";
|
|
255
|
+
var theme = {
|
|
256
|
+
accent: color.amber,
|
|
257
|
+
chrome: color.gray,
|
|
258
|
+
cursor: (s) => color.amber(color.bold(s)),
|
|
259
|
+
ctx: color.cyan,
|
|
260
|
+
cost: color.green,
|
|
261
|
+
caps: color.magenta
|
|
262
|
+
};
|
|
263
|
+
var BOX = {
|
|
264
|
+
tl: "\u256D",
|
|
265
|
+
tr: "\u256E",
|
|
266
|
+
bl: "\u2570",
|
|
267
|
+
br: "\u256F",
|
|
268
|
+
h: "\u2500",
|
|
269
|
+
v: "\u2502"
|
|
270
|
+
};
|
|
271
|
+
var PICKER_MIN_WIDTH = 74;
|
|
272
|
+
var PICKER_MAX_WIDTH = 100;
|
|
273
|
+
function pickerWidth() {
|
|
274
|
+
const cols = process.stdout.columns;
|
|
275
|
+
if (typeof cols !== "number" || !Number.isFinite(cols) || cols <= 0) {
|
|
276
|
+
return PICKER_MIN_WIDTH;
|
|
277
|
+
}
|
|
278
|
+
return Math.max(PICKER_MIN_WIDTH, Math.min(PICKER_MAX_WIDTH, cols - 2));
|
|
279
|
+
}
|
|
280
|
+
function visibleWidth(s) {
|
|
281
|
+
return stripAnsi(s).length;
|
|
282
|
+
}
|
|
283
|
+
function padVisible(s, width) {
|
|
284
|
+
const w = visibleWidth(s);
|
|
285
|
+
if (w === width) return s;
|
|
286
|
+
if (w < width) return s + " ".repeat(width - w);
|
|
287
|
+
const plain = stripAnsi(s);
|
|
288
|
+
return `${plain.slice(0, Math.max(0, width - 1))}\u2026`;
|
|
289
|
+
}
|
|
290
|
+
function boxTop(title) {
|
|
291
|
+
const width = pickerWidth();
|
|
292
|
+
const label = ` ${title} `;
|
|
293
|
+
const pad = Math.max(0, width - visibleWidth(label) - 1);
|
|
294
|
+
return theme.chrome(
|
|
295
|
+
`${BOX.tl}${BOX.h}${theme.accent(color.bold(label))}${theme.chrome(BOX.h.repeat(pad))}${BOX.tr}`
|
|
296
|
+
);
|
|
297
|
+
}
|
|
298
|
+
function boxBottom() {
|
|
299
|
+
return theme.chrome(`${BOX.bl}${BOX.h.repeat(pickerWidth())}${BOX.br}`);
|
|
300
|
+
}
|
|
301
|
+
function boxRow(content) {
|
|
302
|
+
return `${theme.chrome(BOX.v)} ${padVisible(content, pickerWidth() - 2)} ${theme.chrome(BOX.v)}`;
|
|
303
|
+
}
|
|
304
|
+
function boxDivider() {
|
|
305
|
+
return theme.chrome(`${BOX.v}${BOX.h.repeat(pickerWidth())}${BOX.v}`);
|
|
306
|
+
}
|
|
307
|
+
function keyHints(pairs) {
|
|
308
|
+
return pairs.map(([k, label]) => `${theme.accent(k)} ${color.dim(label)}`).join(color.dim(" \xB7 "));
|
|
309
|
+
}
|
|
310
|
+
var CODEX_PROVIDER_ID = "openai-codex";
|
|
311
|
+
var CODEX_PICKER_HEADER = "Select Model and Effort";
|
|
312
|
+
var CODEX_LEGACY_NOTE = "Access legacy models by running `wstack -m <model_name>` or in your `config.json`.";
|
|
313
|
+
function codexPickerPreamble(provider) {
|
|
314
|
+
if (provider.id !== CODEX_PROVIDER_ID) return "";
|
|
315
|
+
return ` ${color.bold(CODEX_PICKER_HEADER)}
|
|
316
|
+
${color.dim(` ${CODEX_LEGACY_NOTE}`)}
|
|
317
|
+
|
|
318
|
+
`;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
// src/picker-model-picker.ts
|
|
322
|
+
var LIVE_PICKER_MAX_VISIBLE = 15;
|
|
323
|
+
function filterModels(query, models) {
|
|
324
|
+
const q = query.trim().toLowerCase();
|
|
325
|
+
if (!q) return [...models];
|
|
326
|
+
return models.filter((m) => m.id.toLowerCase().includes(q) || m.name.toLowerCase().includes(q));
|
|
327
|
+
}
|
|
328
|
+
function renderLiveModelList(query, filtered, selectedIdx, header) {
|
|
329
|
+
const ordered = [...filtered].sort(
|
|
330
|
+
(a, b) => (b.release_date ?? "").localeCompare(a.release_date ?? "")
|
|
331
|
+
);
|
|
332
|
+
const visible = ordered.slice(0, LIVE_PICKER_MAX_VISIBLE);
|
|
333
|
+
const lines = [];
|
|
334
|
+
lines.push(boxTop("Select a model"));
|
|
335
|
+
lines.push(boxRow(color2.dim(header)));
|
|
336
|
+
const caret = query.length > 0 ? color2.dim("\u258F") : theme.cursor("\u258F");
|
|
337
|
+
lines.push(boxRow(`${theme.accent("\u276F")} ${color2.dim("Select model:")} ${query}${caret}`));
|
|
338
|
+
lines.push(boxDivider());
|
|
339
|
+
let flat = 0;
|
|
340
|
+
for (const m of visible) {
|
|
341
|
+
const selected = flat === selectedIdx;
|
|
342
|
+
const marker = selected ? theme.cursor("\u25B6") : " ";
|
|
343
|
+
const ctxRaw = m.limit?.context ? `${(m.limit.context / 1e3).toFixed(0)}k` : "?";
|
|
344
|
+
const ctx = theme.ctx(ctxRaw.padStart(6));
|
|
345
|
+
const costRaw = m.cost?.input !== void 0 ? `$${m.cost.input}/$${m.cost.output ?? "?"}` : "";
|
|
346
|
+
const cost = costRaw ? theme.cost(costRaw) : "";
|
|
347
|
+
const capTags = [];
|
|
348
|
+
if (m.tool_call) capTags.push("tools");
|
|
349
|
+
if (m.reasoning) capTags.push("reason");
|
|
350
|
+
if (m.modalities?.input?.includes("image")) capTags.push("vision");
|
|
351
|
+
const caps = capTags.map((c) => theme.caps(c)).join(color2.dim(" "));
|
|
352
|
+
const id = selected ? theme.accent(color2.bold(m.id)) : m.id;
|
|
353
|
+
lines.push(boxRow(`${marker} ${padVisible(id, 34)} ${ctx} ${padVisible(cost, 12)} ${caps}`));
|
|
354
|
+
flat++;
|
|
355
|
+
}
|
|
356
|
+
if (ordered.length > LIVE_PICKER_MAX_VISIBLE) {
|
|
357
|
+
lines.push(
|
|
358
|
+
boxRow(color2.dim(` \u2026 ${ordered.length - LIVE_PICKER_MAX_VISIBLE} more \u2014 type to filter`))
|
|
359
|
+
);
|
|
360
|
+
}
|
|
361
|
+
lines.push(boxDivider());
|
|
362
|
+
lines.push(
|
|
363
|
+
boxRow(
|
|
364
|
+
keyHints([
|
|
365
|
+
["\u2191\u2193", "move"],
|
|
366
|
+
["Enter", "select"],
|
|
367
|
+
["Esc", "clear"],
|
|
368
|
+
["Ctrl+C", "quit"]
|
|
369
|
+
])
|
|
370
|
+
)
|
|
371
|
+
);
|
|
372
|
+
lines.push(boxBottom());
|
|
373
|
+
return lines.join("\n");
|
|
374
|
+
}
|
|
375
|
+
async function runLiveModelPicker(provider, defaultModel) {
|
|
376
|
+
const stdin = process.stdin;
|
|
377
|
+
const out = process.stdout;
|
|
378
|
+
if (!stdin.isTTY || !out.isTTY) return void 0;
|
|
379
|
+
const header = `${provider.name} (${provider.id}) models:`;
|
|
380
|
+
const byNewest = (a, b) => (b.release_date ?? "").localeCompare(a.release_date ?? "");
|
|
381
|
+
const ranked = [...provider.models].sort(byNewest);
|
|
382
|
+
const defaultIdx = defaultModel !== void 0 ? ranked.findIndex((m) => m.id === defaultModel) : -1;
|
|
383
|
+
setOutputLineGuard(null);
|
|
384
|
+
let state = {
|
|
385
|
+
query: "",
|
|
386
|
+
selected: defaultIdx >= 0 ? defaultIdx : 0,
|
|
387
|
+
status: "typing"
|
|
388
|
+
};
|
|
389
|
+
const order = (filtered) => [...filtered].sort(byNewest);
|
|
390
|
+
let ordered = order(filterModels(state.query, provider.models));
|
|
391
|
+
const visibleCount = () => Math.min(ordered.length, LIVE_PICKER_MAX_VISIBLE);
|
|
392
|
+
const clamp = () => {
|
|
393
|
+
if (state.selected >= visibleCount()) state.selected = Math.max(0, visibleCount() - 1);
|
|
394
|
+
};
|
|
395
|
+
clamp();
|
|
396
|
+
const preamble = codexPickerPreamble(provider);
|
|
397
|
+
if (preamble) writeOut(preamble);
|
|
398
|
+
let frame = renderLiveModelList(state.query, ordered, state.selected, header);
|
|
399
|
+
writeOut(frame);
|
|
400
|
+
return new Promise((resolve) => {
|
|
401
|
+
const wasRaw = stdin.isRaw;
|
|
402
|
+
const wasPaused = stdin.isPaused();
|
|
403
|
+
setRawMode(stdin, true);
|
|
404
|
+
stdin.resume();
|
|
405
|
+
stdin.setEncoding("utf8");
|
|
406
|
+
const cleanup = () => {
|
|
407
|
+
stdin.off("data", onData);
|
|
408
|
+
setRawMode(stdin, wasRaw);
|
|
409
|
+
if (wasPaused) stdin.pause();
|
|
410
|
+
};
|
|
411
|
+
const repaint = () => {
|
|
412
|
+
const ups = (frame.match(/\n/g) ?? []).length;
|
|
413
|
+
writeOut(`\x1B[${ups}A\r\x1B[J`);
|
|
414
|
+
ordered = order(filterModels(state.query, provider.models));
|
|
415
|
+
clamp();
|
|
416
|
+
frame = renderLiveModelList(state.query, ordered, state.selected, header);
|
|
417
|
+
writeOut(frame);
|
|
418
|
+
};
|
|
419
|
+
const onData = (chunk) => {
|
|
420
|
+
ordered = order(filterModels(state.query, provider.models));
|
|
421
|
+
state = applyPickerKey(state, chunk, visibleCount());
|
|
422
|
+
ordered = order(filterModels(state.query, provider.models));
|
|
423
|
+
clamp();
|
|
424
|
+
if (state.status === "cancelled") {
|
|
425
|
+
cleanup();
|
|
426
|
+
writeOut("\n");
|
|
427
|
+
resolve(void 0);
|
|
428
|
+
return;
|
|
429
|
+
}
|
|
430
|
+
if (state.status === "submitted") {
|
|
431
|
+
if (ordered.length === 0) {
|
|
432
|
+
state = { ...state, status: "typing" };
|
|
433
|
+
repaint();
|
|
434
|
+
return;
|
|
435
|
+
}
|
|
436
|
+
const pick = ordered[state.selected] ?? expectDefined(ordered[0]);
|
|
437
|
+
cleanup();
|
|
438
|
+
writeOut("\n");
|
|
439
|
+
resolve(pick);
|
|
440
|
+
return;
|
|
441
|
+
}
|
|
442
|
+
repaint();
|
|
443
|
+
};
|
|
444
|
+
stdin.on("data", onData);
|
|
445
|
+
});
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
// src/picker.ts
|
|
449
|
+
function appendLocalPresetProviders(merged) {
|
|
450
|
+
const existing = new Set(merged.map((p) => p.id));
|
|
451
|
+
for (const preset of LOCAL_LLM_PRESETS) {
|
|
452
|
+
if (existing.has(preset.id)) continue;
|
|
453
|
+
merged.push({
|
|
454
|
+
id: preset.id,
|
|
455
|
+
name: preset.label,
|
|
456
|
+
family: "openai-compatible",
|
|
457
|
+
apiBase: preset.defaultBaseUrl,
|
|
458
|
+
// No env vars → with a loopback apiBase this reads as a keyless
|
|
459
|
+
// local gateway, so the picker offers it without a key.
|
|
460
|
+
envVars: [],
|
|
461
|
+
// No catalog models yet; OmniRoute/LM Studio/etc. auto-discover at
|
|
462
|
+
// boot or the user picks `m` to set a list. An empty list still
|
|
463
|
+
// lets the provider be chosen — pickModel surfaces the "no models
|
|
464
|
+
// listed" hint and the user can type an id directly.
|
|
465
|
+
models: []
|
|
466
|
+
});
|
|
467
|
+
}
|
|
468
|
+
return merged;
|
|
469
|
+
}
|
|
470
|
+
function filterProviders(query, providers) {
|
|
471
|
+
const q = query.trim().toLowerCase();
|
|
472
|
+
if (!q) return [...providers];
|
|
473
|
+
return providers.filter(
|
|
474
|
+
(p) => p.id.toLowerCase().includes(q) || p.name.toLowerCase().includes(q)
|
|
475
|
+
);
|
|
476
|
+
}
|
|
477
|
+
var PROVIDER_FAMILY_PREFERRED_ORDER = [
|
|
478
|
+
"anthropic",
|
|
479
|
+
"anthropic-oauth",
|
|
480
|
+
"openai",
|
|
481
|
+
"openai-codex",
|
|
482
|
+
"github-copilot",
|
|
483
|
+
"google",
|
|
484
|
+
"openai-compatible"
|
|
485
|
+
];
|
|
486
|
+
function orderProvidersForDisplay(filtered) {
|
|
487
|
+
const families = /* @__PURE__ */ new Map();
|
|
488
|
+
for (const p of filtered) {
|
|
489
|
+
const arr = families.get(p.family) ?? [];
|
|
490
|
+
arr.push(p);
|
|
491
|
+
families.set(p.family, arr);
|
|
492
|
+
}
|
|
493
|
+
const order = [
|
|
494
|
+
...PROVIDER_FAMILY_PREFERRED_ORDER.filter((f) => families.has(f)),
|
|
495
|
+
...[...families.keys()].filter((f) => !PROVIDER_FAMILY_PREFERRED_ORDER.includes(f))
|
|
496
|
+
];
|
|
497
|
+
const flat = [];
|
|
498
|
+
for (const fam of order) {
|
|
499
|
+
const arr = (families.get(fam) ?? []).slice().sort((a, b) => a.id.toLowerCase().localeCompare(b.id.toLowerCase()));
|
|
500
|
+
flat.push(...arr);
|
|
501
|
+
}
|
|
502
|
+
return flat;
|
|
503
|
+
}
|
|
504
|
+
function renderLiveProviderList(query, filtered, selectedIdx, savedSet) {
|
|
505
|
+
const ordered = orderProvidersForDisplay(filtered);
|
|
506
|
+
const scrollOffset = Math.max(0, selectedIdx - LIVE_PICKER_MAX_VISIBLE + 1);
|
|
507
|
+
const visible = ordered.slice(scrollOffset, scrollOffset + LIVE_PICKER_MAX_VISIBLE);
|
|
508
|
+
const lines = [];
|
|
509
|
+
lines.push(boxTop("Select a provider"));
|
|
510
|
+
const caret = query.length > 0 ? color3.dim("\u258F") : theme.cursor("\u258F");
|
|
511
|
+
lines.push(boxRow(`${theme.accent("\u276F")} ${color3.dim("Select provider:")} ${query}${caret}`));
|
|
512
|
+
lines.push(boxDivider());
|
|
513
|
+
if (scrollOffset > 0) {
|
|
514
|
+
lines.push(boxRow(color3.dim(` ${scrollOffset} more above \u2191`)));
|
|
515
|
+
}
|
|
516
|
+
let flat = 0;
|
|
517
|
+
let lastFamily = "";
|
|
518
|
+
for (const p of visible) {
|
|
519
|
+
if (p.family !== lastFamily) {
|
|
520
|
+
lines.push(boxRow(`${theme.accent("\xB7")} ${color3.dim(p.family.toUpperCase())}`));
|
|
521
|
+
lastFamily = p.family;
|
|
522
|
+
}
|
|
523
|
+
const selected = flat === selectedIdx - scrollOffset;
|
|
524
|
+
const sel = selected ? theme.cursor("\u25B6") : " ";
|
|
525
|
+
let marker;
|
|
526
|
+
if (savedSet) {
|
|
527
|
+
const mark = savedSet.has(p.id) ? color3.cyan("\u25C9") : color3.dim("\u25CB");
|
|
528
|
+
marker = `${sel} ${mark}`;
|
|
529
|
+
} else {
|
|
530
|
+
marker = `${sel}`;
|
|
531
|
+
}
|
|
532
|
+
const id = selected ? theme.accent(color3.bold(p.id)) : p.id;
|
|
533
|
+
const name = selected ? p.name : color3.dim(p.name);
|
|
534
|
+
lines.push(boxRow(`${marker} ${padVisible(id, 24)} ${name}`));
|
|
535
|
+
flat++;
|
|
536
|
+
}
|
|
537
|
+
if (scrollOffset + LIVE_PICKER_MAX_VISIBLE < ordered.length) {
|
|
538
|
+
lines.push(
|
|
539
|
+
boxRow(
|
|
540
|
+
color3.dim(` ${ordered.length - scrollOffset - LIVE_PICKER_MAX_VISIBLE} more below \u2193`)
|
|
541
|
+
)
|
|
542
|
+
);
|
|
543
|
+
}
|
|
544
|
+
lines.push(boxDivider());
|
|
545
|
+
lines.push(
|
|
546
|
+
boxRow(
|
|
547
|
+
keyHints([
|
|
548
|
+
["\u2191\u2193", "scroll"],
|
|
549
|
+
["Enter", "select"],
|
|
550
|
+
["Esc", "clear"],
|
|
551
|
+
["Ctrl+C", "quit"]
|
|
552
|
+
])
|
|
553
|
+
)
|
|
554
|
+
);
|
|
555
|
+
lines.push(boxBottom());
|
|
556
|
+
return lines.join("\n");
|
|
557
|
+
}
|
|
558
|
+
async function saveToGlobalConfig(configPath, provider, model, homeFn = () => process.env.HOME ?? os.homedir()) {
|
|
559
|
+
try {
|
|
560
|
+
const { atomicWrite } = await import("@wrongstack/core/utils");
|
|
561
|
+
const fs = await import("node:fs/promises");
|
|
562
|
+
let existing = {};
|
|
563
|
+
try {
|
|
564
|
+
const raw = await fs.readFile(configPath, "utf8");
|
|
565
|
+
existing = JSON.parse(raw);
|
|
566
|
+
} catch {
|
|
567
|
+
}
|
|
568
|
+
const oldCfg = { ...existing };
|
|
569
|
+
existing.provider = provider;
|
|
570
|
+
existing.model = model;
|
|
571
|
+
try {
|
|
572
|
+
await backupCurrent(homeFn, configPath);
|
|
573
|
+
} catch (err) {
|
|
574
|
+
console.warn(
|
|
575
|
+
JSON.stringify({
|
|
576
|
+
level: "warn",
|
|
577
|
+
event: "picker.backup_failed",
|
|
578
|
+
message: toErrorMessage(err),
|
|
579
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
580
|
+
})
|
|
581
|
+
);
|
|
582
|
+
}
|
|
583
|
+
await atomicWrite(configPath, JSON.stringify(existing, null, 2), { mode: 384 });
|
|
584
|
+
try {
|
|
585
|
+
await appendHistory(
|
|
586
|
+
oldCfg,
|
|
587
|
+
existing,
|
|
588
|
+
`Provider/model changed: ${oldCfg.provider ?? "(none)"} \u2192 ${provider}, ${oldCfg.model ?? "(none)"} \u2192 ${model}`,
|
|
589
|
+
homeFn,
|
|
590
|
+
configPath
|
|
591
|
+
);
|
|
592
|
+
} catch {
|
|
593
|
+
}
|
|
594
|
+
return true;
|
|
595
|
+
} catch (err) {
|
|
596
|
+
console.warn(
|
|
597
|
+
JSON.stringify({
|
|
598
|
+
level: "warn",
|
|
599
|
+
event: "picker.save_failed",
|
|
600
|
+
message: toErrorMessage(err),
|
|
601
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
602
|
+
})
|
|
603
|
+
);
|
|
604
|
+
return false;
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
var QUERY_MARKER = "Select provider:";
|
|
608
|
+
function cursorToQuery(frame, query) {
|
|
609
|
+
const rows = frame.split("\n");
|
|
610
|
+
const lastIdx = rows.length - 1;
|
|
611
|
+
const queryIdx = rows.findIndex((r) => r.includes(QUERY_MARKER));
|
|
612
|
+
if (queryIdx < 0) return;
|
|
613
|
+
const up = lastIdx - queryIdx;
|
|
614
|
+
const queryLine = rows[queryIdx] ?? "";
|
|
615
|
+
const plain = stripAnsi2(queryLine);
|
|
616
|
+
const markerAt = plain.indexOf(QUERY_MARKER);
|
|
617
|
+
const col = markerAt + QUERY_MARKER.length + 1 + query.length + 1;
|
|
618
|
+
if (up > 0) writeOut2(`\x1B[${up}A`);
|
|
619
|
+
writeOut2(`\x1B[${col}G`);
|
|
620
|
+
}
|
|
621
|
+
async function runLiveProviderPicker(displayList, savedSet) {
|
|
622
|
+
const stdin = process.stdin;
|
|
623
|
+
const out = process.stdout;
|
|
624
|
+
if (!stdin.isTTY || !out.isTTY) return void 0;
|
|
625
|
+
setOutputLineGuard2(null);
|
|
626
|
+
let state = { query: "", selected: 0, status: "typing" };
|
|
627
|
+
let ordered = orderProvidersForDisplay(filterProviders(state.query, displayList));
|
|
628
|
+
const visibleCount = () => ordered.length;
|
|
629
|
+
const clamp = () => {
|
|
630
|
+
if (state.selected >= visibleCount()) state.selected = Math.max(0, visibleCount() - 1);
|
|
631
|
+
};
|
|
632
|
+
clamp();
|
|
633
|
+
let frame = renderLiveProviderList(state.query, ordered, state.selected, savedSet);
|
|
634
|
+
writeOut2(frame);
|
|
635
|
+
writeOut2("\x1B7");
|
|
636
|
+
cursorToQuery(frame, state.query);
|
|
637
|
+
return new Promise((resolve) => {
|
|
638
|
+
const wasRaw = stdin.isRaw;
|
|
639
|
+
const wasPaused = stdin.isPaused();
|
|
640
|
+
setRawMode2(stdin, true);
|
|
641
|
+
stdin.resume();
|
|
642
|
+
stdin.setEncoding("utf8");
|
|
643
|
+
const cleanup = () => {
|
|
644
|
+
stdin.off("data", onData);
|
|
645
|
+
setRawMode2(stdin, wasRaw);
|
|
646
|
+
if (wasPaused) stdin.pause();
|
|
647
|
+
};
|
|
648
|
+
const repaint = () => {
|
|
649
|
+
writeOut2("\x1B8");
|
|
650
|
+
const ups = (frame.match(/\n/g) ?? []).length;
|
|
651
|
+
writeOut2(`\x1B[${ups}A\r\x1B[J`);
|
|
652
|
+
ordered = orderProvidersForDisplay(filterProviders(state.query, displayList));
|
|
653
|
+
clamp();
|
|
654
|
+
frame = renderLiveProviderList(state.query, ordered, state.selected, savedSet);
|
|
655
|
+
writeOut2(frame);
|
|
656
|
+
writeOut2("\x1B7");
|
|
657
|
+
cursorToQuery(frame, state.query);
|
|
658
|
+
};
|
|
659
|
+
const onData = (chunk) => {
|
|
660
|
+
ordered = orderProvidersForDisplay(filterProviders(state.query, displayList));
|
|
661
|
+
state = applyPickerKey(state, chunk, visibleCount());
|
|
662
|
+
ordered = orderProvidersForDisplay(filterProviders(state.query, displayList));
|
|
663
|
+
clamp();
|
|
664
|
+
if (state.status === "cancelled") {
|
|
665
|
+
cleanup();
|
|
666
|
+
writeOut2("\n");
|
|
667
|
+
resolve(void 0);
|
|
668
|
+
return;
|
|
669
|
+
}
|
|
670
|
+
if (state.status === "submitted") {
|
|
671
|
+
if (ordered.length === 0) {
|
|
672
|
+
state = { ...state, status: "typing" };
|
|
673
|
+
repaint();
|
|
674
|
+
return;
|
|
675
|
+
}
|
|
676
|
+
const pick = ordered[state.selected] ?? ordered[0];
|
|
677
|
+
cleanup();
|
|
678
|
+
writeOut2("\n");
|
|
679
|
+
resolve(pick);
|
|
680
|
+
return;
|
|
681
|
+
}
|
|
682
|
+
repaint();
|
|
683
|
+
};
|
|
684
|
+
stdin.on("data", onData);
|
|
685
|
+
});
|
|
686
|
+
}
|
|
687
|
+
async function runPicker(deps) {
|
|
688
|
+
const { modelsRegistry, renderer, reader, config, defaultProvider, defaultModel } = deps;
|
|
689
|
+
renderer.write(
|
|
690
|
+
`
|
|
691
|
+
${theme.accent(color3.bold("\u258C WrongStack"))} ${color3.dim("Provider & Model Selection")}
|
|
692
|
+
`
|
|
693
|
+
);
|
|
694
|
+
renderer.write(color3.dim(`${theme.chrome("\xB7")} Loading provider catalog\u2026
|
|
695
|
+
`));
|
|
696
|
+
let providers;
|
|
697
|
+
try {
|
|
698
|
+
providers = await modelsRegistry.listProviders();
|
|
699
|
+
} catch {
|
|
700
|
+
renderer.writeError(
|
|
701
|
+
"Failed to load provider catalog. Pass --provider and --model to skip the picker."
|
|
702
|
+
);
|
|
703
|
+
return void 0;
|
|
704
|
+
}
|
|
705
|
+
const supported = providers.filter((p) => p.family !== "unsupported");
|
|
706
|
+
const catalogById = new Map(supported.map((p) => [p.id, p]));
|
|
707
|
+
const overlay = config?.providers ?? {};
|
|
708
|
+
const seen = /* @__PURE__ */ new Set();
|
|
709
|
+
const merged = [];
|
|
710
|
+
for (const p of supported) {
|
|
711
|
+
const cfg = overlay[p.id];
|
|
712
|
+
seen.add(p.id);
|
|
713
|
+
if (cfg) {
|
|
714
|
+
merged.push({
|
|
715
|
+
...p,
|
|
716
|
+
family: cfg.family ?? p.family,
|
|
717
|
+
apiBase: cfg.baseUrl ?? p.apiBase,
|
|
718
|
+
envVars: cfg.envVars && cfg.envVars.length > 0 ? cfg.envVars : p.envVars,
|
|
719
|
+
// When the user has saved an explicit model list, it wins — they
|
|
720
|
+
// know which models their endpoint actually serves (e.g. LM
|
|
721
|
+
// Studio, vLLM, or a proxy with custom model ids). Otherwise the
|
|
722
|
+
// catalog list keeps providing suggestions.
|
|
723
|
+
models: visibleModelIds(
|
|
724
|
+
p.id,
|
|
725
|
+
config ?? { providers: {} },
|
|
726
|
+
p.models.map((m) => m.id),
|
|
727
|
+
cfg
|
|
728
|
+
).map((m) => p.models.find((pm) => pm.id === m) ?? { id: m, name: m })
|
|
729
|
+
});
|
|
730
|
+
} else {
|
|
731
|
+
merged.push(p);
|
|
732
|
+
}
|
|
733
|
+
}
|
|
734
|
+
for (const [id, cfg] of Object.entries(overlay)) {
|
|
735
|
+
if (seen.has(id)) continue;
|
|
736
|
+
if (!cfg?.family || cfg.family === "unsupported") continue;
|
|
737
|
+
const catalogType = cfg.type && cfg.type !== id ? cfg.type : void 0;
|
|
738
|
+
const inherited = catalogType ? catalogById.get(catalogType) : void 0;
|
|
739
|
+
merged.push({
|
|
740
|
+
id,
|
|
741
|
+
name: inherited ? `${inherited.name} ${color3.dim("(alias)")}` : id,
|
|
742
|
+
family: cfg.family,
|
|
743
|
+
apiBase: cfg.baseUrl ?? inherited?.apiBase,
|
|
744
|
+
envVars: cfg.envVars ?? inherited?.envVars ?? [],
|
|
745
|
+
models: visibleModelIds(
|
|
746
|
+
id,
|
|
747
|
+
config ?? { providers: {} },
|
|
748
|
+
(inherited?.models ?? []).map((m) => m.id),
|
|
749
|
+
cfg
|
|
750
|
+
).map((m) => inherited?.models.find((pm) => pm.id === m) ?? { id: m, name: m }),
|
|
751
|
+
npm: inherited?.npm
|
|
752
|
+
});
|
|
753
|
+
}
|
|
754
|
+
const keyed = merged.filter((p) => hasApiKey(p, config) || isKeylessLocalProvider(p));
|
|
755
|
+
let displayList = keyed;
|
|
756
|
+
let showingFallback = false;
|
|
757
|
+
if (keyed.length === 0) {
|
|
758
|
+
displayList = merged;
|
|
759
|
+
showingFallback = merged.length > 0;
|
|
760
|
+
}
|
|
761
|
+
appendLocalPresetProviders(displayList);
|
|
762
|
+
if (displayList.length === 0) {
|
|
763
|
+
renderer.writeError("No supported providers found in catalog.");
|
|
764
|
+
return void 0;
|
|
765
|
+
}
|
|
766
|
+
if (process.stdin.isTTY) {
|
|
767
|
+
const chosen2 = await runLiveProviderPicker(displayList);
|
|
768
|
+
if (!chosen2) {
|
|
769
|
+
renderer.write(color3.dim("Cancelled.\n"));
|
|
770
|
+
return void 0;
|
|
771
|
+
}
|
|
772
|
+
return pickModel(chosen2, modelsRegistry, renderer, reader, defaultModel);
|
|
773
|
+
}
|
|
774
|
+
const families = /* @__PURE__ */ new Map();
|
|
775
|
+
for (const p of displayList) {
|
|
776
|
+
const list = families.get(p.family) ?? [];
|
|
777
|
+
list.push(p);
|
|
778
|
+
families.set(p.family, list);
|
|
779
|
+
}
|
|
780
|
+
const ordered = [];
|
|
781
|
+
const preferredOrder = [
|
|
782
|
+
"anthropic",
|
|
783
|
+
"anthropic-oauth",
|
|
784
|
+
"openai",
|
|
785
|
+
"openai-codex",
|
|
786
|
+
"github-copilot",
|
|
787
|
+
"google",
|
|
788
|
+
"openai-compatible"
|
|
789
|
+
];
|
|
790
|
+
const familyOrder = [
|
|
791
|
+
...preferredOrder.filter((f) => families.has(f)),
|
|
792
|
+
...[...families.keys()].filter((f) => !preferredOrder.includes(f))
|
|
793
|
+
];
|
|
794
|
+
let idx = 1;
|
|
795
|
+
let defaultIdx;
|
|
796
|
+
renderer.write("\n");
|
|
797
|
+
renderer.write(`${boxTop("Select a provider")}
|
|
798
|
+
`);
|
|
799
|
+
for (const fam of familyOrder) {
|
|
800
|
+
const list = [...families.get(fam) ?? []].sort(
|
|
801
|
+
(a, b) => a.id.toLowerCase().localeCompare(b.id.toLowerCase())
|
|
802
|
+
);
|
|
803
|
+
if (!list || list.length === 0) continue;
|
|
804
|
+
renderer.write(`${boxRow(`${theme.accent("\xB7")} ${color3.dim(fam.toUpperCase())}`)}
|
|
805
|
+
`);
|
|
806
|
+
for (const p of list) {
|
|
807
|
+
const envFound = p.envVars.some((v) => !!process.env[v]);
|
|
808
|
+
const entry = config?.providers?.[p.id];
|
|
809
|
+
const configKey = typeof entry?.apiKey === "string" && entry.apiKey.length > 0 || Array.isArray(entry?.apiKeys) && entry?.apiKeys?.some((k) => k?.apiKey);
|
|
810
|
+
const marker = envFound ? color3.green("\u25CF") : configKey ? color3.cyan("\u25C9") : color3.dim("\u25CB");
|
|
811
|
+
const isDefault = p.id === defaultProvider;
|
|
812
|
+
if (isDefault) defaultIdx = idx;
|
|
813
|
+
const idLabel = isDefault ? theme.accent(color3.bold(p.id)) : p.id;
|
|
814
|
+
const suffix = isDefault ? color3.dim(" (default)") : "";
|
|
815
|
+
renderer.write(
|
|
816
|
+
`${boxRow(`${color3.dim(`${idx}.`.padStart(4))} ${marker} ${padVisible(idLabel, 22)} ${color3.dim(p.name)}${suffix}`)}
|
|
817
|
+
`
|
|
818
|
+
);
|
|
819
|
+
ordered.push({ provider: p, index: idx });
|
|
820
|
+
idx++;
|
|
821
|
+
}
|
|
822
|
+
}
|
|
823
|
+
renderer.write(`${boxDivider()}
|
|
824
|
+
`);
|
|
825
|
+
if (showingFallback) {
|
|
826
|
+
renderer.write(
|
|
827
|
+
`${boxRow(`${color3.yellow("\u26A0 No API keys detected.")} ${color3.dim("Run `wstack auth <provider>` after picking.")}`)}
|
|
828
|
+
`
|
|
829
|
+
);
|
|
830
|
+
} else {
|
|
831
|
+
renderer.write(`${boxRow(color3.dim("\u25CF env key \u25C9 stored in config \u25CB no key"))}
|
|
832
|
+
`);
|
|
833
|
+
}
|
|
834
|
+
renderer.write(`${boxBottom()}
|
|
835
|
+
`);
|
|
836
|
+
const defaultHint = defaultIdx !== void 0 && defaultProvider ? ` ${color3.dim(`[Enter = ${defaultProvider}]`)}` : "";
|
|
837
|
+
const providerAnswer = (await reader.readLine(
|
|
838
|
+
`
|
|
839
|
+
${color3.amber("?")} Select provider (1-${ordered.length})${defaultHint} ${color3.dim("[q to quit]")}: `
|
|
840
|
+
)).trim();
|
|
841
|
+
if (providerAnswer.toLowerCase() === "q") {
|
|
842
|
+
renderer.write(color3.dim("Cancelled.\n"));
|
|
843
|
+
return void 0;
|
|
844
|
+
}
|
|
845
|
+
if (!providerAnswer) {
|
|
846
|
+
if (defaultIdx !== void 0) {
|
|
847
|
+
const def = ordered[defaultIdx - 1];
|
|
848
|
+
if (def) return pickModel(def.provider, modelsRegistry, renderer, reader, defaultModel);
|
|
849
|
+
}
|
|
850
|
+
renderer.write(color3.dim("Cancelled.\n"));
|
|
851
|
+
return void 0;
|
|
852
|
+
}
|
|
853
|
+
const providerIdx = Number.parseInt(providerAnswer, 10);
|
|
854
|
+
if (Number.isNaN(providerIdx) || providerIdx < 1 || providerIdx > ordered.length) {
|
|
855
|
+
const byId = ordered.find((o) => o.provider.id.toLowerCase() === providerAnswer.toLowerCase());
|
|
856
|
+
if (!byId) {
|
|
857
|
+
renderer.writeError(`Invalid selection: "${providerAnswer}"`);
|
|
858
|
+
return void 0;
|
|
859
|
+
}
|
|
860
|
+
return pickModel(byId.provider, modelsRegistry, renderer, reader, defaultModel);
|
|
861
|
+
}
|
|
862
|
+
const chosen = ordered[providerIdx - 1];
|
|
863
|
+
if (!chosen) return void 0;
|
|
864
|
+
const modelHint = chosen.provider.id === defaultProvider ? defaultModel : void 0;
|
|
865
|
+
return pickModel(chosen.provider, modelsRegistry, renderer, reader, modelHint);
|
|
866
|
+
}
|
|
867
|
+
async function pickModel(provider, registry, renderer, reader, defaultModel) {
|
|
868
|
+
renderer.write(`
|
|
869
|
+
${boxTop("Select a model")}
|
|
870
|
+
`);
|
|
871
|
+
renderer.write(
|
|
872
|
+
`${boxRow(`${color3.bold(provider.name)} ${color3.dim(`(${provider.id})`)} models:`)}
|
|
873
|
+
`
|
|
874
|
+
);
|
|
875
|
+
renderer.write(`${boxBottom()}
|
|
876
|
+
`);
|
|
877
|
+
const codexBlock = codexPickerPreamble(provider);
|
|
878
|
+
if (codexBlock) renderer.write(codexBlock);
|
|
879
|
+
const models = [...provider.models].sort(
|
|
880
|
+
(a, b) => (b.release_date ?? "").localeCompare(a.release_date ?? "")
|
|
881
|
+
);
|
|
882
|
+
if (models.length === 0) {
|
|
883
|
+
renderer.write(
|
|
884
|
+
color3.dim(
|
|
885
|
+
" No models listed yet for this provider \u2014 type a model id to use it (local servers auto-discover models at launch).\n"
|
|
886
|
+
)
|
|
887
|
+
);
|
|
888
|
+
const typed = (await reader.readLine(`
|
|
889
|
+
${color3.amber("?")} Model id ${color3.dim("(or Enter to cancel)")}: `)).trim();
|
|
890
|
+
if (!typed) {
|
|
891
|
+
renderer.write(color3.dim("Cancelled.\n"));
|
|
892
|
+
return void 0;
|
|
893
|
+
}
|
|
894
|
+
renderer.write(`
|
|
895
|
+
${color3.green("\u2713")} ${color3.bold(provider.id)} / ${color3.bold(typed)}
|
|
896
|
+
|
|
897
|
+
`);
|
|
898
|
+
return { provider: provider.id, model: typed };
|
|
899
|
+
}
|
|
900
|
+
if (process.stdin.isTTY) {
|
|
901
|
+
const chosen = await runLiveModelPicker(provider, defaultModel);
|
|
902
|
+
if (!chosen) {
|
|
903
|
+
renderer.write(color3.dim("Cancelled.\n"));
|
|
904
|
+
return void 0;
|
|
905
|
+
}
|
|
906
|
+
renderer.write(
|
|
907
|
+
`
|
|
908
|
+
${color3.green("\u2713")} ${color3.bold(provider.id)} / ${color3.bold(chosen.id)}
|
|
909
|
+
|
|
910
|
+
`
|
|
911
|
+
);
|
|
912
|
+
return { provider: provider.id, model: chosen.id };
|
|
913
|
+
}
|
|
914
|
+
const defaultIdxInModels = defaultModel !== void 0 ? models.findIndex((m) => m.id === defaultModel) : -1;
|
|
915
|
+
const pageSize = 30;
|
|
916
|
+
let offset = 0;
|
|
917
|
+
while (offset < models.length) {
|
|
918
|
+
const page = models.slice(offset, offset + pageSize);
|
|
919
|
+
const pageFrom = offset + 1;
|
|
920
|
+
const pageTo = Math.min(offset + page.length, models.length);
|
|
921
|
+
renderer.write(`${boxTop(`Models ${pageFrom}\u2013${pageTo} of ${models.length}`)}
|
|
922
|
+
`);
|
|
923
|
+
for (let i = 0; i < page.length; i++) {
|
|
924
|
+
const m = expectDefined2(page[i]);
|
|
925
|
+
const num = offset + i + 1;
|
|
926
|
+
const ctxRaw = m.limit?.context ? `${(m.limit.context / 1e3).toFixed(0)}k` : "?";
|
|
927
|
+
const ctx = theme.ctx(ctxRaw.padStart(6));
|
|
928
|
+
const cost = m.cost?.input !== void 0 ? `$${m.cost.input}/$${m.cost.output ?? "?"}` : "";
|
|
929
|
+
const costCol = cost ? theme.cost(cost) : "";
|
|
930
|
+
const capTags = [];
|
|
931
|
+
if (m.tool_call) capTags.push("tools");
|
|
932
|
+
if (m.reasoning) capTags.push("reason");
|
|
933
|
+
if (m.modalities?.input?.includes("image")) capTags.push("vision");
|
|
934
|
+
const capStr = capTags.map((c) => theme.caps(c)).join(color3.dim(" "));
|
|
935
|
+
const isDefault = m.id === defaultModel;
|
|
936
|
+
const idLabel = isDefault ? theme.accent(color3.bold(m.id)) : m.id;
|
|
937
|
+
const suffix = isDefault ? color3.dim(" (default)") : "";
|
|
938
|
+
const num5 = color3.dim(`${num}.`.padStart(5));
|
|
939
|
+
renderer.write(
|
|
940
|
+
`${boxRow(`${num5} ${padVisible(idLabel, 34)} ${ctx} ${padVisible(costCol, 11)} ${capStr}${suffix}`)}
|
|
941
|
+
`
|
|
942
|
+
);
|
|
943
|
+
}
|
|
944
|
+
renderer.write(`${boxBottom()}
|
|
945
|
+
`);
|
|
946
|
+
offset += pageSize;
|
|
947
|
+
if (offset < models.length) {
|
|
948
|
+
const more = (await reader.readLine(
|
|
949
|
+
`
|
|
950
|
+
${color3.amber("?")} Showing ${Math.min(offset, models.length)}/${models.length} \u2014 Enter number, ${color3.dim("Enter")} for more, or ${color3.dim("q")} to quit: `
|
|
951
|
+
)).trim();
|
|
952
|
+
if (more.toLowerCase() === "q") {
|
|
953
|
+
renderer.write(color3.dim("Cancelled.\n"));
|
|
954
|
+
return void 0;
|
|
955
|
+
}
|
|
956
|
+
if (!more) continue;
|
|
957
|
+
return resolveModelSelection(more, models, provider, registry, renderer, reader);
|
|
958
|
+
}
|
|
959
|
+
}
|
|
960
|
+
const defaultHint = defaultIdxInModels >= 0 && defaultModel ? ` ${color3.dim(`[Enter = ${defaultModel}]`)}` : "";
|
|
961
|
+
const answer = (await reader.readLine(
|
|
962
|
+
`
|
|
963
|
+
${color3.amber("?")} Select model (1-${models.length})${defaultHint} ${color3.dim("[q to quit]")}: `
|
|
964
|
+
)).trim();
|
|
965
|
+
if (answer.toLowerCase() === "q") {
|
|
966
|
+
renderer.write(color3.dim("Cancelled.\n"));
|
|
967
|
+
return void 0;
|
|
968
|
+
}
|
|
969
|
+
if (!answer) {
|
|
970
|
+
if (defaultIdxInModels >= 0 && defaultModel) {
|
|
971
|
+
renderer.write(
|
|
972
|
+
`
|
|
973
|
+
${color3.green("\u2713")} ${color3.bold(provider.id)} / ${color3.bold(defaultModel)}
|
|
974
|
+
|
|
975
|
+
`
|
|
976
|
+
);
|
|
977
|
+
return { provider: provider.id, model: defaultModel };
|
|
978
|
+
}
|
|
979
|
+
renderer.write(color3.dim("Cancelled.\n"));
|
|
980
|
+
return void 0;
|
|
981
|
+
}
|
|
982
|
+
return resolveModelSelection(answer, models, provider, registry, renderer, reader);
|
|
983
|
+
}
|
|
984
|
+
async function resolveModelSelection(answer, models, provider, _registry, renderer, _reader) {
|
|
985
|
+
const idx = Number.parseInt(answer, 10);
|
|
986
|
+
let modelId;
|
|
987
|
+
if (!Number.isNaN(idx) && idx >= 1 && idx <= models.length) {
|
|
988
|
+
modelId = models[idx - 1]?.id;
|
|
989
|
+
} else {
|
|
990
|
+
const lower = answer.toLowerCase();
|
|
991
|
+
const match = models.find((m) => m.id.toLowerCase() === lower);
|
|
992
|
+
if (match) {
|
|
993
|
+
modelId = match.id;
|
|
994
|
+
} else {
|
|
995
|
+
const partial = models.filter((m) => m.id.toLowerCase().includes(lower));
|
|
996
|
+
if (partial.length === 1) {
|
|
997
|
+
modelId = partial[0]?.id;
|
|
998
|
+
} else if (partial.length > 1) {
|
|
999
|
+
renderer.writeError(`"${answer}" matches multiple models. Be more specific.`);
|
|
1000
|
+
return void 0;
|
|
1001
|
+
}
|
|
1002
|
+
}
|
|
1003
|
+
}
|
|
1004
|
+
if (!modelId) {
|
|
1005
|
+
modelId = answer;
|
|
1006
|
+
}
|
|
1007
|
+
renderer.write(`
|
|
1008
|
+
${color3.green("\u2713")} ${color3.bold(provider.id)} / ${color3.bold(modelId)}
|
|
1009
|
+
|
|
1010
|
+
`);
|
|
1011
|
+
return { provider: provider.id, model: modelId };
|
|
1012
|
+
}
|
|
1013
|
+
|
|
1014
|
+
export {
|
|
1015
|
+
parseArgs,
|
|
1016
|
+
parseAuthFlags,
|
|
1017
|
+
parseSpawnFlags,
|
|
1018
|
+
LOCAL_LLM_PRESETS,
|
|
1019
|
+
saveToGlobalConfig,
|
|
1020
|
+
runLiveProviderPicker,
|
|
1021
|
+
runPicker
|
|
1022
|
+
};
|
|
1023
|
+
//# sourceMappingURL=chunk-JBSQ7ONN.js.map
|