handmux 0.6.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -4
- package/README.zh-CN.md +0 -4
- package/bin/handmux.js +24 -17
- package/hooks/handmux-statusline.cjs +75 -0
- package/hooks/handmux-write.cjs +6 -26
- package/package.json +1 -2
- package/public/assets/index-CCvTPJwI.js +157 -0
- package/public/assets/{index-_nvN0yNe.css → index-CYEn5HNU.css} +1 -1
- package/public/index.html +2 -2
- package/src/claudeEvents.js +2 -9
- package/src/cli/i18n/en.js +5 -5
- package/src/cli/i18n/zh.js +5 -5
- package/src/cli/setupWizard.js +4 -1
- package/src/cli/statusLine.js +79 -0
- package/src/httpApi.js +8 -0
- package/src/usage.js +94 -0
- package/public/assets/index-DlO8ul0J.js +0 -157
- package/src/cli/tmuxConf.js +0 -90
- package/tmux/README.md +0 -77
- package/tmux/claude-tab-seed.py +0 -72
- package/tmux/claude-tab-seen.sh +0 -14
|
@@ -29,4 +29,4 @@
|
|
|
29
29
|
* The original design remains. The terminal itself
|
|
30
30
|
* has been extended to include xterm CSI codes, among
|
|
31
31
|
* other features.
|
|
32
|
-
*/.xterm{cursor:text;position:relative;user-select:none;-ms-user-select:none;-webkit-user-select:none}.xterm.focus,.xterm:focus{outline:none}.xterm .xterm-helpers{position:absolute;top:0;z-index:5}.xterm .xterm-helper-textarea{padding:0;border:0;margin:0;position:absolute;opacity:0;left:-9999em;top:0;width:0;height:0;z-index:-5;white-space:nowrap;overflow:hidden;resize:none}.xterm .composition-view{background:#000;color:#fff;display:none;position:absolute;white-space:nowrap;z-index:1}.xterm .composition-view.active{display:block}.xterm .xterm-viewport{background-color:#000;overflow-y:scroll;cursor:default;position:absolute;right:0;left:0;top:0;bottom:0}.xterm .xterm-screen{position:relative}.xterm .xterm-screen canvas{position:absolute;left:0;top:0}.xterm .xterm-scroll-area{visibility:hidden}.xterm-char-measure-element{display:inline-block;visibility:hidden;position:absolute;top:0;left:-9999em;line-height:normal}.xterm.enable-mouse-events{cursor:default}.xterm.xterm-cursor-pointer,.xterm .xterm-cursor-pointer{cursor:pointer}.xterm.column-select.focus{cursor:crosshair}.xterm .xterm-accessibility:not(.debug),.xterm .xterm-message{position:absolute;left:0;top:0;bottom:0;right:0;z-index:10;color:transparent;pointer-events:none}.xterm .xterm-accessibility-tree:not(.debug) *::selection{color:transparent}.xterm .xterm-accessibility-tree{-webkit-user-select:text;user-select:text;white-space:pre}.xterm .live-region{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}.xterm-dim{opacity:1!important}.xterm-underline-1{text-decoration:underline}.xterm-underline-2{text-decoration:double underline}.xterm-underline-3{text-decoration:wavy underline}.xterm-underline-4{text-decoration:dotted underline}.xterm-underline-5{text-decoration:dashed underline}.xterm-overline{text-decoration:overline}.xterm-overline.xterm-underline-1{text-decoration:overline underline}.xterm-overline.xterm-underline-2{text-decoration:overline double underline}.xterm-overline.xterm-underline-3{text-decoration:overline wavy underline}.xterm-overline.xterm-underline-4{text-decoration:overline dotted underline}.xterm-overline.xterm-underline-5{text-decoration:overline dashed underline}.xterm-strikethrough{text-decoration:line-through}.xterm-screen .xterm-decoration-container .xterm-decoration{z-index:6;position:absolute}.xterm-screen .xterm-decoration-container .xterm-decoration.xterm-decoration-top-layer{z-index:7}.xterm-decoration-overview-ruler{z-index:8;position:absolute;top:0;right:0;pointer-events:none}.xterm-decoration-top{z-index:2;position:relative}*{box-sizing:border-box}@font-face{font-family:JetBrainsMono Nerd Font;src:url(/fonts/JetBrainsMonoNerdFontMono-Regular.woff2) format("woff2");font-weight:400;font-style:normal;font-display:swap}@font-face{font-family:TW Unifont;src:url(/fonts/TWUnifont.woff2) format("woff2");font-weight:400;font-style:normal;font-display:swap;unicode-range:U+2190-21FF,U+2300-23FF,U+2400-243F,U+2500-257F,U+2580-259F,U+25A0-25FF,U+2600-26FF,U+2700-27BF,U+2800-28FF,U+2B00-2BFF}html,body,#root{height:100%;margin:0;overscroll-behavior:none}body{font-family:-apple-system,system-ui,sans-serif;background:#1a1b1e;color:#e6e6e6}.app{display:flex;flex-direction:column;height:100%;overflow:hidden}.topbar{display:flex;align-items:center;gap:12px;padding:8px 12px;background:#2a2b2e}.hamburger{font-size:20px;background:none;border:none;color:#e6e6e6}.session-name{font-weight:600;margin-right:auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.fontbtn{min-width:36px;padding:4px 10px;border:none;border-radius:6px;background:#33353a;color:#e6e6e6;font-size:14px;touch-action:manipulation}.fontbtn[aria-pressed=true]{background:#2a4060;color:#7ab4f5}.topbar-icon{display:inline-flex;align-items:center;padding:4px;border:none;background:none;color:#e6e6e6;touch-action:manipulation}.topbar-icon:active{color:#4aa3ff}.topbar-icon svg{width:21px;height:21px;display:block}.settings-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;background:#00000080;z-index:19}.settings-card{position:fixed;z-index:20;left:50%;top:50%;transform:translate(-50%,-50%);width:calc(100% - 48px);max-width:360px;background:#232427;border-radius:12px;padding:16px;box-shadow:0 10px 40px #00000080}.settings-head{display:flex;align-items:center;margin-bottom:12px}.settings-title{font-size:16px;font-weight:600;margin-right:auto}.settings-close{background:none;border:none;color:#aaa;font-size:16px;padding:4px 8px;touch-action:manipulation}.settings-section{padding:10px 0;border-top:1px solid #33353a}.settings-label{font-size:12px;color:#888;letter-spacing:1px;margin-bottom:8px}.settings-btns{display:flex;align-items:center;gap:8px;flex-wrap:wrap}.lang-drop{position:relative;display:inline-block}.lang-drop-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1}.lang-trigger{display:flex;align-items:center;gap:8px;padding:5px 10px;background:#33353a;border:none;border-radius:6px;color:#e6e6e6;font-size:14px;touch-action:manipulation;cursor:pointer}.lang-chevron{font-size:11px;color:#888}.lang-menu{position:absolute;top:calc(100% + 4px);left:0;min-width:100%;background:#2a2c30;border-radius:8px;box-shadow:0 4px 20px #00000080;z-index:2;overflow:hidden}.lang-option{display:block;width:100%;padding:9px 14px;border:none;background:none;color:#e6e6e6;font-size:14px;text-align:left;touch-action:manipulation;white-space:nowrap}.lang-option:active{background:#33353a}.lang-option.active{color:#7ab4f5}.settings-value{min-width:56px;text-align:center;font-size:14px;color:#e6e6e6}.cols-btns{flex-wrap:nowrap;gap:5px}.col-step{min-width:40px;padding:4px 6px;letter-spacing:.3px}.col-fine{color:#aaa}.settings-note{font-size:13px;color:#9aa0a6;flex:1 1 auto;min-width:0}.settings-hint{font-size:12px;color:#7c8088;line-height:1.5;margin-top:8px}.settings-hint.preview-dynamic-disabled{color:#6b6f77;border-left:2px solid #34373d;padding-left:8px;margin-top:6px}@keyframes tw-spin{to{transform:rotate(360deg)}}.spinner{display:inline-block;width:14px;height:14px;flex:none;border:2px solid #4a4d52;border-top-color:#e6e6e6;border-radius:50%;animation:tw-spin .7s linear infinite}.bind-input{width:100%;padding:10px;border-radius:6px;border:1px solid #444;background:#1a1b1e;color:#fff;font-size:14px}.startup-custom{margin-top:6px}.opt+.opt{margin-top:14px}.field{width:100%;box-sizing:border-box;display:flex;align-items:center;gap:8px;padding:10px;border-radius:6px;border:1px solid #444;background:#1a1b1e;color:#fff;font-size:14px;text-align:left;touch-action:manipulation}.field:active{border-color:#555}.cwd-field{justify-content:space-between}.cwd-path{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:13px;opacity:.9}.cwd-action{flex:none;color:#4aa3ff;font-size:13px}.cwd-reset{margin-top:6px;background:none;border:none;color:#888;font-size:12px;padding:2px 0;touch-action:manipulation}.dd{position:relative}.dd-trigger{justify-content:space-between}.dd-value{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dd-caret{flex:none;color:#8a8f98;font-size:12px;transition:transform .15s ease}.dd-caret.open{transform:rotate(180deg)}.dd-menu{position:absolute;top:calc(100% + 6px);left:0;right:0;z-index:30;background:#26282c;border:1px solid #3a3c42;border-radius:8px;padding:4px;box-shadow:0 10px 30px #0000008c;transform-origin:top;animation:dd-pop .12s ease}@keyframes dd-pop{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:none}}.dd-option{display:flex;align-items:center;justify-content:space-between;gap:8px;width:100%;padding:10px;border:none;border-radius:6px;background:none;color:#e6e6e6;font-size:14px;text-align:left;touch-action:manipulation}.dd-option:active{background:#33353a}.dd-option.is-selected{color:#07c160}.dd-check{flex:none;color:#07c160;font-size:13px}.bind-error{margin-top:8px;color:#ff8585;font-size:13px}.bind-hint{margin-top:8px;color:#888;font-size:13px}.bind-actions{margin-top:12px;justify-content:flex-end}.bind-confirm{background:#4a7cff;color:#fff}.bind-confirm:disabled{opacity:.6}.windowbar{display:flex;gap:8px;align-items:center;padding:6px 8px;background:#222}.windowbar-scroll{flex:1;min-width:0;display:flex;gap:4px;overflow-x:auto;overflow-y:hidden;-webkit-overflow-scrolling:touch;touch-action:pan-x;scrollbar-width:none}.windowbar-scroll::-webkit-scrollbar{display:none}.win-tab{white-space:nowrap;padding:4px 10px;border:none;border-radius:6px;background:#33353a;color:#bbb;font-size:13px;touch-action:manipulation}.win-tab.active{background:#4a7cff;color:#fff}.win-new{border:1px dashed #555;color:#8aa;font-weight:700;background:transparent}.win-panes{margin-left:5px;font-size:11px;color:#889}.win-tab.active .win-panes{color:#d6e4ff}.wt-dd{position:relative;flex:none}.wt-trigger{display:inline-flex;align-items:center;gap:4px}.wt-sep{margin:0 -1px;color:#cfe0ff;opacity:.4;font-weight:400}.wt-pane{font-weight:600}.wt-caret{flex:none;font-size:11px;color:#d6e4ff;transition:transform .15s ease}.wt-caret.open{transform:rotate(180deg)}.wt-menu{position:fixed;top:auto;right:auto;min-width:160px;max-width:240px}.terminal-wrap{position:relative;flex:1;min-height:0;overflow:hidden}.terminal{height:100%;overflow-x:auto;overflow-y:hidden;overscroll-behavior:contain;-webkit-overflow-scrolling:touch;touch-action:pan-x pan-y}.terminal--loading{opacity:0}.terminal .xterm{display:flex;flex-direction:column;justify-content:flex-end;height:100%;width:max-content;min-width:100%}.terminal .xterm-screen{flex:none}.terminal .xterm-viewport{touch-action:pan-x pan-y;overscroll-behavior:contain}.terminal .xterm-helper-textarea{pointer-events:none;opacity:0}.new-output{position:absolute;right:12px;bottom:12px;z-index:5;touch-action:manipulation;padding:8px 14px;border:none;border-radius:16px;background:#4a7cff;color:#fff;box-shadow:0 2px 8px #0006}.dbg{position:absolute;left:6px;top:6px;z-index:6;font:12px/1.4 monospace;color:#9fe;background:#0009;padding:2px 6px;border-radius:4px;pointer-events:none}.term-banner{position:absolute;left:0;right:0;top:0;z-index:6;font:12px/1.7 -apple-system,system-ui,sans-serif;text-align:center;padding:2px 10px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;pointer-events:none}.term-banner--hist{background:#e0a800;color:#1a1400}.term-banner--err{background:#d32f2f;color:#fff}.copy-bubble{position:absolute;z-index:7;padding:7px 16px;border:none;border-radius:16px;background:#4a7cff;color:#fff;font-size:14px;font-weight:600;box-shadow:0 2px 10px #00000080;touch-action:manipulation}.sel-hint{position:absolute;left:50%;top:12px;transform:translate(-50%);z-index:8;max-width:92%;padding:7px 14px;border-radius:16px;background:#4a7cfff5;color:#fff;font-size:13px;font-weight:600;white-space:nowrap;box-shadow:0 2px 10px #00000080;pointer-events:none}.input-text{flex:1;min-width:0;padding:5px 4px;border:none;background:transparent;color:#fff;font-family:inherit;font-size:16px;line-height:22px;max-height:156px;resize:none;overflow-y:auto;display:block}.input-text:focus{outline:none}.token-prompt button{padding:8px 14px;border:none;border-radius:6px;background:#4a7cff;color:#fff}.drawer{position:fixed;top:0;left:0;width:78%;max-width:320px;height:100%;background:#232427;transform:translate(-100%);transition:transform .2s;z-index:10;padding:12px;display:flex;flex-direction:column;overflow:hidden}.drawer.open{transform:translate(0)}.drawer-list{flex:1;min-height:0;overflow-y:auto}.drawer-logout{flex:none;margin-top:8px;padding:10px;border:none;border-radius:6px;background:#2e2a2c;color:#ffb4b4;font-size:14px;touch-action:manipulation}.drawer-logout:active{background:#4a2f33}.drawer-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;background:#0006;z-index:9}.drawer-title{font-size:12px;color:#888;letter-spacing:1px;margin-bottom:8px}.drawer-row{display:flex;align-items:center;gap:6px;border-radius:6px}.drawer-name{flex:1;min-width:0;padding:8px 4px;cursor:pointer;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.drawer-session.active{background:#4a7cff;color:#fff}.drawer-unbind{flex:none;background:none;border:none;color:#888;font-size:14px;padding:6px 8px;touch-action:manipulation}.drawer-session.active .drawer-unbind{color:#d6e4ff}.drawer-empty{padding:12px 4px;color:#888;font-size:13px}.drawer-bind{width:100%;margin-top:8px;padding:10px;border:none;border-radius:6px;background:#2b3550;color:#cdddff;font-size:14px;touch-action:manipulation}.drawer-bind:active{background:#344168}.token-prompt{max-width:360px;margin:80px auto;display:flex;flex-direction:column;gap:12px;padding:0 16px}.token-prompt input{padding:10px;border-radius:6px;border:1px solid #444;background:#1a1b1e;color:#fff}.loading{padding:40px;text-align:center;color:#888}.empty-cta{margin:auto;display:flex;flex-direction:column;gap:6px;align-items:center;padding:28px 32px;background:none;border:1px dashed #44464c;border-radius:12px;color:#aab;font-size:15px;touch-action:manipulation}.empty-cta span{font-size:13px;color:#6f7bff}.empty-cta:active{background:#232427}.bottom-dock{display:flex;gap:8px;padding:8px;background:#2a2b2e;align-items:stretch}.dock-left{flex:1;min-width:0;display:flex;flex-direction:column;gap:6px}.keyrow{display:flex;align-items:stretch;gap:6px}.keyrow .keybar{flex:1;min-width:0}.keyrow-stack{flex:none;width:66px;display:flex;flex-direction:column;gap:4px}.keyrow-del,.keyrow-enter{flex:1;width:100%;min-height:40px;border:none;border-radius:6px;background:#33353a;color:#e6e6e6;touch-action:manipulation;-webkit-user-select:none;user-select:none}.keyrow-del{font:19px/1 ui-monospace,SF Mono,Menlo,monospace}.keyrow-enter{font-size:15px}.keyrow-del:active,.keyrow-enter:active{background:#4a7cff;color:#fff}.keybar{display:flex}.keybar-scroll{flex:1;display:flex;gap:4px;overflow-x:auto;overflow-y:hidden;-webkit-overflow-scrolling:touch;touch-action:pan-x;scrollbar-width:none}.keybar-scroll::-webkit-scrollbar{display:none}.keybar-col{display:flex;flex-direction:column;gap:4px}.keybar-key{flex:1;min-width:42px;min-height:34px;padding:0 8px;border:none;border-radius:6px;white-space:nowrap;background:#33353a;color:#e6e6e6;font:13px/1 ui-monospace,SF Mono,Menlo,monospace;touch-action:manipulation;-webkit-user-select:none;user-select:none}.keybar-key:active{background:#4a7cff;color:#fff}.keybar-key[data-key=esc],.keybar-key[data-key=tab],.keybar-key[data-key=up],.keybar-key[data-key=down]{min-width:52px}.dock-input-row{display:flex;gap:6px;align-items:stretch}.input-wrap{position:relative;flex:1;min-width:0;display:flex;align-items:flex-end;gap:2px;padding:4px;border:1px solid #444;border-radius:6px;background:#1a1b1e}.input-wrap:focus-within{border-color:#07c160;box-shadow:0 0 0 1px #07c16073}.input-upload{flex:none;width:34px;height:34px;display:inline-flex;align-items:center;justify-content:center;border:none;border-radius:6px;background:transparent;color:#8a93a0;padding:0;touch-action:manipulation;-webkit-user-select:none;user-select:none}.input-upload:active{color:#4a7cff}.input-upload:disabled{opacity:.4}.input-upload svg{width:22px;height:22px;display:block}.dock-upload{padding:6px 4px 2px}.dock-upload-label{display:block;color:#9fb6d0;font-size:12px;margin-bottom:4px;font-variant-numeric:tabular-nums}.dock-upload.error .dock-upload-label{color:#ff8a8a}.dock-upload-track{display:block;height:4px;border-radius:2px;background:#1c2b3a;overflow:hidden}.dock-upload-fill{display:block;height:100%;background:#3a5a7e;transition:width .1s linear}.input-send{flex:none;width:34px;height:34px;display:inline-flex;align-items:center;justify-content:center;border:none;border-radius:50%;background:#4a7cff;color:#fff;padding:0;touch-action:manipulation;-webkit-user-select:none;user-select:none}.input-send:active{background:#3a66e0}.input-send:disabled{background:#3a3c42;color:#6b7280}.input-send svg{width:20px;height:20px;display:block}.input-cmd{flex:none;width:34px;height:34px;display:inline-flex;align-items:center;justify-content:center;border:none;border-radius:6px;background:transparent;color:#8a93a0;padding:0;touch-action:manipulation;-webkit-user-select:none;user-select:none}.input-cmd svg{width:20px;height:20px;display:block}.input-cmd:active{color:#4a7cff}.input-wrap.recording{background:#07c16024;border:2px solid #07c160;animation:rec-breathe 1.3s ease-in-out infinite}.input-wrap.recording .input-text{color:#eafff3}@keyframes rec-breathe{0%,to{box-shadow:0 0 5px #07c1604d;border-color:#2fd07e}50%{box-shadow:0 0 16px 4px #07c160cc;border-color:#07c160}}.input-mic{flex:none;width:34px;height:34px;display:inline-flex;align-items:center;justify-content:center;border:none;border-radius:50%;background:#00000040;color:#b6c0cc;padding:0;touch-action:manipulation;-webkit-user-select:none;user-select:none}.input-mic.on{color:#fff;background:#07c160}.input-mic:disabled{opacity:.5}.input-mic svg{width:21px;height:21px;display:block}.cmd-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;background:#00000080;z-index:21}.cmd-panel{position:fixed;left:0;right:0;bottom:0;z-index:22;max-height:72vh;display:flex;flex-direction:column;background:#232427;border-radius:12px 12px 0 0;box-shadow:0 -8px 30px #00000080}.cmd-head{display:flex;align-items:center;gap:8px;padding:12px 14px;border-bottom:1px solid #33353a}.cmd-title{font-size:15px;font-weight:600;margin-right:auto;display:flex;align-items:center;gap:7px}.idea-head-count{font-size:11px;font-weight:600;color:#a8c4e0;background:#3d5068;border-radius:6px;padding:1px 6px}.cmd-close{background:none;border:none;color:#aaa;padding:4px 8px;touch-action:manipulation;display:inline-flex;align-items:center}.cmd-close svg{width:16px;height:16px;display:block}.cmd-list{overflow-y:auto;-webkit-overflow-scrolling:touch;padding:6px 0 10px}.cmd-section{display:flex;align-items:baseline;gap:8px;padding:9px 14px 5px}.cmd-section.recent{margin-top:6px;border-top:1px solid #2c2e33;padding-top:12px}.cmd-section-name{font-size:12px;font-weight:700;letter-spacing:1px}.cmd-section.fav .cmd-section-name{color:#ffd27a}.cmd-section.recent .cmd-section-name{color:#9db8ff}.cmd-scope{margin-left:auto;font-size:10px;color:#9a9a9a;background:#2c2e33;padding:2px 8px;border-radius:10px;white-space:nowrap}.cmd-row{display:flex;align-items:center;gap:6px;padding:0 8px 0 14px}.cmd-text{flex:1;min-width:0;padding:9px 0;font:13px/1.3 ui-monospace,SF Mono,Menlo,monospace;color:#e6e6e6;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;touch-action:manipulation}.cmd-text:active{color:#9db8ff}.cmd-star{flex:none;background:none;border:none;color:#667;padding:6px 8px;touch-action:manipulation;display:inline-flex;align-items:center}.cmd-star svg{width:16px;height:16px;display:block}.cmd-star.on{color:#ffd27a}.cmd-star.on svg{fill:currentColor}.cmd-del{flex:none;background:none;border:none;color:#888;padding:6px 8px;touch-action:manipulation;display:inline-flex;align-items:center}.cmd-del svg{width:14px;height:14px;display:block}.cmd-empty{padding:20px 14px;color:#888;font-size:13px;text-align:center}.idea-panel{position:fixed;left:0;right:0;bottom:0;z-index:22;min-height:50vh;max-height:80vh;display:flex;flex-direction:column;background:#232427;border-radius:12px 12px 0 0;box-shadow:0 -8px 30px #00000080}.idea-compose{display:flex;align-items:flex-end;gap:8px;padding:10px 14px;border-bottom:1px solid #33353a}.idea-input{flex:1;min-width:0;resize:none;max-height:96px;padding:8px 10px;border:1px solid #3a3c42;border-radius:8px;background:#1b1c1f;color:#e6e6e6;font:14px/1.4 -apple-system,system-ui,sans-serif}.idea-input:focus{outline:none;border-color:#5b78d6}.idea-compose .input-mic{position:static;right:auto;bottom:auto;flex:none}.idea-act{flex:none;width:34px;height:34px;display:inline-flex;align-items:center;justify-content:center;border:none;border-radius:50%;background:#3a6df0;color:#fff;padding:0;touch-action:manipulation}.idea-act:disabled{background:#00000040;color:#b6c0cc;opacity:.55}.idea-act svg{width:20px;height:20px;display:block}.idea-cancel{flex:none;background:none;border:none;color:#aaa;font-size:13px;padding:9px 4px;touch-action:manipulation}.idea-list{flex:1;overflow-y:auto;-webkit-overflow-scrolling:touch;padding:6px 0 12px}.idea-list:has(.cmd-empty){display:flex;align-items:center;justify-content:center}.idea-row{display:flex;align-items:center;gap:6px;padding:0 8px 0 4px;background:#232427}.idea-row.editing{background:#262a31}.idea-row.dragging{background:#2c2f36;border-radius:8px;box-shadow:0 2px 12px #00000073}.idea-handle{flex:none;background:none;border:none;color:#777;font-size:20px;line-height:1;padding:11px 16px;cursor:grab;touch-action:none;-webkit-user-select:none;user-select:none}.idea-text{flex:1;min-width:0;padding:11px 0;font-size:14px;line-height:1.35;color:#e6e6e6;white-space:pre-wrap;overflow-wrap:anywhere;touch-action:manipulation}.idea-text:active{color:#9db8ff}.idea-send{flex:none;background:#2c2e33;color:#9db8ff;border:none;border-radius:6px;padding:6px 10px;font-size:13px;touch-action:manipulation}.idea-del{flex:none;background:none;border:none;color:#888;font-size:14px;padding:6px 8px;touch-action:manipulation}.changelog-panel{position:fixed;left:0;right:0;bottom:0;z-index:22;max-height:80vh;display:flex;flex-direction:column;background:#232427;border-radius:12px 12px 0 0;box-shadow:0 -8px 30px #00000080}.changelog-list{overflow-y:auto;-webkit-overflow-scrolling:touch;padding:6px 16px 16px}.rel{padding:12px 0;border-bottom:1px solid #2c2e33}.rel:last-child{border-bottom:none}.rel-date{font-size:12px;font-weight:700;letter-spacing:.5px;color:#9db8ff;margin-bottom:6px}.rel-items{margin:0;padding-left:18px}.rel-items li{font-size:13px;line-height:1.5;color:#e6e6e6;margin:3px 0}.topbar-icon{position:relative}.topbar-dot{position:absolute;top:4px;right:4px;width:7px;height:7px;border-radius:50%;background:#ff5a52;box-shadow:0 0 0 2px #1b1c1f}.idea-badge{position:absolute;top:2px;right:1px;min-width:14px;height:14px;border-radius:7px;padding:0 3px;box-sizing:border-box;background:#3d5068;color:#a8c4e0;font-size:9px;font-weight:700;line-height:14px;text-align:center;pointer-events:none}.settings-dot{display:inline-block;width:7px;height:7px;margin-left:6px;border-radius:50%;background:#ff5a52;vertical-align:middle}.sheet-actions{display:flex;flex-direction:column;gap:8px}.sheet-action{width:100%;padding:12px;border:1px solid #33353a;border-radius:6px;background:#2a2c31;color:#ddd;font-size:15px;text-align:center;touch-action:manipulation}.sheet-action.danger{color:#ff8585}.sheet-action.armed{background:#ff8585;color:#fff;border-color:#ff8585}.sheet-action:disabled{opacity:.4}.sheet-row{display:flex;gap:8px}.sheet-row .sheet-action{flex:1}.sheet-cancel{margin-top:4px}.win-tab,.session-name{-webkit-user-select:none;user-select:none;-webkit-touch-callout:none}.file-sheet{position:fixed;top:0;right:0;bottom:0;left:0;z-index:50;display:flex;flex-direction:column;background:#0b0f14;transform:translateY(100%);transition:transform .28s cubic-bezier(.22,.61,.36,1);pointer-events:none}.file-sheet.open{transform:translateY(0);pointer-events:auto}.file-tabs{display:flex;align-items:stretch;border-bottom:1px solid #1d2630;background:#11161d}.file-tabs-scroll{display:flex;overflow-x:auto;flex:1;-webkit-overflow-scrolling:touch}.file-tab{display:inline-flex;align-items:center;white-space:nowrap;border-right:1px solid #1d2630}.file-tab.active{background:#0b0f14;box-shadow:inset 0 -2px #4aa3ff}.file-tab-label{display:inline-flex;align-items:center;gap:5px;padding:10px 8px 10px 12px;background:transparent;border:none;color:#9fb0c0;font-size:13px}.file-tab-label svg{width:15px;height:15px}.file-tab.active .file-tab-label{color:#e6edf3}.file-tab-x{background:transparent;border:none;color:#6b7a89;font-size:11px;padding:0 10px 0 2px}.file-min{flex:0 0 auto;width:44px;display:inline-flex;align-items:center;justify-content:center;background:transparent;color:#9fb0c0;border:none;border-left:1px solid #1d2630}.file-min svg{width:20px;height:20px}.file-body{flex:1;overflow:hidden;display:flex}.preview-frame{flex:1;width:100%;border:0;background:#fff}.preview-body.pc{display:block;position:relative;overflow:auto;-webkit-overflow-scrolling:touch}.preview-scaler{position:relative}.preview-body.pc .preview-frame{position:absolute;top:0;left:0;flex:none}.preview-zoom{position:absolute;bottom:14px;left:50%;transform:translate(-50%);z-index:2;display:flex;align-items:center;gap:2px;padding:4px;background:#1c1e22eb;border:1px solid #3a3c42;border-radius:999px;box-shadow:0 6px 20px #00000073}.preview-zoom-btn{width:34px;height:30px;display:inline-flex;align-items:center;justify-content:center;background:transparent;border:none;color:#e6edf3;font-size:20px;line-height:1;border-radius:999px;touch-action:manipulation}.preview-zoom-btn:disabled{color:#5a626b}.preview-zoom-val{min-width:46px;text-align:center;color:#9fb0c0;font-size:13px;font-variant-numeric:tabular-nums}.preview-head{position:relative;align-items:center;gap:4px;min-height:44px;padding-left:10px}.preview-status{display:inline-flex;align-items:center;gap:5px;min-width:0;color:#e6edf3;font-size:12px}.preview-status svg{width:15px;height:15px;flex:0 0 auto}.preview-state{color:#3fb950;font-weight:600;flex:0 0 auto}.preview-name{color:#9fb0c0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}.preview-detail{color:#6e7d8c;margin-left:6px}.preview-remain{margin-left:auto;flex:0 0 auto;font-variant-numeric:tabular-nums;color:#9fb0c0;font-size:12px;padding:4px 8px;background:transparent;border:1px solid #33353a;border-radius:6px;touch-action:manipulation}.preview-remain:active{color:#4aa3ff;border-color:#4aa3ff}.preview-pop-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:5}.preview-pop{position:absolute;top:46px;right:8px;z-index:6;min-width:168px;display:flex;flex-direction:column;gap:2px;padding:6px;background:#232427;border:1px solid #33353a;border-radius:10px;box-shadow:0 10px 30px #00000080}.preview-pop-item{background:transparent;border:none;color:#e6edf3;text-align:left;padding:10px 12px;border-radius:6px;font-size:14px}.preview-pop-item:active{background:#2f3338}.preview-pop-danger{color:#ffb4b4}.preview-iconbtn{flex:0 0 auto;width:32px;display:inline-flex;align-items:center;justify-content:center;background:transparent;border:none;color:#9fb0c0;touch-action:manipulation}.preview-iconbtn svg{width:17px;height:17px}.preview-iconbtn:active{color:#4aa3ff}.preview-head .file-min{width:34px}.preview-head .file-min svg{width:18px;height:18px}.preview-confirm-backdrop{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;display:flex;align-items:center;justify-content:center;background:#00000080}.preview-confirm{width:min(86vw,320px);background:#232427;border-radius:12px;padding:16px;box-shadow:0 10px 40px #00000080}.preview-confirm-title{font-size:16px;font-weight:600;color:#e6edf3;margin-bottom:8px}.preview-confirm-text{font-size:13px;color:#9aa3ad;line-height:1.5;margin-bottom:14px}.preview-confirm-btns{display:flex;justify-content:flex-end;gap:8px}.preview-confirm-danger{background:#5a1f1f;color:#ffb4b4}.settings-group{margin:16px -16px 0;padding:7px 16px;background:#1b1c1f;color:#9aa3ad;font-size:11px;font-weight:700;letter-spacing:1.2px;border-top:1px solid #33353a;border-bottom:1px solid #33353a}.settings-head+.settings-group{margin-top:0}.settings-group+.settings-section{border-top:none}.preview-running{display:inline-flex;align-items:center;gap:6px;color:#3fb950;font-weight:600;font-size:13px}.live-dot{width:8px;height:8px;border-radius:50%;background:#3fb950}.preview-port{width:9em;padding:6px 10px;font-size:15px;color:#e8e8ea;background:#1b1c1f;border:1px solid #3a3c42;border-radius:8px}.preview-seg{display:inline-flex;align-self:flex-start;border:1px solid #3a3c42;border-radius:8px;overflow:hidden}.preview-seg button{background:transparent;border:none;color:#9aa3ad;padding:7px 18px;min-width:60px;font-size:14px;touch-action:manipulation}.preview-seg button+button{border-left:1px solid #3a3c42}.preview-seg button.on{background:#2f6df6;color:#fff}.preview-start{display:flex;flex-direction:column;gap:12px}.preview-active{display:flex;flex-direction:column;gap:10px}.preview-active-head{display:flex;align-items:center;gap:10px}.preview-remain-s{margin-left:auto;font-variant-numeric:tabular-nums;color:#9aa3ad;font-size:13px}.settings-err{color:#ff9d9d}.preview-live{color:#3fb950}.home-pane{flex:1;display:flex;flex-direction:column;min-width:0}.file-seg{display:flex;gap:8px;padding:10px 12px;border-bottom:1px solid #1d2630;background:#0e131a}.file-seg-btn{flex:1;display:inline-flex;align-items:center;justify-content:center;gap:6px;padding:9px;border-radius:8px;background:#11161d;border:1px solid #1d2630;color:#9fb0c0;font-size:14px}.file-seg-btn.on{background:#15212f;border-color:#2f6fc0;color:#cfe0f2}.file-seg-btn svg{width:16px;height:16px}.git-head{align-items:stretch;min-height:42px}.git-back{flex:0 0 auto;width:40px;align-self:stretch;display:inline-flex;align-items:center;justify-content:center;background:transparent;border:none;color:#9fb0c0;font-size:26px;line-height:1}.git-drill-head{flex:1;min-width:0;display:flex;align-items:center;gap:4px;overflow:hidden}.git-drill-title{display:inline-flex;align-items:center;gap:7px;min-width:0;color:#e6edf3;font-size:14px}.git-drill-title svg{width:16px;height:16px;color:#6b86a3;flex:0 0 auto}.git-title-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.git-tabs-scroll{display:flex;align-items:stretch;overflow-x:auto;flex:1;-webkit-overflow-scrolling:touch}.git-tab-add{flex:0 0 auto;width:40px;display:inline-flex;align-items:center;justify-content:center;background:transparent;border:none;border-right:1px solid #1d2630;color:#8fb2dc;font-size:20px;line-height:1}.git-tab{flex:0 0 auto;display:inline-flex;align-items:center;white-space:nowrap;border-right:1px solid #1d2630}.git-tab.active{background:#0b0f14;box-shadow:inset 0 -2px #4aa3ff}.git-tab-label{display:inline-flex;align-items:center;padding:10px 4px 10px 12px;background:transparent;border:none;color:#9fb0c0;font-size:13px}.git-tab.active .git-tab-label{color:#e6edf3}.git-tab-x{background:transparent;border:none;color:#6b7a89;font-size:11px;padding:0 10px 0 4px;align-self:stretch}.git-branch-bar{display:flex;align-items:center;gap:10px;padding:7px 12px 7px 14px;border-bottom:1px solid #1d2630;background:#0b0f14;font-size:13px}.git-branch-bar-name{flex:1;min-width:0;color:#cfe0f2;font-weight:600;display:flex;align-items:center;gap:6px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.git-branch-glyph{color:#8fb2dc}.git-branch-cur-tag{flex:0 0 auto;font-size:11px;font-weight:600;color:#3fb950;background:#3fb9501f;border:1px solid rgba(63,185,80,.4);border-radius:999px;padding:1px 7px}.git-branch-bar-track{flex:0 0 auto;font-size:12px;font-variant-numeric:tabular-nums;display:flex;gap:5px}.git-branch-dd{position:relative;flex:0 0 auto}.git-branch-trigger{max-width:46vw;display:flex;align-items:center;gap:5px;background:#11161d;border:1px solid #1d2630;border-radius:8px;color:#9fb0c0;font-size:12px;padding:5px 9px}.git-branch-trigger.other{border-color:#2f6fc0;background:#15212f;color:#cfe0f2}.git-branch-trigger-name{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.git-branch-caret{flex:0 0 auto;display:inline-flex;color:#6b7a89}.git-branch-caret svg{width:13px;height:13px}.git-dd-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:40}.git-dd-menu{position:absolute;top:calc(100% + 6px);right:0;z-index:41;min-width:56vw;max-width:calc(100vw - 24px);max-height:56vh;overflow:auto;-webkit-overflow-scrolling:touch;background:#0e141b;border:1px solid #243040;border-radius:10px;box-shadow:0 10px 28px #00000080;padding:4px}.git-dd-item{display:flex;align-items:center;gap:8px;width:100%;text-align:left;background:transparent;border:none;color:#e6edf3;padding:10px;font-size:13px;border-radius:7px}.git-dd-item:active{background:#15212f}.git-dd-item.viewing{background:#15212f;box-shadow:inset 3px 0 #2f6fc0}.git-dd-item.current .git-row-path{color:#cfe0f2;font-weight:600}.git-section{display:flex;flex-direction:column;min-height:0;border-bottom:1px solid #161d26}.git-section:not(.open){flex:0 0 auto}.git-section.open.git-section--top{flex:0 1 auto;min-height:25%;max-height:50%}.git-section.open.git-section--mid{flex:1 1 0;min-height:96px}.git-section-head{flex:0 0 auto;display:flex;align-items:center;gap:8px;width:100%;text-align:left;background:#0b0f14;border:none;color:#9fb0c0;padding:10px 14px;font-size:13px;font-weight:600}.git-section-head:active{background:#11161d}.git-section-caret{flex:0 0 auto;display:inline-flex;color:#6b7a89;transition:transform .15s;transform:rotate(-90deg)}.git-section.open .git-section-caret{transform:rotate(0)}.git-section-caret svg{width:14px;height:14px}.git-section-title{flex:0 0 auto}.git-section-sub{flex:1;min-width:0;color:#6b7a89;font-weight:400;font-size:12px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.git-section-count{flex:0 0 auto;margin-left:auto;color:#6b7a89;font-weight:400;font-size:12px;font-variant-numeric:tabular-nums}.git-section-sub+.git-section-count{margin-left:8px}.git-section-body{flex:1;min-height:0;overflow:auto;-webkit-overflow-scrolling:touch}.git-more{text-align:center;color:#6b7a89;font-size:12px;padding:12px}.git-body{flex:1;min-height:0;display:flex;flex-direction:column;overflow:hidden;padding-bottom:var(--kb-inset, 0px)}.git-scroll{flex:1;min-height:0;overflow:auto;-webkit-overflow-scrolling:touch}.git-error{color:#ff9d9d;font-size:13px;padding:14px 16px}.git-loading,.git-empty{color:#6b7a89;font-size:13px;padding:16px}.git-list{display:flex;flex-direction:column}.git-row{display:flex;align-items:center;gap:9px;width:100%;text-align:left;background:transparent;border:none;border-bottom:1px solid #161d26;color:#e6edf3;padding:11px 14px;font-size:13px}.git-row:active{background:#11161d}.git-row-path{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0;flex:1}.git-badge{flex:0 0 auto;width:20px;text-align:center;font-size:12px;font-weight:600;font-variant-numeric:tabular-nums;color:#9aa3ad}.git-badge-m{color:#d8a13a}.git-badge-a{color:#3fb950}.git-badge-d{color:#f06b6b}.git-badge-r{color:#8fb2dc}.git-badge-q{color:#6b7a89}.git-commit-row{align-items:flex-start}.git-hash{flex:0 0 auto;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;color:#8fb2dc;font-size:12px;padding-top:1px}.git-commit-main{display:flex;flex-direction:column;gap:3px;min-width:0;flex:1}.git-commit-meta{color:#6b7a89;font-size:11px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.git-branch{gap:8px}.git-branch.current .git-row-path{color:#cfe0f2;font-weight:600}.git-branch.viewing{background:#11161d;box-shadow:inset 3px 0 #2f6fc0}.git-branch-dot{flex:0 0 auto;width:12px;text-align:center;color:#3fb950;font-size:11px}.git-branch-up{flex:0 0 auto;color:#6b7a89;font-size:11px;font-variant-numeric:tabular-nums}.git-ahead{color:#3fb950}.git-behind{color:#f06b6b}.git-commit-detail{display:flex;flex-direction:column}.git-commit-msg{white-space:pre-wrap;word-break:break-word;margin:0;padding:14px 16px;color:#c9d6e2;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:12px;line-height:1.5;border-bottom:1px solid #161d26;background:#0e131a}.git-diff-wrap{display:flex;flex-direction:column}.git-diff-zoom{position:sticky;top:0;z-index:2;display:flex;gap:6px;justify-content:flex-end;padding:8px 12px}.git-diff-trunc{position:sticky;top:0;z-index:1;background:#3a2a12;color:#f0c674;font-size:12px;padding:8px 14px;border-bottom:1px solid #5a4318}.git-diff-fname{padding:10px 14px 6px;color:#9fb0c0;font-size:12px;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}.git-diff{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:inherit;line-height:1.5;white-space:pre;overflow-x:auto;-webkit-overflow-scrolling:touch}.git-diff-line{padding:0 14px;min-width:max-content}.git-diff-hunk{color:#6b86a3;background:#0e131a}.git-diff-add{background:#3fb95029;color:#c7f0cf}.git-diff-del{background:#f06b6b29;color:#f3cccc}.git-diff-ctx{color:#c9d6e2}.home-view{flex:1;overflow:auto;-webkit-overflow-scrolling:touch;padding:12px;color:#c9d6e2}.home-empty{color:#6b7a89;font-size:13px;display:flex;flex-direction:column;gap:4px;padding:16px 4px}.home-empty span{color:#4a5663;font-size:12px}.home-recent-row{display:flex;align-items:center;width:100%}.home-recent{flex:1;display:flex;flex-direction:column;align-items:flex-start;background:#11161d;border:1px solid #1d2630;border-radius:8px;padding:8px 10px;margin-bottom:6px;color:#e6edf3;text-align:left}.home-path{font-size:11px;color:#6b7a89;overflow:hidden;text-overflow:ellipsis;max-width:80vw}.home-x{background:transparent;border:none;color:#6b7a89;padding:0 8px}.browse-view{flex:1;display:flex;flex-direction:column;min-height:0;position:relative}.browse-bar{display:flex;align-items:center;gap:8px;padding:10px 12px;border-bottom:1px solid #1d2630;background:#0e131a}.browse-root-dd{flex:0 0 auto}.browse-root{display:inline-flex;align-items:center;gap:3px;padding:9px 4px 9px 10px;background:transparent;border:none;color:#6b86a3;font-size:13px}.browse-root .dd-caret{font-size:10px}.browse-root-dd .dd-menu{left:0;right:auto;min-width:120px}.browse-up{flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;width:38px;height:38px;background:#11161d;border:1px solid #1d2630;border-radius:8px;color:#9fb0c0}.browse-up:disabled{opacity:.4}.browse-up svg{width:18px;height:18px}.browse-cwd{flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;width:38px;height:38px;background:#11161d;border:1px solid #1d2630;border-radius:8px;color:#9fb0c0}.browse-cwd svg{width:18px;height:18px}.browse-path{flex:1;min-width:0;display:flex;align-items:center;border-radius:8px;border:1px solid #243446;background:#11161d}.browse-path:focus-within{border-color:#3a5a7e}.browse-input:focus{outline:none}.browse-home{flex:0 0 auto;padding:9px 2px 9px 10px;color:#6b86a3;font-size:13px;-webkit-user-select:none;user-select:none}.browse-input{flex:1;min-width:0;padding:9px 10px 9px 0;border:none;border-radius:8px;background:transparent;color:#e6edf3;font-size:13px}.browse-err{padding:8px 12px 0}.browse-notice{position:absolute;left:50%;bottom:16px;transform:translate(-50%);z-index:6;max-width:88%;width:max-content;padding:9px 14px;border-radius:10px;background:#1c1e22f7;color:#d3dbe4;font-size:13px;line-height:1.4;box-shadow:0 6px 24px #00000080;pointer-events:none;word-break:break-all}.browse-saved{display:flex;align-items:center;gap:10px;margin:8px 12px 0;padding:8px 10px;border:1px solid #2a3f56;border-radius:8px;background:#15212e}.browse-saved-text{flex:1;min-width:0;color:#cfe0f0;font-size:13px}.browse-saved-close{flex:0 0 auto;width:32px;height:32px;border:none;border-radius:8px;background:transparent;color:#8aa0b6;font-size:20px;line-height:1}.browse-pending{display:flex;align-items:center;gap:10px;margin:8px 12px 0;padding:8px 10px;border:1px solid #2a3f56;border-radius:8px;background:#15212e}.browse-pending-text{flex:1;min-width:0;color:#cfe0f0;font-size:13px;overflow:hidden;text-overflow:ellipsis}.browse-pending-hint{color:#8aa0b6;font-style:normal;font-size:12px}.browse-pending-btn{flex:0 0 auto;height:32px;padding:0 14px;border:none;border-radius:8px;background:#2f5fa0;color:#fff;font-size:13px}.browse-pending-btn:disabled{opacity:.4}.browse-list{flex:1;overflow:auto;-webkit-overflow-scrolling:touch;padding:4px 12px 16px}.browse-empty{color:#6b7a89;font-size:13px;padding:16px 4px}.browse-overflow{color:#6b7a89;font-size:12px;padding:12px 4px 16px;text-align:center}.browse-entry{display:flex;align-items:center;gap:9px;width:100%;background:transparent;border:none;border-bottom:1px solid #161d26;color:#e6edf3;padding:11px 4px;text-align:left}.browse-entry-icon{flex:0 0 auto;display:inline-flex;color:#6b86a3}.browse-entry-icon svg{width:17px;height:17px}.browse-entry-name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.browse-upload{flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;width:38px;height:38px;background:#11161d;border:1px solid #1d2630;border-radius:8px;color:#9fb0c0}.browse-upload:disabled{opacity:.4}.browse-upload svg{width:18px;height:18px}.browse-file-input{position:absolute;width:1px;height:1px;margin:-1px;padding:0;border:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}.browse-mkdir{flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;width:38px;height:38px;background:#11161d;border:1px solid #1d2630;border-radius:8px;color:#9fb0c0}.browse-mkdir:disabled{opacity:.4}.browse-mkdir svg{width:18px;height:18px}.browse-newfolder{display:flex;align-items:center;gap:8px;padding:8px 12px}.browse-newfolder-input{flex:1;min-width:0;padding:9px 10px;border-radius:8px;border:1px solid #243446;background:#11161d;color:#e6edf3;font-size:13px}.browse-newfolder-input:focus{outline:none;border-color:#3a5a7e}.browse-newfolder-ok{flex:0 0 auto;height:36px;padding:0 14px;border:none;border-radius:8px;background:#2f5fa0;color:#fff;font-size:13px;white-space:nowrap}.browse-newfolder-x{flex:0 0 auto;width:36px;height:36px;border:1px solid #1d2630;border-radius:8px;background:#11161d;color:#9fb0c0;font-size:15px;line-height:1}.browse-progress{padding:8px 12px 0}.browse-progress-label{display:block;color:#9fb6d0;font-size:12px;margin-bottom:4px;font-variant-numeric:tabular-nums}.browse-progress-track{display:block;height:4px;border-radius:2px;background:#1c2b3a;overflow:hidden}.browse-progress-fill{display:block;height:100%;background:#3a5a7e;transition:width .1s linear}.browse-entry-row{display:flex;align-items:center}.browse-entry-row .browse-entry{flex:1;min-width:0}.browse-entry-size{flex:0 0 auto;margin-left:auto;padding-left:8px;color:#6b7a89;font-size:12px;font-variant-numeric:tabular-nums}.browse-dl,.browse-copy{flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;width:36px;height:36px;border:none;background:none;color:#6b86a3;margin-left:4px}.browse-dl svg,.browse-copy svg{width:17px;height:17px}.browse-copy:active{color:#9db8ff}.browse-pick-bar{padding:8px;border-top:1px solid #1d2630}.browse-pick-confirm{width:100%;padding:10px;border:none;border-radius:8px;background:#4a7cff;color:#fff;font-size:14px}.dirpick-backdrop{z-index:30;background:#0000009e}.dirpick-card{width:min(92vw,520px);max-width:none;z-index:31;max-height:min(80vh,calc(100vh - var(--kb-inset, 0px) - 32px));display:flex;flex-direction:column}.dirpick-card .browse-view{flex:1;min-height:0}.dirpick-hint{font-size:12px;color:#9a9a9a;line-height:1.5;margin-bottom:10px;word-break:break-all}.dirpick-hint code{color:#d8c08a;background:#2c2e33;padding:1px 5px;border-radius:4px}.doc-md-wrap{position:relative;flex:1;min-width:0;overflow-y:auto;overflow-x:hidden;-webkit-overflow-scrolling:touch}.doc-zoom{position:sticky;top:0;z-index:1;display:flex;gap:6px;align-items:center;padding:8px 12px 0}.doc-tts{display:flex;gap:6px}.doc-fonts{display:flex;gap:6px;margin-left:auto}.doc-zoom-btn{display:inline-flex;align-items:center;justify-content:center;background:#11161d;border:1px solid #1d2630;color:#9fb0c0;border-radius:8px;padding:4px 12px;font-size:14px;touch-action:manipulation}.doc-zoom-btn:disabled{opacity:.4}.doc-zoom-icon{padding:4px 9px}.doc-zoom-icon svg{width:17px;height:17px;display:block}.tts-active{background:#4a7cff4d;border-radius:3px;box-decoration-break:clone;-webkit-box-decoration-break:clone}.doc-md{padding:16px;color:#e6edf3;line-height:1.6;word-wrap:break-word}.doc-md h1,.doc-md h2,.doc-md h3{border-bottom:1px solid #1d2630;padding-bottom:4px}.doc-md pre{background:#11161d;padding:12px;border-radius:8px;overflow:auto}.doc-md code{background:#11161d;padding:1px 4px;border-radius:4px}.doc-md a{color:#4aa3ff}.doc-md img{max-width:100%}.doc-md table{display:block;max-width:100%;overflow-x:auto;border-collapse:collapse}.doc-text{margin:0;padding:16px;color:#e6edf3;line-height:1.5;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;white-space:pre-wrap;word-break:break-word;overflow-wrap:anywhere}.doc-iframe{width:100%;height:100%;border:0;background:#fff}.doc-image-wrap{flex:1;min-height:0;overflow:hidden;position:relative;display:flex;align-items:center;justify-content:center;padding:8px;background:#1b1d22;touch-action:none;user-select:none;-webkit-user-select:none}.doc-image{max-width:100%;max-height:100%;object-fit:contain;display:block;will-change:transform;-webkit-touch-callout:none}.doc-image-msg{flex:1;display:flex;align-items:center;justify-content:center;color:#9fb0c0;font-size:14px}.doc-image-zoom{position:absolute;bottom:14px;left:50%;transform:translate(-50%);z-index:2;display:flex;align-items:center;gap:2px;padding:4px;background:#1c1e22eb;border:1px solid #3a3c42;border-radius:999px;box-shadow:0 6px 20px #00000073}.doc-image-zoom button{width:34px;height:30px;display:inline-flex;align-items:center;justify-content:center;background:transparent;border:none;color:#e6edf3;font-size:20px;line-height:1;border-radius:999px;touch-action:manipulation}.doc-image-zoom button:disabled{color:#5a626b}.doc-image-zoom-val{min-width:46px;text-align:center;color:#9fb0c0;font-size:13px;font-variant-numeric:tabular-nums}.doc-image-note{position:absolute;top:14px;left:50%;transform:translate(-50%);z-index:3;max-width:88%;padding:7px 14px;border-radius:999px;white-space:nowrap;background:#1c1e22f0;border:1px solid #3a3c42;color:#e6edf3;font-size:13px;box-shadow:0 6px 20px #00000073}.doclink-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:58}.doclink-pop{position:fixed;z-index:59;width:max-content;max-width:calc(100vw - 16px);background:#1b2330;border:1px solid #2c3a4e;border-radius:12px;padding:12px 14px;box-shadow:0 12px 32px #0000008c;color:#e6edf3}.doclink-name{display:flex;align-items:center;gap:7px;font-weight:600;font-size:14px}.doclink-name svg{width:17px;height:17px;color:#6cb4ff;flex:0 0 auto}.doclink-path{font-size:11px;color:#7d8da0;margin:5px 0 11px;word-break:break-all;max-width:72vw}.doclink-actions{display:flex;gap:8px;justify-content:flex-end}.doclink-actions button{border:1px solid #2c3a4e;background:#11161d;color:#c9d6e2;border-radius:8px;padding:7px 18px;font-size:14px}.doclink-open{background:#2563b0;border-color:#2f6fc0;color:#fff}.doc-deco{border-bottom:2px solid #6cb4ff;background:#4aa3ff38;border-radius:3px;box-sizing:border-box}.doc-toast{position:fixed;left:50%;bottom:24px;transform:translate(-50%);z-index:60;max-width:86vw;background:#2a1518;color:#ffd7d7;border:1px solid #5a2a2a;padding:10px 14px;border-radius:10px;font-size:13px;box-shadow:0 6px 20px #0006}.inbox-btn{position:relative}.inbox-dot{position:absolute;top:1px;right:1px;width:9px;height:9px;border-radius:50%;border:1.5px solid #2a2b2e}.inbox-dot.needs{background:#e0a020}.inbox-dot.done{background:#2e7d46}.inbox-dot.working{background:#2f6fed;animation:tw-blink 1s ease-in-out infinite}@media (prefers-reduced-motion: reduce){.inbox-dot.working{animation:none}}.inbox-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;background:#00000080;z-index:19}.inbox-panel{position:fixed;z-index:20;top:48px;right:8px;width:calc(100% - 32px);max-width:360px;max-height:70vh;overflow-y:auto;background:#232427;border-radius:12px;padding:8px;box-shadow:0 10px 40px #00000080}.inbox-group-title{font-size:12px;color:#888;letter-spacing:1px;padding:8px 8px 4px}.inbox-row{display:flex;flex-direction:column;gap:2px;width:100%;text-align:left;background:none;border:none;color:#e6e6e6;padding:8px;border-radius:8px;touch-action:manipulation}.inbox-row:active{background:#2f3034}.inbox-row-head{display:flex;align-items:center;gap:6px;min-width:0}.agent-mark{width:15px;height:15px;flex:none;display:inline-block;object-fit:contain}.win-tab .agent-mark{vertical-align:-2px;margin-right:4px}.inbox-chip{font-size:11px;padding:1px 6px;border-radius:4px;flex:none}.inbox-chip.needs{background:#e0a020;color:#111}.inbox-chip.done{background:#2e7d46;color:#fff}.inbox-chip.working{background:#2f6fed;color:#fff;animation:tw-blink 1s ease-in-out infinite}@keyframes tw-blink{50%{opacity:.4}}@media (prefers-reduced-motion: reduce){.inbox-chip.working{animation:none}}.inbox-head{display:flex;align-items:center;gap:8px;padding:2px 8px 8px;font-size:13px;color:#9aa0a6}.inbox-summary{display:flex;gap:4px;margin-left:auto}.inbox-summary .inbox-chip{animation:none;font-size:10px;padding:1px 5px}.inbox-readall{background:none;border:none;color:#4aa3ff;font-size:13px;padding:4px 6px;touch-action:manipulation}.inbox-loc{font-weight:600;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.inbox-time{margin-left:auto;font-size:11px;color:#888;flex:none}.inbox-msg{font-size:12px;color:#9aa0a6;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.inbox-empty{padding:24px 8px;text-align:center;color:#888;font-size:13px}.inbox-enable{display:flex;flex-direction:column;gap:8px;align-items:stretch;text-align:left}.inbox-enable-title{font-weight:600;color:#e8eaed;font-size:14px}.inbox-enable-hint{color:#9aa0a6;font-size:12px;line-height:1.4}.inbox-enable-btn{margin-top:2px;padding:8px 12px;border:none;border-radius:8px;background:#2f6fed;color:#fff;font-size:13px;touch-action:manipulation}.inbox-enable-btn:disabled{opacity:.6}.inbox-enable-err{color:#e06b5e;font-size:12px}.drawer-orphans{border-top:1px solid #34353a;margin-top:10px;padding-top:6px}.drawer-orphans-head{display:flex;align-items:center;width:100%;gap:6px;background:none;border:none;color:#888;font-size:12px;letter-spacing:1px;padding:6px 4px;text-align:left;touch-action:manipulation}.drawer-orphans-caret{margin-left:auto}.drawer-orphans-hint{color:#777;font-size:11px;padding:0 4px 4px}.drawer-orphan-row{padding:6px 4px}.drawer-orphan-row+.drawer-orphan-row{border-top:1px solid #2a2b2f}.drawer-orphan-head{display:flex;align-items:center;gap:6px}.drawer-orphan-cwd{flex:1;min-width:0;color:#cdddff;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.drawer-orphan-btn{flex:none;padding:4px 10px;border:none;border-radius:6px;background:#2b3550;color:#cdddff;font-size:13px;touch-action:manipulation}.drawer-orphan-btn:active{background:#344168}.drawer-orphan-btn:disabled{opacity:.45}.drawer-orphan-meta{display:flex;align-items:center;gap:6px;margin-top:2px;min-width:0}.drawer-orphan-agent{flex:none;font-size:10px;padding:0 5px;border-radius:3px;background:#333a45;color:#c7ccd1}.drawer-orphan-state{flex:none;font-size:10px;padding:0 5px;border-radius:3px}.drawer-orphan-state.idle{background:#2e7d46;color:#fff}.drawer-orphan-state.busy{background:#2f6fed;color:#fff}.drawer-orphan-time{flex:none;font-size:11px;color:#888}.drawer-orphan-msg{flex:1;min-width:0;font-size:11px;color:#9aa0a6;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.orphan-targets{display:flex;flex-wrap:wrap;gap:6px}.orphan-targets .fontbtn[aria-pressed=true]{background:#2f6fed;color:#fff;border-color:#2f6fed}.orphan-reco{margin-left:6px;font-size:10px;color:#7ee0a0}.orphan-targets .fontbtn[aria-pressed=true] .orphan-reco{color:#d6f5e3}.orphan-help{font-size:11px;color:#9aa0a6;line-height:1.5;margin-top:6px}
|
|
32
|
+
*/.xterm{cursor:text;position:relative;user-select:none;-ms-user-select:none;-webkit-user-select:none}.xterm.focus,.xterm:focus{outline:none}.xterm .xterm-helpers{position:absolute;top:0;z-index:5}.xterm .xterm-helper-textarea{padding:0;border:0;margin:0;position:absolute;opacity:0;left:-9999em;top:0;width:0;height:0;z-index:-5;white-space:nowrap;overflow:hidden;resize:none}.xterm .composition-view{background:#000;color:#fff;display:none;position:absolute;white-space:nowrap;z-index:1}.xterm .composition-view.active{display:block}.xterm .xterm-viewport{background-color:#000;overflow-y:scroll;cursor:default;position:absolute;right:0;left:0;top:0;bottom:0}.xterm .xterm-screen{position:relative}.xterm .xterm-screen canvas{position:absolute;left:0;top:0}.xterm .xterm-scroll-area{visibility:hidden}.xterm-char-measure-element{display:inline-block;visibility:hidden;position:absolute;top:0;left:-9999em;line-height:normal}.xterm.enable-mouse-events{cursor:default}.xterm.xterm-cursor-pointer,.xterm .xterm-cursor-pointer{cursor:pointer}.xterm.column-select.focus{cursor:crosshair}.xterm .xterm-accessibility:not(.debug),.xterm .xterm-message{position:absolute;left:0;top:0;bottom:0;right:0;z-index:10;color:transparent;pointer-events:none}.xterm .xterm-accessibility-tree:not(.debug) *::selection{color:transparent}.xterm .xterm-accessibility-tree{-webkit-user-select:text;user-select:text;white-space:pre}.xterm .live-region{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}.xterm-dim{opacity:1!important}.xterm-underline-1{text-decoration:underline}.xterm-underline-2{text-decoration:double underline}.xterm-underline-3{text-decoration:wavy underline}.xterm-underline-4{text-decoration:dotted underline}.xterm-underline-5{text-decoration:dashed underline}.xterm-overline{text-decoration:overline}.xterm-overline.xterm-underline-1{text-decoration:overline underline}.xterm-overline.xterm-underline-2{text-decoration:overline double underline}.xterm-overline.xterm-underline-3{text-decoration:overline wavy underline}.xterm-overline.xterm-underline-4{text-decoration:overline dotted underline}.xterm-overline.xterm-underline-5{text-decoration:overline dashed underline}.xterm-strikethrough{text-decoration:line-through}.xterm-screen .xterm-decoration-container .xterm-decoration{z-index:6;position:absolute}.xterm-screen .xterm-decoration-container .xterm-decoration.xterm-decoration-top-layer{z-index:7}.xterm-decoration-overview-ruler{z-index:8;position:absolute;top:0;right:0;pointer-events:none}.xterm-decoration-top{z-index:2;position:relative}*{box-sizing:border-box}@font-face{font-family:JetBrainsMono Nerd Font;src:url(/fonts/JetBrainsMonoNerdFontMono-Regular.woff2) format("woff2");font-weight:400;font-style:normal;font-display:swap}@font-face{font-family:TW Unifont;src:url(/fonts/TWUnifont.woff2) format("woff2");font-weight:400;font-style:normal;font-display:swap;unicode-range:U+2190-21FF,U+2300-23FF,U+2400-243F,U+2500-257F,U+2580-259F,U+25A0-25FF,U+2600-26FF,U+2700-27BF,U+2800-28FF,U+2B00-2BFF}html,body,#root{height:100%;margin:0;overscroll-behavior:none}body{font-family:-apple-system,system-ui,sans-serif;background:#1a1b1e;color:#e6e6e6}.app{display:flex;flex-direction:column;height:100%;overflow:hidden}.topbar{display:flex;align-items:center;gap:12px;padding:8px 12px;background:#2a2b2e}.hamburger{font-size:20px;background:none;border:none;color:#e6e6e6}.session-name{font-weight:600;margin-right:auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.fontbtn{min-width:36px;padding:4px 10px;border:none;border-radius:6px;background:#33353a;color:#e6e6e6;font-size:14px;touch-action:manipulation}.fontbtn[aria-pressed=true]{background:#2a4060;color:#7ab4f5}.topbar-icon{display:inline-flex;align-items:center;padding:4px;border:none;background:none;color:#e6e6e6;touch-action:manipulation}.topbar-icon:active{color:#4aa3ff}.topbar-icon svg{width:21px;height:21px;display:block}.settings-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;background:#00000080;z-index:19}.settings-card{position:fixed;z-index:20;left:50%;top:50%;transform:translate(-50%,-50%);width:calc(100% - 48px);max-width:360px;background:#232427;border-radius:12px;padding:16px;box-shadow:0 10px 40px #00000080}.settings-head{display:flex;align-items:center;margin-bottom:12px}.settings-title{font-size:16px;font-weight:600;margin-right:auto}.settings-close{background:none;border:none;color:#aaa;font-size:16px;padding:4px 8px;touch-action:manipulation}.settings-section{padding:10px 0;border-top:1px solid #33353a}.settings-label{font-size:12px;color:#888;letter-spacing:1px;margin-bottom:8px}.settings-btns{display:flex;align-items:center;gap:8px;flex-wrap:wrap}.lang-drop{position:relative;display:inline-block}.lang-drop-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1}.lang-trigger{display:flex;align-items:center;gap:8px;padding:5px 10px;background:#33353a;border:none;border-radius:6px;color:#e6e6e6;font-size:14px;touch-action:manipulation;cursor:pointer}.lang-chevron{font-size:11px;color:#888}.lang-menu{position:absolute;top:calc(100% + 4px);left:0;min-width:100%;background:#2a2c30;border-radius:8px;box-shadow:0 4px 20px #00000080;z-index:2;overflow:hidden}.lang-option{display:block;width:100%;padding:9px 14px;border:none;background:none;color:#e6e6e6;font-size:14px;text-align:left;touch-action:manipulation;white-space:nowrap}.lang-option:active{background:#33353a}.lang-option.active{color:#7ab4f5}.settings-value{min-width:56px;text-align:center;font-size:14px;color:#e6e6e6}.cols-btns{flex-wrap:nowrap;gap:5px}.col-step{min-width:40px;padding:4px 6px;letter-spacing:.3px}.col-fine{color:#aaa}.settings-note{font-size:13px;color:#9aa0a6;flex:1 1 auto;min-width:0}.settings-hint{font-size:12px;color:#7c8088;line-height:1.5;margin-top:8px}.settings-hint.preview-dynamic-disabled{color:#6b6f77;border-left:2px solid #34373d;padding-left:8px;margin-top:6px}@keyframes tw-spin{to{transform:rotate(360deg)}}.spinner{display:inline-block;width:14px;height:14px;flex:none;border:2px solid #4a4d52;border-top-color:#e6e6e6;border-radius:50%;animation:tw-spin .7s linear infinite}.bind-input{width:100%;padding:10px;border-radius:6px;border:1px solid #444;background:#1a1b1e;color:#fff;font-size:14px}.startup-custom{margin-top:6px}.opt+.opt{margin-top:14px}.field{width:100%;box-sizing:border-box;display:flex;align-items:center;gap:8px;padding:10px;border-radius:6px;border:1px solid #444;background:#1a1b1e;color:#fff;font-size:14px;text-align:left;touch-action:manipulation}.field:active{border-color:#555}.cwd-field{justify-content:space-between}.cwd-path{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:13px;opacity:.9}.cwd-action{flex:none;color:#4aa3ff;font-size:13px}.cwd-reset{margin-top:6px;background:none;border:none;color:#888;font-size:12px;padding:2px 0;touch-action:manipulation}.dd{position:relative}.dd-trigger{justify-content:space-between}.dd-value{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dd-caret{flex:none;color:#8a8f98;font-size:12px;transition:transform .15s ease}.dd-caret.open{transform:rotate(180deg)}.dd-menu{position:absolute;top:calc(100% + 6px);left:0;right:0;z-index:30;background:#26282c;border:1px solid #3a3c42;border-radius:8px;padding:4px;box-shadow:0 10px 30px #0000008c;transform-origin:top;animation:dd-pop .12s ease}@keyframes dd-pop{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:none}}.dd-option{display:flex;align-items:center;justify-content:space-between;gap:8px;width:100%;padding:10px;border:none;border-radius:6px;background:none;color:#e6e6e6;font-size:14px;text-align:left;touch-action:manipulation}.dd-option:active{background:#33353a}.dd-option.is-selected{color:#07c160}.dd-check{flex:none;color:#07c160;font-size:13px}.bind-error{margin-top:8px;color:#ff8585;font-size:13px}.bind-hint{margin-top:8px;color:#888;font-size:13px}.bind-actions{margin-top:12px;justify-content:flex-end}.bind-confirm{background:#4a7cff;color:#fff}.bind-confirm:disabled{opacity:.6}.windowbar{display:flex;gap:8px;align-items:center;padding:6px 8px;background:#222}.windowbar-scroll{flex:1;min-width:0;display:flex;gap:4px;overflow-x:auto;overflow-y:hidden;-webkit-overflow-scrolling:touch;touch-action:pan-x;scrollbar-width:none}.windowbar-scroll::-webkit-scrollbar{display:none}.win-tab{white-space:nowrap;padding:4px 10px;border:none;border-radius:6px;background:#33353a;color:#bbb;font-size:13px;touch-action:manipulation}.win-tab.active{background:#4a7cff;color:#fff}.win-new{border:1px dashed #555;color:#8aa;font-weight:700;background:transparent}.win-panes{margin-left:5px;font-size:11px;color:#889}.win-tab.active .win-panes{color:#d6e4ff}.wt-dd{position:relative;flex:none}.wt-trigger{display:inline-flex;align-items:center;gap:4px}.wt-sep{margin:0 -1px;color:#cfe0ff;opacity:.4;font-weight:400}.wt-pane{font-weight:600}.wt-caret{flex:none;font-size:11px;color:#d6e4ff;transition:transform .15s ease}.wt-caret.open{transform:rotate(180deg)}.wt-menu{position:fixed;top:auto;right:auto;min-width:160px;max-width:240px}.terminal-wrap{position:relative;flex:1;min-height:0;overflow:hidden}.terminal{height:100%;overflow-x:auto;overflow-y:hidden;overscroll-behavior:contain;-webkit-overflow-scrolling:touch;touch-action:pan-x pan-y}.terminal--loading{opacity:0}.terminal .xterm{display:flex;flex-direction:column;justify-content:flex-end;height:100%;width:max-content;min-width:100%}.terminal .xterm-screen{flex:none}.terminal .xterm-viewport{touch-action:pan-x pan-y;overscroll-behavior:contain}.terminal .xterm-helper-textarea{pointer-events:none;opacity:0}.new-output{position:absolute;right:12px;bottom:12px;z-index:5;touch-action:manipulation;padding:8px 14px;border:none;border-radius:16px;background:#4a7cff;color:#fff;box-shadow:0 2px 8px #0006}.dbg{position:absolute;left:6px;top:6px;z-index:6;font:12px/1.4 monospace;color:#9fe;background:#0009;padding:2px 6px;border-radius:4px;pointer-events:none}.term-banner{position:absolute;left:0;right:0;top:0;z-index:6;font:12px/1.7 -apple-system,system-ui,sans-serif;text-align:center;padding:2px 10px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;pointer-events:none}.term-banner--hist{background:#e0a800;color:#1a1400}.term-banner--err{background:#d32f2f;color:#fff}.copy-bubble{position:absolute;z-index:7;padding:7px 16px;border:none;border-radius:16px;background:#4a7cff;color:#fff;font-size:14px;font-weight:600;box-shadow:0 2px 10px #00000080;touch-action:manipulation}.sel-hint{position:absolute;left:50%;top:12px;transform:translate(-50%);z-index:8;max-width:92%;padding:7px 14px;border-radius:16px;background:#4a7cfff5;color:#fff;font-size:13px;font-weight:600;white-space:nowrap;box-shadow:0 2px 10px #00000080;pointer-events:none}.input-text{flex:1;min-width:0;padding:5px 4px;border:none;background:transparent;color:#fff;font-family:inherit;font-size:16px;line-height:22px;max-height:156px;resize:none;overflow-y:auto;display:block}.input-text:focus{outline:none}.token-prompt button{padding:8px 14px;border:none;border-radius:6px;background:#4a7cff;color:#fff}.drawer{position:fixed;top:0;left:0;width:78%;max-width:320px;height:100%;background:#232427;transform:translate(-100%);transition:transform .2s;z-index:10;padding:12px;display:flex;flex-direction:column;overflow:hidden}.drawer.open{transform:translate(0)}.drawer-list{flex:1;min-height:0;overflow-y:auto}.drawer-logout{flex:none;margin-top:8px;padding:10px;border:none;border-radius:6px;background:#2e2a2c;color:#ffb4b4;font-size:14px;touch-action:manipulation}.drawer-logout:active{background:#4a2f33}.drawer-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;background:#0006;z-index:9}.drawer-title{font-size:12px;color:#888;letter-spacing:1px;margin-bottom:8px}.drawer-row{display:flex;align-items:center;gap:6px;border-radius:6px}.drawer-name{flex:1;min-width:0;padding:8px 4px;cursor:pointer;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.drawer-session.active{background:#4a7cff;color:#fff}.drawer-unbind{flex:none;background:none;border:none;color:#888;font-size:14px;padding:6px 8px;touch-action:manipulation}.drawer-session.active .drawer-unbind{color:#d6e4ff}.drawer-empty{padding:12px 4px;color:#888;font-size:13px}.drawer-bind{width:100%;margin-top:8px;padding:10px;border:none;border-radius:6px;background:#2b3550;color:#cdddff;font-size:14px;touch-action:manipulation}.drawer-bind:active{background:#344168}.token-prompt{max-width:360px;margin:80px auto;display:flex;flex-direction:column;gap:12px;padding:0 16px}.token-prompt input{padding:10px;border-radius:6px;border:1px solid #444;background:#1a1b1e;color:#fff}.loading{padding:40px;text-align:center;color:#888}.empty-cta{margin:auto;display:flex;flex-direction:column;gap:6px;align-items:center;padding:28px 32px;background:none;border:1px dashed #44464c;border-radius:12px;color:#aab;font-size:15px;touch-action:manipulation}.empty-cta span{font-size:13px;color:#6f7bff}.empty-cta:active{background:#232427}.bottom-dock{display:flex;gap:8px;padding:8px;background:#2a2b2e;align-items:stretch}.dock-left{flex:1;min-width:0;display:flex;flex-direction:column;gap:6px}.keyrow{display:flex;align-items:stretch;gap:6px}.keyrow .keybar{flex:1;min-width:0}.keyrow-stack{flex:none;width:66px;display:flex;flex-direction:column;gap:4px}.keyrow-del,.keyrow-enter{flex:1;width:100%;min-height:40px;border:none;border-radius:6px;background:#33353a;color:#e6e6e6;touch-action:manipulation;-webkit-user-select:none;user-select:none}.keyrow-del{font:19px/1 ui-monospace,SF Mono,Menlo,monospace}.keyrow-enter{font-size:15px}.keyrow-del:active,.keyrow-enter:active{background:#4a7cff;color:#fff}.keybar{display:flex}.keybar-scroll{flex:1;display:flex;gap:4px;overflow-x:auto;overflow-y:hidden;-webkit-overflow-scrolling:touch;touch-action:pan-x;scrollbar-width:none}.keybar-scroll::-webkit-scrollbar{display:none}.keybar-col{display:flex;flex-direction:column;gap:4px}.keybar-key{flex:1;min-width:42px;min-height:34px;padding:0 8px;border:none;border-radius:6px;white-space:nowrap;background:#33353a;color:#e6e6e6;font:13px/1 ui-monospace,SF Mono,Menlo,monospace;touch-action:manipulation;-webkit-user-select:none;user-select:none}.keybar-key:active{background:#4a7cff;color:#fff}.keybar-key[data-key=esc],.keybar-key[data-key=tab],.keybar-key[data-key=up],.keybar-key[data-key=down]{min-width:52px}.dock-input-row{display:flex;gap:6px;align-items:stretch}.input-wrap{position:relative;flex:1;min-width:0;display:flex;align-items:flex-end;gap:2px;padding:4px;border:1px solid #444;border-radius:6px;background:#1a1b1e}.input-wrap:focus-within{border-color:#07c160;box-shadow:0 0 0 1px #07c16073}.input-upload{flex:none;width:34px;height:34px;display:inline-flex;align-items:center;justify-content:center;border:none;border-radius:6px;background:transparent;color:#8a93a0;padding:0;touch-action:manipulation;-webkit-user-select:none;user-select:none}.input-upload:active{color:#4a7cff}.input-upload:disabled{opacity:.4}.input-upload svg{width:22px;height:22px;display:block}.dock-upload{padding:6px 4px 2px}.dock-upload-label{display:block;color:#9fb6d0;font-size:12px;margin-bottom:4px;font-variant-numeric:tabular-nums}.dock-upload.error .dock-upload-label{color:#ff8a8a}.dock-upload-track{display:block;height:4px;border-radius:2px;background:#1c2b3a;overflow:hidden}.dock-upload-fill{display:block;height:100%;background:#3a5a7e;transition:width .1s linear}.input-send{flex:none;width:34px;height:34px;display:inline-flex;align-items:center;justify-content:center;border:none;border-radius:50%;background:#4a7cff;color:#fff;padding:0;touch-action:manipulation;-webkit-user-select:none;user-select:none}.input-send:active{background:#3a66e0}.input-send:disabled{background:#3a3c42;color:#6b7280}.input-send svg{width:20px;height:20px;display:block}.input-cmd{flex:none;width:34px;height:34px;display:inline-flex;align-items:center;justify-content:center;border:none;border-radius:6px;background:transparent;color:#8a93a0;padding:0;touch-action:manipulation;-webkit-user-select:none;user-select:none}.input-cmd svg{width:20px;height:20px;display:block}.input-cmd:active{color:#4a7cff}.input-wrap.recording{background:#07c16024;border:2px solid #07c160;animation:rec-breathe 1.3s ease-in-out infinite}.input-wrap.recording .input-text{color:#eafff3}@keyframes rec-breathe{0%,to{box-shadow:0 0 5px #07c1604d;border-color:#2fd07e}50%{box-shadow:0 0 16px 4px #07c160cc;border-color:#07c160}}.input-mic{flex:none;width:34px;height:34px;display:inline-flex;align-items:center;justify-content:center;border:none;border-radius:50%;background:#00000040;color:#b6c0cc;padding:0;touch-action:manipulation;-webkit-user-select:none;user-select:none}.input-mic.on{color:#fff;background:#07c160}.input-mic:disabled{opacity:.5}.input-mic svg{width:21px;height:21px;display:block}.cmd-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;background:#00000080;z-index:21}.cmd-panel{position:fixed;left:0;right:0;bottom:0;z-index:22;max-height:72vh;display:flex;flex-direction:column;background:#232427;border-radius:12px 12px 0 0;box-shadow:0 -8px 30px #00000080}.cmd-head{display:flex;align-items:center;gap:8px;padding:12px 14px;border-bottom:1px solid #33353a}.cmd-title{font-size:15px;font-weight:600;margin-right:auto;display:flex;align-items:center;gap:7px}.idea-head-count{font-size:11px;font-weight:600;color:#a8c4e0;background:#3d5068;border-radius:6px;padding:1px 6px}.cmd-close{background:none;border:none;color:#aaa;padding:4px 8px;touch-action:manipulation;display:inline-flex;align-items:center}.cmd-close svg{width:16px;height:16px;display:block}.cmd-list{overflow-y:auto;-webkit-overflow-scrolling:touch;padding:6px 0 10px}.cmd-section{display:flex;align-items:baseline;gap:8px;padding:9px 14px 5px}.cmd-section.recent{margin-top:6px;border-top:1px solid #2c2e33;padding-top:12px}.cmd-section-name{font-size:12px;font-weight:700;letter-spacing:1px}.cmd-section.fav .cmd-section-name{color:#ffd27a}.cmd-section.recent .cmd-section-name{color:#9db8ff}.cmd-scope{margin-left:auto;font-size:10px;color:#9a9a9a;background:#2c2e33;padding:2px 8px;border-radius:10px;white-space:nowrap}.cmd-row{display:flex;align-items:center;gap:6px;padding:0 8px 0 14px}.cmd-text{flex:1;min-width:0;padding:9px 0;font:13px/1.3 ui-monospace,SF Mono,Menlo,monospace;color:#e6e6e6;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;touch-action:manipulation}.cmd-text:active{color:#9db8ff}.cmd-star{flex:none;background:none;border:none;color:#667;padding:6px 8px;touch-action:manipulation;display:inline-flex;align-items:center}.cmd-star svg{width:16px;height:16px;display:block}.cmd-star.on{color:#ffd27a}.cmd-star.on svg{fill:currentColor}.cmd-del{flex:none;background:none;border:none;color:#888;padding:6px 8px;touch-action:manipulation;display:inline-flex;align-items:center}.cmd-del svg{width:14px;height:14px;display:block}.cmd-empty{padding:20px 14px;color:#888;font-size:13px;text-align:center}.idea-panel{position:fixed;left:0;right:0;bottom:0;z-index:22;min-height:50vh;max-height:80vh;display:flex;flex-direction:column;background:#232427;border-radius:12px 12px 0 0;box-shadow:0 -8px 30px #00000080}.idea-compose{display:flex;align-items:flex-end;gap:8px;padding:10px 14px;border-bottom:1px solid #33353a}.idea-input{flex:1;min-width:0;resize:none;max-height:96px;padding:8px 10px;border:1px solid #3a3c42;border-radius:8px;background:#1b1c1f;color:#e6e6e6;font:14px/1.4 -apple-system,system-ui,sans-serif}.idea-input:focus{outline:none;border-color:#5b78d6}.idea-compose .input-mic{position:static;right:auto;bottom:auto;flex:none}.idea-act{flex:none;width:34px;height:34px;display:inline-flex;align-items:center;justify-content:center;border:none;border-radius:50%;background:#3a6df0;color:#fff;padding:0;touch-action:manipulation}.idea-act:disabled{background:#00000040;color:#b6c0cc;opacity:.55}.idea-act svg{width:20px;height:20px;display:block}.idea-cancel{flex:none;background:none;border:none;color:#aaa;font-size:13px;padding:9px 4px;touch-action:manipulation}.idea-list{flex:1;overflow-y:auto;-webkit-overflow-scrolling:touch;padding:6px 0 12px}.idea-list:has(.cmd-empty){display:flex;align-items:center;justify-content:center}.idea-row{display:flex;align-items:center;gap:6px;padding:0 8px 0 4px;background:#232427}.idea-row.editing{background:#262a31}.idea-row.dragging{background:#2c2f36;border-radius:8px;box-shadow:0 2px 12px #00000073}.idea-handle{flex:none;background:none;border:none;color:#777;font-size:20px;line-height:1;padding:11px 16px;cursor:grab;touch-action:none;-webkit-user-select:none;user-select:none}.idea-text{flex:1;min-width:0;padding:11px 0;font-size:14px;line-height:1.35;color:#e6e6e6;white-space:pre-wrap;overflow-wrap:anywhere;touch-action:manipulation}.idea-text:active{color:#9db8ff}.idea-send{flex:none;background:#2c2e33;color:#9db8ff;border:none;border-radius:6px;padding:6px 10px;font-size:13px;touch-action:manipulation}.idea-del{flex:none;background:none;border:none;color:#888;font-size:14px;padding:6px 8px;touch-action:manipulation}.changelog-panel{position:fixed;left:0;right:0;bottom:0;z-index:22;max-height:80vh;display:flex;flex-direction:column;background:#232427;border-radius:12px 12px 0 0;box-shadow:0 -8px 30px #00000080}.changelog-list{overflow-y:auto;-webkit-overflow-scrolling:touch;padding:6px 16px 16px}.rel{padding:12px 0;border-bottom:1px solid #2c2e33}.rel:last-child{border-bottom:none}.rel-date{font-size:12px;font-weight:700;letter-spacing:.5px;color:#9db8ff;margin-bottom:6px}.rel-items{margin:0;padding-left:18px}.rel-items li{font-size:13px;line-height:1.5;color:#e6e6e6;margin:3px 0}.topbar-icon{position:relative}.topbar-dot{position:absolute;top:4px;right:4px;width:7px;height:7px;border-radius:50%;background:#ff5a52;box-shadow:0 0 0 2px #1b1c1f}.idea-badge{position:absolute;top:2px;right:1px;min-width:14px;height:14px;border-radius:7px;padding:0 3px;box-sizing:border-box;background:#3d5068;color:#a8c4e0;font-size:9px;font-weight:700;line-height:14px;text-align:center;pointer-events:none}.settings-dot{display:inline-block;width:7px;height:7px;margin-left:6px;border-radius:50%;background:#ff5a52;vertical-align:middle}.sheet-actions{display:flex;flex-direction:column;gap:8px}.sheet-action{width:100%;padding:12px;border:1px solid #33353a;border-radius:6px;background:#2a2c31;color:#ddd;font-size:15px;text-align:center;touch-action:manipulation}.sheet-action.danger{color:#ff8585}.sheet-action.armed{background:#ff8585;color:#fff;border-color:#ff8585}.sheet-action:disabled{opacity:.4}.sheet-row{display:flex;gap:8px}.sheet-row .sheet-action{flex:1}.sheet-cancel{margin-top:4px}.win-tab,.session-name{-webkit-user-select:none;user-select:none;-webkit-touch-callout:none}.file-sheet{position:fixed;top:0;right:0;bottom:0;left:0;z-index:50;display:flex;flex-direction:column;background:#0b0f14;transform:translateY(100%);transition:transform .28s cubic-bezier(.22,.61,.36,1);pointer-events:none}.file-sheet.open{transform:translateY(0);pointer-events:auto}.file-tabs{display:flex;align-items:stretch;border-bottom:1px solid #1d2630;background:#11161d}.file-tabs-scroll{display:flex;overflow-x:auto;flex:1;-webkit-overflow-scrolling:touch}.file-tab{display:inline-flex;align-items:center;white-space:nowrap;border-right:1px solid #1d2630}.file-tab.active{background:#0b0f14;box-shadow:inset 0 -2px #4aa3ff}.file-tab-label{display:inline-flex;align-items:center;gap:5px;padding:10px 8px 10px 12px;background:transparent;border:none;color:#9fb0c0;font-size:13px}.file-tab-label svg{width:15px;height:15px}.file-tab.active .file-tab-label{color:#e6edf3}.file-tab-x{background:transparent;border:none;color:#6b7a89;font-size:11px;padding:0 10px 0 2px}.file-min{flex:0 0 auto;width:44px;display:inline-flex;align-items:center;justify-content:center;background:transparent;color:#9fb0c0;border:none;border-left:1px solid #1d2630}.file-min svg{width:20px;height:20px}.file-body{flex:1;overflow:hidden;display:flex}.preview-frame{flex:1;width:100%;border:0;background:#fff}.preview-body.pc{display:block;position:relative;overflow:auto;-webkit-overflow-scrolling:touch}.preview-scaler{position:relative}.preview-body.pc .preview-frame{position:absolute;top:0;left:0;flex:none}.preview-zoom{position:absolute;bottom:14px;left:50%;transform:translate(-50%);z-index:2;display:flex;align-items:center;gap:2px;padding:4px;background:#1c1e22eb;border:1px solid #3a3c42;border-radius:999px;box-shadow:0 6px 20px #00000073}.preview-zoom-btn{width:34px;height:30px;display:inline-flex;align-items:center;justify-content:center;background:transparent;border:none;color:#e6edf3;font-size:20px;line-height:1;border-radius:999px;touch-action:manipulation}.preview-zoom-btn:disabled{color:#5a626b}.preview-zoom-val{min-width:46px;text-align:center;color:#9fb0c0;font-size:13px;font-variant-numeric:tabular-nums}.preview-head{position:relative;align-items:center;gap:4px;min-height:44px;padding-left:10px}.preview-status{display:inline-flex;align-items:center;gap:5px;min-width:0;color:#e6edf3;font-size:12px}.preview-status svg{width:15px;height:15px;flex:0 0 auto}.preview-state{color:#3fb950;font-weight:600;flex:0 0 auto}.preview-name{color:#9fb0c0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}.preview-detail{color:#6e7d8c;margin-left:6px}.preview-remain{margin-left:auto;flex:0 0 auto;font-variant-numeric:tabular-nums;color:#9fb0c0;font-size:12px;padding:4px 8px;background:transparent;border:1px solid #33353a;border-radius:6px;touch-action:manipulation}.preview-remain:active{color:#4aa3ff;border-color:#4aa3ff}.preview-pop-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:5}.preview-pop{position:absolute;top:46px;right:8px;z-index:6;min-width:168px;display:flex;flex-direction:column;gap:2px;padding:6px;background:#232427;border:1px solid #33353a;border-radius:10px;box-shadow:0 10px 30px #00000080}.preview-pop-item{background:transparent;border:none;color:#e6edf3;text-align:left;padding:10px 12px;border-radius:6px;font-size:14px}.preview-pop-item:active{background:#2f3338}.preview-pop-danger{color:#ffb4b4}.preview-iconbtn{flex:0 0 auto;width:32px;display:inline-flex;align-items:center;justify-content:center;background:transparent;border:none;color:#9fb0c0;touch-action:manipulation}.preview-iconbtn svg{width:17px;height:17px}.preview-iconbtn:active{color:#4aa3ff}.preview-head .file-min{width:34px}.preview-head .file-min svg{width:18px;height:18px}.preview-confirm-backdrop{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;display:flex;align-items:center;justify-content:center;background:#00000080}.preview-confirm{width:min(86vw,320px);background:#232427;border-radius:12px;padding:16px;box-shadow:0 10px 40px #00000080}.preview-confirm-title{font-size:16px;font-weight:600;color:#e6edf3;margin-bottom:8px}.preview-confirm-text{font-size:13px;color:#9aa3ad;line-height:1.5;margin-bottom:14px}.preview-confirm-btns{display:flex;justify-content:flex-end;gap:8px}.preview-confirm-danger{background:#5a1f1f;color:#ffb4b4}.settings-group{margin:16px -16px 0;padding:7px 16px;background:#1b1c1f;color:#9aa3ad;font-size:11px;font-weight:700;letter-spacing:1.2px;border-top:1px solid #33353a;border-bottom:1px solid #33353a}.settings-head+.settings-group{margin-top:0}.settings-group+.settings-section{border-top:none}.preview-running{display:inline-flex;align-items:center;gap:6px;color:#3fb950;font-weight:600;font-size:13px}.live-dot{width:8px;height:8px;border-radius:50%;background:#3fb950}.preview-port{width:9em;padding:6px 10px;font-size:15px;color:#e8e8ea;background:#1b1c1f;border:1px solid #3a3c42;border-radius:8px}.preview-seg{display:inline-flex;align-self:flex-start;border:1px solid #3a3c42;border-radius:8px;overflow:hidden}.preview-seg button{background:transparent;border:none;color:#9aa3ad;padding:7px 18px;min-width:60px;font-size:14px;touch-action:manipulation}.preview-seg button+button{border-left:1px solid #3a3c42}.preview-seg button.on{background:#2f6df6;color:#fff}.preview-start{display:flex;flex-direction:column;gap:12px}.preview-active{display:flex;flex-direction:column;gap:10px}.preview-active-head{display:flex;align-items:center;gap:10px}.preview-remain-s{margin-left:auto;font-variant-numeric:tabular-nums;color:#9aa3ad;font-size:13px}.settings-err{color:#ff9d9d}.preview-live{color:#3fb950}.home-pane{flex:1;display:flex;flex-direction:column;min-width:0}.file-seg{display:flex;gap:8px;padding:10px 12px;border-bottom:1px solid #1d2630;background:#0e131a}.file-seg-btn{flex:1;display:inline-flex;align-items:center;justify-content:center;gap:6px;padding:9px;border-radius:8px;background:#11161d;border:1px solid #1d2630;color:#9fb0c0;font-size:14px}.file-seg-btn.on{background:#15212f;border-color:#2f6fc0;color:#cfe0f2}.file-seg-btn svg{width:16px;height:16px}.git-head{align-items:stretch;min-height:42px}.git-back{flex:0 0 auto;width:40px;align-self:stretch;display:inline-flex;align-items:center;justify-content:center;background:transparent;border:none;color:#9fb0c0;font-size:26px;line-height:1}.git-drill-head{flex:1;min-width:0;display:flex;align-items:center;gap:4px;overflow:hidden}.git-drill-title{display:inline-flex;align-items:center;gap:7px;min-width:0;color:#e6edf3;font-size:14px}.git-drill-title svg{width:16px;height:16px;color:#6b86a3;flex:0 0 auto}.git-title-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.git-tabs-scroll{display:flex;align-items:stretch;overflow-x:auto;flex:1;-webkit-overflow-scrolling:touch}.git-tab-add{flex:0 0 auto;width:40px;display:inline-flex;align-items:center;justify-content:center;background:transparent;border:none;border-right:1px solid #1d2630;color:#8fb2dc;font-size:20px;line-height:1}.git-tab{flex:0 0 auto;display:inline-flex;align-items:center;white-space:nowrap;border-right:1px solid #1d2630}.git-tab.active{background:#0b0f14;box-shadow:inset 0 -2px #4aa3ff}.git-tab-label{display:inline-flex;align-items:center;padding:10px 4px 10px 12px;background:transparent;border:none;color:#9fb0c0;font-size:13px}.git-tab.active .git-tab-label{color:#e6edf3}.git-tab-x{background:transparent;border:none;color:#6b7a89;font-size:11px;padding:0 10px 0 4px;align-self:stretch}.git-branch-bar{display:flex;align-items:center;gap:10px;padding:7px 12px 7px 14px;border-bottom:1px solid #1d2630;background:#0b0f14;font-size:13px}.git-branch-bar-name{flex:1;min-width:0;color:#cfe0f2;font-weight:600;display:flex;align-items:center;gap:6px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.git-branch-glyph{color:#8fb2dc}.git-branch-cur-tag{flex:0 0 auto;font-size:11px;font-weight:600;color:#3fb950;background:#3fb9501f;border:1px solid rgba(63,185,80,.4);border-radius:999px;padding:1px 7px}.git-branch-bar-track{flex:0 0 auto;font-size:12px;font-variant-numeric:tabular-nums;display:flex;gap:5px}.git-branch-dd{position:relative;flex:0 0 auto}.git-branch-trigger{max-width:46vw;display:flex;align-items:center;gap:5px;background:#11161d;border:1px solid #1d2630;border-radius:8px;color:#9fb0c0;font-size:12px;padding:5px 9px}.git-branch-trigger.other{border-color:#2f6fc0;background:#15212f;color:#cfe0f2}.git-branch-trigger-name{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.git-branch-caret{flex:0 0 auto;display:inline-flex;color:#6b7a89}.git-branch-caret svg{width:13px;height:13px}.git-dd-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:40}.git-dd-menu{position:absolute;top:calc(100% + 6px);right:0;z-index:41;min-width:56vw;max-width:calc(100vw - 24px);max-height:56vh;overflow:auto;-webkit-overflow-scrolling:touch;background:#0e141b;border:1px solid #243040;border-radius:10px;box-shadow:0 10px 28px #00000080;padding:4px}.git-dd-item{display:flex;align-items:center;gap:8px;width:100%;text-align:left;background:transparent;border:none;color:#e6edf3;padding:10px;font-size:13px;border-radius:7px}.git-dd-item:active{background:#15212f}.git-dd-item.viewing{background:#15212f;box-shadow:inset 3px 0 #2f6fc0}.git-dd-item.current .git-row-path{color:#cfe0f2;font-weight:600}.git-section{display:flex;flex-direction:column;min-height:0;border-bottom:1px solid #161d26}.git-section:not(.open){flex:0 0 auto}.git-section.open.git-section--top{flex:0 1 auto;min-height:25%;max-height:50%}.git-section.open.git-section--mid{flex:1 1 0;min-height:96px}.git-section-head{flex:0 0 auto;display:flex;align-items:center;gap:8px;width:100%;text-align:left;background:#0b0f14;border:none;color:#9fb0c0;padding:10px 14px;font-size:13px;font-weight:600}.git-section-head:active{background:#11161d}.git-section-caret{flex:0 0 auto;display:inline-flex;color:#6b7a89;transition:transform .15s;transform:rotate(-90deg)}.git-section.open .git-section-caret{transform:rotate(0)}.git-section-caret svg{width:14px;height:14px}.git-section-title{flex:0 0 auto}.git-section-sub{flex:1;min-width:0;color:#6b7a89;font-weight:400;font-size:12px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.git-section-count{flex:0 0 auto;margin-left:auto;color:#6b7a89;font-weight:400;font-size:12px;font-variant-numeric:tabular-nums}.git-section-sub+.git-section-count{margin-left:8px}.git-section-body{flex:1;min-height:0;overflow:auto;-webkit-overflow-scrolling:touch}.git-more{text-align:center;color:#6b7a89;font-size:12px;padding:12px}.git-body{flex:1;min-height:0;display:flex;flex-direction:column;overflow:hidden;padding-bottom:var(--kb-inset, 0px)}.git-scroll{flex:1;min-height:0;overflow:auto;-webkit-overflow-scrolling:touch}.git-error{color:#ff9d9d;font-size:13px;padding:14px 16px}.git-loading,.git-empty{color:#6b7a89;font-size:13px;padding:16px}.git-list{display:flex;flex-direction:column}.git-row{display:flex;align-items:center;gap:9px;width:100%;text-align:left;background:transparent;border:none;border-bottom:1px solid #161d26;color:#e6edf3;padding:11px 14px;font-size:13px}.git-row:active{background:#11161d}.git-row-path{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0;flex:1}.git-badge{flex:0 0 auto;width:20px;text-align:center;font-size:12px;font-weight:600;font-variant-numeric:tabular-nums;color:#9aa3ad}.git-badge-m{color:#d8a13a}.git-badge-a{color:#3fb950}.git-badge-d{color:#f06b6b}.git-badge-r{color:#8fb2dc}.git-badge-q{color:#6b7a89}.git-commit-row{align-items:flex-start}.git-hash{flex:0 0 auto;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;color:#8fb2dc;font-size:12px;padding-top:1px}.git-commit-main{display:flex;flex-direction:column;gap:3px;min-width:0;flex:1}.git-commit-meta{color:#6b7a89;font-size:11px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.git-branch{gap:8px}.git-branch.current .git-row-path{color:#cfe0f2;font-weight:600}.git-branch.viewing{background:#11161d;box-shadow:inset 3px 0 #2f6fc0}.git-branch-dot{flex:0 0 auto;width:12px;text-align:center;color:#3fb950;font-size:11px}.git-branch-up{flex:0 0 auto;color:#6b7a89;font-size:11px;font-variant-numeric:tabular-nums}.git-ahead{color:#3fb950}.git-behind{color:#f06b6b}.git-commit-detail{display:flex;flex-direction:column}.git-commit-msg{white-space:pre-wrap;word-break:break-word;margin:0;padding:14px 16px;color:#c9d6e2;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:12px;line-height:1.5;border-bottom:1px solid #161d26;background:#0e131a}.git-diff-wrap{display:flex;flex-direction:column}.git-diff-zoom{position:sticky;top:0;z-index:2;display:flex;gap:6px;justify-content:flex-end;padding:8px 12px}.git-diff-trunc{position:sticky;top:0;z-index:1;background:#3a2a12;color:#f0c674;font-size:12px;padding:8px 14px;border-bottom:1px solid #5a4318}.git-diff-fname{padding:10px 14px 6px;color:#9fb0c0;font-size:12px;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}.git-diff{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:inherit;line-height:1.5;white-space:pre;overflow-x:auto;-webkit-overflow-scrolling:touch}.git-diff-line{padding:0 14px;min-width:max-content}.git-diff-hunk{color:#6b86a3;background:#0e131a}.git-diff-add{background:#3fb95029;color:#c7f0cf}.git-diff-del{background:#f06b6b29;color:#f3cccc}.git-diff-ctx{color:#c9d6e2}.home-view{flex:1;overflow:auto;-webkit-overflow-scrolling:touch;padding:12px;color:#c9d6e2}.home-empty{color:#6b7a89;font-size:13px;display:flex;flex-direction:column;gap:4px;padding:16px 4px}.home-empty span{color:#4a5663;font-size:12px}.home-recent-row{display:flex;align-items:center;width:100%}.home-recent{flex:1;display:flex;flex-direction:column;align-items:flex-start;background:#11161d;border:1px solid #1d2630;border-radius:8px;padding:8px 10px;margin-bottom:6px;color:#e6edf3;text-align:left}.home-path{font-size:11px;color:#6b7a89;overflow:hidden;text-overflow:ellipsis;max-width:80vw}.home-x{background:transparent;border:none;color:#6b7a89;padding:0 8px}.browse-view{flex:1;display:flex;flex-direction:column;min-height:0;position:relative}.browse-bar{display:flex;align-items:center;gap:8px;padding:10px 12px;border-bottom:1px solid #1d2630;background:#0e131a}.browse-root-dd{flex:0 0 auto}.browse-root{display:inline-flex;align-items:center;gap:3px;padding:9px 4px 9px 10px;background:transparent;border:none;color:#6b86a3;font-size:13px}.browse-root .dd-caret{font-size:10px}.browse-root-dd .dd-menu{left:0;right:auto;min-width:120px}.browse-up{flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;width:38px;height:38px;background:#11161d;border:1px solid #1d2630;border-radius:8px;color:#9fb0c0}.browse-up:disabled{opacity:.4}.browse-up svg{width:18px;height:18px}.browse-cwd{flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;width:38px;height:38px;background:#11161d;border:1px solid #1d2630;border-radius:8px;color:#9fb0c0}.browse-cwd svg{width:18px;height:18px}.browse-path{flex:1;min-width:0;display:flex;align-items:center;border-radius:8px;border:1px solid #243446;background:#11161d}.browse-path:focus-within{border-color:#3a5a7e}.browse-input:focus{outline:none}.browse-home{flex:0 0 auto;padding:9px 2px 9px 10px;color:#6b86a3;font-size:13px;-webkit-user-select:none;user-select:none}.browse-input{flex:1;min-width:0;padding:9px 10px 9px 0;border:none;border-radius:8px;background:transparent;color:#e6edf3;font-size:13px}.browse-err{padding:8px 12px 0}.browse-notice{position:absolute;left:50%;bottom:16px;transform:translate(-50%);z-index:6;max-width:88%;width:max-content;padding:9px 14px;border-radius:10px;background:#1c1e22f7;color:#d3dbe4;font-size:13px;line-height:1.4;box-shadow:0 6px 24px #00000080;pointer-events:none;word-break:break-all}.browse-saved{display:flex;align-items:center;gap:10px;margin:8px 12px 0;padding:8px 10px;border:1px solid #2a3f56;border-radius:8px;background:#15212e}.browse-saved-text{flex:1;min-width:0;color:#cfe0f0;font-size:13px}.browse-saved-close{flex:0 0 auto;width:32px;height:32px;border:none;border-radius:8px;background:transparent;color:#8aa0b6;font-size:20px;line-height:1}.browse-pending{display:flex;align-items:center;gap:10px;margin:8px 12px 0;padding:8px 10px;border:1px solid #2a3f56;border-radius:8px;background:#15212e}.browse-pending-text{flex:1;min-width:0;color:#cfe0f0;font-size:13px;overflow:hidden;text-overflow:ellipsis}.browse-pending-hint{color:#8aa0b6;font-style:normal;font-size:12px}.browse-pending-btn{flex:0 0 auto;height:32px;padding:0 14px;border:none;border-radius:8px;background:#2f5fa0;color:#fff;font-size:13px}.browse-pending-btn:disabled{opacity:.4}.browse-list{flex:1;overflow:auto;-webkit-overflow-scrolling:touch;padding:4px 12px 16px}.browse-empty{color:#6b7a89;font-size:13px;padding:16px 4px}.browse-overflow{color:#6b7a89;font-size:12px;padding:12px 4px 16px;text-align:center}.browse-entry{display:flex;align-items:center;gap:9px;width:100%;background:transparent;border:none;border-bottom:1px solid #161d26;color:#e6edf3;padding:11px 4px;text-align:left}.browse-entry-icon{flex:0 0 auto;display:inline-flex;color:#6b86a3}.browse-entry-icon svg{width:17px;height:17px}.browse-entry-name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.browse-upload{flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;width:38px;height:38px;background:#11161d;border:1px solid #1d2630;border-radius:8px;color:#9fb0c0}.browse-upload:disabled{opacity:.4}.browse-upload svg{width:18px;height:18px}.browse-file-input{position:absolute;width:1px;height:1px;margin:-1px;padding:0;border:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}.browse-mkdir{flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;width:38px;height:38px;background:#11161d;border:1px solid #1d2630;border-radius:8px;color:#9fb0c0}.browse-mkdir:disabled{opacity:.4}.browse-mkdir svg{width:18px;height:18px}.browse-newfolder{display:flex;align-items:center;gap:8px;padding:8px 12px}.browse-newfolder-input{flex:1;min-width:0;padding:9px 10px;border-radius:8px;border:1px solid #243446;background:#11161d;color:#e6edf3;font-size:13px}.browse-newfolder-input:focus{outline:none;border-color:#3a5a7e}.browse-newfolder-ok{flex:0 0 auto;height:36px;padding:0 14px;border:none;border-radius:8px;background:#2f5fa0;color:#fff;font-size:13px;white-space:nowrap}.browse-newfolder-x{flex:0 0 auto;width:36px;height:36px;border:1px solid #1d2630;border-radius:8px;background:#11161d;color:#9fb0c0;font-size:15px;line-height:1}.browse-progress{padding:8px 12px 0}.browse-progress-label{display:block;color:#9fb6d0;font-size:12px;margin-bottom:4px;font-variant-numeric:tabular-nums}.browse-progress-track{display:block;height:4px;border-radius:2px;background:#1c2b3a;overflow:hidden}.browse-progress-fill{display:block;height:100%;background:#3a5a7e;transition:width .1s linear}.browse-entry-row{display:flex;align-items:center}.browse-entry-row .browse-entry{flex:1;min-width:0}.browse-entry-size{flex:0 0 auto;margin-left:auto;padding-left:8px;color:#6b7a89;font-size:12px;font-variant-numeric:tabular-nums}.browse-dl,.browse-copy{flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;width:36px;height:36px;border:none;background:none;color:#6b86a3;margin-left:4px}.browse-dl svg,.browse-copy svg{width:17px;height:17px}.browse-copy:active{color:#9db8ff}.browse-pick-bar{padding:8px;border-top:1px solid #1d2630}.browse-pick-confirm{width:100%;padding:10px;border:none;border-radius:8px;background:#4a7cff;color:#fff;font-size:14px}.dirpick-backdrop{z-index:30;background:#0000009e}.dirpick-card{width:min(92vw,520px);max-width:none;z-index:31;max-height:min(80vh,calc(100vh - var(--kb-inset, 0px) - 32px));display:flex;flex-direction:column}.dirpick-card .browse-view{flex:1;min-height:0}.dirpick-hint{font-size:12px;color:#9a9a9a;line-height:1.5;margin-bottom:10px;word-break:break-all}.dirpick-hint code{color:#d8c08a;background:#2c2e33;padding:1px 5px;border-radius:4px}.doc-md-wrap{position:relative;flex:1;min-width:0;overflow-y:auto;overflow-x:hidden;-webkit-overflow-scrolling:touch}.doc-zoom{position:sticky;top:0;z-index:1;display:flex;gap:6px;align-items:center;padding:8px 12px 0}.doc-tts{display:flex;gap:6px}.doc-fonts{display:flex;gap:6px;margin-left:auto}.doc-zoom-btn{display:inline-flex;align-items:center;justify-content:center;background:#11161d;border:1px solid #1d2630;color:#9fb0c0;border-radius:8px;padding:4px 12px;font-size:14px;touch-action:manipulation}.doc-zoom-btn:disabled{opacity:.4}.doc-zoom-icon{padding:4px 9px}.doc-zoom-icon svg{width:17px;height:17px;display:block}.tts-active{background:#4a7cff4d;border-radius:3px;box-decoration-break:clone;-webkit-box-decoration-break:clone}.doc-md{padding:16px;color:#e6edf3;line-height:1.6;word-wrap:break-word}.doc-md h1,.doc-md h2,.doc-md h3{border-bottom:1px solid #1d2630;padding-bottom:4px}.doc-md pre{background:#11161d;padding:12px;border-radius:8px;overflow:auto}.doc-md code{background:#11161d;padding:1px 4px;border-radius:4px}.doc-md a{color:#4aa3ff}.doc-md img{max-width:100%}.doc-md table{display:block;max-width:100%;overflow-x:auto;border-collapse:collapse}.doc-text{margin:0;padding:16px;color:#e6edf3;line-height:1.5;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;white-space:pre-wrap;word-break:break-word;overflow-wrap:anywhere}.doc-iframe{width:100%;height:100%;border:0;background:#fff}.doc-image-wrap{flex:1;min-height:0;overflow:hidden;position:relative;display:flex;align-items:center;justify-content:center;padding:8px;background:#1b1d22;touch-action:none;user-select:none;-webkit-user-select:none}.doc-image{max-width:100%;max-height:100%;object-fit:contain;display:block;will-change:transform;-webkit-touch-callout:none}.doc-image-msg{flex:1;display:flex;align-items:center;justify-content:center;color:#9fb0c0;font-size:14px}.doc-image-zoom{position:absolute;bottom:14px;left:50%;transform:translate(-50%);z-index:2;display:flex;align-items:center;gap:2px;padding:4px;background:#1c1e22eb;border:1px solid #3a3c42;border-radius:999px;box-shadow:0 6px 20px #00000073}.doc-image-zoom button{width:34px;height:30px;display:inline-flex;align-items:center;justify-content:center;background:transparent;border:none;color:#e6edf3;font-size:20px;line-height:1;border-radius:999px;touch-action:manipulation}.doc-image-zoom button:disabled{color:#5a626b}.doc-image-zoom-val{min-width:46px;text-align:center;color:#9fb0c0;font-size:13px;font-variant-numeric:tabular-nums}.doc-image-note{position:absolute;top:14px;left:50%;transform:translate(-50%);z-index:3;max-width:88%;padding:7px 14px;border-radius:999px;white-space:nowrap;background:#1c1e22f0;border:1px solid #3a3c42;color:#e6edf3;font-size:13px;box-shadow:0 6px 20px #00000073}.doclink-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:58}.doclink-pop{position:fixed;z-index:59;width:max-content;max-width:calc(100vw - 16px);background:#1b2330;border:1px solid #2c3a4e;border-radius:12px;padding:12px 14px;box-shadow:0 12px 32px #0000008c;color:#e6edf3}.doclink-name{display:flex;align-items:center;gap:7px;font-weight:600;font-size:14px}.doclink-name svg{width:17px;height:17px;color:#6cb4ff;flex:0 0 auto}.doclink-path{font-size:11px;color:#7d8da0;margin:5px 0 11px;word-break:break-all;max-width:72vw}.doclink-actions{display:flex;gap:8px;justify-content:flex-end}.doclink-actions button{border:1px solid #2c3a4e;background:#11161d;color:#c9d6e2;border-radius:8px;padding:7px 18px;font-size:14px}.doclink-open{background:#2563b0;border-color:#2f6fc0;color:#fff}.doc-deco{border-bottom:2px solid #6cb4ff;background:#4aa3ff38;border-radius:3px;box-sizing:border-box}.doc-toast{position:fixed;left:50%;bottom:24px;transform:translate(-50%);z-index:60;max-width:86vw;background:#2a1518;color:#ffd7d7;border:1px solid #5a2a2a;padding:10px 14px;border-radius:10px;font-size:13px;box-shadow:0 6px 20px #0006}.inbox-btn{position:relative}.inbox-dot{position:absolute;top:1px;right:1px;width:9px;height:9px;border-radius:50%;border:1.5px solid #2a2b2e}.inbox-dot.needs{background:#e0a020}.inbox-dot.done{background:#2e7d46}.inbox-dot.working{background:#2f6fed;animation:tw-blink 1s ease-in-out infinite}@media (prefers-reduced-motion: reduce){.inbox-dot.working{animation:none}}.inbox-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;background:#00000080;z-index:19}.inbox-panel{position:fixed;z-index:20;top:48px;right:8px;width:calc(100% - 32px);max-width:360px;max-height:70vh;overflow-y:auto;background:#232427;border-radius:12px;padding:8px;box-shadow:0 10px 40px #00000080}.inbox-group-title{font-size:12px;color:#888;letter-spacing:1px;padding:8px 8px 4px}.inbox-row{display:flex;flex-direction:column;gap:2px;width:100%;text-align:left;background:none;border:none;color:#e6e6e6;padding:8px;border-radius:8px;touch-action:manipulation}.inbox-row:active{background:#2f3034}.inbox-row-head{display:flex;align-items:center;gap:6px;min-width:0}.agent-mark{width:15px;height:15px;flex:none;display:inline-block;object-fit:contain}.win-tab .agent-mark{vertical-align:-2px;margin-right:4px}.inbox-chip{font-size:11px;padding:1px 6px;border-radius:4px;flex:none}.inbox-chip.needs{background:#e0a020;color:#111}.inbox-chip.done{background:#2e7d46;color:#fff}.inbox-chip.working{background:#2f6fed;color:#fff;animation:tw-blink 1s ease-in-out infinite}@keyframes tw-blink{50%{opacity:.4}}@media (prefers-reduced-motion: reduce){.inbox-chip.working{animation:none}}.inbox-head{display:flex;align-items:center;gap:8px;padding:2px 8px 8px;font-size:13px;color:#9aa0a6}.inbox-summary{display:flex;gap:4px;margin-left:auto}.inbox-summary .inbox-chip{animation:none;font-size:10px;padding:1px 5px}.inbox-readall{background:none;border:none;color:#4aa3ff;font-size:13px;padding:4px 6px;touch-action:manipulation}.inbox-loc{font-weight:600;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.inbox-time{margin-left:auto;font-size:11px;color:#888;flex:none}.inbox-msg{font-size:12px;color:#9aa0a6;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.inbox-empty{padding:24px 8px;text-align:center;color:#888;font-size:13px}.inbox-enable{display:flex;flex-direction:column;gap:8px;align-items:stretch;text-align:left}.inbox-enable-title{font-weight:600;color:#e8eaed;font-size:14px}.inbox-enable-hint{color:#9aa0a6;font-size:12px;line-height:1.4}.inbox-enable-btn{margin-top:2px;padding:8px 12px;border:none;border-radius:8px;background:#2f6fed;color:#fff;font-size:13px;touch-action:manipulation}.inbox-enable-btn:disabled{opacity:.6}.inbox-enable-err{color:#e06b5e;font-size:12px}.drawer-orphans{border-top:1px solid #34353a;margin-top:10px;padding-top:6px}.drawer-orphans-head{display:flex;align-items:center;width:100%;gap:6px;background:none;border:none;color:#888;font-size:12px;letter-spacing:1px;padding:6px 4px;text-align:left;touch-action:manipulation}.drawer-orphans-caret{margin-left:auto}.drawer-orphans-hint{color:#777;font-size:11px;padding:0 4px 4px}.drawer-orphan-row{padding:6px 4px}.drawer-orphan-row+.drawer-orphan-row{border-top:1px solid #2a2b2f}.drawer-orphan-head{display:flex;align-items:center;gap:6px}.drawer-orphan-cwd{flex:1;min-width:0;color:#cdddff;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.drawer-orphan-btn{flex:none;padding:4px 10px;border:none;border-radius:6px;background:#2b3550;color:#cdddff;font-size:13px;touch-action:manipulation}.drawer-orphan-btn:active{background:#344168}.drawer-orphan-btn:disabled{opacity:.45}.drawer-orphan-meta{display:flex;align-items:center;gap:6px;margin-top:2px;min-width:0}.drawer-orphan-agent{flex:none;font-size:10px;padding:0 5px;border-radius:3px;background:#333a45;color:#c7ccd1}.drawer-orphan-state{flex:none;font-size:10px;padding:0 5px;border-radius:3px}.drawer-orphan-state.idle{background:#2e7d46;color:#fff}.drawer-orphan-state.busy{background:#2f6fed;color:#fff}.drawer-orphan-time{flex:none;font-size:11px;color:#888}.drawer-orphan-msg{flex:1;min-width:0;font-size:11px;color:#9aa0a6;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.orphan-targets{display:flex;flex-wrap:wrap;gap:6px}.orphan-targets .fontbtn[aria-pressed=true]{background:#2f6fed;color:#fff;border-color:#2f6fed}.orphan-reco{margin-left:6px;font-size:10px;color:#7ee0a0}.orphan-targets .fontbtn[aria-pressed=true] .orphan-reco{color:#d6f5e3}.orphan-help{font-size:11px;color:#9aa0a6;line-height:1.5;margin-top:6px}.usage-card{max-width:420px;max-height:80vh;overflow-y:auto}.usage-agent{padding:12px 0}.usage-agent+.usage-agent{border-top:1px solid #33353a}.usage-agent-head{display:flex;align-items:center;gap:8px;font-weight:600;font-size:14px;margin-bottom:8px}.usage-agent-head .agent-mark{width:18px;height:18px}.usage-row{margin:12px 0}.usage-row-head{display:flex;justify-content:space-between;align-items:baseline;font-size:13px;margin-bottom:5px}.usage-row-label{color:#ddd}.usage-row-sub{color:#888}.usage-row-pct{font-variant-numeric:tabular-nums;color:#ddd;font-weight:600}.usage-bar{height:8px;background:#33353a;border-radius:5px;overflow:hidden}.usage-bar-fill{height:100%;border-radius:5px;transition:width .3s ease}.usage-bar-fill.lvl-lo{background:#4ec98a}.usage-bar-fill.lvl-mid{background:#e0b341}.usage-bar-fill.lvl-hi{background:#ff6b6b}.usage-row-reset{margin-top:4px;font-size:11px;color:#888}.usage-empty{font-size:13px;color:#9aa0a6;padding:6px 0;line-height:1.5}.usage-code{display:inline-block;margin-top:6px;font-family:ui-monospace,SFMono-Regular,monospace;font-size:12px;background:#1a1b1e;color:#b7f0cd;padding:3px 8px;border-radius:6px}.usage-updated{margin-left:auto;font-size:11px;color:#777}.usage-card .settings-title{margin-right:8px}.usage-head-note{margin-right:auto;font-size:11px;color:#777}
|
package/public/index.html
CHANGED
|
@@ -42,8 +42,8 @@
|
|
|
42
42
|
@keyframes bootDot { 0%,100% { opacity: .22; transform: translateY(0); } 40% { opacity: 1; transform: translateY(-3px); } }
|
|
43
43
|
@media (prefers-reduced-motion: reduce) { .boot-glow, .boot-dots i { animation: none; opacity: .8; } }
|
|
44
44
|
</style>
|
|
45
|
-
<script type="module" crossorigin src="/assets/index-
|
|
46
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
45
|
+
<script type="module" crossorigin src="/assets/index-CCvTPJwI.js"></script>
|
|
46
|
+
<link rel="stylesheet" crossorigin href="/assets/index-CYEn5HNU.css" media="print" onload="this.media='all'"><noscript><link rel="stylesheet" crossorigin href="/assets/index-CYEn5HNU.css"></noscript>
|
|
47
47
|
</head>
|
|
48
48
|
<body>
|
|
49
49
|
<div id="boot-splash" aria-hidden="true">
|
package/src/claudeEvents.js
CHANGED
|
@@ -62,7 +62,6 @@ function readStateFile(file) {
|
|
|
62
62
|
// change (the watcher, for push). No persisted state of our own — the file IS the persistence.
|
|
63
63
|
export function createClaudeEvents({ commands, push, file = DEFAULT_STATE_FILE, now = () => Date.now() } = {}) {
|
|
64
64
|
const lastPushed = {}; // pane → 'needs' | 'done' | null (in-process push-transition dedup, by display view)
|
|
65
|
-
const dotClearedFor = {}; // pane → ts of the stuck 进行中 we already cleared @claude_dot for (clear once)
|
|
66
65
|
// The dedup above is in-process ONLY: a restart (e.g. ./deploy.sh) wipes it while the hook's state
|
|
67
66
|
// file on disk keeps every pane's latest 需要你/已完成. Without priming, the first read after boot
|
|
68
67
|
// would see an empty dedup and re-push every resting pane — a flood of "historical" notifications on
|
|
@@ -136,14 +135,8 @@ export function createClaudeEvents({ commands, push, file = DEFAULT_STATE_FILE,
|
|
|
136
135
|
// (2) roster — drop ended / dead / claude-exited panes; resolve location from the live tmux row.
|
|
137
136
|
if (!c || c.kind === 'end' || gone) continue;
|
|
138
137
|
// Expire a 进行中 latched past the TTL (an ESC-interrupt / walk-away that never got a Stop): drop it
|
|
139
|
-
// from the roster
|
|
140
|
-
if (c.kind === 'working' && now() - (rec.ts || 0) > WORKING_TTL_MS)
|
|
141
|
-
if (live && typeof commands.runTmux === 'function' && dotClearedFor[pane] !== rec.ts) {
|
|
142
|
-
dotClearedFor[pane] = rec.ts;
|
|
143
|
-
try { await commands.runTmux(['set-option', '-w', '-t', pane, '@claude_dot', '']); } catch { /* best effort */ }
|
|
144
|
-
}
|
|
145
|
-
continue;
|
|
146
|
-
}
|
|
138
|
+
// from the roster so the stuck working pane goes away. See WORKING_TTL_MS.
|
|
139
|
+
if (c.kind === 'working' && now() - (rec.ts || 0) > WORKING_TTL_MS) continue;
|
|
147
140
|
const loc = lp ? { session: lp.session, window: lp.window, windowName: lp.windowName } : {};
|
|
148
141
|
if (allow && !allow.has(loc.session)) continue;
|
|
149
142
|
out[pane] = { ...loc, kind: c.kind, msg: c.msg || '', ts: rec.ts || 0, agent: agent.id };
|
package/src/cli/i18n/en.js
CHANGED
|
@@ -80,11 +80,11 @@ export default {
|
|
|
80
80
|
'hooks.removed': '✓ Agent hooks removed.',
|
|
81
81
|
'hooks.usage': 'usage: handmux hooks install|uninstall',
|
|
82
82
|
|
|
83
|
-
//
|
|
84
|
-
'
|
|
85
|
-
'
|
|
86
|
-
'
|
|
87
|
-
'
|
|
83
|
+
// Claude statusLine usage capturer (powers the phone Usage page's 5h/weekly bars)
|
|
84
|
+
'statusline.confirmEnable': "Show Claude's 5h/weekly usage on the phone? (installs a Claude statusLine)",
|
|
85
|
+
'statusline.installed': '✓ Claude statusLine installed → ~/.claude/settings.json',
|
|
86
|
+
'statusline.reload': ' Open a new Claude session to load it; the Usage page fills in as it reports.',
|
|
87
|
+
'statusline.foreignHint': 'You already have a Claude statusLine — leaving it untouched. To also feed the phone Usage page, pipe it through our capturer:',
|
|
88
88
|
|
|
89
89
|
// service
|
|
90
90
|
'service.usage': 'usage: handmux service install [start-flags] | handmux service uninstall',
|
package/src/cli/i18n/zh.js
CHANGED
|
@@ -79,11 +79,11 @@ export default {
|
|
|
79
79
|
'hooks.removed': '✓ agent hooks 已移除。',
|
|
80
80
|
'hooks.usage': '用法:handmux hooks install|uninstall',
|
|
81
81
|
|
|
82
|
-
//
|
|
83
|
-
'
|
|
84
|
-
'
|
|
85
|
-
'
|
|
86
|
-
'
|
|
82
|
+
// Claude statusLine 用量捕获(点亮手机用量页的 5h/周额度条)
|
|
83
|
+
'statusline.confirmEnable': '在手机上显示 Claude 的 5h/周额度?(会安装一个 Claude statusLine)',
|
|
84
|
+
'statusline.installed': '✓ Claude statusLine 已安装 → ~/.claude/settings.json',
|
|
85
|
+
'statusline.reload': ' 新开一个 Claude 会话以加载;用量页会随上报逐渐填上。',
|
|
86
|
+
'statusline.foreignHint': '你已经有自己的 Claude statusLine —— 保持不动。想同时点亮手机用量页,把它接到我们的捕获器后面:',
|
|
87
87
|
|
|
88
88
|
// service
|
|
89
89
|
'service.usage': '用法:handmux service install [start-flags] | handmux service uninstall',
|
package/src/cli/setupWizard.js
CHANGED
|
@@ -124,7 +124,10 @@ export async function runSetup({ home = homedir(), target = configPath(home), lo
|
|
|
124
124
|
log.log(t('setup.tunnel2'));
|
|
125
125
|
log.log(t('setup.tunnel3'));
|
|
126
126
|
log.log(t('setup.tunnel4'));
|
|
127
|
-
|
|
127
|
+
// Default to the CURRENT tunnel when re-running; for a brand-new user (no config) default to '2'
|
|
128
|
+
// (cloudflare quick tunnel — zero-config, instant public URL) rather than '3' (cloudflare-named),
|
|
129
|
+
// which a bare-Enter newcomer can't complete without a Cloudflare login + their own domain.
|
|
130
|
+
const curPick = { none: '1', cloudflare: '2', 'cloudflare-named': '3', ssh: '4' }[cur.tunnel] || '2';
|
|
128
131
|
const pick = await ask(rl, t('setup.choose'), curPick);
|
|
129
132
|
const tunnel = { 1: 'none', 2: 'cloudflare', 3: 'cloudflare-named', 4: 'ssh' }[pick];
|
|
130
133
|
if (!tunnel) { log.error(t('setup.invalid')); return null; }
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
// Install/uninstall the handmux Claude statusLine — the capturer that snapshots the 5h/weekly rate-limit %
|
|
2
|
+
// (from Claude Code's statusLine stdin, the only documented local source) to ~/.handmux/claude-usage.json
|
|
3
|
+
// for the phone's Usage page. Opt-in, and NON-DESTRUCTIVE by design: Claude allows exactly one statusLine,
|
|
4
|
+
// so if the user already has their OWN we NEVER clobber it — we report 'foreign' and the CLI prints a
|
|
5
|
+
// one-line compose snippet instead. We only ever write settings.statusLine when it's absent or already ours.
|
|
6
|
+
//
|
|
7
|
+
// Iron rule (same as claudeHooks): only ever touch ~/.handmux/ and — after opt-in — ~/.claude/. Never
|
|
8
|
+
// create ~/.claude.
|
|
9
|
+
import fs from 'node:fs';
|
|
10
|
+
import path from 'node:path';
|
|
11
|
+
import { homedir } from 'node:os';
|
|
12
|
+
|
|
13
|
+
const STATUS_MARK = 'handmux-statusline.cjs'; // identifies our statusLine command among the user's own
|
|
14
|
+
const SCRIPT = 'handmux-statusline.cjs';
|
|
15
|
+
|
|
16
|
+
function claudeDir(home = homedir()) { return path.join(home, '.claude'); }
|
|
17
|
+
function settingsPath(home = homedir()) { return path.join(claudeDir(home), 'settings.json'); }
|
|
18
|
+
|
|
19
|
+
function readSettings(home) {
|
|
20
|
+
try { return JSON.parse(fs.readFileSync(settingsPath(home), 'utf8')); } catch { return {}; }
|
|
21
|
+
}
|
|
22
|
+
function writeJsonAtomic(file, obj) {
|
|
23
|
+
const tmp = `${file}.tmp`;
|
|
24
|
+
fs.writeFileSync(tmp, JSON.stringify(obj, null, 2));
|
|
25
|
+
fs.renameSync(tmp, file);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function isOurs(sl) {
|
|
29
|
+
return !!(sl && typeof sl.command === 'string' && sl.command.includes(STATUS_MARK));
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// 'no-claude' → ~/.claude absent. 'ours' → our statusLine is installed. 'foreign' → the user has their own
|
|
33
|
+
// statusLine (we must not touch it). 'absent' → Claude Code is here but no statusLine configured.
|
|
34
|
+
export function statusLineStatus(home = homedir()) {
|
|
35
|
+
if (!fs.existsSync(claudeDir(home))) return 'no-claude';
|
|
36
|
+
const sl = readSettings(home).statusLine;
|
|
37
|
+
if (isOurs(sl)) return 'ours';
|
|
38
|
+
if (sl && (sl.command || sl.type)) return 'foreign';
|
|
39
|
+
return 'absent';
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// The exact command a user with an EXISTING statusline appends to capture without changing their display:
|
|
43
|
+
// pipe their statusline's stdin through our capturer in TEE mode first. Returned so the CLI can print it.
|
|
44
|
+
export function composeHint(home = homedir(), { usageFile } = {}) {
|
|
45
|
+
const dest = path.join(claudeDir(home), 'hooks', SCRIPT);
|
|
46
|
+
return `HANDMUX_STATUS_TEE=1 node ${dest} ${usageFile} | <your existing statusline>`;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Install (opt-in): copy the capturer to ~/.claude/hooks/ and point settings.statusLine at it — but ONLY
|
|
50
|
+
// when it's safe (absent or already ours). A 'foreign' statusLine is left untouched. Returns { status }.
|
|
51
|
+
// srcDir = bundled hooks dir (server/hooks)
|
|
52
|
+
// usageFile = ~/.handmux/claude-usage.json (the snapshot the server reads)
|
|
53
|
+
export function installStatusLine(home = homedir(), { srcDir, usageFile } = {}) {
|
|
54
|
+
if (!fs.existsSync(claudeDir(home))) return { status: 'no-claude' };
|
|
55
|
+
const status = statusLineStatus(home);
|
|
56
|
+
// Always deploy the capturer script (it's ours, inert until invoked) so the compose one-liner works even
|
|
57
|
+
// in the foreign case. Only the settings.statusLine write is gated on not clobbering the user's own.
|
|
58
|
+
const hooksDir = path.join(claudeDir(home), 'hooks');
|
|
59
|
+
fs.mkdirSync(hooksDir, { recursive: true });
|
|
60
|
+
const dest = path.join(hooksDir, SCRIPT);
|
|
61
|
+
fs.copyFileSync(path.join(srcDir, SCRIPT), dest);
|
|
62
|
+
if (status === 'foreign') return { status: 'foreign', script: dest }; // never touch their statusLine
|
|
63
|
+
const settings = readSettings(home);
|
|
64
|
+
settings.statusLine = { type: 'command', command: `node ${dest} ${usageFile}` };
|
|
65
|
+
writeJsonAtomic(settingsPath(home), settings);
|
|
66
|
+
return { status: 'installed' };
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Uninstall: drop settings.statusLine only if it's ours, and remove the copied script. Leaves a foreign
|
|
70
|
+
// statusLine and everything else intact.
|
|
71
|
+
export function uninstallStatusLine(home = homedir()) {
|
|
72
|
+
const settings = readSettings(home);
|
|
73
|
+
if (isOurs(settings.statusLine)) {
|
|
74
|
+
delete settings.statusLine;
|
|
75
|
+
if (fs.existsSync(settingsPath(home))) writeJsonAtomic(settingsPath(home), settings);
|
|
76
|
+
}
|
|
77
|
+
try { fs.unlinkSync(path.join(claudeDir(home), 'hooks', SCRIPT)); } catch { /* already gone */ }
|
|
78
|
+
return { status: 'absent' };
|
|
79
|
+
}
|
package/src/httpApi.js
CHANGED
|
@@ -24,6 +24,7 @@ import { hooksStatus, installHooks } from './cli/claudeHooks.js';
|
|
|
24
24
|
import { codexHooksStatus, installCodexHooks } from './cli/codexHooks.js';
|
|
25
25
|
import { claudeStatePath } from './cli/state.js';
|
|
26
26
|
import { scanOrphans, takeoverOrphan, defaultProjectsDir } from './orphans.js';
|
|
27
|
+
import { getUsageCached } from './usage.js';
|
|
27
28
|
|
|
28
29
|
const here = dirname(fileURLToPath(import.meta.url));
|
|
29
30
|
const HOOKS_SRC = resolvePath(here, '../hooks'); // server/hooks (bundled scripts)
|
|
@@ -530,6 +531,13 @@ export function createApiRouter({
|
|
|
530
531
|
try { res.json(await claudeEvents.getStates(allowed)); } catch (e) { next(e); }
|
|
531
532
|
});
|
|
532
533
|
|
|
534
|
+
// Agent usage/quota for the Usage page. Disk-only, no credentials: Claude's 5h/weekly % from the
|
|
535
|
+
// statusLine snapshot (if the capturer is opted in), Codex's rate_limits + tokens from its newest
|
|
536
|
+
// rollout. Either side is null when unavailable. Cached briefly (see usage.js); never throws.
|
|
537
|
+
r.get('/usage', (req, res, next) => {
|
|
538
|
+
try { res.json(getUsageCached(home)); } catch (e) { next(e); }
|
|
539
|
+
});
|
|
540
|
+
|
|
533
541
|
// Orphan Claude sessions: `claude` processes running on this host but NOT inside a tmux pane, so
|
|
534
542
|
// handmux can't steer them. Surfaced at the bottom of the Inbox with a "takeover" (spawn
|
|
535
543
|
// `claude --resume` in tmux). Best-effort process scan (see orphans.js); never throws.
|
package/src/usage.js
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
// Usage/quota reader for the phone's Usage page. Purely reads what each agent already puts on disk — no
|
|
2
|
+
// API calls, no credentials:
|
|
3
|
+
// • Claude — the snapshot the statusLine capturer writes to ~/.handmux/claude-usage.json. Claude Code's
|
|
4
|
+
// statusLine stdin is the ONLY documented local source of the 5h/weekly rate-limit % (see
|
|
5
|
+
// server/hooks/handmux-statusline.cjs). Absent until the user opts the capturer in → returns null.
|
|
6
|
+
// • Codex — the newest rollout's most recent `token_count` event, which carries `rate_limits` (used %,
|
|
7
|
+
// reset, window) and cumulative token usage. Always available once Codex has run, no wiring needed.
|
|
8
|
+
import fs from 'node:fs';
|
|
9
|
+
import path from 'node:path';
|
|
10
|
+
import { homedir } from 'node:os';
|
|
11
|
+
import { pocketHome } from './cli/state.js';
|
|
12
|
+
|
|
13
|
+
export function claudeUsagePath(home = homedir()) { return path.join(pocketHome(home), 'claude-usage.json'); }
|
|
14
|
+
export function codexSessionsDir(home = homedir()) { return path.join(home, '.codex', 'sessions'); }
|
|
15
|
+
|
|
16
|
+
// Claude: read the statusLine snapshot. null if the capturer isn't wired / never populated it.
|
|
17
|
+
export function readClaudeUsage(home = homedir()) {
|
|
18
|
+
try {
|
|
19
|
+
const snap = JSON.parse(fs.readFileSync(claudeUsagePath(home), 'utf8'));
|
|
20
|
+
return (snap && typeof snap === 'object' && !Array.isArray(snap)) ? snap : null;
|
|
21
|
+
} catch { return null; }
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// The rollout tree is date-nested (sessions/YYYY/MM/DD/rollout-<ISO>-<uuid>.jsonl) and every path segment
|
|
25
|
+
// sorts lexically = chronologically, so the newest rollout is the lexically-largest entry at each level —
|
|
26
|
+
// found without walking the whole tree.
|
|
27
|
+
function newestRollout(dir) {
|
|
28
|
+
const maxEntry = (d, pred) => {
|
|
29
|
+
let names;
|
|
30
|
+
try { names = fs.readdirSync(d); } catch { return null; }
|
|
31
|
+
names = names.filter((n) => !n.startsWith('.') && (!pred || pred(n))).sort();
|
|
32
|
+
return names.length ? names[names.length - 1] : null;
|
|
33
|
+
};
|
|
34
|
+
const y = maxEntry(dir); if (!y) return null;
|
|
35
|
+
const m = maxEntry(path.join(dir, y)); if (!m) return null;
|
|
36
|
+
const d = maxEntry(path.join(dir, y, m)); if (!d) return null;
|
|
37
|
+
const dayDir = path.join(dir, y, m, d);
|
|
38
|
+
const f = maxEntry(dayDir, (n) => n.startsWith('rollout-') && n.endsWith('.jsonl'));
|
|
39
|
+
return f ? path.join(dayDir, f) : null;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// One Codex rate-limit window → our shape, or null if absent (secondary is often null on plans without it).
|
|
43
|
+
function codexWindow(w) {
|
|
44
|
+
if (!w || typeof w.used_percent !== 'number') return null;
|
|
45
|
+
return {
|
|
46
|
+
usedPercent: w.used_percent,
|
|
47
|
+
windowMinutes: typeof w.window_minutes === 'number' ? w.window_minutes : null,
|
|
48
|
+
resetsAt: typeof w.resets_at === 'number' ? w.resets_at : null,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Codex: scan the newest rollout from the end for the last `token_count` event (carries the account-wide
|
|
53
|
+
// rate_limits + the session's cumulative tokens). null if Codex hasn't run or the rollout has none yet.
|
|
54
|
+
export function readCodexUsage(home = homedir()) {
|
|
55
|
+
const f = newestRollout(codexSessionsDir(home));
|
|
56
|
+
if (!f) return null;
|
|
57
|
+
let lines;
|
|
58
|
+
try { lines = fs.readFileSync(f, 'utf8').split('\n'); } catch { return null; }
|
|
59
|
+
for (let i = lines.length - 1; i >= 0; i--) {
|
|
60
|
+
const ln = lines[i];
|
|
61
|
+
if (!ln || ln.indexOf('token_count') === -1) continue;
|
|
62
|
+
let rec; try { rec = JSON.parse(ln); } catch { continue; }
|
|
63
|
+
const p = rec.payload;
|
|
64
|
+
if (!p || p.type !== 'token_count') continue;
|
|
65
|
+
const info = p.info || {};
|
|
66
|
+
const tu = info.total_token_usage || {};
|
|
67
|
+
const rl = p.rate_limits || {};
|
|
68
|
+
return {
|
|
69
|
+
updatedAt: Date.parse(rec.timestamp) || null,
|
|
70
|
+
rateLimits: { primary: codexWindow(rl.primary), secondary: codexWindow(rl.secondary) },
|
|
71
|
+
tokens: {
|
|
72
|
+
total: tu.total_tokens ?? null,
|
|
73
|
+
input: tu.input_tokens ?? null,
|
|
74
|
+
cachedInput: tu.cached_input_tokens ?? null,
|
|
75
|
+
output: tu.output_tokens ?? null,
|
|
76
|
+
reasoning: tu.reasoning_output_tokens ?? null,
|
|
77
|
+
},
|
|
78
|
+
contextWindow: typeof info.model_context_window === 'number' ? info.model_context_window : null,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export function getUsage(home = homedir()) {
|
|
85
|
+
return { claude: readClaudeUsage(home), codex: readCodexUsage(home) };
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Small TTL cache so a phone that re-polls doesn't rescan the rollout every few seconds.
|
|
89
|
+
let _cache = { at: 0, home: null, data: null };
|
|
90
|
+
export function getUsageCached(home = homedir(), { ttlMs = 15000, now = Date.now() } = {}) {
|
|
91
|
+
if (_cache.data && _cache.home === home && (now - _cache.at) < ttlMs) return _cache.data;
|
|
92
|
+
_cache = { at: now, home, data: getUsage(home) };
|
|
93
|
+
return _cache.data;
|
|
94
|
+
}
|