@leterhong/multichat 1.7.0 → 1.8.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.
Files changed (37) hide show
  1. package/backend/package.json +1 -1
  2. package/frontend/dist/assets/{agentPicker-DIOlVr1C.js → agentPicker-Jan8fWb3.js} +9 -9
  3. package/frontend/dist/assets/{assets-D2_TVEqD.js → assets-ChkvQqhp.js} +1 -1
  4. package/frontend/dist/assets/{compare-BYqbOF36.js → compare-CkyqXEbN.js} +1 -1
  5. package/frontend/dist/assets/conversations-DoyXfY4T.js +1 -0
  6. package/frontend/dist/assets/data-BN7t_AoO.js +1 -0
  7. package/frontend/dist/assets/{extensionImport-C2cHyfeC.js → extensionImport-DPZhdnxE.js} +10 -10
  8. package/frontend/dist/assets/{importExport-BWpKt1dW.js → importExport-Bb6-L-4y.js} +18 -18
  9. package/frontend/dist/assets/index-CeU_ksnE.js +49 -0
  10. package/frontend/dist/assets/index-DDdMiim6.css +1 -0
  11. package/frontend/dist/assets/init-yIIG9GSH.js +1 -0
  12. package/frontend/dist/assets/{modal-CO4he94s.js → modal-BYrNUOVj.js} +1 -1
  13. package/frontend/dist/assets/modelPicker-B612Gojw.js +14 -0
  14. package/frontend/dist/assets/pluginsUI-KCpFagXv.js +16 -0
  15. package/frontend/dist/assets/react-sySUN5R7.js +1 -0
  16. package/frontend/dist/assets/{render-BVmIwN3C.js → render-BBfAbC8M.js} +1 -1
  17. package/frontend/dist/assets/send-BAyqvnlM.js +14 -0
  18. package/frontend/dist/assets/settings-DkUaMAOG.js +2 -0
  19. package/frontend/dist/assets/{shell-BLqMMR-L.js → shell-Cny595HR.js} +1 -1
  20. package/frontend/dist/assets/{workbench-ChZGUESv.js → workbench-cTwE7423.js} +12 -12
  21. package/frontend/dist/boot-fallback.js +2 -0
  22. package/frontend/dist/icon-maskable.svg +18 -6
  23. package/frontend/dist/icon.svg +13 -6
  24. package/frontend/dist/index.html +6 -6
  25. package/frontend/dist/manifest.webmanifest +2 -2
  26. package/frontend/dist/theme-seed.js +10 -0
  27. package/package.json +1 -1
  28. package/frontend/dist/assets/conversations-DSJtvviE.js +0 -1
  29. package/frontend/dist/assets/data-D6TAf2h9.js +0 -1
  30. package/frontend/dist/assets/index-BaUGyQ3C.js +0 -46
  31. package/frontend/dist/assets/index-DXwClNo-.css +0 -1
  32. package/frontend/dist/assets/init-DUZJcBWS.js +0 -1
  33. package/frontend/dist/assets/modelPicker-Ddloc_nz.js +0 -14
  34. package/frontend/dist/assets/pluginsUI-28Rxtlgo.js +0 -16
  35. package/frontend/dist/assets/react-CDEwA66Z.js +0 -1
  36. package/frontend/dist/assets/send-yu3ud0kM.js +0 -14
  37. package/frontend/dist/assets/settings-IUzleKUb.js +0 -2
@@ -0,0 +1 @@
1
+ :root{--mc-p-canvas:#f7f8fa;--mc-p-surface:#fff;--mc-p-surface-subtle:#f6f7f9;--mc-p-surface-elevated:#fff;--mc-p-surface-hover:#f1f3f6;--mc-p-surface-active:#e9edf3;--mc-p-sidebar:#f3f5f8;--mc-p-sidebar-raised:#fff;--mc-p-sidebar-title:#1f2329;--mc-p-sidebar-text:#4a505c;--mc-p-sidebar-muted:#838a97;--mc-p-sidebar-faint:#a2a8b3;--mc-p-sidebar-hover:#e9edf2;--mc-p-sidebar-active:#e7edfb;--mc-p-sidebar-line:#e3e7ed;--mc-p-text:#1f2329;--mc-p-text-muted:#5a6270;--mc-p-text-subtle:#838a97;--mc-p-text-faint:#a2a8b3;--mc-p-text-disabled:#c3c8d1;--mc-p-line-faint:#f0f2f5;--mc-p-line:#e1e5eb;--mc-p-line-hover:#cbd2dc;--mc-p-line-strong:#aeb6c2;--mc-p-accent:#3b6cf6;--mc-p-accent-strong:#2f59dc;--mc-p-accent-soft:#edf2fe;--mc-p-accent-glow:#3b6cf61f;--mc-p-accent-line:#3b6cf661;--mc-p-accent-cyan:#179299;--mc-p-on-accent:#fff;--mc-p-user-surface:#eef2fd;--mc-p-user-line:#dbe4fb;--mc-p-gradient-glow:#3b6cf61a;--mc-p-warning:#df8e1d;--mc-p-warning-soft:#fdf0d5;--mc-p-danger:#d20f39;--mc-p-danger-soft:#fde3e9;--mc-p-success:#40a02b;--mc-p-success-soft:#e6f2df;--mc-p-info:#04a5e5;--mc-p-info-soft:#e2f2fc;--mc-p-ai:#3b6cf6;--mc-p-ai-soft:#edf2fe;--mc-p-scrollbar-thumb:#464e603d;--mc-p-scrollbar-thumb-hover:#464e6066;--mc-p-dark-canvas:#1e1e2e;--mc-p-dark-surface:#24243a;--mc-p-dark-surface-subtle:#2a2a42;--mc-p-dark-surface-elevated:#26263e;--mc-p-dark-surface-hover:#302f4d;--mc-p-dark-surface-active:#38375a;--mc-p-dark-sidebar:#181825;--mc-p-dark-sidebar-raised:#1e1e2e;--mc-p-dark-sidebar-title:#cdd6f4;--mc-p-dark-sidebar-text:#a6adc8;--mc-p-dark-sidebar-muted:#7f849c;--mc-p-dark-sidebar-faint:#626382;--mc-p-dark-sidebar-hover:#2b2b40;--mc-p-dark-sidebar-active:#31315a;--mc-p-dark-sidebar-line:#cdd6f414;--mc-p-dark-text:#cdd6f4;--mc-p-dark-text-muted:#a6adc8;--mc-p-dark-text-subtle:#9399b2;--mc-p-dark-text-faint:#737089;--mc-p-dark-text-disabled:#52536b;--mc-p-dark-line-faint:#cdd6f40f;--mc-p-dark-line:#cdd6f41a;--mc-p-dark-line-hover:#cdd6f429;--mc-p-dark-line-strong:#cdd6f43d;--mc-p-dark-accent:#89b4fa;--mc-p-dark-accent-strong:#b4befe;--mc-p-dark-accent-soft:#89b4fa24;--mc-p-dark-accent-glow:#89b4fa33;--mc-p-dark-accent-line:#89b4fa80;--mc-p-dark-accent-cyan:#94e2d5;--mc-p-dark-on-accent:#fff;--mc-p-dark-user-surface:#89b4fa21;--mc-p-dark-user-line:#89b4fa4d;--mc-p-dark-gradient-glow:#89b4fa24;--mc-p-dark-warning:#f9e2af;--mc-p-dark-warning-soft:#f9e2af1f;--mc-p-dark-danger:#f38ba8;--mc-p-dark-danger-soft:#f38ba81f;--mc-p-dark-success:#a6e3a1;--mc-p-dark-success-soft:#a6e3a11f;--mc-p-dark-info:#6aa5f8;--mc-p-dark-info-soft:#6aa5f81f;--mc-p-dark-ai:#89b4fa;--mc-p-dark-ai-soft:#89b4fa21;--mc-p-dark-scrollbar-thumb:#ffffff29;--mc-p-dark-scrollbar-thumb-hover:#ffffff4d;--mc-c-composer-bg:var(--mc-surface);--mc-c-composer-border:var(--mc-line);--mc-c-page-pad:30px;--mc-c-section-gap:18px}html[data-skin=graphite]{--mc-p-accent:#4b5563;--mc-p-accent-strong:#374151;--mc-p-accent-soft:#eef0f3;--mc-p-accent-glow:#4b55631f;--mc-p-accent-line:#4b556361;--mc-p-accent-cyan:#4b6b6b;--mc-p-user-surface:#eef0f3;--mc-p-user-line:#d9dee5;--mc-p-gradient-glow:#4b55631a;--mc-p-ai:#4b5563;--mc-p-ai-soft:#eef0f3;--mc-p-dark-accent:#bac2de;--mc-p-dark-accent-strong:#cdd6f4;--mc-p-dark-accent-soft:#bac2de24;--mc-p-dark-accent-glow:#bac2de33;--mc-p-dark-accent-line:#bac2de80;--mc-p-dark-accent-cyan:#94e2d5;--mc-p-dark-user-surface:#bac2de21;--mc-p-dark-user-line:#bac2de4d;--mc-p-dark-gradient-glow:#bac2de24;--mc-p-dark-ai:#bac2de;--mc-p-dark-ai-soft:#bac2de21}html[data-skin=teal]{--mc-p-accent:#0d9488;--mc-p-accent-strong:#0f766e;--mc-p-accent-soft:#e6f5f2;--mc-p-accent-glow:#0d94881f;--mc-p-accent-line:#0d948861;--mc-p-accent-cyan:#0f766e;--mc-p-user-surface:#e6f5f2;--mc-p-user-line:#c7e6e0;--mc-p-gradient-glow:#0d94881a;--mc-p-ai:#0d9488;--mc-p-ai-soft:#e6f5f2;--mc-p-dark-accent:#5eead4;--mc-p-dark-accent-strong:#99f6e4;--mc-p-dark-accent-soft:#5eead424;--mc-p-dark-accent-glow:#5eead433;--mc-p-dark-accent-line:#5eead480;--mc-p-dark-accent-cyan:#94e2d5;--mc-p-dark-user-surface:#5eead421;--mc-p-dark-user-line:#5eead44d;--mc-p-dark-gradient-glow:#5eead424;--mc-p-dark-ai:#5eead4;--mc-p-dark-ai-soft:#5eead421}html[data-density=compact]{--mc-space-1:3px;--mc-space-2:6px;--mc-space-3:9px;--mc-space-4:12px;--mc-space-5:16px;--mc-space-6:18px;--mc-space-8:24px;--mc-radius-lg:8px;--mc-radius-xl:10px;--mc-radius-2xl:12px;--mc-sidebar-width:216px;--mc-topbar-height:46px;--mc-c-page-pad:18px;--mc-c-section-gap:12px}:root{--mc-space-1:4px;--mc-space-2:8px;--mc-space-3:12px;--mc-space-4:16px;--mc-space-5:20px;--mc-space-6:24px;--mc-space-8:32px;--mc-canvas:var(--mc-p-canvas);--mc-surface:var(--mc-p-surface);--mc-surface-subtle:var(--mc-p-surface-subtle);--mc-surface-elevated:var(--mc-p-surface-elevated);--mc-surface-hover:var(--mc-p-surface-hover);--mc-surface-active:var(--mc-p-surface-active);--mc-sidebar:var(--mc-p-sidebar);--mc-sidebar-raised:var(--mc-p-sidebar-raised);--mc-sidebar-title:var(--mc-p-sidebar-title);--mc-sidebar-text:var(--mc-p-sidebar-text);--mc-sidebar-muted:var(--mc-p-sidebar-muted);--mc-sidebar-faint:var(--mc-p-sidebar-faint);--mc-sidebar-hover:var(--mc-p-sidebar-hover);--mc-sidebar-active:var(--mc-p-sidebar-active);--mc-sidebar-line:var(--mc-p-sidebar-line);--mc-text:var(--mc-p-text);--mc-text-muted:var(--mc-p-text-muted);--mc-text-subtle:var(--mc-p-text-subtle);--mc-text-faint:var(--mc-p-text-faint);--mc-text-disabled:var(--mc-p-text-disabled);--mc-line-faint:var(--mc-p-line-faint);--mc-line:var(--mc-p-line);--mc-line-hover:var(--mc-p-line-hover);--mc-line-strong:var(--mc-p-line-strong);--mc-accent:var(--mc-p-accent);--mc-accent-strong:var(--mc-p-accent-strong);--mc-accent-soft:var(--mc-p-accent-soft);--mc-accent-glow:var(--mc-p-accent-glow);--mc-accent-line:var(--mc-p-accent-line);--mc-accent-cyan:var(--mc-p-accent-cyan);--mc-on-accent:var(--mc-p-on-accent);--mc-user-surface:var(--mc-p-user-surface);--mc-user-line:var(--mc-p-user-line);--mc-gradient-accent:var(--mc-accent);--mc-gradient-glow:var(--mc-p-gradient-glow);--mc-warning:var(--mc-p-warning);--mc-warning-soft:var(--mc-p-warning-soft);--mc-danger:var(--mc-p-danger);--mc-danger-soft:var(--mc-p-danger-soft);--mc-success:var(--mc-p-success);--mc-success-soft:var(--mc-p-success-soft);--mc-info:var(--mc-p-info);--mc-info-soft:var(--mc-p-info-soft);--mc-ai:var(--mc-p-ai);--mc-ai-soft:var(--mc-p-ai-soft);--mc-radius-xs:4px;--mc-radius-sm:6px;--mc-radius-md:8px;--mc-radius-pill:999px;--mc-shadow-xs:0 1px 2px #1218280d;--mc-shadow-sm:0 2px 8px #1218280f;--mc-shadow:0 12px 32px #12182817;--mc-shadow-pop:0 24px 70px #0a101e3d;--mc-font-sans:"Inter","Aptos",-apple-system,BlinkMacSystemFont,"Segoe UI","PingFang SC","Microsoft YaHei",sans-serif;--mc-font-mono:"JetBrains Mono","SF Mono","Menlo","Consolas","Liberation Mono",monospace;--mc-easing:cubic-bezier(.22,.72,.2,1);--mc-duration-fast:.14s;--mc-duration:.2s;--mc-sidebar-width:240px;--mc-sidebar-collapsed:64px;--mc-topbar-height:52px;--mc-inspector-width:344px;--mc-reading-width:860px;--mc-z-base:1;--mc-z-sticky:20;--mc-z-drawer:60;--mc-z-overlay:100;--mc-z-toast:160;--mc-scrollbar-thumb:var(--mc-p-scrollbar-thumb);--mc-scrollbar-thumb-hover:var(--mc-p-scrollbar-thumb-hover)}:root[data-theme=dark]{--mc-canvas:var(--mc-p-dark-canvas);--mc-surface:var(--mc-p-dark-surface);--mc-surface-subtle:var(--mc-p-dark-surface-subtle);--mc-surface-elevated:var(--mc-p-dark-surface-elevated);--mc-surface-hover:var(--mc-p-dark-surface-hover);--mc-surface-active:var(--mc-p-dark-surface-active);--mc-sidebar:var(--mc-p-dark-sidebar);--mc-sidebar-raised:var(--mc-p-dark-sidebar-raised);--mc-sidebar-title:var(--mc-p-dark-sidebar-title);--mc-sidebar-text:var(--mc-p-dark-sidebar-text);--mc-sidebar-muted:var(--mc-p-dark-sidebar-muted);--mc-sidebar-faint:var(--mc-p-dark-sidebar-faint);--mc-sidebar-hover:var(--mc-p-dark-sidebar-hover);--mc-sidebar-active:var(--mc-p-dark-sidebar-active);--mc-sidebar-line:var(--mc-p-dark-sidebar-line);--mc-text:var(--mc-p-dark-text);--mc-text-muted:var(--mc-p-dark-text-muted);--mc-text-subtle:var(--mc-p-dark-text-subtle);--mc-text-faint:var(--mc-p-dark-text-faint);--mc-text-disabled:var(--mc-p-dark-text-disabled);--mc-line-faint:var(--mc-p-dark-line-faint);--mc-line:var(--mc-p-dark-line);--mc-line-hover:var(--mc-p-dark-line-hover);--mc-line-strong:var(--mc-p-dark-line-strong);--mc-accent:var(--mc-p-dark-accent);--mc-accent-strong:var(--mc-p-dark-accent-strong);--mc-accent-soft:var(--mc-p-dark-accent-soft);--mc-accent-glow:var(--mc-p-dark-accent-glow);--mc-accent-line:var(--mc-p-dark-accent-line);--mc-accent-cyan:var(--mc-p-dark-accent-cyan);--mc-on-accent:var(--mc-p-dark-on-accent);--mc-user-surface:var(--mc-p-dark-user-surface);--mc-user-line:var(--mc-p-dark-user-line);--mc-gradient-accent:var(--mc-accent);--mc-gradient-glow:var(--mc-p-dark-gradient-glow);--mc-warning:var(--mc-p-dark-warning);--mc-warning-soft:var(--mc-p-dark-warning-soft);--mc-danger:var(--mc-p-dark-danger);--mc-danger-soft:var(--mc-p-dark-danger-soft);--mc-success:var(--mc-p-dark-success);--mc-success-soft:var(--mc-p-dark-success-soft);--mc-info:var(--mc-p-dark-info);--mc-info-soft:var(--mc-p-dark-info-soft);--mc-ai:var(--mc-p-dark-ai);--mc-ai-soft:var(--mc-p-dark-ai-soft);--mc-shadow-xs:0 1px 2px #00000059;--mc-shadow-sm:0 2px 8px #0006;--mc-shadow:0 12px 32px #00000073;--mc-shadow-pop:0 24px 70px #0009;--mc-scrollbar-thumb:var(--mc-p-dark-scrollbar-thumb);--mc-scrollbar-thumb-hover:var(--mc-p-dark-scrollbar-thumb-hover);--lightningcss-light: ;--lightningcss-dark:initial;color-scheme:dark}*,:after,:before{box-sizing:border-box}#root,body,html{width:100%;height:100%}body{background:var(--mc-canvas);color:var(--mc-text);font-family:var(--mc-font-sans);-webkit-font-smoothing:antialiased;text-rendering:optimizelegibility;font-size:14px;line-height:1.55}body,h1,h2,h3,h4,p{margin:0}button{color:inherit;cursor:pointer;font:inherit;background:0 0;border:0;padding:0}button:disabled{cursor:not-allowed;opacity:.55}input,select,textarea{color:inherit;font:inherit}a{color:var(--mc-accent);text-decoration:none}a:hover{text-decoration:underline}code,kbd,pre{font-family:var(--mc-font-mono)}kbd{background:var(--mc-surface-subtle);border:solid var(--mc-line);border-radius:var(--mc-radius-xs);color:var(--mc-text-muted);border-width:1px 1px 2px;padding:1px 6px;font-size:11px;display:inline-block}:focus-visible{border-radius:var(--mc-radius-xs);outline:2px solid var(--mc-accent);outline-offset:2px}::-webkit-scrollbar{width:10px;height:10px}::-webkit-scrollbar-thumb{border-radius:var(--mc-radius-pill)}::-webkit-scrollbar-thumb{border:2px solid #0000}::-webkit-scrollbar-thumb:hover{border:2px solid #0000}::-webkit-scrollbar-track{background:0 0}*{scrollbar-color:var(--mc-scrollbar-thumb) transparent;scrollbar-width:thin}.sr-only{clip:rect(0 0 0 0);white-space:nowrap;border:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.spacer{flex:1}.lead,.lead-tight,.muted{color:var(--mc-text-muted)}.lead,.lead-tight{font-size:13px;line-height:1.65}.lead-tight{line-height:1.5}.sep{background:var(--mc-line);flex:none;width:1px;height:18px}.left{text-align:left}.app{background:var(--mc-canvas);grid-template-columns:var(--mc-sidebar-width) minmax(0,1fr);width:100%;height:100dvh;display:grid;overflow:hidden}.app.shell-collapsed{grid-template-columns:var(--mc-sidebar-collapsed) minmax(0,1fr)}.sidebar{border-right:1px solid var(--mc-sidebar-line);flex-direction:column;gap:4px;min-width:0;min-height:0;padding:12px 10px 10px;display:flex;overflow:hidden auto}.sidebar-head,.sidebar>.brand{align-items:center;gap:10px;padding:2px 6px 10px;display:flex}.brand-logo{flex:none}.brand-copy{min-width:0}.brand-copy strong{color:var(--mc-sidebar-title);letter-spacing:-.01em;font-size:14.5px;font-weight:700;display:block}.brand-copy small,.brand-copy span{color:var(--mc-sidebar-muted);font-size:11px;display:block}.sidebar-collapse{margin-left:auto}.shell-collapsed .sidebar .brand-copy,.shell-collapsed .sidebar .recent-work-actions,.shell-collapsed .sidebar .sidebar-section-label,.shell-collapsed .sidebar .sidebar-workspace-switcher>svg,.shell-collapsed .sidebar kbd,.shell-collapsed .sidebar span:not(.workspace-switcher-mark):not(.recent-indicator):not(.model-glyph):not(.model-status-dot):not(.picker-status){display:none}.shell-collapsed .sidebar .new-task-button,.shell-collapsed .sidebar .primary-nav button,.shell-collapsed .sidebar .recent-work-open,.shell-collapsed .sidebar .sidebar-utility,.shell-collapsed .sidebar .sidebar-workspace-switcher{justify-content:center}.sidebar-workspace-switcher{border-radius:var(--mc-radius-md);text-align:left;transition:background var(--mc-duration-fast) var(--mc-easing);align-items:center;gap:10px;width:100%;padding:9px 10px;display:flex}.sidebar-workspace-switcher:hover{background:var(--mc-sidebar-hover)}.sidebar-workspace-switcher span{flex:1;min-width:0}.sidebar-workspace-switcher strong{color:var(--mc-sidebar-title);font-size:13px;font-weight:650}.sidebar-workspace-switcher small,.sidebar-workspace-switcher strong{text-overflow:ellipsis;white-space:nowrap;display:block;overflow:hidden}.sidebar-workspace-switcher small{color:var(--mc-sidebar-muted);font-size:11px}.workspace-switcher-mark{background:var(--mc-accent);border-radius:var(--mc-radius-sm);color:var(--mc-on-accent);flex:none;justify-content:center;align-items:center;width:28px;height:28px;font-size:13px;font-weight:700;display:inline-flex}.sidebar-section-label{color:var(--mc-sidebar-faint);letter-spacing:.08em;text-transform:uppercase;padding:14px 10px 6px;font-size:10.5px;font-weight:700}.primary-nav{flex-direction:column;gap:2px;display:flex}.primary-nav button{border-radius:var(--mc-radius-md);color:var(--mc-sidebar-text);text-align:left;transition:background var(--mc-duration-fast) var(--mc-easing),color var(--mc-duration-fast) var(--mc-easing);align-items:center;gap:10px;width:100%;padding:8px 10px;font-size:13px;font-weight:560;display:flex}.primary-nav button:hover{background:var(--mc-sidebar-hover);color:var(--mc-sidebar-title)}.primary-nav button.active{box-shadow:var(--mc-shadow-xs)}.recent-work{flex-direction:column;flex:1;min-height:0;margin-top:4px;display:flex}.recent-work-heading{justify-content:space-between;align-items:center;padding:12px 10px 6px;display:flex}.recent-work-heading span{color:var(--mc-sidebar-faint);letter-spacing:.08em;text-transform:uppercase;font-size:10.5px;font-weight:700}.recent-work-heading button{border-radius:var(--mc-radius-xs);color:var(--mc-sidebar-muted);font-size:11.5px}.recent-work-heading button:hover{color:var(--mc-accent)}.recent-work-list{flex-direction:column;gap:2px;min-height:0;display:flex;overflow-y:auto}.recent-work-row{border-radius:var(--mc-radius-md);transition:background var(--mc-duration-fast) var(--mc-easing);align-items:center;gap:2px;display:flex}.recent-work-row:hover{background:var(--mc-sidebar-hover)}.recent-work-row.active{box-shadow:var(--mc-shadow-xs)}.recent-work-open{text-align:left;flex:1;align-items:center;gap:9px;min-width:0;padding:7px 6px 7px 10px;display:flex}.recent-indicator{background:var(--mc-line-strong);border-radius:50%;flex:none;width:6px;height:6px}.recent-work-row.active .recent-indicator{background:var(--mc-accent)}.recent-work-copy{flex:1;min-width:0}.recent-work-copy strong{color:var(--mc-sidebar-title);text-overflow:ellipsis;white-space:nowrap;font-size:12.5px;font-weight:570;display:block;overflow:hidden}.recent-work-copy small{color:var(--mc-sidebar-muted);font-size:10.5px;display:block}.recent-work-actions{align-items:center;gap:2px;padding-right:6px;display:none}.recent-work-row:focus-within .recent-work-actions,.recent-work-row:hover .recent-work-actions{display:flex}.recent-work-actions button{border-radius:var(--mc-radius-xs);color:var(--mc-sidebar-muted);justify-content:center;align-items:center;width:24px;height:24px;display:inline-flex}.recent-work-actions button:hover{background:var(--mc-sidebar-hover);color:var(--mc-danger)}.sidebar p{color:var(--mc-sidebar-muted);padding:10px;font-size:11.5px}.sidebar-footer{border-top:1px solid var(--mc-sidebar-line);margin-top:auto;padding-top:8px}.sidebar-utility{border-radius:var(--mc-radius-md);color:var(--mc-sidebar-text);align-items:center;gap:10px;width:100%;padding:8px 10px;font-size:12.5px;display:flex}.sidebar-utility:hover{background:var(--mc-sidebar-hover)}.sidebar-utility kbd{margin-left:auto;font-size:10px}.new-task{margin:4px 0 2px;position:relative}.new-task-button{background:var(--mc-accent);border-radius:var(--mc-radius-md);color:var(--mc-on-accent);min-height:38px;transition:background var(--mc-duration-fast) var(--mc-easing),transform var(--mc-duration-fast) var(--mc-easing);align-items:center;gap:9px;width:100%;padding:0 12px;font-size:13px;font-weight:650;display:flex}.new-task-button:hover{background:var(--mc-accent-strong)}.new-task-button:active{transform:scale(.985)}.new-task-button span{text-align:left;flex:1}.new-task-menu{animation:menu-in var(--mc-duration) var(--mc-easing);background:var(--mc-surface-elevated);border:1px solid var(--mc-line);border-radius:var(--mc-radius-lg);box-shadow:var(--mc-shadow);z-index:var(--mc-z-sticky);padding:6px;position:absolute;top:calc(100% + 6px);left:0;right:0}.new-task-menu button{border-radius:var(--mc-radius-md);text-align:left;align-items:flex-start;gap:10px;width:100%;padding:9px 10px;display:flex}.new-task-menu button:hover{background:var(--mc-surface-hover)}.new-task-menu svg{color:var(--mc-accent);margin-top:2px}.new-task-menu strong{font-size:13px;font-weight:640;display:block}.new-task-menu small{color:var(--mc-text-muted);font-size:11.5px;display:block}.workspace-frame{grid-template-rows:var(--mc-topbar-height) minmax(0,1fr);min-width:0;min-height:0;display:grid;overflow:hidden}.topbar{background:var(--mc-canvas);border-bottom:1px solid var(--mc-line-faint);grid-row:1;align-items:center;gap:8px;min-width:0;padding:0 14px 0 16px;display:flex}.topbar-context{min-width:0;margin-right:6px}.topbar-title{color:var(--mc-text);font-size:13.5px;font-weight:660}.topbar-path,.topbar-title{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.topbar-path{color:var(--mc-text-faint);font-size:11px}.topbar-spacer{flex:1}.global-search{background:var(--mc-surface);border:1px solid var(--mc-line);border-radius:var(--mc-radius-md);color:var(--mc-text-faint);min-width:0;max-width:380px;transition:border-color var(--mc-duration-fast) var(--mc-easing);flex:1;align-items:center;gap:8px;padding:6px 10px;font-size:12.5px;display:flex}.global-search:hover{border-color:var(--mc-line-hover)}.global-search span{text-align:left;text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0;overflow:hidden}.connection-status{border-radius:var(--mc-radius-pill);color:var(--mc-text-muted);white-space:nowrap;align-items:center;gap:7px;padding:4px 10px;font-size:11.5px;font-weight:600;display:inline-flex}.connection-status i{background:var(--mc-success);border-radius:50%;width:7px;height:7px}.connection-status.busy i{background:var(--mc-warning);animation:1.6s ease-out infinite pulse-dot}.mobile-menu{display:none}.mobile-scrim,.scrim{opacity:0;pointer-events:none;transition:opacity var(--mc-duration) var(--mc-easing);z-index:var(--mc-z-drawer);background:#090d146b;position:fixed;inset:0}.mobile-scrim.open,.scrim.open{opacity:1;pointer-events:auto}.main{grid-row:2;display:flex;position:relative;overflow:hidden}.content,.main{background:var(--mc-canvas);min-width:0;min-height:0}.content{flex:1;overflow:hidden auto}.icon-btn{border-radius:var(--mc-radius-md);color:var(--mc-text-muted);height:32px;transition:background var(--mc-duration-fast) var(--mc-easing),color var(--mc-duration-fast) var(--mc-easing),transform var(--mc-duration-fast) var(--mc-easing);justify-content:center;align-items:center;width:32px;display:inline-flex}.icon-btn:hover{background:var(--mc-surface-hover);color:var(--mc-text)}.icon-btn:active{transform:scale(.94)}.close-round{background:var(--mc-surface-subtle);border-radius:50%}.btn-primary{background:var(--mc-accent);border-radius:var(--mc-radius-md);color:var(--mc-on-accent);transition:background var(--mc-duration-fast) var(--mc-easing),transform var(--mc-duration-fast) var(--mc-easing),box-shadow var(--mc-duration-fast) var(--mc-easing);white-space:nowrap;align-items:center;gap:8px;padding:9px 18px;font-size:13px;font-weight:640;display:inline-flex}.btn-primary:hover{background:var(--mc-accent-strong);box-shadow:0 4px 14px var(--mc-accent-glow)}.btn-primary:active{transform:scale(.97)}.btn-ghost{background:var(--mc-surface);border:1px solid var(--mc-line);border-radius:var(--mc-radius-md);color:var(--mc-text);transition:border-color var(--mc-duration-fast) var(--mc-easing),background var(--mc-duration-fast) var(--mc-easing),transform var(--mc-duration-fast) var(--mc-easing);white-space:nowrap;align-items:center;gap:7px;padding:8px 14px;font-size:12.5px;font-weight:570;display:inline-flex}.btn-ghost:hover{background:var(--mc-surface-hover);border-color:var(--mc-line-hover)}.btn-ghost:active{transform:scale(.97)}.btn-danger,.danger-ghost{color:var(--mc-danger)}.danger-ghost{border-radius:var(--mc-radius-md);background:0 0;border:1px solid #0000;align-items:center;gap:7px;padding:8px 14px;font-size:12.5px;font-weight:570;display:inline-flex}.danger-ghost:hover{background:var(--mc-danger-soft)}.btn-auto{border-radius:var(--mc-radius-md);color:var(--mc-accent-strong);align-items:center;gap:7px;padding:7px 12px;font-size:12.5px;font-weight:620;display:inline-flex}.btn-auto,.btn-auto:hover{background:var(--mc-accent-soft)}.btn-auto:hover{filter:brightness(.97)}:root[data-theme=dark] .btn-auto:hover{filter:brightness(1.15)}.field{flex-direction:column;gap:6px;min-width:0;display:flex}.field>label,.field>strong{color:var(--mc-text-muted);font-size:12px;font-weight:620}.field input,.field select,.field textarea,.form-control,input[type=number],input[type=password],input[type=search],input[type=text],select,textarea{background:var(--mc-surface);border:1px solid var(--mc-line);border-radius:var(--mc-radius-md);color:var(--mc-text);transition:border-color var(--mc-duration-fast) var(--mc-easing),box-shadow var(--mc-duration-fast) var(--mc-easing);width:100%;padding:9px 12px;font-size:13px}.field input:hover,.field select:hover,.field textarea:hover,.form-control:hover{border-color:var(--mc-line-hover)}.field input:focus,.field select:focus,.field textarea:focus,.form-control:focus,input:focus,textarea:focus{border-color:var(--mc-accent);box-shadow:0 0 0 3px var(--mc-accent-glow);outline:none}.field textarea{resize:vertical;min-height:72px}.field-hint{color:var(--mc-text-faint);font-size:11.5px;line-height:1.5}input[type=range]{accent-color:var(--mc-accent);appearance:none;background:var(--mc-line);border-radius:var(--mc-radius-pill);cursor:pointer;border:0;width:100%;height:4px}input[type=range]::-webkit-slider-thumb{appearance:none;background:var(--mc-accent);border:2px solid var(--mc-surface);box-shadow:var(--mc-shadow-xs);border-radius:50%;width:16px;height:16px}input[type=checkbox]{accent-color:var(--mc-accent);width:16px;height:16px}select{appearance:none;background-image:linear-gradient(45deg,transparent 50%,var(--mc-text-faint) 50%),linear-gradient(135deg,var(--mc-text-faint) 50%,transparent 50%);background-position:calc(100% - 16px) 55%,calc(100% - 11px) 55%;background-repeat:no-repeat;background-size:5px 5px;padding-right:30px}.mc-tag{background:var(--mc-surface-subtle);border-radius:var(--mc-radius-pill);color:var(--mc-text-muted);white-space:nowrap;align-items:center;gap:5px;padding:3px 9px;font-size:11px;font-weight:600;display:inline-flex}.mc-tag.on{color:var(--mc-accent-strong)}:root[data-theme=dark] .mc-tag.on{color:var(--mc-accent)}.mc-tags{flex-wrap:wrap;gap:6px;display:flex}.ok{color:var(--mc-success)}.warn{color:var(--mc-warning)}.danger,.error{color:var(--mc-danger)}.success{color:var(--mc-success)}.info{color:var(--mc-info)}.value{font-variant-numeric:tabular-nums;font-weight:640}.pmeta,.speed{color:var(--mc-text-faint);font-variant-numeric:tabular-nums;font-size:11.5px}.ui-skeleton{background:linear-gradient(100deg,var(--mc-surface-subtle) 40%,var(--mc-surface-hover) 50%,var(--mc-surface-subtle) 60%);border-radius:var(--mc-radius-md);background-size:200% 100%;animation:1.4s ease-in-out infinite skeleton-sweep}.home-workbench,.workspace-home{animation:view-in .35s var(--mc-easing);background:var(--mc-canvas);width:100%;min-height:100%;padding:0 0 64px}.home-hero{flex-direction:column;align-items:flex-start;width:min(1020px,100%);margin:0 auto;padding:clamp(30px,6vh,60px) 30px 8px;display:flex}.hero-eyebrow{color:var(--mc-accent);letter-spacing:.34em;text-transform:uppercase;margin:0 0 14px;font-size:11px;font-weight:700}.hero-display{color:var(--mc-text);letter-spacing:-.025em;margin:0 0 16px;font-size:clamp(34px,5vw,58px);font-weight:700;line-height:1.06}.hero-sub{color:var(--mc-text-muted);margin:0 0 24px;font-size:15px;line-height:1.7}.hero-cta-row{flex-wrap:wrap;align-items:center;gap:12px;display:flex}.hero-cta-primary{background:var(--mc-accent);border-radius:var(--mc-radius-md);color:var(--mc-on-accent);transition:background var(--mc-duration-fast) var(--mc-easing),transform var(--mc-duration-fast) var(--mc-easing),box-shadow var(--mc-duration-fast) var(--mc-easing);align-items:center;gap:8px;padding:11px 22px;font-size:13.5px;font-weight:650;display:inline-flex}.hero-cta-primary:hover{background:var(--mc-accent-strong);box-shadow:0 6px 18px var(--mc-accent-glow);transform:translateY(-1px)}.hero-cta-primary:active{transform:scale(.97)}.hero-cta-ghost{border-radius:var(--mc-radius-pill);color:var(--mc-text);gap:10px;padding:6px 18px 6px 7px;font-size:13px;font-weight:600}.hero-cta-ghost,.hero-play{align-items:center;display:inline-flex}.hero-play{background:var(--mc-surface);border:1px solid var(--mc-line);color:var(--mc-text-muted);height:32px;transition:border-color var(--mc-duration-fast) var(--mc-easing),color var(--mc-duration-fast) var(--mc-easing),background var(--mc-duration-fast) var(--mc-easing);border-radius:50%;justify-content:center;width:32px}.hero-play svg{margin-left:2px}.hero-cta-ghost:hover .hero-play{background:var(--mc-accent-soft);border-color:var(--mc-accent-line);color:var(--mc-accent)}.hero-live{color:var(--mc-text-faint);letter-spacing:.18em;text-transform:uppercase;align-items:center;gap:8px;margin-top:26px;font-size:11px;font-weight:650;display:inline-flex}.hero-live-dot{border-radius:50%;width:7px;height:7px}.hero-scroll-cue{border-radius:var(--mc-radius-pill);color:var(--mc-text-faint);letter-spacing:.26em;align-self:flex-end;align-items:center;gap:8px;margin-top:18px;padding:8px 13px;font-size:10.5px;font-weight:650;display:inline-flex}.hero-scroll-cue:hover{background:var(--mc-accent-soft);color:var(--mc-accent)}.hero-announce{border-bottom:1px solid var(--mc-line-faint);color:var(--mc-text-muted);justify-content:center;align-items:center;gap:8px;width:100%;padding:9px 18px;font-size:12px;display:flex}.hero-announce:hover{color:var(--mc-accent)}.home-task-entry{padding:var(--mc-c-page-pad) var(--mc-c-page-pad) 0;width:min(1020px,100%);margin:0 auto}.home-workspace-context{color:var(--mc-text-subtle);align-items:center;gap:8px;min-height:20px;margin-bottom:10px;font-size:12px;display:flex}.home-workspace-context button{border-radius:var(--mc-radius-sm);color:var(--mc-text-muted);align-items:center;gap:6px;padding:3px 8px;font-size:12px;display:inline-flex}.home-workspace-context button:hover{background:var(--mc-surface-hover);color:var(--mc-text)}.home-task-entry h1,.home-task-entry h2{color:var(--mc-text);letter-spacing:-.02em;font-size:24px;font-weight:700}.home-main-grid{align-items:start;gap:var(--mc-c-section-gap);grid-template-columns:minmax(0,1fr) 300px;display:grid}.home-compose-column{flex-direction:column;gap:14px;min-width:0;display:flex}.universal-composer{background:var(--mc-c-composer-bg);border:1px solid var(--mc-c-composer-border);border-radius:var(--mc-radius-lg);box-shadow:var(--mc-shadow-sm);transition:border-color var(--mc-duration-fast) var(--mc-easing),box-shadow var(--mc-duration-fast) var(--mc-easing);padding:14px}.universal-composer:focus-within{border-color:var(--mc-accent);box-shadow:0 0 0 3px var(--mc-accent-glow)}.home-mode-row{justify-content:space-between;align-items:center;gap:12px;display:flex}.home-mode-row.is-outside{margin:0 0 var(--mc-space-2);padding:0 2px}.home-mode-row.is-outside .task-mode-switch{background:var(--mc-surface-subtle)}.home-mode-row.is-outside .home-mode-description{color:var(--mc-text-subtle)}.task-mode-switch{background:var(--mc-surface-subtle);border-radius:var(--mc-radius-md);gap:2px;padding:3px;display:inline-flex}.task-mode-switch button{border-radius:var(--mc-radius-sm);color:var(--mc-text-muted);transition:background var(--mc-duration-fast) var(--mc-easing),color var(--mc-duration-fast) var(--mc-easing),box-shadow var(--mc-duration-fast) var(--mc-easing);padding:5px 13px;font-size:12.5px;font-weight:600}.task-mode-switch button:hover{color:var(--mc-text)}.task-mode-switch button.active{background:var(--mc-surface);box-shadow:var(--mc-shadow-xs);color:var(--mc-text)}.home-mode-description,.mode-description{color:var(--mc-text-faint);font-size:12px}.composer-input,.hero-input,textarea#heroInput{color:var(--mc-text);resize:none;background:0 0;border:0;width:100%;min-height:96px;padding:4px 6px;font-size:14px;line-height:1.6}.composer-input:focus,.hero-input:focus{box-shadow:none;border:0;outline:none}.composer-actions,.hero-actions{border-top:1px solid var(--mc-line-faint);align-items:center;gap:6px;padding-top:10px;display:flex}.composer-actions button,.composer-tool,.hero-actions button{border-radius:var(--mc-radius-sm);color:var(--mc-text-muted);transition:background var(--mc-duration-fast) var(--mc-easing),color var(--mc-duration-fast) var(--mc-easing);align-items:center;gap:6px;padding:6px 10px;font-size:12px;font-weight:560;display:inline-flex}.composer-actions button:hover,.composer-tool:hover,.hero-actions button:hover{background:var(--mc-surface-hover);color:var(--mc-text)}.composer-context-summary{color:var(--mc-text-faint);white-space:nowrap;font-size:11.5px}.contextual-agent,.hero-model,.model-picker{background:var(--mc-surface);border:1px solid var(--mc-line);border-radius:var(--mc-radius-md);color:var(--mc-text);white-space:nowrap;align-items:center;gap:7px;max-width:220px;padding:6px 11px;font-size:12px;font-weight:580;display:inline-flex}.hero-model:hover,.model-picker:hover{background:var(--mc-surface-hover);border-color:var(--mc-line-hover)}.hero-model span,.mp-name{text-overflow:ellipsis;min-width:0;overflow:hidden}.send-btn{background:var(--mc-accent);border-radius:var(--mc-radius-md);color:var(--mc-on-accent);height:34px;transition:background var(--mc-duration-fast) var(--mc-easing),transform var(--mc-duration-fast) var(--mc-easing);flex:none;justify-content:center;align-items:center;width:34px;display:inline-flex}.send-btn:hover:not(:disabled){background:var(--mc-accent-strong)}.send-btn:active:not(:disabled){transform:scale(.92)}.send-btn.stop{background:var(--mc-danger);color:#fff}.home-quick{flex-wrap:wrap;align-items:center;gap:8px;display:flex}.home-quick>span{color:var(--mc-text-faint);font-size:12px;font-weight:600}.home-quick button{background:var(--mc-surface);border:1px solid var(--mc-line);color:var(--mc-text-muted);transition:border-color var(--mc-duration-fast) var(--mc-easing),color var(--mc-duration-fast) var(--mc-easing),background var(--mc-duration-fast) var(--mc-easing);padding:6px 13px;font-size:12px}.home-quick button:hover{color:var(--mc-accent)}.home-footnote{color:var(--mc-text-faint);font-size:11.5px}.home-recent{background:var(--mc-surface);border:1px solid var(--mc-line);border-radius:var(--mc-radius-lg);box-shadow:var(--mc-shadow-sm);padding:14px}.home-recent>header{border-bottom:1px solid var(--mc-line-faint);justify-content:space-between;align-items:flex-start;gap:10px;padding-bottom:10px;display:flex}.home-recent h2{font-size:14px;font-weight:680}.home-recent header p{color:var(--mc-text-faint);margin-top:2px;font-size:11.5px}.home-recent header>span{color:var(--mc-text-faint);white-space:nowrap;font-size:11px}.home-recent-list{flex-direction:column;padding-top:6px;display:flex}.home-recent-list button{border-radius:var(--mc-radius-md);text-align:left;transition:background var(--mc-duration-fast) var(--mc-easing);align-items:center;gap:10px;width:100%;padding:9px 8px;display:flex}.home-recent-list button:hover{background:var(--mc-surface-hover)}.home-recent-mark{background:var(--mc-surface-subtle);border-radius:var(--mc-radius-sm);color:var(--mc-text-muted);flex:none;justify-content:center;align-items:center;width:28px;height:28px;font-size:12px;font-weight:700;display:inline-flex}.home-recent-copy{flex:1;min-width:0}.home-recent-title{text-overflow:ellipsis;white-space:nowrap;font-size:12.5px;font-weight:590;display:block;overflow:hidden}.home-recent-meta{color:var(--mc-text-faint);font-size:10.5px;display:block}.home-recent-arrow{color:var(--mc-text-faint);opacity:.5;transition:transform var(--mc-duration) var(--mc-easing),opacity var(--mc-duration) var(--mc-easing)}.home-recent-list button:hover .home-recent-arrow{opacity:1;transform:translate(3px)}.home-recent-empty{color:var(--mc-text-muted);padding:18px 8px;font-size:12.5px}.home-recent-empty small{color:var(--mc-text-faint);margin-top:3px;font-size:11px;display:block}.chat-workspace{animation:view-in .3s var(--mc-easing);background:var(--mc-canvas);flex-direction:column;width:100%;height:100%;min-height:0;padding:0;display:flex}.conversation-canvas{flex-direction:column;flex:1;min-height:0;display:flex}.task-header{color:var(--mc-text-faint);justify-content:space-between;align-items:center;gap:12px;padding:10px 26px;font-size:11.5px;display:flex}.task-header>span:first-child{color:var(--mc-text-muted);font-weight:600}.task-header .running{align-items:center;gap:7px;display:inline-flex}.run-dot,.task-header .running i{background:var(--mc-accent);border-radius:50%;width:7px;height:7px}.task-header .running.running i,.task-header span.running i{animation:1.6s ease-out infinite pulse-dot}.transcript{flex:1;min-height:0;padding:6px 0 12px;overflow-y:auto}.transcript-virtual:focus{outline:none}.transcript-footer{height:8px}.msg{width:min(var(--mc-reading-width),calc(100% - 48px));gap:12px;margin:0 auto 22px;padding:0 2px;display:flex}.msg.user{flex-direction:row-reverse}.msg-avatar{border-radius:var(--mc-radius-md);color:var(--mc-text-muted);flex:none;justify-content:center;align-items:center;width:32px;height:32px;font-size:12px;font-weight:700;display:inline-flex;overflow:hidden}.msg-body{flex-direction:column;gap:6px;min-width:0;max-width:calc(100% - 44px);display:flex}.msg.user .msg-body{align-items:flex-end}.msg-role{align-items:center;gap:8px;min-height:18px;font-size:12px;display:flex}.message-identity{color:var(--mc-text-muted);align-items:center;gap:6px;font-weight:650;display:inline-flex}.model-status-dot{background:var(--mc-ai);border-radius:50%;width:7px;height:7px}.msg-model{background:var(--mc-ai-soft);border-radius:var(--mc-radius-pill);color:var(--mc-ai);padding:2px 8px;font-size:10.5px;font-weight:650}.message-hover-meta{color:var(--mc-text-faint);opacity:0;transition:opacity var(--mc-duration) var(--mc-easing);font-size:11px}.msg:hover .message-hover-meta{opacity:1}.busy-label{color:var(--mc-text-faint);font-size:11px;font-weight:620}.msg-content{background:var(--mc-surface);border:1px solid var(--mc-line);border-radius:var(--mc-radius-lg);overflow-wrap:break-word;min-width:0;max-width:100%;padding:10px 14px;font-size:14px;line-height:1.7}.msg-content.user-plain-text{border-bottom-right-radius:var(--mc-radius-xs);border-color:var(--mc-user-line);white-space:pre-wrap}.msg.streaming .msg-actions,.msg:hover .msg-actions{opacity:1}.msg-actions{opacity:0;transition:opacity var(--mc-duration) var(--mc-easing);align-items:center;gap:4px;display:flex}.msg-action{border-radius:var(--mc-radius-sm);color:var(--mc-text-faint);padding:4px 9px;font-size:11.5px}.msg-action:hover{background:var(--mc-surface-hover);color:var(--mc-text)}.msg-stats{color:var(--mc-text-faint);font-variant-numeric:tabular-nums;flex-wrap:wrap;gap:10px;font-size:11px;display:flex}.mc-trace,.think-row{background:var(--mc-surface);overflow:hidden}.mc-trace summary,.think-row summary{color:var(--mc-text-muted);cursor:pointer;-webkit-user-select:none;user-select:none;align-items:center;gap:8px;padding:8px 12px;font-size:12px;font-weight:620;list-style:none;display:flex}.mc-trace summary::-webkit-details-marker{display:none}.think-row summary::-webkit-details-marker{display:none}.think-caret,.think-ico,.tool-caret,.trace-ico-svg{color:var(--mc-text-faint);flex:none}.think-caret{transition:transform var(--mc-duration) var(--mc-easing);margin-left:auto;transform:rotate(0)}.mc-trace[open] .think-caret,.think-row[open] .think-caret{transform:rotate(180deg)}.think-summary{color:var(--mc-text-faint);text-overflow:ellipsis;white-space:nowrap;min-width:0;margin-left:auto;font-size:11px;font-weight:500;overflow:hidden}.think-row[data-state=running] summary{color:var(--mc-accent)}.think-body,.tool-body,.trace-body{border-top:1px solid var(--mc-line-faint);color:var(--mc-text-muted);white-space:pre-wrap;max-height:260px;padding:10px 12px;font-size:12.5px;line-height:1.65;overflow-y:auto}.tool-name,.trace-label{color:var(--mc-text);font-weight:640}.tool-summary,.trace-count,.trace-dur,.trace-status,.trace-step{color:var(--mc-text-faint);font-size:11px}.trace-main{min-width:0}.mcp-warning{background:var(--mc-warning-soft);border-left:3px solid var(--mc-warning);border-radius:var(--mc-radius-sm);color:var(--mc-warning);margin-bottom:10px;padding:9px 12px;font-size:12px}.mcp-warning strong{margin-bottom:3px;display:block}.code-block{background:var(--mc-surface-subtle);border:1px solid var(--mc-line);border-radius:var(--mc-radius-md);margin:10px 0;position:relative;overflow:hidden}.code-block pre{margin:0;padding:12px 14px;font-size:12.5px;line-height:1.6;overflow-x:auto}.code-copy{background:var(--mc-surface);border:1px solid var(--mc-line);border-radius:var(--mc-radius-sm);color:var(--mc-text-muted);opacity:0;transition:opacity var(--mc-duration) var(--mc-easing);padding:4px 10px;font-size:11px;position:absolute;top:6px;right:6px}.code-block:hover .code-copy{opacity:1}.composer-wrap{background:var(--mc-surface);border:1px solid var(--mc-line);border-radius:var(--mc-radius-lg);box-shadow:var(--mc-shadow-sm);transition:border-color var(--mc-duration-fast) var(--mc-easing),box-shadow var(--mc-duration-fast) var(--mc-easing);width:min(var(--mc-reading-width),calc(100% - 48px));margin:0 auto 18px;padding:12px 14px}.composer-wrap:focus-within{border-color:var(--mc-accent);box-shadow:0 0 0 3px var(--mc-accent-glow)}.composer-start{width:min(640px,100% - 40px);margin-top:14px}.empty-task-shell{animation:view-in .35s var(--mc-easing);flex-direction:column;flex:1;justify-content:center;align-items:center;padding:30px 20px 60px;display:flex}.empty-task-heading{text-align:center;margin-bottom:18px}.empty-task-heading span{color:var(--mc-accent);letter-spacing:.3em;text-transform:uppercase;font-size:11px;font-weight:700}.empty-task-heading h1{letter-spacing:-.02em;margin:10px 0 8px;font-size:26px;font-weight:720}.empty-task-heading p{color:var(--mc-text-muted);font-size:13.5px}.composer{flex-direction:column;display:flex}.composer-hint{color:var(--mc-text-faint);text-align:center;margin-top:8px;font-size:11px}.composer-tool-label{color:var(--mc-text-muted)}.ctx-hint,.file-ctx{color:var(--mc-text-faint);font-size:11.5px}.ctx-hint,.file-ctx-body{padding:2px 0}.card-grid{grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:14px;display:grid}.agent-card,.control-card-head,.mc-card,.passport-card,.provider-card,.skill-card,.tool-card,.workflow-block{background:var(--mc-surface);border:1px solid var(--mc-line);border-radius:var(--mc-radius-lg)}.agent-card,.mc-card,.passport-card,.provider-card,.tool-card{transition:border-color var(--mc-duration-fast) var(--mc-easing),box-shadow var(--mc-duration) var(--mc-easing);flex-direction:column;gap:10px;padding:15px;display:flex}.agent-card:hover,.mc-card:hover,.passport-card:hover,.provider-card:hover,.tool-card:hover{box-shadow:var(--mc-shadow-sm)}.mc-top,.passport-head,.provider-card-head,.tool-card>header{align-items:center;gap:10px;display:flex}.mc-ico{background:var(--mc-accent-soft);border-radius:var(--mc-radius-md);color:var(--mc-accent);flex:none;justify-content:center;align-items:center;width:34px;height:34px;display:inline-flex}.mc-title-wrap,.provider-identity{flex:1;min-width:0}.mc-title{font-size:13.5px;font-weight:660}.mc-sub,.mc-title,.provider-id,.tpl-name{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.mc-sub,.provider-id,.tpl-name{color:var(--mc-text-faint);font-size:11.5px}.mc-desc{color:var(--mc-text-muted);min-height:0;font-size:12.5px;line-height:1.6}.mc-actions{flex-wrap:wrap;align-items:center;gap:7px;margin-top:auto;display:flex}.extension-card-actions{margin-top:4px}.mc-act{background:var(--mc-surface);border:1px solid var(--mc-line);border-radius:var(--mc-radius-md);color:var(--mc-text);transition:border-color var(--mc-duration-fast) var(--mc-easing),background var(--mc-duration-fast) var(--mc-easing);white-space:nowrap;padding:6px 12px;font-size:12px;font-weight:580}.mc-act:hover{background:var(--mc-surface-hover);border-color:var(--mc-line-hover)}.mc-act.primary{background:var(--mc-accent-soft);border-color:var(--mc-accent-line);color:var(--mc-accent-strong)}:root[data-theme=dark] .mc-act.primary{color:var(--mc-accent)}.mc-act.danger{color:var(--mc-danger);border-color:#0000}.mc-act.danger:hover{background:var(--mc-danger-soft)}.mc-act.wide{flex:1;justify-content:center;min-width:0}.mc-toggle{background:var(--mc-surface);border:1px solid var(--mc-line);border-radius:var(--mc-radius-md);color:var(--mc-text-muted);align-items:center;gap:8px;padding:6px 12px;font-size:12px;font-weight:580;display:inline-flex}.mc-toggle.on{background:var(--mc-accent-soft);border-color:var(--mc-accent-line);color:var(--mc-accent-strong)}:root[data-theme=dark] .mc-toggle.on{color:var(--mc-accent)}.mc-switch{background:var(--mc-line-strong);border-radius:var(--mc-radius-pill);height:15px;transition:background var(--mc-duration-fast) var(--mc-easing);width:26px;position:relative}.mc-switch:after{background:var(--mc-surface);content:"";height:11px;transition:transform var(--mc-duration-fast) var(--mc-easing);border-radius:50%;width:11px;position:absolute;top:2px;left:2px}.mc-toggle.on .mc-switch{background:var(--mc-accent)}.mc-toggle.on .mc-switch:after{transform:translate(11px)}.add-provider,.add-tile,.mc-add,.mc-add-tile{border:1px dashed var(--mc-line-strong);border-radius:var(--mc-radius-lg);color:var(--mc-text-muted);text-align:left;min-height:110px;transition:border-color var(--mc-duration-fast) var(--mc-easing),color var(--mc-duration-fast) var(--mc-easing),background var(--mc-duration-fast) var(--mc-easing);flex-direction:column;align-items:flex-start;gap:6px;padding:15px;display:flex}.add-provider:hover,.add-tile:hover,.mc-add:hover{background:var(--mc-accent-soft);border-color:var(--mc-accent-line);color:var(--mc-accent)}.plus-t{color:var(--mc-text);font-size:13px;font-weight:650}.mc-add .plus-t{color:inherit}.auth-error,.mc-sub{font-size:11.5px}.auth-error{background:var(--mc-danger-soft);border-radius:var(--mc-radius-sm);color:var(--mc-danger);-webkit-line-clamp:2;text-overflow:ellipsis;-webkit-box-orient:vertical;padding:8px 11px;line-height:1.5;display:-webkit-box;overflow:hidden}.activity-empty,.compare-empty,.control-empty,.empty-state,.extension-empty,.plan-empty,.provider-empty,.rail-empty,.usage-empty{border:1px dashed var(--mc-line);border-radius:var(--mc-radius-lg);color:var(--mc-text-muted);text-align:center;padding:26px 18px;font-size:12.5px}.settings{background:var(--mc-canvas);opacity:0;transition:opacity var(--mc-duration) var(--mc-easing),visibility 0s linear var(--mc-duration);visibility:hidden;z-index:var(--mc-z-overlay);display:flex;position:fixed;inset:0}.settings.open{opacity:1;transition:opacity var(--mc-duration) var(--mc-easing);visibility:visible}.settings-side{background:var(--mc-sidebar);border-right:1px solid var(--mc-line-faint);flex-direction:column;flex:none;gap:2px;width:264px;padding:16px 12px;display:flex;overflow-y:auto}.settings-brand{align-items:center;gap:10px;padding:4px 8px 16px;display:flex}.settings-brand strong{font-size:14px;font-weight:700;display:block}.settings-brand span{color:var(--mc-text-faint);font-size:11px}.settings-group-label{color:var(--mc-text-faint);letter-spacing:.08em;text-transform:uppercase;padding:12px 10px 5px;font-size:10.5px;font-weight:700}.settings-nav-group{flex-direction:column;gap:2px;display:flex}.settings-tab{border-radius:var(--mc-radius-md);color:var(--mc-text-muted);text-align:left;transition:background var(--mc-duration-fast) var(--mc-easing),color var(--mc-duration-fast) var(--mc-easing);align-items:center;gap:10px;width:100%;padding:8px 10px;font-size:13px;font-weight:560;display:flex}.settings-tab:hover{background:var(--mc-sidebar-hover);color:var(--mc-text)}.settings-tab.active{background:var(--mc-sidebar-active);box-shadow:var(--mc-shadow-xs);color:var(--mc-text)}.tab-ico{color:var(--mc-text-faint);flex:none}.settings-tab.active .tab-ico{color:var(--mc-accent)}.settings-side-spacer{flex:1}.settings-body{flex:1;min-width:0;padding:30px clamp(20px,5vw,56px) 60px;overflow-y:auto}.settings-page-heading,.settings-subtitle{margin-bottom:20px}.settings-body h2,.settings-body h3{letter-spacing:-.01em;font-size:17px;font-weight:700}.settings-body>h3{margin:26px 0 12px;font-size:14px}.settings-top{position:absolute;top:14px;right:16px}.settings-group{margin-bottom:26px}.agent-studio-grid,.passport-grid,.provider-add-grid,.provider-grid,.usage-grid{grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:14px;display:grid}.provider-card-fields,.provider-config-card{flex-direction:column;gap:12px;display:flex}.provider-config-card .field input,.provider-config-card .field textarea{background:var(--mc-surface)}.passport-summary,.provider-caps,.provider-summary{flex-wrap:wrap;gap:6px;display:flex}.provider-private,.provider-row,.provider-state{color:var(--mc-text-muted);align-items:center;gap:8px;font-size:12px;display:flex}.memory-mark,.picker-provider-mark,.provider-mark,.rail-current-model-mark,.snapshot-mark{background:var(--mc-surface-subtle);border-radius:var(--mc-radius-xs);color:var(--mc-text-muted);flex:none;justify-content:center;align-items:center;width:22px;height:22px;font-size:11px;font-weight:700;display:inline-flex}.provider-probe-result,.provider-template-grid,.tool-test-result{margin-top:2px}.provider-probe-result,.tool-test-result{background:var(--mc-info-soft);border-radius:var(--mc-radius-sm);color:var(--mc-info);padding:9px 11px;font-size:11.5px;line-height:1.55}.provider-template-grid{grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:8px;display:grid}.heading-actions-row{flex-wrap:wrap;justify-content:space-between;align-items:center;gap:12px;margin-bottom:14px;display:flex}.settings-page-heading{flex-direction:column;gap:4px;display:flex}.compact-action{padding:7px 13px}.usage-layout,.usage-panel{flex-direction:column;gap:16px;display:flex}.usage-heading,.usage-heading-actions,.usage-panel-head{flex-wrap:wrap;justify-content:space-between;align-items:center;gap:12px;display:flex}.usage-kicker{color:var(--mc-text-faint);letter-spacing:.1em;text-transform:uppercase;font-size:11px;font-weight:700}.usage-metric,.usage-metrics{gap:12px;display:grid}.usage-metrics{grid-template-columns:repeat(auto-fit,minmax(180px,1fr))}.usage-metric{background:var(--mc-surface);border:1px solid var(--mc-line);border-radius:var(--mc-radius-lg);padding:14px}.usage-date,.usage-metric .label{color:var(--mc-text-faint);font-size:11px;font-weight:620}.usage-metric .value{letter-spacing:-.01em;font-size:20px}.usage-bar-input,.usage-bar-output,.usage-donut,.usage-heatmap,.usage-line,.usage-trend{background:var(--mc-surface);border:1px solid var(--mc-line);border-radius:var(--mc-radius-lg);padding:14px}.usage-insights,.usage-legend,.usage-model-list,.usage-provider-list,.usage-ranges{color:var(--mc-text-muted);flex-wrap:wrap;gap:8px;font-size:12px;display:flex}.usage-loading{color:var(--mc-text-faint);padding:20px 0;font-size:12.5px}.usage-wide{grid-column:1/-1}.usage-page{flex-direction:column;gap:16px;display:flex}.execution-detail,.knowledge-results,.memory-list,.run-list,.snapshot-list{flex-direction:column;gap:8px;display:flex}.activity-item,.knowledge-hit,.memory-item,.run-row,.snapshot-item{background:var(--mc-surface);border:1px solid var(--mc-line);border-radius:var(--mc-radius-md);transition:border-color var(--mc-duration-fast) var(--mc-easing),background var(--mc-duration-fast) var(--mc-easing);align-items:center;gap:10px;padding:10px 12px;display:flex}.activity-item:hover,.knowledge-hit:hover,.memory-item:hover,.run-row:hover,.snapshot-item:hover{background:var(--mc-surface-hover);border-color:var(--mc-line-hover)}.knowledge-hit>div,.memory-item>div,.run-main{flex:1;min-width:0}.fc-name,.knowledge-hit strong,.memory-item strong,.run-title{text-overflow:ellipsis;white-space:nowrap;font-size:12.5px;font-weight:620;display:block;overflow:hidden}.activity-item small,.fc-meta,.knowledge-hit small,.memory-item small,.run-meta,.snapshot-item small{color:var(--mc-text-faint);font-size:11px;display:block}.activity-status,.execution-status,.inspector-status,.picker-option-state,.run-state,.run-status{background:var(--mc-surface-subtle);border-radius:var(--mc-radius-pill);color:var(--mc-text-muted);white-space:nowrap;align-items:center;gap:6px;padding:3px 9px;font-size:10.5px;font-weight:650;display:inline-flex}.activity-status.completed,.execution-status.done,.picker-option-state.ok,.run-state.completed,.run-state.ready,.run-status.ready{background:var(--mc-success-soft);color:var(--mc-success)}.activity-status.running,.execution-status.running,.run-paused,.run-state.running,.run-status.running{background:var(--mc-info-soft);color:var(--mc-info)}.activity-status.error,.compare-cancelled,.compare-error,.execution-status.error,.run-state.error,.run-status.error{background:var(--mc-danger-soft);color:var(--mc-danger)}.run-open,.run-row-button{color:var(--mc-text-faint);flex:none}.run-open:hover,.run-row-button:hover{color:var(--mc-accent)}.compare-config,.compare-history,.compare-lab,.compare-result,.compare-results{background:var(--mc-surface);border:1px solid var(--mc-line);border-radius:var(--mc-radius-lg)}.compare-config,.compare-lab{flex-direction:column;gap:14px;padding:16px;display:flex}.compare-results{gap:12px;margin-top:14px;padding:16px;display:grid}.compare-result{flex-direction:column;gap:10px;padding:14px;display:flex}.compare-result-body{color:var(--mc-text);overflow-wrap:break-word;font-size:13.5px;line-height:1.7}.compare-state{align-self:flex-start}.compare-context,.compare-intro,.compare-prompt-label,.compare-targets{color:var(--mc-text-muted);font-size:12.5px}.compare-actions{flex-wrap:wrap;align-items:center;gap:8px;display:flex}.compare-summary{color:var(--mc-text-muted);font-size:12.5px}.compare-history-item{border:1px solid var(--mc-line-faint);border-radius:var(--mc-radius-md);align-items:center;gap:10px;padding:9px 11px;font-size:12.5px;display:flex}.compare-history-empty{color:var(--mc-text-faint);font-size:12px}.compare-adopt{margin-left:auto}.compare-loading{color:var(--mc-text-faint);font-size:12.5px;animation:1.6s ease-in-out infinite skeleton-sweep}.modal{z-index:var(--mc-z-overlay);background:#090d1470;justify-content:center;align-items:center;padding:24px;display:none;position:fixed;inset:0}.modal.open{animation:fade-in var(--mc-duration) var(--mc-easing);display:flex}.modal-card{background:var(--mc-surface-elevated);border:1px solid var(--mc-line);border-radius:var(--mc-radius-xl);box-shadow:var(--mc-shadow-pop);width:min(760px,100%);max-height:min(86dvh,900px);padding:20px;overflow-y:auto}.modal.open .modal-card{animation:pop-in .28s var(--mc-easing)}.modal-close,.modal-heading{display:flex}.modal-heading{justify-content:space-between;align-items:center;gap:12px;margin-bottom:14px}.modal-heading h2{font-size:16px;font-weight:700}.command-palette{z-index:var(--mc-z-overlay);background:#090d1466;justify-content:center;align-items:flex-start;padding:12vh 20px 20px;display:none;position:fixed;inset:0}.command-palette.open{animation:fade-in var(--mc-duration) var(--mc-easing);display:flex}.command-panel{background:var(--mc-surface-elevated);border:1px solid var(--mc-line);border-radius:var(--mc-radius-xl);box-shadow:var(--mc-shadow-pop);width:min(600px,100%);max-height:68dvh;padding:10px;overflow:hidden auto}.command-palette.open .command-panel{animation:pop-in .24s var(--mc-easing)}.command-search-wrap{background:var(--mc-surface);border:1px solid var(--mc-line);border-radius:var(--mc-radius-md);color:var(--mc-text-faint);align-items:center;gap:9px;padding:9px 11px;display:flex}.command-search-wrap input{color:var(--mc-text);background:0 0;border:0;flex:1;font-size:13.5px}.command-search-wrap input:focus{box-shadow:none;outline:none}.command-caption{color:var(--mc-text-faint);letter-spacing:.08em;text-transform:uppercase;padding:12px 10px 6px;font-size:10.5px;font-weight:700}.command-list{flex-direction:column;gap:2px;display:flex}.command-item{border-radius:var(--mc-radius-md);text-align:left;transition:background var(--mc-duration-fast) var(--mc-easing);align-items:center;gap:10px;padding:9px 10px;display:flex}.command-item:focus-visible,.command-item:hover{background:var(--mc-surface-hover)}.command-item-copy{flex:1;min-width:0}.command-item-copy strong{font-size:13px;font-weight:590;display:block}.command-item-copy small{color:var(--mc-text-faint);font-size:11px;display:block}.command-item-group{color:var(--mc-text-faint);white-space:nowrap;font-size:10.5px}.command-empty{color:var(--mc-text-faint);text-align:center;padding:20px 10px;font-size:12.5px}.toast{background:var(--mc-surface-elevated);border:1px solid var(--mc-line);box-shadow:var(--mc-shadow);color:var(--mc-text);opacity:0;pointer-events:none;max-width:min(460px,100vw - 40px);transition:opacity var(--mc-duration) var(--mc-easing),transform var(--mc-duration) var(--mc-easing);z-index:var(--mc-z-toast);padding:11px 16px;font-size:13px;position:fixed;bottom:22px;left:50%;transform:translate(-50%)translateY(0)}.toast.open,.toast.show{opacity:1;transform:translate(-50%)translateY(-4px)}.toast.error{border-color:var(--mc-danger);color:var(--mc-danger)}.workspace-rail{background:var(--mc-sidebar);border-left:1px solid var(--mc-line);bottom:0;right:0;top:var(--mc-topbar-height);transition:transform .26s var(--mc-easing);visibility:hidden;width:min(var(--mc-inspector-width),94vw);z-index:var(--mc-z-drawer);flex-direction:column;display:flex;position:fixed;transform:translate(102%)}body.workflow-rail-open .workspace-rail{visibility:visible;transform:none}.workflow-rail-body,.workflow-rail-close,.workflow-rail-head{display:flex}.workflow-rail-head{justify-content:space-between;align-items:center;gap:10px;padding:12px 14px 8px}.workflow-rail-body{flex-direction:column;flex:1;gap:10px;min-height:0;padding:0 12px 16px;overflow-y:auto}.workflow-tabs,.workflow-task-tabs{background:var(--mc-surface-subtle);border-radius:var(--mc-radius-md);gap:2px;padding:3px;display:flex}.workflow-tabs button,.workflow-task-tabs button{border-radius:var(--mc-radius-sm);color:var(--mc-text-muted);flex:1;padding:6px 8px;font-size:12px;font-weight:600}.workflow-tabs button.active,.workflow-task-tabs button.active{background:var(--mc-surface);box-shadow:var(--mc-shadow-xs);color:var(--mc-text)}.rail-tab-panel,.workflow-block{flex-direction:column;gap:10px;display:flex}.workflow-block{padding:12px}.workflow-block-head{color:var(--mc-text-muted);justify-content:space-between;align-items:center;gap:8px;font-size:12px;font-weight:660;display:flex}.rail-model-switcher{border:0}.rail-model-switcher summary{cursor:pointer;list-style:none}.rail-model-switcher summary::-webkit-details-marker{display:none}.rail-model-menu{flex-direction:column;gap:2px;max-height:240px;margin-top:8px;display:flex;overflow-y:auto}.mp-option,.rail-model-menu button{border-radius:var(--mc-radius-sm);text-align:left;align-items:center;gap:8px;padding:7px 9px;font-size:12.5px;display:flex}.mp-option:hover,.rail-model-menu button:hover{background:var(--mc-surface-hover)}.rail-local-note,.rail-metric-grid{color:var(--mc-text-muted);font-size:11.5px}.rail-metric-grid{grid-template-columns:1fr 1fr;gap:8px;display:grid}.rail-metric-grid .value{font-size:16px}.mode-segments{background:var(--mc-surface-subtle);border-radius:var(--mc-radius-md);gap:2px;padding:3px;display:flex}.mode-segments button{border-radius:var(--mc-radius-sm);color:var(--mc-text-muted);flex:1;padding:5px 8px;font-size:12px;font-weight:600}.mode-segments button.active{background:var(--mc-surface);box-shadow:var(--mc-shadow-xs);color:var(--mc-text)}.verification-list{flex-direction:column;gap:6px;display:flex}.verification-list button{border-radius:var(--mc-radius-sm);color:var(--mc-text-muted);text-align:left;align-items:center;gap:8px;padding:7px 9px;font-size:12.5px;display:flex}.verification-list button:hover{background:var(--mc-surface-hover)}.verification-list button.active{color:var(--mc-success)}.workflow-context-grid{grid-template-columns:1fr 1fr;gap:8px;display:grid}.workflow-folder-action{border:1px dashed var(--mc-line-strong);border-radius:var(--mc-radius-md);color:var(--mc-text-muted);align-items:center;gap:8px;padding:9px 10px;font-size:12.5px;display:flex}.workflow-folder-action:hover{border-color:var(--mc-accent-line);color:var(--mc-accent)}.workflow-rail-scrim{opacity:0;pointer-events:none;transition:opacity var(--mc-duration) var(--mc-easing);z-index:calc(var(--mc-z-drawer) - 1);background:#090d1452;position:fixed;inset:0}body.workflow-rail-open .workflow-rail-scrim{opacity:1;pointer-events:auto}.plan-block{background:var(--mc-surface);border:1px solid var(--mc-line);border-radius:var(--mc-radius-md);flex-direction:column;gap:8px;padding:10px 12px;display:flex}.plan-progress-head{justify-content:space-between;align-items:center;font-size:12px;font-weight:640;display:flex}.plan-progress-track{background:var(--mc-line);border-radius:var(--mc-radius-pill);height:5px;overflow:hidden}.plan-progress-track i{background:var(--mc-accent);border-radius:inherit;height:100%;transition:width var(--mc-duration) var(--mc-easing);display:block}.plan-step-list{flex-direction:column;gap:4px;display:flex}.flight-step,.plan-step-list>div{border-radius:var(--mc-radius-sm);align-items:center;gap:8px;padding:5px 6px;font-size:12.5px;display:flex}.plan-step-remove,.plan-step-toggle{color:var(--mc-text-faint);margin-left:auto}.plan-step-remove:hover{color:var(--mc-danger)}.flight-timeline{flex-direction:column;gap:4px;display:flex}.flight-step{color:var(--mc-text-muted)}.execution-meta{color:var(--mc-text-faint);font-variant-numeric:tabular-nums;font-size:11px}.ctx-hint,.file-ctx-head{color:var(--mc-text-muted);font-size:11.5px;font-weight:600}.context-source-block,.context-source-list{flex-direction:column;gap:6px;display:flex}.context-source{color:var(--mc-text-muted);align-items:center;gap:8px;font-size:12px;display:flex}.context-budget{background:var(--mc-surface);border:1px solid var(--mc-line);border-radius:var(--mc-radius-md);flex-direction:column;gap:8px;padding:10px 12px;display:flex}.context-budget-title{font-size:12px;font-weight:650}.context-budget-track{background:var(--mc-line);border-radius:var(--mc-radius-pill);height:5px;overflow:hidden}.context-budget-track i{background:var(--mc-accent);height:100%;display:block}.context-budget-legend{color:var(--mc-text-faint);gap:10px;font-size:10.5px;display:flex}.context-lens,.metrics-context-card{background:var(--mc-surface);border:1px solid var(--mc-line);border-radius:var(--mc-radius-md);color:var(--mc-text-muted);padding:10px 12px;font-size:12px}.extension-heading,.extension-heading-actions,.extension-import-confirm{display:flex}.extension-heading{flex-direction:column;gap:4px;margin-bottom:16px}.extension-heading h3{font-size:16px;font-weight:700}.extension-heading-actions{flex-wrap:wrap;align-items:center;gap:8px}.extension-source{color:var(--mc-text-faint);align-items:center;gap:8px;font-size:11px;display:flex}.extension-source span:first-child{flex:none;font-weight:640}.extension-source span:last-child{min-width:0}.extension-command,.extension-source span:last-child{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.extension-command{background:var(--mc-surface-subtle);border-radius:var(--mc-radius-sm);color:var(--mc-text-muted);font-family:var(--mc-font-mono);padding:7px 10px;font-size:11.5px}.extension-tool-list{flex-wrap:wrap;gap:5px;display:flex}.extension-tool-list span{background:var(--mc-surface-subtle);border-radius:var(--mc-radius-pill);color:var(--mc-text-muted);font-family:var(--mc-font-mono);padding:3px 8px;font-size:10.5px}.extension-dropzone{border:1px dashed var(--mc-line-strong);border-radius:var(--mc-radius-lg);color:var(--mc-text-muted);transition:border-color var(--mc-duration-fast) var(--mc-easing),background var(--mc-duration-fast) var(--mc-easing);flex-direction:column;align-items:center;gap:8px;padding:34px 20px;font-size:13px;display:flex}.extension-dropzone.over,.extension-dropzone:hover{background:var(--mc-accent-soft);border-color:var(--mc-accent)}.extension-drop-icon{color:var(--mc-text-faint)}.extension-import-list{flex-direction:column;gap:6px;display:flex}.extension-import-row{border:1px solid var(--mc-line-faint);border-radius:var(--mc-radius-sm);align-items:center;gap:9px;padding:8px 10px;font-size:12.5px;display:flex}.extension-import-name{font-weight:620}.extension-import-note,.extension-import-summary,.extension-import-warnings{color:var(--mc-text-muted);font-size:11.5px;line-height:1.55}.extension-import-kind,.extension-import-scope,.extension-import-tags{flex-wrap:wrap;gap:5px;display:flex}.extension-import-conflicts,.extension-import-warnings{color:var(--mc-warning)}.diff-context,.diff-summary,.extension-checks,.extension-diff{background:var(--mc-surface);border:1px solid var(--mc-line);border-radius:var(--mc-radius-md);font-size:12.5px}.diff-context,.extension-diff{font-family:var(--mc-font-mono);white-space:pre-wrap;max-height:300px;padding:10px 12px;font-size:11.5px;overflow:auto}.diff-summary{color:var(--mc-text-muted);align-items:center;padding:8px 11px}.diff-actions,.diff-summary{gap:8px;display:flex}.approval-card,.approval-wrap,.extension-pick-status{font-size:12px}.approval-card,.approval-wrap{background:var(--mc-surface);border:1px solid var(--mc-line);border-radius:var(--mc-radius-md);flex-direction:column;gap:8px;padding:10px 12px;display:flex}.ap-actions,.ap-args,.ap-head,.ap-perms{flex-wrap:wrap;align-items:center;gap:8px;display:flex}.ap-tool{font-family:var(--mc-font-mono);font-size:12px;font-weight:640}.ap-args-label{color:var(--mc-text-faint);font-size:11px;font-weight:650}.ap-args{font-family:var(--mc-font-mono);overflow-wrap:anywhere;font-size:11.5px}.ap-args,.ap-perm{color:var(--mc-text-muted)}.ap-perm{border:1px solid var(--mc-line);border-radius:var(--mc-radius-pill);padding:3px 9px;font-size:11px}.ap-perm.ap-trust{border-color:var(--mc-success);color:var(--mc-success)}.ap-btn{border:1px solid var(--mc-line);border-radius:var(--mc-radius-sm);padding:5px 11px;font-size:12px}.ap-btn:hover{background:var(--mc-surface-hover)}.ap-btn.ap-approve{background:var(--mc-success);border-color:var(--mc-success);color:#fff}.ap-btn.ap-approve:hover{filter:brightness(.94)}.ap-btn.ap-reject{border-color:var(--mc-danger);color:var(--mc-danger)}.ap-btn.ap-reject:hover{background:var(--mc-danger-soft)}.ap-resolved{color:var(--mc-text-faint);font-size:11.5px}.extension-file-tree{border:1px solid var(--mc-line);border-radius:var(--mc-radius-md);font-family:var(--mc-font-mono);max-height:260px;padding:8px 10px;overflow:auto}.extension-file-tree,.passport-issues,.passport-risk,.passport-type{color:var(--mc-text-muted);font-size:12px}.passport-toolbar{flex-wrap:wrap;gap:8px;display:flex}.passport-clean{color:var(--mc-success);font-size:12px}.passport-perms{flex-wrap:wrap;gap:6px;display:flex}.acceptance-block{background:var(--mc-info-soft);border-radius:var(--mc-radius-sm);color:var(--mc-info);padding:9px 11px;font-size:12px;line-height:1.55}.agent-capability-summary,.agent-studio-grid>*{min-width:0}.model-picker .model-picker-list,.model-picker-list{flex-direction:column;gap:2px;max-height:320px;display:flex;overflow-y:auto}.model-block{padding:10px 12px}.model-picker{position:relative}.picker-status{background:var(--mc-success);border-radius:50%;width:7px;height:7px}.mp-name,.picker-option-copy{min-width:0}.picker-dialog-intro{color:var(--mc-text-muted);margin-bottom:12px;font-size:12.5px}.picker-import-project{margin-top:10px}.cached,.estimate-note{color:var(--mc-text-faint);font-size:11px}.boot-error{color:var(--mc-danger);text-align:center;padding:20px}.import-bar,.import-bar-label{color:var(--mc-text-muted);align-items:center;gap:8px;font-size:12px;display:flex}.mini-btn{border:1px solid var(--mc-line);border-radius:var(--mc-radius-sm);color:var(--mc-text-muted);padding:4px 10px;font-size:11.5px}.mini-btn:hover{background:var(--mc-surface-hover);color:var(--mc-text)}.row{align-items:center;gap:8px;display:flex}.folder,.resource-count,.resource-search,.resource-toolbar,.workspace-file-actions,.workspace-resource-list{color:var(--mc-text-muted);font-size:12px}.resource-toolbar{flex-wrap:wrap;align-items:center;gap:8px;display:flex}.workspace-resource-list{flex-direction:column;gap:4px;display:flex}.inspector-checks,.inspector-facts,.inspector-metrics,.inspector-section{color:var(--mc-text-muted);flex-direction:column;gap:6px;font-size:12px;display:flex}.inspector-section-head{color:var(--mc-text);font-weight:660}.inspector-check,.inspector-note,.inspector-score{align-items:center;gap:7px;display:flex}.inspector-run{margin-top:4px}.inspector-empty{color:var(--mc-text-faint);padding:12px 0;font-size:12px}.fc-check,.fc-count,.fc-item,.fc-title{color:var(--mc-text-muted);font-size:12px}.fc-actions{gap:6px;display:flex}.execution-detail .run-detail-grid{grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:8px;display:grid}.run-detail-summary{color:var(--mc-text-muted);font-size:12px}.activity-summary.done,.execution-status.completed,.is-approved,.verification-list .done{color:var(--mc-success)}.is-rejected{color:var(--mc-danger)}.approved{color:var(--mc-success)}.rejected{color:var(--mc-danger)}.resolved{color:var(--mc-text-faint)}.active-state,.completed,.done,.on,.ready,.start,.started,.stop{font-weight:620}@keyframes view-in{0%{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}@keyframes fade-in{0%{opacity:0}to{opacity:1}}@keyframes pop-in{0%{opacity:0;transform:translateY(10px)scale(.98)}to{opacity:1;transform:translateY(0)scale(1)}}@keyframes menu-in{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}@keyframes pulse-dot{0%{box-shadow:0 0 0 0 var(--mc-accent-glow)}70%{box-shadow:0 0 0 7px #0000}to{box-shadow:0 0 #0000}}@keyframes skeleton-sweep{0%{background-position:120% 0}to{background-position:-120% 0}}@media (width<=1100px){.home-main-grid{grid-template-columns:1fr}}@media (width<=800px){.app{grid-template-columns:1fr}.sidebar{transition:transform .26s var(--mc-easing);width:min(300px,86vw);z-index:calc(var(--mc-z-drawer) + 1);position:fixed;top:0;bottom:0;left:0;transform:translate(-102%)}.sidebar.open{transform:none}.mobile-menu{display:inline-flex}.global-search,.hero-scroll-cue{display:none}.home-hero,.home-task-entry{padding-inline:20px}.composer-wrap,.msg{width:calc(100% - 24px)}.settings-side{width:220px}}@media (prefers-reduced-motion:reduce){*,:after,:before{transition-duration:.01ms!important;animation-duration:.01ms!important;animation-iteration-count:1!important}}.ap-badge{background:var(--mc-surface-subtle);border-radius:var(--mc-radius-pill);color:var(--mc-text-muted);padding:2px 8px;font-size:10.5px;font-weight:650}.brand-arc,.brand-core{display:block}.command-arrow{color:var(--mc-text-faint)}.compare-answer{background:var(--mc-surface-subtle);border:1px solid var(--mc-line);border-radius:var(--mc-radius-sm);color:var(--mc-text-muted);white-space:pre-wrap;max-height:220px;padding:9px 11px;font-size:12.5px;overflow-y:auto}.confirm-message{color:var(--mc-text-muted);font-size:13px;line-height:1.6}.context-budget-card{background:var(--mc-surface);border:1px solid var(--mc-line);border-radius:var(--mc-radius-md);flex-direction:column;gap:8px;padding:10px 12px;display:flex}.diff-git-status{color:var(--mc-text-faint);font-family:var(--mc-font-mono);font-size:11px}.diff-message{background:var(--mc-surface-subtle);border-radius:var(--mc-radius-sm);color:var(--mc-text-muted);white-space:pre-wrap;padding:8px 10px;font-size:12px}.diff-summary-icon{color:var(--mc-text-faint)}.memory-item.disabled{opacity:.62}.memory-actions,.memory-toggle{align-items:center;gap:6px;display:inline-flex}.memory-toggle{color:var(--mc-text-faint);margin-left:auto}.provider-state.local,.provider-state.ready{background:var(--mc-success-soft);color:var(--mc-success)}.provider-state.error,.provider-state.offline{background:var(--mc-danger-soft);color:var(--mc-danger)}.provider-card-footer{flex-wrap:wrap;align-items:center;gap:8px;margin-top:auto;display:flex}.passport-page,.provider-settings{flex-direction:column;gap:16px;display:flex}.activity-block,.activity-list{flex-direction:column;gap:6px;display:flex}.experiment-settings{flex-direction:column;gap:16px;display:flex}.experiment-requirement{background:var(--mc-warning-soft);border-radius:var(--mc-radius-sm);color:var(--mc-warning);padding:9px 12px;font-size:12.5px}.hero-tag{background:var(--mc-surface);border:1px solid var(--mc-line);border-radius:var(--mc-radius-pill);color:var(--mc-text-muted);gap:6px;padding:4px 11px;font-size:11.5px}.hero-tag,.ico{align-items:center;display:inline-flex}.ico{justify-content:center}.add-tile .ico{font-size:18px}.mcp-security-note{background:var(--mc-info-soft);border-radius:var(--mc-radius-sm);color:var(--mc-info);padding:9px 11px;font-size:12px;line-height:1.55}.knowledge-search{border-top:1px solid var(--mc-line-faint);align-items:center;gap:8px;margin-top:12px;padding-top:12px;display:flex}.knowledge-search input{flex:1;min-width:0}.plan-add{border:1px dashed var(--mc-line-strong);border-radius:var(--mc-radius-sm);color:var(--mc-text-muted);align-self:flex-start;padding:6px 12px;font-size:12px}.plan-add:hover{border-color:var(--mc-accent-line);color:var(--mc-accent)}.rail-back{align-items:center;gap:6px;display:inline-flex}.rail-empty-action{background:var(--mc-accent-soft);border-radius:var(--mc-radius-md);color:var(--mc-accent-strong);align-self:flex-start;padding:7px 13px;font-size:12.5px;font-weight:620}:root[data-theme=dark] .rail-empty-action{color:var(--mc-accent)}.rail-empty-action:hover{filter:brightness(.97)}:root[data-theme=dark] .rail-empty-action:hover{filter:brightness(1.12)}.settings-close-side{margin-top:10px}.extension-picker-actions,.skill-card-actions,.tpl-actions{flex-wrap:wrap;align-items:center;gap:7px;margin-top:auto;display:flex}.task-only{display:none}.topbar .task-only,body.task-view .task-only{display:inline-flex}.tpl-meta{color:var(--mc-text-faint);font-size:11px}.tpl-save{margin-left:auto}.trace-title{color:var(--mc-text);font-size:12px;font-weight:640}.trace-sub{color:var(--mc-text-faint);font-size:11px}.usage-model-wrap{flex-direction:column;gap:8px;display:flex}.usage-legend .input{align-items:center;gap:5px;display:inline-flex}.usage-legend .input:before,.usage-legend .output:before{background:var(--mc-accent);content:"";border-radius:3px;width:9px;height:9px}.usage-legend .output:before{background:var(--mc-ai)}.memory-item .memory-actions button,.msg-actions .msg-action{color:var(--mc-text-faint)}.card-grid>.mc-add{justify-content:center}.provider-card-fields .row{flex-wrap:wrap}.command-list .command-item[aria-selected=true]{background:var(--mc-surface-hover)}input[type=checkbox]+label{cursor:pointer;align-items:center;gap:7px;display:inline-flex}label:has(input[type=checkbox]){cursor:pointer;align-items:center;gap:7px;display:inline-flex}.compare-actions .is-stopping{background:var(--mc-danger);color:#fff}.sidebar-close{border-radius:var(--mc-radius-md);color:var(--mc-sidebar-muted);align-items:center;gap:8px;padding:8px 10px;font-size:12.5px;display:inline-flex}.sidebar-close:hover{background:var(--mc-sidebar-hover);color:var(--mc-sidebar-title)}[hidden]{display:none!important}.hero-scroll-cue{justify-content:flex-end;align-self:auto;width:min(1020px,100%);margin:0 auto;padding:0 30px;display:flex}.home-hero{min-height:clamp(320px,calc(100vh - var(--mc-topbar-height) - 430px),480px);text-align:center;align-items:center;padding-top:clamp(48px,10vh,96px)}.hero-display{letter-spacing:-.02em}.hero-sub{max-width:520px}.hero-cta-row,.hero-live{justify-content:center}.hero-eyebrow,.hero-scroll-cue{display:none}.primary-nav button.active,.recent-work-row.active{box-shadow:none}.recent-work-row.active .recent-work-copy strong{font-weight:640}.composer-wrap,.universal-composer{border-radius:var(--mc-radius-xl);box-shadow:var(--mc-shadow-xs)}.composer-wrap:focus-within,.universal-composer:focus-within{box-shadow:var(--mc-shadow-sm)}.mode-segments,.task-mode-switch{background:0 0;gap:8px;padding:0}.mode-segments button,.task-mode-switch button{background:var(--mc-surface);border:1px solid var(--mc-line);border-radius:var(--mc-radius-pill);box-shadow:none;color:var(--mc-text-muted);padding:6px 15px}.mode-segments button:hover,.task-mode-switch button:hover{background:var(--mc-surface);border-color:var(--mc-line-hover);color:var(--mc-text)}.mode-segments button.active,.task-mode-switch button.active{background:var(--mc-accent-soft);border-color:var(--mc-accent);box-shadow:none;color:var(--mc-accent)}.workflow-tabs,.workflow-task-tabs{background:0 0}.workflow-tabs button,.workflow-task-tabs button{border-radius:var(--mc-radius-pill);border:1px solid #0000}.workflow-tabs button.active,.workflow-task-tabs button.active{background:var(--mc-surface-subtle);border-color:var(--mc-line);box-shadow:none}.send-btn{border-radius:var(--mc-radius-lg)}.msg-content.user-plain-text{border-bottom-right-radius:var(--mc-radius-lg)}.msg-avatar{background:var(--mc-accent-soft);border-radius:var(--mc-radius-pill)}.btn-primary{border-radius:var(--mc-radius-lg)}.hero-cta-primary{border-radius:var(--mc-radius-pill);padding:11px 26px}.btn-primary,.hero-cta-primary,.send-btn{box-shadow:none}.hero-cta-primary:hover{box-shadow:0 4px 14px var(--mc-accent-glow)}.home-quick button{background:var(--mc-surface-subtle);border-radius:var(--mc-radius-pill);border-color:#0000}.home-quick button:hover{background:var(--mc-accent-soft);border-color:var(--mc-accent-line)}.new-task-button{border-radius:var(--mc-radius-lg)}.hero-announce{background:var(--mc-surface-subtle);border-bottom-color:var(--mc-line-faint)}.hero-announce:hover{background:var(--mc-accent-soft)}.activity-status,.execution-status,.inspector-status,.mc-tag,.picker-option-state,.run-state,.run-status{border-radius:var(--mc-radius-sm)}.home-hero{min-height:0;padding-top:clamp(56px,14vh,130px);padding-bottom:6px}.hero-display{letter-spacing:0;font-size:clamp(26px,3.2vw,38px);font-weight:640}.hero-cta-row,.hero-live,.hero-sub{display:none}.home-task-entry{padding-top:var(--mc-c-page-pad);width:min(720px,100%)}.home-main-grid{grid-template-columns:minmax(0,1fr)}.home-footnote,.home-quick,.home-recent{display:none}.home-task-entry h1,.home-task-entry h2{color:var(--mc-text-subtle);text-align:center;font-size:17px;font-weight:620}.home-workspace-context{justify-content:center}.home-heading{margin-bottom:0}.home-workspace-context{display:none}.home-workbench{min-height:calc(100vh - var(--mc-topbar-height));flex-direction:column;padding-bottom:0;display:flex}.home-hero{margin-top:auto;padding-top:30px}.home-hero .hero-display{margin-bottom:4px;font-size:clamp(24px,2.6vw,34px)}.home-task-entry{padding-bottom:var(--mc-c-section-gap);margin-bottom:auto}.home-task-entry h1,.home-task-entry h2{margin-bottom:14px}.hero-input,textarea#heroInput{min-height:108px}.hero-announce,.topbar .global-search,.topbar-path{display:none}.topbar{gap:6px}.sidebar{background:var(--mc-sidebar);padding-top:14px}.sidebar-search{border-radius:var(--mc-radius-md);color:var(--mc-sidebar-muted);transition:background var(--mc-duration-fast) var(--mc-easing),color var(--mc-duration-fast) var(--mc-easing);align-items:center;gap:10px;width:100%;margin:6px 0 2px;padding:8px 10px;font-size:13px;display:flex}.sidebar-search:hover{background:var(--mc-sidebar-hover);color:var(--mc-sidebar-title)}.recent-indicator,.recent-work-copy small{display:none}.recent-work-copy strong{color:var(--mc-sidebar-text);font-size:13px;font-weight:560}.recent-work-row.active .recent-work-copy strong{color:var(--mc-sidebar-title)}.recent-work-heading{padding-top:16px}.sidebar-footer{border-top:0}.msg .msg-content{background:0 0;border:0;padding:2px 0 0}.msg-content.user-plain-text{background:var(--mc-user-surface);border-radius:var(--mc-radius-lg);border:0;padding:10px 16px}.msg.user .msg-body{max-width:78%}.mc-trace,.think-row{background:var(--mc-surface-subtle);border:1px solid var(--mc-line);border-radius:var(--mc-radius-md)}.mcp-warning{border:1px solid var(--mc-warning-soft)}.composer-wrap,.universal-composer{background:var(--mc-c-composer-bg);border:1px solid var(--mc-c-composer-border)}.composer .composer-input,.hero-input,textarea#heroInput{font-size:15px}.topbar-title{font-size:14px;font-weight:600}.brand-mark{height:var(--brand-mark-size,34px);width:var(--brand-mark-size,34px);flex:none;justify-content:center;align-items:center;display:inline-flex}.brand-mark svg{width:100%;height:100%}.brand-mark .brand-arc{fill:none;stroke:var(--mc-accent);stroke-linecap:round;stroke-width:3.1px}.brand-mark .brand-core{fill:var(--mc-accent);stroke:none}.msg-content table{border-collapse:collapse;width:100%;margin:12px 0;font-size:13px}.msg-content td,.msg-content th{border:1px solid var(--mc-line);text-align:left;vertical-align:top;padding:8px 12px}.msg-content th{background:var(--mc-surface-subtle);font-weight:650}.msg-content tr:nth-child(2n) td{background:color-mix(in srgb,var(--mc-surface-subtle) 55%,transparent)}.agent-capability-summary{color:var(--mc-text-muted);flex-wrap:wrap;gap:4px 14px;font-size:12px;display:flex}.agent-capability-summary strong{font-variant-numeric:tabular-nums;margin-right:3px}.agent-status{background:var(--mc-success-soft);border-radius:var(--mc-radius-pill);color:var(--mc-success);white-space:nowrap;align-items:center;gap:6px;padding:3px 10px;font-size:11px;font-weight:650;display:inline-flex}.agent-status i{background:currentColor;border-radius:50%;width:6px;height:6px}.compare-targets{border:0;flex-wrap:wrap;align-items:center;gap:8px;min-height:46px;margin:0;padding:0;display:flex}.compare-targets legend{color:var(--mc-text-muted);margin-bottom:8px;padding:0;font-size:12px;font-weight:630}.compare-targets label{background:var(--mc-surface);border:1px solid var(--mc-line);border-radius:var(--mc-radius-pill);cursor:pointer;transition:border-color var(--mc-duration-fast) var(--mc-easing),background var(--mc-duration-fast) var(--mc-easing);align-items:center;gap:8px;padding:7px 13px;display:inline-flex}.compare-targets label:has(input:checked){background:var(--mc-accent-soft);border-color:var(--mc-accent)}.compare-targets input{accent-color:var(--mc-accent)}.compare-targets strong{font-size:12.5px;font-weight:620}.compare-targets small{color:var(--mc-text-faint);font-size:11px}.compare-results:not(:has(*)){display:none}.settings-body:empty:after{color:var(--mc-text-faint);content:"该设置页暂无内容";text-align:center;padding:40px 0;font-size:13px;display:block}.add-tile strong,.mc-add strong{color:var(--mc-text);font-size:13px;font-weight:650;display:block}.add-tile small,.mc-add small{color:var(--mc-text-muted);margin-top:2px;font-size:11.5px;line-height:1.5;display:block}.provider-summary{gap:14px}.provider-summary>span{white-space:nowrap}.settings-body>*{max-width:980px}.settings-body{padding-inline:clamp(20px,4vw,48px)}:root{--mc-radius-lg:10px;--mc-radius-xl:12px;--mc-radius-2xl:16px}.btn-primary,.hero-cta-primary,.new-task-button,.send-btn:not(.stop){background:var(--mc-accent);border-radius:var(--mc-radius-md);box-shadow:none}.btn-primary:hover,.hero-cta-primary:hover,.new-task-button:hover,.send-btn:hover:not(:disabled){background:var(--mc-accent-strong);box-shadow:none;filter:none}.send-btn:disabled{background:var(--mc-surface-active);color:var(--mc-text-subtle);opacity:1}.hero-display,:root[data-theme=dark] .hero-display{-webkit-text-fill-color:currentColor;color:var(--mc-text);background:0 0;-webkit-background-clip:border-box;background-clip:border-box}.primary-nav button.active{box-shadow:none;color:var(--mc-sidebar-title)}.primary-nav button.active,.recent-work-row.active{background:var(--mc-sidebar-active)}.mode-segments button.active,.task-mode-switch button.active,:root[data-theme=dark] .mode-segments button.active,:root[data-theme=dark] .task-mode-switch button.active{background:var(--mc-accent);border-color:var(--mc-accent);box-shadow:none;color:var(--mc-on-accent)}.composer-wrap:focus-within,.universal-composer:focus-within{border-color:var(--mc-accent-line);box-shadow:none}.agent-card:hover,.mc-card:hover,.passport-card:hover,.provider-card:hover,.tool-card:hover{border-color:var(--mc-line-hover);box-shadow:var(--mc-shadow-xs)}::selection{background:var(--mc-accent-glow)}::-webkit-scrollbar-thumb{background:var(--mc-scrollbar-thumb);background-clip:content-box}::-webkit-scrollbar-thumb:hover{background:var(--mc-scrollbar-thumb-hover);background-clip:content-box}.msg-avatar{background:var(--mc-surface-subtle);color:var(--mc-accent)}.connection-status i,.hero-live-dot,.model-status-dot{background:var(--mc-success)}.hero-live-dot{animation:2.4s ease-out infinite pulse-dot}.mc-tag.on{background:var(--mc-accent-soft);color:var(--mc-accent)}.toast{border-radius:var(--mc-radius-md);box-shadow:var(--mc-shadow-sm)}.home-workbench{position:relative;overflow:hidden}.home-workbench:after,.home-workbench:before{display:none}.workspace-home>:not(.hero-ambient){z-index:1;position:relative}.hero-ambient{display:none}.home-mascot{color:var(--mc-accent);filter:none;margin-bottom:6px}.mascot-ear-l,.mascot-ear-r,.mascot-head{fill:var(--mc-accent-soft);stroke:var(--mc-accent);stroke-linecap:round;stroke-linejoin:round;stroke-width:2.4px}.mascot-face{fill:var(--mc-accent)}.mascot-face path{fill:none;stroke:var(--mc-accent);stroke-width:2.2px}.character-grid{grid-template-columns:repeat(3,minmax(0,1fr));gap:10px;margin-top:10px;display:grid}.home-characters{width:min(720px,100%);margin:22px auto 0;padding:0}.home-characters header h3{font-size:13px;font-weight:600}.home-characters header p{color:var(--mc-text-subtle);margin-top:2px;font-size:12px}.character-card{background:var(--mc-surface);border:1px solid var(--mc-line);border-radius:var(--mc-radius-md);text-align:left;transition:border-color var(--mc-duration-fast) var(--mc-easing),background var(--mc-duration-fast) var(--mc-easing);flex-direction:column;align-items:flex-start;gap:4px;padding:12px 14px;display:flex;position:relative;overflow:hidden}.character-card:before{display:none}.character-card[class*=hue-]{--hue:var(--mc-accent-soft)}.character-card:hover{background:var(--mc-surface-subtle);border-color:var(--mc-accent-line);box-shadow:none;transform:none}.character-avatar{color:var(--mc-accent);display:inline-flex}.character-card strong{color:var(--mc-text);font-size:13px;font-weight:600}.character-card small{color:var(--mc-text-muted);-webkit-line-clamp:2;-webkit-box-orient:vertical;font-size:11.5px;line-height:1.5;display:-webkit-box;overflow:hidden}.character-go{color:var(--mc-accent);opacity:0;transition:opacity var(--mc-duration) var(--mc-easing),transform var(--mc-duration) var(--mc-easing);margin-top:4px;font-weight:700;transform:translate(-4px)}.character-card:hover .character-go{opacity:1;transform:translate(0)}.skill-page-heading{flex-flow:wrap;justify-content:space-between;align-items:flex-start;gap:16px}.skill-page-heading h3{margin:0}.skill-page-heading .lead{margin:4px 0 0}.skill-heading-actions{flex-wrap:wrap;align-items:center;gap:8px;display:flex}.skill-heading-actions button{white-space:nowrap;align-items:center;gap:6px;display:inline-flex}.skill-tabs{border-bottom:1px solid var(--mc-line);align-items:center;gap:4px;margin-bottom:12px;display:flex}.skill-tab{color:var(--mc-text-muted);cursor:pointer;background:0 0;border:0;padding:8px 14px 10px;font-size:13px;font-weight:560;position:relative}.skill-tab:hover{color:var(--mc-text)}.skill-tab.active{color:var(--mc-accent);font-weight:650}.skill-tab.active:after{background:var(--mc-accent);content:"";border-radius:2px;height:2px;position:absolute;bottom:-1px;left:10px;right:10px}.skill-toolbar{flex-wrap:nowrap;align-items:center;gap:10px;margin-bottom:12px}.skill-toolbar .resource-search{background:var(--mc-surface);border:1px solid var(--mc-line);border-radius:var(--mc-radius-md);flex:0 280px;align-items:center;gap:8px;min-width:180px;height:40px;padding:0 10px;display:inline-flex}.skill-toolbar .resource-search:focus-within{border-color:var(--mc-accent);box-shadow:0 0 0 2px var(--mc-accent-soft)}.skill-toolbar .resource-search svg{color:var(--mc-text-muted);flex:none}.skill-toolbar .resource-search input{background:0 0;border:0;outline:none;flex:1;width:auto;min-width:0;padding:0;font-size:13px}.skill-toolbar select{flex:none;width:auto;min-width:150px;height:40px;padding-top:0;padding-bottom:0}.skill-toolbar .resource-count{white-space:nowrap;margin-left:auto}@media (width<=720px){.skill-toolbar{flex-wrap:wrap}.skill-toolbar .resource-count{margin-left:0}}.skill-list{flex-direction:column;gap:8px;display:flex}.skill-row{background:var(--mc-surface);border:1px solid var(--mc-line);border-radius:var(--mc-radius-lg);transition:border-color var(--mc-duration-fast) var(--mc-easing),box-shadow var(--mc-duration-fast) var(--mc-easing)}.skill-row.is-open,.skill-row:hover{border-color:var(--mc-line-hover);box-shadow:var(--mc-shadow-sm)}.skill-row-main{align-items:center;gap:12px;padding:12px 14px;display:flex}.skill-row-ico{background:var(--mc-accent-soft);border-radius:var(--mc-radius-md);color:var(--mc-accent);flex:none;justify-content:center;align-items:center;width:38px;height:38px;display:inline-flex}.skill-row-copy{flex:1;min-width:0}.skill-row-title{align-items:center;gap:8px;min-width:0;display:flex}.skill-row-title strong{color:var(--mc-text);text-overflow:ellipsis;white-space:nowrap;font-size:13.5px;font-weight:660;overflow:hidden}.skill-row-badge{background:var(--mc-surface-subtle);border-radius:var(--mc-radius-pill);color:var(--mc-text-muted);flex:none;padding:1px 7px;font-size:10.5px;font-weight:560}.skill-row-badge.danger{background:var(--mc-danger-soft);color:var(--mc-danger)}.skill-row-desc{color:var(--mc-text-muted);margin:3px 0 0;font-size:12.5px;line-height:1.5}.skill-row-desc,.skill-row-id{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.skill-row-id{color:var(--mc-text-faint);font-family:var(--mc-font-mono);margin-top:2px;font-size:10.5px;display:block}.skill-row-actions{flex:none;align-items:center;gap:10px;display:flex}.skill-row-actions .mc-toggle,.skill-row-actions .mc-toggle.on{background:0 0;border:0;gap:0;padding:4px}.skill-row-expand{background:var(--mc-surface);border:1px solid var(--mc-line);border-radius:var(--mc-radius-sm);color:var(--mc-text-muted);cursor:pointer;justify-content:center;align-items:center;width:28px;height:28px;display:inline-flex}.skill-row-expand:hover{color:var(--mc-accent)}.skill-row.is-open .skill-row-expand svg{transform:rotate(180deg)}.skill-row-detail{border-top:1px solid var(--mc-line);padding:4px 14px 14px}.skill-row-detail[hidden]{display:none}.skill-facts{grid-template-columns:repeat(2,minmax(0,1fr));gap:8px 16px;margin:12px 0;font-size:11.5px;display:grid}.skill-facts>div{align-items:baseline;gap:8px;min-width:0;display:flex}.skill-facts dt{color:var(--mc-text-faint);flex:none;width:52px}.skill-facts dd{color:var(--mc-text-muted);font-family:var(--mc-font-mono);text-overflow:ellipsis;white-space:nowrap;min-width:0;margin:0;overflow:hidden}.skill-detail-tags{margin-bottom:12px}.skill-detail-actions{flex-wrap:wrap;gap:8px;display:flex}.skill-detail-actions .mc-act{justify-content:center;align-items:center;gap:6px;display:inline-flex}.skill-readonly-note{color:var(--mc-text-faint);align-self:center;font-size:11.5px}@media (width<=720px){.skill-facts{grid-template-columns:minmax(0,1fr)}}.skill-row-detail .resource-detail-extra{max-width:100%;margin:0 0 10px}.skill-row-detail .extension-command{margin-top:12px}.skill-row-detail .extension-tool-list{max-height:108px;overflow-y:auto}.skill-row-detail .tool-test-result{overflow-wrap:anywhere;margin-top:0}.skill-row-detail .agent-capability-summary{margin-top:-4px}.skill-row-detail .skill-detail-actions:last-child{margin-bottom:0}.mc-tag.danger{background:var(--mc-danger-soft);color:var(--mc-danger)}.skill-page-heading>div:first-child{flex:1;min-width:0}.skill-heading-actions{flex:none}.skill-detail-actions .mc-act.danger{border-color:var(--mc-line)}.skill-detail-actions .mc-act.danger:hover{background:var(--mc-danger-soft);border-color:var(--mc-danger)}@media (width<=720px){.skill-page-heading{flex-direction:column}.skill-heading-actions{width:100%}}
@@ -0,0 +1 @@
1
+ import{C as e,E as t,T as n,b as r,f as i,g as a,i as o,w as s}from"./index-CeU_ksnE.js";async function c(){await d(),await l(),window.addEventListener(`popstate`,()=>{l()})}async function l(){let i=location.hash.replace(/^#\/?/,``).split(`/`).filter(Boolean).map(decodeURIComponent),a=t(`#modal`)?.classList.contains(`open`)&&t(`#modalCard`)?.classList.contains(`compare-modal-card`);if(i[0]!==`compare`&&a&&closeModal(),i[0]===`settings`)openSettings(i[1]||`general`);else if(t(`#settings`)?.classList.contains(`open`)&&closeSettings(),i[0]===`home`||!i[0])o(`home`);else if(i[0]===`compare`)openCompare();else if(i[0]===`chat`&&i[1]&&!u(i[1])){if(r.conversationsLoadFailed){o(`chat`),await openConversation(i[1]);return}r.currentConvId=null,r.messages=[],r.workflowScope=s(null,r.selectedProject?.id),r.workflow=e(r.workflowScope),o(`home`),history.replaceState(null,``,`#/home`),renderTopbar(),renderContent(),n(`该任务不存在或已被删除,已返回新任务页`,`error`)}else i[0]===`chat`&&i[1]&&i[1]!==r.currentConvId?(o(`chat`),await openConversation(i[1])):i[0]===`new`&&(r.currentConvId||r.messages.length?await newConversation():o(`home`),history.replaceState(null,``,`#/home`))}function u(e,t=r.conversations){return t.some(t=>t.id===e)}async function d(){await Promise.all([loadProviders(),loadConversations(),loadSkills(),loadTools(),loadMcpServers(),loadAgents(),loadPlugins(),loadRuntime(),loadRuns()]),a();let n=localStorage.getItem(`multichat_lastModel`);if(n){let[e,...t]=n.split(`:`),i=t.join(`:`),a=r.providers.find(t=>t.id===e);a&&(r.selectedProvider=a,r.selectedModel=i)}if(!r.selectedProvider&&r.providers.length>0){let e=r.providers[0];r.selectedProvider=e,r.selectedModel=e.models&&e.models[0]||e.defaultModel||e.model||``}await loadWorkspaces(),r.workflowScope=s(null,r.selectedProject?.id),r.workflow=e(r.workflowScope),renderTopbar(),renderContent(),renderSettings();let i=t(`#fcMin`);i&&(i.onclick=()=>{let e=t(`#fileCtxBody`);e&&(e.classList.toggle(`collapsed`),i.textContent=e.classList.contains(`collapsed`)?`▸`:`▾`)}),renderFileContext(),f();let o=t(`#convSearch`);o&&(o.oninput=e=>{r.convSearch=e.target.value,renderConvList()});let c=t(`#forkBtn`);c&&(c.onclick=p);let l=t(`#composerFileBtn`);l&&(l.onclick=()=>openSettings(`workspace`))}function f(){let e=t(`#content`);e&&(e.addEventListener(`dragover`,t=>{t.preventDefault(),e.classList.add(`drag-over`)}),e.addEventListener(`dragleave`,t=>{t.target===e&&e.classList.remove(`drag-over`)}),e.addEventListener(`drop`,async t=>{t.preventDefault(),e.classList.remove(`drag-over`);let a=t.dataTransfer&&t.dataTransfer.files;if(a&&a.length){if(!r.selectedProject)n(`请先在右上角选择工作区/项目`,`error`);else{for(let e of Array.from(a))if(e.size>2e6)n(`文件超过 2MB 限制,已跳过:`+e.name,`error`);else try{let t=await e.text(),a=await i(`/api/assets`,{method:`POST`,body:JSON.stringify({projectId:r.selectedProject.id,name:e.name,mimeType:e.type||`text/plain`,content:t})});r.assets=[a,...r.assets],r.selectedAssetIds=new Set([...r.selectedAssetIds,a.id]),n(`已添加文件:`+e.name)}catch(e){n(`文件添加失败:`+e.message,`error`)}renderFileContext()}}}))}async function p(){let e=r.messages.filter(e=>e.content&&!e.streaming).map(e=>({role:e.role,content:e.content,model:e.model}));if(!e.length){n(`当前没有可分支的内容`,`error`);return}let a=`分支 · `+(e.find(e=>e.role===`user`)?.content?.slice(0,20)||`新对话`);r.currentConvId=null,r.messages=[],t(`#topbarTitle`).textContent=`新对话(分支)`,renderContent(),renderConvList();try{let o=await i(`/api/conversations`,{method:`POST`,body:JSON.stringify({title:a,workspaceId:r.selectedWorkspace?.id||null,projectId:r.selectedProject?.id||null})});r.currentConvId=o.id,window.history.replaceState(null,``,`#/chat/${encodeURIComponent(o.id)}`),await i(`/api/conversations/`+o.id+`/messages`,{method:`POST`,body:JSON.stringify(e)}),r.messages=e,t(`#topbarTitle`).textContent=o.title||`对话`,await loadConversations(),renderContent(),renderConvList(),n(`已创建分支对话`)}catch(e){n(`分支失败:`+e.message,`error`)}}export{l as applyLocationRoute,c as bootstrap,p as forkConversation,d as initApp,u as isKnownConversation,f as setupDrop};
@@ -1,2 +1,2 @@
1
- import{S as e,w as t}from"./index-BaUGyQ3C.js";var n=null,r,i=null,a=`input:not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), [href], [tabindex="0"]`;function o(e){if(e)try{e.focus({preventScroll:!0})}catch{e.focus()}}function s({title:s,body:l,onMount:u,onClose:d=null}){let f=e(`#modal`),p=e(`#modalCard`),m=e(`#app`),h=e(`#settings`),g=`modalTitle-${Date.now()}`;r!==void 0&&(window.clearTimeout(r),r=void 0),n=document.activeElement instanceof HTMLElement?document.activeElement:null,i=typeof d==`function`?d:null,p.className=`modal-card`,p.innerHTML=`<div class="modal-heading"><h3 id="${g}">${t(s||``)}</h3><button type="button" class="modal-close" aria-label="关闭弹窗" title="关闭">✕</button></div>${l||``}`,f.setAttribute(`aria-labelledby`,g),f.setAttribute(`aria-hidden`,`false`),f.inert=!1,f.classList.add(`open`);let _=p.querySelector(`.modal-close`);_&&(_.onclick=c),u&&u(p),o(Array.from(p.querySelectorAll(a)).find(e=>!e.classList.contains(`modal-close`))||p),m.inert=!0,h.inert=!0}function c(){let t=e(`#modal`),a=e(`#app`),s=e(`#settings`);if(!t.classList.contains(`open`))return;let c=s.classList.contains(`open`),l=c?s:a;a.inert=c,s.inert=!c;let u=e(c?`#settingsBody`:`#settingsBtn`);o(n?.isConnected&&l.contains(n)?n:u),t.contains(document.activeElement)&&o(u),t.classList.remove(`open`),t.inert=!0,t.setAttribute(`aria-hidden`,`true`),n=null;let d=i;i=null,d?.(),r=window.setTimeout(()=>{t.classList.contains(`open`)||(e(`#modalCard`).innerHTML=``),r=void 0},160)}function l({title:n=`请确认`,message:r,confirmLabel:i=`确认`,cancelLabel:a=`取消`,danger:o=!1}){let l=!1;return new Promise(u=>{let d=e=>{l||(l=!0,u(e))};s({title:n,body:`<div class="confirm-message">${t(r)}</div><div class="row"><button type="button" class="btn-ghost" id="dialogCancel">${t(a)}</button><button type="button" class="${o?`btn-danger`:`btn-primary`} btn-auto" id="dialogAccept">${t(i)}</button></div>`,onMount:t=>{e(`#dialogCancel`,t).onclick=()=>{d(!1),c()},e(`#dialogAccept`,t).onclick=()=>{d(!0),c()}},onClose:()=>d(!1)})})}function u({title:n,message:r=``,label:i=`名称`,value:a=``,placeholder:o=``,required:l=!0,maxLength:u,multiline:d=!1,rows:f=5,confirmLabel:p=`确定`}){let m=!1;return new Promise(h=>{let g=e=>{m||(m=!0,h(e))},_=d?`<textarea name="value" rows="${f}" placeholder="${t(o)}" ${u?`maxlength="${u}"`:``} autofocus>${t(a)}</textarea>`:`<input name="value" value="${t(a)}" placeholder="${t(o)}" ${u?`maxlength="${u}"`:``} autofocus />`;s({title:n,body:`${r?`<p class="lead lead-tight">${t(r)}</p>`:``}
1
+ import{E as e,O as t}from"./index-CeU_ksnE.js";var n=null,r,i=null,a=`input:not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), [href], [tabindex="0"]`;function o(e){if(e)try{e.focus({preventScroll:!0})}catch{e.focus()}}function s({title:s,body:l,onMount:u,onClose:d=null}){let f=e(`#modal`),p=e(`#modalCard`),m=e(`#app`),h=e(`#settings`),g=`modalTitle-${Date.now()}`;r!==void 0&&(window.clearTimeout(r),r=void 0),n=document.activeElement instanceof HTMLElement?document.activeElement:null,i=typeof d==`function`?d:null,p.className=`modal-card`,p.innerHTML=`<div class="modal-heading"><h3 id="${g}">${t(s||``)}</h3><button type="button" class="modal-close" aria-label="关闭弹窗" title="关闭">✕</button></div>${l||``}`,f.setAttribute(`aria-labelledby`,g),f.setAttribute(`aria-hidden`,`false`),f.inert=!1,f.classList.add(`open`);let _=p.querySelector(`.modal-close`);_&&(_.onclick=c),u&&u(p),o(Array.from(p.querySelectorAll(a)).find(e=>!e.classList.contains(`modal-close`))||p),m.inert=!0,h.inert=!0}function c(){let t=e(`#modal`),a=e(`#app`),s=e(`#settings`);if(!t.classList.contains(`open`))return;let c=s.classList.contains(`open`),l=c?s:a;a.inert=c,s.inert=!c;let u=e(c?`#settingsBody`:`#settingsBtn`);o(n?.isConnected&&l.contains(n)?n:u),t.contains(document.activeElement)&&o(u),t.classList.remove(`open`),t.inert=!0,t.setAttribute(`aria-hidden`,`true`),n=null;let d=i;i=null,d?.(),r=window.setTimeout(()=>{t.classList.contains(`open`)||(e(`#modalCard`).innerHTML=``),r=void 0},160)}function l({title:n=`请确认`,message:r,confirmLabel:i=`确认`,cancelLabel:a=`取消`,danger:o=!1}){let l=!1;return new Promise(u=>{let d=e=>{l||(l=!0,u(e))};s({title:n,body:`<div class="confirm-message">${t(r)}</div><div class="row"><button type="button" class="btn-ghost" id="dialogCancel">${t(a)}</button><button type="button" class="${o?`btn-danger`:`btn-primary`} btn-auto" id="dialogAccept">${t(i)}</button></div>`,onMount:t=>{e(`#dialogCancel`,t).onclick=()=>{d(!1),c()},e(`#dialogAccept`,t).onclick=()=>{d(!0),c()}},onClose:()=>d(!1)})})}function u({title:n,message:r=``,label:i=`名称`,value:a=``,placeholder:o=``,required:l=!0,maxLength:u,multiline:d=!1,rows:f=5,confirmLabel:p=`确定`}){let m=!1;return new Promise(h=>{let g=e=>{m||(m=!0,h(e))},_=d?`<textarea name="value" rows="${f}" placeholder="${t(o)}" ${u?`maxlength="${u}"`:``} autofocus>${t(a)}</textarea>`:`<input name="value" value="${t(a)}" placeholder="${t(o)}" ${u?`maxlength="${u}"`:``} autofocus />`;s({title:n,body:`${r?`<p class="lead lead-tight">${t(r)}</p>`:``}
2
2
  <form id="dialogPromptForm"><div class="field"><label>${t(i)}</label>${_}</div><div class="row"><button type="button" class="btn-ghost" id="dialogCancel">取消</button><button class="btn-primary btn-auto" type="submit">${t(p)}</button></div></form>`,onMount:t=>{e(`#dialogCancel`,t).onclick=()=>{g(null),c()},e(`#dialogPromptForm`,t).onsubmit=e=>{e.preventDefault();let n=(t.querySelector(`[name="value"]`)?.value??``).trim();(!l||n)&&(g(n),c())}},onClose:()=>g(null)})})}e(`#modal`).addEventListener(`click`,e=>{e.target.id===`modal`&&c()}),document.addEventListener(`keydown`,t=>{if(!e(`#modal`).classList.contains(`open`))return;if(t.key===`Escape`){t.preventDefault(),c();return}if(t.key!==`Tab`)return;let n=e(`#modalCard`),r=Array.from(n.querySelectorAll(a));if(!r.length){t.preventDefault(),n.focus();return}let i=r[0],o=r[r.length-1];t.shiftKey&&document.activeElement===i?(t.preventDefault(),o.focus()):!t.shiftKey&&document.activeElement===o&&(t.preventDefault(),i.focus())});export{c as closeModal,l as showConfirm,s as showModal,u as showPrompt};
@@ -0,0 +1,14 @@
1
+ import{O as e,T as t,b as n}from"./index-CeU_ksnE.js";function r(){if(!n.providers.length){openSettings(`providers`),t(`请先添加模型`);return}let r=[];n.providers.forEach(e=>{let t=e.models||(e.model?[e.model]:[]),n=e.name||e.id,i={pid:e.id,providerName:n,apiType:e.apiType||`openai`,initial:n.trim().slice(0,1).toUpperCase()||`M`};t.length?t.forEach(e=>r.push({...i,model:e,modelLabel:e})):r.push({...i,model:``,modelLabel:`手动输入模型名`,custom:!0})}),showModal({title:`选择模型`,body:`<div class="picker-dialog-intro">
2
+ <span>为接下来的消息选择运行模型</span>
3
+ <span>${r.length} 个可用模型</span>
4
+ </div>
5
+ <div class="model-picker-list">
6
+ ${r.map(t=>{let r=n.selectedProvider?.id===t.pid&&n.selectedModel===t.model;return`<button type="button" class="picker-option${r?` active`:``}" data-pid="${e(t.pid)}" data-model="${e(t.model)}" data-custom="${+!!t.custom}" aria-pressed="${r}">
7
+ <span class="picker-provider-mark" aria-hidden="true">${e(t.initial)}</span>
8
+ <span class="picker-option-copy">
9
+ <strong>${e(t.modelLabel)}</strong>
10
+ <small>${e(t.providerName)} · ${e(t.apiType)}</small>
11
+ </span>
12
+ <span class="picker-option-state" aria-hidden="true">${r?`✓`:`›`}</span>
13
+ </button>`}).join(``)}
14
+ </div>`,onMount:e=>{e.classList.add(`model-picker-modal`),e.querySelectorAll(`.picker-option`).forEach(e=>{e.onclick=async()=>{let t=e.dataset.pid,r=n.providers.find(e=>e.id===t);if(!r)return;let i=e.dataset.model;if(e.dataset.custom===`1`){let e=await showPrompt({title:`自定义模型`,message:`为「${r.name||r.id}」输入模型名称`,label:`模型名称`,placeholder:`例如 deepseek-chat`,maxLength:120});if(!e)return;i=e.trim(),r.models||=[],r.models.includes(i)||r.models.push(i)}n.selectedProvider=r,n.selectedModel=i,localStorage.setItem(`multichat_lastModel`,t+`:`+i),a(),closeModal(),n.messages.length||renderContent()}})}})}function i(e,r){let i=n.providers.find(t=>t.id===e);!i||!(i.models||[]).includes(r)?t(`该模型已不可用,请刷新模型列表`,`error`):(n.selectedProvider=i,n.selectedModel=r,localStorage.setItem(`multichat_lastModel`,`${e}:${r}`),a(),renderContent())}function a(){renderInspector()}function o(){}export{r as openModelPicker,a as renderTopbar,i as selectModel,o as syncModelUI};
@@ -0,0 +1,16 @@
1
+ import{i as e,t}from"./react-sySUN5R7.js";import{E as n,I as r,N as i,O as a,R as o,T as s,b as c,f as l,k as u,z as d}from"./index-CeU_ksnE.js";var f=o(`box`,[[`path`,{d:`M21 8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16Z`,key:`hh9hay`}],[`path`,{d:`m3.3 7 8.7 5 8.7-5`,key:`g66t2b`}],[`path`,{d:`M12 22V12`,key:`d0xqtd`}]]),p=o(`plug-zap`,[[`path`,{d:`M6.3 20.3a2.4 2.4 0 0 0 3.4 0L12 18l-6-6-2.3 2.3a2.4 2.4 0 0 0 0 3.4Z`,key:`goz73y`}],[`path`,{d:`m2 22 3-3`,key:`19mgm9`}],[`path`,{d:`M7.5 13.5 10 11`,key:`7xgeeb`}],[`path`,{d:`M10.5 16.5 13 14`,key:`10btkg`}],[`path`,{d:`m18 3-4 4h6l-4 4`,key:`16psg9`}]]),m=o(`upload`,[[`path`,{d:`M12 3v12`,key:`1x0j5s`}],[`path`,{d:`m17 8-5-5-5 5`,key:`7q97r8`}],[`path`,{d:`M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4`,key:`ih7n3h`}]]),h=d(),g=e(t(),1),_=u();function v({title:e,lead:t,headingActions:n,tabs:a=[],sourceOptions:o=[],sourceAriaLabel:s=`按来源筛选`,sourceDefaultLabel:c=`全部来源`,searchPlaceholder:l=`搜索名称、说明或 ID`,countNoun:u,items:d,emptyText:f,ariaLabel:p,className:m=``}){let[h,v]=(0,g.useState)(``),[y,b]=(0,g.useState)(``),[x,S]=(0,g.useState)(``),[C,w]=(0,g.useState)(null),T=(0,g.useMemo)(()=>d.filter(e=>(!h||[e.name,e.description,e.meta,e.haystack,...(e.badges||[]).map(e=>e.label)].filter(Boolean).join(` `).toLowerCase().includes(h.toLowerCase()))&&(!y||(e.statusValue??(e.enabled?`enabled`:`disabled`))===y)&&(!x||e.sourceKind===x)),[d,h,y,x]);return(0,_.jsxs)(`section`,{className:`skill-settings resource-settings ${m}`.trim(),"aria-label":p,children:[(0,_.jsxs)(`div`,{className:`settings-page-heading skill-page-heading`,children:[(0,_.jsxs)(`div`,{children:[(0,_.jsx)(`h3`,{children:e}),(0,_.jsx)(`p`,{className:`lead`,children:t})]}),n&&(0,_.jsx)(`div`,{className:`skill-heading-actions`,children:n})]}),!!a.length&&(0,_.jsx)(`div`,{className:`skill-tabs`,role:`group`,"aria-label":`按状态筛选${u}`,children:a.map(e=>(0,_.jsx)(`button`,{type:`button`,className:`skill-tab${y===e.value?` active`:``}`,"aria-pressed":y===e.value,onClick:()=>b(e.value),children:e.label},e.value))}),(0,_.jsxs)(`div`,{className:`resource-toolbar skill-toolbar`,"aria-label":`筛选${u}`,children:[(0,_.jsxs)(`label`,{className:`resource-search`,children:[(0,_.jsx)(i,{size:15,"aria-hidden":!0}),(0,_.jsx)(`input`,{type:`search`,"aria-label":`搜索${u}`,placeholder:l,value:h,onChange:e=>v(e.target.value)})]}),!!o.length&&(0,_.jsxs)(`select`,{"aria-label":s,value:x,onChange:e=>S(e.target.value),children:[(0,_.jsx)(`option`,{value:``,children:c}),o.map(e=>(0,_.jsx)(`option`,{value:e.value,children:e.label},e.value))]}),(0,_.jsxs)(`span`,{className:`resource-count`,children:[T.length,` / `,d.length,` `,u]})]}),(0,_.jsxs)(`div`,{className:`skill-list`,children:[T.map((e,t)=>{let n=C===e.key,i=`resource-detail-${t}`;return(0,_.jsxs)(`article`,{className:`skill-row${n?` is-open`:``}`,children:[(0,_.jsxs)(`div`,{className:`skill-row-main`,children:[(0,_.jsx)(`span`,{className:`skill-row-ico`,"aria-hidden":!0,children:e.icon}),(0,_.jsxs)(`div`,{className:`skill-row-copy`,children:[(0,_.jsxs)(`div`,{className:`skill-row-title`,children:[(0,_.jsx)(`strong`,{children:e.name}),(e.badges||[]).map((e,t)=>(0,_.jsx)(`span`,{className:`skill-row-badge${e.danger?` danger`:``}`,children:e.label},`${e.label}-${t}`))]}),(0,_.jsx)(`p`,{className:`skill-row-desc`,children:e.description||`(暂无描述)`}),e.meta&&(0,_.jsx)(`span`,{className:`skill-row-id`,children:e.meta})]}),(0,_.jsxs)(`div`,{className:`skill-row-actions`,children:[typeof e.enabled==`boolean`&&e.onToggle&&(0,_.jsx)(`button`,{type:`button`,className:`mc-toggle${e.enabled?` on`:``}`,"aria-pressed":e.enabled,"aria-label":`${e.name}:${e.enabled?`已启用,点击停用`:`已停用,点击启用`}`,onClick:()=>void e.onToggle?.(),children:(0,_.jsx)(`span`,{className:`mc-switch`,"aria-hidden":!0})}),(0,_.jsx)(`button`,{type:`button`,className:`skill-row-expand`,"aria-expanded":n,"aria-controls":i,"aria-label":`${n?`收起`:`展开`} ${e.name} 详情`,onClick:()=>w(n?null:e.key),children:(0,_.jsx)(r,{size:16,"aria-hidden":!0})})]})]}),(0,_.jsx)(`div`,{className:`skill-row-detail`,id:i,hidden:!n,children:e.detail})]},e.key)}),!T.length&&(0,_.jsx)(`div`,{className:`extension-empty`,children:f})]})]})}function y({facts:e}){return(0,_.jsx)(`dl`,{className:`skill-facts`,children:e.map(e=>(0,_.jsxs)(`div`,{children:[(0,_.jsx)(`dt`,{children:e.label}),(0,_.jsx)(`dd`,{title:e.title||e.value,children:e.value})]},e.label))})}function b({tags:e}){return(0,_.jsx)(`div`,{className:`mc-tags skill-detail-tags`,children:e.map((e,t)=>(0,_.jsx)(`span`,{className:`mc-tag${e.on?` on`:``}${e.danger?` danger`:``}`,title:e.title,children:e.label},`${e.label}-${t}`))})}function x({children:e,note:t}){return(0,_.jsxs)(`div`,{className:`skill-detail-actions`,children:[e,t&&(0,_.jsx)(`span`,{className:`skill-readonly-note`,children:t})]})}function S({plugins:e,sourceLabel:t,onImport:n,onToggle:r,onDiff:i,onDelete:a}){let o=[...new Set(e.map(e=>e.source?.kind||`repo`))],s=e.map(e=>{let n=e.components||{};return{key:e.key||e.id,icon:(0,_.jsx)(f,{size:18,"aria-hidden":!0}),name:e.name,badges:[{label:`v${e.version||`0.0.0`}`},...e.imported?[{label:`已导入`}]:[]],description:e.description||``,meta:e.id,haystack:[e.id,e.version,t(e.source)].filter(Boolean).join(` `),sourceKind:e.source?.kind||`repo`,enabled:!!e.enabled,onToggle:()=>r(e),detail:(0,_.jsxs)(_.Fragment,{children:[(0,_.jsx)(y,{facts:[{label:`插件 ID`,value:e.id},{label:`版本`,value:`v${e.version||`0.0.0`}`},{label:`来源`,value:t(e.source)},{label:`路径`,value:e.source?.path||`—`,title:e.source?.path||``}]}),(0,_.jsx)(b,{tags:[{label:e.imported?`已导入`:`项目内置`,on:!!e.imported},{label:`${n.skills||0} Skills`},{label:`${n.mcpServers||0} MCP`},...n.agents?[{label:`${n.agents} Agents`}]:[],...n.commands?[{label:`${n.commands} Commands`}]:[],...n.hooks?[{label:`Hooks`}]:[],{label:e.enabled?`MultiChat 已启用`:`已停用`,on:!!e.enabled}]}),(0,_.jsxs)(x,{note:`插件组件保留在原目录,不复制进私有 JSON`,children:[(0,_.jsx)(`button`,{className:`mc-act wide`,type:`button`,onClick:()=>void i(e),children:`查看 Diff`}),e.removable&&(0,_.jsx)(`button`,{className:`mc-act wide danger`,type:`button`,onClick:()=>void a(e),children:`卸载`})]})]})}});return(0,_.jsx)(v,{title:`插件`,lead:(0,_.jsxs)(_.Fragment,{children:[`插件是完整能力包,以 `,(0,_.jsx)(`code`,{children:`.codex-plugin/plugin.json`}),` 为入口,可组合 Skills、MCP servers、hooks 及宿主专属组件。组件保持原目录,不复制进私有 JSON。`]}),ariaLabel:`插件`,countNoun:`个插件`,items:s,emptyText:`未发现插件。请在项目的 .agents/plugins/marketplace.json 中登记标准插件包。`,headingActions:(0,_.jsxs)(`button`,{type:`button`,className:`btn-primary compact-action`,onClick:n,children:[(0,_.jsx)(m,{size:15,"aria-hidden":!0}),` 上传 / 安装插件包`]}),tabs:[{value:``,label:`全部`},{value:`enabled`,label:`已启用`},{value:`disabled`,label:`已停用`}],sourceOptions:o.map(e=>({value:e,label:t({kind:e})}))})}function C({servers:e,sourceLabel:t,onImport:n,onSync:r,onAdd:i,onDiscover:a,onEdit:o,onToggle:s,onTrust:c,onPrivate:l,onDelete:u}){let d=e.map(e=>{let n=e.transport===`http`?e.url:[e.command,...e.args||[]].join(` `),r=e.status===`ready`?`已连接`:e.status===`error`?`连接失败`:`未探测`;return{key:e.id,icon:(0,_.jsx)(p,{size:18,"aria-hidden":!0}),name:e.name,badges:[{label:e.transport===`http`?`HTTP`:`STDIO`},{label:r,danger:e.status===`error`}],description:e.description||``,meta:e.id,haystack:[e.id,n,...(e.tools||[]).map(e=>e.name)].filter(Boolean).join(` `),sourceKind:e.transport===`http`?`http`:`stdio`,enabled:!!e.enabled,onToggle:()=>s(e),detail:(0,_.jsxs)(_.Fragment,{children:[(0,_.jsx)(y,{facts:[{label:`Server ID`,value:e.id},{label:`Transport`,value:e.transport===`http`?`HTTP`:`STDIO`},{label:`来源`,value:t(e.source)},{label:`环境变量`,value:e.envKeys?.length?e.envKeys.join(`, `):`无`}]}),(0,_.jsx)(`div`,{className:`extension-command resource-detail-extra`,title:n,children:n}),(0,_.jsx)(b,{tags:[{label:`${(e.tools||[]).length} tools`},...(e.targets||[]).map(e=>({label:e,on:!0})),{label:e.trustLevel===`trusted`?`受信任`:`需审批`,on:e.trustLevel===`trusted`},...e.allowPrivate?[{label:`允许内网`}]:[]]}),!!e.tools?.length&&(0,_.jsx)(`div`,{className:`extension-tool-list resource-detail-extra`,children:e.tools.map(e=>(0,_.jsx)(`span`,{title:e.description||``,children:e.name},e.name))}),e.error&&(0,_.jsx)(`div`,{className:`auth-error resource-detail-extra`,title:e.error,children:e.error}),(0,_.jsxs)(x,{children:[(0,_.jsx)(`button`,{className:`mc-act wide primary`,type:`button`,disabled:!e.enabled,onClick:()=>void a(e),children:`探测 tools`}),(0,_.jsx)(`button`,{className:`mc-act wide`,type:`button`,onClick:()=>o(e),children:`配置`}),(0,_.jsx)(`button`,{className:`mc-act wide`,type:`button`,onClick:()=>void c(e),children:e.trustLevel===`trusted`?`改为需审批`:`设为受信任`}),e.transport===`http`&&(0,_.jsx)(`button`,{className:`mc-act wide`,type:`button`,onClick:()=>void l(e),children:e.allowPrivate?`阻止内网`:`允许内网`}),e.source?.kind!==`plugin`&&(0,_.jsx)(`button`,{className:`mc-act wide danger`,type:`button`,onClick:()=>void u(e),children:`删除`})]})]})}});return(0,_.jsx)(v,{title:`MCP servers`,lead:(0,_.jsxs)(_.Fragment,{children:[`每个 server 独立管理 transport、命令或 URL、环境变量、启用范围和实际 tools。Tools 通过实时 `,(0,_.jsx)(`code`,{children:`tools/list`}),` 发现。`]}),ariaLabel:`MCP servers`,countNoun:`个 server`,items:d,emptyText:`还没有 MCP server。`,headingActions:(0,_.jsxs)(_.Fragment,{children:[(0,_.jsx)(`button`,{className:`btn-ghost compact-action`,type:`button`,onClick:n,children:`导入 MCP JSON`}),(0,_.jsx)(`button`,{className:`btn-ghost compact-action`,type:`button`,onClick:()=>void r(),children:`同步到 Codex`}),(0,_.jsx)(`button`,{className:`btn-primary compact-action`,type:`button`,onClick:i,children:`添加 server`})]}),tabs:[{value:``,label:`全部`},{value:`enabled`,label:`已启用`},{value:`disabled`,label:`已停用`}],sourceAriaLabel:`按传输方式筛选`,sourceDefaultLabel:`全部传输方式`,sourceOptions:[{value:`stdio`,label:`STDIO`},{value:`http`,label:`HTTP`}]})}var w=`<svg viewBox="0 0 24 24"><path d="M12 3v12M8 11l4 4 4-4M5 21h14"/></svg>`;function T(e){return{repo:`项目仓库`,managed:`MultiChat 托管`,user:`用户目录`,plugin:`插件`,builtin:`内置`}[e?.kind]||e?.kind||`未知来源`}function E(e,t,r=null){let i=String(t?.status||`clean`).trim()||`clean`,o=String(t?.diff||``).trim(),s=i===`clean`&&!o,c=i===`unavailable`,l=i===`external`,u=s?`clean`:c||l?`warning`:`changed`,d=i.split(/\r?\n/).filter(Boolean).length,f=s?`没有未提交变更`:c?`暂时无法读取变更`:l?`不在项目仓库中`:`检测到 ${d} 项未提交变更`,p=s?`当前内容与 Git 中记录的版本一致。`:c?`请确认当前目录可由 Git 读取后再试。`:l?`该内容位于项目仓库之外,无法提供项目级 Git 差异。`:`请在启用或发布前检查下面的差异内容。`,m=r?.name?`<div class="diff-context"><div><span>检查对象</span><strong>${a(r.name)}</strong></div>${r.meta?`<code title="${a(r.meta)}">${a(r.meta)}</code>`:``}</div>`:``,h=s?``:c||l?`<div class="diff-message ${c?`error`:`warning`}">${a(t?.error||`此目录不属于当前项目仓库。`)}</div>`:`<div class="diff-git-status"><span>Git 状态</span><code title="${a(i)}">${a(i)}</code></div>${o?`<pre class="extension-diff" aria-label="Git 变更内容">${a(o)}</pre>`:`<div class="diff-message">Git 已检测到状态变化,但没有可展示的文本差异。</div>`}`;showModal({title:e,body:`${m}<div class="diff-summary ${u}" role="status"><span class="diff-summary-icon" aria-hidden="true">${s?`✓`:c?`!`:`↗`}</span><div><strong>${f}</strong><span>${p}</span></div></div>${h}<div class="row diff-actions"><button class="btn-primary" id="diffClose">关闭</button></div>`,onMount:e=>{n(`#diffClose`,e).onclick=closeModal}})}function D(e,t){let n=String(e||``).trim();if(!n)return;let r;try{r=JSON.parse(n)}catch{throw Error(`${t} 必须是合法 JSON 对象`)}if(!r||typeof r!=`object`||Array.isArray(r))throw Error(`${t} 必须是 JSON 对象`);return r}function O(e=null){let t=!!e,r=t?c.mcpServers.find(t=>t.id===e):null,i=r?.source?.kind===`plugin`;showModal({title:t?`编辑 MCP server`:`添加 MCP server`,body:`<form id="mcpForm">
2
+ <p class="lead mcp-security-note">STDIO server 会按你的操作启动本地进程;“受信任”只控制工具调用是否逐次审批,不是进程沙箱。只配置你确认可信的命令。</p>
3
+ <div class="field"><label>Server ID</label><input name="id" value="${a(r?.id||``)}" placeholder="context7" ${t?`readonly`:``} required /></div>
4
+ <div class="field"><label>显示名称</label><input name="name" value="${a(r?.name||``)}" placeholder="Context7" required /></div>
5
+ <div class="field"><label>说明</label><input name="description" value="${a(r?.description||``)}" /></div>
6
+ <div class="field"><label>传输方式</label><select name="transport" id="mcpTransport"><option value="stdio" ${r?.transport===`http`?``:`selected`}>STDIO</option><option value="http" ${r?.transport===`http`?`selected`:``}>Streamable HTTP</option></select></div>
7
+ <div id="mcpStdioFields"><div class="field"><label>Command</label><input name="command" value="${a(r?.command||``)}" placeholder="npx" /></div><div class="field"><label>Args(每行一个,原样传递)</label><textarea name="args" rows="3" placeholder="-y&#10;@upstash/context7-mcp">${a((r?.args||[]).join(`
8
+ `))}</textarea></div><div class="field"><label>Working directory</label><input name="cwd" value="${a(r?.cwd||``)}" placeholder=".(相对项目根目录)" /></div><div class="field"><label>Environment JSON</label><textarea name="env" rows="2" placeholder='{"TOKEN":"value"}'></textarea>${r?.envKeys?.length?`<div class="pmeta">已保存:${a(r.envKeys.join(`, `))};留空即保留</div>`:``}</div></div>
9
+ <div id="mcpHttpFields"><div class="field"><label>URL</label><input name="url" value="${a(r?.url||``)}" placeholder="https://example.com/mcp" /></div><div class="field"><label>Bearer token 环境变量名</label><input name="bearerTokenEnvVar" value="${a(r?.bearerTokenEnvVar||``)}" placeholder="MCP_TOKEN" /></div><div class="field"><label>Headers JSON</label><textarea name="headers" rows="2" placeholder='{"X-Region":"cn"}'></textarea>${r?.headerKeys?.length?`<div class="pmeta">已保存:${a(r.headerKeys.join(`, `))};留空即保留</div>`:``}</div></div>
10
+ <div class="field"><label>信任级别</label><select name="trustLevel"><option value="untrusted" ${r?.trustLevel===`trusted`?``:`selected`}>未信任(调用前审批)</option><option value="trusted" ${r?.trustLevel===`trusted`?`selected`:``}>受信任</option></select></div>
11
+ <div class="field"><label>启用范围</label><div class="extension-checks"><label><input type="checkbox" name="target" value="multichat" ${(r?.targets||[`multichat`,`codex`]).includes(`multichat`)?`checked`:``}/> MultiChat</label><label><input type="checkbox" name="target" value="codex" ${(r?.targets||[`multichat`,`codex`]).includes(`codex`)?`checked`:``}/> 当前项目 Codex</label></div></div>
12
+ <div id="mcpErr" class="auth-error">${i?`此 server 来自插件,请在插件源中修改。`:``}</div>
13
+ <div class="row"><button type="button" class="btn-ghost" id="mcpCancel">取消</button><button class="btn-primary compact-action" type="submit" ${i?`disabled`:``}>保存</button></div>
14
+ </form>`,onMount:i=>{let a=n(`#mcpTransport`,i),o=()=>{n(`#mcpStdioFields`,i).style.display=a.value===`stdio`?``:`none`,n(`#mcpHttpFields`,i).style.display=a.value===`http`?``:`none`};a.onchange=o,o(),n(`#mcpCancel`,i).onclick=closeModal,n(`#mcpForm`,i).onsubmit=async a=>{a.preventDefault();let o=a.target,c=Object.fromEntries(new FormData(o).entries());c.args=String(c.args||``).split(/\r?\n/).map(e=>e.trim()).filter(Boolean),c.targets=Array.from(o.querySelectorAll(`input[name="target"]:checked`)).map(e=>e.value);try{let n=D(c.env,`Environment`);n?c.env=n:delete c.env;let i=D(c.headers,`Headers`);if(i?c.headers=i:delete c.headers,c.transport===`stdio`&&(!t||c.command!==r?.command||c.args.join(`
15
+ `)!==(r?.args||[]).join(`
16
+ `))&&!await showConfirm({title:`允许启动本地进程`,message:`允许 MultiChat 启动这个本地 MCP 进程?\n\n${c.command} ${c.args.join(` `)}`,confirmLabel:`允许并保存`}))return;let a=t?`/api/mcp-servers/${encodeURIComponent(e)}`:`/api/mcp-servers`;await l(a,{method:t?`PUT`:`POST`,body:JSON.stringify(c)}),await loadMcpServers(),renderSettings(`mcp`,!0),closeModal(),s(`MCP server 已保存并同步`)}catch(e){n(`#mcpErr`,i).textContent=e.message}}}})}var k=null;function A(){k?.unmount(),k=null}function j(e,t){let r=n(`#settingsBody`);A();let i=document.createElement(`div`);i.className=`settings-react-page`,r.replaceChildren(i),k=(0,h.createRoot)(i),k.render((0,g.createElement)(e,t))}function M(){j(S,{plugins:c.plugins||[],sourceLabel:T,onImport:()=>showExtensionImport(`plugin`),onToggle:async e=>{if(!(!e.enabled&&(e.components?.mcpServers||0)>0&&!await showConfirm({title:`启用插件`,message:`启用插件「${e.name}」?\n\n它包含 MCP server。只有被运行配置选中时才会连接,但本地进程仍以当前用户权限运行,请先审核来源和 Diff。`,confirmLabel:`启用插件`})))try{await l(`/api/plugins/${encodeURIComponent(e.key||e.id)}/toggle`,{method:`POST`,body:JSON.stringify({enabled:!e.enabled})}),await Promise.all([loadPlugins(),loadSkills(),loadMcpServers()]),renderSettings(`plugins`,!0),s(e.enabled?`插件已停用`:`插件已启用`)}catch(e){s(e.message,`error`)}},onDiff:async e=>{try{E(`插件变更`,await l(`/api/plugins/${encodeURIComponent(e.key||e.id)}/diff`),{name:e.name||`插件包`,meta:[e.id,e.version?`v${e.version}`:``].filter(Boolean).join(` · `)})}catch(e){s(e.message,`error`)}},onDelete:async e=>{if(await showConfirm({title:`卸载插件`,message:`卸载插件「${e.name}」?\n\n整包目录、项目市场条目,以及运行配置对其 Skill / MCP 的引用都会移除。`,confirmLabel:`卸载`,danger:!0}))try{await l(`/api/plugins/${encodeURIComponent(e.key||e.id)}`,{method:`DELETE`}),await Promise.all([loadPlugins(),loadSkills(),loadMcpServers(),loadAgents(),loadRuntime()]),renderSettings(`plugins`,!0),s(`插件已卸载`)}catch(e){s(e.message,`error`)}}})}function N(){let e=c.mcpServers||[],t=async()=>{await loadMcpServers(),renderSettings(`mcp`,!0)};j(C,{servers:e,sourceLabel:T,onImport:()=>showExtensionImport(`mcp`),onAdd:()=>O(),onEdit:e=>O(e.id),onSync:async()=>{try{let e=await l(`/api/mcp-servers/sync/codex`,{method:`POST`});s(`已同步 ${e.servers} 个 server 到项目 Codex 配置`)}catch(e){s(e.message,`error`)}},onDiscover:async e=>{try{let n=await l(`/api/mcp-servers/${encodeURIComponent(e.id)}/discover`,{method:`POST`});await t(),s(`发现 ${n.tools.length} 个 tools`)}catch(e){await t(),s(e.message,`error`)}},onToggle:async e=>{if(!e.enabled){let t=e.transport===`http`?e.url:[e.command,...e.args||[]].join(` `);if(!await showConfirm({title:`启用 MCP server`,message:`启用 MCP server「${e.name}」?\n\n${t}\n\nSTDIO 命令会以当前用户权限运行;HTTP server 会连接所示地址。`,confirmLabel:`启用`}))return}try{await l(`/api/mcp-servers/${encodeURIComponent(e.id)}`,{method:`PUT`,body:JSON.stringify({enabled:!e.enabled})}),await t(),s(e.enabled?`MCP server 已停用`:`MCP server 已启用`)}catch(e){s(e.message,`error`)}},onTrust:async e=>{try{let n=e.trustLevel===`trusted`?`untrusted`:`trusted`;await l(`/api/mcp-servers/${encodeURIComponent(e.id)}`,{method:`PUT`,body:JSON.stringify({trustLevel:n})}),await t(),s(n===`trusted`?`已设为受信任;工具调用将不再逐次审批`:`已恢复工具调用审批`)}catch(e){s(e.message,`error`)}},onPrivate:async e=>{if(e.allowPrivate||await showConfirm({title:`允许内网访问`,message:`允许此 HTTP MCP 访问 localhost 或内网地址?只应对你信任的服务器启用。`,confirmLabel:`允许内网`}))try{await l(`/api/mcp-servers/${encodeURIComponent(e.id)}`,{method:`PUT`,body:JSON.stringify({allowPrivate:!e.allowPrivate})}),await t(),s(e.allowPrivate?`已阻止内网地址`:`已允许内网地址`)}catch(e){s(e.message,`error`)}},onDelete:async e=>{if(await showConfirm({title:`删除 MCP server`,message:`删除这个 MCP server?项目 Codex 配置也会同步移除。`,confirmLabel:`删除`,danger:!0}))try{await l(`/api/mcp-servers/${encodeURIComponent(e.id)}`,{method:`DELETE`}),await t(),s(`已删除`)}catch(e){s(e.message,`error`)}}})}export{w as EXPORT_ICON,m as a,b as i,j as mountExtensionSettings,y as n,v as r,N as renderMcpServers,M as renderPlugins,E as showDiff,T as sourceLabel,x as t,A as unmountExtensionSettings};
@@ -0,0 +1 @@
1
+ var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,t)=>()=>(t||(e((t={exports:{}}).exports,t,t.exports),e=null),t.exports),s=(e,n)=>{let r={};for(var i in e)t(r,i,{get:e[i],enumerable:!0});return n||t(r,Symbol.toStringTag,{value:`Module`}),r},c=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},l=(n,r,o)=>(o=n==null?{}:e(i(n)),c(r||!n||!n.__esModule||!a.call(n,`default`)?t(o,`default`,{value:n,enumerable:!0}):o,n)),u=o((e=>{var t=Symbol.for(`react.transitional.element`),n=Symbol.for(`react.portal`),r=Symbol.for(`react.fragment`),i=Symbol.for(`react.strict_mode`),a=Symbol.for(`react.profiler`),o=Symbol.for(`react.consumer`),s=Symbol.for(`react.context`),c=Symbol.for(`react.forward_ref`),l=Symbol.for(`react.suspense`),u=Symbol.for(`react.memo`),d=Symbol.for(`react.lazy`),f=Symbol.for(`react.activity`),p=Symbol.for(`react.view_transition`),m=Symbol.iterator;function h(e){return typeof e!=`object`||!e?null:(e=m&&e[m]||e[`@@iterator`],typeof e==`function`?e:null)}var g={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},_=Object.assign,v={};function y(e,t,n){this.props=e,this.context=t,this.refs=v,this.updater=n||g}y.prototype.isReactComponent={},y.prototype.setState=function(e,t){if(typeof e!=`object`&&typeof e!=`function`&&e!=null)throw Error(`takes an object of state variables to update or a function which returns an object of state variables.`);this.updater.enqueueSetState(this,e,t,`setState`)},y.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this,e,`forceUpdate`)};function b(){}b.prototype=y.prototype;function x(e,t,n){this.props=e,this.context=t,this.refs=v,this.updater=n||g}var S=x.prototype=new b;S.constructor=x,_(S,y.prototype),S.isPureReactComponent=!0;var C=Array.isArray;function w(){}var T={H:null,A:null,T:null,S:null},E=Object.prototype.hasOwnProperty;function D(e,n,r){var i=r.ref;return{$$typeof:t,type:e,key:n,ref:i===void 0?null:i,props:r}}function O(e,t){return D(e.type,t,e.props)}function k(e){return typeof e==`object`&&!!e&&e.$$typeof===t}function A(e){var t={"=":`=0`,":":`=2`};return`$`+e.replace(/[=:]/g,function(e){return t[e]})}var j=/\/+/g;function M(e,t){return typeof e==`object`&&e&&e.key!=null?A(``+e.key):t.toString(36)}function N(e){switch(e.status){case`fulfilled`:return e.value;case`rejected`:throw e.reason;default:switch(typeof e.status==`string`?e.then(w,w):(e.status=`pending`,e.then(function(t){e.status===`pending`&&(e.status=`fulfilled`,e.value=t)},function(t){e.status===`pending`&&(e.status=`rejected`,e.reason=t)})),e.status){case`fulfilled`:return e.value;case`rejected`:throw e.reason}}throw e}function P(e,r,i,a,o){var s=typeof e;(s===`undefined`||s===`boolean`)&&(e=null);var c=!1;if(e===null)c=!0;else switch(s){case`bigint`:case`string`:case`number`:c=!0;break;case`object`:switch(e.$$typeof){case t:case n:c=!0;break;case d:return c=e._init,P(c(e._payload),r,i,a,o)}}if(c)return o=o(e),c=a===``?`.`+M(e,0):a,C(o)?(i=``,c!=null&&(i=c.replace(j,`$&/`)+`/`),P(o,r,i,``,function(e){return e})):o!=null&&(k(o)&&(o=O(o,i+(o.key==null||e&&e.key===o.key?``:(``+o.key).replace(j,`$&/`)+`/`)+c)),r.push(o)),1;c=0;var l=a===``?`.`:a+`:`;if(C(e))for(var u=0;u<e.length;u++)a=e[u],s=l+M(a,u),c+=P(a,r,i,s,o);else if(u=h(e),typeof u==`function`)for(e=u.call(e),u=0;!(a=e.next()).done;)a=a.value,s=l+M(a,u++),c+=P(a,r,i,s,o);else if(s===`object`){if(typeof e.then==`function`)return P(N(e),r,i,a,o);throw r=String(e),Error(`Objects are not valid as a React child (found: `+(r===`[object Object]`?`object with keys {`+Object.keys(e).join(`, `)+`}`:r)+`). If you meant to render a collection of children, use an array instead.`)}return c}function F(e,t,n){if(e==null)return e;var r=[],i=0;return P(e,r,``,``,function(e){return t.call(n,e,i++)}),r}function I(e){if(e._status===-1){var t=e._result,n=t();n.then(function(t){(e._status===0||e._status===-1)&&(e._status=1,e._result=t,n.status===void 0&&(n.status=`fulfilled`,n.value=t))},function(t){(e._status===0||e._status===-1)&&(e._status=2,e._result=t,n.status===void 0&&(n.status=`rejected`,n.reason=t))}),e._status===-1&&(e._status=0,e._result=n)}if(e._status===1)return e._result.default;throw e._result}var L=typeof reportError==`function`?reportError:function(e){if(typeof window==`object`&&typeof window.ErrorEvent==`function`){var t=new window.ErrorEvent(`error`,{bubbles:!0,cancelable:!0,message:typeof e==`object`&&e&&typeof e.message==`string`?String(e.message):String(e),error:e});if(!window.dispatchEvent(t))return}else if(typeof process==`object`&&typeof process.emit==`function`){process.emit(`uncaughtException`,e);return}console.error(e)};function R(e){var t=T.T,n={};n.types=t===null?null:t.types,T.T=n;try{var r=e(),i=T.S;i!==null&&i(n,r),typeof r==`object`&&r&&typeof r.then==`function`&&r.then(w,L)}catch(e){L(e)}finally{t!==null&&n.types!==null&&(t.types=n.types),T.T=t}}function z(e){var t=T.T;if(t!==null){var n=t.types;n===null?t.types=[e]:n.indexOf(e)===-1&&n.push(e)}else R(z.bind(null,e))}var B={map:F,forEach:function(e,t,n){F(e,function(){t.apply(this,arguments)},n)},count:function(e){var t=0;return F(e,function(){t++}),t},toArray:function(e){return F(e,function(e){return e})||[]},only:function(e){if(!k(e))throw Error(`React.Children.only expected to receive a single React element child.`);return e}};e.Activity=f,e.Children=B,e.Component=y,e.Fragment=r,e.Profiler=a,e.PureComponent=x,e.StrictMode=i,e.Suspense=l,e.ViewTransition=p,e.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE=T,e.__COMPILER_RUNTIME={__proto__:null,c:function(e){return T.H.useMemoCache(e)}},e.addTransitionType=z,e.cache=function(e){return function(){return e.apply(null,arguments)}},e.cacheSignal=function(){return null},e.cloneElement=function(e,t,n){if(e==null)throw Error(`The argument must be a React element, but you passed `+e+`.`);var r=_({},e.props),i=e.key;if(t!=null)for(a in t.key!==void 0&&(i=``+t.key),t)!E.call(t,a)||a===`key`||a===`__self`||a===`__source`||a===`ref`&&t.ref===void 0||(r[a]=t[a]);var a=arguments.length-2;if(a===1)r.children=n;else if(1<a){for(var o=Array(a),s=0;s<a;s++)o[s]=arguments[s+2];r.children=o}return D(e.type,i,r)},e.createContext=function(e){return e={$$typeof:s,_currentValue:e,_currentValue2:e,_threadCount:0,Provider:null,Consumer:null},e.Provider=e,e.Consumer={$$typeof:o,_context:e},e},e.createElement=function(e,t,n){var r,i={},a=null;if(t!=null)for(r in t.key!==void 0&&(a=``+t.key),t)E.call(t,r)&&r!==`key`&&r!==`__self`&&r!==`__source`&&(i[r]=t[r]);var o=arguments.length-2;if(o===1)i.children=n;else if(1<o){for(var s=Array(o),c=0;c<o;c++)s[c]=arguments[c+2];i.children=s}if(e&&e.defaultProps)for(r in o=e.defaultProps,o)i[r]===void 0&&(i[r]=o[r]);return D(e,a,i)},e.createRef=function(){return{current:null}},e.forwardRef=function(e){return{$$typeof:c,render:e}},e.isValidElement=k,e.lazy=function(e){return{$$typeof:d,_payload:{_status:-1,_result:e},_init:I}},e.memo=function(e,t){return{$$typeof:u,type:e,compare:t===void 0?null:t}},e.startTransition=R,e.unstable_useCacheRefresh=function(){return T.H.useCacheRefresh()},e.use=function(e){return T.H.use(e)},e.useActionState=function(e,t,n){return T.H.useActionState(e,t,n)},e.useCallback=function(e,t){return T.H.useCallback(e,t)},e.useContext=function(e){return T.H.useContext(e)},e.useDebugValue=function(){},e.useDeferredValue=function(e,t){return T.H.useDeferredValue(e,t)},e.useEffect=function(e,t){return T.H.useEffect(e,t)},e.useEffectEvent=function(e){return T.H.useEffectEvent(e)},e.useId=function(){return T.H.useId()},e.useImperativeHandle=function(e,t,n){return T.H.useImperativeHandle(e,t,n)},e.useInsertionEffect=function(e,t){return T.H.useInsertionEffect(e,t)},e.useLayoutEffect=function(e,t){return T.H.useLayoutEffect(e,t)},e.useMemo=function(e,t){return T.H.useMemo(e,t)},e.useOptimistic=function(e,t){return T.H.useOptimistic(e,t)},e.useReducer=function(e,t,n){return T.H.useReducer(e,t,n)},e.useRef=function(e){return T.H.useRef(e)},e.useState=function(e){return T.H.useState(e)},e.useSyncExternalStore=function(e,t,n){return T.H.useSyncExternalStore(e,t,n)},e.useTransition=function(){return T.H.useTransition()},e.version=`19.3.1`})),d=o(((e,t)=>{t.exports=u()}));export{l as i,o as n,s as r,d as t};
@@ -1 +1 @@
1
- import{p as e}from"./index-BaUGyQ3C.js";function t(){e()}function n(e){e&&(e.style.height=`auto`,e.style.height=`${Math.min(240,e.scrollHeight)}px`)}export{n as autoresize,t as renderContent};
1
+ import{_ as e}from"./index-CeU_ksnE.js";function t(){e()}function n(e){e&&(e.style.height=`auto`,e.style.height=`${Math.min(240,e.scrollHeight)}px`)}export{n as autoresize,t as renderContent};
@@ -0,0 +1,14 @@
1
+ import{E as e,S as t,T as n,b as r,f as i,m as a,w as o,x as s}from"./index-CeU_ksnE.js";import{openModelPicker as c}from"./modelPicker-B612Gojw.js";async function l(t){if(r.streaming){d();return}let i=r.messages.length?e(`#input`):e(`#heroInput`),a=(t??i?.value??``).trim();if(a){if(!r.selectedProvider||!r.selectedModel)n(r.providers.length?`请先选择模型`:`请先添加模型`,`error`),r.providers.length?c():openSettings(`providers`);else{if(r.messages.push({role:`user`,content:a}),r.messages.push({role:`assistant`,content:``,streaming:!0,model:r.selectedModel,providerName:r.selectedProvider.name||r.selectedProvider.id,startTime:performance.now()}),i&&(i.value=``),r.streaming=!0,u(),renderContent(),r.messages.length){let t=e(`#input`);t&&t.focus()}try{await f()}catch(e){m(`无法创建或保存对话`,e),await h();return}await g()}}}function u(){renderContent()}function d(){if(r.abortCtrl&&(r.abortCtrl.abort(),r.abortCtrl=null),r.streaming){let e=r.messages[r.messages.length-1];e&&e.streaming&&(e.streaming=!1),r.streaming=!1,u(),renderContent(),p()}}async function f(){if(r.currentConvId)return;let n=r.messages.find(e=>e.role===`user`)?.content?.slice(0,24)||`新对话`,a=await i(`/api/conversations`,{method:`POST`,body:JSON.stringify({title:n,workspaceId:r.selectedWorkspace?.id||null,projectId:r.selectedProject?.id||null})});r.currentConvId=a.id;let s=o(a.id,a.projectId||r.selectedProject?.id);r.workflow=t(r.workflowScope,s,r.workflow),r.workflowScope=s,e(`#topbarTitle`).textContent=a.title||`对话`;let c=`#/chat/${encodeURIComponent(a.id)}`;location.hash!==c&&history.replaceState(null,``,c),await loadConversations()}async function p(){if(r.currentConvId)try{await i(`/api/conversations/`+r.currentConvId+`/messages`,{method:`POST`,body:JSON.stringify(r.messages.filter(e=>!e.streaming))})}catch{}}function m(e,t){let n=r.messages[r.messages.length-1];if(!n||n.role!==`assistant`)return;let i=t?.message?`:${t.message}`:``;n.content=n.content?`${n.content}\n\n**${e}**${i}`:`**${e}**${i}`,n.streaming=!1}async function h(){let e=r.messages[r.messages.length-1];e?.streaming&&(e.streaming=!1),r.abortCtrl=null,r.streaming=!1,u(),await p()}async function g(e){try{await _(e)}catch(e){if(e?.name===`AbortError`){let e=r.messages[r.messages.length-1];e&&(e.cancelled=!0,e.content||=`(已停止)`)}else m(`连接意外中断`,e),n(`连接意外中断,请重试`,`error`)}finally{await h()}}async function _(e){let t=r.selectedProvider,n=r.selectedModel;if(!t){let e=r.messages[r.messages.length-1];e&&(e.content=`**未选择模型**:请先在「设置 → 模型」中添加并选择模型。
2
+
3
+ → [打开 设置 → 模型连接](#/settings/providers)`,e.streaming=!1),renderContent();return}if(t.id!==`mock`&&![`ollama`,`lmstudio`,`mock`].includes((t.apiType||``).toLowerCase())&&!t.apiKey&&!t.apiKeyMasked){let e=r.messages[r.messages.length-1];e&&(e.content=`**缺少 API Key**:Provider「${t.name}」尚未填写 API Key。\n\n→ [打开 设置 → 模型连接填写 Key](#/settings/providers)`,e.streaming=!1),renderContent();return}if(!t.baseUrl){let e=r.messages[r.messages.length-1];e&&(e.content=`**缺少 API 地址**:Provider「${t.name}」尚未填写 baseUrl。\n\n→ [打开 设置 → 模型连接补全地址](#/settings/providers)`,e.streaming=!1),renderContent();return}let i=!!r.selectedAgent,o=i?`/api/agents/${r.selectedAgent.id}/chat`:`/v1/chat/completions`,c=s(r.workflow),l=r.messages.filter(e=>!e.streaming||e.role===`user`).map(e=>({role:e.role,content:e.content}));l.unshift({role:`system`,content:c});let u={model:t.id+`:`+n,providerId:t.id,messages:l,stream:!0,temperature:r.params.temperature,max_tokens:r.params.max_tokens,top_p:r.params.top_p,workspaceId:r.selectedWorkspace?.id||null,projectId:r.selectedProject?.id||null,conversationId:r.currentConvId||null,interactionId:`${r.currentConvId||`chat`}_${Date.now().toString(36)}`,assetIds:[...r.selectedAssetIds]};e&&(u.resumeFromRunId=e),r.abortCtrl=new AbortController;let d;try{d=await fetch(r.apiBase+o,{method:`POST`,headers:{"Content-Type":`application/json`,...a()},body:JSON.stringify(u),signal:r.abortCtrl.signal})}catch(e){if(e.name===`AbortError`){i&&r.currentRunId&&fetch(r.apiBase+`/api/runs/`+r.currentRunId+`/cancel`,{method:`POST`,headers:{"Content-Type":`application/json`,...a()}}).catch(()=>{});let e=r.messages[r.messages.length-1];e&&(e.streaming=!1,e.cancelled=!0,e.content||=`(已停止)`),renderContent();return}let t=r.messages[r.messages.length-1];t&&(t.content=`**网络错误**: `+e.message,t.streaming=!1),renderContent();return}if(!d.ok){let e=``;try{let t=await d.clone().json();e=(typeof t?.error==`string`?t.error:t?.error?.message)||t?.message||``}catch{}let t={400:`请求参数有误(通常是 model 名不识别或 messages 格式不对)`,401:`上游 API 鉴权失败 — API Key 无效或已过期`,403:`上游拒绝访问 — 可能原因:API Key 被禁用 / 余额不足 / IP 地区受限`,404:`上游接口或模型不存在 — 检查 baseUrl 和模型名`,429:`上游限流 — 请稍后重试或降低请求频率`,500:`上游服务器内部错误`,502:`MultiChat 无法连接上游 — 检查 baseUrl 是否可访问`,503:`上游服务暂不可用`}[d.status]||``,n=r.messages[r.messages.length-1];n&&(n.content=`**请求失败 (HTTP ${d.status})**${t?`:`+t:``}`+(e?`\n\n> ${e}`:``)+(i?`
4
+
5
+ 排查建议:① 设置 → 运行配置确认提示词与 Skill 关联正确;② 设置 → 模型连接确认 API Key 正确;③ 切换其他模型试一下。`:`
6
+
7
+ 排查建议:① 设置 → 模型 中确认 API Key 正确;② baseUrl 可在浏览器直接访问;③ 切换其他模型试一下。`)+(d.status===401||d.status===403?`
8
+
9
+ → [打开 设置 → 模型连接,测试或更换 API Key](#/settings/providers)`:``),n.streaming=!1),renderContent();return}if(!d.body){let e=r.messages[r.messages.length-1];e&&(e.content=`**错误**: 响应无 body`,e.streaming=!1),renderContent();return}let f=d.body.getReader(),m=new TextDecoder(`utf-8`),h=``,g=``;for(;;){let{value:e,done:t}=await f.read();if(t)break;h+=m.decode(e,{stream:!0});let n;for(;(n=h.indexOf(`
10
+
11
+ `))>=0;){let e=h.slice(0,n);h=h.slice(n+2);let t=e.split(`
12
+ `).find(e=>e.startsWith(`data:`));if(!t)continue;let i=t.slice(5).trim();if(i!==`[DONE]`)try{let e=JSON.parse(i),t=r.messages[r.messages.length-1];if(!t)continue;if(e.meta&&e.meta.agent){t.agentTag=e.meta.agent.name,t.mcpWarnings=e.meta.mcpWarnings||[],e.meta.run&&e.meta.run.id&&(r.currentRunId=e.meta.run.id),renderContent();continue}if(e.agentEvent){t.trace||=[];let n=e.agentEvent;if(n.type===`cancelled`)t.cancelled=!0;else if(n.type===`paused`)t.resumeRunId=n.runId,t.pauseReason=n.reason||`已达到本轮执行上限`,t.streaming=!1;else if(n.type===`approval_required`)t.pendingApprovals||={},t.pendingApprovals[n.approval.id]=n.approval;else if(n.type===`approval_resolved`){t.pendingApprovals||={};let e=t.pendingApprovals[n.approval.id]||{};t.pendingApprovals[n.approval.id]=Object.assign({},e,n.approval)}else if(n.step){let e=t.trace.findIndex(e=>e.sid===n.step.sid);e<0?t.trace.push(n.step):t.trace[e]=Object.assign({},t.trace[e],n.step)}renderContent();continue}if(e.error){g+=(g?`
13
+
14
+ `:``)+`**[错误]** `+(e.error.message||`未知错误`),t.content=g,t.streaming=!1,renderContent();continue}if(e.usage){t.usage=e.usage,e.model&&(t.model=e.model),renderContent();continue}if(e.choices&&e.choices[0]&&e.choices[0].delta&&e.choices[0].delta.tool_result){let n=e.choices[0].delta.tool_result;t.toolCalls||=[],t.toolCalls.push({id:n.id,name:n.name,content:n.content}),renderContent();continue}if(e.choices&&e.choices[0]&&e.choices[0].delta&&e.choices[0].delta.reasoning_content){let n=e.choices[0].delta.reasoning_content;t.reasoning||=``,t.reasoning+=n,renderContent();continue}let n=e?.choices?.[0]?.delta?.content??e?.choices?.[0]?.message?.content??``;n&&(g+=n,t.content=g,renderContent())}catch{}}}let _=r.messages[r.messages.length-1];_&&(_.streaming=!1,_.startTime&&(_.elapsedMs=Math.round(performance.now()-_.startTime))),renderContent(),p(),i&&loadRuns().then(()=>renderInspector())}async function v(e){await navigator.clipboard.writeText(r.messages[e]?.content||``),n(`已复制`)}async function y(e){let t=r.messages[e];if(!t)return;let n=await showPrompt({title:`编辑消息`,label:`消息内容`,value:t.content,multiline:!0,rows:7,required:!1,confirmLabel:`保存`});n!=null&&(t.content=n,r.messages=r.messages.slice(0,e+1),renderContent(),p())}async function b(e){r.streaming||(r.messages=r.messages.slice(0,e),r.messages.push({role:`assistant`,content:``,streaming:!0,model:r.selectedModel,providerName:r.selectedProvider?.name||r.selectedProvider?.id,startTime:performance.now()}),r.streaming=!0,renderContent(),await g())}async function x(e){if(r.streaming)return;let t=r.messages[e];t?.resumeRunId&&(r.messages.push({role:`assistant`,content:``,streaming:!0,model:r.selectedModel,providerName:r.selectedProvider?.name||r.selectedProvider?.id,startTime:performance.now()}),r.streaming=!0,renderContent(),await g(t.resumeRunId))}async function S(e,t){let i=r.currentRunId;if(!i){n(`无法定位运行任务`,`error`);return}let o=await fetch(r.apiBase+`/api/runs/`+i+`/approval/`+e,{method:`POST`,headers:{"Content-Type":`application/json`,...a()},body:JSON.stringify({action:t})}),s=await o.json().catch(()=>({}));if(!o.ok)throw n(`审批失败:`+(s?.error?.message||s?.error||`未知错误`),`error`),Error(s?.error?.message||s?.error||`审批失败`);let c=r.messages.find(t=>t.pendingApprovals&&t.pendingApprovals[e]),l=c?r.messages.indexOf(c):-1;if(c){let n=t===`approve`?`approved`:`rejected`;c.pendingApprovals[e]={...c.pendingApprovals[e],status:n,resolvedAt:new Date().toISOString()},renderContent()}n(t===`approve`?`已批准,Agent 继续执行`:`已拒绝`),s.resumable&&c&&l>=0&&(c.resumeRunId=i,c.pauseReason=t===`approve`?`授权已记录,正在从检查点继续。`:`拒绝已记录,正在让 Agent 收束本轮。`,await x(l))}export{v as copyMessage,y as editMessage,f as ensureConversation,b as regenerateMessage,S as resolveApproval,x as resumeMessage,p as saveCurrentMessages,l as send,d as stopStream,_ as streamReply,u as updateSendBtn};
@@ -0,0 +1,2 @@
1
+ import{A as e,D as t,E as n,F as r,I as i,L as a,M as o,N as s,O as c,P as l,R as u,T as d,a as f,b as p,c as m,d as h,f as g,h as _,j as v,k as y,l as b,n as x,o as S,p as C,s as w,u as T,v as E,y as D}from"./index-CeU_ksnE.js";import{a as O,i as k,mountExtensionSettings as A,n as j,r as ee,renderMcpServers as te,renderPlugins as ne,showDiff as re,sourceLabel as ie,t as ae,unmountExtensionSettings as oe}from"./pluginsUI-KCpFagXv.js";import{i as se,t as ce}from"./react-sySUN5R7.js";import{importProjectFolder as le}from"./assets-ChkvQqhp.js";import{applyProjectDefaults as ue,renderFileContext as M}from"./conversations-DoyXfY4T.js";import{loadAgents as N,loadCapabilities as P,loadProjectControlData as F,loadProjects as I,loadProviders as de,loadRuns as fe,loadSkills as pe,loadTools as me,loadUsage as he,loadWorkspaces as ge}from"./data-BN7t_AoO.js";import{showExtensionImport as _e}from"./extensionImport-DPZhdnxE.js";import{doImport as ve,exportEntity as ye,normalizeImport as be,showAddBuiltin as xe,showAddCustom as Se,showAgentModal as Ce,showSkillModal as we}from"./importExport-Bb6-L-4y.js";import{closeModal as L,showModal as R}from"./modal-BYrNUOVj.js";import{renderTopbar as z}from"./modelPicker-B612Gojw.js";import{renderContent as Te}from"./render-BBfAbC8M.js";import{adoptResult as Ee,compareTargets as De,executeTarget as Oe}from"./compare-CkyqXEbN.js";var B=u(`download`,[[`path`,{d:`M12 15V3`,key:`m9g1x1`}],[`path`,{d:`M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4`,key:`ih7n3h`}],[`path`,{d:`m7 10 5 5 5-5`,key:`brsn70`}]]),V=u(`file-pen-line`,[[`path`,{d:`m18 5-2.414-2.414A2 2 0 0 0 14.172 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2`,key:`142zxg`}],[`path`,{d:`M21.378 12.626a1 1 0 0 0-3.004-3.004l-4.01 4.012a2 2 0 0 0-.506.854l-.837 2.87a.5.5 0 0 0 .62.62l2.87-.837a2 2 0 0 0 .854-.506z`,key:`2t3380`}],[`path`,{d:`M8 18h1`,key:`13wk12`}]]),ke=u(`pen-line`,[[`path`,{d:`M13 21h8`,key:`1jsn5i`}],[`path`,{d:`M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z`,key:`1a8usu`}]]),H=se(ce(),1),U=y();function Ae({params:e,theme:t,token:n,onSaveParams:r,onTheme:i,onSaveToken:a,skin:o,density:s,onSkin:c,onDensity:l}){let[u,d]=(0,H.useState)(Number(e.temperature)),[f,p]=(0,H.useState)(Number(e.max_tokens)),[m,h]=(0,H.useState)(Number(e.top_p)),[g,_]=(0,H.useState)(n),[v,y]=(0,H.useState)(t),[b,x]=(0,H.useState)(o||`blue`),[S,C]=(0,H.useState)(s||`comfortable`);return(0,H.useEffect)(()=>{let e=e=>{let t=e.detail?.preference;t&&y(t)},t=e=>{let t=e.detail;t?.skin&&x(t.skin),t?.density&&C(t.density)};return window.addEventListener(`multichat:themechange`,e),window.addEventListener(`multichat:appearancechange`,t),()=>{window.removeEventListener(`multichat:themechange`,e),window.removeEventListener(`multichat:appearancechange`,t)}},[]),(0,U.jsxs)(U.Fragment,{children:[(0,U.jsx)(`h3`,{children:`偏好设置`}),(0,U.jsx)(`p`,{className:`lead`,children:`模型参数与外观`}),(0,U.jsxs)(`section`,{className:`provider-card`,children:[(0,U.jsx)(`h4`,{children:`模型参数`}),(0,U.jsx)(`div`,{className:`pmeta`,children:`应用于每次对话请求(OpenAI 兼容)`}),(0,U.jsxs)(`div`,{className:`field`,children:[(0,U.jsxs)(`label`,{htmlFor:`pTempReact`,children:[`温度 Temperature:`,u]}),(0,U.jsx)(`input`,{id:`pTempReact`,type:`range`,min:`0`,max:`2`,step:`0.1`,value:u,onChange:e=>d(Number(e.target.value))})]}),(0,U.jsxs)(`div`,{className:`field`,children:[(0,U.jsx)(`label`,{htmlFor:`pMaxReact`,children:`最大输出 Token`}),(0,U.jsx)(`input`,{id:`pMaxReact`,type:`number`,min:`1`,max:`128000`,value:f,onChange:e=>p(Number(e.target.value))})]}),(0,U.jsxs)(`div`,{className:`field`,children:[(0,U.jsxs)(`label`,{htmlFor:`pTopReact`,children:[`Top P:`,m]}),(0,U.jsx)(`input`,{id:`pTopReact`,type:`range`,min:`0`,max:`1`,step:`0.05`,value:m,onChange:e=>h(Number(e.target.value))})]}),(0,U.jsxs)(`div`,{className:`provider-row`,children:[(0,U.jsx)(`button`,{className:`btn-ghost`,type:`button`,onClick:()=>{d(.7),p(2e3),h(1)},children:`重置`}),(0,U.jsx)(`button`,{className:`btn-primary compact-action`,type:`button`,onClick:()=>r({temperature:u,max_tokens:f||2e3,top_p:m}),children:`保存`})]})]}),(0,U.jsxs)(`section`,{className:`provider-card`,children:[(0,U.jsx)(`h4`,{children:`外观`}),(0,U.jsxs)(`div`,{className:`field`,children:[(0,U.jsx)(`label`,{htmlFor:`themeReact`,children:`主题`}),(0,U.jsxs)(`select`,{id:`themeReact`,value:v,onChange:e=>{y(e.target.value),i(e.target.value)},children:[(0,U.jsx)(`option`,{value:`light`,children:`浅色`}),(0,U.jsx)(`option`,{value:`dark`,children:`深色`}),(0,U.jsx)(`option`,{value:`system`,children:`跟随系统`})]})]}),(0,U.jsxs)(`div`,{className:`field`,children:[(0,U.jsx)(`label`,{htmlFor:`skinReact`,children:`强调色`}),(0,U.jsxs)(`select`,{id:`skinReact`,value:b,onChange:e=>{x(e.target.value),c(e.target.value)},children:[(0,U.jsx)(`option`,{value:`blue`,children:`工作台蓝`}),(0,U.jsx)(`option`,{value:`graphite`,children:`石墨灰`}),(0,U.jsx)(`option`,{value:`teal`,children:`青绿`})]})]}),(0,U.jsxs)(`div`,{className:`field`,children:[(0,U.jsx)(`label`,{htmlFor:`densityReact`,children:`界面密度`}),(0,U.jsxs)(`select`,{id:`densityReact`,value:S,onChange:e=>{C(e.target.value),l(e.target.value)},children:[(0,U.jsx)(`option`,{value:`comfortable`,children:`标准`}),(0,U.jsx)(`option`,{value:`compact`,children:`紧凑`})]})]})]}),(0,U.jsxs)(`section`,{className:`provider-card`,children:[(0,U.jsx)(`h4`,{children:`本地服务访问保护`}),(0,U.jsx)(`div`,{className:`pmeta`,children:`仅在服务启用 MULTICHAT_API_TOKEN(兼容 MC_API_TOKEN)时填写;只保存在当前浏览器。`}),(0,U.jsxs)(`div`,{className:`field`,children:[(0,U.jsx)(`label`,{htmlFor:`serverTokenReact`,children:`访问令牌`}),(0,U.jsx)(`input`,{id:`serverTokenReact`,type:`password`,value:g,onChange:e=>_(e.target.value),autoComplete:`off`,placeholder:`未启用则留空`})]}),(0,U.jsxs)(`div`,{className:`provider-row`,children:[(0,U.jsx)(`button`,{className:`btn-ghost`,type:`button`,onClick:()=>{_(``),a(``)},children:`清除`}),(0,U.jsx)(`button`,{className:`btn-primary compact-action`,type:`button`,onClick:()=>a(g.trim()),children:`保存令牌`})]})]}),(0,U.jsxs)(`section`,{className:`provider-card`,children:[(0,U.jsx)(`h4`,{children:`关于`}),(0,U.jsxs)(`div`,{className:`pmeta`,children:[`MultiChat · 本地优先的多模型工作台`,(0,U.jsx)(`br`,{}),`模型、Skills、MCP 与插件按运行配置组合。`]})]})]})}function je({provider:e,onSave:t,onDelete:n,onProbe:r}){let i=e.models||(e.model?[e.model]:[]),a=[`ollama`,`lmstudio`,`mock`].includes((e.apiType||``).toLowerCase())||e.id===`mock`,o=!!(e.apiKeyMasked||e.apiKey)||a,[s,c]=(0,H.useState)(``),[l,u]=(0,H.useState)(i.join(`, `)),[d,f]=(0,H.useState)(!!e.allowPrivate),[p,m]=(0,H.useState)(!1),[h,g]=(0,H.useState)(``),_=async()=>{m(!0),g(``);try{let t=await r(e),n=Array.isArray(t.models)?t.models:[];n.length?l.trim()?g(`✓ 连接成功 · 服务端返回 ${n.length} 个模型`):(u(n.join(`, `)),g(`✓ 连接成功 · 发现 ${n.length} 个模型,已填入列表,记得保存`)):g(`✓ 连接成功,但服务未返回模型清单;可手动填写`)}catch(e){g(`✗ ${e.message||`连接失败`}`)}finally{m(!1)}};return(0,U.jsxs)(`article`,{className:`provider-card provider-config-card`,children:[(0,U.jsxs)(`div`,{className:`provider-card-head`,children:[(0,U.jsx)(`span`,{className:`provider-mark`,"aria-hidden":!0,children:(e.name||e.id).trim().slice(0,1).toUpperCase()||`M`}),(0,U.jsxs)(`div`,{className:`provider-identity`,children:[(0,U.jsxs)(`h4`,{children:[e.name||e.id,` `,(0,U.jsx)(`span`,{className:`provider-id`,children:e.id})]}),(0,U.jsxs)(`div`,{className:`pmeta`,children:[e.apiType||`openai`,` · `,i.length?`${i.length} 个模型`:`手动输入模型`,(e.capabilities?.vision||e.capabilities?.reasoning)&&(0,U.jsxs)(`span`,{className:`provider-caps`,children:[e.capabilities.vision?`视觉`:``,e.capabilities.vision&&e.capabilities.reasoning?` · `:``,e.capabilities.reasoning?`推理`:``]})]})]}),(0,U.jsx)(`span`,{className:`provider-state ${o?a?`local`:`ready`:`missing`}`,children:o?a?`本地`:`已配置`:`待配置`})]}),(0,U.jsxs)(`div`,{className:`provider-card-fields`,children:[(0,U.jsxs)(`div`,{className:`field`,children:[(0,U.jsx)(`label`,{htmlFor:`provider-key-r-${e.id}`,children:`API 密钥`}),(0,U.jsx)(`input`,{id:`provider-key-r-${e.id}`,type:`password`,value:s,onChange:e=>c(e.target.value),placeholder:e.apiKeyMasked?`已安全保存 ····${e.apiKeyPreview||``}`:a?`本地提供方可留空`:`输入 API 密钥`,autoComplete:`new-password`})]}),(0,U.jsxs)(`div`,{className:`field`,children:[(0,U.jsx)(`label`,{htmlFor:`provider-models-r-${e.id}`,children:`模型列表`}),(0,U.jsx)(`textarea`,{id:`provider-models-r-${e.id}`,rows:1,value:l,onChange:e=>u(e.target.value)})]})]}),(0,U.jsxs)(`div`,{className:`provider-card-footer`,children:[(0,U.jsxs)(`label`,{className:`provider-private`,children:[(0,U.jsx)(`input`,{type:`checkbox`,checked:d,onChange:e=>f(e.target.checked)}),` 允许访问本机 / 内网`]}),(0,U.jsxs)(`div`,{className:`provider-row`,children:[(0,U.jsx)(`button`,{className:`btn-ghost`,type:`button`,disabled:p,onClick:()=>void _(),children:p?`测试中…`:`测试连接`}),(0,U.jsx)(`button`,{className:`btn-ghost danger-ghost`,type:`button`,onClick:()=>void n(e),children:`删除`}),(0,U.jsx)(`button`,{className:`btn-primary`,type:`button`,onClick:()=>void t(e,{...s?{apiKey:s}:{},models:l.split(/[,\n]/).map(e=>e.trim()).filter(Boolean),allowPrivate:d}),children:`保存`})]})]}),h&&(0,U.jsx)(`div`,{className:`provider-probe-result`,role:`status`,children:h})]})}function Me({providers:e,onSave:t,onDelete:n,onAddBuiltin:i,onAddCustom:a,onProbe:o}){let[s,c]=(0,H.useState)(e),l=s.reduce((e,t)=>e+(t.models?.length||+!!t.model),0),u=s.filter(e=>!!(e.apiKeyMasked||e.apiKey)||e.id===`mock`||[`ollama`,`lmstudio`,`mock`].includes((e.apiType||``).toLowerCase())).length;return(0,U.jsxs)(`section`,{className:`provider-settings`,children:[(0,U.jsxs)(`div`,{className:`settings-page-heading`,children:[(0,U.jsxs)(`div`,{children:[(0,U.jsx)(`h3`,{children:`模型连接`}),(0,U.jsx)(`p`,{className:`lead`,children:`管理提供方凭证和可选模型;所有配置仅保存在本地。`})]}),(0,U.jsxs)(`div`,{className:`provider-summary`,"aria-label":`模型配置概览`,children:[(0,U.jsxs)(`span`,{children:[(0,U.jsx)(`strong`,{children:s.length}),` 个提供方`]}),(0,U.jsxs)(`span`,{children:[(0,U.jsx)(`strong`,{children:l}),` 个模型`]}),(0,U.jsxs)(`span`,{children:[(0,U.jsx)(`strong`,{children:u}),` 个可用`]})]})]}),(0,U.jsxs)(`div`,{className:`provider-grid`,children:[s.map(e=>(0,U.jsx)(je,{provider:e,onSave:t,onProbe:o,onDelete:async e=>{await n(e)&&c(t=>t.filter(t=>t.id!==e.id))}},e.id)),!s.length&&(0,U.jsx)(`div`,{className:`provider-empty`,children:`还没有添加任何模型,点击下方按钮开始配置。`})]}),(0,U.jsxs)(`div`,{className:`add-provider provider-add-grid`,children:[(0,U.jsxs)(`button`,{type:`button`,className:`add-tile`,onClick:i,children:[(0,U.jsx)(r,{className:`ico`,"aria-hidden":!0}),(0,U.jsxs)(`span`,{children:[(0,U.jsx)(`strong`,{children:`添加提供方`}),(0,U.jsx)(`small`,{children:`从内置模板快速配置`})]})]}),(0,U.jsxs)(`button`,{type:`button`,className:`add-tile`,onClick:a,children:[(0,U.jsx)(r,{className:`ico`,"aria-hidden":!0}),(0,U.jsxs)(`span`,{children:[(0,U.jsx)(`strong`,{children:`自定义提供方`}),(0,U.jsx)(`small`,{children:`接入 OpenAI 兼容服务`})]})]})]})]})}function Ne({initialSkills:e,sourceLabel:t,onToggle:n,onEdit:a,onDiff:c,onDelete:l,onImport:u,onAdd:d}){let[f,p]=(0,H.useState)(e),[m,h]=(0,H.useState)(``),[g,_]=(0,H.useState)(``),[y,b]=(0,H.useState)(``),[x,S]=(0,H.useState)(null),C=(0,H.useMemo)(()=>[...new Set(f.map(e=>e.source?.kind||`managed`))],[f]),w=f.filter(e=>(!m||[e.name,e.id,e.description,t(e.source)].filter(Boolean).join(` `).toLowerCase().includes(m.toLowerCase()))&&(!g||(e.source?.kind||`managed`)===g)&&(!y||(e.enabled?`enabled`:`disabled`)===y));return(0,U.jsxs)(`section`,{className:`skill-settings`,children:[(0,U.jsxs)(`div`,{className:`settings-page-heading skill-page-heading`,children:[(0,U.jsxs)(`div`,{children:[(0,U.jsx)(`h3`,{children:`Agent Skills`}),(0,U.jsxs)(`p`,{className:`lead`,children:[`每个 Skill 都是一个以 `,(0,U.jsx)(`code`,{children:`SKILL.md`}),` 为入口的目录,可附带 scripts、references 和 assets;这里的开关控制 MultiChat 是否使用它。`]})]}),(0,U.jsxs)(`div`,{className:`skill-heading-actions`,children:[(0,U.jsxs)(`button`,{type:`button`,className:`btn-primary compact-action`,onClick:u,children:[(0,U.jsx)(O,{size:15,"aria-hidden":!0}),` 上传 / 导入`]}),(0,U.jsxs)(`button`,{type:`button`,className:`btn-ghost compact-action`,onClick:d,children:[(0,U.jsx)(r,{size:15,"aria-hidden":!0}),` 新建 Skill`]})]})]}),(0,U.jsx)(`div`,{className:`skill-tabs`,role:`group`,"aria-label":`按状态筛选 Skills`,children:[{value:``,label:`全部`},{value:`enabled`,label:`已启用`},{value:`disabled`,label:`已停用`}].map(e=>(0,U.jsx)(`button`,{type:`button`,className:`skill-tab${y===e.value?` active`:``}`,"aria-pressed":y===e.value,onClick:()=>b(e.value),children:e.label},e.value))}),(0,U.jsxs)(`div`,{className:`resource-toolbar skill-toolbar`,"aria-label":`筛选 Skills`,children:[(0,U.jsxs)(`label`,{className:`resource-search`,children:[(0,U.jsx)(s,{size:15,"aria-hidden":!0}),(0,U.jsx)(`input`,{type:`search`,"aria-label":`搜索 Skills`,placeholder:`搜索名称、说明或 ID`,value:m,onChange:e=>h(e.target.value)})]}),(0,U.jsxs)(`select`,{"aria-label":`按来源筛选`,value:g,onChange:e=>_(e.target.value),children:[(0,U.jsx)(`option`,{value:``,children:`全部来源`}),C.map(e=>(0,U.jsx)(`option`,{value:e,children:t({kind:e})},e))]}),(0,U.jsxs)(`span`,{className:`resource-count`,children:[w.length,` / `,f.length,` 个 Skills`]})]}),(0,U.jsxs)(`div`,{className:`skill-list`,children:[w.map((e,r)=>{let s=e.key||e.id,u=[`managed`,`repo`].includes(e.source?.kind),d=x===s,f=`skill-detail-${r}`;return(0,U.jsxs)(`article`,{className:`skill-row${d?` is-open`:``}`,children:[(0,U.jsxs)(`div`,{className:`skill-row-main`,children:[(0,U.jsx)(`span`,{className:`skill-row-ico`,"aria-hidden":!0,children:(0,U.jsx)(V,{size:18})}),(0,U.jsxs)(`div`,{className:`skill-row-copy`,children:[(0,U.jsxs)(`div`,{className:`skill-row-title`,children:[(0,U.jsx)(`strong`,{children:e.name}),(0,U.jsx)(`span`,{className:`skill-row-badge`,children:t(e.source)}),e.invalid&&(0,U.jsx)(`span`,{className:`skill-row-badge danger`,children:`格式无效`})]}),(0,U.jsx)(`p`,{className:`skill-row-desc`,children:e.description||`(暂无描述)`}),(0,U.jsx)(`span`,{className:`skill-row-id`,children:e.id})]}),(0,U.jsxs)(`div`,{className:`skill-row-actions`,children:[(0,U.jsx)(`button`,{type:`button`,className:`mc-toggle${e.enabled?` on`:``}`,"aria-pressed":!!e.enabled,"aria-label":`${e.name}:${e.enabled?`已启用,点击停用`:`已停用,点击启用`}`,onClick:async()=>{await n(e)&&p(e=>e.map(e=>(e.key||e.id)===s?{...e,enabled:!e.enabled}:e))},children:(0,U.jsx)(`span`,{className:`mc-switch`,"aria-hidden":!0})}),(0,U.jsx)(`button`,{type:`button`,className:`skill-row-expand`,"aria-expanded":d,"aria-controls":f,"aria-label":`${d?`收起`:`展开`} ${e.name} 详情`,onClick:()=>S(d?null:s),children:(0,U.jsx)(i,{size:16,"aria-hidden":!0})})]})]}),(0,U.jsxs)(`div`,{className:`skill-row-detail`,id:f,hidden:!d,children:[(0,U.jsxs)(`dl`,{className:`skill-facts`,children:[(0,U.jsxs)(`div`,{children:[(0,U.jsx)(`dt`,{children:`Skill ID`}),(0,U.jsx)(`dd`,{children:e.id})]}),(0,U.jsxs)(`div`,{children:[(0,U.jsx)(`dt`,{children:`来源`}),(0,U.jsx)(`dd`,{children:t(e.source)})]}),(0,U.jsxs)(`div`,{children:[(0,U.jsx)(`dt`,{children:`作用域`}),(0,U.jsx)(`dd`,{children:e.scope||`project`})]}),(0,U.jsxs)(`div`,{children:[(0,U.jsx)(`dt`,{children:`路径`}),(0,U.jsx)(`dd`,{title:e.path||``,children:e.path||`—`})]})]}),(0,U.jsxs)(`div`,{className:`mc-tags skill-detail-tags`,children:[(0,U.jsx)(`span`,{className:`mc-tag${e.enabled?` on`:``}`,children:`SKILL.md`}),(0,U.jsxs)(`span`,{className:`mc-tag`,children:[`MultiChat `,e.enabled?`已启用`:`已停用`]}),(e.resources||[]).map(e=>(0,U.jsx)(`span`,{className:`mc-tag`,children:e},e)),e.invalid&&(0,U.jsx)(`span`,{className:`mc-tag danger`,children:`格式无效`})]}),(0,U.jsxs)(`div`,{className:`skill-detail-actions`,children:[[`repo`,`plugin`].includes(e.source?.kind)&&(0,U.jsxs)(`button`,{className:`mc-act wide`,type:`button`,onClick:()=>void c(e),children:[(0,U.jsx)(o,{size:14,"aria-hidden":!0}),` 查看 Git 变更`]}),u&&(0,U.jsxs)(`button`,{className:`mc-act wide`,type:`button`,onClick:()=>a(e),children:[(0,U.jsx)(V,{size:14,"aria-hidden":!0}),` 编辑`]}),u&&(0,U.jsxs)(`button`,{className:`mc-act wide danger`,type:`button`,onClick:async()=>{await l(e)&&p(e=>e.filter(e=>(e.key||e.id)!==s))},children:[(0,U.jsx)(v,{size:14,"aria-hidden":!0}),` 删除`]}),!u&&![`repo`,`plugin`].includes(e.source?.kind)&&(0,U.jsx)(`span`,{className:`skill-readonly-note`,children:`只读来源 · 启停可用,编辑请在原目录进行`})]})]})]},s)}),!w.length&&(0,U.jsx)(`div`,{className:`extension-empty`,children:`没有符合筛选条件的 Skill。`})]})]})}function Pe({initialTools:t,onToggle:n,agents:r=[],onTest:i}){let[a,o]=(0,H.useState)(t),[s,c]=(0,H.useState)(``),[l,u]=(0,H.useState)({}),d=async(e,t)=>{c(e.id);try{let n=await i(e,t),r=n.ok?`✓ ${e.type===`calculator`?t+` = `:``}${typeof n.data==`string`?n.data:JSON.stringify(n.data)}(${n.elapsedMs}ms)`:`✗ ${n.error}`;u(t=>({...t,[e.id]:r}))}catch(t){u(n=>({...n,[e.id]:`✗ ${t.message}`}))}finally{c(``)}},f=async e=>{if(e.type===`calculator`){let t=await showPrompt({title:`试跑 · ${e.name}`,label:`数学表达式`,placeholder:`例如 (2 + 3) * 14 / 5`,maxLength:200});if(t==null||!t.trim())return;await d(e,t.trim())}else await d(e)},p=e=>r.filter(t=>(t.toolIds||[]).includes(e.id)).length,m=[...new Set(a.map(e=>e.type||`function`))],h=a.map(t=>{let r=[`datetime`,`calculator`].includes(t.type),i=p(t),a=t.permissions||[];return{key:t.id,icon:(0,U.jsx)(e,{size:18,"aria-hidden":!0}),name:t.name,badges:[{label:t.type||`function`}],description:t.description||``,meta:t.id,haystack:a.join(` `),sourceKind:t.type||`function`,enabled:!!t.enabled,onToggle:async()=>{await n(t)&&o(e=>e.map(e=>e.id===t.id?{...e,enabled:!e.enabled}:e))},detail:(0,U.jsxs)(U.Fragment,{children:[(0,U.jsx)(j,{facts:[{label:`工具 ID`,value:t.id},{label:`类型`,value:t.type||`function`},{label:`权限`,value:a.join(`, `)||`无`},{label:`引用`,value:i?`${i} 个运行配置`:`未被引用`}]}),(0,U.jsx)(k,{tags:[...a.map(e=>({label:e})),{label:t.enabled?`已启用`:`已停用`,on:!!t.enabled},{label:i?`${i} 个运行配置引用`:`未被运行配置引用`,on:!!i,title:`引用该工具的运行配置数量`}]}),r&&(0,U.jsx)(ae,{note:`试跑会真实执行该工具,不会调用模型`,children:(0,U.jsx)(`button`,{className:`mc-act wide`,type:`button`,disabled:s===t.id,onClick:()=>void f(t),children:s===t.id?`试跑中…`:`试跑`})}),l[t.id]&&(0,U.jsx)(`div`,{className:`tool-test-result resource-detail-extra`,role:`status`,children:l[t.id]})]})}});return(0,U.jsx)(ee,{title:`内置工具`,lead:`这些是 MultiChat 自身实现的函数调用能力。停用后不会暴露给模型。`,ariaLabel:`内置工具`,countNoun:`个工具`,items:h,emptyText:`没有内置工具。`,searchPlaceholder:`搜索名称、说明或 ID`,tabs:[{value:``,label:`全部`},{value:`enabled`,label:`已启用`},{value:`disabled`,label:`已停用`}],sourceAriaLabel:`按类型筛选`,sourceDefaultLabel:`全部类型`,sourceOptions:m.map(e=>({value:e,label:e}))})}function W(e){let t=Number(e||0);return t>=1e9?`${(t/1e9).toFixed(t>=1e10?0:1)}B`:t>=1e6?`${(t/1e6).toFixed(t>=1e7?0:1)}M`:t>=1e3?`${(t/1e3).toFixed(t>=1e4?0:1)}K`:t.toLocaleString(`zh-CN`)}function Fe(e){let t=f(e=>e.projects),n=f(e=>e.agents),r=f(e=>e.providers),i=f(e=>e.assets),a=f(e=>e.memories),o=f(e=>e.snapshots),c=f(e=>e.selectedProject),l=(0,H.useRef)(null),[u,d]=(0,H.useState)(c?.defaultAgentId||``),[p,m]=(0,H.useState)(c?.defaultProviderId&&c?.defaultModel?`${c.defaultProviderId}:${c.defaultModel}`:``),[h,g]=(0,H.useState)(``),[_,y]=(0,H.useState)(!1),[b,x]=(0,H.useState)(!1),[S,C]=(0,H.useState)(``),[w,T]=(0,H.useState)([]);(0,H.useEffect)(()=>{d(c?.defaultAgentId||``),m(c?.defaultProviderId&&c?.defaultModel?`${c.defaultProviderId}:${c.defaultModel}`:``),T([]),x(!1),C(``)},[c?.id,c?.defaultAgentId,c?.defaultProviderId,c?.defaultModel]);let E=r.flatMap(e=>(e.models||[]).map(t=>({value:`${e.id}:${t}`,label:`${e.name||e.id} · ${t}`}))),D=async t=>{if(t.preventDefault(),h.trim()&&c){y(!0),C(``);try{T(await e.onSearch(h.trim()))}catch(e){T([]),C(e.message)}finally{y(!1),x(!0)}}},k=async()=>{let[t,...n]=p.split(`:`);await e.onSaveDefaults(u||null,t||null,n.join(`:`)||null)};return(0,U.jsxs)(U.Fragment,{children:[(0,U.jsx)(`h3`,{children:`项目与文件`}),(0,U.jsx)(`p`,{className:`lead`,children:`一个项目对应一个代码文件夹及其对话上下文;内部存储空间由 MultiChat 自动管理。`}),(0,U.jsxs)(`section`,{className:`provider-card`,children:[(0,U.jsxs)(`div`,{className:`control-card-head`,children:[(0,U.jsxs)(`div`,{children:[(0,U.jsx)(`h4`,{children:`当前项目`}),(0,U.jsx)(`div`,{className:`pmeta`,children:`切换项目时会自动载入对应的文件、记忆和默认模型。`})]}),(0,U.jsxs)(`button`,{className:`btn-primary compact-action`,type:`button`,onClick:()=>void e.onImportFolder(),children:[(0,U.jsx)(O,{size:15,"aria-hidden":!0}),` 打开项目文件夹`]})]}),(0,U.jsxs)(`div`,{className:`field`,children:[(0,U.jsx)(`label`,{htmlFor:`projectSelectReact`,children:`已打开的项目`}),(0,U.jsx)(`select`,{id:`projectSelectReact`,value:c?.id||``,onChange:t=>void e.onProjectChange(t.target.value),children:t.map(e=>(0,U.jsx)(`option`,{value:e.id,children:e.name===`收件箱`?`无项目(临时对话)`:e.name},e.id))})]}),(0,U.jsxs)(`div`,{className:`field`,children:[(0,U.jsx)(`label`,{htmlFor:`projectAgentReact`,children:`项目默认运行配置`}),(0,U.jsxs)(`select`,{id:`projectAgentReact`,value:u,onChange:e=>d(e.target.value),children:[(0,U.jsx)(`option`,{value:``,children:`(继承全局)`}),n.map(e=>(0,U.jsx)(`option`,{value:e.id,children:e.name},e.id))]})]}),(0,U.jsxs)(`div`,{className:`field`,children:[(0,U.jsx)(`label`,{htmlFor:`projectModelReact`,children:`项目默认模型`}),(0,U.jsxs)(`select`,{id:`projectModelReact`,value:p,onChange:e=>m(e.target.value),children:[(0,U.jsx)(`option`,{value:``,children:`(继承全局)`}),E.map(e=>(0,U.jsx)(`option`,{value:e.value,children:e.label},e.value))]})]}),(0,U.jsx)(`div`,{className:`provider-row`,children:(0,U.jsx)(`button`,{className:`btn-primary compact-action`,type:`button`,onClick:()=>void k(),children:`保存项目默认`})}),(0,U.jsx)(`div`,{className:`provider-row`,children:(0,U.jsx)(`button`,{className:`btn-ghost`,type:`button`,onClick:e.onNewProject,children:`新建空项目`})})]}),(0,U.jsxs)(`section`,{className:`provider-card`,children:[(0,U.jsx)(`h4`,{children:`项目文件`}),(0,U.jsx)(`div`,{className:`pmeta`,children:`支持本地文本文件和 URL 文本资源;对话时会按相关性截取并附带文件/行号来源。`}),(0,U.jsxs)(`div`,{className:`provider-row workspace-file-actions`,children:[(0,U.jsxs)(`button`,{className:`btn-ghost`,type:`button`,onClick:()=>l.current?.click(),children:[(0,U.jsx)(O,{size:15,"aria-hidden":!0}),` 上传本地文件`]}),(0,U.jsx)(`button`,{className:`btn-ghost`,type:`button`,onClick:e.onImportUrl,children:`从 URL 添加`}),(0,U.jsx)(`input`,{ref:l,type:`file`,accept:`.txt,.md,.json,.csv,.js,.ts,.py,.html,.css,.yaml,.yml`,hidden:!0,onChange:t=>{let n=t.target.files?.[0];n&&e.onUploadFile(n),t.target.value=``}})]}),(0,U.jsxs)(`div`,{className:`run-list workspace-resource-list`,children:[i.map(t=>(0,U.jsxs)(`div`,{className:`run-row`,children:[(0,U.jsx)(`span`,{className:`run-dot completed`}),(0,U.jsxs)(`div`,{className:`run-main`,children:[(0,U.jsx)(`div`,{className:`run-title`,children:t.name}),(0,U.jsxs)(`div`,{className:`run-meta`,children:[t.mimeType,` · `,t.size,` bytes · `,t.source]})]}),(0,U.jsx)(`button`,{className:`mc-act danger`,type:`button`,title:`删除`,"aria-label":`删除文件 ${t.name}`,onClick:()=>void e.onDeleteAsset(t.id),children:(0,U.jsx)(v,{size:15,"aria-hidden":!0})})]},t.id)),!i.length&&(0,U.jsx)(`div`,{className:`control-empty`,children:`当前项目还没有文件。`})]}),(0,U.jsxs)(`form`,{className:`knowledge-search`,onSubmit:D,children:[(0,U.jsxs)(`label`,{className:`resource-search`,children:[(0,U.jsx)(s,{size:15,"aria-hidden":!0}),(0,U.jsx)(`input`,{"aria-label":`搜索项目知识`,value:h,onChange:e=>g(e.target.value),placeholder:`搜索项目知识,例如:认证流程在哪里实现?`})]}),(0,U.jsx)(`button`,{className:`btn-ghost`,disabled:_,children:_?`检索中…`:`搜索知识`})]}),(0,U.jsxs)(`div`,{className:`knowledge-results`,"aria-live":`polite`,children:[S&&(0,U.jsx)(`div`,{className:`auth-error`,children:S}),w.map((e,t)=>(0,U.jsxs)(`article`,{className:`knowledge-hit`,children:[(0,U.jsxs)(`strong`,{children:[e.name,` `,(0,U.jsxs)(`span`,{children:[`L`,e.lineStart,`–L`,e.lineEnd]})]}),(0,U.jsx)(`p`,{children:String(e.snippet||``).slice(0,500)})]},`${e.id||e.name}-${t}`)),b&&!_&&!S&&w.length===0&&(0,U.jsx)(`div`,{className:`control-empty`,children:`没有找到相关片段。`})]})]}),(0,U.jsxs)(`section`,{className:`provider-card`,children:[(0,U.jsxs)(`div`,{className:`control-card-head`,children:[(0,U.jsxs)(`div`,{children:[(0,U.jsx)(`h4`,{children:`项目记忆`}),(0,U.jsx)(`div`,{className:`pmeta`,children:`由你明确维护的事实和偏好;可逐条停用,不会从聊天中偷偷学习。`})]}),(0,U.jsx)(`button`,{className:`btn-ghost`,type:`button`,onClick:e.onAddMemory,children:`新增记忆`})]}),(0,U.jsxs)(`div`,{className:`memory-list`,children:[a.map(t=>(0,U.jsxs)(`article`,{className:`memory-item${t.enabled===!1?` disabled`:``}`,children:[(0,U.jsxs)(`button`,{className:`memory-toggle`,type:`button`,"aria-pressed":t.enabled!==!1,onClick:()=>void e.onToggleMemory(t),children:[(0,U.jsx)(`i`,{}),t.enabled===!1?`已停用`:`已启用`]}),(0,U.jsxs)(`div`,{children:[(0,U.jsx)(`strong`,{children:t.title}),(0,U.jsx)(`p`,{children:t.content})]}),(0,U.jsxs)(`div`,{className:`memory-actions`,children:[(0,U.jsx)(`button`,{className:`mc-act`,type:`button`,onClick:()=>e.onEditMemory(t.id),children:`编辑`}),(0,U.jsx)(`button`,{className:`mc-act danger`,type:`button`,onClick:()=>void e.onDeleteMemory(t.id),children:`删除`})]})]},t.id)),!a.length&&(0,U.jsx)(`div`,{className:`control-empty`,children:`还没有项目记忆。只保存值得长期复用的事实和偏好。`})]})]}),(0,U.jsxs)(`section`,{className:`provider-card`,children:[(0,U.jsxs)(`div`,{className:`control-card-head`,children:[(0,U.jsxs)(`div`,{children:[(0,U.jsx)(`h4`,{children:`项目时光机`}),(0,U.jsx)(`div`,{className:`pmeta`,children:`保存项目设置、知识文件、记忆、默认运行配置和当前 Git 状态;恢复前会自动再备份一次。`})]}),(0,U.jsx)(`button`,{className:`btn-primary compact-action`,type:`button`,onClick:()=>void e.onCreateSnapshot(),children:`创建快照`})]}),(0,U.jsxs)(`div`,{className:`snapshot-list`,children:[o.map(t=>(0,U.jsxs)(`article`,{className:`snapshot-item`,children:[(0,U.jsx)(`span`,{className:`snapshot-mark`,children:t.git?.commit||`LOCAL`}),(0,U.jsxs)(`div`,{children:[(0,U.jsx)(`strong`,{children:t.title}),(0,U.jsxs)(`p`,{children:[new Date(t.createdAt).toLocaleString(`zh-CN`),` · `,t.assets,` 文件 · `,t.memories,` 记忆 ·`,` `,W(t.size),`B`,t.git?.branch?` · ${t.git.branch}${t.git.dirty?`(有改动)`:``}`:``]})]}),(0,U.jsxs)(`div`,{className:`memory-actions`,children:[(0,U.jsx)(`button`,{className:`mc-act`,type:`button`,onClick:()=>void e.onRestoreSnapshot(t.id),children:`恢复`}),(0,U.jsx)(`button`,{className:`mc-act danger`,type:`button`,onClick:()=>void e.onDeleteSnapshot(t.id),children:`删除`})]})]},t.id)),!o.length&&(0,U.jsx)(`div`,{className:`control-empty`,children:`尚未创建项目快照。`})]})]})]})}function Ie({onEdit:e,onExport:t,onDelete:n,onImport:i}){let o=f(e=>e.agents),s=f(e=>e.selectedAgent),c=(0,H.useRef)(null),l=o.map(r=>{let i=r.skillRefs||r.skillIds||[],o=r.toolIds||[],c=r.mcpServerIds||[],l=s?.id===r.id;return{key:r.id,icon:(0,U.jsx)(a,{size:18,"aria-hidden":!0}),name:r.name,badges:l?[{label:`当前使用`}]:[],description:r.description||`尚未添加说明,可编辑智能体补充职责与适用任务。`,meta:r.id,haystack:[r.id,...i,...o,...c].filter(Boolean).join(` `),statusValue:l?`current`:`available`,detail:(0,U.jsxs)(U.Fragment,{children:[(0,U.jsx)(j,{facts:[{label:`智能体 ID`,value:r.id},{label:`状态`,value:l?`当前使用`:`可用`},{label:`技能`,value:`${i.length} Skills`},{label:`工具`,value:`${o.length} 工具 / ${c.length} MCP`}]}),(0,U.jsxs)(`div`,{className:`agent-capability-summary resource-detail-extra`,children:[(0,U.jsxs)(`span`,{children:[(0,U.jsx)(`strong`,{children:i.length}),` Skills`]}),(0,U.jsxs)(`span`,{children:[(0,U.jsx)(`strong`,{children:o.length}),` 工具`]}),(0,U.jsxs)(`span`,{children:[(0,U.jsx)(`strong`,{children:c.length}),` MCP`]})]}),(0,U.jsx)(k,{tags:[...i.slice(0,3).map(e=>({label:e})),...i.length>3?[{label:`+${i.length-3}`}]:[],...i.length?[]:[{label:`尚未绑定 Skill`}],...l?[{label:`当前使用`,on:!0}]:[]]}),(0,U.jsxs)(ae,{note:`只有当前智能体选中的能力会进入运行`,children:[(0,U.jsxs)(`button`,{className:`mc-act wide`,type:`button`,"aria-label":`编辑 ${r.name}`,onClick:()=>e(r.id),children:[(0,U.jsx)(ke,{size:14,"aria-hidden":!0}),` 编辑`]}),(0,U.jsxs)(`button`,{className:`mc-act wide`,type:`button`,"aria-label":`导出 ${r.name}`,onClick:()=>t(r),children:[(0,U.jsx)(B,{size:14,"aria-hidden":!0}),` 导出`]}),(0,U.jsxs)(`button`,{className:`mc-act wide danger`,type:`button`,"aria-label":`删除 ${r.name}`,onClick:()=>void n(r),children:[(0,U.jsx)(v,{size:14,"aria-hidden":!0}),` 删除`]})]})]})}});return(0,U.jsx)(ee,{title:`智能体工作室`,lead:`把系统提示词、Skills、内置工具和 MCP 服务组合成可复用的 AI 角色。只有当前智能体选中的能力才会进入运行。`,ariaLabel:`智能体工作室`,countNoun:`个智能体`,items:l,emptyText:(0,U.jsx)(U.Fragment,{children:`还没有智能体。创建一个角色,组合提示词、Skills 和工具。`}),searchPlaceholder:`搜索名称、说明、ID 或能力`,headingActions:(0,U.jsxs)(U.Fragment,{children:[(0,U.jsxs)(`button`,{className:`btn-ghost compact-action`,type:`button`,onClick:()=>c.current?.click(),children:[(0,U.jsx)(O,{size:15,"aria-hidden":!0}),` 导入智能体`]}),(0,U.jsxs)(`button`,{className:`btn-primary compact-action`,type:`button`,onClick:()=>e(null),children:[(0,U.jsx)(r,{size:15,"aria-hidden":!0}),` 新建智能体`]}),(0,U.jsx)(`input`,{ref:c,type:`file`,accept:`.json,application/json`,hidden:!0,onChange:e=>{let t=e.target.files?.[0];t&&i(t),e.target.value=``}})]}),tabs:[{value:``,label:`全部`},{value:`current`,label:`当前使用`},{value:`available`,label:`可用`}]})}var G={plugin:`插件`,skill:`Skill`,mcp:`MCP`,tool:`内置工具`},Le={high:`高风险`,medium:`中风险`,low:`低风险`};function Re({onRefresh:e}){let t=f(e=>e.capabilities),[n,r]=(0,H.useState)(``),[i,a]=(0,H.useState)(``),[o,c]=(0,H.useState)(``),u=(0,H.useMemo)(()=>(t?.items||[]).filter(e=>{let t=[e.name,e.id,e.source,e.scope,...e.permissions||[]].join(` `).toLowerCase();return(!n||t.includes(n.toLowerCase()))&&(!i||e.type===i)&&(!o||e.risk===o)}),[t,n,i,o]);return t?(0,U.jsxs)(`section`,{className:`passport-page`,children:[(0,U.jsxs)(`div`,{className:`settings-page-heading`,children:[(0,U.jsxs)(`div`,{children:[(0,U.jsx)(`div`,{className:`usage-kicker`,children:`能力治理`}),(0,U.jsx)(`h3`,{children:`能力审计`}),(0,U.jsx)(`p`,{className:`lead`,children:`统一查看每项能力的来源、版本、权限、信任边界和结构完整性。`})]}),(0,U.jsxs)(`button`,{className:`btn-ghost`,type:`button`,onClick:()=>void e(),children:[(0,U.jsx)(l,{size:15,"aria-hidden":!0}),` 重新扫描`]})]}),(0,U.jsxs)(`div`,{className:`passport-summary`,children:[(0,U.jsxs)(`span`,{children:[(0,U.jsx)(`strong`,{children:t.summary.total}),` 项能力`]}),(0,U.jsxs)(`span`,{children:[(0,U.jsx)(`strong`,{children:t.summary.enabled}),` 项启用`]}),(0,U.jsxs)(`span`,{className:t.summary.highRisk?`warn`:``,children:[(0,U.jsx)(`strong`,{children:t.summary.highRisk}),` 项高风险`]}),(0,U.jsxs)(`span`,{className:t.summary.issues?`warn`:``,children:[(0,U.jsx)(`strong`,{children:t.summary.issues}),` 个待处理问题`]})]}),(0,U.jsxs)(`div`,{className:`resource-toolbar passport-toolbar`,children:[(0,U.jsxs)(`label`,{className:`resource-search`,children:[(0,U.jsx)(s,{size:15,"aria-hidden":!0}),(0,U.jsx)(`input`,{type:`search`,"aria-label":`搜索能力`,placeholder:`搜索能力、来源或权限`,value:n,onChange:e=>r(e.target.value)})]}),(0,U.jsxs)(`select`,{"aria-label":`按类型筛选`,value:i,onChange:e=>a(e.target.value),children:[(0,U.jsx)(`option`,{value:``,children:`全部类型`}),Object.entries(G).map(([e,t])=>(0,U.jsx)(`option`,{value:e,children:t},e))]}),(0,U.jsxs)(`select`,{"aria-label":`按风险筛选`,value:o,onChange:e=>c(e.target.value),children:[(0,U.jsx)(`option`,{value:``,children:`全部风险`}),(0,U.jsx)(`option`,{value:`high`,children:`高风险`}),(0,U.jsx)(`option`,{value:`medium`,children:`中风险`}),(0,U.jsx)(`option`,{value:`low`,children:`低风险`})]}),(0,U.jsxs)(`span`,{className:`resource-count`,children:[u.length,` / `,t.items.length,` 项`]})]}),(0,U.jsx)(`div`,{className:`passport-grid`,children:u.map(e=>(0,U.jsxs)(`article`,{className:`passport-card`,children:[(0,U.jsxs)(`div`,{className:`passport-head`,children:[(0,U.jsx)(`span`,{className:`passport-type ${e.type}`,children:G[e.type]||e.type}),(0,U.jsx)(`span`,{className:`passport-risk ${e.risk}`,children:Le[e.risk]||e.risk})]}),(0,U.jsx)(`h4`,{children:e.name}),(0,U.jsx)(`code`,{children:e.id}),(0,U.jsx)(`p`,{children:e.description||`暂无说明`}),(0,U.jsxs)(`dl`,{children:[(0,U.jsxs)(`div`,{children:[(0,U.jsx)(`dt`,{children:`来源`}),(0,U.jsxs)(`dd`,{children:[e.source,` · `,e.scope||`project`]})]}),(0,U.jsxs)(`div`,{children:[(0,U.jsx)(`dt`,{children:`版本 / 完整性`}),(0,U.jsxs)(`dd`,{children:[e.version||`未声明`,` · `,e.integrity||`unknown`]})]}),(0,U.jsxs)(`div`,{children:[(0,U.jsx)(`dt`,{children:`信任`}),(0,U.jsx)(`dd`,{children:e.trust||`unknown`})]})]}),(0,U.jsxs)(`div`,{className:`passport-perms`,children:[(e.permissions||[]).map(e=>(0,U.jsx)(`span`,{children:e},e)),!e.permissions?.length&&(0,U.jsx)(`span`,{className:`none`,children:`无特殊权限`})]}),e.issues?.length?(0,U.jsx)(`div`,{className:`passport-issues`,children:e.issues.map(e=>(0,U.jsx)(`span`,{children:e},e))}):(0,U.jsx)(`div`,{className:`passport-clean`,children:`结构检查通过`})]},`${e.type}:${e.id}`))}),!u.length&&(0,U.jsx)(`div`,{className:`extension-empty`,children:`没有符合筛选条件的能力。`})]}):(0,U.jsxs)(U.Fragment,{children:[(0,U.jsx)(`h3`,{children:`能力审计`}),(0,U.jsx)(`p`,{className:`lead`,children:`正在生成能力护照…`}),(0,U.jsx)(`div`,{className:`usage-loading`,role:`status`,"aria-label":`正在加载`})]})}var K=[`#6158e8`,`#16aabd`,`#9b77f2`,`#ef9f52`,`#46a575`,`#d65f7a`];function ze({rows:e=[]}){let t=Math.max(1,...e.map(e=>Number(e.totalTokens||0))),n=710/Math.max(1,e.length),r=e.map((e,r)=>`${38+r*n+n/2},${196-178*Number(e.totalTokens||0)/t}`).join(` `);return(0,U.jsxs)(`svg`,{className:`usage-trend`,viewBox:`0 0 760 226`,role:`img`,"aria-label":`每日 Token 用量趋势`,children:[(0,U.jsx)(`g`,{className:`usage-grid`,children:[0,.5,1].map(e=>(0,U.jsxs)(`g`,{children:[(0,U.jsx)(`line`,{x1:38,x2:748,y1:18+178*(1-e),y2:18+178*(1-e)}),(0,U.jsx)(`text`,{x:`0`,y:18+178*(1-e)+4,children:W(t*e)})]},e))}),e.map((e,r)=>{let i=38+r*n+Math.max(1,n*.16),a=Math.max(2,n*.68),o=178*Number(e.inputTokens||0)/t,s=178*Number(e.outputTokens||0)/t;return(0,U.jsxs)(`g`,{children:[(0,U.jsxs)(`title`,{children:[e.date,` · `,W(e.totalTokens),` tokens`]}),(0,U.jsx)(`rect`,{className:`usage-bar-input`,x:i,y:196-o,width:a,height:o,rx:`2`}),(0,U.jsx)(`rect`,{className:`usage-bar-output`,x:i,y:196-o-s,width:a,height:s,rx:`2`})]},e.date)}),r&&(0,U.jsx)(`polyline`,{className:`usage-line`,points:r}),(0,U.jsx)(`text`,{className:`usage-date`,x:38,y:221,children:e[0]?.date?.slice(5)||``}),(0,U.jsx)(`text`,{className:`usage-date`,x:748,y:221,textAnchor:`end`,children:e[e.length-1]?.date?.slice(5)||``})]})}function Be({onRange:e,onExport:t}){let n=f(e=>e.usage),r=f(e=>e.usageLoading),i=f(e=>e.usageRange);if(r&&!n)return(0,U.jsxs)(U.Fragment,{children:[(0,U.jsx)(`h3`,{children:`用量中心`}),(0,U.jsx)(`p`,{className:`lead`,children:`正在汇总本地运行记录…`}),(0,U.jsx)(`div`,{className:`usage-loading`,role:`status`,"aria-label":`正在加载`})]});let a=n?.totals||{},o=n?.daily||[],s=o[o.length-1]||{},c=n?.models||[],l=n?.providers||[],u=0,d=c.slice(0,6).map((e,t)=>{let n=u;return u+=Number(e.share||0)*360,`${K[t%K.length]} ${n}deg ${u}deg`}).join(`,`);return(0,U.jsxs)(`section`,{className:`usage-page`,children:[(0,U.jsxs)(`div`,{className:`settings-page-heading usage-heading`,children:[(0,U.jsxs)(`div`,{children:[(0,U.jsx)(`div`,{className:`usage-kicker`,children:`本地用量统计`}),(0,U.jsx)(`h3`,{children:`每日 Token 用量`}),(0,U.jsx)(`p`,{className:`lead`,children:`按本机请求汇总;上游未返回 usage 时会明确标记为估算,不读取任何提示词正文。`})]}),(0,U.jsxs)(`div`,{className:`usage-heading-actions`,children:[(0,U.jsx)(`div`,{className:`usage-ranges`,children:[[`7`,`近 7 天`],[`30`,`近 30 天`],[`all`,`全部`]].map(([t,n])=>(0,U.jsx)(`button`,{className:`usage-range${i===t?` active`:``}`,type:`button`,onClick:()=>void e(t),children:n},t))}),(0,U.jsxs)(`button`,{className:`btn-ghost`,type:`button`,onClick:()=>t(n,i),children:[(0,U.jsx)(B,{size:15,"aria-hidden":!0}),` 导出 CSV`]})]})]}),(0,U.jsxs)(`div`,{className:`usage-metrics`,children:[(0,U.jsxs)(`article`,{className:`usage-metric primary`,children:[(0,U.jsx)(`span`,{children:`Token 总量`}),(0,U.jsx)(`strong`,{children:W(a.totalTokens)}),(0,U.jsxs)(`small`,{children:[`输入 `,W(a.inputTokens),` · 输出 `,W(a.outputTokens)]})]}),(0,U.jsxs)(`article`,{className:`usage-metric`,children:[(0,U.jsx)(`span`,{children:`今日用量`}),(0,U.jsx)(`strong`,{children:W(s.totalTokens)}),(0,U.jsxs)(`small`,{children:[s.requests||0,` 次模型请求`]})]}),(0,U.jsxs)(`article`,{className:`usage-metric`,children:[(0,U.jsx)(`span`,{children:`有效交互`}),(0,U.jsx)(`strong`,{children:W(a.messages)}),(0,U.jsxs)(`small`,{children:[a.requests||0,` 次模型调用`]})]}),(0,U.jsxs)(`article`,{className:`usage-metric`,children:[(0,U.jsx)(`span`,{children:`活跃天数`}),(0,U.jsx)(`strong`,{children:a.activeDays||0}),(0,U.jsxs)(`small`,{children:[`连续 `,a.currentStreak||0,` 天 · 最长 `,a.longestStreak||0,` 天`]})]})]}),(0,U.jsxs)(`div`,{className:`usage-insights`,children:[(0,U.jsxs)(`span`,{children:[(0,U.jsx)(`i`,{className:`success`}),`成功率 `,(0,U.jsxs)(`strong`,{children:[((a.successRate??1)*100).toFixed(1),`%`]})]}),(0,U.jsxs)(`span`,{children:[`日均 `,(0,U.jsx)(`strong`,{children:W(a.averagePerActiveDay)})]}),(0,U.jsxs)(`span`,{children:[`峰值时段`,` `,(0,U.jsxs)(`strong`,{children:[String(a.peakHour||0).padStart(2,`0`),`:00–`,String(((a.peakHour||0)+1)%24).padStart(2,`0`),`:00`]})]}),(0,U.jsxs)(`span`,{children:[`真实上报 `,(0,U.jsxs)(`strong`,{children:[((a.reportedShare||0)*100).toFixed(0),`%`]})]}),a.estimatedTokens?(0,U.jsxs)(`span`,{className:`estimate-note`,children:[`约 `,W(a.estimatedTokens),` Token 为本地估算`]}):null]}),(0,U.jsxs)(`div`,{className:`usage-layout`,children:[(0,U.jsxs)(`article`,{className:`usage-panel usage-wide`,children:[(0,U.jsxs)(`div`,{className:`usage-panel-head`,children:[(0,U.jsxs)(`div`,{children:[(0,U.jsx)(`h4`,{children:`按天趋势`}),(0,U.jsx)(`p`,{children:`深色为输入,浅色为输出;悬停柱形查看当天明细。`})]}),(0,U.jsxs)(`div`,{className:`usage-legend`,children:[(0,U.jsx)(`span`,{className:`input`}),`输入 `,(0,U.jsx)(`span`,{className:`output`}),`输出`]})]}),(0,U.jsx)(ze,{rows:o})]}),(0,U.jsxs)(`article`,{className:`usage-panel`,children:[(0,U.jsx)(`div`,{className:`usage-panel-head`,children:(0,U.jsxs)(`div`,{children:[(0,U.jsx)(`h4`,{children:`模型用量`}),(0,U.jsx)(`p`,{children:`选定周期内的 Token 占比`})]})}),(0,U.jsxs)(`div`,{className:`usage-model-wrap`,children:[(0,U.jsx)(`div`,{className:`usage-donut`,style:{background:`conic-gradient(${d||`var(--mc-line) 0 360deg`})`},children:(0,U.jsxs)(`div`,{children:[(0,U.jsx)(`strong`,{children:c.length}),(0,U.jsx)(`span`,{children:`模型`})]})}),(0,U.jsxs)(`div`,{className:`usage-model-list`,children:[c.slice(0,6).map((e,t)=>(0,U.jsxs)(`div`,{children:[(0,U.jsx)(`i`,{style:{background:K[t%K.length]}}),(0,U.jsx)(`span`,{title:e.name,children:e.name}),(0,U.jsxs)(`strong`,{children:[(Number(e.share||0)*100).toFixed(1),`%`]}),(0,U.jsx)(`small`,{children:W(e.totalTokens)})]},e.name)),!c.length&&(0,U.jsx)(`p`,{className:`usage-empty`,children:`还没有用量记录`})]})]})]}),(0,U.jsxs)(`article`,{className:`usage-panel usage-wide`,children:[(0,U.jsxs)(`div`,{className:`usage-panel-head`,children:[(0,U.jsxs)(`div`,{children:[(0,U.jsx)(`h4`,{children:`活跃热力图`}),(0,U.jsx)(`p`,{children:`最近 26 周的本地模型调用`})]}),(0,U.jsxs)(`span`,{children:[n?.heatmap?.filter(e=>e.totalTokens>0).length||0,` 个活跃日`]})]}),(0,U.jsx)(`div`,{className:`usage-heatmap`,role:`img`,"aria-label":`最近 26 周活跃情况`,children:(n?.heatmap||[]).map(e=>{let t=e.totalTokens===0?0:e.totalTokens<1e3?1:e.totalTokens<1e4?2:e.totalTokens<1e5?3:4;return(0,U.jsx)(`i`,{"data-level":t,children:(0,U.jsxs)(`span`,{children:[e.date,` · `,W(e.totalTokens),` tokens`]})},e.date)})})]}),(0,U.jsxs)(`article`,{className:`usage-panel`,children:[(0,U.jsx)(`div`,{className:`usage-panel-head`,children:(0,U.jsxs)(`div`,{children:[(0,U.jsx)(`h4`,{children:`提供方健康`}),(0,U.jsx)(`p`,{children:`请求、用量与错误率`})]})}),(0,U.jsxs)(`div`,{className:`usage-provider-list`,children:[l.map(e=>(0,U.jsxs)(`div`,{children:[(0,U.jsxs)(`span`,{children:[(0,U.jsx)(`i`,{}),e.name]}),(0,U.jsx)(`strong`,{children:W(e.totalTokens)}),(0,U.jsxs)(`small`,{children:[e.requests,` 次 ·`,` `,e.requests?(e.errors/e.requests*100).toFixed(0):0,`% 错误`]})]},e.id||e.name)),!l.length&&(0,U.jsx)(`p`,{className:`usage-empty`,children:`还没有提供方记录`})]})]})]})]})}function Ve({onRefresh:e,onOpen:t}){let n=f(e=>e.runs||[]),r=n.filter(e=>e.status===`completed`).length,i=n.reduce((e,t)=>e+Number(t.usage?.totalTokens||0),0),a=e=>e===`completed`?`已完成`:e===`error`?`失败`:e===`cancelled`?`已取消`:`进行中`;return(0,U.jsxs)(U.Fragment,{children:[(0,U.jsxs)(`div`,{className:`settings-page-heading`,children:[(0,U.jsxs)(`div`,{children:[(0,U.jsx)(`div`,{className:`usage-kicker`,children:`运行记录`}),(0,U.jsx)(`h3`,{children:`执行与复盘`}),(0,U.jsx)(`p`,{className:`lead`,children:`复盘模型请求、工具权限、上下文来源、耗时与 Token;点击记录查看完整上下文。`})]}),(0,U.jsxs)(`div`,{className:`heading-actions-row`,children:[(0,U.jsx)(`button`,{className:`btn-ghost`,type:`button`,onClick:()=>{let e=document.createElement(`a`);e.href=`/api/runs/export`,e.download=``,e.click()},children:`导出审计包`}),(0,U.jsxs)(`button`,{className:`btn-ghost`,type:`button`,onClick:()=>void e(),children:[(0,U.jsx)(l,{size:15,"aria-hidden":!0}),` 刷新`]})]})]}),(0,U.jsxs)(`div`,{className:`passport-summary`,children:[(0,U.jsxs)(`span`,{children:[(0,U.jsx)(`strong`,{children:n.length}),` 条记录`]}),(0,U.jsxs)(`span`,{children:[(0,U.jsx)(`strong`,{children:r}),` 次完成`]}),(0,U.jsxs)(`span`,{children:[(0,U.jsx)(`strong`,{children:W(i)}),` tokens`]}),(0,U.jsxs)(`span`,{className:n.length-r?`warn`:``,children:[(0,U.jsx)(`strong`,{children:n.length-r}),` 次未完成`]})]}),(0,U.jsxs)(`div`,{className:`run-list`,children:[n.map(e=>(0,U.jsxs)(`button`,{className:`run-row run-row-button`,type:`button`,onClick:()=>t(e.id),children:[(0,U.jsx)(`span`,{className:`run-dot ${e.status||``}`}),(0,U.jsxs)(`div`,{className:`run-main`,children:[(0,U.jsxs)(`div`,{className:`run-title`,children:[e.agentName||e.agentId||`智能体运行`,` `,(0,U.jsx)(`span`,{children:e.provider?.name||``})]}),(0,U.jsxs)(`div`,{className:`run-meta`,children:[e.model||`未指定模型`,` · `,e.steps||0,` 步 · `,e.toolCalls||0,` 次工具 ·`,` `,W(e.usage?.totalTokens||0),` tokens ·`,` `,e.finishedAt?`${((Date.parse(e.finishedAt)-Date.parse(e.startedAt))/1e3).toFixed(1)}s`:`运行中`]})]}),(0,U.jsx)(`span`,{className:`run-status`,children:a(e.status)}),(0,U.jsx)(`span`,{className:`run-open`,children:`›`})]},e.id)),!n.length&&(0,U.jsx)(`div`,{className:`control-empty`,children:`还没有 Agent 运行记录。`})]})]})}var q=`multichat_compare_history_v1`;function J(){try{let e=JSON.parse(localStorage.getItem(q)||`[]`);return Array.isArray(e)?e.filter(e=>e&&typeof e.id==`string`&&typeof e.prompt==`string`&&Array.isArray(e.results)).map(e=>({id:e.id,prompt:e.prompt,createdAt:typeof e.createdAt==`string`?e.createdAt:``,projectName:typeof e.projectName==`string`?e.projectName:`未选择项目`,results:e.results.filter(e=>e&&typeof e.model==`string`&&typeof e.providerId==`string`)})).slice(0,12):[]}catch{return[]}}function He(e,t,n){let r=[{id:`experiment_${Date.now().toString(36)}`,prompt:e,createdAt:new Date().toISOString(),projectName:t,results:n},...J()].slice(0,12);try{localStorage.setItem(q,JSON.stringify(r))}catch{d(`实验已完成,但本地历史无法保存`,`error`)}return r}function Ue({result:e,prompt:t,adopt:n}){let r=e.usage?.total_tokens??e.usage?.total??0,i=e.status===`running`?`运行中`:e.status===`error`?`失败`:e.status===`cancelled`?`已停止`:e.status===`success`?`完成`:`等待`;return(0,U.jsxs)(`article`,{className:`compare-result`,"data-state":e.status,children:[(0,U.jsxs)(`header`,{children:[(0,U.jsxs)(`div`,{children:[(0,U.jsx)(`strong`,{children:e.model}),(0,U.jsx)(`span`,{children:e.providerName})]}),(0,U.jsx)(`span`,{className:`compare-state`,children:i})]}),(0,U.jsxs)(`div`,{className:`compare-result-body`,children:[e.status===`running`&&(0,U.jsxs)(`div`,{className:`compare-loading`,"aria-label":`模型正在运行`,children:[(0,U.jsx)(`span`,{}),(0,U.jsx)(`span`,{}),(0,U.jsx)(`span`,{})]}),e.status===`error`&&(0,U.jsx)(`div`,{className:`compare-error`,children:e.error||`请求失败`}),e.status===`cancelled`&&(0,U.jsx)(`div`,{className:`compare-cancelled`,children:`本次模型请求已停止。`}),e.status===`success`&&(0,U.jsx)(`div`,{className:`compare-answer`,children:(0,U.jsx)(x,{children:e.text||``})}),e.status===`idle`&&(0,U.jsx)(`div`,{className:`compare-empty`,children:`等待开始`})]}),e.status===`success`&&(0,U.jsxs)(`footer`,{children:[(0,U.jsxs)(`span`,{children:[((e.elapsedMs||0)/1e3).toFixed(1),` 秒`]}),(0,U.jsxs)(`span`,{children:[Number(r).toLocaleString(`zh-CN`),` Token`]}),(0,U.jsxs)(`div`,{children:[(0,U.jsx)(`button`,{type:`button`,onClick:async()=>{try{await navigator.clipboard.writeText(e.text||``),d(`结果已复制`)}catch{d(`复制失败`,`error`)}},children:`复制`}),(0,U.jsx)(`button`,{type:`button`,className:`compare-adopt`,onClick:()=>void n(e,t),children:`采用到对话`})]})]})]})}function We({results:e}){let t=e.filter(e=>e.status===`success`);if(!t.length)return null;let n=[...t].sort((e,t)=>Number(e.elapsedMs||1/0)-Number(t.elapsedMs||1/0))[0],r=[...t.filter(e=>Number(e.usage?.total_tokens??e.usage?.total??0)>0)].sort((e,t)=>Number(e.usage?.total_tokens??e.usage?.total)-Number(t.usage?.total_tokens??t.usage?.total))[0];return(0,U.jsxs)(`section`,{className:`compare-summary`,"aria-label":`实验摘要`,children:[(0,U.jsxs)(`header`,{children:[(0,U.jsxs)(`div`,{children:[(0,U.jsx)(`span`,{children:`实验摘要`}),(0,U.jsx)(`strong`,{children:`只比较可验证指标`})]}),(0,U.jsxs)(`small`,{children:[t.length,` / `,e.length,` 个模型完成`]})]}),(0,U.jsxs)(`dl`,{children:[(0,U.jsxs)(`div`,{children:[(0,U.jsx)(`dt`,{children:`最快响应`}),(0,U.jsxs)(`dd`,{children:[n.model,(0,U.jsxs)(`small`,{children:[((n.elapsedMs||0)/1e3).toFixed(1),` 秒`]})]})]}),(0,U.jsxs)(`div`,{children:[(0,U.jsx)(`dt`,{children:`最低消耗`}),(0,U.jsxs)(`dd`,{children:[r?.model||`暂无数据`,(0,U.jsx)(`small`,{children:r?`${Number(r.usage?.total_tokens??r.usage?.total).toLocaleString(`zh-CN`)} Token`:`上游未返回用量`})]})]}),(0,U.jsxs)(`div`,{children:[(0,U.jsx)(`dt`,{children:`上下文口径`}),(0,U.jsxs)(`dd`,{children:[`完全一致`,(0,U.jsx)(`small`,{children:`同一任务、参数和项目资料`})]})]})]})]})}function Ge({targets:e,defaultTargetIds:t,initialPrompt:n,projectName:r,fileCount:i,memoryCount:a,execute:o,adopt:s}){let[c,l]=(0,H.useState)(()=>new Set(t)),[u,f]=(0,H.useState)(n),[p,m]=(0,H.useState)([]),[h,g]=(0,H.useState)(J),[_,v]=(0,H.useState)(!1),y=(0,H.useRef)(null),b=(0,H.useMemo)(()=>e.filter(e=>c.has(e.id)),[e,c]);(0,H.useEffect)(()=>()=>y.current?.abort(),[]);let x=(e,t)=>{let n=new Set(c);if(t){if(n.size>=4){d(`一次最多实验 4 个模型`,`error`);return}n.add(e)}else n.delete(e);l(n)},S=async()=>{if(_){y.current?.abort();return}let e=u.trim();if(!e){d(`请输入实验任务`,`error`);return}if(b.length<2){d(`至少选择两个模型`,`error`);return}v(!0),m(b.map(e=>({...e,status:`running`})));let t=new AbortController;y.current=t;try{let n=await Promise.all(b.map(async n=>{let r=await o(n,e,t.signal);return m(e=>e.map(e=>e.id===n.id?r:e)),r}));n.some(e=>e.status===`success`)&&g(He(e,r,n))}finally{y.current===t&&(y.current=null),v(!1)}};return(0,U.jsxs)(`div`,{className:`compare-lab`,children:[(0,U.jsxs)(`div`,{className:`compare-intro`,children:[(0,U.jsx)(`div`,{children:(0,U.jsx)(`p`,{children:`同一任务、同一上下文,并行观察不同模型的答案。`})}),(0,U.jsxs)(`span`,{className:`compare-context`,children:[i,` 个文件 · `,a,` 条记忆`]})]}),(0,U.jsxs)(`div`,{className:`compare-config`,children:[(0,U.jsxs)(`fieldset`,{className:`compare-targets`,children:[(0,U.jsx)(`legend`,{children:`参与模型`}),e.map(e=>(0,U.jsxs)(`label`,{children:[(0,U.jsx)(`input`,{type:`checkbox`,checked:c.has(e.id),disabled:_,onChange:t=>x(e.id,t.target.checked)}),(0,U.jsxs)(`span`,{children:[(0,U.jsx)(`strong`,{children:e.model}),(0,U.jsx)(`small`,{children:e.providerName})]})]},e.id))]}),(0,U.jsx)(`label`,{className:`compare-prompt-label`,htmlFor:`comparePrompt`,children:`实验任务`}),(0,U.jsx)(`textarea`,{id:`comparePrompt`,className:`compare-prompt`,rows:3,placeholder:`输入要交给多个模型的相同任务…`,value:u,onChange:e=>f(e.target.value)}),(0,U.jsxs)(`div`,{className:`compare-actions`,children:[(0,U.jsxs)(`span`,{children:[`已选择 `,b.length,` 个模型`]}),(0,U.jsx)(`button`,{className:`btn-primary${_?` is-stopping`:``}`,type:`button`,disabled:!_&&b.length<2,onClick:()=>void S(),children:_?`停止实验`:p.length?`再次实验`:`开始实验`})]})]}),(0,U.jsx)(`div`,{className:`compare-results`,children:p.map(e=>(0,U.jsx)(Ue,{result:e,prompt:u.trim(),adopt:s},e.id))}),(0,U.jsx)(We,{results:p}),(0,U.jsxs)(`details`,{className:`compare-history`,open:!h.length,children:[(0,U.jsxs)(`summary`,{children:[(0,U.jsx)(`span`,{children:`历史实验`}),(0,U.jsxs)(`small`,{children:[h.length,` 条,保存在当前设备`]})]}),(0,U.jsx)(`div`,{children:h.length?h.map(e=>{let t=new Date(e.createdAt),n=Number.isNaN(t.getTime())?``:t.toLocaleString(`zh-CN`,{month:`numeric`,day:`numeric`,hour:`2-digit`,minute:`2-digit`}),r=e.results.filter(e=>e.status===`success`).length;return(0,U.jsxs)(`button`,{type:`button`,className:`compare-history-item`,onClick:()=>{f(e.prompt),m(e.results)},children:[(0,U.jsxs)(`span`,{children:[(0,U.jsx)(`strong`,{children:e.prompt}),(0,U.jsxs)(`small`,{children:[e.projectName,` · `,r,` 个结果`]})]}),(0,U.jsx)(`time`,{children:n})]},e.id)}):(0,U.jsx)(`div`,{className:`compare-history-empty`,children:`完成一次实验后,结果会保存在当前设备。`})})]})]})}function Ke(e){return(0,U.jsxs)(`div`,{className:`settings-page experiment-settings`,children:[(0,U.jsx)(`div`,{className:`settings-page-heading`,children:(0,U.jsxs)(`div`,{children:[(0,U.jsx)(`div`,{className:`usage-kicker`,children:`MODEL ARENA`}),(0,U.jsx)(`h3`,{children:`模型竞技场`}),(0,U.jsx)(`p`,{children:`用同一个任务、参数和项目上下文并行观察结果;首页和普通对话始终只运行当前主模型。`})]})}),e.targets.length<2&&(0,U.jsxs)(`div`,{className:`experiment-requirement`,children:[(0,U.jsx)(`strong`,{children:`还需要一个模型`}),(0,U.jsx)(`span`,{children:`至少连接两个模型后才能进行公平的并行实验。`})]}),(0,U.jsx)(Ge,{...e})]})}var Y=null;function qe(e=`general`){let t=n(`#settings`);t.classList.contains(`open`)||(Y=document.activeElement instanceof HTMLElement?document.activeElement:null),t.inert=!1,t.setAttribute(`aria-hidden`,`false`),t.classList.add(`open`),n(`#scrim`).classList.add(`open`),Z(e),n(`#settingsBody`)?.focus?.({preventScroll:!0}),n(`#app`).inert=!0;let r=`#/settings/${encodeURIComponent(e)}`;location.hash!==r&&history.pushState(null,``,r)}function X(){let e=n(`#settings`);if(!e.classList.contains(`open`))return;let t=n(`#app`);t.inert=!1;let r=n(`#settingsBtn`),i=Y?.isConnected&&t.contains(Y)?Y:r;try{i?.focus?.({preventScroll:!0})}catch{i?.focus?.()}e.contains(document.activeElement)&&r?.focus?.({preventScroll:!0}),e.classList.remove(`open`),e.inert=!0,e.setAttribute(`aria-hidden`,`true`),n(`#scrim`).classList.remove(`open`),Y=null,window.dispatchEvent(new CustomEvent(`multichat:settingschange`,{detail:{open:!1}})),location.hash.startsWith(`#/settings/`)&&history.replaceState(null,``,p.currentConvId?`#/chat/${encodeURIComponent(p.currentConvId)}`:`#/new`)}n(`#scrim`).onclick=X,n(`#closeSettings`).onclick=X,n(`#closeSettingsTop`).onclick=X,document.addEventListener(`keydown`,e=>{let t=n(`#settings`);if(!t.classList.contains(`open`)||n(`#modal`).classList.contains(`open`))return;if(e.key===`Escape`){X();return}if(e.key!==`Tab`)return;let r=Array.from(t.querySelectorAll(`input:not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), [href], [tabindex="0"]`)).filter(e=>e.offsetParent!==null);if(!r.length){e.preventDefault(),n(`#settingsBody`)?.focus();return}let i=r[0],a=r[r.length-1];e.shiftKey&&document.activeElement===i?(e.preventDefault(),a.focus()):!e.shiftKey&&document.activeElement===a&&(e.preventDefault(),i.focus())}),t(`.settings-tab[data-tab]`).forEach(e=>e.onclick=()=>Z(e.dataset.tab));function Z(e){if(p.currentTab=e,t(`.settings-tab[data-tab]`).forEach(t=>t.classList.toggle(`active`,t.dataset.tab===e)),Ye(e),window.dispatchEvent(new CustomEvent(`multichat:settingschange`,{detail:{open:!0,tab:e}})),n(`#settings`).classList.contains(`open`)){let t=`#/settings/${encodeURIComponent(e)}`;location.hash!==t&&history.replaceState(null,``,t)}e===`usage`?he(p.usageRange):e===`capabilities`&&P()}var Je=[`general`,`workspace`,`providers`,`agents`,`experiment`,`skills`,`tools`,`mcp`,`plugins`,`capabilities`,`runs`,`usage`];function Ye(e=`general`,t=!1){let r=Je.includes(e)?e:`general`,i=n(`#settingsBody`);oe();let a=t?i.scrollTop:0;if(r===`general`)A(Ae,{params:p.params,theme:m(),skin:w(),density:S(),token:C(),onSaveParams:e=>{p.params=e,E(),d(`已保存`)},onTheme:e=>{h(e),d(`主题已切换`)},onSkin:e=>{T(e),d(`强调色已切换`)},onDensity:e=>{b(e),d(`界面密度已切换`)},onSaveToken:e=>{_(e),d(e.trim()?`访问令牌已保存`:`访问令牌已清除`)}});else if(r===`providers`)A(Me,{providers:p.providers,onSave:async(e,t)=>{try{return await g(`/api/providers/${encodeURIComponent(e.id)}`,{method:`PUT`,body:JSON.stringify(t)}),await de(),z(),d(`已保存`),!0}catch(e){return d(e.message,`error`),!1}},onDelete:async e=>{if(!await showConfirm({title:`删除模型提供方`,message:`删除「${e.name||e.id}」?此操作不可撤销。`,confirmLabel:`删除`,danger:!0}))return!1;try{return await g(`/api/providers/${encodeURIComponent(e.id)}`,{method:`DELETE`}),await de(),z(),d(`已删除`),!0}catch(e){return d(e.message,`error`),!1}},onAddBuiltin:xe,onAddCustom:Se,onProbe:async e=>g(`/api/providers/${encodeURIComponent(e.id)}/probe`,{method:`POST`,body:JSON.stringify({})})});else if(r===`experiment`){let e=De(),t=[p.selectedProvider&&p.selectedModel?`${p.selectedProvider.id}:${p.selectedModel}`:``,...e.map(e=>e.id)].filter(Boolean).filter((e,t,n)=>n.indexOf(e)===t).slice(0,2),r=localStorage.getItem(`multichat_compare_draft`)||``,i=r||[...p.messages||[]].reverse().find(e=>e.role===`user`)?.content||``;r&&localStorage.removeItem(`multichat_compare_draft`),A(Ke,{targets:e,defaultTargetIds:t,initialPrompt:i,projectName:p.selectedProject?.name||`未选择项目`,fileCount:p.selectedAssetIds?.size||0,memoryCount:(p.memories||[]).filter(e=>e.enabled!==!1).length,execute:Oe,adopt:async(e,t)=>{await Ee(e,t),X(),window.requestAnimationFrame(()=>n(`#input`)?.focus())}})}else r===`skills`?A(Ne,{initialSkills:p.skills,sourceLabel:ie,onToggle:async e=>{try{return await g(`/api/skills/${encodeURIComponent(e.key||e.id)}/toggle`,{method:`POST`,body:JSON.stringify({enabled:!e.enabled})}),await pe(),!0}catch(e){return d(e.message,`error`),!1}},onEdit:e=>we(e.key||e.id),onDiff:async e=>{try{re(`Skill 变更`,await g(`/api/skills/${encodeURIComponent(e.key||e.id)}/diff`))}catch(e){d(e.message,`error`)}},onDelete:async e=>{if(!await showConfirm({title:`删除 Skill`,message:`删除该 Skill?关联运行配置的引用也将被移除。`,confirmLabel:`删除`,danger:!0}))return!1;try{return await g(`/api/skills/${encodeURIComponent(e.key||e.id)}`,{method:`DELETE`}),await Promise.all([pe(),N()]),!0}catch(e){return d(e.message,`error`),!1}},onImport:()=>_e(`skill`),onAdd:()=>we(null)}):r===`tools`?A(Pe,{initialTools:p.tools,agents:p.agents,onTest:async(e,t)=>g(`/api/tools/${encodeURIComponent(e.id)}/test`,{method:`POST`,body:JSON.stringify(t===void 0?{}:{expression:t})}),onToggle:async e=>{try{return await g(`/api/tools/${encodeURIComponent(e.id)}`,{method:`PUT`,body:JSON.stringify({enabled:!e.enabled})}),await me(),d(e.enabled?`工具已停用`:`工具已启用`),!0}catch(e){return d(e.message,`error`),!1}}}):r===`workspace`?Xe():r===`agents`?Ze():r===`plugins`?ne():r===`mcp`?te():r===`capabilities`?Qe():r===`usage`?et():r===`runs`&&tt();t&&requestAnimationFrame(()=>{i.scrollTop=Math.min(a,Math.max(0,i.scrollHeight-i.clientHeight))})}function Xe(){A(Fe,{onProjectChange:async e=>{p.selectedProject=p.projects.find(t=>t.id===e)||null,p.selectedProject&&localStorage.setItem(`multichat_project`,p.selectedProject.id),await I(),z(),Te(),M()},onSaveDefaults:async(e,t,n)=>{if(!p.selectedProject)d(`请先选择项目`,`error`);else try{await g(`/api/projects/${encodeURIComponent(p.selectedProject.id)}`,{method:`PUT`,body:JSON.stringify({defaultAgentId:e,defaultProviderId:t,defaultModel:n})});let r={...p.selectedProject,defaultAgentId:e,defaultProviderId:t,defaultModel:n};p.selectedProject=r,p.projects=p.projects.map(e=>e.id===r.id?r:e),ue(),d(`已保存项目默认`)}catch(e){d(e.message,`error`)}},onNewProject:$,onImportFolder:le,onImportUrl:rt,onUploadFile:async e=>{if(p.selectedProject)try{await g(`/api/assets`,{method:`POST`,body:JSON.stringify({projectId:p.selectedProject.id,name:e.name,mimeType:e.type||`text/plain`,content:await e.text()})}),await I(),d(`文件已加入项目`)}catch(e){d(e.message,`error`)}},onDeleteAsset:async e=>{try{await g(`/api/assets/${encodeURIComponent(e)}`,{method:`DELETE`}),await I()}catch(e){d(e.message,`error`)}},onSearch:async e=>p.selectedProject?g(`/api/projects/${encodeURIComponent(p.selectedProject.id)}/search?q=${encodeURIComponent(e)}`):[],onAddMemory:()=>Q(),onEditMemory:e=>Q(e),onToggleMemory:async e=>{await g(`/api/memories/${encodeURIComponent(e.id)}`,{method:`PUT`,body:JSON.stringify({enabled:e.enabled===!1})}),await F()},onDeleteMemory:async e=>{await showConfirm({title:`删除项目记忆`,message:`删除这条项目记忆?`,confirmLabel:`删除`,danger:!0})&&(await g(`/api/memories/${encodeURIComponent(e)}`,{method:`DELETE`}),await F())},onCreateSnapshot:async()=>{if(!p.selectedProject)return;let e=await showPrompt({title:`新建项目快照`,label:`快照名称`,value:`项目快照 ${new Date().toLocaleString(`zh-CN`)}`,maxLength:120});if(e!=null)try{await g(`/api/snapshots`,{method:`POST`,body:JSON.stringify({projectId:p.selectedProject.id,title:e})}),await F(),d(`项目快照已创建`)}catch(e){d(e.message,`error`)}},onRestoreSnapshot:async e=>{if(await showConfirm({title:`恢复快照`,message:`恢复该快照?当前状态会先自动备份,随后替换项目文件、记忆和默认配置。`,confirmLabel:`恢复快照`,danger:!0}))try{await g(`/api/snapshots/${encodeURIComponent(e)}/restore`,{method:`POST`}),await Promise.all([I(),N()]),M(),d(`快照已恢复`)}catch(e){d(e.message,`error`)}},onDeleteSnapshot:async e=>{await showConfirm({title:`删除项目快照`,message:`删除该项目快照?`,confirmLabel:`删除`,danger:!0})&&(await g(`/api/snapshots/${encodeURIComponent(e)}`,{method:`DELETE`}),await F())}})}function Ze(){A(Ie,{onEdit:e=>Ce(e),onExport:e=>ye(e,`agent`),onDelete:async e=>{if(await showConfirm({title:`删除运行配置`,message:`删除该运行配置?`,confirmLabel:`删除`,danger:!0})){try{await g(`/api/agents/${encodeURIComponent(e.id)}`,{method:`DELETE`})}catch(e){d(e.message,`error`);return}p.selectedAgent?.id===e.id&&(p.selectedAgent=null),D(),await N(),z()}},onImport:async e=>{try{await ve(be(JSON.parse(await e.text())),`文件 ${e.name}`)}catch(e){d(`解析失败:${e.message}`,`error`)}}})}function Qe(){A(Re,{onRefresh:async()=>{p.capabilities=null,await P()}})}function $e(e,t){let n=[[`date`,`input_tokens`,`output_tokens`,`total_tokens`,`requests`,`errors`],...(e?.daily||[]).map(e=>[e.date,e.inputTokens,e.outputTokens,e.totalTokens,e.requests,e.errors])],r=new Blob([n.map(e=>e.join(`,`)).join(`
2
+ `)],{type:`text/csv;charset=utf-8`}),i=document.createElement(`a`);i.href=URL.createObjectURL(r),i.download=`multichat-usage-${t}d.csv`,i.click(),setTimeout(()=>URL.revokeObjectURL(i.href),1e3)}function et(){A(Be,{onRange:async e=>{p.usage=null,await he(e)},onExport:$e})}function tt(){A(Ve,{onRefresh:fe,onOpen:it})}function nt(){R({title:`新建工作区`,body:`<form id="workspaceForm"><div class="field"><label>名称</label><input name="name" required placeholder="例如:产品研发" /></div><div class="field"><label>描述</label><input name="description" placeholder="这个工作区用于什么" /></div><div class="row"><button type="button" class="btn-ghost" id="workspaceCancel">取消</button><button class="btn-primary" type="submit">创建</button></div></form>`,onMount:e=>{n(`#workspaceCancel`,e).onclick=L,n(`#workspaceForm`,e).onsubmit=async e=>{e.preventDefault();let t=Object.fromEntries(new FormData(e.target).entries());try{await g(`/api/workspaces`,{method:`POST`,body:JSON.stringify(t)}),await ge(),z(),L(),d(`工作区已创建`)}catch(e){d(e.message,`error`)}}}})}function Q(e=null){let t=e?p.memories.find(t=>t.id===e):null;R({title:t?`编辑项目记忆`:`新增项目记忆`,body:`<form id="memoryForm"><div class="field"><label>标题</label><input name="title" required maxlength="120" value="${c(t?.title||``)}" placeholder="例如:代码风格" /></div><div class="field"><label>事实或偏好</label><textarea name="content" required maxlength="4000" rows="6" placeholder="只记录可长期复用、由你确认的信息。">${c(t?.content||``)}</textarea><div class="pmeta">记忆作为上下文参考,不会被当作可执行指令。</div></div><div id="memoryErr" class="auth-error"></div><div class="row"><button type="button" class="btn-ghost" id="memoryCancel">取消</button><button class="btn-primary" type="submit">保存</button></div></form>`,onMount:e=>{n(`#memoryCancel`,e).onclick=L,n(`#memoryForm`,e).onsubmit=async r=>{r.preventDefault();let i={...Object.fromEntries(new FormData(r.target).entries()),projectId:p.selectedProject?.id,enabled:!t||t.enabled!==!1};try{await g(t?`/api/memories/${encodeURIComponent(t.id)}`:`/api/memories`,{method:t?`PUT`:`POST`,body:JSON.stringify(i)}),await F(),L(),d(`项目记忆已保存`)}catch(t){n(`#memoryErr`,e).textContent=t.message}}}})}function $(){if(!p.selectedWorkspace)return d(`请先选择工作区`,`error`);R({title:`新建项目`,body:`<form id="projectForm"><div class="field"><label>名称</label><input name="name" required placeholder="例如:移动端重构" /></div><div class="field"><label>描述</label><input name="description" placeholder="项目目标或范围" /></div><div class="row"><button type="button" class="btn-ghost" id="projectCancel">取消</button><button class="btn-primary" type="submit">创建</button></div></form>`,onMount:e=>{n(`#projectCancel`,e).onclick=L,n(`#projectForm`,e).onsubmit=async e=>{e.preventDefault();let t=Object.fromEntries(new FormData(e.target).entries());t.workspaceId=p.selectedWorkspace.id;try{await g(`/api/projects`,{method:`POST`,body:JSON.stringify(t)}),await I(),L(),d(`项目已创建`)}catch(e){d(e.message,`error`)}}}})}function rt(){if(!p.selectedProject)return d(`请先选择项目`,`error`);R({title:`从 URL 添加文件`,body:`<form id="assetUrlForm"><div class="field"><label>URL</label><input name="url" type="url" required placeholder="https://example.com/notes.md" /></div><div class="field"><label>显示名称(可选)</label><input name="name" placeholder="自动从 URL 推断" /></div><div id="assetUrlErr" class="auth-error"></div><div class="row"><button type="button" class="btn-ghost" id="assetUrlCancel">取消</button><button class="btn-primary" type="submit">添加</button></div></form>`,onMount:e=>{n(`#assetUrlCancel`,e).onclick=L,n(`#assetUrlForm`,e).onsubmit=async t=>{t.preventDefault();let r=Object.fromEntries(new FormData(t.target).entries());r.projectId=p.selectedProject.id;try{await g(`/api/assets`,{method:`POST`,body:JSON.stringify(r)}),await I(),L(),d(`远程文件已加入项目`)}catch(t){n(`#assetUrlErr`,e).textContent=t.message}}}})}async function it(e){try{let t=await g(`/api/runs/${encodeURIComponent(e)}`),r=(t.turns||[]).flatMap(e=>e.steps||[]),i=t.contextManifest||{},a=t.usage||{},o=(e,t)=>`<span><small>${c(e)}</small><strong>${c(t)}</strong></span>`,s=t.status===`completed`?`已完成`:t.status===`error`?`失败`:t.status===`cancelled`?`已取消`:`运行中`;R({title:`运行详情 · ${t.agentName||t.agentId}`,body:`<div class="run-detail-summary">${o(`状态`,s)}${o(`模型`,t.model||`—`)}${o(`Token`,W(a.totalTokens||0))}${o(`步骤`,String(r.length))}${o(`策略`,t.toolPolicy===`safe`?`安全`:`自动`)}</div><div class="run-detail-grid"><section><h4>执行时间线</h4><div class="flight-timeline">${r.map((e,t)=>`<article class="flight-step ${c(e.status)}"><i>${t+1}</i><div><strong>${e.kind===`tool_call`?c(e.tool||`工具调用`):`模型请求 · ${c(e.model||``)}`}</strong><p>${e.kind===`tool_call`?`${c((e.permissions||[]).join(`, `)||`无特殊权限`)} · ${c(e.risk||`low`)}`:`${e.messageCount||0} 条上下文 · ${W(e.usage?.total||0)} tokens`}</p>${e.error?`<code>${c(e.error)}</code>`:``}</div><span>${e.durationMs==null?c(e.status):`${(e.durationMs/1e3).toFixed(2)}s`}</span></article>`).join(``)||`<div class="control-empty">没有步骤轨迹。</div>`}</div></section><section><h4>上下文透镜</h4><div class="context-lens"><div><span>消息</span><strong>${i.messages||0}</strong></div><div><span>系统上下文</span><strong>${W(i.systemCharacters||0)} 字</strong></div><div><span>项目文件</span><strong>${(i.assets||[]).length}</strong></div><div><span>记忆</span><strong>${(i.memories||[]).length}</strong></div></div><div class="context-source"><h5>注入来源</h5>${[[`文件`,i.assets],[`记忆`,i.memories],[`Skills`,i.skills],[`工具`,i.tools],[`MCP`,i.mcpServers]].map(([e,t])=>`<div><strong>${e}</strong><span>${(t||[]).map(e=>c(e.name||e.id)).join(`、`)||`无`}</span></div>`).join(``)}</div><div class="context-source"><h5>Token 构成</h5><div><strong>输入</strong><span>${W(a.inputTokens||0)}</span></div><div><strong>输出</strong><span>${W(a.outputTokens||0)}</span></div><div><strong>缓存</strong><span>${W(a.cachedTokens||0)}</span></div><div><strong>估算</strong><span>${W(a.estimatedTokens||0)}</span></div></div></section></div><div class="row"><button class="btn-ghost" id="exportRun">导出运行快照</button><button class="btn-primary" id="closeRunDetail">关闭</button></div>`,onMount:e=>{e.classList.add(`run-detail-modal`),n(`#closeRunDetail`,e).onclick=L,n(`#exportRun`,e).onclick=()=>{let e=new Blob([JSON.stringify(t,null,2)],{type:`application/json`}),n=document.createElement(`a`);n.href=URL.createObjectURL(e),n.download=`${t.id}.json`,n.click(),setTimeout(()=>URL.revokeObjectURL(n.href),1e3)}}})}catch(e){d(e.message,`error`)}}export{X as closeSettings,qe as openSettings,Qe as renderCapabilities,tt as renderRuns,Ye as renderSettings,et as renderUsage,rt as showAssetUrlModal,Q as showMemoryModal,$ as showProjectForm,it as showRunDetail,nt as showWorkspaceForm,Z as switchSettingsTab};
@@ -1 +1 @@
1
- import{S as e}from"./index-BaUGyQ3C.js";function t(){let t=e(`#sidebar`),n=e(`#sidebarToggle`),r=e(`#sidebarClose`),i=e(`#mobileScrim`),a=e(`.main`);if(!t||!n||!i)return;let o=(e=!1)=>{a&&(a.inert=!1),e&&n.focus({preventScroll:!0}),t.classList.remove(`open`),i.classList.remove(`open`),n.setAttribute(`aria-expanded`,`false`),document.body.classList.remove(`mobile-nav-open`)},s=()=>{t.classList.add(`open`),i.classList.add(`open`),n.setAttribute(`aria-expanded`,`true`),document.body.classList.add(`mobile-nav-open`);let r=e(`#convSearch`);r&&r.focus({preventScroll:!0}),a&&(a.inert=!0)};n.onclick=()=>t.classList.contains(`open`)?o(!0):s(),r&&(r.onclick=()=>o(!0)),i.onclick=()=>o(!0),document.addEventListener(`keydown`,e=>{e.key===`Escape`&&t.classList.contains(`open`)&&o(!0)}),window.addEventListener(`resize`,()=>{window.innerWidth>760&&o()})}export{t as setupShell};
1
+ import{E as e}from"./index-CeU_ksnE.js";function t(){let t=e(`#sidebar`),n=e(`#sidebarToggle`),r=e(`#sidebarClose`),i=e(`#mobileScrim`),a=e(`.main`);if(!t||!n||!i)return;let o=(e=!1)=>{a&&(a.inert=!1),e&&n.focus({preventScroll:!0}),t.classList.remove(`open`),i.classList.remove(`open`),n.setAttribute(`aria-expanded`,`false`),document.body.classList.remove(`mobile-nav-open`)},s=()=>{t.classList.add(`open`),i.classList.add(`open`),n.setAttribute(`aria-expanded`,`true`),document.body.classList.add(`mobile-nav-open`);let r=e(`#convSearch`);r&&r.focus({preventScroll:!0}),a&&(a.inert=!0)};n.onclick=()=>t.classList.contains(`open`)?o(!0):s(),r&&(r.onclick=()=>o(!0)),i.onclick=()=>o(!0),document.addEventListener(`keydown`,e=>{e.key===`Escape`&&t.classList.contains(`open`)&&o(!0)}),window.addEventListener(`resize`,()=>{window.innerWidth>760&&o()})}export{t as setupShell};