cli-jaw 1.4.11 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.ko.md +56 -26
- package/README.md +30 -24
- package/README.zh-CN.md +56 -26
- package/dist/bin/commands/browser.js +3 -1
- package/dist/bin/commands/browser.js.map +1 -1
- package/dist/bin/commands/chat.js +358 -9
- package/dist/bin/commands/chat.js.map +1 -1
- package/dist/bin/commands/doctor.js +80 -2
- package/dist/bin/commands/doctor.js.map +1 -1
- package/dist/bin/commands/init.js +88 -6
- package/dist/bin/commands/init.js.map +1 -1
- package/dist/bin/commands/serve.js +1 -0
- package/dist/bin/commands/serve.js.map +1 -1
- package/dist/lib/mcp-sync.js +101 -51
- package/dist/lib/mcp-sync.js.map +1 -1
- package/dist/lib/quota-copilot.js +4 -0
- package/dist/lib/quota-copilot.js.map +1 -1
- package/dist/server.js +131 -35
- package/dist/server.js.map +1 -1
- package/dist/src/agent/events.js +198 -29
- package/dist/src/agent/events.js.map +1 -1
- package/dist/src/agent/smoke-detector.js +111 -0
- package/dist/src/agent/smoke-detector.js.map +1 -0
- package/dist/src/agent/spawn.js +157 -26
- package/dist/src/agent/spawn.js.map +1 -1
- package/dist/src/browser/connection.js +9 -1
- package/dist/src/browser/connection.js.map +1 -1
- package/dist/src/browser/launch-policy.js +32 -0
- package/dist/src/browser/launch-policy.js.map +1 -0
- package/dist/src/cli/claude-models.js +46 -0
- package/dist/src/cli/claude-models.js.map +1 -0
- package/dist/src/cli/command-context.js +19 -8
- package/dist/src/cli/command-context.js.map +1 -1
- package/dist/src/cli/commands.js +16 -13
- package/dist/src/cli/commands.js.map +1 -1
- package/dist/src/cli/compact.js +93 -0
- package/dist/src/cli/compact.js.map +1 -0
- package/dist/src/cli/handlers.js +94 -32
- package/dist/src/cli/handlers.js.map +1 -1
- package/dist/src/cli/readiness.js +69 -0
- package/dist/src/cli/readiness.js.map +1 -0
- package/dist/src/cli/registry.js +3 -2
- package/dist/src/cli/registry.js.map +1 -1
- package/dist/src/cli/tui/composer.js +6 -4
- package/dist/src/cli/tui/composer.js.map +1 -1
- package/dist/src/cli/tui/keymap.js +2 -0
- package/dist/src/cli/tui/keymap.js.map +1 -1
- package/dist/src/cli/tui/overlay.js +170 -0
- package/dist/src/cli/tui/overlay.js.map +1 -1
- package/dist/src/cli/tui/store.js +25 -0
- package/dist/src/cli/tui/store.js.map +1 -1
- package/dist/src/cli/tui/transcript.js +46 -0
- package/dist/src/cli/tui/transcript.js.map +1 -0
- package/dist/src/command-contract/catalog.js +8 -4
- package/dist/src/command-contract/catalog.js.map +1 -1
- package/dist/src/core/bus.js +1 -0
- package/dist/src/core/bus.js.map +1 -1
- package/dist/src/core/compact.js +70 -0
- package/dist/src/core/compact.js.map +1 -0
- package/dist/src/core/config.js +109 -3
- package/dist/src/core/config.js.map +1 -1
- package/dist/src/core/db.js +13 -4
- package/dist/src/core/db.js.map +1 -1
- package/dist/src/core/main-session.js +15 -0
- package/dist/src/core/main-session.js.map +1 -1
- package/dist/src/core/runtime-settings.js +19 -4
- package/dist/src/core/runtime-settings.js.map +1 -1
- package/dist/src/core/settings-merge.js +1 -1
- package/dist/src/core/settings-merge.js.map +1 -1
- package/dist/src/discord/bot.js +274 -0
- package/dist/src/discord/bot.js.map +1 -0
- package/dist/src/discord/commands.js +103 -0
- package/dist/src/discord/commands.js.map +1 -0
- package/dist/src/discord/discord-file.js +43 -0
- package/dist/src/discord/discord-file.js.map +1 -0
- package/dist/src/discord/forwarder.js +45 -0
- package/dist/src/discord/forwarder.js.map +1 -0
- package/dist/src/memory/bootstrap.js +341 -0
- package/dist/src/memory/bootstrap.js.map +1 -0
- package/dist/src/memory/heartbeat.js +11 -22
- package/dist/src/memory/heartbeat.js.map +1 -1
- package/dist/src/memory/indexing.js +329 -0
- package/dist/src/memory/indexing.js.map +1 -0
- package/dist/src/memory/keyword-expand.js +247 -0
- package/dist/src/memory/keyword-expand.js.map +1 -0
- package/dist/src/memory/runtime.js +56 -1090
- package/dist/src/memory/runtime.js.map +1 -1
- package/dist/src/memory/shared.js +167 -0
- package/dist/src/memory/shared.js.map +1 -0
- package/dist/src/messaging/runtime.js +122 -0
- package/dist/src/messaging/runtime.js.map +1 -0
- package/dist/src/messaging/send.js +120 -0
- package/dist/src/messaging/send.js.map +1 -0
- package/dist/src/messaging/session-key.js +25 -0
- package/dist/src/messaging/session-key.js.map +1 -0
- package/dist/src/messaging/types.js +6 -0
- package/dist/src/messaging/types.js.map +1 -0
- package/dist/src/orchestrator/collect.js +5 -0
- package/dist/src/orchestrator/collect.js.map +1 -1
- package/dist/src/orchestrator/distribute.js +34 -8
- package/dist/src/orchestrator/distribute.js.map +1 -1
- package/dist/src/orchestrator/gateway.js +18 -12
- package/dist/src/orchestrator/gateway.js.map +1 -1
- package/dist/src/orchestrator/parser.js +0 -28
- package/dist/src/orchestrator/parser.js.map +1 -1
- package/dist/src/orchestrator/pipeline.js +94 -75
- package/dist/src/orchestrator/pipeline.js.map +1 -1
- package/dist/src/orchestrator/state-machine.js +23 -20
- package/dist/src/orchestrator/state-machine.js.map +1 -1
- package/dist/src/orchestrator/worker-monitor.js +50 -0
- package/dist/src/orchestrator/worker-monitor.js.map +1 -0
- package/dist/src/orchestrator/worker-registry.js +107 -0
- package/dist/src/orchestrator/worker-registry.js.map +1 -0
- package/dist/src/prompt/builder.js +78 -6
- package/dist/src/prompt/builder.js.map +1 -1
- package/dist/src/prompt/templates/a1-system.md +52 -10
- package/dist/src/prompt/templates/employee.md +17 -5
- package/dist/src/prompt/templates/orchestration.md +11 -10
- package/dist/src/prompt/templates/research-worker.md +1 -1
- package/dist/src/prompt/templates/worker-context.md +4 -4
- package/dist/src/routes/browser.js +14 -3
- package/dist/src/routes/browser.js.map +1 -1
- package/dist/src/telegram/bot.js +92 -8
- package/dist/src/telegram/bot.js.map +1 -1
- package/dist/src/types/agent.js +4 -0
- package/dist/src/types/agent.js.map +1 -0
- package/package.json +27 -15
- package/public/css/chat.css +365 -127
- package/public/css/layout.css +67 -10
- package/public/css/markdown.css +219 -54
- package/public/css/modals.css +35 -15
- package/public/css/orc-state.css +16 -16
- package/public/css/sidebar.css +12 -12
- package/public/css/tool-ui.css +483 -0
- package/public/css/variables.css +334 -6
- package/public/dist/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
- package/public/dist/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
- package/public/dist/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
- package/public/dist/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
- package/public/dist/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
- package/public/dist/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
- package/public/dist/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
- package/public/dist/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
- package/public/dist/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
- package/public/dist/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
- package/public/dist/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
- package/public/dist/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
- package/public/dist/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
- package/public/dist/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
- package/public/dist/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
- package/public/dist/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
- package/public/dist/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
- package/public/dist/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
- package/public/dist/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
- package/public/dist/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
- package/public/dist/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
- package/public/dist/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
- package/public/dist/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
- package/public/dist/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
- package/public/dist/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
- package/public/dist/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
- package/public/dist/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
- package/public/dist/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
- package/public/dist/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
- package/public/dist/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
- package/public/dist/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
- package/public/dist/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
- package/public/dist/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
- package/public/dist/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
- package/public/dist/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
- package/public/dist/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
- package/public/dist/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
- package/public/dist/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
- package/public/dist/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
- package/public/dist/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
- package/public/dist/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
- package/public/dist/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
- package/public/dist/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
- package/public/dist/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
- package/public/dist/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
- package/public/dist/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
- package/public/dist/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
- package/public/dist/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
- package/public/dist/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
- package/public/dist/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
- package/public/dist/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
- package/public/dist/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
- package/public/dist/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
- package/public/dist/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
- package/public/dist/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
- package/public/dist/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
- package/public/dist/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
- package/public/dist/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
- package/public/dist/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
- package/public/dist/assets/api-B8XKQ4OT.js +1 -0
- package/public/dist/assets/api-BlPw3bUI.js +1 -0
- package/public/dist/assets/architecture-YZFGNWBL-BkS7SZQi.js +1 -0
- package/public/dist/assets/architectureDiagram-Q4EWVU46-Dl3iBKeR.js +1 -0
- package/public/dist/assets/blockDiagram-DXYQGD6D-DPr4D17p.js +1 -0
- package/public/dist/assets/c4Diagram-AHTNJAMY-CfoxJtDk.js +1 -0
- package/public/dist/assets/classDiagram-6PBFFD2Q-BOAdHnnB.js +1 -0
- package/public/dist/assets/classDiagram-v2-HSJHXN6E-B2QCJXWC.js +1 -0
- package/public/dist/assets/constants-DshMUJbo.js +1 -0
- package/public/dist/assets/cose-bilkent-S5V4N54A-CA14jk7w.js +1 -0
- package/public/dist/assets/dagre-KV5264BT-BVwNaSwC.js +1 -0
- package/public/dist/assets/diagram-5BDNPKRD-CHqIAvdc.js +1 -0
- package/public/dist/assets/diagram-G4DWMVQ6-DxvsCvTP.js +1 -0
- package/public/dist/assets/diagram-MMDJMWI5-DqOPO7dl.js +1 -0
- package/public/dist/assets/diagram-TYMM5635-C9xMWPQn.js +1 -0
- package/public/dist/assets/employees-CFRlsbHm.js +39 -0
- package/public/dist/assets/erDiagram-SMLLAGMA-BTmpfRkm.js +1 -0
- package/public/dist/assets/flowDiagram-DWJPFMVM-DZBSQAKA.js +1 -0
- package/public/dist/assets/ganttDiagram-T4ZO3ILL-TAEMCRbT.js +1 -0
- package/public/dist/assets/gitGraph-7Q5UKJZL-bbxndRNA.js +1 -0
- package/public/dist/assets/gitGraphDiagram-UUTBAWPF-CBxtx0MB.js +1 -0
- package/public/dist/assets/icon-192-CwXPIYF5.png +0 -0
- package/public/dist/assets/index-1Gg-6jeC.css +1 -0
- package/public/dist/assets/index-CQHqXjrK.js +49 -0
- package/public/dist/assets/info-OMHHGYJF-DRXq_Ywr.js +1 -0
- package/public/dist/assets/infoDiagram-42DDH7IO-C7FFwX4m.js +1 -0
- package/public/dist/assets/ishikawaDiagram-UXIWVN3A-DEZJE79j.js +1 -0
- package/public/dist/assets/journeyDiagram-VCZTEJTY-ZHLiY6GV.js +1 -0
- package/public/dist/assets/kanban-definition-6JOO6SKY-NP7pY7ML.js +1 -0
- package/public/dist/assets/katex-DZLS_HFU.js +1 -0
- package/public/dist/assets/locale-BjoAcbis.js +1 -0
- package/public/dist/assets/manifest-Bw-LRm-c.json +20 -0
- package/public/dist/assets/mermaid.core-CHuluSlD.js +1 -0
- package/public/dist/assets/mindmap-definition-QFDTVHPH-Bd1OgfN_.js +1 -0
- package/public/dist/assets/packet-4T2RLAQJ-CGu8ST97.js +1 -0
- package/public/dist/assets/pie-ZZUOXDRM-CDG65mhS.js +1 -0
- package/public/dist/assets/pieDiagram-DEJITSTG-BbMBHLDM.js +1 -0
- package/public/dist/assets/quadrantDiagram-34T5L4WZ-CDCDgI1e.js +1 -0
- package/public/dist/assets/radar-PYXPWWZC-1gS-6ylu.js +1 -0
- package/public/dist/assets/render-YHvL5VM_.js +6 -0
- package/public/dist/assets/requirementDiagram-MS252O5E-DkmvOtYz.js +1 -0
- package/public/dist/assets/rolldown-runtime-FhOqtrmT.js +1 -0
- package/public/dist/assets/sankeyDiagram-XADWPNL6-GNcXIYsL.js +1 -0
- package/public/dist/assets/sequenceDiagram-FGHM5R23-BFrw2n6x.js +1 -0
- package/public/dist/assets/settings-BQF_u5px.js +37 -0
- package/public/dist/assets/settings-C5Q9IPjJ.js +1 -0
- package/public/dist/assets/shark-sprite-B3AAuERd.png +0 -0
- package/public/dist/assets/skills-9Pd2rOw-.js +1 -0
- package/public/dist/assets/skills-BI7sQAdk.js +12 -0
- package/public/dist/assets/slash-commands-DMsE88bu.js +14 -0
- package/public/dist/assets/slash-commands-FMpJzlDB.js +1 -0
- package/public/dist/assets/state-O6NVkWcL.js +1 -0
- package/public/dist/assets/stateDiagram-FHFEXIEX-BLgKnllT.js +1 -0
- package/public/dist/assets/stateDiagram-v2-QKLJ7IA2-CbzuWsSa.js +1 -0
- package/public/dist/assets/timeline-definition-GMOUNBTQ-CcZTJ3gL.js +1 -0
- package/public/dist/assets/treeView-SZITEDCU-BDqBsaH1.js +1 -0
- package/public/dist/assets/treemap-W4RFUUIX-BaWHA3Di.js +1 -0
- package/public/dist/assets/ui-BukgLHuh.js +29 -0
- package/public/dist/assets/ui-Bvz1JfTE.js +1 -0
- package/public/dist/assets/vendor-mermaid-COidH9HB.js +2934 -0
- package/public/dist/assets/vendor-render-Bjnw0wQ6.css +1 -0
- package/public/dist/assets/vendor-render-D2YP6GiF.js +322 -0
- package/public/dist/assets/vennDiagram-DHZGUBPP-BWV_j1bh.js +1 -0
- package/public/dist/assets/wardley-RL74JXVD-C7gKA3d7.js +1 -0
- package/public/dist/assets/wardleyDiagram-NUSXRM2D-BUoq_wug.js +1 -0
- package/public/dist/assets/ws-S_AZgx7L.js +2 -0
- package/public/dist/assets/xychartDiagram-5P7HB3ND-PvT5Ec82.js +1 -0
- package/public/dist/dist/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
- package/public/dist/dist/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
- package/public/dist/dist/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
- package/public/dist/dist/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
- package/public/dist/dist/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
- package/public/dist/dist/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
- package/public/dist/dist/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
- package/public/dist/dist/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
- package/public/dist/dist/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
- package/public/dist/dist/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
- package/public/dist/dist/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
- package/public/dist/dist/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
- package/public/dist/dist/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
- package/public/dist/dist/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
- package/public/dist/dist/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
- package/public/dist/dist/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
- package/public/dist/dist/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
- package/public/dist/dist/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
- package/public/dist/dist/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
- package/public/dist/dist/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
- package/public/dist/dist/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
- package/public/dist/dist/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
- package/public/dist/dist/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
- package/public/dist/dist/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
- package/public/dist/dist/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
- package/public/dist/dist/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
- package/public/dist/dist/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
- package/public/dist/dist/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
- package/public/dist/dist/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
- package/public/dist/dist/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
- package/public/dist/dist/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
- package/public/dist/dist/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
- package/public/dist/dist/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
- package/public/dist/dist/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
- package/public/dist/dist/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
- package/public/dist/dist/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
- package/public/dist/dist/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
- package/public/dist/dist/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
- package/public/dist/dist/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
- package/public/dist/dist/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
- package/public/dist/dist/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
- package/public/dist/dist/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
- package/public/dist/dist/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
- package/public/dist/dist/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
- package/public/dist/dist/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
- package/public/dist/dist/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
- package/public/dist/dist/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
- package/public/dist/dist/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
- package/public/dist/dist/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
- package/public/dist/dist/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
- package/public/dist/dist/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
- package/public/dist/dist/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
- package/public/dist/dist/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
- package/public/dist/dist/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
- package/public/dist/dist/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
- package/public/dist/dist/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
- package/public/dist/dist/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
- package/public/dist/dist/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
- package/public/dist/dist/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
- package/public/dist/dist/assets/api-B8XKQ4OT.js +1 -0
- package/public/dist/dist/assets/api-BlPw3bUI.js +1 -0
- package/public/dist/dist/assets/architecture-YZFGNWBL-BkS7SZQi.js +1 -0
- package/public/dist/dist/assets/architectureDiagram-Q4EWVU46-Dl3iBKeR.js +1 -0
- package/public/dist/dist/assets/blockDiagram-DXYQGD6D-DPr4D17p.js +1 -0
- package/public/dist/dist/assets/c4Diagram-AHTNJAMY-CfoxJtDk.js +1 -0
- package/public/dist/dist/assets/classDiagram-6PBFFD2Q-BOAdHnnB.js +1 -0
- package/public/dist/dist/assets/classDiagram-v2-HSJHXN6E-B2QCJXWC.js +1 -0
- package/public/dist/dist/assets/constants-DshMUJbo.js +1 -0
- package/public/dist/dist/assets/cose-bilkent-S5V4N54A-CA14jk7w.js +1 -0
- package/public/dist/dist/assets/dagre-KV5264BT-BVwNaSwC.js +1 -0
- package/public/dist/dist/assets/diagram-5BDNPKRD-CHqIAvdc.js +1 -0
- package/public/dist/dist/assets/diagram-G4DWMVQ6-DxvsCvTP.js +1 -0
- package/public/dist/dist/assets/diagram-MMDJMWI5-DqOPO7dl.js +1 -0
- package/public/dist/dist/assets/diagram-TYMM5635-C9xMWPQn.js +1 -0
- package/public/dist/dist/assets/employees-CFRlsbHm.js +39 -0
- package/public/dist/dist/assets/erDiagram-SMLLAGMA-BTmpfRkm.js +1 -0
- package/public/dist/dist/assets/flowDiagram-DWJPFMVM-DZBSQAKA.js +1 -0
- package/public/dist/dist/assets/ganttDiagram-T4ZO3ILL-TAEMCRbT.js +1 -0
- package/public/dist/dist/assets/gitGraph-7Q5UKJZL-bbxndRNA.js +1 -0
- package/public/dist/dist/assets/gitGraphDiagram-UUTBAWPF-CBxtx0MB.js +1 -0
- package/public/dist/dist/assets/icon-192-CwXPIYF5.png +0 -0
- package/public/dist/dist/assets/index-1Gg-6jeC.css +1 -0
- package/public/dist/dist/assets/index-CQHqXjrK.js +49 -0
- package/public/dist/dist/assets/info-OMHHGYJF-DRXq_Ywr.js +1 -0
- package/public/dist/dist/assets/infoDiagram-42DDH7IO-C7FFwX4m.js +1 -0
- package/public/dist/dist/assets/ishikawaDiagram-UXIWVN3A-DEZJE79j.js +1 -0
- package/public/dist/dist/assets/journeyDiagram-VCZTEJTY-ZHLiY6GV.js +1 -0
- package/public/dist/dist/assets/kanban-definition-6JOO6SKY-NP7pY7ML.js +1 -0
- package/public/dist/dist/assets/katex-DZLS_HFU.js +1 -0
- package/public/dist/dist/assets/locale-BjoAcbis.js +1 -0
- package/public/dist/dist/assets/manifest-Bw-LRm-c.json +20 -0
- package/public/dist/dist/assets/mermaid.core-CHuluSlD.js +1 -0
- package/public/dist/dist/assets/mindmap-definition-QFDTVHPH-Bd1OgfN_.js +1 -0
- package/public/dist/dist/assets/packet-4T2RLAQJ-CGu8ST97.js +1 -0
- package/public/dist/dist/assets/pie-ZZUOXDRM-CDG65mhS.js +1 -0
- package/public/dist/dist/assets/pieDiagram-DEJITSTG-BbMBHLDM.js +1 -0
- package/public/dist/dist/assets/quadrantDiagram-34T5L4WZ-CDCDgI1e.js +1 -0
- package/public/dist/dist/assets/radar-PYXPWWZC-1gS-6ylu.js +1 -0
- package/public/dist/dist/assets/render-YHvL5VM_.js +6 -0
- package/public/dist/dist/assets/requirementDiagram-MS252O5E-DkmvOtYz.js +1 -0
- package/public/dist/dist/assets/rolldown-runtime-FhOqtrmT.js +1 -0
- package/public/dist/dist/assets/sankeyDiagram-XADWPNL6-GNcXIYsL.js +1 -0
- package/public/dist/dist/assets/sequenceDiagram-FGHM5R23-BFrw2n6x.js +1 -0
- package/public/dist/dist/assets/settings-BQF_u5px.js +37 -0
- package/public/dist/dist/assets/settings-C5Q9IPjJ.js +1 -0
- package/public/dist/dist/assets/shark-sprite-B3AAuERd.png +0 -0
- package/public/dist/dist/assets/skills-9Pd2rOw-.js +1 -0
- package/public/dist/dist/assets/skills-BI7sQAdk.js +12 -0
- package/public/dist/dist/assets/slash-commands-DMsE88bu.js +14 -0
- package/public/dist/dist/assets/slash-commands-FMpJzlDB.js +1 -0
- package/public/dist/dist/assets/state-O6NVkWcL.js +1 -0
- package/public/dist/dist/assets/stateDiagram-FHFEXIEX-BLgKnllT.js +1 -0
- package/public/dist/dist/assets/stateDiagram-v2-QKLJ7IA2-CbzuWsSa.js +1 -0
- package/public/dist/dist/assets/timeline-definition-GMOUNBTQ-CcZTJ3gL.js +1 -0
- package/public/dist/dist/assets/treeView-SZITEDCU-BDqBsaH1.js +1 -0
- package/public/dist/dist/assets/treemap-W4RFUUIX-BaWHA3Di.js +1 -0
- package/public/dist/dist/assets/ui-BukgLHuh.js +29 -0
- package/public/dist/dist/assets/ui-Bvz1JfTE.js +1 -0
- package/public/dist/dist/assets/vendor-mermaid-COidH9HB.js +2934 -0
- package/public/dist/dist/assets/vendor-render-Bjnw0wQ6.css +1 -0
- package/public/dist/dist/assets/vendor-render-D2YP6GiF.js +322 -0
- package/public/dist/dist/assets/vennDiagram-DHZGUBPP-BWV_j1bh.js +1 -0
- package/public/dist/dist/assets/wardley-RL74JXVD-C7gKA3d7.js +1 -0
- package/public/dist/dist/assets/wardleyDiagram-NUSXRM2D-BUoq_wug.js +1 -0
- package/public/dist/dist/assets/ws-S_AZgx7L.js +2 -0
- package/public/dist/dist/assets/xychartDiagram-5P7HB3ND-PvT5Ec82.js +1 -0
- package/public/dist/dist/index.html +708 -0
- package/public/dist/index.html +708 -0
- package/public/icons/icon-192.png +0 -0
- package/public/icons/icon-512-maskable.png +0 -0
- package/public/icons/icon-512.png +0 -0
- package/public/index.html +178 -125
- package/public/js/constants.ts +6 -6
- package/public/js/features/chat.ts +23 -3
- package/public/js/features/employees.ts +12 -12
- package/public/js/features/gesture.ts +61 -0
- package/public/js/features/heartbeat.ts +1 -1
- package/public/js/features/idb-cache.ts +89 -0
- package/public/js/features/memory.ts +4 -1
- package/public/js/features/process-block.ts +236 -0
- package/public/js/features/settings-channel.ts +53 -0
- package/public/js/features/settings-cli-status.ts +164 -0
- package/public/js/features/settings-core.ts +357 -0
- package/public/js/features/settings-discord.ts +52 -0
- package/public/js/features/settings-mcp.ts +54 -0
- package/public/js/features/settings-stt.ts +78 -0
- package/public/js/features/settings-telegram.ts +40 -0
- package/public/js/features/settings-templates.ts +129 -0
- package/public/js/features/settings-types.ts +24 -0
- package/public/js/features/settings.ts +9 -815
- package/public/js/features/sidebar.ts +4 -2
- package/public/js/features/skills.ts +5 -4
- package/public/js/features/slash-commands.ts +1 -8
- package/public/js/features/theme.ts +16 -10
- package/public/js/features/tool-ui.ts +113 -0
- package/public/js/main.ts +67 -8
- package/public/js/render.ts +128 -90
- package/public/js/state.ts +4 -0
- package/public/js/streaming-render.ts +55 -0
- package/public/js/ui.ts +289 -46
- package/public/js/virtual-scroll.ts +189 -0
- package/public/js/ws.ts +175 -112
- package/public/locales/en.json +6 -1
- package/public/locales/ko.json +6 -1
- package/public/manifest.json +20 -0
- package/public/public/dist/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
- package/public/public/dist/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
- package/public/public/dist/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
- package/public/public/dist/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
- package/public/public/dist/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
- package/public/public/dist/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
- package/public/public/dist/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
- package/public/public/dist/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
- package/public/public/dist/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
- package/public/public/dist/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
- package/public/public/dist/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
- package/public/public/dist/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
- package/public/public/dist/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
- package/public/public/dist/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
- package/public/public/dist/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
- package/public/public/dist/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
- package/public/public/dist/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
- package/public/public/dist/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
- package/public/public/dist/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
- package/public/public/dist/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
- package/public/public/dist/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
- package/public/public/dist/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
- package/public/public/dist/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
- package/public/public/dist/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
- package/public/public/dist/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
- package/public/public/dist/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
- package/public/public/dist/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
- package/public/public/dist/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
- package/public/public/dist/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
- package/public/public/dist/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
- package/public/public/dist/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
- package/public/public/dist/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
- package/public/public/dist/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
- package/public/public/dist/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
- package/public/public/dist/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
- package/public/public/dist/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
- package/public/public/dist/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
- package/public/public/dist/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
- package/public/public/dist/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
- package/public/public/dist/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
- package/public/public/dist/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
- package/public/public/dist/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
- package/public/public/dist/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
- package/public/public/dist/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
- package/public/public/dist/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
- package/public/public/dist/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
- package/public/public/dist/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
- package/public/public/dist/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
- package/public/public/dist/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
- package/public/public/dist/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
- package/public/public/dist/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
- package/public/public/dist/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
- package/public/public/dist/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
- package/public/public/dist/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
- package/public/public/dist/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
- package/public/public/dist/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
- package/public/public/dist/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
- package/public/public/dist/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
- package/public/public/dist/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
- package/public/public/dist/assets/api-B8XKQ4OT.js +1 -0
- package/public/public/dist/assets/api-BlPw3bUI.js +1 -0
- package/public/public/dist/assets/architecture-YZFGNWBL-BkS7SZQi.js +1 -0
- package/public/public/dist/assets/architectureDiagram-Q4EWVU46-Dl3iBKeR.js +1 -0
- package/public/public/dist/assets/blockDiagram-DXYQGD6D-DPr4D17p.js +1 -0
- package/public/public/dist/assets/c4Diagram-AHTNJAMY-CfoxJtDk.js +1 -0
- package/public/public/dist/assets/classDiagram-6PBFFD2Q-BOAdHnnB.js +1 -0
- package/public/public/dist/assets/classDiagram-v2-HSJHXN6E-B2QCJXWC.js +1 -0
- package/public/public/dist/assets/constants-DshMUJbo.js +1 -0
- package/public/public/dist/assets/cose-bilkent-S5V4N54A-CA14jk7w.js +1 -0
- package/public/public/dist/assets/dagre-KV5264BT-BVwNaSwC.js +1 -0
- package/public/public/dist/assets/diagram-5BDNPKRD-CHqIAvdc.js +1 -0
- package/public/public/dist/assets/diagram-G4DWMVQ6-DxvsCvTP.js +1 -0
- package/public/public/dist/assets/diagram-MMDJMWI5-DqOPO7dl.js +1 -0
- package/public/public/dist/assets/diagram-TYMM5635-C9xMWPQn.js +1 -0
- package/public/public/dist/assets/employees-CFRlsbHm.js +39 -0
- package/public/public/dist/assets/erDiagram-SMLLAGMA-BTmpfRkm.js +1 -0
- package/public/public/dist/assets/flowDiagram-DWJPFMVM-DZBSQAKA.js +1 -0
- package/public/public/dist/assets/ganttDiagram-T4ZO3ILL-TAEMCRbT.js +1 -0
- package/public/public/dist/assets/gitGraph-7Q5UKJZL-bbxndRNA.js +1 -0
- package/public/public/dist/assets/gitGraphDiagram-UUTBAWPF-CBxtx0MB.js +1 -0
- package/public/public/dist/assets/icon-192-CwXPIYF5.png +0 -0
- package/public/public/dist/assets/index-1Gg-6jeC.css +1 -0
- package/public/public/dist/assets/index-CQHqXjrK.js +49 -0
- package/public/public/dist/assets/info-OMHHGYJF-DRXq_Ywr.js +1 -0
- package/public/public/dist/assets/infoDiagram-42DDH7IO-C7FFwX4m.js +1 -0
- package/public/public/dist/assets/ishikawaDiagram-UXIWVN3A-DEZJE79j.js +1 -0
- package/public/public/dist/assets/journeyDiagram-VCZTEJTY-ZHLiY6GV.js +1 -0
- package/public/public/dist/assets/kanban-definition-6JOO6SKY-NP7pY7ML.js +1 -0
- package/public/public/dist/assets/katex-DZLS_HFU.js +1 -0
- package/public/public/dist/assets/locale-BjoAcbis.js +1 -0
- package/public/public/dist/assets/manifest-Bw-LRm-c.json +20 -0
- package/public/public/dist/assets/mermaid.core-CHuluSlD.js +1 -0
- package/public/public/dist/assets/mindmap-definition-QFDTVHPH-Bd1OgfN_.js +1 -0
- package/public/public/dist/assets/packet-4T2RLAQJ-CGu8ST97.js +1 -0
- package/public/public/dist/assets/pie-ZZUOXDRM-CDG65mhS.js +1 -0
- package/public/public/dist/assets/pieDiagram-DEJITSTG-BbMBHLDM.js +1 -0
- package/public/public/dist/assets/quadrantDiagram-34T5L4WZ-CDCDgI1e.js +1 -0
- package/public/public/dist/assets/radar-PYXPWWZC-1gS-6ylu.js +1 -0
- package/public/public/dist/assets/render-YHvL5VM_.js +6 -0
- package/public/public/dist/assets/requirementDiagram-MS252O5E-DkmvOtYz.js +1 -0
- package/public/public/dist/assets/rolldown-runtime-FhOqtrmT.js +1 -0
- package/public/public/dist/assets/sankeyDiagram-XADWPNL6-GNcXIYsL.js +1 -0
- package/public/public/dist/assets/sequenceDiagram-FGHM5R23-BFrw2n6x.js +1 -0
- package/public/public/dist/assets/settings-BQF_u5px.js +37 -0
- package/public/public/dist/assets/settings-C5Q9IPjJ.js +1 -0
- package/public/public/dist/assets/shark-sprite-B3AAuERd.png +0 -0
- package/public/public/dist/assets/skills-9Pd2rOw-.js +1 -0
- package/public/public/dist/assets/skills-BI7sQAdk.js +12 -0
- package/public/public/dist/assets/slash-commands-DMsE88bu.js +14 -0
- package/public/public/dist/assets/slash-commands-FMpJzlDB.js +1 -0
- package/public/public/dist/assets/state-O6NVkWcL.js +1 -0
- package/public/public/dist/assets/stateDiagram-FHFEXIEX-BLgKnllT.js +1 -0
- package/public/public/dist/assets/stateDiagram-v2-QKLJ7IA2-CbzuWsSa.js +1 -0
- package/public/public/dist/assets/timeline-definition-GMOUNBTQ-CcZTJ3gL.js +1 -0
- package/public/public/dist/assets/treeView-SZITEDCU-BDqBsaH1.js +1 -0
- package/public/public/dist/assets/treemap-W4RFUUIX-BaWHA3Di.js +1 -0
- package/public/public/dist/assets/ui-BukgLHuh.js +29 -0
- package/public/public/dist/assets/ui-Bvz1JfTE.js +1 -0
- package/public/public/dist/assets/vendor-mermaid-COidH9HB.js +2934 -0
- package/public/public/dist/assets/vendor-render-Bjnw0wQ6.css +1 -0
- package/public/public/dist/assets/vendor-render-D2YP6GiF.js +322 -0
- package/public/public/dist/assets/vennDiagram-DHZGUBPP-BWV_j1bh.js +1 -0
- package/public/public/dist/assets/wardley-RL74JXVD-C7gKA3d7.js +1 -0
- package/public/public/dist/assets/wardleyDiagram-NUSXRM2D-BUoq_wug.js +1 -0
- package/public/public/dist/assets/ws-S_AZgx7L.js +2 -0
- package/public/public/dist/assets/xychartDiagram-5P7HB3ND-PvT5Ec82.js +1 -0
- package/public/public/dist/index.html +708 -0
- package/public/sw.js +104 -0
- package/scripts/install-officecli.sh +145 -0
- package/scripts/release-preview.sh +18 -10
- package/scripts/release.sh +3 -3
- package/public/dist/bundle.js +0 -151
- package/public/dist/bundle.js.map +0 -7
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
// ── CLI Status & Quota ──
|
|
2
|
+
import { api } from '../api.js';
|
|
3
|
+
import { escapeHtml } from '../render.js';
|
|
4
|
+
import { t } from './i18n.js';
|
|
5
|
+
import { state } from '../state.js';
|
|
6
|
+
import type { QuotaEntry } from './settings-types.js';
|
|
7
|
+
|
|
8
|
+
export async function loadCliStatus(force = false): Promise<void> {
|
|
9
|
+
const interval = Number(localStorage.getItem('cliStatusInterval') || 300);
|
|
10
|
+
if (!force && state.cliStatusCache && interval > 0 && (Date.now() - state.cliStatusTs) < interval * 1000) {
|
|
11
|
+
renderCliStatus({ cliStatus: (state.cliStatusCache as Record<string, unknown>)?.cliStatus as Record<string, { available: boolean }> | null, quota: (state.cliStatusCache as Record<string, unknown>)?.quota as Record<string, QuotaEntry> | null });
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const el = document.getElementById('cliStatusList');
|
|
16
|
+
if (el) el.innerHTML = '<div style="color:var(--text-dim);font-size:11px">Loading...</div>';
|
|
17
|
+
|
|
18
|
+
const [cliStatus, quota] = await Promise.all([
|
|
19
|
+
api<Record<string, { available: boolean }>>('/api/cli-status'),
|
|
20
|
+
api<Record<string, QuotaEntry>>('/api/quota'),
|
|
21
|
+
]);
|
|
22
|
+
|
|
23
|
+
state.cliStatusCache = { cliStatus, quota } as Record<string, unknown>;
|
|
24
|
+
state.cliStatusTs = Date.now();
|
|
25
|
+
renderCliStatus({ cliStatus, quota });
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function renderCliStatus(data: { cliStatus: Record<string, { available: boolean }> | null; quota: Record<string, QuotaEntry> | null }): void {
|
|
29
|
+
const { cliStatus, quota } = data;
|
|
30
|
+
const el = document.getElementById('cliStatusList');
|
|
31
|
+
|
|
32
|
+
const AUTH_HINTS: Record<string, { install: string; auth: string }> = {
|
|
33
|
+
claude: { install: 'npm i -g @anthropic-ai/claude-code', auth: 'claude auth' },
|
|
34
|
+
codex: { install: 'npm i -g @openai/codex', auth: 'codex login' },
|
|
35
|
+
gemini: { install: 'npm i -g @google/gemini-cli', auth: `gemini (${t('cli.gemini.auth')})` },
|
|
36
|
+
opencode: { install: 'npm i -g opencode-ai', auth: 'opencode auth' },
|
|
37
|
+
copilot: { install: 'npm i -g copilot', auth: 'copilot login 또는 gh auth login' },
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
let html = '';
|
|
41
|
+
|
|
42
|
+
if (!cliStatus || typeof cliStatus !== 'object') {
|
|
43
|
+
if (el) el.innerHTML = '<div style="color:var(--text-dim);font-size:11px">Failed to load CLI status</div>';
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
for (const [name, info] of Object.entries(cliStatus)) {
|
|
48
|
+
const q = quota?.[name];
|
|
49
|
+
let dotClass: string;
|
|
50
|
+
if (!info.available) {
|
|
51
|
+
dotClass = 'missing';
|
|
52
|
+
} else if (!q || q.error) {
|
|
53
|
+
dotClass = 'ok';
|
|
54
|
+
} else if (q.authenticated === false) {
|
|
55
|
+
dotClass = 'warn';
|
|
56
|
+
} else {
|
|
57
|
+
dotClass = 'ok';
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
let accountLine = '';
|
|
61
|
+
if (q?.account) {
|
|
62
|
+
const parts = [];
|
|
63
|
+
if (q.account.email) parts.push(q.account.email);
|
|
64
|
+
if (q.account.type) parts.push(q.account.type);
|
|
65
|
+
if (q.account.plan) parts.push(q.account.plan);
|
|
66
|
+
if (q.account.tier) parts.push(q.account.tier);
|
|
67
|
+
if (parts.length) accountLine = `<div style="font-size:10px;color:var(--text-dim);margin:2px 0 4px 16px">${escapeHtml(parts.join(' · '))}</div>`;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
let authHint = '';
|
|
71
|
+
if (!info.available || dotClass === 'warn') {
|
|
72
|
+
const hint = AUTH_HINTS[name];
|
|
73
|
+
if (hint) {
|
|
74
|
+
const isNotInstalled = !info.available;
|
|
75
|
+
const title = isNotInstalled ? t('cli.authRequired') : t('cli.notAuthenticated');
|
|
76
|
+
const borderColor = isNotInstalled ? '#ef4444' : '#fbbf24';
|
|
77
|
+
authHint = `
|
|
78
|
+
<div style="font-size:10px;margin:4px 0 2px 16px;padding:6px 8px;background:var(--bg-dim, #1e1e2e);border-radius:4px;border-left:2px solid ${borderColor}">
|
|
79
|
+
<div style="color:${borderColor};margin-bottom:3px">${title}</div>
|
|
80
|
+
${isNotInstalled ? `<div style="color:var(--text-dim)"><code style="font-size:10px;background:var(--border);padding:1px 4px;border-radius:2px">${escapeHtml(hint.install)}</code></div>` : ''}
|
|
81
|
+
<div style="color:var(--text-dim)${isNotInstalled ? ';margin-top:2px' : ''}"><code style="font-size:10px;background:var(--border);padding:1px 4px;border-radius:2px">${escapeHtml(hint.auth)}</code></div>
|
|
82
|
+
</div>
|
|
83
|
+
`;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
let windowsHtml = '';
|
|
88
|
+
if (q?.windows?.length) {
|
|
89
|
+
windowsHtml = q.windows.map(w => {
|
|
90
|
+
const pct = Math.round(w.percent);
|
|
91
|
+
const barColor = pct > 80 ? '#ef4444' : pct > 50 ? '#fbbf24' : '#38bdf8';
|
|
92
|
+
const shortLabel = w.label.replace('-hour', 'h').replace('-day', 'd').replace(' Sonnet', '').replace(' Opus', '').replace('plus monthly subscriber quota', 'plus').replace('Premium', 'Prem');
|
|
93
|
+
let resetStr = '';
|
|
94
|
+
if (w.resetsAt) {
|
|
95
|
+
const d = new Date(typeof w.resetsAt === 'number' ? w.resetsAt * 1000 : w.resetsAt);
|
|
96
|
+
const now = new Date();
|
|
97
|
+
if (d.toDateString() === now.toDateString()) {
|
|
98
|
+
resetStr = `${d.getHours()}:${String(d.getMinutes()).padStart(2, '0')}`;
|
|
99
|
+
} else {
|
|
100
|
+
resetStr = `${d.getMonth() + 1}/${d.getDate()}`;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return `
|
|
104
|
+
<div style="display:flex;align-items:center;gap:4px;margin-left:16px;font-size:10px;color:var(--text-dim)">
|
|
105
|
+
<span style="min-width:18px;max-width:48px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis">${escapeHtml(shortLabel)}</span>
|
|
106
|
+
<div style="flex:1;height:4px;background:var(--border);border-radius:2px;overflow:hidden">
|
|
107
|
+
<div style="width:${pct}%;height:100%;background:${barColor};border-radius:2px"></div>
|
|
108
|
+
</div>
|
|
109
|
+
<span style="width:24px;text-align:right">${pct}%</span>
|
|
110
|
+
${resetStr ? `<span style="width:30px;text-align:right;opacity:0.6">${resetStr}</span>` : ''}
|
|
111
|
+
</div>
|
|
112
|
+
`;
|
|
113
|
+
}).join('');
|
|
114
|
+
} else if (q?.error && info.available) {
|
|
115
|
+
const msg = q.reason === 'rate_limited' ? 'Rate limited — retry in a moment' : 'Usage data unavailable';
|
|
116
|
+
windowsHtml = `<div style="font-size:10px;color:var(--text-dim);margin:2px 0 0 16px;opacity:0.7">⚠ ${msg}</div>`;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
html += `
|
|
120
|
+
<div class="settings-group" style="margin-bottom:6px;padding:8px 10px">
|
|
121
|
+
<div class="cli-status-row">
|
|
122
|
+
<span class="cli-dot ${dotClass}"></span>
|
|
123
|
+
<span class="cli-name" style="font-weight:600">${escapeHtml(name)}</span>${name === 'copilot' ? `<button id="copilotKeychainBtn" style="font-size:9px;margin-left:6px;padding:1px 5px;background:var(--border);color:var(--text-dim);border:1px solid var(--text-dim);border-radius:3px;cursor:pointer;vertical-align:middle;line-height:1" title="${t('copilot.keychainHint')}">🔑</button>` : ''}
|
|
124
|
+
</div>
|
|
125
|
+
${accountLine}
|
|
126
|
+
${authHint}
|
|
127
|
+
${windowsHtml}
|
|
128
|
+
</div>
|
|
129
|
+
`;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if (el) el.innerHTML = html;
|
|
133
|
+
|
|
134
|
+
const allEntries = Object.entries(cliStatus);
|
|
135
|
+
const hasReadyCli = allEntries.some(([name, info]) => {
|
|
136
|
+
if (!info.available) return false;
|
|
137
|
+
const q = quota?.[name];
|
|
138
|
+
return !q || q.authenticated !== false;
|
|
139
|
+
});
|
|
140
|
+
if (!hasReadyCli && allEntries.length > 0 && el) {
|
|
141
|
+
el.insertAdjacentHTML('afterbegin',
|
|
142
|
+
`<div style="padding:8px 10px;margin-bottom:8px;background:#fbbf2422;border:1px solid #fbbf24;border-radius:6px;font-size:11px;color:#fbbf24">
|
|
143
|
+
⚠ ${t('cli.noReadyCli')}
|
|
144
|
+
</div>`
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const kcBtn = document.getElementById('copilotKeychainBtn');
|
|
149
|
+
if (kcBtn) {
|
|
150
|
+
kcBtn.addEventListener('click', async () => {
|
|
151
|
+
const btn = kcBtn as HTMLButtonElement;
|
|
152
|
+
btn.disabled = true;
|
|
153
|
+
btn.textContent = '⏳';
|
|
154
|
+
try {
|
|
155
|
+
const res = await api<{ ok: boolean }>('/api/copilot/refresh', { method: 'POST' });
|
|
156
|
+
btn.textContent = res?.ok ? '✅' : '❌';
|
|
157
|
+
if (res?.ok) await loadCliStatus(true);
|
|
158
|
+
} catch {
|
|
159
|
+
btn.textContent = '❌';
|
|
160
|
+
}
|
|
161
|
+
setTimeout(() => { btn.textContent = '🔑'; btn.disabled = false; }, 2000);
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
}
|
|
@@ -0,0 +1,357 @@
|
|
|
1
|
+
// ── Settings Core ──
|
|
2
|
+
import { MODEL_MAP, loadCliRegistry, getCliKeys, getCliMeta } from '../constants.js';
|
|
3
|
+
import { escapeHtml } from '../render.js';
|
|
4
|
+
import { syncStoredLocale } from '../locale.js';
|
|
5
|
+
import { t } from './i18n.js';
|
|
6
|
+
import { api, apiJson, apiFire } from '../api.js';
|
|
7
|
+
import type { PerCliConfig, SettingsData } from './settings-types.js';
|
|
8
|
+
import { initSttSettings } from './settings-stt.js';
|
|
9
|
+
import { loadTelegramSettings } from './settings-telegram.js';
|
|
10
|
+
import { loadDiscordSettings } from './settings-discord.js';
|
|
11
|
+
import { loadActiveChannel, loadFallbackOrder } from './settings-channel.js';
|
|
12
|
+
import { loadMcpServers } from './settings-mcp.js';
|
|
13
|
+
|
|
14
|
+
function toCap(cli: string): string {
|
|
15
|
+
return cli.charAt(0).toUpperCase() + cli.slice(1);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function getModelSelect(cli: string): HTMLSelectElement | null {
|
|
19
|
+
return document.getElementById('model' + toCap(cli)) as HTMLSelectElement | null;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function getCustomModelInput(cli: string): HTMLInputElement | null {
|
|
23
|
+
return document.getElementById('customModel' + toCap(cli)) as HTMLInputElement | null;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function getEffortSelect(cli: string): HTMLSelectElement | null {
|
|
27
|
+
return document.getElementById('effort' + toCap(cli)) as HTMLSelectElement | null;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function setSelectOptions(selectEl: HTMLSelectElement | null, values: string[], { includeCustom = false, includeDefault = false, selected = '' } = {}): void {
|
|
31
|
+
if (!selectEl) return;
|
|
32
|
+
const defaultHtml = includeDefault ? '<option value="default">default</option>' : '';
|
|
33
|
+
const customHtml = includeCustom ? `<option value="__custom__">${t('model.customOption')}</option>` : '';
|
|
34
|
+
const opts = (values || []).map(v => `<option value="${escapeHtml(v)}">${escapeHtml(v)}</option>`).join('');
|
|
35
|
+
selectEl.innerHTML = defaultHtml + opts + customHtml;
|
|
36
|
+
|
|
37
|
+
if (selected && Array.from(selectEl.options).some(o => o.value === selected)) {
|
|
38
|
+
selectEl.value = selected;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function appendCustomOption(selectEl: HTMLSelectElement | null, value: string): void {
|
|
43
|
+
if (!selectEl || !value) return;
|
|
44
|
+
if (Array.from(selectEl.options).some(o => o.value === value)) return;
|
|
45
|
+
const opt = document.createElement('option');
|
|
46
|
+
opt.value = value;
|
|
47
|
+
opt.textContent = value;
|
|
48
|
+
const customOpt = selectEl.querySelector('option[value="__custom__"]');
|
|
49
|
+
if (customOpt) selectEl.insertBefore(opt, customOpt);
|
|
50
|
+
else selectEl.appendChild(opt);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function syncCliOptionSelects(settings: SettingsData | null = null): void {
|
|
54
|
+
const cliKeys = getCliKeys();
|
|
55
|
+
|
|
56
|
+
const selCli = document.getElementById('selCli') as HTMLSelectElement | null;
|
|
57
|
+
if (selCli) {
|
|
58
|
+
const current = settings?.cli || selCli.value || cliKeys[0] || 'claude';
|
|
59
|
+
selCli.innerHTML = cliKeys.map(cli => {
|
|
60
|
+
const label = getCliMeta(cli)?.label || cli;
|
|
61
|
+
return `<option value="${escapeHtml(cli)}">${escapeHtml(label)}</option>`;
|
|
62
|
+
}).join('');
|
|
63
|
+
if (Array.from(selCli.options).some(o => o.value === current)) selCli.value = current;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const memCli = document.getElementById('memCli') as HTMLSelectElement | null;
|
|
67
|
+
if (memCli) {
|
|
68
|
+
const current = settings?.memory?.cli || memCli.value || '';
|
|
69
|
+
memCli.innerHTML = '<option value="">(active CLI)</option>' +
|
|
70
|
+
cliKeys.map(cli => `<option value="${escapeHtml(cli)}">${escapeHtml(cli)}</option>`).join('');
|
|
71
|
+
if (Array.from(memCli.options).some(o => o.value === current)) memCli.value = current;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function normalizeModelForDisplay(cli: string, model: string): string {
|
|
76
|
+
if (cli !== 'claude') return model;
|
|
77
|
+
switch ((model || '').trim()) {
|
|
78
|
+
case 'claude-sonnet-4-6': return 'sonnet';
|
|
79
|
+
case 'claude-opus-4-6': return 'opus';
|
|
80
|
+
case 'claude-sonnet-4-6[1m]': return 'sonnet[1m]';
|
|
81
|
+
case 'claude-opus-4-6[1m]': return 'opus[1m]';
|
|
82
|
+
default: return model;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function syncPerCliModelAndEffortControls(settings: SettingsData | null = null): void {
|
|
87
|
+
for (const cli of getCliKeys()) {
|
|
88
|
+
const modelSel = getModelSelect(cli);
|
|
89
|
+
if (modelSel) {
|
|
90
|
+
const raw = settings?.perCli?.[cli]?.model || modelSel.value || '';
|
|
91
|
+
const selected = normalizeModelForDisplay(cli, raw);
|
|
92
|
+
setSelectOptions(modelSel, MODEL_MAP[cli] || [], { includeCustom: true, selected });
|
|
93
|
+
if (selected && !Array.from(modelSel.options).some(o => o.value === selected)) {
|
|
94
|
+
appendCustomOption(modelSel, selected);
|
|
95
|
+
modelSel.value = selected;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const effortSel = getEffortSelect(cli);
|
|
100
|
+
if (effortSel) {
|
|
101
|
+
const meta = getCliMeta(cli);
|
|
102
|
+
const options = [''].concat(meta?.efforts || []);
|
|
103
|
+
const selected = settings?.perCli?.[cli]?.effort || effortSel.value || '';
|
|
104
|
+
const unique = [...new Set(options)];
|
|
105
|
+
const noneLabel = (meta?.efforts?.length === 0 && meta?.effortNote) ? meta.effortNote : '— none';
|
|
106
|
+
effortSel.innerHTML = unique.map(v => {
|
|
107
|
+
if (!v) return `<option value="">${escapeHtml(noneLabel)}</option>`;
|
|
108
|
+
return `<option value="${escapeHtml(v)}">${escapeHtml(v)}</option>`;
|
|
109
|
+
}).join('');
|
|
110
|
+
if (meta?.effortNote) effortSel.title = meta.effortNote;
|
|
111
|
+
effortSel.disabled = (meta?.efforts?.length === 0 && !!meta?.effortNote);
|
|
112
|
+
if (Array.from(effortSel.options).some(o => o.value === selected)) effortSel.value = selected;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
function syncActiveEffortOptions(cli: string, selected = ''): void {
|
|
118
|
+
const selEffort = document.getElementById('selEffort') as HTMLSelectElement | null;
|
|
119
|
+
if (!selEffort) return;
|
|
120
|
+
const meta = getCliMeta(cli);
|
|
121
|
+
if (meta?.effortNote) {
|
|
122
|
+
selEffort.innerHTML = `<option value="">${escapeHtml(meta.effortNote)}</option>`;
|
|
123
|
+
selEffort.title = meta.effortNote;
|
|
124
|
+
selEffort.disabled = true;
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
const efforts = [''].concat(meta?.efforts || []);
|
|
128
|
+
const unique = [...new Set(efforts)];
|
|
129
|
+
selEffort.innerHTML = unique.map(v => {
|
|
130
|
+
if (!v) return '<option value="">— none</option>';
|
|
131
|
+
return `<option value="${escapeHtml(v)}">${escapeHtml(v)}</option>`;
|
|
132
|
+
}).join('');
|
|
133
|
+
selEffort.disabled = false;
|
|
134
|
+
selEffort.title = '';
|
|
135
|
+
if (Array.from(selEffort.options).some(o => o.value === selected)) selEffort.value = selected;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
export async function loadSettings(): Promise<void> {
|
|
139
|
+
await loadCliRegistry();
|
|
140
|
+
const s = await api<SettingsData>('/api/settings');
|
|
141
|
+
if (!s) return;
|
|
142
|
+
syncStoredLocale(s.locale ?? '');
|
|
143
|
+
syncCliOptionSelects(s);
|
|
144
|
+
syncPerCliModelAndEffortControls(s);
|
|
145
|
+
|
|
146
|
+
const selCli = document.getElementById('selCli') as HTMLSelectElement | null;
|
|
147
|
+
if (selCli && Array.from(selCli.options).some(o => o.value === s.cli)) {
|
|
148
|
+
selCli.value = s.cli;
|
|
149
|
+
}
|
|
150
|
+
const cwdEl = document.getElementById('inpCwd');
|
|
151
|
+
if (cwdEl) cwdEl.textContent = s.workingDir;
|
|
152
|
+
const headerEl = document.getElementById('headerCli');
|
|
153
|
+
if (headerEl) headerEl.textContent = s.cli;
|
|
154
|
+
setPerm(s.permissions, false);
|
|
155
|
+
|
|
156
|
+
if (s.perCli) {
|
|
157
|
+
for (const [cli, cfg] of Object.entries(s.perCli) as [string, PerCliConfig][]) {
|
|
158
|
+
const modelEl = getModelSelect(cli);
|
|
159
|
+
const effortEl = getEffortSelect(cli);
|
|
160
|
+
if (modelEl && cfg.model) {
|
|
161
|
+
const displayModel = normalizeModelForDisplay(cli, cfg.model);
|
|
162
|
+
appendCustomOption(modelEl, displayModel);
|
|
163
|
+
modelEl.value = displayModel;
|
|
164
|
+
}
|
|
165
|
+
if (effortEl) effortEl.value = cfg.effort || '';
|
|
166
|
+
if (cli === 'codex' && cfg.fastMode !== undefined) {
|
|
167
|
+
document.getElementById('codexFastOn')?.classList.toggle('active', cfg.fastMode);
|
|
168
|
+
document.getElementById('codexFastOff')?.classList.toggle('active', !cfg.fastMode);
|
|
169
|
+
}
|
|
170
|
+
if (cli === 'codex') {
|
|
171
|
+
const ctxOn = !!cfg.contextWindow;
|
|
172
|
+
document.getElementById('codexCtxOn')?.classList.toggle('active', ctxOn);
|
|
173
|
+
document.getElementById('codexCtxOff')?.classList.toggle('active', !ctxOn);
|
|
174
|
+
const valDiv = document.getElementById('codexCtxValues');
|
|
175
|
+
if (valDiv) valDiv.style.display = ctxOn ? '' : 'none';
|
|
176
|
+
const winInput = document.getElementById('codexCtxWindow') as HTMLInputElement | null;
|
|
177
|
+
const compInput = document.getElementById('codexCtxCompact') as HTMLInputElement | null;
|
|
178
|
+
if (winInput && cfg.contextWindowSize) winInput.value = String(cfg.contextWindowSize);
|
|
179
|
+
if (compInput && cfg.contextCompactLimit) compInput.value = String(cfg.contextCompactLimit);
|
|
180
|
+
}
|
|
181
|
+
if (cli === 'claude') {
|
|
182
|
+
const is1m = !!(cfg.model && String(cfg.model).endsWith('[1m]'));
|
|
183
|
+
document.getElementById('claude1mOn')?.classList.toggle('active', is1m);
|
|
184
|
+
document.getElementById('claude1mOff')?.classList.toggle('active', !is1m);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
onCliChange(false);
|
|
190
|
+
const ao = s.activeOverrides?.[s.cli] || {};
|
|
191
|
+
const pc = s.perCli?.[s.cli] || {};
|
|
192
|
+
const activeModel = ao.model || pc.model;
|
|
193
|
+
const activeEffort = ao.effort || pc.effort || '';
|
|
194
|
+
const selModel = document.getElementById('selModel') as HTMLSelectElement | null;
|
|
195
|
+
if (activeModel && selModel) {
|
|
196
|
+
const displayModel = normalizeModelForDisplay(s.cli, activeModel);
|
|
197
|
+
if (displayModel && !Array.from(selModel.options).some(o => o.value === displayModel)) {
|
|
198
|
+
appendCustomOption(selModel, displayModel);
|
|
199
|
+
}
|
|
200
|
+
selModel.value = displayModel;
|
|
201
|
+
}
|
|
202
|
+
syncActiveEffortOptions(s.cli, activeEffort);
|
|
203
|
+
|
|
204
|
+
loadTelegramSettings(s);
|
|
205
|
+
loadDiscordSettings(s);
|
|
206
|
+
loadActiveChannel(s);
|
|
207
|
+
loadFallbackOrder(s);
|
|
208
|
+
loadMcpServers();
|
|
209
|
+
initSttSettings(s.stt || {});
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
export async function updateSettings(): Promise<void> {
|
|
213
|
+
const s = {
|
|
214
|
+
cli: (document.getElementById('selCli') as HTMLSelectElement)?.value || 'claude',
|
|
215
|
+
};
|
|
216
|
+
const hdr = document.getElementById('headerCli');
|
|
217
|
+
if (hdr) hdr.textContent = s.cli;
|
|
218
|
+
await apiJson('/api/settings', 'PUT', s);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
export function setPerm(_p: string, save = true): void {
|
|
222
|
+
if (save) apiFire('/api/settings', 'PUT', { permissions: 'auto' });
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
export function getModelValue(cli: string): string {
|
|
226
|
+
const sel = getModelSelect(cli);
|
|
227
|
+
if (!sel) return 'default';
|
|
228
|
+
if (sel.value === '__custom__') {
|
|
229
|
+
const inp = getCustomModelInput(cli);
|
|
230
|
+
return inp?.value?.trim() || sel.options[0]?.value || 'default';
|
|
231
|
+
}
|
|
232
|
+
return sel.value;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
export function handleModelSelect(cli: string, selectEl: HTMLSelectElement): void {
|
|
236
|
+
const customInput = getCustomModelInput(cli);
|
|
237
|
+
if (!customInput) return;
|
|
238
|
+
if (selectEl.value === '__custom__') {
|
|
239
|
+
customInput.style.display = 'block';
|
|
240
|
+
customInput.focus();
|
|
241
|
+
} else {
|
|
242
|
+
customInput.style.display = 'none';
|
|
243
|
+
if (cli === 'claude') syncClaude1mToggle(selectEl.value);
|
|
244
|
+
savePerCli();
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/** Sync Claude 1M toggle button state to match current model value */
|
|
249
|
+
function syncClaude1mToggle(model: string): void {
|
|
250
|
+
const is1m = !!(model && model.endsWith('[1m]'));
|
|
251
|
+
document.getElementById('claude1mOn')?.classList.toggle('active', is1m);
|
|
252
|
+
document.getElementById('claude1mOff')?.classList.toggle('active', !is1m);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
export function applyCustomModel(cli: string, inputEl: HTMLInputElement): void {
|
|
256
|
+
const val = inputEl.value.trim();
|
|
257
|
+
if (!val) return;
|
|
258
|
+
const select = getModelSelect(cli);
|
|
259
|
+
if (!select) return;
|
|
260
|
+
appendCustomOption(select, val);
|
|
261
|
+
select.value = val;
|
|
262
|
+
inputEl.style.display = 'none';
|
|
263
|
+
if (cli === 'claude') syncClaude1mToggle(val);
|
|
264
|
+
savePerCli();
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
export async function savePerCli(): Promise<void> {
|
|
268
|
+
const perCli: Record<string, PerCliConfig> = {};
|
|
269
|
+
for (const cli of getCliKeys()) {
|
|
270
|
+
const modelEl = getModelSelect(cli);
|
|
271
|
+
if (!modelEl) continue;
|
|
272
|
+
const effortEl = getEffortSelect(cli);
|
|
273
|
+
const entry: PerCliConfig = {
|
|
274
|
+
model: getModelValue(cli),
|
|
275
|
+
effort: effortEl ? effortEl.value : '',
|
|
276
|
+
};
|
|
277
|
+
if (cli === 'codex') {
|
|
278
|
+
const onBtn = document.getElementById('codexFastOn');
|
|
279
|
+
entry.fastMode = onBtn?.classList.contains('active') ?? false;
|
|
280
|
+
const ctxOn = document.getElementById('codexCtxOn');
|
|
281
|
+
entry.contextWindow = ctxOn?.classList.contains('active') ?? false;
|
|
282
|
+
const winInput = document.getElementById('codexCtxWindow') as HTMLInputElement | null;
|
|
283
|
+
const compInput = document.getElementById('codexCtxCompact') as HTMLInputElement | null;
|
|
284
|
+
entry.contextWindowSize = parseInt(winInput?.value || '1000000', 10);
|
|
285
|
+
entry.contextCompactLimit = parseInt(compInput?.value || '900000', 10);
|
|
286
|
+
}
|
|
287
|
+
perCli[cli] = entry;
|
|
288
|
+
}
|
|
289
|
+
await apiJson('/api/settings', 'PUT', { perCli });
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
export function onCliChange(save = true): void {
|
|
293
|
+
const cli = (document.getElementById('selCli') as HTMLSelectElement)?.value || 'claude';
|
|
294
|
+
const models = MODEL_MAP[cli] || [];
|
|
295
|
+
const modelSel = document.getElementById('selModel') as HTMLSelectElement | null;
|
|
296
|
+
setSelectOptions(modelSel, models, { includeCustom: true, includeDefault: true });
|
|
297
|
+
const hdrCli = document.getElementById('headerCli');
|
|
298
|
+
if (hdrCli) hdrCli.textContent = cli;
|
|
299
|
+
syncActiveEffortOptions(cli);
|
|
300
|
+
|
|
301
|
+
const oldInput = document.getElementById('selModelCustom');
|
|
302
|
+
if (oldInput) oldInput.remove();
|
|
303
|
+
const inp = document.createElement('input');
|
|
304
|
+
inp.type = 'text'; inp.id = 'selModelCustom';
|
|
305
|
+
inp.className = 'custom-model-input';
|
|
306
|
+
inp.placeholder = t('model.placeholder');
|
|
307
|
+
inp.style.display = 'none';
|
|
308
|
+
inp.onchange = function () {
|
|
309
|
+
const val = (this as HTMLInputElement).value.trim();
|
|
310
|
+
if (!val || !modelSel) return;
|
|
311
|
+
appendCustomOption(modelSel, val);
|
|
312
|
+
modelSel.value = val;
|
|
313
|
+
(this as HTMLInputElement).style.display = 'none';
|
|
314
|
+
saveActiveCliSettings();
|
|
315
|
+
};
|
|
316
|
+
if (!modelSel) { if (save) updateSettings(); return; }
|
|
317
|
+
modelSel.parentElement?.appendChild(inp);
|
|
318
|
+
modelSel.onchange = function () {
|
|
319
|
+
if ((this as HTMLSelectElement).value === '__custom__') {
|
|
320
|
+
inp.style.display = 'block';
|
|
321
|
+
inp.focus();
|
|
322
|
+
} else {
|
|
323
|
+
inp.style.display = 'none';
|
|
324
|
+
saveActiveCliSettings();
|
|
325
|
+
}
|
|
326
|
+
};
|
|
327
|
+
|
|
328
|
+
api<SettingsData>('/api/settings').then(s => {
|
|
329
|
+
if (!s) return;
|
|
330
|
+
const ao = s.activeOverrides?.[cli] || {};
|
|
331
|
+
const pc = s.perCli?.[cli] || {};
|
|
332
|
+
const model = ao.model || pc.model;
|
|
333
|
+
const effort = ao.effort || pc.effort || '';
|
|
334
|
+
if (model && modelSel) {
|
|
335
|
+
const displayModel = normalizeModelForDisplay(cli, model);
|
|
336
|
+
appendCustomOption(modelSel, displayModel);
|
|
337
|
+
modelSel.value = displayModel;
|
|
338
|
+
}
|
|
339
|
+
syncActiveEffortOptions(cli, effort);
|
|
340
|
+
});
|
|
341
|
+
|
|
342
|
+
if (save) updateSettings();
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
export async function saveActiveCliSettings(): Promise<void> {
|
|
346
|
+
const cli = (document.getElementById('selCli') as HTMLSelectElement)?.value || 'claude';
|
|
347
|
+
const modelSel = document.getElementById('selModel') as HTMLSelectElement | null;
|
|
348
|
+
let model = modelSel?.value || 'default';
|
|
349
|
+
if (model === '__custom__') {
|
|
350
|
+
model = (document.getElementById('selModelCustom') as HTMLInputElement | null)?.value?.trim() || 'default';
|
|
351
|
+
}
|
|
352
|
+
const effortEl = document.getElementById('selEffort') as HTMLSelectElement | null;
|
|
353
|
+
const overrides: Record<string, PerCliConfig> = {};
|
|
354
|
+
overrides[cli] = { model };
|
|
355
|
+
if (effortEl && !effortEl.disabled) overrides[cli].effort = effortEl.value || '';
|
|
356
|
+
await apiJson('/api/settings', 'PUT', { activeOverrides: overrides });
|
|
357
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
// ── Discord Settings ──
|
|
2
|
+
import { apiJson } from '../api.js';
|
|
3
|
+
import type { SettingsData } from './settings-types.js';
|
|
4
|
+
|
|
5
|
+
export async function saveDiscordSettings(): Promise<void> {
|
|
6
|
+
const token = (document.getElementById('dcToken') as HTMLInputElement)?.value.trim() || '';
|
|
7
|
+
const guildId = (document.getElementById('dcGuildId') as HTMLInputElement)?.value.trim() || '';
|
|
8
|
+
const channelIdsRaw = (document.getElementById('dcChannelIds') as HTMLInputElement)?.value.trim() || '';
|
|
9
|
+
const channelIds = channelIdsRaw
|
|
10
|
+
? channelIdsRaw.split(',').map(s => s.trim()).filter(Boolean)
|
|
11
|
+
: [];
|
|
12
|
+
await apiJson('/api/settings', 'PUT', { discord: { token, guildId, channelIds } });
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export async function setDiscord(enabled: boolean): Promise<void> {
|
|
16
|
+
document.getElementById('dcOn')?.classList.toggle('active', enabled);
|
|
17
|
+
document.getElementById('dcOff')?.classList.toggle('active', !enabled);
|
|
18
|
+
await apiJson('/api/settings', 'PUT', { discord: { enabled } });
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export async function setDiscordForwardAll(enabled: boolean): Promise<void> {
|
|
22
|
+
document.getElementById('dcForwardOn')?.classList.toggle('active', enabled);
|
|
23
|
+
document.getElementById('dcForwardOff')?.classList.toggle('active', !enabled);
|
|
24
|
+
await apiJson('/api/settings', 'PUT', { discord: { forwardAll: enabled } });
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export async function setDiscordAllowBots(allow: boolean): Promise<void> {
|
|
28
|
+
document.getElementById('dcAllowBotsOn')?.classList.toggle('active', allow);
|
|
29
|
+
document.getElementById('dcAllowBotsOff')?.classList.toggle('active', !allow);
|
|
30
|
+
await apiJson('/api/settings', 'PUT', { discord: { allowBots: allow } });
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function loadDiscordSettings(s: SettingsData): void {
|
|
34
|
+
if (!s.discord) return;
|
|
35
|
+
const dc = s.discord;
|
|
36
|
+
document.getElementById('dcOn')?.classList.toggle('active', !!dc.enabled);
|
|
37
|
+
document.getElementById('dcOff')?.classList.toggle('active', !dc.enabled);
|
|
38
|
+
const dcToken = document.getElementById('dcToken') as HTMLInputElement | null;
|
|
39
|
+
if (dc.token && dcToken) dcToken.value = dc.token;
|
|
40
|
+
const dcGuildId = document.getElementById('dcGuildId') as HTMLInputElement | null;
|
|
41
|
+
if (dc.guildId && dcGuildId) dcGuildId.value = dc.guildId;
|
|
42
|
+
const dcChannelIds = document.getElementById('dcChannelIds') as HTMLInputElement | null;
|
|
43
|
+
if (dc.channelIds?.length && dcChannelIds) {
|
|
44
|
+
dcChannelIds.value = dc.channelIds.join(', ');
|
|
45
|
+
}
|
|
46
|
+
const fwdOn = dc.forwardAll !== false;
|
|
47
|
+
document.getElementById('dcForwardOn')?.classList.toggle('active', fwdOn);
|
|
48
|
+
document.getElementById('dcForwardOff')?.classList.toggle('active', !fwdOn);
|
|
49
|
+
const allowBots = !!dc.allowBots;
|
|
50
|
+
document.getElementById('dcAllowBotsOn')?.classList.toggle('active', allowBots);
|
|
51
|
+
document.getElementById('dcAllowBotsOff')?.classList.toggle('active', !allowBots);
|
|
52
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
// ── MCP Server Settings ──
|
|
2
|
+
import { api, apiJson } from '../api.js';
|
|
3
|
+
import { escapeHtml } from '../render.js';
|
|
4
|
+
import { t } from './i18n.js';
|
|
5
|
+
|
|
6
|
+
interface McpData { servers: Record<string, { command: string; args?: string[] }>; }
|
|
7
|
+
interface McpSyncResult { results: Record<string, boolean>; }
|
|
8
|
+
interface McpInstallEntry { status: string; bin?: string; }
|
|
9
|
+
interface McpInstallResult { results: Record<string, McpInstallEntry>; }
|
|
10
|
+
|
|
11
|
+
export async function loadMcpServers(): Promise<void> {
|
|
12
|
+
try {
|
|
13
|
+
const d = await api<McpData>('/api/mcp');
|
|
14
|
+
if (!d) return;
|
|
15
|
+
const el = document.getElementById('mcpServerList');
|
|
16
|
+
if (!el) return;
|
|
17
|
+
const names = Object.entries(d.servers || {});
|
|
18
|
+
if (!names.length) { el.textContent = t('mcp.noServers'); return; }
|
|
19
|
+
el.innerHTML = names.map(([n, s]) =>
|
|
20
|
+
`<div style="padding:2px 0">• <b>${escapeHtml(n)}</b> <span style="opacity:.6">${escapeHtml(s.command)} ${(s.args || []).slice(0, 2).map(a => escapeHtml(a)).join(' ')}</span></div>`
|
|
21
|
+
).join('');
|
|
22
|
+
} catch { }
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export async function syncMcpServers(): Promise<void> {
|
|
26
|
+
const resultEl = document.getElementById('mcpSyncResult');
|
|
27
|
+
if (!resultEl) return;
|
|
28
|
+
resultEl.style.display = 'block';
|
|
29
|
+
resultEl.textContent = t('mcp.syncing');
|
|
30
|
+
try {
|
|
31
|
+
const d = await apiJson('/api/mcp/sync', 'POST', {}) as McpSyncResult | null;
|
|
32
|
+
if (!d) { resultEl.textContent = '❌ sync failed'; return; }
|
|
33
|
+
const r = d.results || {};
|
|
34
|
+
resultEl.innerHTML = Object.entries(r).map(([k, v]) =>
|
|
35
|
+
`${v ? '✅' : '⏭️'} ${escapeHtml(k)}`
|
|
36
|
+
).join(' ');
|
|
37
|
+
} catch (e) { resultEl.textContent = '❌ ' + (e as Error).message; }
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export async function installMcpGlobal(): Promise<void> {
|
|
41
|
+
const resultEl = document.getElementById('mcpSyncResult');
|
|
42
|
+
if (!resultEl) return;
|
|
43
|
+
resultEl.style.display = 'block';
|
|
44
|
+
resultEl.textContent = t('mcp.installing');
|
|
45
|
+
try {
|
|
46
|
+
const d = await apiJson('/api/mcp/install', 'POST', {}) as McpInstallResult | null;
|
|
47
|
+
if (!d) { resultEl.textContent = '❌ install failed'; return; }
|
|
48
|
+
resultEl.innerHTML = Object.entries(d.results || {}).map(([k, v]) => {
|
|
49
|
+
const icon = v.status === 'installed' ? '✅' : v.status === 'skip' ? '⏭️' : '❌';
|
|
50
|
+
return `${icon} <b>${escapeHtml(k)}</b>: ${escapeHtml(v.status)}${v.bin ? ' → ' + escapeHtml(v.bin) : ''}`;
|
|
51
|
+
}).join('<br>');
|
|
52
|
+
loadMcpServers();
|
|
53
|
+
} catch (e) { resultEl.textContent = '❌ ' + (e as Error).message; }
|
|
54
|
+
}
|