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
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { api } from '../api.js';
|
|
2
2
|
import { getVirtualScroll } from '../virtual-scroll.js';
|
|
3
3
|
import { escapeHtml } from '../render.js';
|
|
4
|
+
import { bootMessageQuery } from './message-history.js';
|
|
4
5
|
|
|
5
6
|
const IS_IFRAME = window.parent !== window;
|
|
6
7
|
|
|
@@ -94,7 +95,10 @@ export function closeChatSearch(): void {
|
|
|
94
95
|
|
|
95
96
|
function buildMessageIndexMap(): void {
|
|
96
97
|
messageIdToVsIndex = new Map();
|
|
97
|
-
|
|
98
|
+
// Must mirror the rendered boot window so id→virtual-scroll index stays
|
|
99
|
+
// aligned with what loadMessages() actually rendered (embedded: recent-N;
|
|
100
|
+
// standalone: full history).
|
|
101
|
+
api<{ id: number }[]>(`/api/messages${bootMessageQuery()}`).then(msgs => {
|
|
98
102
|
if (!msgs) return;
|
|
99
103
|
messageIdToVsIndex = new Map();
|
|
100
104
|
msgs.forEach((m, i) => messageIdToVsIndex!.set(m.id, i));
|
|
@@ -53,8 +53,13 @@ function normalizeEmployeeModel(_cli: string, model?: string): string {
|
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
function getDefaultEmployeeModel(cli: string, models: string[]): string {
|
|
56
|
-
if (cli
|
|
57
|
-
|
|
56
|
+
if (cli === 'claude' || cli === 'claude-e') {
|
|
57
|
+
if (models.includes('claude-opus-4-8')) return 'claude-opus-4-8';
|
|
58
|
+
if (models.includes('opus')) return 'opus';
|
|
59
|
+
}
|
|
60
|
+
if (cli === 'codex' || cli === 'codex-app') {
|
|
61
|
+
if (models.includes('gpt-5.5')) return 'gpt-5.5';
|
|
62
|
+
}
|
|
58
63
|
return models[0] || 'default';
|
|
59
64
|
}
|
|
60
65
|
|
|
@@ -14,6 +14,10 @@ export function setMessageScope(scope: string): void {
|
|
|
14
14
|
localStorage.setItem(SCOPE_KEY, currentScope);
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
+
export function getMessageScope(): string {
|
|
18
|
+
return currentScope;
|
|
19
|
+
}
|
|
20
|
+
|
|
17
21
|
export interface CachedMessage {
|
|
18
22
|
id?: number;
|
|
19
23
|
role: string;
|
|
@@ -6,7 +6,7 @@ import { bootstrapVirtualHistory, type VirtualHistoryBootstrapDeps } from '../vi
|
|
|
6
6
|
import { activateWidgets } from '../diagram/iframe-renderer.js';
|
|
7
7
|
import { ICONS } from '../icons.js';
|
|
8
8
|
import { t } from './i18n.js';
|
|
9
|
-
import { cacheMessages, getScopedMessages, setMessageScope } from './idb-cache.js';
|
|
9
|
+
import { cacheMessages, getMessageScope, getScopedMessages, setMessageScope } from './idb-cache.js';
|
|
10
10
|
import { addMessage, addSystemMsg, showEmptyState } from './chat-messages.js';
|
|
11
11
|
import { buildLazyVirtualMessageItem } from './message-item-html.js';
|
|
12
12
|
import { addStep, buildProcessBlockHtml, collapseBlock, createProcessBlock } from './process-block.js';
|
|
@@ -19,6 +19,47 @@ export function buildVirtualHistoryItems(msgs: MessageItem[]): VirtualItem[] {
|
|
|
19
19
|
return msgs.map((m, index) => buildLazyVirtualMessageItem(normalizeMessageToolLog(m), index));
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
+
// Only the embedded dashboard preview frame remounts on every instance switch,
|
|
23
|
+
// so it fetches a bounded recent-N window to keep the per-remount payload small
|
|
24
|
+
// (the full all-time history was ~tens of MB). The standalone chat tab loads
|
|
25
|
+
// once and never remounts, so it keeps the full scrollable history — bounding it
|
|
26
|
+
// would silently drop access to older messages (no load-older mechanism exists).
|
|
27
|
+
export const BOOT_MESSAGE_LIMIT = 300;
|
|
28
|
+
|
|
29
|
+
export function bootMessageQuery(): string {
|
|
30
|
+
let embedded = true;
|
|
31
|
+
try { embedded = window.parent !== window; } catch { embedded = true; }
|
|
32
|
+
return embedded ? `?limit=${BOOT_MESSAGE_LIMIT}` : '';
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function normalizeMessageScopePart(value: string | null | undefined): string {
|
|
36
|
+
return String(value || '').trim() || 'unknown';
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function buildMessageLocationKey(input: { origin?: string; pathname?: string | null }): string {
|
|
40
|
+
const origin = normalizeMessageScopePart(input.origin);
|
|
41
|
+
const pathname = normalizeMessageScopePart(input.pathname || '/');
|
|
42
|
+
return `${origin}${pathname.startsWith('/') ? pathname : `/${pathname}`}`;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export function buildMessageScopeIdentity(input: { locationKey?: string; workingDir?: string | null }): string {
|
|
46
|
+
return `${normalizeMessageScopePart(input.locationKey)}::${normalizeMessageScopePart(input.workingDir)}`;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function readCurrentMessageLocationKey(): string {
|
|
50
|
+
if (typeof window === 'undefined') return buildMessageLocationKey({});
|
|
51
|
+
return buildMessageLocationKey({
|
|
52
|
+
origin: window.location.origin,
|
|
53
|
+
pathname: window.location.pathname,
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function readWorkingDirFromScope(scope: string): string | null {
|
|
58
|
+
if (!scope || scope === 'default') return null;
|
|
59
|
+
const markerIndex = scope.indexOf('::');
|
|
60
|
+
return markerIndex >= 0 ? scope.slice(markerIndex + 2) : scope;
|
|
61
|
+
}
|
|
62
|
+
|
|
22
63
|
export function registerVirtualScrollCallbacks(vs: ReturnType<typeof getVirtualScroll>): void {
|
|
23
64
|
vs.onLazyRender = (targets: HTMLElement[]) => {
|
|
24
65
|
for (const el of targets) {
|
|
@@ -89,25 +130,32 @@ function hydrateSmallHistory(messages: MessageItem[]): void {
|
|
|
89
130
|
export async function loadMessages(): Promise<void> {
|
|
90
131
|
const vs = getVirtualScroll();
|
|
91
132
|
const chatEl = document.getElementById('chatMessages');
|
|
133
|
+
const previousScope = getMessageScope();
|
|
134
|
+
const locationKey = readCurrentMessageLocationKey();
|
|
135
|
+
let workingDir = readWorkingDirFromScope(previousScope);
|
|
92
136
|
try {
|
|
93
137
|
const settings = await api<{ workingDir?: string }>('/api/settings');
|
|
94
|
-
if (settings?.workingDir)
|
|
138
|
+
if (settings?.workingDir) workingDir = settings.workingDir;
|
|
95
139
|
} catch { /* localStorage fallback already initialized currentScope */ }
|
|
96
|
-
const
|
|
140
|
+
const nextScope = buildMessageScopeIdentity({ locationKey, workingDir });
|
|
141
|
+
setMessageScope(nextScope);
|
|
142
|
+
const scopeChanged = nextScope !== previousScope;
|
|
143
|
+
const msgs = await api<MessageItem[]>(`/api/messages${bootMessageQuery()}`);
|
|
97
144
|
if (msgs !== null) {
|
|
98
145
|
const safeMsgs = msgs.map(normalizeMessageToolLog);
|
|
99
146
|
const hadRenderedHistory = Boolean(chatEl?.querySelector('.msg')) || vs.active;
|
|
100
|
-
const
|
|
147
|
+
const shouldForceBottom = scopeChanged || !hadRenderedHistory;
|
|
148
|
+
const savedIndex = !shouldForceBottom && vs.active ? vs.firstVisibleIndex() : null;
|
|
101
149
|
vs.clear();
|
|
102
150
|
if (chatEl) chatEl.innerHTML = '';
|
|
103
151
|
if (safeMsgs.length >= VS_THRESHOLD) {
|
|
104
152
|
bootstrapVirtualHistory(buildVirtualHistoryItems(safeMsgs), makeBootstrapDeps(vs, {
|
|
105
|
-
forceInitialBottom:
|
|
106
|
-
restoreIndex:
|
|
153
|
+
forceInitialBottom: shouldForceBottom,
|
|
154
|
+
restoreIndex: shouldForceBottom ? null : savedIndex,
|
|
107
155
|
}));
|
|
108
156
|
} else {
|
|
109
157
|
hydrateSmallHistory(safeMsgs);
|
|
110
|
-
if (
|
|
158
|
+
if (shouldForceBottom) settleChatBottomAfterInitialLoad();
|
|
111
159
|
}
|
|
112
160
|
cacheMessages(safeMsgs.map(m => ({
|
|
113
161
|
role: m.role, content: m.content, cli: m.cli ?? null, tool_log: m.tool_log ?? null, timestamp: Date.now(),
|
|
@@ -11,6 +11,7 @@ import { ICONS } from '../icons.js';
|
|
|
11
11
|
import { apiJson } from '../api.js';
|
|
12
12
|
import { t } from './i18n.js';
|
|
13
13
|
import { setStatus } from './ui-status.js';
|
|
14
|
+
import { syncOrchestrateSnapshot } from '../ws.js';
|
|
14
15
|
|
|
15
16
|
export interface PendingItem {
|
|
16
17
|
id: string;
|
|
@@ -144,8 +145,13 @@ async function fire(id: string, action: Action): Promise<void> {
|
|
|
144
145
|
if (action === 'steer') setStatus('running');
|
|
145
146
|
const result = await apiJson<{ pending: number }>(path, method, {});
|
|
146
147
|
if (result == null) {
|
|
147
|
-
|
|
148
|
-
|
|
148
|
+
// Item may have been processed by processQueue while arm was pending.
|
|
149
|
+
// Remove from UI regardless — snapshot sync will reconcile.
|
|
150
|
+
lastItems = lastItems.filter(it => it.id !== id);
|
|
151
|
+
renderPendingQueue(lastItems);
|
|
152
|
+
if (action === 'steer') {
|
|
153
|
+
syncOrchestrateSnapshot('steer-fire-miss').catch(() => {});
|
|
154
|
+
}
|
|
149
155
|
return;
|
|
150
156
|
}
|
|
151
157
|
lastItems = lastItems.filter(it => it.id !== id);
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { escapeHtml } from '../render.js';
|
|
2
2
|
import { ICONS } from '../icons.js';
|
|
3
|
+
import {
|
|
4
|
+
displayShellCommand,
|
|
5
|
+
displayShellCommandDetail,
|
|
6
|
+
} from '../../../src/shared/shell-command-display.js';
|
|
3
7
|
|
|
4
8
|
declare global {
|
|
5
9
|
interface Window {
|
|
@@ -107,36 +111,47 @@ export function getStoredProcessStepDetail(stepId: string): string {
|
|
|
107
111
|
return processDetailStore.get(stepId)?.detail || '';
|
|
108
112
|
}
|
|
109
113
|
|
|
114
|
+
function normalizeProcessStepForDisplay(step: ProcessStep): ProcessStep {
|
|
115
|
+
if (step.type !== 'tool') return step;
|
|
116
|
+
return {
|
|
117
|
+
...step,
|
|
118
|
+
label: displayShellCommand(step.label || ''),
|
|
119
|
+
detail: displayShellCommandDetail(step.detail || ''),
|
|
120
|
+
detailPreview: step.detailPreview ? displayShellCommandDetail(step.detailPreview) : step.detailPreview,
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
|
|
110
124
|
export function compactProcessStepForStorage(step: ProcessStep): ProcessStep {
|
|
111
|
-
const
|
|
112
|
-
const
|
|
125
|
+
const displayStep = normalizeProcessStepForDisplay(step);
|
|
126
|
+
const storedDetail = displayShellCommandDetail(getStoredProcessStepDetail(displayStep.id));
|
|
127
|
+
const fullDetail = storedDetail || displayStep.detail || '';
|
|
113
128
|
const retained = retainedDetail(fullDetail);
|
|
114
|
-
const preview =
|
|
129
|
+
const preview = displayStep.detailPreview || previewText(fullDetail, PROCESS_DETAIL_PREVIEW_CHARS);
|
|
115
130
|
if (fullDetail) {
|
|
116
|
-
processDetailStore.set(
|
|
131
|
+
processDetailStore.set(displayStep.id, {
|
|
117
132
|
detail: retained.detail,
|
|
118
133
|
originalLength: fullDetail.length,
|
|
119
134
|
truncated: retained.truncated,
|
|
120
135
|
});
|
|
121
136
|
}
|
|
122
|
-
processStepMetaStore.set(
|
|
123
|
-
id:
|
|
124
|
-
type:
|
|
125
|
-
icon:
|
|
126
|
-
rawIcon:
|
|
127
|
-
label:
|
|
128
|
-
isEmployee:
|
|
129
|
-
stepRef:
|
|
130
|
-
traceRunId:
|
|
131
|
-
detailBytes:
|
|
132
|
-
status:
|
|
133
|
-
startTime:
|
|
137
|
+
processStepMetaStore.set(displayStep.id, {
|
|
138
|
+
id: displayStep.id,
|
|
139
|
+
type: displayStep.type,
|
|
140
|
+
icon: displayStep.icon,
|
|
141
|
+
rawIcon: displayStep.rawIcon,
|
|
142
|
+
label: displayStep.label,
|
|
143
|
+
isEmployee: displayStep.isEmployee,
|
|
144
|
+
stepRef: displayStep.stepRef,
|
|
145
|
+
traceRunId: displayStep.traceRunId, traceSeq: displayStep.traceSeq, detailAvailable: displayStep.detailAvailable,
|
|
146
|
+
detailBytes: displayStep.detailBytes, rawRetentionStatus: displayStep.rawRetentionStatus,
|
|
147
|
+
status: displayStep.status,
|
|
148
|
+
startTime: displayStep.startTime,
|
|
134
149
|
preview,
|
|
135
150
|
detailLength: fullDetail.length,
|
|
136
151
|
detailTruncated: retained.truncated,
|
|
137
152
|
});
|
|
138
153
|
return {
|
|
139
|
-
...
|
|
154
|
+
...displayStep,
|
|
140
155
|
detail: preview,
|
|
141
156
|
detailPreview: preview,
|
|
142
157
|
detailLength: fullDetail.length,
|
|
@@ -5,6 +5,10 @@ import {
|
|
|
5
5
|
sanitizeToolLogForDurableStorage,
|
|
6
6
|
serializeSanitizedToolLog,
|
|
7
7
|
} from '../../../src/shared/tool-log-sanitize.js';
|
|
8
|
+
import {
|
|
9
|
+
displayShellCommand,
|
|
10
|
+
displayShellCommandDetail,
|
|
11
|
+
} from '../../../src/shared/shell-command-display.js';
|
|
8
12
|
import type { ProcessStep } from './process-block.js';
|
|
9
13
|
import type { ToolLogEntry } from './tool-ui.js';
|
|
10
14
|
|
|
@@ -28,6 +32,11 @@ function fallbackToolLabel(tool: ToolLogEntry): string {
|
|
|
28
32
|
return typeof named.name === 'string' && named.name ? named.name : 'tool';
|
|
29
33
|
}
|
|
30
34
|
|
|
35
|
+
function displayToolLabel(tool: ToolLogEntry): string {
|
|
36
|
+
const label = fallbackToolLabel(tool);
|
|
37
|
+
return tool.toolType === 'tool' ? displayShellCommand(label) : label;
|
|
38
|
+
}
|
|
39
|
+
|
|
31
40
|
export function parseToolLog(toolLog?: string | null): ToolLogEntry[] {
|
|
32
41
|
return parseToolLogBounded(toolLog) as ToolLogEntry[];
|
|
33
42
|
}
|
|
@@ -47,10 +56,10 @@ export function toProcessSteps(tools: ToolLogEntry[], runStartedAt?: number): Pr
|
|
|
47
56
|
id: generateId(),
|
|
48
57
|
icon: tool.icon ? emojiToIcon(tool.icon) : ICONS.tool,
|
|
49
58
|
rawIcon: tool.rawIcon || tool.icon || '',
|
|
50
|
-
label:
|
|
59
|
+
label: displayToolLabel(tool),
|
|
51
60
|
isEmployee: tool.isEmployee === true,
|
|
52
61
|
type: processStepType(tool.toolType),
|
|
53
|
-
detail: tool.detail || '',
|
|
62
|
+
detail: tool.toolType === 'tool' ? displayShellCommandDetail(tool.detail || '') : tool.detail || '',
|
|
54
63
|
stepRef: tool.stepRef || '',
|
|
55
64
|
traceRunId: tool.traceRunId || '',
|
|
56
65
|
traceSeq: tool.traceSeq,
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import { escapeHtml } from '../render.js';
|
|
2
|
+
import { providerLabel } from '../provider-icons.js';
|
|
3
|
+
import { t } from './i18n.js';
|
|
4
|
+
import type { QuotaEntry } from './settings-types.js';
|
|
5
|
+
|
|
6
|
+
type QuotaSetupHint = {
|
|
7
|
+
title: string;
|
|
8
|
+
commands: string[];
|
|
9
|
+
note?: string;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export const QUOTA_HIDDEN_CLIS = new Set(['ai-e', 'codex-app']);
|
|
13
|
+
export const QUOTA_CUSTOM_MSG: Record<string, string> = {
|
|
14
|
+
claude: 'Currently subscribed, by June with credit',
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export const QUOTA_SETUP_HINTS: Record<string, QuotaSetupHint> = {
|
|
18
|
+
cursor: {
|
|
19
|
+
title: 'Enable quota bars (dashboard session)',
|
|
20
|
+
commands: [
|
|
21
|
+
'cursor-agent login',
|
|
22
|
+
'export CURSOR_SESSION_TOKEN="<WorkosCursorSessionToken from cursor.com DevTools>"',
|
|
23
|
+
'echo "$CURSOR_SESSION_TOKEN" > ~/.cli-jaw/quota/cursor-session-token && chmod 600 ~/.cli-jaw/quota/cursor-session-token',
|
|
24
|
+
],
|
|
25
|
+
},
|
|
26
|
+
agy: {
|
|
27
|
+
title: 'Enable Gem / Cla quota bars',
|
|
28
|
+
commands: [
|
|
29
|
+
'npx antigravity-usage login',
|
|
30
|
+
'npx antigravity-usage --json',
|
|
31
|
+
],
|
|
32
|
+
},
|
|
33
|
+
grok: {
|
|
34
|
+
title: 'Grok Build auth (plan quota not in grok CLI)',
|
|
35
|
+
commands: [
|
|
36
|
+
'grok login --oauth',
|
|
37
|
+
'grok models # verify auth',
|
|
38
|
+
],
|
|
39
|
+
note: 'Subscription remaining quota: xAI console only. No official grok quota subcommand.',
|
|
40
|
+
},
|
|
41
|
+
opencode: {
|
|
42
|
+
title: 'OpenCode auth + optional plan quota plugin',
|
|
43
|
+
commands: [
|
|
44
|
+
'opencode auth login',
|
|
45
|
+
'opencode plugin add @slkiser/opencode-quota',
|
|
46
|
+
'npx @slkiser/opencode-quota show',
|
|
47
|
+
],
|
|
48
|
+
note: 'Built-in opencode stats shows session tokens/cost, not subscription limits. opencode-go/* models use the same CLI.',
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
export function normalizeQuotaWindowLabel(cliName: string, label: string): string {
|
|
53
|
+
if (cliName === 'gemini') {
|
|
54
|
+
if (label === 'Pro' || label === 'P') return 'P';
|
|
55
|
+
if (label === 'Flash' || label === 'F') return 'F';
|
|
56
|
+
return label;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (cliName === 'copilot') {
|
|
60
|
+
if (label === 'Premium' || label === 'Prem') return '30d';
|
|
61
|
+
if (label.includes('plus monthly subscriber quota')) return '30d';
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return label
|
|
65
|
+
.replace('-hour', 'h')
|
|
66
|
+
.replace('-day', 'd')
|
|
67
|
+
.replace(' Sonnet', '')
|
|
68
|
+
.replace(' Opus', '');
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export function describeStatusOnlyQuota(cliName: string, q: QuotaEntry): string {
|
|
72
|
+
if (q.delegatedProvider) return `Delegates quota/status to ${q.delegatedProvider}`;
|
|
73
|
+
const match = q.quotaSource?.match(/^not-exposed-by-(.*?)-cli$/);
|
|
74
|
+
if (match) return `Quota not exposed by ${match[1].toUpperCase()} CLI`;
|
|
75
|
+
if (q.quotaSource) return q.quotaSource;
|
|
76
|
+
return cliName === 'opencode' ? 'Auth/status only' : 'Usage data not exposed by this CLI';
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function normalizeAccountToken(value: string): string {
|
|
80
|
+
return value.toLowerCase().replace(/^cursor\s+/i, '').trim();
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export const ACCOUNT_LABEL_SKIP = new Set([
|
|
84
|
+
'auth/status only',
|
|
85
|
+
'google cloud code',
|
|
86
|
+
'runtime-checked',
|
|
87
|
+
]);
|
|
88
|
+
|
|
89
|
+
export const PROVIDER_ACCOUNT_TYPES = new Set([
|
|
90
|
+
'cursor',
|
|
91
|
+
'antigravity.google',
|
|
92
|
+
'antigravity',
|
|
93
|
+
'max',
|
|
94
|
+
'copilot',
|
|
95
|
+
'gemini',
|
|
96
|
+
]);
|
|
97
|
+
|
|
98
|
+
export function buildAccountParts(_cliName: string, q: QuotaEntry): string[] {
|
|
99
|
+
const account = q.account;
|
|
100
|
+
if (!account) return [];
|
|
101
|
+
|
|
102
|
+
const parts: string[] = [];
|
|
103
|
+
if (account.email) parts.push(account.email);
|
|
104
|
+
|
|
105
|
+
const seen = new Set(parts.map(normalizeAccountToken));
|
|
106
|
+
for (const value of [account.plan, account.tier]) {
|
|
107
|
+
if (!value) continue;
|
|
108
|
+
const norm = normalizeAccountToken(value);
|
|
109
|
+
if (!norm || ACCOUNT_LABEL_SKIP.has(norm)) continue;
|
|
110
|
+
if (PROVIDER_ACCOUNT_TYPES.has(norm)) continue;
|
|
111
|
+
if (seen.has(norm)) continue;
|
|
112
|
+
seen.add(norm);
|
|
113
|
+
parts.push(value);
|
|
114
|
+
break;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return parts;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export function renderSetupHelpMark(cliName: string, q: QuotaEntry, extraTooltip: string[] = []): string {
|
|
121
|
+
const hint = QUOTA_SETUP_HINTS[cliName];
|
|
122
|
+
const tooltipParts = [
|
|
123
|
+
...extraTooltip,
|
|
124
|
+
...(hint ? hint.commands : []),
|
|
125
|
+
...(hint?.note ? [hint.note] : []),
|
|
126
|
+
].filter(Boolean);
|
|
127
|
+
if (!tooltipParts.length) return '';
|
|
128
|
+
const tooltip = escapeHtml(tooltipParts.join('\n'));
|
|
129
|
+
return `<button type="button" class="help-trigger" style="margin-left:4px" data-cli-help="${tooltip}" aria-label="Setup help">?</button>`;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export function renderQuotaSetupBox(cliName: string, q: QuotaEntry): string {
|
|
133
|
+
const hint = QUOTA_SETUP_HINTS[cliName];
|
|
134
|
+
const usage = q.sessionUsage;
|
|
135
|
+
const extraTooltip: string[] = [];
|
|
136
|
+
if (usage?.primaryModelId) extraTooltip.push(`Model: ${usage.primaryModelId}`);
|
|
137
|
+
if (usage?.contextTokensUsed && usage?.contextWindowTokens) {
|
|
138
|
+
extraTooltip.push(`Session context: ${Math.round(usage.contextTokensUsed).toLocaleString()} / ${Math.round(usage.contextWindowTokens).toLocaleString()} tokens`);
|
|
139
|
+
} else if (usage?.turnCount) {
|
|
140
|
+
extraTooltip.push(`Session turns: ${Math.round(usage.turnCount).toLocaleString()}`);
|
|
141
|
+
}
|
|
142
|
+
const helpMark = renderSetupHelpMark(cliName, q, extraTooltip);
|
|
143
|
+
|
|
144
|
+
if (hint) {
|
|
145
|
+
const commandLines = hint.commands.map(cmd => `
|
|
146
|
+
<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>
|
|
147
|
+
`).join('');
|
|
148
|
+
return `
|
|
149
|
+
<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">
|
|
150
|
+
<div style="color:var(--text);font-weight:600">${escapeHtml(hint.title)}${helpMark}</div>
|
|
151
|
+
${commandLines}
|
|
152
|
+
${hint.note ? `<div style="margin-top:4px;opacity:0.75">${escapeHtml(hint.note)}</div>` : ''}
|
|
153
|
+
</div>
|
|
154
|
+
`;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
return `
|
|
158
|
+
<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">
|
|
159
|
+
<div style="color:var(--text);font-weight:600">${escapeHtml(q.displayTier || providerLabel(cliName))}${helpMark}</div>
|
|
160
|
+
<div style="margin-top:2px">${escapeHtml(describeStatusOnlyQuota(cliName, q))}</div>
|
|
161
|
+
</div>
|
|
162
|
+
`;
|
|
163
|
+
}
|