cli-jaw 2.1.1 → 2.1.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/README.ja.md +8 -6
- package/README.ko.md +8 -6
- package/README.md +12 -6
- package/README.zh-CN.md +8 -6
- package/dist/bin/cli-jaw.js +5 -1
- package/dist/bin/cli-jaw.js.map +1 -1
- package/dist/bin/commands/browser.js +1 -1
- package/dist/bin/commands/browser.js.map +1 -1
- package/dist/bin/commands/chat.js +98 -58
- package/dist/bin/commands/chat.js.map +1 -1
- package/dist/bin/commands/dispatch.js +130 -5
- package/dist/bin/commands/dispatch.js.map +1 -1
- package/dist/bin/commands/goal.js +18 -6
- package/dist/bin/commands/goal.js.map +1 -1
- package/dist/bin/commands/orchestrate.js.map +1 -1
- package/dist/bin/commands/tui/fullscreen-mode.js +237 -0
- package/dist/bin/commands/tui/fullscreen-mode.js.map +1 -0
- package/dist/bin/commands/tui/input-handler.js +139 -52
- package/dist/bin/commands/tui/input-handler.js.map +1 -1
- package/dist/bin/commands/tui/overlays.js +177 -70
- package/dist/bin/commands/tui/overlays.js.map +1 -1
- package/dist/bin/commands/tui/renderer.js +70 -20
- package/dist/bin/commands/tui/renderer.js.map +1 -1
- package/dist/bin/commands/tui/simple-mode.js +1 -1
- package/dist/bin/commands/tui/simple-mode.js.map +1 -1
- package/dist/bin/commands/tui/tui-io.js +8 -0
- package/dist/bin/commands/tui/tui-io.js.map +1 -0
- package/dist/bin/commands/tui/types.js +9 -0
- package/dist/bin/commands/tui/types.js.map +1 -1
- package/dist/bin/commands/tui/ws-handler.js +115 -23
- package/dist/bin/commands/tui/ws-handler.js.map +1 -1
- package/dist/bin/commands/worker.js +159 -0
- package/dist/bin/commands/worker.js.map +1 -0
- package/dist/bin/postinstall.js +0 -76
- package/dist/bin/postinstall.js.map +1 -1
- package/dist/lib/mcp/format-converters.js +21 -2
- package/dist/lib/mcp/format-converters.js.map +1 -1
- package/dist/lib/mcp/mcp-registry.js +75 -0
- package/dist/lib/mcp/mcp-registry.js.map +1 -0
- package/dist/lib/stt.js +1 -1
- package/dist/lib/stt.js.map +1 -1
- package/dist/scripts/fresh-install-smoke.js +1 -1
- package/dist/scripts/fresh-install-smoke.js.map +1 -1
- package/dist/server.js +27 -6
- package/dist/server.js.map +1 -1
- package/dist/src/agent/args.js +33 -1
- package/dist/src/agent/args.js.map +1 -1
- package/dist/src/agent/claude-e-runtime.js +1 -1
- package/dist/src/agent/claude-e-runtime.js.map +1 -1
- package/dist/src/agent/codex-app-client.js +1 -1
- package/dist/src/agent/error-classifier.js +6 -1
- package/dist/src/agent/error-classifier.js.map +1 -1
- package/dist/src/agent/events/claude.js +1 -0
- package/dist/src/agent/events/claude.js.map +1 -1
- package/dist/src/agent/events/codex.js +0 -44
- package/dist/src/agent/events/codex.js.map +1 -1
- package/dist/src/agent/events/helpers.js +52 -5
- package/dist/src/agent/events/helpers.js.map +1 -1
- package/dist/src/agent/events/opencode.js +6 -2
- package/dist/src/agent/events/opencode.js.map +1 -1
- package/dist/src/agent/events/summary.js +3 -2
- package/dist/src/agent/events/summary.js.map +1 -1
- package/dist/src/agent/events/tool-labels.js +8 -5
- package/dist/src/agent/events/tool-labels.js.map +1 -1
- package/dist/src/agent/kiro-auth.js +213 -0
- package/dist/src/agent/kiro-auth.js.map +1 -0
- package/dist/src/agent/kiro-models.js +79 -0
- package/dist/src/agent/kiro-models.js.map +1 -0
- package/dist/src/agent/kiro-runtime.js +306 -0
- package/dist/src/agent/kiro-runtime.js.map +1 -0
- package/dist/src/agent/lifecycle-handler.js +190 -12
- package/dist/src/agent/lifecycle-handler.js.map +1 -1
- package/dist/src/agent/memory-flush-controller.js +1 -3
- package/dist/src/agent/memory-flush-controller.js.map +1 -1
- package/dist/src/agent/resume-classifier.js +18 -1
- package/dist/src/agent/resume-classifier.js.map +1 -1
- package/dist/src/agent/session-persistence.js +1 -1
- package/dist/src/agent/session-persistence.js.map +1 -1
- package/dist/src/agent/smoke-detector.js +3 -0
- package/dist/src/agent/smoke-detector.js.map +1 -1
- package/dist/src/agent/spawn/queue.js +10 -4
- package/dist/src/agent/spawn/queue.js.map +1 -1
- package/dist/src/agent/spawn/resume.js +6 -1
- package/dist/src/agent/spawn/resume.js.map +1 -1
- package/dist/src/agent/spawn-env.js +1 -1
- package/dist/src/agent/spawn-env.js.map +1 -1
- package/dist/src/agent/spawn.js +188 -28
- package/dist/src/agent/spawn.js.map +1 -1
- package/dist/src/browser/web-ai/grok-live.js +2 -0
- package/dist/src/browser/web-ai/grok-live.js.map +1 -1
- package/dist/src/cli/claude-models.js +2 -2
- package/dist/src/cli/claude-models.js.map +1 -1
- package/dist/src/cli/commands.js +3 -2
- package/dist/src/cli/commands.js.map +1 -1
- package/dist/src/cli/handlers-runtime.js +2 -0
- package/dist/src/cli/handlers-runtime.js.map +1 -1
- package/dist/src/cli/handlers-workflows.js +9 -4
- package/dist/src/cli/handlers-workflows.js.map +1 -1
- package/dist/src/cli/handlers.js +47 -7
- package/dist/src/cli/handlers.js.map +1 -1
- package/dist/src/cli/readiness.js +17 -1
- package/dist/src/cli/readiness.js.map +1 -1
- package/dist/src/cli/registry-live.js +17 -0
- package/dist/src/cli/registry-live.js.map +1 -0
- package/dist/src/cli/registry.js +44 -3
- package/dist/src/cli/registry.js.map +1 -1
- package/dist/src/cli/tui/composer.js +135 -5
- package/dist/src/cli/tui/composer.js.map +1 -1
- package/dist/src/cli/tui/diffview.js +41 -0
- package/dist/src/cli/tui/diffview.js.map +1 -0
- package/dist/src/cli/tui/editor.js +45 -0
- package/dist/src/cli/tui/editor.js.map +1 -0
- package/dist/src/cli/tui/file-mention.js +78 -0
- package/dist/src/cli/tui/file-mention.js.map +1 -0
- package/dist/src/cli/tui/highlight.js +82 -0
- package/dist/src/cli/tui/highlight.js.map +1 -0
- package/dist/src/cli/tui/keymap.js +21 -0
- package/dist/src/cli/tui/keymap.js.map +1 -1
- package/dist/src/cli/tui/markdown.js +124 -0
- package/dist/src/cli/tui/markdown.js.map +1 -0
- package/dist/src/cli/tui/mode.js +26 -0
- package/dist/src/cli/tui/mode.js.map +1 -0
- package/dist/src/cli/tui/overlay.js +121 -98
- package/dist/src/cli/tui/overlay.js.map +1 -1
- package/dist/src/cli/tui/render/frame.js +72 -0
- package/dist/src/cli/tui/render/frame.js.map +1 -0
- package/dist/src/cli/tui/render/layout.js +22 -0
- package/dist/src/cli/tui/render/layout.js.map +1 -0
- package/dist/src/cli/tui/render/mouse.js +25 -0
- package/dist/src/cli/tui/render/mouse.js.map +1 -0
- package/dist/src/cli/tui/render/scheduler.js +37 -0
- package/dist/src/cli/tui/render/scheduler.js.map +1 -0
- package/dist/src/cli/tui/render/viewport.js +82 -0
- package/dist/src/cli/tui/render/viewport.js.map +1 -0
- package/dist/src/cli/tui/renderers.js +37 -0
- package/dist/src/cli/tui/renderers.js.map +1 -1
- package/dist/src/cli/tui/stream.js +48 -0
- package/dist/src/cli/tui/stream.js.map +1 -0
- package/dist/src/cli/tui/text-buffer.js +143 -0
- package/dist/src/cli/tui/text-buffer.js.map +1 -0
- package/dist/src/cli/tui/theme.js +128 -0
- package/dist/src/cli/tui/theme.js.map +1 -0
- package/dist/src/cli/tui/transcript.js +4 -0
- package/dist/src/cli/tui/transcript.js.map +1 -1
- package/dist/src/command-contract/help-renderer.js +1 -1
- package/dist/src/command-contract/help-renderer.js.map +1 -1
- package/dist/src/core/cli-detection.js +14 -0
- package/dist/src/core/cli-detection.js.map +1 -1
- package/dist/src/core/config.js +5 -0
- package/dist/src/core/config.js.map +1 -1
- package/dist/src/core/db.js +7 -0
- package/dist/src/core/db.js.map +1 -1
- package/dist/src/core/employees.js +2 -2
- package/dist/src/core/employees.js.map +1 -1
- package/dist/src/discord/bot.js.map +1 -1
- package/dist/src/discord/discord-file.js +1 -1
- package/dist/src/discord/discord-file.js.map +1 -1
- package/dist/src/discord/send-only-client.js +1 -3
- package/dist/src/discord/send-only-client.js.map +1 -1
- package/dist/src/goal/heartbeat.js +30 -7
- package/dist/src/goal/heartbeat.js.map +1 -1
- package/dist/src/goal/store.js +6 -2
- package/dist/src/goal/store.js.map +1 -1
- package/dist/src/ide/diff.js +37 -0
- package/dist/src/ide/diff.js.map +1 -1
- package/dist/src/manager/launchd-service.js +1 -1
- package/dist/src/manager/launchd-service.js.map +1 -1
- package/dist/src/manager/lifecycle-helpers.js +14 -0
- package/dist/src/manager/lifecycle-helpers.js.map +1 -1
- package/dist/src/manager/lifecycle.js +49 -4
- package/dist/src/manager/lifecycle.js.map +1 -1
- package/dist/src/manager/notes/routes.js +0 -31
- package/dist/src/manager/notes/routes.js.map +1 -1
- package/dist/src/manager/notes/ws.js.map +1 -1
- package/dist/src/manager/registry.js.map +1 -1
- package/dist/src/manager/routes/dashboard-memory.js.map +1 -1
- package/dist/src/manager/scan.js +36 -1
- package/dist/src/manager/scan.js.map +1 -1
- package/dist/src/manager/server.js +21 -2
- package/dist/src/manager/server.js.map +1 -1
- package/dist/src/manager/systemd-service.js +1 -1
- package/dist/src/manager/systemd-service.js.map +1 -1
- package/dist/src/memory/keyword-expand.js +0 -187
- package/dist/src/memory/keyword-expand.js.map +1 -1
- package/dist/src/memory/runtime.js +2 -2
- package/dist/src/memory/runtime.js.map +1 -1
- package/dist/src/memory/shared.js.map +1 -1
- package/dist/src/orchestrator/collect.js +3 -2
- package/dist/src/orchestrator/collect.js.map +1 -1
- package/dist/src/orchestrator/distribute.js +7 -1
- package/dist/src/orchestrator/distribute.js.map +1 -1
- package/dist/src/orchestrator/friction.js +59 -0
- package/dist/src/orchestrator/friction.js.map +1 -0
- package/dist/src/orchestrator/pipeline.js +88 -45
- package/dist/src/orchestrator/pipeline.js.map +1 -1
- package/dist/src/orchestrator/sanitize.js +19 -0
- package/dist/src/orchestrator/sanitize.js.map +1 -0
- package/dist/src/orchestrator/seed.js +50 -0
- package/dist/src/orchestrator/seed.js.map +1 -0
- package/dist/src/orchestrator/state-machine.js +206 -74
- package/dist/src/orchestrator/state-machine.js.map +1 -1
- package/dist/src/orchestrator/worker-monitor.js +1 -1
- package/dist/src/orchestrator/worker-monitor.js.map +1 -1
- package/dist/src/orchestrator/worker-progress.js +29 -0
- package/dist/src/orchestrator/worker-progress.js.map +1 -0
- package/dist/src/orchestrator/worker-registry.js +63 -2
- package/dist/src/orchestrator/worker-registry.js.map +1 -1
- package/dist/src/prompt/builder.js +19 -29
- package/dist/src/prompt/builder.js.map +1 -1
- package/dist/src/prompt/templates/a1-system.md +40 -5
- package/dist/src/prompt/templates/control-system.md +2 -2
- package/dist/src/prompt/templates/employee.md +4 -1
- package/dist/src/prompt/templates/orchestration.md +23 -8
- package/dist/src/routes/employees.js +4 -4
- package/dist/src/routes/employees.js.map +1 -1
- package/dist/src/routes/goal.js +11 -3
- package/dist/src/routes/goal.js.map +1 -1
- package/dist/src/routes/heartbeat.js +1 -1
- package/dist/src/routes/heartbeat.js.map +1 -1
- package/dist/src/routes/i18n.js +1 -1
- package/dist/src/routes/i18n.js.map +1 -1
- package/dist/src/routes/jaw-memory.js +1 -1
- package/dist/src/routes/jaw-memory.js.map +1 -1
- package/dist/src/routes/memory.js.map +1 -1
- package/dist/src/routes/messaging.js.map +1 -1
- package/dist/src/routes/orchestrate.js +265 -116
- package/dist/src/routes/orchestrate.js.map +1 -1
- package/dist/src/routes/quota-agy-reverse.js +0 -5
- package/dist/src/routes/quota-agy-reverse.js.map +1 -1
- package/dist/src/routes/quota-kiro-reverse.js +187 -0
- package/dist/src/routes/quota-kiro-reverse.js.map +1 -0
- package/dist/src/routes/settings.js +31 -2
- package/dist/src/routes/settings.js.map +1 -1
- package/dist/src/routes/skills.js.map +1 -1
- package/dist/src/security/security-audit-log.js.map +1 -1
- package/dist/src/shared/shell-command-display.js +51 -0
- package/dist/src/shared/shell-command-display.js.map +1 -0
- package/dist/src/telegram/bot.js.map +1 -1
- package/dist/src/trace/store.js +32 -0
- package/dist/src/trace/store.js.map +1 -1
- package/dist/src/types/cli-engine.js +1 -0
- package/dist/src/types/cli-engine.js.map +1 -1
- package/dist/src/workflows/employee-boundary.js +7 -7
- package/dist/src/workflows/employee-boundary.js.map +1 -1
- package/dist/src/workflows/handoff.js +16 -16
- package/dist/src/workflows/handoff.js.map +1 -1
- package/dist/src/workflows/scope-sandbox.js +46 -0
- package/dist/src/workflows/scope-sandbox.js.map +1 -0
- package/package.json +1 -1
- package/public/assets/providers/kiro-color.svg +15 -0
- package/public/assets/providers/kiro.svg +14 -0
- package/public/css/modals.css +79 -0
- package/public/css/sidebar.css +85 -0
- package/public/css/variables.css +2 -2
- package/public/dist/assets/{Agent-CIUGaUVn.js → Agent-DkH7eoHd.js} +1 -1
- package/public/dist/assets/{DocPanel-C1pGgE-S.js → DocPanel-BU16GUlB.js} +1 -1
- package/public/dist/assets/DocPanel-gU-WkgyA.css +1 -0
- package/public/dist/assets/Employees-F0ssNuO-.js +1 -0
- package/public/dist/assets/Heartbeat-C3JS6gkF.js +1 -0
- package/public/dist/assets/Mcp-_Yq4N3Sk.js +4 -0
- package/public/dist/assets/{Memory-BgN8djV4.js → Memory-C-EQubN2.js} +1 -1
- package/public/dist/assets/{ModelProvider-DHQ1Zvw0.js → ModelProvider-BD2KrypI.js} +1 -1
- package/public/dist/assets/agent-meta-B1098B_a.js +1 -0
- package/public/dist/assets/app-ByHYOMZE.js +48 -0
- package/public/dist/assets/app-CYdhP6Vh.css +1 -0
- package/public/dist/assets/constants-s2UJodER.js +1 -0
- package/public/dist/assets/{employees-DiNLzEXS.js → employees-_A-p_bZg.js} +7 -7
- package/public/dist/assets/idb-cache-0LNMskFB.js +1 -0
- package/public/dist/assets/idb-cache-5H89a4l8.js +1 -0
- package/public/dist/assets/{manager-DyrwJLZr.css → manager-B2qEQRxN.css} +1 -1
- package/public/dist/assets/manager-CR9BA-wO.js +12 -0
- package/public/dist/assets/memory-D1RKYvyu.js +1 -0
- package/public/dist/assets/{memory-B_nn0A4v.js → memory-D9AUn8fG.js} +9 -9
- package/public/dist/assets/{provider-icons-XEfJPGTe.js → provider-icons-CVVK5xUP.js} +35 -6
- package/public/dist/assets/{render-CgDEBoCX.js → render-DFBujF8n.js} +4 -4
- package/public/dist/assets/settings-B4ZkeaU-.js +1 -0
- package/public/dist/assets/settings-D9jTceN0.js +151 -0
- package/public/dist/assets/sidebar-DPPRNiTc.js +48 -0
- package/public/dist/assets/skills-8nHJkv-r.js +1 -0
- package/public/dist/assets/{skills-COa4iSwL.js → skills-BDVLIrVT.js} +6 -6
- package/public/dist/assets/{slash-commands-C_ePvrPi.js → slash-commands-C5da3q1p.js} +1 -1
- package/public/dist/assets/slash-commands-RJWO8wJZ.js +1 -0
- package/public/dist/assets/{trace-drawer-CY4z_Ie8.js → trace-drawer-5kqBzFMk.js} +1 -1
- package/public/dist/assets/ui-Crnp79bG.js +142 -0
- package/public/dist/assets/ui-HtSKByR3.js +1 -0
- package/public/dist/index.html +113 -86
- package/public/dist/manager/index.html +2 -2
- package/public/index.html +111 -84
- package/public/js/constants.ts +30 -7
- package/public/js/features/chat-search.ts +5 -1
- package/public/js/features/employees.ts +7 -2
- package/public/js/features/idb-cache.ts +4 -0
- package/public/js/features/message-history.ts +55 -7
- package/public/js/features/pending-queue.ts +8 -2
- package/public/js/features/process-block.ts +32 -17
- package/public/js/features/process-log-adapter.ts +11 -2
- package/public/js/features/settings-cli-status-render.ts +163 -0
- package/public/js/features/settings-cli-status.ts +130 -185
- package/public/js/features/settings-core.ts +5 -1
- package/public/js/features/settings-mcp.ts +513 -7
- package/public/js/features/settings.ts +1 -1
- package/public/js/features/tool-ui.ts +18 -4
- package/public/js/features/transport-status-row.ts +3 -0
- package/public/js/main.ts +3 -0
- package/public/js/preview-parent-origin.ts +14 -0
- package/public/js/provider-icons.ts +6 -1
- package/public/js/render/file-links.ts +10 -2
- package/public/js/ui.ts +5 -2
- package/public/js/virtual-scroll.ts +19 -0
- package/public/js/ws.ts +133 -8
- package/public/locales/en.json +8 -2
- package/public/locales/ja.json +8 -2
- package/public/locales/ko.json +8 -2
- package/public/locales/zh.json +8 -2
- package/public/manager/src/App.tsx +13 -70
- package/public/manager/src/InstancePreview.tsx +36 -11
- package/public/manager/src/SidebarRailRouter.tsx +1 -1
- package/public/manager/src/doc-panel/DocPanel.tsx +14 -1
- package/public/manager/src/doc-panel/doc-panel.css +16 -0
- package/public/manager/src/hooks/useInstanceMessageEvents.ts +4 -15
- package/public/manager/src/manager-components.css +1 -1
- package/public/manager/src/manager-polish.css +1 -1
- package/public/manager/src/manager-shortcut-runner.ts +107 -0
- package/public/manager/src/manager-shortcuts.ts +15 -0
- package/public/manager/src/panels/desktop-bridge.ts +2 -0
- package/public/manager/src/settings/SettingsSidebar.tsx +1 -1
- package/public/manager/src/settings/components/sidebar-filter.ts +2 -0
- package/public/manager/src/settings/pages/Mcp.tsx +311 -43
- package/public/manager/src/settings/pages/components/McpServerCard.tsx +89 -55
- package/public/manager/src/settings/pages/components/agent/agent-meta.ts +29 -6
- package/public/manager/src/settings/pages/components/employees-helpers.ts +1 -0
- package/public/manager/src/settings/pages/components/heartbeat-helpers.ts +1 -0
- package/public/manager/src/settings/pages/mcp-helpers.ts +54 -12
- package/public/manager/src/settings/types.ts +1 -0
- package/public/manager/src/types.ts +2 -1
- package/scripts/fresh-install-smoke.ts +1 -1
- package/public/dist/assets/DocPanel-CL1scIfq.css +0 -1
- package/public/dist/assets/Employees-BL9MAzzx.js +0 -1
- package/public/dist/assets/Heartbeat-D64JCg4t.js +0 -1
- package/public/dist/assets/Mcp-wYwJA_61.js +0 -3
- package/public/dist/assets/agent-meta-BhEbjy4P.js +0 -1
- package/public/dist/assets/app-2Rz848bQ.js +0 -48
- package/public/dist/assets/app-BW-Xz2p6.css +0 -1
- package/public/dist/assets/constants-ahKI_aEG.js +0 -1
- package/public/dist/assets/idb-cache-BnZfG5FD.js +0 -1
- package/public/dist/assets/idb-cache-CZ3JdK8r.js +0 -1
- package/public/dist/assets/manager-CfyZloIP.js +0 -12
- package/public/dist/assets/memory-CCjNFWmO.js +0 -1
- package/public/dist/assets/settings-CY_6tGuS.js +0 -1
- package/public/dist/assets/settings-DWW4GzNc.js +0 -66
- package/public/dist/assets/sidebar-DQKE5IA1.js +0 -23
- package/public/dist/assets/skills-DYTlqoke.js +0 -1
- package/public/dist/assets/slash-commands-D7CU5oso.js +0 -1
- package/public/dist/assets/ui-Car1OUvV.js +0 -1
- package/public/dist/assets/ui-DK_9ndj0.js +0 -140
|
@@ -6,63 +6,31 @@ import { state } from '../state.js';
|
|
|
6
6
|
import { ICONS } from '../icons.js';
|
|
7
7
|
import { providerIcon, providerLabel } from '../provider-icons.js';
|
|
8
8
|
import type { QuotaEntry } from './settings-types.js';
|
|
9
|
+
import {
|
|
10
|
+
buildAccountParts,
|
|
11
|
+
normalizeQuotaWindowLabel,
|
|
12
|
+
QUOTA_CUSTOM_MSG,
|
|
13
|
+
QUOTA_HIDDEN_CLIS,
|
|
14
|
+
QUOTA_SETUP_HINTS,
|
|
15
|
+
renderQuotaSetupBox,
|
|
16
|
+
renderSetupHelpMark,
|
|
17
|
+
} from './settings-cli-status-render.js';
|
|
18
|
+
|
|
19
|
+
export { normalizeQuotaWindowLabel } from './settings-cli-status-render.js';
|
|
9
20
|
|
|
10
21
|
const CLI_STATUS_INTERVAL_VALUES = new Set([0, 600, 1800]);
|
|
11
22
|
const DEFAULT_CLI_STATUS_INTERVAL_SEC = 0;
|
|
12
23
|
/** Defer heavy /api/quota so chat/history APIs win on initial page load. */
|
|
13
24
|
const QUOTA_LOAD_DEFER_MS = 2000;
|
|
25
|
+
const CLI_STATUS_REFRESH_DONE_CLEAR_MS = 4000;
|
|
14
26
|
|
|
15
|
-
|
|
16
|
-
const QUOTA_CUSTOM_MSG: Record<string, string> = {
|
|
17
|
-
claude: 'Currently subscribed, by June with credit',
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
type QuotaSetupHint = {
|
|
21
|
-
title: string;
|
|
22
|
-
commands: string[];
|
|
23
|
-
note?: string;
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
/** Actionable setup when plan quota is not wired yet (quotaCapable=false). */
|
|
27
|
-
const QUOTA_SETUP_HINTS: Record<string, QuotaSetupHint> = {
|
|
28
|
-
cursor: {
|
|
29
|
-
title: 'Enable quota bars (dashboard session)',
|
|
30
|
-
commands: [
|
|
31
|
-
'cursor-agent login',
|
|
32
|
-
'export CURSOR_SESSION_TOKEN="<WorkosCursorSessionToken from cursor.com DevTools>"',
|
|
33
|
-
'echo "$CURSOR_SESSION_TOKEN" > ~/.cli-jaw/quota/cursor-session-token && chmod 600 ~/.cli-jaw/quota/cursor-session-token',
|
|
34
|
-
],
|
|
35
|
-
},
|
|
36
|
-
agy: {
|
|
37
|
-
title: 'Enable Gem / Cla quota bars',
|
|
38
|
-
commands: [
|
|
39
|
-
'npx antigravity-usage login',
|
|
40
|
-
'npx antigravity-usage --json',
|
|
41
|
-
],
|
|
42
|
-
},
|
|
43
|
-
grok: {
|
|
44
|
-
title: 'Grok Build auth (plan quota not in grok CLI)',
|
|
45
|
-
commands: [
|
|
46
|
-
'grok login --oauth',
|
|
47
|
-
'grok models # verify auth',
|
|
48
|
-
],
|
|
49
|
-
note: 'Subscription remaining quota: xAI console only. No official grok quota subcommand.',
|
|
50
|
-
},
|
|
51
|
-
opencode: {
|
|
52
|
-
title: 'OpenCode auth + optional plan quota plugin',
|
|
53
|
-
commands: [
|
|
54
|
-
'opencode auth login',
|
|
55
|
-
'opencode plugin add @slkiser/opencode-quota',
|
|
56
|
-
'npx @slkiser/opencode-quota show',
|
|
57
|
-
],
|
|
58
|
-
note: 'Built-in opencode stats shows session tokens/cost, not subscription limits. opencode-go/* models use the same CLI.',
|
|
59
|
-
},
|
|
60
|
-
};
|
|
27
|
+
type CliStatusRefreshFeedback = 'idle' | 'refreshing' | 'success' | 'error';
|
|
61
28
|
|
|
62
29
|
let cliStatusTimer: number | null = null;
|
|
63
30
|
let cliStatusPreviewHooksRegistered = false;
|
|
64
31
|
let cliStatusLoadSeq = 0;
|
|
65
32
|
let cliStatusLoadInFlight: Promise<void> | null = null;
|
|
33
|
+
let cliStatusRefreshFeedbackTimer: number | null = null;
|
|
66
34
|
|
|
67
35
|
const CLI_STATUS_COLLAPSED_KEY = 'cliStatusCollapsed';
|
|
68
36
|
|
|
@@ -84,6 +52,47 @@ function saveCliStatusCollapsed(collapsed: boolean): void {
|
|
|
84
52
|
catch { /* ignore */ }
|
|
85
53
|
}
|
|
86
54
|
|
|
55
|
+
function formatCliStatusRefreshTime(date: Date): string {
|
|
56
|
+
return `${String(date.getHours()).padStart(2, '0')}:${String(date.getMinutes()).padStart(2, '0')}:${String(date.getSeconds()).padStart(2, '0')}`;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function clearCliStatusRefreshFeedbackTimer(): void {
|
|
60
|
+
if (cliStatusRefreshFeedbackTimer == null) return;
|
|
61
|
+
window.clearTimeout(cliStatusRefreshFeedbackTimer);
|
|
62
|
+
cliStatusRefreshFeedbackTimer = null;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function setCliStatusRefreshFeedback(kind: CliStatusRefreshFeedback, message = ''): void {
|
|
66
|
+
clearCliStatusRefreshFeedbackTimer();
|
|
67
|
+
|
|
68
|
+
const button = document.getElementById('cliStatusRefreshBtn') as HTMLButtonElement | null;
|
|
69
|
+
const status = document.getElementById('cliStatusRefreshState');
|
|
70
|
+
const label = button?.querySelector<HTMLElement>('.cli-refresh-label');
|
|
71
|
+
|
|
72
|
+
if (button) {
|
|
73
|
+
button.classList.remove('is-refreshing', 'is-success', 'is-error');
|
|
74
|
+
button.disabled = kind === 'refreshing';
|
|
75
|
+
if (kind === 'idle') button.removeAttribute('aria-busy');
|
|
76
|
+
else button.setAttribute('aria-busy', kind === 'refreshing' ? 'true' : 'false');
|
|
77
|
+
if (kind === 'refreshing') button.classList.add('is-refreshing');
|
|
78
|
+
if (kind === 'success') button.classList.add('is-success');
|
|
79
|
+
if (kind === 'error') button.classList.add('is-error');
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (label) label.textContent = kind === 'refreshing' ? 'Refreshing...' : 'Refresh';
|
|
83
|
+
if (status) {
|
|
84
|
+
status.textContent = message;
|
|
85
|
+
status.dataset['state'] = kind;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function finishCliStatusRefreshFeedback(kind: Exclude<CliStatusRefreshFeedback, 'idle' | 'refreshing'>, message: string): void {
|
|
90
|
+
setCliStatusRefreshFeedback(kind, message);
|
|
91
|
+
cliStatusRefreshFeedbackTimer = window.setTimeout(() => {
|
|
92
|
+
setCliStatusRefreshFeedback('idle');
|
|
93
|
+
}, CLI_STATUS_REFRESH_DONE_CLEAR_MS);
|
|
94
|
+
}
|
|
95
|
+
|
|
87
96
|
let cliStatusExpanded = !readCliStatusCollapsed();
|
|
88
97
|
|
|
89
98
|
export function isCliStatusExpanded(): boolean {
|
|
@@ -172,118 +181,6 @@ export function setCliStatusInterval(value: string): void {
|
|
|
172
181
|
scheduleCliStatusRefresh();
|
|
173
182
|
}
|
|
174
183
|
|
|
175
|
-
export function normalizeQuotaWindowLabel(cliName: string, label: string): string {
|
|
176
|
-
if (cliName === 'gemini') {
|
|
177
|
-
if (label === 'Pro' || label === 'P') return 'P';
|
|
178
|
-
if (label === 'Flash' || label === 'F') return 'F';
|
|
179
|
-
return label;
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
if (cliName === 'copilot') {
|
|
183
|
-
if (label === 'Premium' || label === 'Prem') return '30d';
|
|
184
|
-
if (label.includes('plus monthly subscriber quota')) return '30d';
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
return label
|
|
188
|
-
.replace('-hour', 'h')
|
|
189
|
-
.replace('-day', 'd')
|
|
190
|
-
.replace(' Sonnet', '')
|
|
191
|
-
.replace(' Opus', '');
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
function describeStatusOnlyQuota(cliName: string, q: QuotaEntry): string {
|
|
195
|
-
if (q.delegatedProvider) return `Delegates quota/status to ${q.delegatedProvider}`;
|
|
196
|
-
const match = q.quotaSource?.match(/^not-exposed-by-(.*?)-cli$/);
|
|
197
|
-
if (match) return `Quota not exposed by ${match[1].toUpperCase()} CLI`;
|
|
198
|
-
if (q.quotaSource) return q.quotaSource;
|
|
199
|
-
return cliName === 'opencode' ? 'Auth/status only' : 'Usage data not exposed by this CLI';
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
function normalizeAccountToken(value: string): string {
|
|
203
|
-
return value.toLowerCase().replace(/^cursor\s+/i, '').trim();
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
const ACCOUNT_LABEL_SKIP = new Set([
|
|
207
|
-
'auth/status only',
|
|
208
|
-
'google cloud code',
|
|
209
|
-
'runtime-checked',
|
|
210
|
-
]);
|
|
211
|
-
|
|
212
|
-
const PROVIDER_ACCOUNT_TYPES = new Set([
|
|
213
|
-
'cursor',
|
|
214
|
-
'antigravity.google',
|
|
215
|
-
'antigravity',
|
|
216
|
-
'max',
|
|
217
|
-
'copilot',
|
|
218
|
-
'gemini',
|
|
219
|
-
]);
|
|
220
|
-
|
|
221
|
-
function buildAccountParts(_cliName: string, q: QuotaEntry): string[] {
|
|
222
|
-
const account = q.account;
|
|
223
|
-
if (!account) return [];
|
|
224
|
-
|
|
225
|
-
const parts: string[] = [];
|
|
226
|
-
if (account.email) parts.push(account.email);
|
|
227
|
-
|
|
228
|
-
const seen = new Set(parts.map(normalizeAccountToken));
|
|
229
|
-
for (const value of [account.plan, account.tier]) {
|
|
230
|
-
if (!value) continue;
|
|
231
|
-
const norm = normalizeAccountToken(value);
|
|
232
|
-
if (!norm || ACCOUNT_LABEL_SKIP.has(norm)) continue;
|
|
233
|
-
if (PROVIDER_ACCOUNT_TYPES.has(norm)) continue;
|
|
234
|
-
if (seen.has(norm)) continue;
|
|
235
|
-
seen.add(norm);
|
|
236
|
-
parts.push(value);
|
|
237
|
-
break;
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
return parts;
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
function renderSetupHelpMark(cliName: string, q: QuotaEntry, extraTooltip: string[] = []): string {
|
|
244
|
-
const hint = QUOTA_SETUP_HINTS[cliName];
|
|
245
|
-
const tooltipParts = [
|
|
246
|
-
...extraTooltip,
|
|
247
|
-
...(hint ? hint.commands : []),
|
|
248
|
-
...(hint?.note ? [hint.note] : []),
|
|
249
|
-
].filter(Boolean);
|
|
250
|
-
if (!tooltipParts.length) return '';
|
|
251
|
-
return `<span style="cursor:help;opacity:0.55;margin-left:4px;font-weight:400" title="${escapeHtml(tooltipParts.join('\n'))}">?</span>`;
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
function renderQuotaSetupBox(cliName: string, q: QuotaEntry): string {
|
|
255
|
-
const hint = QUOTA_SETUP_HINTS[cliName];
|
|
256
|
-
const usage = q.sessionUsage;
|
|
257
|
-
const extraTooltip: string[] = [];
|
|
258
|
-
if (usage?.primaryModelId) extraTooltip.push(`Model: ${usage.primaryModelId}`);
|
|
259
|
-
if (usage?.contextTokensUsed && usage?.contextWindowTokens) {
|
|
260
|
-
extraTooltip.push(`Session context: ${Math.round(usage.contextTokensUsed).toLocaleString()} / ${Math.round(usage.contextWindowTokens).toLocaleString()} tokens`);
|
|
261
|
-
} else if (usage?.turnCount) {
|
|
262
|
-
extraTooltip.push(`Session turns: ${Math.round(usage.turnCount).toLocaleString()}`);
|
|
263
|
-
}
|
|
264
|
-
const helpMark = renderSetupHelpMark(cliName, q, extraTooltip);
|
|
265
|
-
|
|
266
|
-
if (hint) {
|
|
267
|
-
const commandLines = hint.commands.map(cmd => `
|
|
268
|
-
<div style="margin-top:3px"><code style="font-size:10px;background:var(--border);padding:1px 4px;border-radius:2px;word-break:break-all">${escapeHtml(cmd)}</code></div>
|
|
269
|
-
`).join('');
|
|
270
|
-
return `
|
|
271
|
-
<div style="font-size:10px;color:var(--text-dim);margin:4px 0 0 16px;padding:5px 7px;background:var(--surface);border:1px solid var(--border);border-radius:5px">
|
|
272
|
-
<div style="color:var(--text);font-weight:600">${escapeHtml(hint.title)}${helpMark}</div>
|
|
273
|
-
${commandLines}
|
|
274
|
-
${hint.note ? `<div style="margin-top:4px;opacity:0.75">${escapeHtml(hint.note)}</div>` : ''}
|
|
275
|
-
</div>
|
|
276
|
-
`;
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
return `
|
|
280
|
-
<div style="font-size:10px;color:var(--text-dim);margin:4px 0 0 16px;padding:5px 7px;background:var(--surface);border:1px solid var(--border);border-radius:5px">
|
|
281
|
-
<div style="color:var(--text);font-weight:600">${escapeHtml(q.displayTier || providerLabel(cliName))}${helpMark}</div>
|
|
282
|
-
<div style="margin-top:2px">${escapeHtml(describeStatusOnlyQuota(cliName, q))}</div>
|
|
283
|
-
</div>
|
|
284
|
-
`;
|
|
285
|
-
}
|
|
286
|
-
|
|
287
184
|
function scheduleEmbeddedQuotaRetry(
|
|
288
185
|
seq: number,
|
|
289
186
|
cliStatus: Record<string, { available: boolean }>,
|
|
@@ -305,9 +202,9 @@ async function fetchAndRenderQuota(
|
|
|
305
202
|
seq: number,
|
|
306
203
|
cliStatus: Record<string, { available: boolean }>,
|
|
307
204
|
cachedQuota: Record<string, QuotaEntry> | null | undefined,
|
|
308
|
-
): Promise<
|
|
205
|
+
): Promise<boolean> {
|
|
309
206
|
const quota = await api<Record<string, QuotaEntry>>('/api/quota');
|
|
310
|
-
if (seq !== cliStatusLoadSeq) return;
|
|
207
|
+
if (seq !== cliStatusLoadSeq) return false;
|
|
311
208
|
|
|
312
209
|
const resolvedQuota = quota ?? cachedQuota ?? null;
|
|
313
210
|
state.cliStatusCache = { cliStatus, quota: resolvedQuota } as Record<string, unknown>;
|
|
@@ -315,6 +212,7 @@ async function fetchAndRenderQuota(
|
|
|
315
212
|
renderCliStatus({ cliStatus, quota: resolvedQuota });
|
|
316
213
|
|
|
317
214
|
if (!quota) scheduleEmbeddedQuotaRetry(seq, cliStatus, cachedQuota);
|
|
215
|
+
return Boolean(quota);
|
|
318
216
|
}
|
|
319
217
|
|
|
320
218
|
function scheduleQuotaFetch(
|
|
@@ -322,17 +220,15 @@ function scheduleQuotaFetch(
|
|
|
322
220
|
seq: number,
|
|
323
221
|
cliStatus: Record<string, { available: boolean }>,
|
|
324
222
|
cachedQuota: Record<string, QuotaEntry> | null | undefined,
|
|
325
|
-
): void {
|
|
326
|
-
const run = () => { void fetchAndRenderQuota(seq, cliStatus, cachedQuota); };
|
|
327
|
-
if (force)
|
|
328
|
-
void fetchAndRenderQuota(seq, cliStatus, cachedQuota);
|
|
329
|
-
return;
|
|
330
|
-
}
|
|
223
|
+
): Promise<boolean> | void {
|
|
224
|
+
const run = () => { void fetchAndRenderQuota(seq, cliStatus, cachedQuota).catch(() => {}); };
|
|
225
|
+
if (force) return fetchAndRenderQuota(seq, cliStatus, cachedQuota);
|
|
331
226
|
window.setTimeout(run, QUOTA_LOAD_DEFER_MS);
|
|
332
227
|
}
|
|
333
228
|
|
|
334
229
|
export async function loadCliStatus(force = false): Promise<void> {
|
|
335
230
|
if (!cliStatusExpanded) return;
|
|
231
|
+
if (force) setCliStatusRefreshFeedback('refreshing', 'Refreshing quota...');
|
|
336
232
|
|
|
337
233
|
if (cliStatusLoadInFlight) {
|
|
338
234
|
if (force) await cliStatusLoadInFlight.catch(() => {});
|
|
@@ -341,29 +237,39 @@ export async function loadCliStatus(force = false): Promise<void> {
|
|
|
341
237
|
|
|
342
238
|
cliStatusLoadInFlight = (async () => {
|
|
343
239
|
const seq = ++cliStatusLoadSeq;
|
|
344
|
-
const interval = readCliStatusInterval();
|
|
345
|
-
if (!force && state.cliStatusCache && interval > 0 && (Date.now() - state.cliStatusTs) < interval * 1000) {
|
|
346
|
-
renderCliStatus({
|
|
347
|
-
cliStatus: (state.cliStatusCache as Record<string, unknown>)?.['cliStatus'] as Record<string, { available: boolean }> | null,
|
|
348
|
-
quota: (state.cliStatusCache as Record<string, unknown>)?.['quota'] as Record<string, QuotaEntry> | null,
|
|
349
|
-
});
|
|
350
|
-
return;
|
|
351
|
-
}
|
|
352
|
-
|
|
353
240
|
const el = document.getElementById('cliStatusList');
|
|
354
|
-
|
|
355
|
-
|
|
241
|
+
try {
|
|
242
|
+
const interval = readCliStatusInterval();
|
|
243
|
+
if (!force && state.cliStatusCache && interval > 0 && (Date.now() - state.cliStatusTs) < interval * 1000) {
|
|
244
|
+
renderCliStatus({
|
|
245
|
+
cliStatus: (state.cliStatusCache as Record<string, unknown>)?.['cliStatus'] as Record<string, { available: boolean }> | null,
|
|
246
|
+
quota: (state.cliStatusCache as Record<string, unknown>)?.['quota'] as Record<string, QuotaEntry> | null,
|
|
247
|
+
});
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
356
250
|
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
return;
|
|
362
|
-
|
|
251
|
+
const cachedQuota = (state.cliStatusCache as Record<string, unknown> | null)?.['quota'] as Record<string, QuotaEntry> | null | undefined;
|
|
252
|
+
if (el && !cachedQuota) el.innerHTML = '<div style="color:var(--text-dim);font-size:11px">Loading...</div>';
|
|
253
|
+
|
|
254
|
+
const cliStatus = await api<Record<string, { available: boolean }>>('/api/cli-status');
|
|
255
|
+
if (seq !== cliStatusLoadSeq) return;
|
|
256
|
+
if (!cliStatus || typeof cliStatus !== 'object') {
|
|
257
|
+
if (el) el.innerHTML = '<div style="color:var(--text-dim);font-size:11px">Failed to load CLI status</div>';
|
|
258
|
+
if (force) finishCliStatusRefreshFeedback('error', 'Refresh failed');
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
363
261
|
|
|
364
|
-
|
|
262
|
+
renderCliStatus({ cliStatus, quota: cachedQuota ?? null });
|
|
365
263
|
|
|
366
|
-
|
|
264
|
+
const quotaUpdated = await scheduleQuotaFetch(force, seq, cliStatus, cachedQuota);
|
|
265
|
+
if (force && seq === cliStatusLoadSeq) {
|
|
266
|
+
const verb = quotaUpdated ? 'Updated' : 'Checked';
|
|
267
|
+
finishCliStatusRefreshFeedback('success', `${verb} ${formatCliStatusRefreshTime(new Date())}`);
|
|
268
|
+
}
|
|
269
|
+
} catch {
|
|
270
|
+
if (el) el.innerHTML = '<div style="color:var(--text-dim);font-size:11px">Failed to load CLI status</div>';
|
|
271
|
+
if (force) finishCliStatusRefreshFeedback('error', 'Refresh failed');
|
|
272
|
+
}
|
|
367
273
|
})().finally(() => {
|
|
368
274
|
cliStatusLoadInFlight = null;
|
|
369
275
|
});
|
|
@@ -383,6 +289,7 @@ function renderCliStatus(data: { cliStatus: Record<string, { available: boolean
|
|
|
383
289
|
codex: { install: 'npm i -g @openai/codex', auth: 'codex login' },
|
|
384
290
|
'codex-app': { install: 'npm i -g @openai/codex', auth: 'codex login' },
|
|
385
291
|
cursor: { install: 'curl https://cursor.com/install -fsS | bash', auth: 'cursor-agent login, CURSOR_API_KEY, or CURSOR_SESSION_TOKEN for quota' },
|
|
292
|
+
'kiro-code': { install: 'Install Kiro CLI from https://kiro.dev/docs/cli', auth: 'kiro-cli login' },
|
|
386
293
|
gemini: { install: 'npm i -g @google/gemini-cli', auth: `gemini (${t('cli.gemini.auth')})` },
|
|
387
294
|
grok: { install: 'curl -fsSL https://x.ai/cli/install.sh | bash', auth: 'grok login --oauth' },
|
|
388
295
|
opencode: { install: 'npm i -g opencode-ai', auth: 'opencode auth' },
|
|
@@ -530,4 +437,42 @@ function renderCliStatus(data: { cliStatus: Record<string, { available: boolean
|
|
|
530
437
|
setTimeout(() => { btn.innerHTML = ICONS.key; btn.disabled = false; }, 2000);
|
|
531
438
|
});
|
|
532
439
|
}
|
|
440
|
+
|
|
441
|
+
// Bind CLI setup help ? buttons (rendered as data-cli-help)
|
|
442
|
+
if (el) {
|
|
443
|
+
el.querySelectorAll<HTMLButtonElement>('[data-cli-help]').forEach(btn => {
|
|
444
|
+
btn.addEventListener('click', (e) => {
|
|
445
|
+
e.stopPropagation();
|
|
446
|
+
const text = btn.getAttribute('data-cli-help') || '';
|
|
447
|
+
showCliHelpPopup(text);
|
|
448
|
+
});
|
|
449
|
+
});
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
function showCliHelpPopup(text: string): void {
|
|
454
|
+
const existing = document.getElementById('cliHelpOverlay');
|
|
455
|
+
if (existing) existing.remove();
|
|
456
|
+
|
|
457
|
+
const overlay = document.createElement('div');
|
|
458
|
+
overlay.id = 'cliHelpOverlay';
|
|
459
|
+
overlay.className = 'mcp-help-overlay';
|
|
460
|
+
overlay.addEventListener('click', (e) => { if (e.target === overlay) overlay.remove(); });
|
|
461
|
+
|
|
462
|
+
const inner = document.createElement('div');
|
|
463
|
+
inner.className = 'mcp-help-inner';
|
|
464
|
+
const lines = text.split('\n').filter(Boolean);
|
|
465
|
+
inner.innerHTML = `
|
|
466
|
+
<h4>CLI Setup</h4>
|
|
467
|
+
${lines.map(l => `<p><code>${l.replace(/&/g, '&').replace(/</g, '<')}</code></p>`).join('')}
|
|
468
|
+
<div style="text-align:right;margin-top:12px">
|
|
469
|
+
<button type="button" class="btn-save" id="cliHelpClose">OK</button>
|
|
470
|
+
</div>
|
|
471
|
+
`;
|
|
472
|
+
overlay.append(inner);
|
|
473
|
+
document.body.append(overlay);
|
|
474
|
+
inner.querySelector('#cliHelpClose')?.addEventListener('click', () => overlay.remove());
|
|
475
|
+
document.addEventListener('keydown', function esc(e) {
|
|
476
|
+
if (e.key === 'Escape') { overlay.remove(); document.removeEventListener('keydown', esc, true); }
|
|
477
|
+
}, true);
|
|
533
478
|
}
|
|
@@ -11,6 +11,7 @@ import { loadDiscordSettings } from './settings-discord.js';
|
|
|
11
11
|
import { loadActiveChannel, loadFallbackOrder } from './settings-channel.js';
|
|
12
12
|
import { loadMcpServers } from './settings-mcp.js';
|
|
13
13
|
import { providerIcon, providerLabel } from '../provider-icons.js';
|
|
14
|
+
import { postPreviewInvalidate } from '../preview-parent-origin.js';
|
|
14
15
|
|
|
15
16
|
let activeSettingsSave: Promise<void> | null = null;
|
|
16
17
|
|
|
@@ -336,6 +337,7 @@ export async function updateSettings(): Promise<void> {
|
|
|
336
337
|
selCli.dataset['prev'] = confirmedCli;
|
|
337
338
|
}
|
|
338
339
|
setHeaderCli(confirmedCli);
|
|
340
|
+
postPreviewInvalidate(['instances'], 'active-cli-changed');
|
|
339
341
|
})());
|
|
340
342
|
}
|
|
341
343
|
|
|
@@ -518,7 +520,9 @@ export async function saveActiveCliSettings(): Promise<void> {
|
|
|
518
520
|
if (effortEl && !effortEl.disabled) overrides[cli].effort = effortEl.value || '';
|
|
519
521
|
const patch: Record<string, unknown> = { activeOverrides: overrides };
|
|
520
522
|
if (cli === 'ai-e') patch['perCli'] = { 'ai-e': { provider: getSelectedAiEProvider() } };
|
|
521
|
-
await apiJson('/api/settings', 'PUT', patch)
|
|
523
|
+
if (await apiJson('/api/settings', 'PUT', patch)) {
|
|
524
|
+
postPreviewInvalidate(['instances'], 'active-cli-changed');
|
|
525
|
+
}
|
|
522
526
|
}
|
|
523
527
|
|
|
524
528
|
// ── Flush Agent Sidebar ──
|