aicodeman 1.24.7 → 1.26.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/dist/agent-case-marker.d.ts +91 -0
- package/dist/agent-case-marker.d.ts.map +1 -0
- package/dist/agent-case-marker.js +151 -0
- package/dist/agent-case-marker.js.map +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +17 -2
- package/dist/cli.js.map +1 -1
- package/dist/config/base-path.d.ts +55 -0
- package/dist/config/base-path.d.ts.map +1 -0
- package/dist/config/base-path.js +105 -0
- package/dist/config/base-path.js.map +1 -0
- package/dist/config/cli-registry/schema.d.ts +2 -0
- package/dist/config/cli-registry/schema.d.ts.map +1 -1
- package/dist/config/cli-registry/schema.js +1 -1
- package/dist/config/cli-registry/schema.js.map +1 -1
- package/dist/config/cli-registry/stock.d.ts.map +1 -1
- package/dist/config/cli-registry/stock.js +4 -1
- package/dist/config/cli-registry/stock.js.map +1 -1
- package/dist/config/cli-registry/types.d.ts +9 -0
- package/dist/config/cli-registry/types.d.ts.map +1 -1
- package/dist/daemon-control.d.ts +2 -0
- package/dist/daemon-control.d.ts.map +1 -1
- package/dist/daemon-control.js +2 -0
- package/dist/daemon-control.js.map +1 -1
- package/dist/docker-export.d.ts.map +1 -1
- package/dist/docker-export.js +8 -1
- package/dist/docker-export.js.map +1 -1
- package/dist/docker-hosts.d.ts +97 -3
- package/dist/docker-hosts.d.ts.map +1 -1
- package/dist/docker-hosts.js +260 -4
- package/dist/docker-hosts.js.map +1 -1
- package/dist/hooks-config.d.ts +25 -0
- package/dist/hooks-config.d.ts.map +1 -1
- package/dist/hooks-config.js +106 -6
- package/dist/hooks-config.js.map +1 -1
- package/dist/session.d.ts +31 -1
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +101 -5
- package/dist/session.js.map +1 -1
- package/dist/tmux-manager.d.ts.map +1 -1
- package/dist/tmux-manager.js +54 -8
- package/dist/tmux-manager.js.map +1 -1
- package/dist/types/api.d.ts +51 -1
- package/dist/types/api.d.ts.map +1 -1
- package/dist/types/api.js.map +1 -1
- package/dist/types/session.d.ts +49 -0
- package/dist/types/session.d.ts.map +1 -1
- package/dist/types/session.js.map +1 -1
- package/dist/web/middleware/auth.d.ts +3 -3
- package/dist/web/middleware/auth.d.ts.map +1 -1
- package/dist/web/middleware/auth.js +13 -11
- package/dist/web/middleware/auth.js.map +1 -1
- package/dist/web/public/admin-ui.js.gz +0 -0
- package/dist/web/public/api-client.c9b1cddc.js.gz +0 -0
- package/dist/web/public/app.3a89ac57.js +38 -0
- package/dist/web/public/app.3a89ac57.js.br +0 -0
- package/dist/web/public/app.3a89ac57.js.gz +0 -0
- package/dist/web/public/approvals-ui.js.gz +0 -0
- package/dist/web/public/{constants.7bd482dc.js → constants.7a635e34.js} +58 -0
- package/dist/web/public/constants.7a635e34.js.br +0 -0
- package/dist/web/public/constants.7a635e34.js.gz +0 -0
- package/dist/web/public/cron-ui.js.gz +0 -0
- package/dist/web/public/entrance-animations.js.gz +0 -0
- package/dist/web/public/home-sessions.js.gz +0 -0
- package/dist/web/public/i18n.9db8c4e0.js +1 -0
- package/dist/web/public/i18n.9db8c4e0.js.br +0 -0
- package/dist/web/public/i18n.9db8c4e0.js.gz +0 -0
- package/dist/web/public/image-input.ee16ad88.js.gz +0 -0
- package/dist/web/public/index.html +46 -17
- package/dist/web/public/index.html.br +0 -0
- package/dist/web/public/index.html.gz +0 -0
- package/dist/web/public/input-cjk.87f14251.js.gz +0 -0
- package/dist/web/public/{keyboard-accessory.0454a3e9.js → keyboard-accessory.daf18302.js} +8 -4
- package/dist/web/public/keyboard-accessory.daf18302.js.br +0 -0
- package/dist/web/public/keyboard-accessory.daf18302.js.gz +0 -0
- package/dist/web/public/manifest.json +2 -1
- package/dist/web/public/mobile-handlers.0f83a608.js.gz +0 -0
- package/dist/web/public/mobile-overview.js.gz +0 -0
- package/dist/web/public/{mobile.87674154.css → mobile.7112f27d.css} +1 -1
- package/dist/web/public/{mobile.87674154.css.br → mobile.7112f27d.css.br} +0 -0
- package/dist/web/public/mobile.7112f27d.css.gz +0 -0
- package/dist/web/public/{notification-manager.5d229063.js → notification-manager.36ea4624.js} +1 -1
- package/dist/web/public/notification-manager.36ea4624.js.br +0 -0
- package/dist/web/public/notification-manager.36ea4624.js.gz +0 -0
- package/dist/web/public/orchestrator-panel.js.gz +0 -0
- package/dist/web/public/{panels-ui.e6e06034.js → panels-ui.db4785bf.js} +8 -8
- package/dist/web/public/panels-ui.db4785bf.js.br +0 -0
- package/dist/web/public/panels-ui.db4785bf.js.gz +0 -0
- package/dist/web/public/ralph-panel.6de2d0f8.js.gz +0 -0
- package/dist/web/public/ralph-wizard.13a1831e.js.gz +0 -0
- package/dist/web/public/readmymind-ui.js.gz +0 -0
- package/dist/web/public/respawn-ui.ff0dae4c.js.gz +0 -0
- package/dist/web/public/sanitize-html.bc7078d6.js.gz +0 -0
- package/dist/web/public/session-lineage.js.gz +0 -0
- package/dist/web/public/session-ui.a9c126c6.js +77 -0
- package/dist/web/public/session-ui.a9c126c6.js.br +0 -0
- package/dist/web/public/session-ui.a9c126c6.js.gz +0 -0
- package/dist/web/public/{settings-ui.1ed208dd.js → settings-ui.554f9cdd.js} +1 -1
- package/dist/web/public/settings-ui.554f9cdd.js.br +0 -0
- package/dist/web/public/settings-ui.554f9cdd.js.gz +0 -0
- package/dist/web/public/styles.298f81f2.css +1 -0
- package/dist/web/public/styles.298f81f2.css.br +0 -0
- package/dist/web/public/{styles.421b36d4.css.gz → styles.298f81f2.css.gz} +0 -0
- package/dist/web/public/subagent-windows.e6ca799f.js.gz +0 -0
- package/dist/web/public/sw.js +13 -6
- package/dist/web/public/sw.js.br +0 -0
- package/dist/web/public/sw.js.gz +0 -0
- package/dist/web/public/tab-rail-resize.42c24949.js.gz +0 -0
- package/dist/web/public/terminal-ui.70445f81.js.gz +0 -0
- package/dist/web/public/ultracode-panel.js.gz +0 -0
- package/dist/web/public/ultracode-windows.js.gz +0 -0
- package/dist/web/public/upload.html.gz +0 -0
- package/dist/web/public/vendor/dompurify.min.js.gz +0 -0
- package/dist/web/public/vendor/marked.min.js.gz +0 -0
- package/dist/web/public/vendor/xterm-addon-fit.min.js.gz +0 -0
- package/dist/web/public/vendor/xterm-addon-serialize.min.js.gz +0 -0
- package/dist/web/public/vendor/xterm-addon-unicode11.min.js.gz +0 -0
- package/dist/web/public/vendor/xterm-addon-webgl.min.js.gz +0 -0
- package/dist/web/public/vendor/xterm-predictive-echo.bd6882b8.js.gz +0 -0
- package/dist/web/public/vendor/xterm-zerolag-input.6fee72f2.js.gz +0 -0
- package/dist/web/public/vendor/xterm.css.gz +0 -0
- package/dist/web/public/vendor/xterm.min.js.gz +0 -0
- package/dist/web/public/{voice-input.4ec670b0.js → voice-input.c4b51eb6.js} +1 -1
- package/dist/web/public/voice-input.c4b51eb6.js.br +0 -0
- package/dist/web/public/voice-input.c4b51eb6.js.gz +0 -0
- package/dist/web/public/voice-pcm-worklet.js.gz +0 -0
- package/dist/web/public/webview-tabs.js +3 -1
- package/dist/web/public/webview-tabs.js.br +0 -0
- package/dist/web/public/webview-tabs.js.gz +0 -0
- package/dist/web/route-helpers.d.ts +18 -0
- package/dist/web/route-helpers.d.ts.map +1 -1
- package/dist/web/route-helpers.js +28 -0
- package/dist/web/route-helpers.js.map +1 -1
- package/dist/web/routes/case-routes.d.ts.map +1 -1
- package/dist/web/routes/case-routes.js +261 -6
- package/dist/web/routes/case-routes.js.map +1 -1
- package/dist/web/routes/file-routes.d.ts.map +1 -1
- package/dist/web/routes/file-routes.js +62 -4
- package/dist/web/routes/file-routes.js.map +1 -1
- package/dist/web/routes/hook-event-routes.d.ts.map +1 -1
- package/dist/web/routes/hook-event-routes.js +29 -3
- package/dist/web/routes/hook-event-routes.js.map +1 -1
- package/dist/web/routes/session-routes.d.ts.map +1 -1
- package/dist/web/routes/session-routes.js +139 -59
- package/dist/web/routes/session-routes.js.map +1 -1
- package/dist/web/routes/webview-routes.d.ts +2 -2
- package/dist/web/routes/webview-routes.d.ts.map +1 -1
- package/dist/web/routes/webview-routes.js +23 -21
- package/dist/web/routes/webview-routes.js.map +1 -1
- package/dist/web/schemas.d.ts +30 -0
- package/dist/web/schemas.d.ts.map +1 -1
- package/dist/web/schemas.js +78 -0
- package/dist/web/schemas.js.map +1 -1
- package/dist/web/server.d.ts +4 -2
- package/dist/web/server.d.ts.map +1 -1
- package/dist/web/server.js +75 -12
- package/dist/web/server.js.map +1 -1
- package/dist/web/sse-events.d.ts +4 -2
- package/dist/web/sse-events.d.ts.map +1 -1
- package/dist/web/sse-events.js +4 -2
- package/dist/web/sse-events.js.map +1 -1
- package/dist/web/webview-proxy.d.ts +16 -7
- package/dist/web/webview-proxy.d.ts.map +1 -1
- package/dist/web/webview-proxy.js +28 -15
- package/dist/web/webview-proxy.js.map +1 -1
- package/package.json +8 -7
- package/skills/codeman/SKILL.md +14 -10
- package/skills/codeman/preamble.sh +6 -3
- package/skills/codeman/reference/endpoints.md +10 -0
- package/skills/codeman/reference/recipes.md +1 -1
- package/skills/codeman/reference/verbs.md +26 -1
- package/dist/web/public/app.a5d2fc08.js +0 -38
- package/dist/web/public/app.a5d2fc08.js.br +0 -0
- package/dist/web/public/app.a5d2fc08.js.gz +0 -0
- package/dist/web/public/constants.7bd482dc.js.br +0 -0
- package/dist/web/public/constants.7bd482dc.js.gz +0 -0
- package/dist/web/public/i18n.9ae15b51.js +0 -1
- package/dist/web/public/i18n.9ae15b51.js.br +0 -0
- package/dist/web/public/i18n.9ae15b51.js.gz +0 -0
- package/dist/web/public/keyboard-accessory.0454a3e9.js.br +0 -0
- package/dist/web/public/keyboard-accessory.0454a3e9.js.gz +0 -0
- package/dist/web/public/mobile.87674154.css.gz +0 -0
- package/dist/web/public/notification-manager.5d229063.js.br +0 -0
- package/dist/web/public/notification-manager.5d229063.js.gz +0 -0
- package/dist/web/public/panels-ui.e6e06034.js.br +0 -0
- package/dist/web/public/panels-ui.e6e06034.js.gz +0 -0
- package/dist/web/public/session-ui.c558f981.js +0 -68
- package/dist/web/public/session-ui.c558f981.js.br +0 -0
- package/dist/web/public/session-ui.c558f981.js.gz +0 -0
- package/dist/web/public/settings-ui.1ed208dd.js.br +0 -0
- package/dist/web/public/settings-ui.1ed208dd.js.gz +0 -0
- package/dist/web/public/styles.421b36d4.css +0 -1
- package/dist/web/public/styles.421b36d4.css.br +0 -0
- package/dist/web/public/voice-input.4ec670b0.js.br +0 -0
- package/dist/web/public/voice-input.4ec670b0.js.gz +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
html.mobile-init .header-font-controls,html.mobile-init .header-system-stats,html.mobile-init .header-tokens,html.mobile-init .monitor-panel,html.mobile-init .subagents-panel,html.mobile-init .project-insights-panel,html.mobile-init .file-browser-panel{display:none!important}@media(max-width:768px){input,textarea,select{font-size:16px!important}html{touch-action:manipulation}.session-tab .tab-detach{display:none!important}}@media(max-width:768px)and (min-width:430px){.header{position:fixed;top:0;left:0;right:0;min-height:48px;max-height:48px;padding:.35rem .5rem;padding-left:calc(.5rem + var(--safe-area-left));padding-right:calc(.5rem + var(--safe-area-right));background:#0a0a0a;border-bottom:1px solid rgba(255,255,255,.08);contain:none;overflow:visible;z-index:1200}.ios-device .header{padding-top:calc(.35rem + var(--safe-area-top));min-height:calc(48px + var(--safe-area-top));max-height:calc(48px + var(--safe-area-top))}.app{padding-top:54px}.ios-device .app{padding-top:calc(54px + var(--safe-area-top))}.header-font-controls{gap:.15rem;padding:.15rem .25rem}.header-font-controls .btn-icon-sm{width:18px;height:18px}.header-system-stats{font-size:.6rem;gap:.25rem}.header-right{gap:.35rem}.btn-icon-header:not(.btn-sm){width:44px;height:44px}.session-tabs,.session-tabs.tabs-two-rows{flex-wrap:nowrap;overflow-x:auto;overflow-y:hidden;-webkit-overflow-scrolling:touch;overscroll-behavior-x:contain;scrollbar-width:none;max-height:52px;gap:3px}.session-tabs::-webkit-scrollbar{display:none}.session-tab{padding:.4rem .6rem;font-size:.75rem;min-height:40px}.session-tab .tab-name{max-width:80px}.toolbar{padding:.4rem .5rem;padding-left:calc(.5rem + var(--safe-area-left));padding-right:calc(.5rem + var(--safe-area-right));gap:.4rem}.tab-count-group{display:none}.btn-toolbar{padding:.4rem .8rem;font-size:.8rem;min-height:40px}.case-select-group{max-width:none}.case-combobox{width:160px}.toolbar-select{font-size:.75rem}.monitor-panel,.subagents-panel{width:100%;max-width:100%;left:0;right:0;border-radius:8px 8px 0 0;max-height:40vh}.project-insights-panel{max-width:280px;font-size:.7rem}.modal{z-index:1300}.command-palette-modal{padding:10vh .75rem 0}.command-palette-shell{width:100%;max-height:74vh}.command-palette-input-row{grid-template-columns:20px minmax(0,1fr)}.command-palette-input-row kbd{display:none}.command-palette-item{min-height:56px}.settings-grid{gap:.4rem .75rem}.settings-item{font-size:.7rem}.event-type-grid{grid-template-columns:1fr 40px 40px 40px;gap:5px 6px}.event-label{font-size:.7rem}.subagent-window{width:320px;height:280px;min-width:240px;min-height:160px}.subagent-window-header{padding:.35rem .5rem}.subagent-window-title .id{font-size:.7rem;max-width:180px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.subagent-window-title .status{font-size:.55rem}.subagent-window-body{font-size:.7rem}.respawn-banner{padding:.25rem .5rem;padding-left:calc(.5rem + var(--safe-area-left));padding-right:calc(.5rem + var(--safe-area-right));font-size:.65rem}.respawn-compact-layout{gap:.75rem}.respawn-status-row1{gap:.4rem}.respawn-action-log{max-height:2.6em;font-size:.6rem}.respawn-countdown-timer{font-size:.55rem}.respawn-timer-bar{width:24px}.toolbar-center .btn-toolbar.btn-voice{display:flex!important}.toolbar{padding:0 .5rem;gap:.5rem}.toolbar-left,.toolbar-right,.toolbar-group{gap:.5rem}.btn-toolbar{padding:.4rem .75rem;font-size:.75rem;min-height:unset}}@media(max-width:430px){:root{--header-height: 44px}.header-brand{padding-right:0;margin-right:.1rem;border-right:none}.header-brand .logo{display:inline-flex;align-items:center;justify-content:center;min-width:44px;height:var(--header-height);margin-left:-.3rem;font-size:1.15rem;line-height:1;border-radius:8px;-webkit-tap-highlight-color:transparent}.header-brand .logo:active{background:#60a5fa29}.header-brand .logo .logo-text{display:none}.header-brand .logo .logo-compact{display:inline}.header-font-controls{gap:.1rem;padding:.1rem .2rem}.header-font-controls .btn-icon-sm{width:16px;height:16px}.header-font-controls .font-size-display{font-size:.6rem;min-width:14px}.header-system-stats{font-size:.55rem;gap:.15rem}.header-tokens{font-size:.6rem;padding:.1rem .3rem}.header{position:fixed;top:0;left:0;right:0;min-height:var(--header-height);max-height:var(--header-height);align-items:center;padding:.15rem .3rem;padding-left:calc(.3rem + var(--safe-area-left));padding-right:calc(.3rem + var(--safe-area-right));gap:.15rem;overflow:hidden;background:#0a0a0a;border-bottom:1px solid rgba(255,255,255,.08);contain:none;z-index:1200}.ios-device .header{padding-top:calc(.15rem + var(--safe-area-top));min-height:calc(var(--header-height) + var(--safe-area-top));max-height:calc(var(--header-height) + var(--safe-area-top))}.app{padding-top:calc(var(--header-height) + 6px)}.ios-device .app{padding-top:calc(var(--header-height) + 6px + var(--safe-area-top))}.main{padding-bottom:calc(40px + var(--safe-area-bottom))}.ios-device.safari-browser .main{padding-bottom:calc(40px + var(--safe-area-bottom) + (100vh - var(--app-height, 100vh)))}.header-right{padding-left:.2rem;gap:.1rem;flex-shrink:0;border-left:none}.btn-icon-header{width:26px;height:26px;padding:0}.btn-icon-header svg{width:12px;height:12px}html[data-session-list=sidebar] #sidebarToggleBtn{width:44px;height:44px}html[data-session-list=sidebar] #sidebarToggleBtn svg{width:18px;height:18px}.btn-icon-header.btn-settings,.btn-icon-header.btn-lifecycle-log,.btn-icon-header.btn-away-digest,.btn-icon-header.btn-session-manager,.btn-icon-header.btn-file-viewer,.btn-icon-header.btn-approvals,.btn-icon-header.btn-readmymind,.btn-admin-panel{display:none!important}.btn-voice-mobile{display:inline-flex;align-items:center;justify-content:center;width:26px;height:26px;background:#1a2a3f;border:1px solid rgba(59,130,246,.3);border-radius:4px;color:#93c5fd;cursor:pointer;flex-shrink:0;order:5}.btn-voice-mobile svg{width:13px;height:13px}.btn-voice-mobile:active{background:#2a3a5f}.btn-voice-mobile.recording{background:#ef444440;border-color:#ef444499;color:#ef4444;animation:mobile-voice-pulse 1.2s ease-in-out infinite}@keyframes mobile-voice-pulse{0%,to{box-shadow:inset 0 0 0 1px #ef444459;background:#ef444433}50%{box-shadow:inset 0 0 0 2px #ef4444bf;background:#ef444459}}.btn-settings-mobile{display:inline-flex!important;align-items:center;justify-content:center;width:26px;height:26px;background:transparent;border:1px solid rgba(255,255,255,.2);border-radius:4px;color:#9ca3af;font-size:.85rem;cursor:pointer;flex-shrink:0;order:6;position:relative}.btn-settings-mobile svg{width:13px;height:13px}.btn-settings-mobile:active{background:#ffffff1a;color:#fff}.app{overflow:hidden;position:relative}.keyboard-visible .app{position:fixed;inset:0 0 auto;height:var(--app-height, 100dvh)}.session-tabs,.session-tabs.tabs-two-rows{flex:1;flex-wrap:nowrap;overflow-x:auto;overflow-y:hidden;-webkit-overflow-scrolling:touch;overscroll-behavior-x:contain;scrollbar-width:none;max-height:36px;gap:2px;padding:0}.session-tabs::-webkit-scrollbar{display:none}.session-tab{flex-shrink:0;min-height:32px;max-height:32px;padding:.35rem .5rem;font-size:.7rem;gap:.25rem;border-radius:4px}.session-tab .tab-status{width:4px;height:4px}.session-tab .tab-status.busy{width:9px;height:9px;box-shadow:0 0 8px 2px color-mix(in srgb,var(--green) 55%,transparent)!important}.session-tab .tab-status.busy:after{display:none}.session-tab .tab-name{max-width:50px;overflow:hidden;text-overflow:ellipsis}.session-tab.active .tab-name{min-width:44px}.session-tab .tab-close,.session-tab .tab-gear{display:none}.session-tab.active .tab-gear{display:inline-flex;align-items:center;justify-content:center;font-size:.65rem;line-height:1;width:32px;height:32px;margin-left:auto;opacity:.6}.session-tab.active .tab-close{display:inline-flex;align-items:center;justify-content:center;font-size:1.1rem;line-height:1;width:20px;height:18px;margin-left:-2px}.toolbar{position:fixed;bottom:var(--safe-area-bottom);left:0;right:0;height:40px;min-height:40px;max-height:40px;padding:.3rem .4rem;padding-left:calc(.4rem + var(--safe-area-left));padding-right:calc(.4rem + var(--safe-area-right));flex-wrap:nowrap;gap:.3rem;align-items:center;justify-content:space-between;background:#111;border-top:1px solid rgba(255,255,255,.1);z-index:50;transition:transform .15s ease-out;will-change:transform}.ios-device.safari-browser .toolbar{bottom:calc(var(--safe-area-bottom) + (100vh - var(--app-height, 100vh)))}.keyboard-visible.ios-device.safari-browser .toolbar{bottom:var(--safe-area-bottom)}.keyboard-visible.ios-device.safari-browser .keyboard-accessory-bar{bottom:calc(var(--safe-area-bottom) + 40px)}.toolbar-center{display:flex!important;align-items:center}.toolbar-center .btn-toolbar.btn-voice,.toolbar-right,.version-display{display:none!important}.toolbar-left{flex:1 1 0;min-width:0;align-items:center;gap:.3rem}.toolbar-left .toolbar-group{display:flex;flex:1 1 0;min-width:0;align-items:center;gap:.3rem}.toolbar-left .toolbar-group:first-child{flex:1 1 0;min-width:0;justify-content:space-between;gap:.3rem;flex-wrap:nowrap;align-items:center}.tab-count-group{display:none!important}.btn-toolbar{min-height:26px!important;max-height:26px!important;height:26px!important;padding:0 .5rem!important;font-size:.65rem!important;border-radius:4px;line-height:26px;display:inline-flex;align-items:center;justify-content:center;font-weight:500;letter-spacing:.01em;color:#fff}.run-btn-group{display:flex;flex:0 0 auto}.btn-toolbar.btn-run{flex:0 0 auto;padding:0 .6rem!important;font-weight:500;border-radius:4px 0 0 4px!important;border-right:none!important}.btn-toolbar.btn-run svg{width:10px;height:10px;margin-right:3px}.btn-toolbar.btn-run-gear{flex:0 0 auto;padding:0 .35rem!important;min-width:unset!important;border-radius:0 4px 4px 0!important;border-left:1px solid rgba(255,255,255,.15)!important}.btn-toolbar.btn-run-gear svg{width:10px;height:10px}.btn-toolbar.btn-run.mode-claude,.btn-toolbar.btn-run-gear.mode-claude{background:#1e3a5f;border-color:#3b82f64d;color:#93c5fd}.btn-toolbar.btn-run.mode-claude:active,.btn-toolbar.btn-run-gear.mode-claude:active{background:#2563eb;border-color:#3b82f680}.btn-toolbar.btn-run.mode-opencode,.btn-toolbar.btn-run-gear.mode-opencode{background:#0a2e2a;border-color:#10b9814d;color:#6ee7b7}.btn-toolbar.btn-run.mode-opencode:active,.btn-toolbar.btn-run-gear.mode-opencode:active{background:#0d4a40;border-color:#10b98180}.btn-toolbar.btn-run.mode-gemini,.btn-toolbar.btn-run-gear.mode-gemini{background:#10243f;border-color:#60a5fa4d;color:#dbeafe}.btn-toolbar.btn-run.mode-gemini:active,.btn-toolbar.btn-run-gear.mode-gemini:active{background:#174ea6;border-color:#60a5fa80}.btn-toolbar.btn-run.mode-antigravity,.btn-toolbar.btn-run-gear.mode-antigravity{background:#0b2b33;border-color:#22d3ee4d;color:#cffafe}.btn-toolbar.btn-run.mode-antigravity:active,.btn-toolbar.btn-run-gear.mode-antigravity:active{background:#0e7490;border-color:#22d3ee80}.btn-toolbar.btn-run.mode-pi,.btn-toolbar.btn-run-gear.mode-pi{background:#33121f!important;border-color:#f472b64d!important;color:#fce7f3!important}.btn-toolbar.btn-run.mode-pi:active,.btn-toolbar.btn-run-gear.mode-pi:active{background:#9d174d!important;border-color:#f472b680!important}.btn-toolbar.btn-run.mode-grok,.btn-toolbar.btn-run-gear.mode-grok{background:#1c1c1f!important;border-color:#d4d4d84d!important;color:#f4f4f5!important}.btn-toolbar.btn-run.mode-grok:active,.btn-toolbar.btn-run-gear.mode-grok:active{background:#3f3f46!important;border-color:#d4d4d880!important}.btn-toolbar.btn-run.mode-deepseek,.btn-toolbar.btn-run-gear.mode-deepseek{background:#16225f!important;border-color:#7c93ff59!important;color:#eef2ff!important}.btn-toolbar.btn-run.mode-deepseek:active,.btn-toolbar.btn-run-gear.mode-deepseek:active{background:#3350e6!important;border-color:#96aaff8c!important}.btn-toolbar.btn-run.mode-omp,.btn-toolbar.btn-run-gear.mode-omp{background:#312e81!important;border-color:#818cf84d!important;color:#e0e7ff!important}.btn-toolbar.btn-run.mode-omp:active,.btn-toolbar.btn-run-gear.mode-omp:active{background:#4f46e5!important;border-color:#818cf880!important}.run-mode-menu{bottom:100%;left:0;margin-bottom:6px;min-width:160px;max-width:80vw}.run-mode-option{padding:10px 12px;font-size:.8rem;cursor:pointer;-webkit-tap-highlight-color:rgba(255,255,255,.1)}.run-mode-row-btn{width:34px;height:34px;font-size:1rem;-webkit-tap-highlight-color:rgba(255,255,255,.1)}.run-mode-webview-delete{font-size:1.2rem}.run-mode-history{-webkit-overflow-scrolling:touch;touch-action:manipulation}.btn-toolbar.btn-stop{display:flex!important;flex:0 0 auto;padding:0 8px!important;min-width:unset;order:3}.btn-toolbar.btn-stop svg{width:10px;height:10px;margin-right:0}.btn-toolbar.btn-shell{display:none!important}.btn-toolbar.btn-enter{display:flex!important;flex:0 0 auto;align-items:center;justify-content:center;min-width:54px;width:54px;white-space:nowrap;padding:0 8px!important;overflow:hidden;font-size:.65rem;font-weight:600;letter-spacing:.01em;background:#1e3a5fd9!important;border:1px solid rgba(59,130,246,.45)!important;color:#dbeafe!important;order:4}.btn-toolbar.btn-enter:hover,.btn-toolbar.btn-enter:active{background:#254a7af2!important;border-color:#3b82f6b3!important;color:#fff!important}.case-select-group{display:none!important}.toolbar-left .toolbar-group:first-child{width:100%;gap:8px}.btn-toolbar.btn-case-mobile{display:flex!important;flex:1 1 0!important;min-width:0;padding:0 8px!important;order:2;overflow:hidden;justify-content:center;gap:4px}.btn-toolbar.btn-case-mobile #mobileCaseName{max-width:none;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.btn-case-settings-mobile{display:inline-flex!important;align-items:center;justify-content:center;width:26px;height:26px;background:transparent;border:1px solid rgba(255,255,255,.2);border-radius:4px;color:#9ca3af;cursor:pointer;flex-shrink:0;order:1}.btn-case-settings-mobile:active{background:#ffffff1a;color:#fff}@media(max-width:374px){.toolbar{padding:0 2px}.toolbar-left,.toolbar-left .toolbar-group,.toolbar-left .toolbar-group:first-child{gap:2px}}.btn-case-settings-mobile{display:none!important}.case-settings-popover-mobile{position:fixed;bottom:calc(var(--safe-area-bottom) + 46px);left:8px;right:8px;background:#1e1e1e;border:1px solid rgba(255,255,255,.15);border-radius:8px;padding:.6rem .75rem;z-index:1000;box-shadow:0 4px 16px #00000080;display:block}.case-settings-popover-mobile.hidden{display:none!important}.case-settings-popover-mobile .checkbox-inline{display:flex;align-items:center;gap:6px;font-size:.75rem;color:#e5e7eb}.case-settings-popover-mobile .form-hint{display:block;margin-top:.2rem;font-size:.6rem;color:#6b7280}.keyboard-accessory-bar{display:none;position:fixed;bottom:calc(var(--safe-area-bottom) + 40px);left:0;right:0;height:44px;background:#1a1a1a;border-top:1px solid rgba(255,255,255,.1);padding:6px 8px;padding-left:calc(8px + var(--safe-area-left));padding-right:calc(8px + var(--safe-area-right));gap:8px;align-items:center;overflow-x:auto;overflow-y:hidden;-webkit-overflow-scrolling:touch;z-index:51;transition:transform .15s ease-out;will-change:transform}.keyboard-accessory-bar.visible{display:flex}.keyboard-accessory-bar::-webkit-scrollbar{display:none}.accessory-btn{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;gap:4px;padding:6px 12px;background:#2a2a2a;border:1px solid rgba(255,255,255,.15);border-radius:6px;color:#e5e5e5;font-size:.65rem;font-weight:500;cursor:pointer;transition:background .15s,border-color .15s}.accessory-btn.confirming{background:#6b4f00;border-color:#b8860b;color:#ffd54f}.accessory-btn.accessory-btn-ctrl.armed{background:#2563eb;border-color:#3b82f6e6;color:#fff;font-weight:700;box-shadow:0 0 0 2px #3b82f673}.accessory-btn:active{background:#3a3a3a}.accessory-btn svg{width:14px;height:14px}.accessory-btn-arrow{padding:6px 10px;background:#2563eb;border-color:#3b82f680;color:#fff}.accessory-btn-arrow:active{background:#1d4ed8}.accessory-btn-dismiss{margin-left:auto;flex:1 1 0;max-width:100px;padding:10px 8px;background:#2563eb;border-color:#3b82f680;color:#fff;font-weight:600}.accessory-btn-dismiss svg{width:22px;height:22px}.accessory-btn-dismiss:active{background:#1d4ed8}.voice-preview{bottom:calc(var(--safe-area-bottom) + 94px);font-size:.8rem;max-width:90%;padding:6px 14px}.btn-case-add,.btn-case-settings,.toolbar-select{display:none!important}.toolbar .btn-case-add{min-width:26px!important;max-width:26px!important;width:26px!important;min-height:26px!important;max-height:26px!important;height:26px!important;padding:0!important;font-size:.9rem;font-weight:700;display:inline-flex!important;align-items:center;justify-content:center;line-height:1;border-radius:4px;background:transparent;border:1px solid rgba(255,255,255,.15);color:#9ca3af}.btn-case-add:hover,.btn-case-add:active{background:#ffffff1a;color:#fff}.monitor-panel,.subagents-panel{width:100%;max-width:100%;left:0;right:0;border-radius:8px 8px 0 0;bottom:calc(44px + 2rem + var(--safe-area-bottom));max-height:35vh}.modal{z-index:1300}.modal-content{width:100%;max-width:100%;height:100%;max-height:100%;border-radius:0;margin:0;display:flex;flex-direction:column}.modal-content.modal-sm,.modal-content.readmymind-modal{height:auto;max-height:85vh;border-radius:12px;margin:1rem;width:calc(100% - 2rem)}.readmymind-modal .modal-footer{flex-wrap:wrap}.readmymind-modal .modal-footer .btn-toolbar{flex:1 1 auto;justify-content:center;min-height:38px}.readmymind-alt,.readmymind-steer-input{min-height:38px}.ios-device .modal-content{padding-top:var(--safe-area-top);padding-bottom:var(--safe-area-bottom);padding-left:var(--safe-area-left);padding-right:var(--safe-area-right)}.modal-header{padding:.75rem 1rem}.modal-header h3{font-size:1rem}.modal-body{padding:.75rem 1rem;flex:1;min-height:0;overflow-y:auto;-webkit-overflow-scrolling:touch}.away-digest-modal{width:100%;max-width:100%;height:100%;max-height:100%}.away-digest-ranges{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:.4rem}.away-digest-ranges .filter-btn{min-height:38px;padding:.4rem .5rem}.away-digest-custom-range,.away-digest-custom-range.active{grid-template-columns:1fr}.away-digest-summary{grid-template-columns:repeat(2,minmax(0,1fr));gap:.5rem}.away-digest-item{grid-template-columns:1fr;gap:.5rem}.away-digest-action{width:100%;min-height:38px}.modal-footer,.form-actions{padding:.75rem 1rem;padding-bottom:calc(.75rem + var(--safe-area-bottom))}.ios-device .terminal-container{padding-bottom:var(--safe-area-bottom)}.main{flex:1;min-height:0}.cli-info-bar{display:block}.terminal-container{height:100%;min-height:0;position:relative;overflow:visible;touch-action:none}.terminal-container .xterm,.terminal-container .xterm-viewport,.terminal-container .xterm-screen{touch-action:none}.response-viewer{padding-bottom:var(--safe-area-bottom, 0px);max-height:88vh;max-height:92dvh}.response-viewer-body{font-size:14.5px;line-height:1.65;padding:16px 16px 24px;--rv-content-max: 100%}.response-viewer-body .rv-text pre,.response-viewer-body pre{padding:12px 14px;margin-left:-4px;margin-right:-4px;border-radius:6px}.response-viewer-body .rv-text pre code,.response-viewer-body pre code{font-size:11.5px;line-height:1.5}.response-viewer-body .rv-text h1,.response-viewer-body>h1{font-size:1.35em}.response-viewer-body .rv-text h2,.response-viewer-body>h2{font-size:1.2em}.response-viewer-body .rv-text h3,.response-viewer-body>h3{font-size:1.08em}.welcome-content{max-width:calc(100vw - 1.5rem);padding:1rem .75rem}.welcome-title{font-size:1.2rem;margin-bottom:.5rem}.welcome-desc{font-size:.8rem;margin-bottom:.4rem}.welcome-actions{flex-direction:column;gap:.5rem;margin-top:1rem}.welcome-btn{width:100%;justify-content:center;min-height:44px;padding:.75rem 1rem;font-size:.85rem}.history-show-more{display:block;margin-bottom:.75rem}.welcome-ralph-link{display:block;margin:.75rem auto 0}.welcome-hint{font-size:.7rem;margin-top:.75rem}.modal-wizard{display:flex;flex-direction:column}.wizard-progress{padding:.5rem}.wizard-step{padding:.3rem}.wizard-step-number{width:24px;height:24px;font-size:.7rem}.wizard-step-label{display:none}.timer-banner{padding-left:calc(.5rem + var(--safe-area-left));padding-right:calc(.5rem + var(--safe-area-right))}.respawn-banner{padding:.3rem .5rem;padding-left:calc(.5rem + var(--safe-area-left));padding-right:calc(.5rem + var(--safe-area-right));font-size:.65rem}.respawn-compact-layout{flex-direction:column;gap:.15rem}.respawn-status-col{flex-shrink:1;min-width:0;gap:.1rem}.respawn-status-row1{flex-wrap:wrap;gap:.25rem;row-gap:.1rem}.respawn-state{font-size:.6rem;padding:.05rem .3rem}.respawn-banner .detection-confidence{font-size:.5rem;padding:.02rem .2rem}.respawn-cycles{font-size:.55rem}.respawn-timer{font-size:.55rem;padding:0 .25rem}.respawn-tokens{font-size:.55rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:120px}.respawn-indicator{font-size:.65rem}.respawn-banner .btn-icon-only{min-width:36px;min-height:36px;font-size:1rem;display:flex;align-items:center;justify-content:center;margin-left:auto;border-radius:6px;flex-shrink:0}.respawn-status-row2{font-size:.55rem;gap:.3rem;min-height:0;flex-wrap:wrap}.respawn-banner .detection-hook,.respawn-banner .detection-ai-check,.respawn-banner .detection-status{font-size:.55rem;padding:.02rem .2rem}.respawn-countdown-timers{gap:.2rem}.respawn-countdown-timer{font-size:.5rem;padding:.02rem .2rem;gap:.15rem}.respawn-countdown-timer .respawn-timer-bar{display:none}.respawn-action-log{border-left:none;border-top:1px solid rgba(34,197,94,.15);padding-left:0;padding-top:.15rem;max-height:1.4em;font-size:.55rem;overflow:hidden}.respawn-header{flex-direction:row;gap:.4rem;align-items:center}.respawn-header .respawn-actions{display:flex;gap:.3rem;flex-shrink:0}.respawn-header .respawn-actions .btn-toolbar{min-height:28px!important;font-size:.7rem!important;padding:.2rem .5rem!important;border-radius:5px}.duration-presets{display:flex;flex-wrap:wrap;gap:.2rem}.duration-preset-btn{min-height:24px;padding:.1rem .4rem;font-size:.6rem;border-radius:4px;text-align:center}.duration-custom{display:flex;gap:.2rem;align-items:center}.duration-custom-input.visible{flex:0 1 auto}.duration-custom-input input{width:64px;min-height:24px;font-size:16px;padding:.1rem .3rem}.preset-selector{display:grid;grid-template-columns:1fr 1fr;gap:.25rem}.preset-selector select{grid-column:1 / -1;min-height:32px;font-size:16px;border-radius:5px;padding:.2rem .4rem}.preset-selector .btn{min-height:32px;font-size:.65rem;border-radius:5px;padding:.2rem .4rem}#sessionOptionsModal textarea{font-size:16px;min-height:32px!important;max-height:56px;height:auto!important;border-radius:6px;padding:.3rem .5rem}#modalRespawnPrompt{min-height:32px!important;max-height:56px}#modalRespawnKickstart{min-height:32px!important;max-height:48px}#sessionOptionsModal .checkbox-inline{min-height:30px;font-size:.75rem;padding:.15rem 0;gap:.4rem}#sessionOptionsModal .checkbox-inline input[type=checkbox]{width:18px;height:18px}#sessionOptionsModal .respawn-loop-title{font-size:.75rem}#sessionOptionsModal .respawn-loop-box .checkbox-inline{font-size:.65rem}#sessionOptionsModal .respawn-options-row{gap:.5rem}#sessionOptionsModal .form-section-header{margin-top:.75rem;padding-top:.5rem;font-size:.65rem}#sessionOptionsModal .form-row{margin-bottom:.5rem}#sessionOptionsModal .form-row label{font-size:.65rem;margin-bottom:.2rem}#sessionOptionsModal .form-hint{font-size:.6rem;margin-top:.2rem}.context-setting{padding:.625rem}.context-setting-header{flex-wrap:wrap;gap:.4rem}.context-setting-header .input-suffix-sm input{width:60px;font-size:16px;min-height:36px}.context-setting input[type=text]{font-size:16px;min-height:36px;padding:.4rem .6rem;border-radius:6px}.color-picker{gap:8px}.color-swatch{width:36px;height:36px;border-radius:6px}.form-row-switch{min-height:40px;gap:.4rem}.context-settings-grid input[type=number]{font-size:16px;min-height:36px}.ralph-limits-grid{grid-template-columns:1fr 1fr;gap:.5rem}.ralph-limits-grid .form-col input[type=number]{font-size:16px;min-height:36px;padding:.4rem .5rem;border-radius:6px}#modalRalphPhrase{font-size:16px;min-height:40px;border-radius:6px}.ralph-config-actions{margin-top:1rem}.ralph-config-actions .btn-toolbar{width:100%;min-height:44px;font-size:.85rem;border-radius:8px}.run-summary-filters{gap:.3rem;margin-bottom:.5rem}.filter-btn{padding:.35rem .75rem;font-size:.7rem;min-height:32px}.timeline-event{padding:.4rem .5rem;margin-bottom:.25rem;font-size:.7rem}.run-summary-footer{flex-direction:column;gap:.4rem;padding:.5rem 0}.run-summary-actions{flex-wrap:wrap;gap:.3rem}.run-summary-actions .btn-toolbar{flex:1;min-height:36px;font-size:.7rem;white-space:nowrap}.auto-refresh-label{font-size:.7rem}.ralph-panel{font-size:.75rem}.ralph-summary{padding:.4rem .5rem;padding-left:calc(.5rem + var(--safe-area-left));padding-right:calc(.5rem + var(--safe-area-right))}.project-insights-panel{max-width:100%;font-size:.65rem;bottom:calc(44px + 2rem + var(--safe-area-bottom))}.file-browser-panel{max-width:100%;max-height:50vh;bottom:calc(44px + 2rem + var(--safe-area-bottom))}.file-preview-window{width:100vw;max-width:100vw;height:var(--app-height, 100vh);max-height:var(--app-height, 100vh);border-radius:0;border-left:none;border-right:none}.file-preview-editbar{padding-bottom:calc(.4rem + var(--safe-area-bottom))}.file-preview-overlay .file-preview-footer{padding-bottom:calc(.35rem + var(--safe-area-bottom))}.file-preview-body textarea.file-preview-editor{font-size:16px}.notification-drawer{width:100%;max-width:100%;right:0;border-radius:0;padding-left:var(--safe-area-left);padding-right:var(--safe-area-right);padding-bottom:var(--safe-area-bottom)}input,textarea,[contenteditable]{scroll-margin-bottom:200px;scroll-margin-top:80px}.keyboard-visible .modal-body{max-height:40vh;overflow-y:auto}.keyboard-visible #createCaseModal .modal-body{max-height:60vh}.mobile-case-picker .modal-backdrop{background:#00000080}.mobile-case-picker-sheet{max-height:60vh;padding-bottom:var(--safe-area-bottom);animation:slideUp .2s ease-out}@keyframes slideUp{0%{transform:translateY(100%)}to{transform:translateY(0)}}.mobile-case-picker-header .modal-close{width:32px;height:32px;font-size:1.5rem}.mobile-case-picker-footer{padding-bottom:calc(12px + var(--safe-area-bottom))}#createCaseModal .form-row{margin-bottom:1rem}#createCaseModal .form-row label{font-size:.8rem;margin-bottom:.4rem;font-weight:500;color:#e5e7eb}#createCaseModal .form-row input[type=text]{min-height:44px;font-size:16px;padding:.5rem .75rem;border-radius:8px}#createCaseModal .form-row .form-hint{font-size:.65rem;margin-top:.35rem;line-height:1.4}#createCaseModal .form-actions{padding:.75rem 1rem;padding-bottom:calc(.75rem + var(--safe-area-bottom));gap:.75rem}#createCaseModal .form-actions .btn-toolbar{min-height:44px!important;max-height:44px!important;height:44px!important;font-size:.85rem!important;font-weight:500;border-radius:8px}#caseModalSubmit.loading{opacity:.6;pointer-events:none}#createCaseModal.from-mobile .modal-content{animation:caseModalSlideUp .25s ease-out}@keyframes caseModalSlideUp{0%{transform:translateY(30px);opacity:0}to{transform:translateY(0);opacity:1}}.btn-case-create-mobile{min-height:48px!important;max-height:48px!important;height:48px!important;font-size:.85rem!important;font-weight:500;border-radius:10px}.settings-grid{grid-template-columns:1fr;gap:.35rem}.settings-grid-3col{grid-template-columns:1fr 1fr 1fr}.settings-item{padding:.35rem .5rem;font-size:.7rem}.settings-item-label{font-size:.7rem}.settings-section-header{font-size:.6rem;padding:.35rem 0 .2rem;margin-top:.5rem}.form-row{margin-bottom:.5rem}.form-row label{font-size:.7rem;margin-bottom:.2rem}.form-row .form-hint{font-size:.6rem}.form-row input[type=text],.form-row input[type=number],.form-row textarea,.form-row .form-select,.form-row select{font-size:.75rem;padding:.35rem .5rem;min-height:32px}.form-row-switch{gap:.3rem}.form-row-switch>label:first-child{font-size:.7rem}.form-section-header{font-size:.6rem;margin-top:.75rem}.event-type-grid{grid-template-columns:1fr 36px 36px 36px;gap:4px 4px;padding:6px;margin-top:6px}.event-header{font-size:.55rem}.event-label{font-size:.65rem}.event-type-grid input[type=checkbox]{width:12px;height:12px}.form-actions{gap:.5rem}.form-actions .btn-toolbar{flex:1;min-height:36px!important;max-height:36px!important;height:36px!important;font-size:.75rem!important}.subagent-window{position:fixed;width:calc(100% - 8px);max-width:calc(100% - 8px);height:110px;min-height:80px;max-height:110px;min-width:200px;border-radius:6px;resize:none;box-shadow:0 2px 8px #0006}.subagent-window:after{display:none}.subagent-window-header{padding:.2rem .4rem;min-height:24px}.subagent-window-title{gap:.2rem;overflow:hidden}.subagent-window-title .icon{font-size:.7rem}.subagent-window-title .id{font-size:.6rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:45vw}.subagent-window-title .status{font-size:.45rem;padding:.05rem .15rem}.subagent-model-badge{font-size:.45rem!important;padding:.05rem .15rem!important}.subagent-window-actions button{font-size:.7rem;padding:.15rem .35rem;min-width:26px;min-height:26px;display:flex;align-items:center;justify-content:center}.subagent-window-body{font-size:.6rem;padding:.2rem .35rem}.subagent-window-body .activity-line{gap:.15rem;padding:.05rem 0}.subagent-window-body .activity-line .time{font-size:.5rem}.subagent-window-body .activity-line .tool-name,.subagent-window-body .activity-line .tool-detail{font-size:.55rem}.subagent-window-parent{display:none}.session-tab .tab-subagent-badge{height:14px;padding:0 3px;border-radius:7px;margin-left:2px}.session-tab .tab-subagent-badge .subagent-label{font-size:.45rem}.subagent-dropdown{position:fixed!important;left:8px!important;right:8px!important;bottom:auto!important;min-width:auto!important;max-width:none!important;border-radius:8px;transform:none!important}.mobile-overview.visible{position:absolute;inset:0;z-index:10;display:flex;flex-direction:column;gap:.75rem;padding:.75rem .6rem calc(1rem + var(--safe-area-bottom));background:var(--bg-dark);overflow-y:auto;-webkit-overflow-scrolling:touch;overscroll-behavior:contain}.mobile-overview-top{display:flex;align-items:center;justify-content:space-between;gap:.5rem;padding:0}.mobile-overview-brand{display:inline-flex;align-items:center;min-height:48px;font-size:1.5rem;font-weight:800;line-height:1;color:var(--accent-hover);letter-spacing:-.02em}.mobile-overview-header{position:relative;display:flex;flex-direction:column}.mobile-overview-run-group{display:flex;align-items:stretch;flex-shrink:0}.mobile-overview-run-group .mobile-overview-run{display:inline-flex;align-items:center;gap:.4rem;min-height:48px!important;height:48px!important;max-height:48px!important;padding:0 1.15rem!important;font-size:.95rem!important;line-height:1;font-weight:700;font-family:inherit;border-radius:10px 0 0 10px!important}.mobile-overview-run-mode{font-weight:600;font-size:.85rem;opacity:.8}.mobile-overview-run-group .mobile-overview-run-caret{display:inline-flex;align-items:center;justify-content:center;min-height:48px!important;height:48px!important;max-height:48px!important;min-width:48px!important;width:48px!important;padding:0!important;line-height:1;font-family:inherit;border-radius:0 10px 10px 0!important}.mobile-overview-run-group .mobile-overview-run-caret svg{display:block;width:20px!important;height:20px!important;margin:0!important}.mobile-overview-run-menu{display:flex;flex-direction:column;gap:.15rem;margin:.5rem 0 0;padding:.35rem;border:1px solid var(--border);border-radius:12px;background:var(--floating-bg);box-shadow:var(--elevated-shadow)}.mobile-overview-run-option{display:flex;align-items:center;gap:.5rem;min-height:44px;padding:0 .6rem;border:none;border-radius:8px;background:transparent;color:var(--text);font-family:inherit;font-size:.82rem;text-align:left}.mobile-overview-run-option.selected{background:var(--control-bg-hover)}.mobile-overview-run-option:active{background:var(--bg-hover)}.mobile-overview-run-option--add{color:var(--accent)}.mobile-overview-run-header{padding:.4rem .6rem .2rem;font-size:.6rem;font-weight:700;letter-spacing:.09em;text-transform:uppercase;color:var(--text-muted)}.mobile-overview-section{display:flex;flex-direction:column;gap:.4rem}.mobile-overview-heading{display:flex;align-items:center;gap:.35rem;margin:.35rem 0 0;padding:0;font-size:.65rem;font-weight:700;letter-spacing:.09em;text-transform:uppercase;color:var(--text-muted)}.mobile-overview-heading-count{color:var(--text-dim);font-weight:600}.mobile-overview-empty{margin:0;padding:.5rem 0;font-size:.75rem;color:var(--text-muted)}.mobile-overview-row{display:flex;align-items:center;gap:.6rem;width:100%;min-height:56px;padding:.5rem .7rem;border:1px solid var(--border);border-radius:12px;background:var(--bg-card);color:var(--text);font-family:inherit;text-align:left}.mobile-overview-row:active{background:var(--bg-hover)}.mobile-overview-row-wrap{width:100%}.mobile-overview-approval-strip{display:flex;flex-wrap:wrap;gap:.4rem;padding:.4rem .2rem .1rem}.mobile-overview-approval-btn{border:1px solid var(--border);border-radius:8px;background:var(--bg-card);color:var(--text);font-family:inherit;font-size:.72rem;padding:.35rem .6rem;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.mobile-overview-approval-btn.primary{background:var(--accent);border-color:var(--accent);color:#fff}.mobile-overview-approval-btn.danger{border-color:var(--error);color:var(--error)}.mobile-overview-row--needs{border-color:var(--red);animation:mobile-overview-blink-red 2.5s ease-in-out infinite}.mobile-overview-row--waiting{border-color:var(--yellow);animation:mobile-overview-blink-yellow 3.5s ease-in-out infinite}.mobile-overview-row--error{border-color:var(--red)}.mobile-overview-row--working{border-color:var(--green);animation:mobile-overview-breathe-green 2.2s ease-in-out infinite}@keyframes mobile-overview-breathe-green{0%,to{background:var(--bg-card);border-color:var(--border)}50%{background:#22c55e1a;border-color:var(--green)}}.mobile-overview-pill--working:after{content:"";display:inline-block;width:.75em;text-align:left;animation:mobile-overview-pill-dots 1.5s steps(1,end) infinite}@keyframes mobile-overview-pill-dots{0%{content:""}25%{content:"."}50%{content:".."}75%{content:"..."}}@keyframes mobile-overview-blink-red{0%,to{background:var(--bg-card);border-color:var(--border)}50%{background:#ef444424;border-color:var(--red)}}@keyframes mobile-overview-blink-yellow{0%,to{background:var(--bg-card);border-color:var(--border)}50%{background:#eab3081f;border-color:var(--yellow)}}.mobile-overview-row-body{display:flex;flex-direction:column;gap:.15rem;flex:1;min-width:0}.mobile-overview-row-title{display:block;font-size:.9rem;font-weight:600;color:var(--text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.mobile-overview-row-case{color:var(--text-dim);font-weight:500}.mobile-overview-row-sub{display:block;font-size:.68rem;color:var(--text-muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.mobile-overview-row-meta{display:flex;align-items:center;gap:.3rem;min-width:0;font-family:var(--font-mono, monospace);font-size:.63rem;color:var(--text-muted);white-space:nowrap;overflow:hidden}.mobile-overview-meta-item{min-width:0;overflow:hidden;text-overflow:ellipsis}.mobile-overview-meta-key{margin-right:.3rem;opacity:.6;text-transform:uppercase;letter-spacing:.05em}.mobile-overview-meta-sep{opacity:.45}.mobile-overview-row--working .mobile-overview-meta-since{color:var(--green);opacity:.95}.mobile-overview-dot{flex-shrink:0;width:9px;height:9px;border-radius:50%;background:var(--text-muted)}.mobile-overview-dot--needs,.mobile-overview-dot--error{background:var(--red)}.mobile-overview-dot--waiting{background:var(--yellow)}.mobile-overview-dot--working{background:var(--green);animation:pulse 1.5s infinite;box-shadow:0 0 8px 2px color-mix(in srgb,var(--green) 55%,transparent);will-change:opacity}.mobile-overview-dot{position:relative}.mobile-overview-dot--working:after{content:"";position:absolute;inset:-4px;border:2px solid rgba(34,197,94,.25);border-top-color:var(--green);border-radius:50%;animation:tab-load-spin .7s linear infinite}.mobile-overview-dot--idle{background:var(--green)}.mobile-overview-dot--done{background:var(--text-muted);opacity:.5}.mobile-overview-pill{flex-shrink:0;display:inline-flex;align-items:center;gap:.25rem;padding:.2rem .45rem;border:1px solid var(--border-light);border-radius:999px;font-size:.62rem;font-weight:600;color:var(--text-dim);white-space:nowrap}.mobile-overview-pill--needs,.mobile-overview-pill--error{border-color:var(--red);color:var(--red)}.mobile-overview-pill--waiting{border-color:var(--yellow);color:var(--yellow)}.mobile-overview-pill--idle,.mobile-overview-pill--working{border-color:var(--green);color:var(--green)}.mobile-overview-chevron{flex-shrink:0;color:var(--text-muted);font-size:1rem;line-height:1}.mobile-overview-row--past{background:transparent;border-style:dashed}.mobile-overview-row--past .mobile-overview-row-title{font-weight:500;color:var(--text-dim)}.mobile-overview-dot--past{background:transparent;border:1px solid var(--border-light)}.mobile-overview-pill--past{border-color:var(--border-light);color:var(--text-muted)}.mobile-overview-more{display:flex;align-items:center;justify-content:center;gap:.35rem;min-height:40px;border:none;border-radius:10px;background:var(--control-bg);color:var(--text-dim);font-family:inherit;font-size:.72rem;font-weight:600}.mobile-overview-more-count{padding:.05rem .35rem;border-radius:999px;background:var(--control-bg-hover);color:var(--text-muted)}}@media(prefers-reduced-motion:reduce){.mobile-overview-row--needs,.mobile-overview-row--waiting{animation:none}.mobile-overview-row--needs{background:#ef444424}.mobile-overview-row--waiting{background:#eab3081f}.mobile-overview-dot--working{animation:none}.mobile-overview-dot--working:after{border-color:var(--green);animation:none}.mobile-overview-row--working{animation:none}.mobile-overview-pill--working:after{content:"...";animation:none}}html:is([data-skin=paper-gray],[data-skin=solarized-light],[data-skin=catppuccin-latte],[data-skin=rose-pine-dawn]) :is(.header,.toolbar,.keyboard-accessory-bar){background:var(--glass-bg);border-color:var(--glass-border);color:var(--text)}html:is([data-skin=paper-gray],[data-skin=solarized-light],[data-skin=catppuccin-latte],[data-skin=rose-pine-dawn]) :is(.btn-voice-mobile,.btn-settings-mobile,.btn-toolbar.btn-shell,.toolbar .btn-case-add,.accessory-btn:not(.armed)){background:var(--control-bg);border-color:var(--control-border);color:var(--text-dim)}html:is([data-skin=paper-gray],[data-skin=solarized-light],[data-skin=catppuccin-latte],[data-skin=rose-pine-dawn]) :is(.btn-voice-mobile:active,.btn-settings-mobile:active,.btn-toolbar.btn-shell:hover,.btn-toolbar.btn-shell:active,.btn-case-add:hover,.btn-case-add:active,.accessory-btn:active){background:var(--control-bg-hover);border-color:var(--control-border-hover);color:var(--text)}html:is([data-skin=paper-gray],[data-skin=solarized-light],[data-skin=catppuccin-latte],[data-skin=rose-pine-dawn]) :is(.btn-toolbar.btn-run.mode-claude,.btn-toolbar.btn-run-gear.mode-claude){background:linear-gradient(135deg,var(--accent-grad-a),var(--accent-grad-b));border-color:var(--accent);color:var(--accent-ink)}html:is([data-skin=paper-gray],[data-skin=solarized-light],[data-skin=catppuccin-latte],[data-skin=rose-pine-dawn]) :is(.btn-toolbar.btn-run.mode-opencode,.btn-toolbar.btn-run-gear.mode-opencode){background:linear-gradient(135deg,var(--accent-d),var(--accent-grad-b));border-color:var(--accent);color:var(--accent-ink)}html:is([data-skin=paper-gray],[data-skin=solarized-light],[data-skin=catppuccin-latte],[data-skin=rose-pine-dawn]) :is(.btn-toolbar.btn-run.mode-gemini,.btn-toolbar.btn-run-gear.mode-gemini){background:linear-gradient(135deg,#174ea6,#4f46e5);border-color:#315fc3;color:#fff}html:is([data-skin=paper-gray],[data-skin=solarized-light],[data-skin=catppuccin-latte],[data-skin=rose-pine-dawn]) :is(.btn-toolbar.btn-run.mode-antigravity,.btn-toolbar.btn-run-gear.mode-antigravity){background:linear-gradient(135deg,#0e7490,#0891b2);border-color:#155e75;color:#fff}html:is([data-skin=paper-gray],[data-skin=solarized-light],[data-skin=catppuccin-latte],[data-skin=rose-pine-dawn]) :is(.btn-toolbar.btn-run.mode-pi,.btn-toolbar.btn-run-gear.mode-pi){background:linear-gradient(135deg,#be185d,#db2777);border-color:#9d174d;color:#fff}html:is([data-skin=paper-gray],[data-skin=solarized-light],[data-skin=catppuccin-latte],[data-skin=rose-pine-dawn]) :is(.btn-toolbar.btn-run.mode-omp,.btn-toolbar.btn-run-gear.mode-omp){background:linear-gradient(135deg,#4f46e5,#6366f1);border-color:#4338ca;color:#fff}html:is([data-skin=paper-gray],[data-skin=solarized-light],[data-skin=catppuccin-latte],[data-skin=rose-pine-dawn]) :is(.btn-toolbar.btn-run.mode-grok,.btn-toolbar.btn-run-gear.mode-grok){background:linear-gradient(135deg,#27272a,#52525b);border-color:#18181b;color:#fff}html:is([data-skin=paper-gray],[data-skin=solarized-light],[data-skin=catppuccin-latte],[data-skin=rose-pine-dawn]) :is(.btn-toolbar.btn-run.mode-deepseek,.btn-toolbar.btn-run-gear.mode-deepseek){background:linear-gradient(135deg,#2740c4,#4d6bfe);border-color:#1b2a8f;color:#fff}html:is([data-skin=paper-gray],[data-skin=solarized-light],[data-skin=catppuccin-latte],[data-skin=rose-pine-dawn]) .btn-toolbar.btn-run-gear{border-left-color:var(--control-border-hover)!important}html:is([data-skin=paper-gray],[data-skin=solarized-light],[data-skin=catppuccin-latte],[data-skin=rose-pine-dawn]) :is(.case-settings-popover-mobile,.mobile-case-picker-sheet){background:var(--floating-bg);border-color:var(--control-border);color:var(--text);box-shadow:var(--elevated-shadow)}html:is([data-skin=paper-gray],[data-skin=solarized-light],[data-skin=catppuccin-latte],[data-skin=rose-pine-dawn]) :is(.case-settings-popover-mobile .checkbox-inline,#createCaseModal .form-row label){color:var(--text)}html:is([data-skin=paper-gray],[data-skin=solarized-light],[data-skin=catppuccin-latte],[data-skin=rose-pine-dawn]) .case-settings-popover-mobile .form-hint{color:var(--text-muted)}html:is([data-skin=paper-gray],[data-skin=solarized-light],[data-skin=catppuccin-latte],[data-skin=rose-pine-dawn]) .mobile-case-picker .modal-backdrop{background:var(--modal-backdrop)}.ios-device.safari-browser{overscroll-behavior:none}@media(hover:none)and (pointer:coarse){.session-tab .tab-close,.session-tab .tab-gear{opacity:1;width:auto;padding:.15rem .25rem;align-items:center;justify-content:center}.btn-toolbar:hover,.btn-icon-header:hover{transform:none}.subagent-dropdown-trigger:active+.subagent-dropdown-menu,.subagent-dropdown-trigger:focus+.subagent-dropdown-menu{display:block}}@media(max-width:430px){.attachment-history-drawer{top:0;bottom:0;width:100%;max-width:100%;height:100vh;height:100dvh;border-left:none;border-radius:0;padding-top:var(--safe-area-top);padding-left:var(--safe-area-left);padding-right:var(--safe-area-right);padding-bottom:var(--safe-area-bottom)}.attachment-history-header{padding:12px}.attachment-history-list{padding:6px}.attachment-history-item{grid-template-columns:104px minmax(0,1fr);gap:8px;padding:8px 6px}.attachment-history-thumb{width:104px}.attachment-history-actions{gap:4px}.attachment-history-actions button{padding:4px 7px}}@media(max-width:430px){.offline-banner{padding:.4rem .5rem;padding-left:calc(.5rem + var(--safe-area-left));padding-right:calc(.5rem + var(--safe-area-right));font-size:.7rem;gap:.4rem}.offline-banner-detail{display:none}.offline-banner-retry{padding:.25rem .5rem;margin-left:auto}.offline-overlay-card{padding:22px 18px 18px}.offline-overlay-title{font-size:1.05rem}.offline-overlay-actions{flex-direction:column}.offline-overlay-btn{width:100%;padding:.65rem 1rem}}@media(max-width:860px){:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .modal-content.modal-lg{width:100%;max-width:100%;height:100%;max-height:100%}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-body{display:flex;flex-direction:column;min-height:0}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-rail{flex-direction:row;align-items:center;border-right:0;border-bottom:1px solid var(--border);background:transparent;padding:10px 14px;overflow:visible;flex-shrink:0}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-rail-items,:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-rail-foot{display:none}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-search{margin:0;flex:1}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-search input{padding:9px 10px 9px 30px;border-radius:10px}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-head-actions:has(.set-head-save){padding:3px;border:1px solid var(--border);border-radius:12px;background:var(--bg-input)}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-head-save{display:inline-flex;height:36px;padding:0 16px;font-size:.86rem}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-head-actions .modal-close{width:36px;height:36px;font-size:1.35rem}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-foot{display:none}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-doc{padding:0 14px 34px;flex:1}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-jump{display:flex;position:sticky;top:0;z-index:4;align-items:center;gap:8px;width:100%;margin:10px 0 2px;padding:10px 12px;border-radius:11px;font:inherit;font-size:.82rem;color:var(--text);background:rgba(var(--accent-rgb),.13);border:1px solid rgba(var(--accent-rgb),.3);-webkit-backdrop-filter:blur(14px);backdrop-filter:blur(14px);cursor:pointer}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-jump-ico{color:var(--accent);flex-shrink:0}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-jump-label{font-weight:580;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-jump-chev{margin-left:auto;color:var(--text-muted);flex-shrink:0;transition:transform .18s}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-jump[aria-expanded=true] .set-jump-chev{transform:rotate(180deg)}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-jump-veil{display:none;position:fixed;inset:0;z-index:8;background:#04080d9e}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-jump-menu{display:none;position:absolute;left:14px;right:14px;z-index:9;padding:7px;border-radius:16px;background:var(--bg-card);border:1px solid var(--control-border);box-shadow:var(--elevated-shadow);max-height:70vh;overflow-y:auto}#appSettingsModal.jump-open .set-jump-veil,#appSettingsModal.jump-open .set-jump-menu{display:block}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-jump-row{display:flex;align-items:center;gap:11px;width:100%;padding:11px 12px;border:0;border-radius:11px;background:transparent;color:var(--text-dim);font:inherit;font-size:.82rem;text-align:left}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-jump-row svg{color:var(--text-muted);flex-shrink:0}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-jump-row .set-jump-count{margin-left:auto;font-size:.62rem;color:var(--text-muted)}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-jump-row.active{background:rgba(var(--accent-rgb),.14);color:var(--text);font-weight:570}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-jump-row.active svg{color:var(--accent)}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-section{padding-top:0}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-section+.set-section{border-top:0;margin-top:0}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-section-head{gap:7px;margin:18px 0 2px}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-section-head svg{padding:0;border:0;background:none;color:var(--text-muted);width:12px;height:12px}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-section-head h2{font-size:.6rem;font-weight:640;letter-spacing:.1em;text-transform:uppercase;color:var(--text-muted)}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-section-head:after{content:"";flex:1;height:1px;background:linear-gradient(90deg,var(--border),transparent)}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-section-blurb{display:none}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-preview{margin-bottom:12px}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-preview-stage{min-height:62px}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-group{margin-top:14px}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-group+.set-group{margin-top:16px}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-group-head{margin-bottom:7px;padding:0 3px}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-group-hint{padding:0 3px}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-group-body{gap:0;background:#ffffff09;border:1px solid rgba(255,255,255,.06);border-radius:13px;overflow:hidden}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-group-body>.set-row{background:transparent;border:0;border-radius:0;padding:12px 13px;gap:12px}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-group-body>.set-row+.set-row{border-top:1px solid rgba(255,255,255,.055)}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-group-body>.set-chips,:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-group-body>.set-modelgrid,:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-group-body>.set-minigrid,:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-group-body>#appSettingsShortcutsList{padding:12px}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-group-body>.event-type-grid{padding:12px;margin:0}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-row-label{font-size:.84rem}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-row-desc{font-size:.69rem;max-width:none}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-row.has-field{flex-direction:column;align-items:stretch;gap:9px}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-row.has-field .set-select,:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-row.has-field .set-input{width:100%;min-width:0;max-width:none;box-sizing:border-box}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-row-actions-wide{width:100%}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-row-actions-wide .set-input{flex:1;min-width:0}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-num{width:76px}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .switch-sm{width:40px;height:24px}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .switch-sm .slider:before{height:18px;width:18px}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .switch-sm input:checked+.slider:before{transform:translate(16px)}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-chip{font-size:.78rem;padding:9px 14px}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-modelgrid{grid-template-columns:repeat(2,minmax(0,1fr));gap:8px}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-minigrid{grid-template-columns:1fr}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-mini .set-select{width:148px}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-segment{overflow-x:auto;scrollbar-width:none}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-segment::-webkit-scrollbar{display:none}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-segment button{flex:0 0 auto;padding:8px 12px}}@media(max-width:860px){:is(#sessionOptionsModal,#createCaseModal) .set-rail{padding:8px 10px}:is(#sessionOptionsModal,#createCaseModal) .set-rail-items{display:flex;flex-direction:row;flex:1;min-width:0;gap:4px;overflow-x:auto;scrollbar-width:none}:is(#sessionOptionsModal,#createCaseModal) .set-rail-items::-webkit-scrollbar{display:none}:is(#sessionOptionsModal,#createCaseModal) .set-rail-item{white-space:nowrap;padding:8px 12px}:is(#sessionOptionsModal,#createCaseModal) .set-rail-item.active:before{display:none}:is(#sessionOptionsModal,#createCaseModal) .set-rail-item.active{background:rgba(var(--accent-rgb),.13)}}html[data-session-list=sidebar] .session-sidebar{position:absolute;top:0;bottom:0;left:0;width:min(280px,80vw);flex:0 0 auto;transform:translate(-100%);visibility:hidden;transition:transform var(--sidebar-transition),visibility var(--sidebar-transition);box-shadow:10px 0 28px #0000005c;z-index:12;padding-left:var(--safe-area-left)}html[data-session-list=sidebar][data-sidebar-detail=rich] .session-sidebar{width:min(280px,80vw);flex:0 0 auto}html[data-session-list=sidebar] .session-sidebar.open{transform:translate(0);visibility:visible}html[data-session-list=sidebar][data-sidebar=collapsed] .session-sidebar{flex-basis:auto;width:min(280px,80vw)}html[data-session-list=sidebar][data-sidebar=collapsed] .session-sidebar-head,html[data-session-list=sidebar][data-sidebar=collapsed] .session-sidebar-filter{display:flex}html[data-session-list=sidebar][data-sidebar=collapsed] .session-sidebar .session-tab{justify-content:flex-start;flex-wrap:nowrap;padding:.4rem .5rem}html[data-session-list=sidebar][data-sidebar=collapsed] .session-sidebar .tab-info{display:flex}html[data-session-list=sidebar][data-sidebar=collapsed] .session-sidebar .tab-number{display:inline-flex}html[data-session-list=sidebar][data-sidebar=collapsed] .session-sidebar .tab-subagent-badge{margin-left:4px}html[data-session-list=sidebar] .session-sidebar .session-tab{min-height:44px;max-height:none;flex-shrink:0}html[data-session-list=sidebar] .session-sidebar .session-tab .tab-gear,html[data-session-list=sidebar] .session-sidebar .session-tab .tab-close{display:inline-flex;align-items:center;justify-content:center;opacity:1;width:auto;min-width:28px;height:auto;margin-left:0;padding:.15rem .25rem}@media(prefers-reduced-motion:reduce){html[data-session-list=sidebar] .session-sidebar{transition:none}}
|
|
1
|
+
html.mobile-init .header-font-controls,html.mobile-init .header-system-stats,html.mobile-init .header-tokens,html.mobile-init .monitor-panel,html.mobile-init .subagents-panel,html.mobile-init .project-insights-panel,html.mobile-init .file-browser-panel{display:none!important}@media(max-width:768px){input,textarea,select{font-size:16px!important}html{touch-action:manipulation}.session-tab .tab-detach{display:none!important}}@media(max-width:768px)and (min-width:430px){.header{position:fixed;top:0;left:0;right:0;min-height:48px;max-height:48px;padding:.35rem .5rem;padding-left:calc(.5rem + var(--safe-area-left));padding-right:calc(.5rem + var(--safe-area-right));background:#0a0a0a;border-bottom:1px solid rgba(255,255,255,.08);contain:none;overflow:visible;z-index:1200}.ios-device .header{padding-top:calc(.35rem + var(--safe-area-top));min-height:calc(48px + var(--safe-area-top));max-height:calc(48px + var(--safe-area-top))}.app{padding-top:54px}.ios-device .app{padding-top:calc(54px + var(--safe-area-top))}.header-font-controls{gap:.15rem;padding:.15rem .25rem}.header-font-controls .btn-icon-sm{width:18px;height:18px}.header-system-stats{font-size:.6rem;gap:.25rem}.header-right{gap:.35rem}.btn-icon-header:not(.btn-sm){width:44px;height:44px}.session-tabs,.session-tabs.tabs-two-rows{flex-wrap:nowrap;overflow-x:auto;overflow-y:hidden;-webkit-overflow-scrolling:touch;overscroll-behavior-x:contain;scrollbar-width:none;max-height:52px;gap:3px}.session-tabs::-webkit-scrollbar{display:none}.session-tab{padding:.4rem .6rem;font-size:.75rem;min-height:40px}.session-tab .tab-name{max-width:80px}.toolbar{padding:.4rem .5rem;padding-left:calc(.5rem + var(--safe-area-left));padding-right:calc(.5rem + var(--safe-area-right));gap:.4rem}.tab-count-group{display:none}.btn-toolbar{padding:.4rem .8rem;font-size:.8rem;min-height:40px}.case-select-group{max-width:none}.case-combobox{width:160px}.toolbar-select{font-size:.75rem}.monitor-panel,.subagents-panel{width:100%;max-width:100%;left:0;right:0;border-radius:8px 8px 0 0;max-height:40vh}.project-insights-panel{max-width:280px;font-size:.7rem}.modal{z-index:1300}.command-palette-modal{padding:10vh .75rem 0}.command-palette-shell{width:100%;max-height:74vh}.command-palette-input-row{grid-template-columns:20px minmax(0,1fr)}.command-palette-input-row kbd{display:none}.command-palette-item{min-height:56px}.settings-grid{gap:.4rem .75rem}.settings-item{font-size:.7rem}.event-type-grid{grid-template-columns:1fr 40px 40px 40px;gap:5px 6px}.event-label{font-size:.7rem}.subagent-window{width:320px;height:280px;min-width:240px;min-height:160px}.subagent-window-header{padding:.35rem .5rem}.subagent-window-title .id{font-size:.7rem;max-width:180px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.subagent-window-title .status{font-size:.55rem}.subagent-window-body{font-size:.7rem}.respawn-banner{padding:.25rem .5rem;padding-left:calc(.5rem + var(--safe-area-left));padding-right:calc(.5rem + var(--safe-area-right));font-size:.65rem}.respawn-compact-layout{gap:.75rem}.respawn-status-row1{gap:.4rem}.respawn-action-log{max-height:2.6em;font-size:.6rem}.respawn-countdown-timer{font-size:.55rem}.respawn-timer-bar{width:24px}.toolbar-center .btn-toolbar.btn-voice{display:flex!important}.toolbar{padding:0 .5rem;gap:.5rem}.toolbar-left,.toolbar-right,.toolbar-group{gap:.5rem}.btn-toolbar{padding:.4rem .75rem;font-size:.75rem;min-height:unset}}@media(max-width:430px){:root{--header-height: 44px}.header-brand{padding-right:0;margin-right:.1rem;border-right:none}.header-brand .logo{display:inline-flex;align-items:center;justify-content:center;min-width:44px;height:var(--header-height);margin-left:-.3rem;font-size:1.15rem;line-height:1;border-radius:8px;-webkit-tap-highlight-color:transparent}.header-brand .logo:active{background:#60a5fa29}.header-brand .logo .logo-text{display:none}.header-brand .logo .logo-compact{display:inline}.header-font-controls{gap:.1rem;padding:.1rem .2rem}.header-font-controls .btn-icon-sm{width:16px;height:16px}.header-font-controls .font-size-display{font-size:.6rem;min-width:14px}.header-system-stats{font-size:.55rem;gap:.15rem}.header-tokens{font-size:.6rem;padding:.1rem .3rem}.header{position:fixed;top:0;left:0;right:0;min-height:var(--header-height);max-height:var(--header-height);align-items:center;padding:.15rem .3rem;padding-left:calc(.3rem + var(--safe-area-left));padding-right:calc(.3rem + var(--safe-area-right));gap:.15rem;overflow:hidden;background:#0a0a0a;border-bottom:1px solid rgba(255,255,255,.08);contain:none;z-index:1200}.ios-device .header{padding-top:calc(.15rem + var(--safe-area-top));min-height:calc(var(--header-height) + var(--safe-area-top));max-height:calc(var(--header-height) + var(--safe-area-top))}.app{padding-top:calc(var(--header-height) + 6px)}.ios-device .app{padding-top:calc(var(--header-height) + 6px + var(--safe-area-top))}.main{padding-bottom:calc(40px + var(--safe-area-bottom))}.ios-device.safari-browser .main{padding-bottom:calc(40px + var(--safe-area-bottom) + (100vh - var(--app-height, 100vh)))}.header-right{padding-left:.2rem;gap:.1rem;flex-shrink:0;border-left:none}.btn-icon-header{width:26px;height:26px;padding:0}.btn-icon-header svg{width:12px;height:12px}html[data-session-list=sidebar] #sidebarToggleBtn{width:44px;height:44px}html[data-session-list=sidebar] #sidebarToggleBtn svg{width:18px;height:18px}.btn-icon-header.btn-settings,.btn-icon-header.btn-lifecycle-log,.btn-icon-header.btn-away-digest,.btn-icon-header.btn-session-manager,.btn-icon-header.btn-file-viewer,.btn-icon-header.btn-approvals,.btn-icon-header.btn-readmymind,.btn-admin-panel{display:none!important}.btn-voice-mobile{display:inline-flex;align-items:center;justify-content:center;width:26px;height:26px;background:#1a2a3f;border:1px solid rgba(59,130,246,.3);border-radius:4px;color:#93c5fd;cursor:pointer;flex-shrink:0;order:5}.btn-voice-mobile svg{width:13px;height:13px}.btn-voice-mobile:active{background:#2a3a5f}.btn-voice-mobile.recording{background:#ef444440;border-color:#ef444499;color:#ef4444;animation:mobile-voice-pulse 1.2s ease-in-out infinite}@keyframes mobile-voice-pulse{0%,to{box-shadow:inset 0 0 0 1px #ef444459;background:#ef444433}50%{box-shadow:inset 0 0 0 2px #ef4444bf;background:#ef444459}}.btn-settings-mobile{display:inline-flex!important;align-items:center;justify-content:center;width:26px;height:26px;background:transparent;border:1px solid rgba(255,255,255,.2);border-radius:4px;color:#9ca3af;font-size:.85rem;cursor:pointer;flex-shrink:0;order:6;position:relative}.btn-settings-mobile svg{width:13px;height:13px}.btn-settings-mobile:active{background:#ffffff1a;color:#fff}.app{overflow:hidden;position:relative}.keyboard-visible .app{position:fixed;inset:0 0 auto;height:var(--app-height, 100dvh)}.session-tabs,.session-tabs.tabs-two-rows{flex:1;flex-wrap:nowrap;overflow-x:auto;overflow-y:hidden;-webkit-overflow-scrolling:touch;overscroll-behavior-x:contain;scrollbar-width:none;max-height:36px;gap:2px;padding:0}.session-tabs::-webkit-scrollbar{display:none}.session-tab{flex-shrink:0;min-height:32px;max-height:32px;padding:.35rem .5rem;font-size:.7rem;gap:.25rem;border-radius:4px}.session-tab .tab-status{width:4px;height:4px}.session-tab .tab-status.busy{width:9px;height:9px;box-shadow:0 0 8px 2px color-mix(in srgb,var(--green) 55%,transparent)!important}.session-tab .tab-status.busy:after{display:none}.session-tab .tab-name{max-width:50px;overflow:hidden;text-overflow:ellipsis}.session-tab.active .tab-name{min-width:44px}.session-tab .tab-close,.session-tab .tab-gear{display:none}.session-tab.active .tab-gear{display:inline-flex;align-items:center;justify-content:center;font-size:.65rem;line-height:1;width:32px;height:32px;margin-left:auto;opacity:.6}.session-tab.active .tab-close{display:inline-flex;align-items:center;justify-content:center;font-size:1.1rem;line-height:1;width:20px;height:18px;margin-left:-2px}.toolbar{position:fixed;bottom:var(--safe-area-bottom);left:0;right:0;height:40px;min-height:40px;max-height:40px;padding:.3rem .4rem;padding-left:calc(.4rem + var(--safe-area-left));padding-right:calc(.4rem + var(--safe-area-right));flex-wrap:nowrap;gap:.3rem;align-items:center;justify-content:space-between;background:#111;border-top:1px solid rgba(255,255,255,.1);z-index:50;transition:transform .15s ease-out;will-change:transform}.ios-device.safari-browser .toolbar{bottom:calc(var(--safe-area-bottom) + (100vh - var(--app-height, 100vh)))}.keyboard-visible.ios-device.safari-browser .toolbar{bottom:var(--safe-area-bottom)}.keyboard-visible.ios-device.safari-browser .keyboard-accessory-bar{bottom:calc(var(--safe-area-bottom) + 40px)}.toolbar-center{display:flex!important;align-items:center}.toolbar-center .btn-toolbar.btn-voice,.toolbar-right,.version-display{display:none!important}.toolbar-left{flex:1 1 0;min-width:0;align-items:center;gap:.3rem}.toolbar-left .toolbar-group{display:flex;flex:1 1 0;min-width:0;align-items:center;gap:.3rem}.toolbar-left .toolbar-group:first-child{flex:1 1 0;min-width:0;justify-content:space-between;gap:.3rem;flex-wrap:nowrap;align-items:center}.tab-count-group{display:none!important}.btn-toolbar{min-height:26px!important;max-height:26px!important;height:26px!important;padding:0 .5rem!important;font-size:.65rem!important;border-radius:4px;line-height:26px;display:inline-flex;align-items:center;justify-content:center;font-weight:500;letter-spacing:.01em;color:#fff}.run-btn-group{display:flex;flex:0 0 auto}.btn-toolbar.btn-run{flex:0 0 auto;padding:0 .6rem!important;font-weight:500;border-radius:4px 0 0 4px!important;border-right:none!important}.btn-toolbar.btn-run svg{width:10px;height:10px;margin-right:3px}.btn-toolbar.btn-run-gear{flex:0 0 auto;padding:0 .35rem!important;min-width:unset!important;border-radius:0 4px 4px 0!important;border-left:1px solid rgba(255,255,255,.15)!important}.btn-toolbar.btn-run-gear svg{width:10px;height:10px}.btn-toolbar.btn-run.mode-claude,.btn-toolbar.btn-run-gear.mode-claude{background:#1e3a5f;border-color:#3b82f64d;color:#93c5fd}.btn-toolbar.btn-run.mode-claude:active,.btn-toolbar.btn-run-gear.mode-claude:active{background:#2563eb;border-color:#3b82f680}.btn-toolbar.btn-run.mode-opencode,.btn-toolbar.btn-run-gear.mode-opencode{background:#0a2e2a;border-color:#10b9814d;color:#6ee7b7}.btn-toolbar.btn-run.mode-opencode:active,.btn-toolbar.btn-run-gear.mode-opencode:active{background:#0d4a40;border-color:#10b98180}.btn-toolbar.btn-run.mode-gemini,.btn-toolbar.btn-run-gear.mode-gemini{background:#10243f;border-color:#60a5fa4d;color:#dbeafe}.btn-toolbar.btn-run.mode-gemini:active,.btn-toolbar.btn-run-gear.mode-gemini:active{background:#174ea6;border-color:#60a5fa80}.btn-toolbar.btn-run.mode-antigravity,.btn-toolbar.btn-run-gear.mode-antigravity{background:#0b2b33;border-color:#22d3ee4d;color:#cffafe}.btn-toolbar.btn-run.mode-antigravity:active,.btn-toolbar.btn-run-gear.mode-antigravity:active{background:#0e7490;border-color:#22d3ee80}.btn-toolbar.btn-run.mode-pi,.btn-toolbar.btn-run-gear.mode-pi{background:#33121f!important;border-color:#f472b64d!important;color:#fce7f3!important}.btn-toolbar.btn-run.mode-pi:active,.btn-toolbar.btn-run-gear.mode-pi:active{background:#9d174d!important;border-color:#f472b680!important}.btn-toolbar.btn-run.mode-grok,.btn-toolbar.btn-run-gear.mode-grok{background:#1c1c1f!important;border-color:#d4d4d84d!important;color:#f4f4f5!important}.btn-toolbar.btn-run.mode-grok:active,.btn-toolbar.btn-run-gear.mode-grok:active{background:#3f3f46!important;border-color:#d4d4d880!important}.btn-toolbar.btn-run.mode-deepseek,.btn-toolbar.btn-run-gear.mode-deepseek{background:#16225f!important;border-color:#7c93ff59!important;color:#eef2ff!important}.btn-toolbar.btn-run.mode-deepseek:active,.btn-toolbar.btn-run-gear.mode-deepseek:active{background:#3350e6!important;border-color:#96aaff8c!important}.btn-toolbar.btn-run.mode-omp,.btn-toolbar.btn-run-gear.mode-omp{background:#312e81!important;border-color:#818cf84d!important;color:#e0e7ff!important}.btn-toolbar.btn-run.mode-omp:active,.btn-toolbar.btn-run-gear.mode-omp:active{background:#4f46e5!important;border-color:#818cf880!important}.run-mode-menu{bottom:100%;left:0;margin-bottom:6px;min-width:160px;max-width:80vw}.run-mode-option{padding:10px 12px;font-size:.8rem;cursor:pointer;-webkit-tap-highlight-color:rgba(255,255,255,.1)}.run-mode-row-btn{width:34px;height:34px;font-size:1rem;-webkit-tap-highlight-color:rgba(255,255,255,.1)}.run-mode-webview-delete{font-size:1.2rem}.run-mode-history{-webkit-overflow-scrolling:touch;touch-action:manipulation}.btn-toolbar.btn-stop{display:flex!important;flex:0 0 auto;padding:0 8px!important;min-width:unset;order:3}.btn-toolbar.btn-stop svg{width:10px;height:10px;margin-right:0}.btn-toolbar.btn-shell{display:none!important}.btn-toolbar.btn-enter{display:flex!important;flex:0 0 auto;align-items:center;justify-content:center;min-width:54px;width:54px;white-space:nowrap;padding:0 8px!important;overflow:hidden;font-size:.65rem;font-weight:600;letter-spacing:.01em;background:#1e3a5fd9!important;border:1px solid rgba(59,130,246,.45)!important;color:#dbeafe!important;order:4}.btn-toolbar.btn-enter:hover,.btn-toolbar.btn-enter:active{background:#254a7af2!important;border-color:#3b82f6b3!important;color:#fff!important}.case-select-group{display:none!important}.toolbar-left .toolbar-group:first-child{width:100%;gap:8px}.btn-toolbar.btn-case-mobile{display:flex!important;flex:1 1 0!important;min-width:0;padding:0 8px!important;order:2;overflow:hidden;justify-content:center;gap:4px}.btn-toolbar.btn-case-mobile #mobileCaseName{max-width:none;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.btn-case-settings-mobile{display:inline-flex!important;align-items:center;justify-content:center;width:26px;height:26px;background:transparent;border:1px solid rgba(255,255,255,.2);border-radius:4px;color:#9ca3af;cursor:pointer;flex-shrink:0;order:1}.btn-case-settings-mobile:active{background:#ffffff1a;color:#fff}@media(max-width:374px){.toolbar{padding:0 2px}.toolbar-left,.toolbar-left .toolbar-group,.toolbar-left .toolbar-group:first-child{gap:2px}}.btn-case-settings-mobile{display:none!important}.case-settings-popover-mobile{position:fixed;bottom:calc(var(--safe-area-bottom) + 46px);left:8px;right:8px;background:#1e1e1e;border:1px solid rgba(255,255,255,.15);border-radius:8px;padding:.6rem .75rem;z-index:1000;box-shadow:0 4px 16px #00000080;display:block}.case-settings-popover-mobile.hidden{display:none!important}.case-settings-popover-mobile .checkbox-inline{display:flex;align-items:center;gap:6px;font-size:.75rem;color:#e5e7eb}.case-settings-popover-mobile .form-hint{display:block;margin-top:.2rem;font-size:.6rem;color:#6b7280}.keyboard-accessory-bar{display:none;position:fixed;bottom:calc(var(--safe-area-bottom) + 40px);left:0;right:0;height:44px;background:#1a1a1a;border-top:1px solid rgba(255,255,255,.1);padding:6px 8px;padding-left:calc(8px + var(--safe-area-left));padding-right:calc(8px + var(--safe-area-right));gap:8px;align-items:center;overflow-x:auto;overflow-y:hidden;-webkit-overflow-scrolling:touch;z-index:51;transition:transform .15s ease-out;will-change:transform}.keyboard-accessory-bar.visible{display:flex}.keyboard-accessory-bar::-webkit-scrollbar{display:none}.accessory-btn{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;gap:4px;padding:6px 12px;background:#2a2a2a;border:1px solid rgba(255,255,255,.15);border-radius:6px;color:#e5e5e5;font-size:.65rem;font-weight:500;cursor:pointer;transition:background .15s,border-color .15s}.accessory-btn.confirming{background:#6b4f00;border-color:#b8860b;color:#ffd54f}.accessory-btn.accessory-btn-ctrl.armed{background:#2563eb;border-color:#3b82f6e6;color:#fff;font-weight:700;box-shadow:0 0 0 2px #3b82f673}.accessory-btn:active{background:#3a3a3a}.accessory-btn svg{width:14px;height:14px}.accessory-btn-arrow{padding:6px 10px;background:#2563eb;border-color:#3b82f680;color:#fff}.accessory-btn-arrow:active{background:#1d4ed8}.accessory-btn-dismiss{margin-left:auto;flex:1 1 0;max-width:100px;padding:10px 8px;background:#2563eb;border-color:#3b82f680;color:#fff;font-weight:600}.accessory-btn-dismiss svg{width:22px;height:22px}.accessory-btn-dismiss:active{background:#1d4ed8}.voice-preview{bottom:calc(var(--safe-area-bottom) + 94px);font-size:.8rem;max-width:90%;padding:6px 14px}.btn-case-add,.btn-case-settings,.toolbar-select{display:none!important}.toolbar .btn-case-add{min-width:26px!important;max-width:26px!important;width:26px!important;min-height:26px!important;max-height:26px!important;height:26px!important;padding:0!important;font-size:.9rem;font-weight:700;display:inline-flex!important;align-items:center;justify-content:center;line-height:1;border-radius:4px;background:transparent;border:1px solid rgba(255,255,255,.15);color:#9ca3af}.btn-case-add:hover,.btn-case-add:active{background:#ffffff1a;color:#fff}.monitor-panel,.subagents-panel{width:100%;max-width:100%;left:0;right:0;border-radius:8px 8px 0 0;bottom:calc(44px + 2rem + var(--safe-area-bottom));max-height:35vh}.modal{z-index:1300}.modal-content{width:100%;max-width:100%;height:100%;max-height:100%;border-radius:0;margin:0;display:flex;flex-direction:column}.modal-content.modal-sm,.modal-content.readmymind-modal{height:auto;max-height:85vh;border-radius:12px;margin:1rem;width:calc(100% - 2rem)}.readmymind-modal .modal-footer{flex-wrap:wrap}.readmymind-modal .modal-footer .btn-toolbar{flex:1 1 auto;justify-content:center;min-height:38px}.readmymind-alt,.readmymind-steer-input{min-height:38px}.ios-device .modal-content{padding-top:var(--safe-area-top);padding-bottom:var(--safe-area-bottom);padding-left:var(--safe-area-left);padding-right:var(--safe-area-right)}.modal-header{padding:.75rem 1rem}.modal-header h3{font-size:1rem}.modal-body{padding:.75rem 1rem;flex:1;min-height:0;overflow-y:auto;-webkit-overflow-scrolling:touch}.away-digest-modal{width:100%;max-width:100%;height:100%;max-height:100%}.away-digest-ranges{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:.4rem}.away-digest-ranges .filter-btn{min-height:38px;padding:.4rem .5rem}.away-digest-custom-range,.away-digest-custom-range.active{grid-template-columns:1fr}.away-digest-summary{grid-template-columns:repeat(2,minmax(0,1fr));gap:.5rem}.away-digest-item{grid-template-columns:1fr;gap:.5rem}.away-digest-action{width:100%;min-height:38px}.modal-footer,.form-actions{padding:.75rem 1rem;padding-bottom:calc(.75rem + var(--safe-area-bottom))}.ios-device .terminal-container{padding-bottom:var(--safe-area-bottom)}.main{flex:1;min-height:0}.cli-info-bar{display:block}.terminal-container{height:100%;min-height:0;position:relative;overflow:visible;touch-action:none}.terminal-container .xterm,.terminal-container .xterm-viewport,.terminal-container .xterm-screen{touch-action:none}.response-viewer{padding-bottom:var(--safe-area-bottom, 0px);max-height:88vh;max-height:92dvh}.response-viewer-body{font-size:14.5px;line-height:1.65;padding:16px 16px 24px;--rv-content-max: 100%}.response-viewer-body .rv-text pre,.response-viewer-body pre{padding:12px 14px;margin-left:-4px;margin-right:-4px;border-radius:6px}.response-viewer-body .rv-text pre code,.response-viewer-body pre code{font-size:11.5px;line-height:1.5}.response-viewer-body .rv-text h1,.response-viewer-body>h1{font-size:1.35em}.response-viewer-body .rv-text h2,.response-viewer-body>h2{font-size:1.2em}.response-viewer-body .rv-text h3,.response-viewer-body>h3{font-size:1.08em}.welcome-content{max-width:calc(100vw - 1.5rem);padding:1rem .75rem}.welcome-title{font-size:1.2rem;margin-bottom:.5rem}.welcome-desc{font-size:.8rem;margin-bottom:.4rem}.welcome-actions{flex-direction:column;gap:.5rem;margin-top:1rem}.welcome-btn{width:100%;justify-content:center;min-height:44px;padding:.75rem 1rem;font-size:.85rem}.history-show-more{display:block;margin-bottom:.75rem}.welcome-ralph-link{display:block;margin:.75rem auto 0}.welcome-hint{font-size:.7rem;margin-top:.75rem}.modal-wizard{display:flex;flex-direction:column}.wizard-progress{padding:.5rem}.wizard-step{padding:.3rem}.wizard-step-number{width:24px;height:24px;font-size:.7rem}.wizard-step-label{display:none}.timer-banner{padding-left:calc(.5rem + var(--safe-area-left));padding-right:calc(.5rem + var(--safe-area-right))}.respawn-banner{padding:.3rem .5rem;padding-left:calc(.5rem + var(--safe-area-left));padding-right:calc(.5rem + var(--safe-area-right));font-size:.65rem}.respawn-compact-layout{flex-direction:column;gap:.15rem}.respawn-status-col{flex-shrink:1;min-width:0;gap:.1rem}.respawn-status-row1{flex-wrap:wrap;gap:.25rem;row-gap:.1rem}.respawn-state{font-size:.6rem;padding:.05rem .3rem}.respawn-banner .detection-confidence{font-size:.5rem;padding:.02rem .2rem}.respawn-cycles{font-size:.55rem}.respawn-timer{font-size:.55rem;padding:0 .25rem}.respawn-tokens{font-size:.55rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:120px}.respawn-indicator{font-size:.65rem}.respawn-banner .btn-icon-only{min-width:36px;min-height:36px;font-size:1rem;display:flex;align-items:center;justify-content:center;margin-left:auto;border-radius:6px;flex-shrink:0}.respawn-status-row2{font-size:.55rem;gap:.3rem;min-height:0;flex-wrap:wrap}.respawn-banner .detection-hook,.respawn-banner .detection-ai-check,.respawn-banner .detection-status{font-size:.55rem;padding:.02rem .2rem}.respawn-countdown-timers{gap:.2rem}.respawn-countdown-timer{font-size:.5rem;padding:.02rem .2rem;gap:.15rem}.respawn-countdown-timer .respawn-timer-bar{display:none}.respawn-action-log{border-left:none;border-top:1px solid rgba(34,197,94,.15);padding-left:0;padding-top:.15rem;max-height:1.4em;font-size:.55rem;overflow:hidden}.respawn-header{flex-direction:row;gap:.4rem;align-items:center}.respawn-header .respawn-actions{display:flex;gap:.3rem;flex-shrink:0}.respawn-header .respawn-actions .btn-toolbar{min-height:28px!important;font-size:.7rem!important;padding:.2rem .5rem!important;border-radius:5px}.duration-presets{display:flex;flex-wrap:wrap;gap:.2rem}.duration-preset-btn{min-height:24px;padding:.1rem .4rem;font-size:.6rem;border-radius:4px;text-align:center}.duration-custom{display:flex;gap:.2rem;align-items:center}.duration-custom-input.visible{flex:0 1 auto}.duration-custom-input input{width:64px;min-height:24px;font-size:16px;padding:.1rem .3rem}.preset-selector{display:grid;grid-template-columns:1fr 1fr;gap:.25rem}.preset-selector select{grid-column:1 / -1;min-height:32px;font-size:16px;border-radius:5px;padding:.2rem .4rem}.preset-selector .btn{min-height:32px;font-size:.65rem;border-radius:5px;padding:.2rem .4rem}#sessionOptionsModal textarea{font-size:16px;min-height:32px!important;max-height:56px;height:auto!important;border-radius:6px;padding:.3rem .5rem}#modalRespawnPrompt{min-height:32px!important;max-height:56px}#modalRespawnKickstart{min-height:32px!important;max-height:48px}#sessionOptionsModal .checkbox-inline{min-height:30px;font-size:.75rem;padding:.15rem 0;gap:.4rem}#sessionOptionsModal .checkbox-inline input[type=checkbox]{width:18px;height:18px}#sessionOptionsModal .respawn-loop-title{font-size:.75rem}#sessionOptionsModal .respawn-loop-box .checkbox-inline{font-size:.65rem}#sessionOptionsModal .respawn-options-row{gap:.5rem}#sessionOptionsModal .form-section-header{margin-top:.75rem;padding-top:.5rem;font-size:.65rem}#sessionOptionsModal .form-row{margin-bottom:.5rem}#sessionOptionsModal .form-row label{font-size:.65rem;margin-bottom:.2rem}#sessionOptionsModal .form-hint{font-size:.6rem;margin-top:.2rem}.context-setting{padding:.625rem}.context-setting-header{flex-wrap:wrap;gap:.4rem}.context-setting-header .input-suffix-sm input{width:60px;font-size:16px;min-height:36px}.context-setting input[type=text]{font-size:16px;min-height:36px;padding:.4rem .6rem;border-radius:6px}.color-picker{gap:8px}.color-swatch{width:36px;height:36px;border-radius:6px}.form-row-switch{min-height:40px;gap:.4rem}.context-settings-grid input[type=number]{font-size:16px;min-height:36px}.ralph-limits-grid{grid-template-columns:1fr 1fr;gap:.5rem}.ralph-limits-grid .form-col input[type=number]{font-size:16px;min-height:36px;padding:.4rem .5rem;border-radius:6px}#modalRalphPhrase{font-size:16px;min-height:40px;border-radius:6px}.ralph-config-actions{margin-top:1rem}.ralph-config-actions .btn-toolbar{width:100%;min-height:44px;font-size:.85rem;border-radius:8px}.run-summary-filters{gap:.3rem;margin-bottom:.5rem}.filter-btn{padding:.35rem .75rem;font-size:.7rem;min-height:32px}.timeline-event{padding:.4rem .5rem;margin-bottom:.25rem;font-size:.7rem}.run-summary-footer{flex-direction:column;gap:.4rem;padding:.5rem 0}.run-summary-actions{flex-wrap:wrap;gap:.3rem}.run-summary-actions .btn-toolbar{flex:1;min-height:36px;font-size:.7rem;white-space:nowrap}.auto-refresh-label{font-size:.7rem}.ralph-panel{font-size:.75rem}.ralph-summary{padding:.4rem .5rem;padding-left:calc(.5rem + var(--safe-area-left));padding-right:calc(.5rem + var(--safe-area-right))}.project-insights-panel{max-width:100%;font-size:.65rem;bottom:calc(44px + 2rem + var(--safe-area-bottom))}.file-browser-panel{max-width:100%;max-height:50vh;bottom:calc(44px + 2rem + var(--safe-area-bottom))}.file-preview-window{width:100vw;max-width:100vw;height:var(--app-height, 100vh);max-height:var(--app-height, 100vh);border-radius:0;border-left:none;border-right:none}.file-preview-editbar{padding-bottom:calc(.4rem + var(--safe-area-bottom))}.file-preview-overlay .file-preview-footer{padding-bottom:calc(.35rem + var(--safe-area-bottom))}.file-preview-body textarea.file-preview-editor{font-size:16px}.notification-drawer{width:100%;max-width:100%;right:0;border-radius:0;padding-left:var(--safe-area-left);padding-right:var(--safe-area-right);padding-bottom:var(--safe-area-bottom)}input,textarea,[contenteditable]{scroll-margin-bottom:200px;scroll-margin-top:80px}.keyboard-visible .modal-body{max-height:40vh;overflow-y:auto}.keyboard-visible #createCaseModal .modal-body{max-height:60vh}.mobile-case-picker .modal-backdrop{background:#00000080}.mobile-case-picker-sheet{max-height:60vh;padding-bottom:var(--safe-area-bottom);animation:slideUp .2s ease-out}@keyframes slideUp{0%{transform:translateY(100%)}to{transform:translateY(0)}}.mobile-case-picker-header .modal-close{width:32px;height:32px;font-size:1.5rem}.mobile-case-picker-footer{padding-bottom:calc(12px + var(--safe-area-bottom))}#createCaseModal .form-row{margin-bottom:1rem}#createCaseModal .form-row label{font-size:.8rem;margin-bottom:.4rem;font-weight:500;color:#e5e7eb}#createCaseModal .form-row input[type=text]{min-height:44px;font-size:16px;padding:.5rem .75rem;border-radius:8px}#createCaseModal .form-row .form-hint{font-size:.65rem;margin-top:.35rem;line-height:1.4}#createCaseModal .form-actions{padding:.75rem 1rem;padding-bottom:calc(.75rem + var(--safe-area-bottom));gap:.75rem}#createCaseModal .form-actions .btn-toolbar{min-height:44px!important;max-height:44px!important;height:44px!important;font-size:.85rem!important;font-weight:500;border-radius:8px}#caseModalSubmit.loading{opacity:.6;pointer-events:none}#createCaseModal.from-mobile .modal-content{animation:caseModalSlideUp .25s ease-out}@keyframes caseModalSlideUp{0%{transform:translateY(30px);opacity:0}to{transform:translateY(0);opacity:1}}.btn-case-create-mobile{min-height:48px!important;max-height:48px!important;height:48px!important;font-size:.85rem!important;font-weight:500;border-radius:10px}.settings-grid{grid-template-columns:1fr;gap:.35rem}.settings-grid-3col{grid-template-columns:1fr 1fr 1fr}.settings-item{padding:.35rem .5rem;font-size:.7rem}.settings-item-label{font-size:.7rem}.settings-section-header{font-size:.6rem;padding:.35rem 0 .2rem;margin-top:.5rem}.form-row{margin-bottom:.5rem}.form-row label{font-size:.7rem;margin-bottom:.2rem}.form-row .form-hint{font-size:.6rem}.form-row input[type=text],.form-row input[type=number],.form-row textarea,.form-row .form-select,.form-row select{font-size:.75rem;padding:.35rem .5rem;min-height:32px}.form-row-switch{gap:.3rem}.form-row-switch>label:first-child{font-size:.7rem}.form-section-header{font-size:.6rem;margin-top:.75rem}.event-type-grid{grid-template-columns:1fr 36px 36px 36px;gap:4px 4px;padding:6px;margin-top:6px}.event-header{font-size:.55rem}.event-label{font-size:.65rem}.event-type-grid input[type=checkbox]{width:12px;height:12px}.form-actions{gap:.5rem}.form-actions .btn-toolbar{flex:1;min-height:36px!important;max-height:36px!important;height:36px!important;font-size:.75rem!important}.subagent-window{position:fixed;width:calc(100% - 8px);max-width:calc(100% - 8px);height:110px;min-height:80px;max-height:110px;min-width:200px;border-radius:6px;resize:none;box-shadow:0 2px 8px #0006}.subagent-window:after{display:none}.subagent-window-header{padding:.2rem .4rem;min-height:24px}.subagent-window-title{gap:.2rem;overflow:hidden}.subagent-window-title .icon{font-size:.7rem}.subagent-window-title .id{font-size:.6rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:45vw}.subagent-window-title .status{font-size:.45rem;padding:.05rem .15rem}.subagent-model-badge{font-size:.45rem!important;padding:.05rem .15rem!important}.subagent-window-actions button{font-size:.7rem;padding:.15rem .35rem;min-width:26px;min-height:26px;display:flex;align-items:center;justify-content:center}.subagent-window-body{font-size:.6rem;padding:.2rem .35rem}.subagent-window-body .activity-line{gap:.15rem;padding:.05rem 0}.subagent-window-body .activity-line .time{font-size:.5rem}.subagent-window-body .activity-line .tool-name,.subagent-window-body .activity-line .tool-detail{font-size:.55rem}.subagent-window-parent{display:none}.session-tab .tab-subagent-badge{height:14px;padding:0 3px;border-radius:7px;margin-left:2px}.session-tab .tab-subagent-badge .subagent-label{font-size:.45rem}.subagent-dropdown{position:fixed!important;left:8px!important;right:8px!important;bottom:auto!important;min-width:auto!important;max-width:none!important;border-radius:8px;transform:none!important}.mobile-overview.visible{position:absolute;inset:0;z-index:10;display:flex;flex-direction:column;gap:.75rem;padding:.75rem .6rem calc(1rem + var(--safe-area-bottom));background:var(--bg-dark);overflow-y:auto;-webkit-overflow-scrolling:touch;overscroll-behavior:contain}.mobile-overview-top{display:flex;align-items:center;justify-content:space-between;gap:.5rem;padding:0}.mobile-overview-brand{display:inline-flex;align-items:center;min-height:48px;font-size:1.5rem;font-weight:800;line-height:1;color:var(--accent-hover);letter-spacing:-.02em}.mobile-overview-header{position:relative;display:flex;flex-direction:column}.mobile-overview-run-group{display:flex;align-items:stretch;flex-shrink:0}.mobile-overview-run-group .mobile-overview-run{display:inline-flex;align-items:center;gap:.4rem;min-height:48px!important;height:48px!important;max-height:48px!important;padding:0 1.15rem!important;font-size:.95rem!important;line-height:1;font-weight:700;font-family:inherit;border-radius:10px 0 0 10px!important}.mobile-overview-run-mode{font-weight:600;font-size:.85rem;opacity:.8}.mobile-overview-run-group .mobile-overview-run-caret{display:inline-flex;align-items:center;justify-content:center;min-height:48px!important;height:48px!important;max-height:48px!important;min-width:48px!important;width:48px!important;padding:0!important;line-height:1;font-family:inherit;border-radius:0 10px 10px 0!important}.mobile-overview-run-group .mobile-overview-run-caret svg{display:block;width:20px!important;height:20px!important;margin:0!important}.mobile-overview-run-menu{display:flex;flex-direction:column;gap:.15rem;margin:.5rem 0 0;padding:.35rem;border:1px solid var(--border);border-radius:12px;background:var(--floating-bg);box-shadow:var(--elevated-shadow)}.mobile-overview-run-option{display:flex;align-items:center;gap:.5rem;min-height:44px;padding:0 .6rem;border:none;border-radius:8px;background:transparent;color:var(--text);font-family:inherit;font-size:.82rem;text-align:left}.mobile-overview-run-option.selected{background:var(--control-bg-hover)}.mobile-overview-run-option:active{background:var(--bg-hover)}.mobile-overview-run-option--add{color:var(--accent)}.mobile-overview-run-header{padding:.4rem .6rem .2rem;font-size:.6rem;font-weight:700;letter-spacing:.09em;text-transform:uppercase;color:var(--text-muted)}.mobile-overview-section{display:flex;flex-direction:column;gap:.4rem}.mobile-overview-heading{display:flex;align-items:center;gap:.35rem;margin:.35rem 0 0;padding:0;font-size:.65rem;font-weight:700;letter-spacing:.09em;text-transform:uppercase;color:var(--text-muted)}.mobile-overview-heading-count{color:var(--text-dim);font-weight:600}.mobile-overview-empty{margin:0;padding:.5rem 0;font-size:.75rem;color:var(--text-muted)}.mobile-overview-row{display:flex;align-items:center;gap:.6rem;width:100%;min-height:56px;padding:.5rem .7rem;border:1px solid var(--border);border-radius:12px;background:var(--bg-card);color:var(--text);font-family:inherit;text-align:left}.mobile-overview-row:active{background:var(--bg-hover)}.mobile-overview-row-wrap{width:100%}.mobile-overview-approval-strip{display:flex;flex-wrap:wrap;gap:.4rem;padding:.4rem .2rem .1rem}.mobile-overview-approval-btn{border:1px solid var(--border);border-radius:8px;background:var(--bg-card);color:var(--text);font-family:inherit;font-size:.72rem;padding:.35rem .6rem;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.mobile-overview-approval-btn.primary{background:var(--accent);border-color:var(--accent);color:#fff}.mobile-overview-approval-btn.danger{border-color:var(--error);color:var(--error)}.mobile-overview-row--needs{border-color:var(--red);animation:mobile-overview-blink-red 2.5s ease-in-out infinite}.mobile-overview-row--waiting{border-color:var(--yellow);animation:mobile-overview-blink-yellow 3.5s ease-in-out infinite}.mobile-overview-row--error{border-color:var(--red)}.mobile-overview-row--working{border-color:var(--green);animation:mobile-overview-breathe-green 2.2s ease-in-out infinite}@keyframes mobile-overview-breathe-green{0%,to{background:var(--bg-card);border-color:var(--border)}50%{background:#22c55e1a;border-color:var(--green)}}.mobile-overview-pill--working:after{content:"";display:inline-block;width:.75em;text-align:left;animation:mobile-overview-pill-dots 1.5s steps(1,end) infinite}@keyframes mobile-overview-pill-dots{0%{content:""}25%{content:"."}50%{content:".."}75%{content:"..."}}@keyframes mobile-overview-blink-red{0%,to{background:var(--bg-card);border-color:var(--border)}50%{background:#ef444424;border-color:var(--red)}}@keyframes mobile-overview-blink-yellow{0%,to{background:var(--bg-card);border-color:var(--border)}50%{background:#eab3081f;border-color:var(--yellow)}}.mobile-overview-row-body{display:flex;flex-direction:column;gap:.15rem;flex:1;min-width:0}.mobile-overview-row-title{display:block;font-size:.9rem;font-weight:600;color:var(--text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.mobile-overview-row-case{color:var(--text-dim);font-weight:500}.mobile-overview-row-sub{display:block;font-size:.68rem;color:var(--text-muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.mobile-overview-row-meta{display:flex;align-items:center;gap:.3rem;min-width:0;font-family:var(--font-mono, monospace);font-size:.63rem;color:var(--text-muted);white-space:nowrap;overflow:hidden}.mobile-overview-meta-item{min-width:0;overflow:hidden;text-overflow:ellipsis}.mobile-overview-meta-key{margin-right:.3rem;opacity:.6;text-transform:uppercase;letter-spacing:.05em}.mobile-overview-meta-sep{opacity:.45}.mobile-overview-row--working .mobile-overview-meta-since{color:var(--green);opacity:.95}.mobile-overview-dot{flex-shrink:0;width:9px;height:9px;border-radius:50%;background:var(--text-muted)}.mobile-overview-dot--needs,.mobile-overview-dot--error{background:var(--red)}.mobile-overview-dot--waiting{background:var(--yellow)}.mobile-overview-dot--working{background:var(--green);animation:pulse 1.5s infinite;box-shadow:0 0 8px 2px color-mix(in srgb,var(--green) 55%,transparent);will-change:opacity}.mobile-overview-dot{position:relative}.mobile-overview-dot--working:after{content:"";position:absolute;inset:-4px;border:2px solid rgba(34,197,94,.25);border-top-color:var(--green);border-radius:50%;animation:tab-load-spin .7s linear infinite}.mobile-overview-dot--idle{background:var(--green)}.mobile-overview-dot--done{background:var(--text-muted);opacity:.5}.mobile-overview-pill{flex-shrink:0;display:inline-flex;align-items:center;gap:.25rem;padding:.2rem .45rem;border:1px solid var(--border-light);border-radius:999px;font-size:.62rem;font-weight:600;color:var(--text-dim);white-space:nowrap}.mobile-overview-pill--needs,.mobile-overview-pill--error{border-color:var(--red);color:var(--red)}.mobile-overview-pill--waiting{border-color:var(--yellow);color:var(--yellow)}.mobile-overview-pill--idle,.mobile-overview-pill--working{border-color:var(--green);color:var(--green)}.mobile-overview-chevron{flex-shrink:0;color:var(--text-muted);font-size:1rem;line-height:1}.mobile-overview-row--past{background:transparent;border-style:dashed}.mobile-overview-row--past .mobile-overview-row-title{font-weight:500;color:var(--text-dim)}.mobile-overview-dot--past{background:transparent;border:1px solid var(--border-light)}.mobile-overview-pill--past{border-color:var(--border-light);color:var(--text-muted)}.mobile-overview-more{display:flex;align-items:center;justify-content:center;gap:.35rem;min-height:40px;border:none;border-radius:10px;background:var(--control-bg);color:var(--text-dim);font-family:inherit;font-size:.72rem;font-weight:600}.mobile-overview-more-count{padding:.05rem .35rem;border-radius:999px;background:var(--control-bg-hover);color:var(--text-muted)}}@media(prefers-reduced-motion:reduce){.mobile-overview-row--needs,.mobile-overview-row--waiting{animation:none}.mobile-overview-row--needs{background:#ef444424}.mobile-overview-row--waiting{background:#eab3081f}.mobile-overview-dot--working{animation:none}.mobile-overview-dot--working:after{border-color:var(--green);animation:none}.mobile-overview-row--working{animation:none}.mobile-overview-pill--working:after{content:"...";animation:none}}html:is([data-skin=paper-gray],[data-skin=solarized-light],[data-skin=catppuccin-latte],[data-skin=rose-pine-dawn]) :is(.header,.toolbar,.keyboard-accessory-bar){background:var(--glass-bg);border-color:var(--glass-border);color:var(--text)}html:is([data-skin=paper-gray],[data-skin=solarized-light],[data-skin=catppuccin-latte],[data-skin=rose-pine-dawn]) :is(.btn-voice-mobile,.btn-settings-mobile,.btn-toolbar.btn-shell,.toolbar .btn-case-add,.accessory-btn:not(.armed)){background:var(--control-bg);border-color:var(--control-border);color:var(--text-dim)}html:is([data-skin=paper-gray],[data-skin=solarized-light],[data-skin=catppuccin-latte],[data-skin=rose-pine-dawn]) :is(.btn-voice-mobile:active,.btn-settings-mobile:active,.btn-toolbar.btn-shell:hover,.btn-toolbar.btn-shell:active,.btn-case-add:hover,.btn-case-add:active,.accessory-btn:active){background:var(--control-bg-hover);border-color:var(--control-border-hover);color:var(--text)}html:is([data-skin=paper-gray],[data-skin=solarized-light],[data-skin=catppuccin-latte],[data-skin=rose-pine-dawn]) :is(.btn-toolbar.btn-run.mode-claude,.btn-toolbar.btn-run-gear.mode-claude){background:linear-gradient(135deg,var(--accent-grad-a),var(--accent-grad-b));border-color:var(--accent);color:var(--accent-ink)}html:is([data-skin=paper-gray],[data-skin=solarized-light],[data-skin=catppuccin-latte],[data-skin=rose-pine-dawn]) :is(.btn-toolbar.btn-run.mode-opencode,.btn-toolbar.btn-run-gear.mode-opencode){background:linear-gradient(135deg,var(--accent-d),var(--accent-grad-b));border-color:var(--accent);color:var(--accent-ink)}html:is([data-skin=paper-gray],[data-skin=solarized-light],[data-skin=catppuccin-latte],[data-skin=rose-pine-dawn]) :is(.btn-toolbar.btn-run.mode-gemini,.btn-toolbar.btn-run-gear.mode-gemini){background:linear-gradient(135deg,#174ea6,#4f46e5);border-color:#315fc3;color:#fff}html:is([data-skin=paper-gray],[data-skin=solarized-light],[data-skin=catppuccin-latte],[data-skin=rose-pine-dawn]) :is(.btn-toolbar.btn-run.mode-antigravity,.btn-toolbar.btn-run-gear.mode-antigravity){background:linear-gradient(135deg,#0e7490,#0891b2);border-color:#155e75;color:#fff}html:is([data-skin=paper-gray],[data-skin=solarized-light],[data-skin=catppuccin-latte],[data-skin=rose-pine-dawn]) :is(.btn-toolbar.btn-run.mode-pi,.btn-toolbar.btn-run-gear.mode-pi){background:linear-gradient(135deg,#be185d,#db2777);border-color:#9d174d;color:#fff}html:is([data-skin=paper-gray],[data-skin=solarized-light],[data-skin=catppuccin-latte],[data-skin=rose-pine-dawn]) :is(.btn-toolbar.btn-run.mode-omp,.btn-toolbar.btn-run-gear.mode-omp){background:linear-gradient(135deg,#4f46e5,#6366f1);border-color:#4338ca;color:#fff}html:is([data-skin=paper-gray],[data-skin=solarized-light],[data-skin=catppuccin-latte],[data-skin=rose-pine-dawn]) :is(.btn-toolbar.btn-run.mode-grok,.btn-toolbar.btn-run-gear.mode-grok){background:linear-gradient(135deg,#27272a,#52525b);border-color:#18181b;color:#fff}html:is([data-skin=paper-gray],[data-skin=solarized-light],[data-skin=catppuccin-latte],[data-skin=rose-pine-dawn]) :is(.btn-toolbar.btn-run.mode-deepseek,.btn-toolbar.btn-run-gear.mode-deepseek){background:linear-gradient(135deg,#2740c4,#4d6bfe);border-color:#1b2a8f;color:#fff}html:is([data-skin=paper-gray],[data-skin=solarized-light],[data-skin=catppuccin-latte],[data-skin=rose-pine-dawn]) .btn-toolbar.btn-run-gear{border-left-color:var(--control-border-hover)!important}html:is([data-skin=paper-gray],[data-skin=solarized-light],[data-skin=catppuccin-latte],[data-skin=rose-pine-dawn]) :is(.case-settings-popover-mobile,.mobile-case-picker-sheet){background:var(--floating-bg);border-color:var(--control-border);color:var(--text);box-shadow:var(--elevated-shadow)}html:is([data-skin=paper-gray],[data-skin=solarized-light],[data-skin=catppuccin-latte],[data-skin=rose-pine-dawn]) :is(.case-settings-popover-mobile .checkbox-inline,#createCaseModal .form-row label){color:var(--text)}html:is([data-skin=paper-gray],[data-skin=solarized-light],[data-skin=catppuccin-latte],[data-skin=rose-pine-dawn]) .case-settings-popover-mobile .form-hint{color:var(--text-muted)}html:is([data-skin=paper-gray],[data-skin=solarized-light],[data-skin=catppuccin-latte],[data-skin=rose-pine-dawn]) .mobile-case-picker .modal-backdrop{background:var(--modal-backdrop)}.ios-device.safari-browser{overscroll-behavior:none}@media(hover:none)and (pointer:coarse){.session-tab .tab-close,.session-tab .tab-gear{opacity:1;width:auto;padding:.15rem .25rem;align-items:center;justify-content:center}.btn-toolbar:hover,.btn-icon-header:hover{transform:none}.subagent-dropdown-trigger:active+.subagent-dropdown-menu,.subagent-dropdown-trigger:focus+.subagent-dropdown-menu{display:block}}@media(max-width:430px){.attachment-history-drawer{top:0;bottom:0;width:100%;max-width:100%;height:100vh;height:100dvh;border-left:none;border-radius:0;padding-top:var(--safe-area-top);padding-left:var(--safe-area-left);padding-right:var(--safe-area-right);padding-bottom:var(--safe-area-bottom)}.attachment-history-header{padding:12px}.attachment-history-list{padding:6px}.attachment-history-item{grid-template-columns:104px minmax(0,1fr);gap:8px;padding:8px 6px}.attachment-history-thumb{width:104px}.attachment-history-actions{gap:4px}.attachment-history-actions button{padding:4px 7px}}@media(max-width:430px){.offline-banner{padding:.4rem .5rem;padding-left:calc(.5rem + var(--safe-area-left));padding-right:calc(.5rem + var(--safe-area-right));font-size:.7rem;gap:.4rem}.offline-banner-detail{display:none}.offline-banner-retry{padding:.25rem .5rem;margin-left:auto}.offline-overlay-card{padding:22px 18px 18px}.offline-overlay-title{font-size:1.05rem}.offline-overlay-actions{flex-direction:column}.offline-overlay-btn{width:100%;padding:.65rem 1rem}}@media(max-width:860px){:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .modal-content.modal-lg{width:100%;max-width:100%;height:100%;max-height:100%}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-body{display:flex;flex-direction:column;min-height:0}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-rail{flex-direction:row;align-items:center;border-right:0;border-bottom:1px solid var(--border);background:transparent;padding:10px 14px;overflow:visible;flex-shrink:0}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-rail-items,:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-rail-foot{display:none}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-search{margin:0;flex:1}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-search input{padding:9px 10px 9px 30px;border-radius:10px}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-head-actions:has(.set-head-save){padding:3px;border:1px solid var(--border);border-radius:12px;background:var(--bg-input)}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-head-save{display:inline-flex;height:36px;padding:0 16px;font-size:.86rem}#createCaseModal .set-head-save.loading{opacity:.6;pointer-events:none}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-head-actions .modal-close{width:36px;height:36px;font-size:1.35rem}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-foot{display:none}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-doc{padding:0 14px 34px;flex:1}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-jump{display:flex;position:sticky;top:0;z-index:4;align-items:center;gap:8px;width:100%;margin:10px 0 2px;padding:10px 12px;border-radius:11px;font:inherit;font-size:.82rem;color:var(--text);background:rgba(var(--accent-rgb),.13);border:1px solid rgba(var(--accent-rgb),.3);-webkit-backdrop-filter:blur(14px);backdrop-filter:blur(14px);cursor:pointer}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-jump-ico{color:var(--accent);flex-shrink:0}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-jump-label{font-weight:580;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-jump-chev{margin-left:auto;color:var(--text-muted);flex-shrink:0;transition:transform .18s}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-jump[aria-expanded=true] .set-jump-chev{transform:rotate(180deg)}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-jump-veil{display:none;position:fixed;inset:0;z-index:8;background:#04080d9e}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-jump-menu{display:none;position:absolute;left:14px;right:14px;z-index:9;padding:7px;border-radius:16px;background:var(--bg-card);border:1px solid var(--control-border);box-shadow:var(--elevated-shadow);max-height:70vh;overflow-y:auto}#appSettingsModal.jump-open .set-jump-veil,#appSettingsModal.jump-open .set-jump-menu{display:block}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-jump-row{display:flex;align-items:center;gap:11px;width:100%;padding:11px 12px;border:0;border-radius:11px;background:transparent;color:var(--text-dim);font:inherit;font-size:.82rem;text-align:left}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-jump-row svg{color:var(--text-muted);flex-shrink:0}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-jump-row .set-jump-count{margin-left:auto;font-size:.62rem;color:var(--text-muted)}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-jump-row.active{background:rgba(var(--accent-rgb),.14);color:var(--text);font-weight:570}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-jump-row.active svg{color:var(--accent)}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-section{padding-top:0}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-section+.set-section{border-top:0;margin-top:0}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-section-head{gap:7px;margin:18px 0 2px}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-section-head svg{padding:0;border:0;background:none;color:var(--text-muted);width:12px;height:12px}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-section-head h2{font-size:.6rem;font-weight:640;letter-spacing:.1em;text-transform:uppercase;color:var(--text-muted)}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-section-head:after{content:"";flex:1;height:1px;background:linear-gradient(90deg,var(--border),transparent)}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-section-blurb{display:none}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-preview{margin-bottom:12px}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-preview-stage{min-height:62px}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-group{margin-top:14px}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-group+.set-group{margin-top:16px}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-group-head{margin-bottom:7px;padding:0 3px}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-group-hint{padding:0 3px}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-group-body{gap:0;background:#ffffff09;border:1px solid rgba(255,255,255,.06);border-radius:13px;overflow:hidden}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-group-body>.set-row{background:transparent;border:0;border-radius:0;padding:12px 13px;gap:12px}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-group-body>.set-row+.set-row{border-top:1px solid rgba(255,255,255,.055)}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-group-body>.set-chips,:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-group-body>.set-modelgrid,:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-group-body>.set-minigrid,:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-group-body>#appSettingsShortcutsList{padding:12px}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-group-body>.event-type-grid{padding:12px;margin:0}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-row-label{font-size:.84rem}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-row-desc{font-size:.69rem;max-width:none}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-row.has-field{flex-direction:column;align-items:stretch;gap:9px}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-row.has-field .set-select,:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-row.has-field .set-input{width:100%;min-width:0;max-width:none;box-sizing:border-box}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-row-actions-wide{width:100%}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-row-actions-wide .set-input{flex:1;min-width:0}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-num{width:76px}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .switch-sm{width:40px;height:24px}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .switch-sm .slider:before{height:18px;width:18px}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .switch-sm input:checked+.slider:before{transform:translate(16px)}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-chip{font-size:.78rem;padding:9px 14px}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-modelgrid{grid-template-columns:repeat(2,minmax(0,1fr));gap:8px}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-minigrid{grid-template-columns:1fr}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-mini .set-select{width:148px}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-segment{overflow-x:auto;scrollbar-width:none}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-segment::-webkit-scrollbar{display:none}:is(#appSettingsModal,#sessionOptionsModal,#createCaseModal) .set-segment button{flex:0 0 auto;padding:8px 12px}}@media(max-width:860px){:is(#sessionOptionsModal,#createCaseModal) .set-rail{padding:8px 10px}:is(#sessionOptionsModal,#createCaseModal) .set-rail-items{display:flex;flex-direction:row;flex:1;min-width:0;gap:4px;overflow-x:auto;scrollbar-width:none}:is(#sessionOptionsModal,#createCaseModal) .set-rail-items::-webkit-scrollbar{display:none}:is(#sessionOptionsModal,#createCaseModal) .set-rail-item{white-space:nowrap;padding:8px 12px}:is(#sessionOptionsModal,#createCaseModal) .set-rail-item.active:before{display:none}:is(#sessionOptionsModal,#createCaseModal) .set-rail-item.active{background:rgba(var(--accent-rgb),.13)}}html[data-session-list=sidebar] .session-sidebar{position:absolute;top:0;bottom:0;left:0;width:min(280px,80vw);flex:0 0 auto;transform:translate(-100%);visibility:hidden;transition:transform var(--sidebar-transition),visibility var(--sidebar-transition);box-shadow:10px 0 28px #0000005c;z-index:12;padding-left:var(--safe-area-left)}html[data-session-list=sidebar][data-sidebar-detail=rich] .session-sidebar{width:min(280px,80vw);flex:0 0 auto}html[data-session-list=sidebar] .session-sidebar.open{transform:translate(0);visibility:visible}html[data-session-list=sidebar][data-sidebar=collapsed] .session-sidebar{flex-basis:auto;width:min(280px,80vw)}html[data-session-list=sidebar][data-sidebar=collapsed] .session-sidebar-head,html[data-session-list=sidebar][data-sidebar=collapsed] .session-sidebar-filter{display:flex}html[data-session-list=sidebar][data-sidebar=collapsed] .session-sidebar .session-tab{justify-content:flex-start;flex-wrap:nowrap;padding:.4rem .5rem}html[data-session-list=sidebar][data-sidebar=collapsed] .session-sidebar .tab-info{display:flex}html[data-session-list=sidebar][data-sidebar=collapsed] .session-sidebar .tab-number{display:inline-flex}html[data-session-list=sidebar][data-sidebar=collapsed] .session-sidebar .tab-subagent-badge{margin-left:4px}html[data-session-list=sidebar] .session-sidebar .session-tab{min-height:44px;max-height:none;flex-shrink:0}html[data-session-list=sidebar] .session-sidebar .session-tab .tab-gear,html[data-session-list=sidebar] .session-sidebar .session-tab .tab-close{display:inline-flex;align-items:center;justify-content:center;opacity:1;width:auto;min-width:28px;height:auto;margin-left:0;padding:.15rem .25rem}@media(prefers-reduced-motion:reduce){html[data-session-list=sidebar] .session-sidebar{transition:none}}
|
|
Binary file
|
|
Binary file
|
package/dist/web/public/{notification-manager.5d229063.js → notification-manager.36ea4624.js}
RENAMED
|
@@ -390,7 +390,7 @@ class NotificationManager {
|
|
|
390
390
|
const notif = new Notification(`${this.originalTitle}: ${localizedTitle}`, {
|
|
391
391
|
body: localizedBody,
|
|
392
392
|
tag, // Groups same-tag notifications
|
|
393
|
-
icon: '/favicon.ico',
|
|
393
|
+
icon: (window.CodemanBase?.url || ((p) => p))('/favicon.ico'),
|
|
394
394
|
silent: true, // We handle audio ourselves
|
|
395
395
|
});
|
|
396
396
|
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -220,7 +220,7 @@
|
|
|
220
220
|
`)}h.push(`
|
|
221
221
|
</div>
|
|
222
222
|
</div>
|
|
223
|
-
`)}t.innerHTML=h.join("")},closeProjectInsightsPanel(){const e=this.$("projectInsightsPanel");e&&(e.classList.remove("visible"),this.projectInsightsPanelVisible=!1)},_loadFileBrowserShowHidden(){try{return localStorage.getItem(FILE_BROWSER_SHOW_HIDDEN_KEY)==="1"}catch{return!1}},_syncFileBrowserHiddenBtn(){const e=this.$("fileBrowserHiddenBtn");if(!e)return;const t=this.fileBrowserShowHidden===!0;e.classList.toggle("active",t),e.setAttribute("aria-pressed",String(t));const s=t?"Hide hidden files and folders":"Show hidden files and folders";e.setAttribute("title",s),e.setAttribute("aria-label",s)},_ensureFileBrowserState(){if(!this._fileBrowserState){const e=this.activeSessionId||null,t=this.fileBrowserShowHidden===!0;this._fileBrowserState={treeEpoch:0,searchEpoch:0,ownerSessionId:e,view:"normal",normalState:this.fileBrowserData?{sessionId:e,showHidden:t,treeEpoch:0,phase:"ready",data:this.fileBrowserData}:null,treeInFlight:null,inFlight:null,matches:[],deferredDirectoryTarget:null,filter:typeof this.fileBrowserFilter=="string"?this.fileBrowserFilter:""}}return this._fileBrowserState},_activateFileBrowserSession(e){if(!e)return;const t=this._ensureFileBrowserState();t.inFlight?.timer!==void 0&&t.inFlight?.timer!==null&&clearTimeout(t.inFlight.timer),t.searchEpoch++,t.treeEpoch++,t.ownerSessionId=e,t.treeInFlight=null,t.inFlight=null,t.normalState=null,t.matches=[],t.deferredDirectoryTarget=null,t.filter="",t.view="normal",this.fileBrowserData=null,this.fileBrowserFilter="",this.fileBrowserExpandedDirs?.clear?.(),this.fileBrowserAllExpanded=!1;const s=this.$?.("fileBrowserSearch");s&&(s.value=""),this._syncFileBrowserExpandBtn();const n=this.$?.("fileBrowserExpandBtn");n&&(n.innerHTML="\u229E");const i=this.$?.("fileBrowserPanel"),a=this.$?.("fileBrowserTree"),r=this.$?.("fileBrowserStatus"),o=i?.classList.contains("visible")===!0;a&&(a.innerHTML=o?`<div class="file-browser-loading">${escapeHtml("Loading files...")}</div>`:""),r&&(r.textContent=o?"Loading files...":""),o&&this.loadFileBrowser?.(e)?.catch?.(()=>{})},_resetFileBrowserForHide(){const e=this._ensureFileBrowserState();e.inFlight?.timer!==void 0&&e.inFlight?.timer!==null&&clearTimeout(e.inFlight.timer),e.searchEpoch++,e.treeEpoch++,e.treeInFlight=null,e.inFlight=null,e.normalState=null,e.matches=[],e.deferredDirectoryTarget=null,e.filter="",e.view="normal",this.fileBrowserData=null,this.fileBrowserFilter="",this.fileBrowserExpandedDirs?.clear?.(),this.fileBrowserAllExpanded=!1;const t=this.$?.("fileBrowserSearch");t&&(t.value=""),this._syncFileBrowserExpandBtn();const s=this.$?.("fileBrowserExpandBtn");s&&(s.innerHTML="\u229E");const n=this.$?.("fileBrowserTree");n&&(n.innerHTML="");const i=this.$?.("fileBrowserStatus");i&&(i.textContent="")},_setFileBrowserExpandDisabled(e){const t=this.$("fileBrowserExpandBtn");t&&(t.disabled=e)},_hasFileBrowserQuery(){const e=this._ensureFileBrowserState(),t=this.$?.("fileBrowserSearch"),s=typeof t?.value=="string"?t.value:"",n=typeof e.filter=="string"?e.filter:"";return s.trim()!==""||n.trim()!==""},_syncFileBrowserExpandBtn(){this._setFileBrowserExpandDisabled(this._hasFileBrowserQuery())},_renderFileBrowserNormalStatus(e,t){const s=this.$("fileBrowserStatus");if(!s||!e)return;const{totalFiles:n,totalDirectories:i,truncated:a}=e;s.textContent=`${n} files, ${i} dirs${a?" (truncated)":""}${t?" \xB7 hidden shown":""}`},_isFileBrowserNormalCompatible(e,t,s,n){return e?.sessionId===t&&e.showHidden===s&&e.treeEpoch===n},_isFileBrowserTreeContextCurrent(e,t=!1){const s=this._ensureFileBrowserState();return(!t||s.treeInFlight===e)&&s.ownerSessionId===e.sessionId&&s.treeEpoch===e.treeEpoch&&this.fileBrowserShowHidden===!0===e.showHidden},_canRenderFileBrowserNormal(e){const t=this._ensureFileBrowserState();return t.view==="normal"&&this.activeSessionId===e?.sessionId&&this._isFileBrowserNormalCompatible(e,t.ownerSessionId,this.fileBrowserShowHidden===!0,t.treeEpoch)&&this.$("fileBrowserPanel")?.classList.contains("visible")===!0},_renderFileBrowserNormalState(e){if(!e||!this._canRenderFileBrowserNormal(e))return;const t=this.$("fileBrowserTree"),s=this.$("fileBrowserStatus");if(t){if(e.phase==="loading"){this.fileBrowserData=null,t.innerHTML=`<div class="file-browser-loading">${escapeHtml("Loading files...")}</div>`,s&&(s.textContent="Loading files...");return}if(e.phase==="error"){this.fileBrowserData=null;const i=`Failed to load files${e.error&&e.error!=="Failed to load files"?`: ${e.error}`:""}`;t.innerHTML=`<div class="file-browser-empty">${escapeHtml(i)}</div>`,s&&(s.textContent=i);return}e.phase==="ready"&&(this.fileBrowserData=e.data,this._syncFileBrowserExpandBtn(),this.renderFileBrowserTree(e.sessionId),this._renderFileBrowserNormalStatus(e.data,e.showHidden))}},_validateFileBrowserTreeEnvelope(e){if(!e||typeof e!="object"||e.success!==!0)return null;const t=e.data;if(!t||typeof t!="object"||!Array.isArray(t.tree)||t.mode==="search"||typeof t.totalFiles!="number"||!Number.isFinite(t.totalFiles)||t.totalFiles<0||typeof t.totalDirectories!="number"||!Number.isFinite(t.totalDirectories)||t.totalDirectories<0||typeof t.truncated!="boolean")return null;const s=n=>n.every(i=>!(!i||typeof i!="object"||typeof i.name!="string"||typeof i.path!="string"||i.type!=="file"&&i.type!=="directory"||i.size!==void 0&&(typeof i.size!="number"||!Number.isFinite(i.size))||i.extension!==void 0&&typeof i.extension!="string"||i.children!==void 0&&(!Array.isArray(i.children)||!s(i.children))));return s(t.tree)?t:null},_normalizeFileBrowserTreeError(e){return typeof e?.message=="string"&&e.message?e.message:"Failed to load files"},_validateFileBrowserSearchEnvelope(e){if(!e||typeof e!="object"||e.success!==!0)return null;const t=e.data;if(!t||typeof t!="object"||t.mode!=="search"||!Array.isArray(t.matches)||typeof t.truncated!="boolean"||t.matchCount!==void 0&&(typeof t.matchCount!="number"||!Number.isFinite(t.matchCount)||t.matchCount<0))return null;for(const s of t.matches)if(!s||typeof s!="object"||typeof s.name!="string"||typeof s.path!="string"||s.type!=="file"&&s.type!=="directory"||s.size!==void 0&&(typeof s.size!="number"||!Number.isFinite(s.size))||s.extension!==void 0&&typeof s.extension!="string")return null;return t},_canRenderFileBrowserSearch(e){const t=this._ensureFileBrowserState(),s=this.$("fileBrowserPanel");return t.searchEpoch===e.epoch&&t.ownerSessionId===e.ownerSessionId&&this.activeSessionId===e.ownerSessionId&&this.fileBrowserShowHidden===!0===e.showHidden&&t.filter===e.rawInput&&s?.classList.contains("visible")===!0},_renderFileBrowserSearchError(){const e=this.$("fileBrowserTree"),t=this.$("fileBrowserStatus"),s="Search failed";e&&(e.innerHTML=`<div class="file-browser-empty">${escapeHtml(s)}</div>`),t&&(t.textContent=s)},_canContinueFileBrowserHiddenReload(e,t){const s=this._ensureFileBrowserState(),n=this.$?.("fileBrowserSearch"),i=typeof n?.value=="string"?n.value:s.filter;return s.view==="normal"&&s.searchEpoch===e.searchEpoch&&s.treeEpoch===e.treeEpoch&&s.ownerSessionId===e.ownerSessionId&&this.activeSessionId===e.ownerSessionId&&this.fileBrowserShowHidden===!0===e.showHidden&&s.filter===e.rawInput&&i===e.rawInput&&i.trim()===e.query&&this.$?.("fileBrowserPanel")?.classList.contains("visible")===!0&&t?.phase==="ready"&&this._isFileBrowserNormalCompatible(t,e.ownerSessionId,e.showHidden,e.treeEpoch)},async toggleFileBrowserHidden(){const e=this._ensureFileBrowserState(),t=typeof e.filter=="string"?e.filter:"",s=t.trim();this.fileBrowserShowHidden=!this.fileBrowserShowHidden;try{localStorage.setItem(FILE_BROWSER_SHOW_HIDDEN_KEY,this.fileBrowserShowHidden?"1":"0")}catch{}this._syncFileBrowserHiddenBtn(),e.inFlight?.timer!==void 0&&e.inFlight?.timer!==null&&clearTimeout(e.inFlight.timer),e.searchEpoch++,e.inFlight=null,e.matches=[],e.deferredDirectoryTarget=null,e.normalState=null,this.fileBrowserData=null,s.length<=256&&(e.view="normal"),this._syncFileBrowserExpandBtn();const n=e.ownerSessionId||this.activeSessionId;if(!n||this.activeSessionId!==n)return;const i=e.searchEpoch,a=this.fileBrowserShowHidden===!0,r=this.loadFileBrowser(n,{force:!0}),o=e.treeEpoch;if(!r?.then||(await r,!s||s.length>256))return;const l={ownerSessionId:n,showHidden:a,treeEpoch:o,searchEpoch:i,rawInput:t,query:s};this._canContinueFileBrowserHiddenReload(l,e.normalState)&&this.filterFileBrowser(t)},loadFileBrowser(e,{force:t=!1}={}){if(!e)return;const s=this._ensureFileBrowserState(),n=this.$("fileBrowserTree");if(this._syncFileBrowserHiddenBtn(),!n||(s.ownerSessionId||(s.ownerSessionId=e),s.ownerSessionId!==e))return;t&&s.treeEpoch++;const i=this.fileBrowserShowHidden===!0,a=s.treeEpoch,r=s.treeInFlight;if(!t&&this._isFileBrowserNormalCompatible(r,e,i,a))return r.promise;const o=s.normalState;if(!t&&this._isFileBrowserNormalCompatible(o,e,i,a)&&(o.phase==="ready"||o.phase==="error"))return o.phase==="ready"&&(this.fileBrowserData=o.data),this._renderFileBrowserNormalState(o),Promise.resolve(o);const l={sessionId:e,showHidden:i,treeEpoch:a,phase:"loading"};s.normalState=l,this.fileBrowserData=null,this._renderFileBrowserNormalState(l);const c={sessionId:e,showHidden:i,treeEpoch:a,promise:null},h=(async()=>{try{const u=await fetch(`/api/sessions/${encodeURIComponent(e)}/files?depth=5&showHidden=${i}`);if(!u.ok)throw new Error("Failed to load files");const d=await u.json(),p=this._validateFileBrowserTreeEnvelope(d);if(!p){const y=d&&typeof d=="object"&&typeof d.error=="string"?d.error:"Failed to load files";throw new Error(y)}if(!this._isFileBrowserTreeContextCurrent(c,!0))return;const m={sessionId:e,showHidden:i,treeEpoch:a,phase:"ready",data:p};s.normalState=m,this.fileBrowserData=p,this._completeDeferredFileBrowserDirectory?.(m)===!0||this._renderFileBrowserNormalState(m)}catch(u){if(!this._isFileBrowserTreeContextCurrent(c,!0))return;const d={sessionId:e,showHidden:i,treeEpoch:a,phase:"error",error:this._normalizeFileBrowserTreeError(u)};s.normalState=d,this.fileBrowserData=null,this._completeDeferredFileBrowserDirectory?.(d),console.error("Failed to load file browser:",u),this._renderFileBrowserNormalState(d)}})();return c.promise=h.finally(()=>{s.treeInFlight===c&&(s.treeInFlight=null)}),s.treeInFlight=c,c.promise},renderFileBrowserTree(e){const t=this.$("fileBrowserTree");if(!t||!this.fileBrowserData)return;const s=this._ensureFileBrowserState(),n=e||s.normalState?.sessionId||s.ownerSessionId||this.activeSessionId;if(!n)return;const{tree:i}=this.fileBrowserData;if(!i||i.length===0){t.innerHTML='<div class="file-browser-empty">No files found</div>';return}const a=[],r=(o,l)=>{const c=o.type==="directory",h=this.fileBrowserExpandedDirs.has(o.path),u=c?h?"\u{1F4C2}":"\u{1F4C1}":this.getFileIcon(o.extension),d=c?`<span class="file-tree-expand${h?" expanded":""}">\u25B6</span>`:'<span class="file-tree-expand"></span>',p=!c&&o.size!==void 0?`<span class="file-tree-size">${this.formatFileSize(o.size)}</span>`:"",m=c?"file-tree-name directory":"file-tree-name",g=c?"":`<a class="file-tree-download" href="${escapeHtml(`/api/sessions/${encodeURIComponent(n)}/file-raw?path=${encodeURIComponent(o.path)}&download=true`)}" title="Download" onclick="event.stopPropagation()">⬇</a>`;if(a.push(`
|
|
223
|
+
`)}t.innerHTML=h.join("")},closeProjectInsightsPanel(){const e=this.$("projectInsightsPanel");e&&(e.classList.remove("visible"),this.projectInsightsPanelVisible=!1)},_loadFileBrowserShowHidden(){try{return localStorage.getItem(FILE_BROWSER_SHOW_HIDDEN_KEY)==="1"}catch{return!1}},_syncFileBrowserHiddenBtn(){const e=this.$("fileBrowserHiddenBtn");if(!e)return;const t=this.fileBrowserShowHidden===!0;e.classList.toggle("active",t),e.setAttribute("aria-pressed",String(t));const s=t?"Hide hidden files and folders":"Show hidden files and folders";e.setAttribute("title",s),e.setAttribute("aria-label",s)},_ensureFileBrowserState(){if(!this._fileBrowserState){const e=this.activeSessionId||null,t=this.fileBrowserShowHidden===!0;this._fileBrowserState={treeEpoch:0,searchEpoch:0,ownerSessionId:e,view:"normal",normalState:this.fileBrowserData?{sessionId:e,showHidden:t,treeEpoch:0,phase:"ready",data:this.fileBrowserData}:null,treeInFlight:null,inFlight:null,matches:[],deferredDirectoryTarget:null,filter:typeof this.fileBrowserFilter=="string"?this.fileBrowserFilter:""}}return this._fileBrowserState},_activateFileBrowserSession(e){if(!e)return;const t=this._ensureFileBrowserState();t.inFlight?.timer!==void 0&&t.inFlight?.timer!==null&&clearTimeout(t.inFlight.timer),t.searchEpoch++,t.treeEpoch++,t.ownerSessionId=e,t.treeInFlight=null,t.inFlight=null,t.normalState=null,t.matches=[],t.deferredDirectoryTarget=null,t.filter="",t.view="normal",this.fileBrowserData=null,this.fileBrowserFilter="",this.fileBrowserExpandedDirs?.clear?.(),this.fileBrowserAllExpanded=!1;const s=this.$?.("fileBrowserSearch");s&&(s.value=""),this._syncFileBrowserExpandBtn();const n=this.$?.("fileBrowserExpandBtn");n&&(n.innerHTML="\u229E");const i=this.$?.("fileBrowserPanel"),a=this.$?.("fileBrowserTree"),r=this.$?.("fileBrowserStatus"),o=i?.classList.contains("visible")===!0;a&&(a.innerHTML=o?`<div class="file-browser-loading">${escapeHtml("Loading files...")}</div>`:""),r&&(r.textContent=o?"Loading files...":""),o&&this.loadFileBrowser?.(e)?.catch?.(()=>{})},_resetFileBrowserForHide(){const e=this._ensureFileBrowserState();e.inFlight?.timer!==void 0&&e.inFlight?.timer!==null&&clearTimeout(e.inFlight.timer),e.searchEpoch++,e.treeEpoch++,e.treeInFlight=null,e.inFlight=null,e.normalState=null,e.matches=[],e.deferredDirectoryTarget=null,e.filter="",e.view="normal",this.fileBrowserData=null,this.fileBrowserFilter="",this.fileBrowserExpandedDirs?.clear?.(),this.fileBrowserAllExpanded=!1;const t=this.$?.("fileBrowserSearch");t&&(t.value=""),this._syncFileBrowserExpandBtn();const s=this.$?.("fileBrowserExpandBtn");s&&(s.innerHTML="\u229E");const n=this.$?.("fileBrowserTree");n&&(n.innerHTML="");const i=this.$?.("fileBrowserStatus");i&&(i.textContent="")},_setFileBrowserExpandDisabled(e){const t=this.$("fileBrowserExpandBtn");t&&(t.disabled=e)},_hasFileBrowserQuery(){const e=this._ensureFileBrowserState(),t=this.$?.("fileBrowserSearch"),s=typeof t?.value=="string"?t.value:"",n=typeof e.filter=="string"?e.filter:"";return s.trim()!==""||n.trim()!==""},_syncFileBrowserExpandBtn(){this._setFileBrowserExpandDisabled(this._hasFileBrowserQuery())},_renderFileBrowserNormalStatus(e,t){const s=this.$("fileBrowserStatus");if(!s||!e)return;const{totalFiles:n,totalDirectories:i,truncated:a}=e;s.textContent=`${n} files, ${i} dirs${a?" (truncated)":""}${t?" \xB7 hidden shown":""}`},_isFileBrowserNormalCompatible(e,t,s,n){return e?.sessionId===t&&e.showHidden===s&&e.treeEpoch===n},_isFileBrowserTreeContextCurrent(e,t=!1){const s=this._ensureFileBrowserState();return(!t||s.treeInFlight===e)&&s.ownerSessionId===e.sessionId&&s.treeEpoch===e.treeEpoch&&this.fileBrowserShowHidden===!0===e.showHidden},_canRenderFileBrowserNormal(e){const t=this._ensureFileBrowserState();return t.view==="normal"&&this.activeSessionId===e?.sessionId&&this._isFileBrowserNormalCompatible(e,t.ownerSessionId,this.fileBrowserShowHidden===!0,t.treeEpoch)&&this.$("fileBrowserPanel")?.classList.contains("visible")===!0},_renderFileBrowserNormalState(e){if(!e||!this._canRenderFileBrowserNormal(e))return;const t=this.$("fileBrowserTree"),s=this.$("fileBrowserStatus");if(t){if(e.phase==="loading"){this.fileBrowserData=null,t.innerHTML=`<div class="file-browser-loading">${escapeHtml("Loading files...")}</div>`,s&&(s.textContent="Loading files...");return}if(e.phase==="error"){this.fileBrowserData=null;const i=`Failed to load files${e.error&&e.error!=="Failed to load files"?`: ${e.error}`:""}`;t.innerHTML=`<div class="file-browser-empty">${escapeHtml(i)}</div>`,s&&(s.textContent=i);return}e.phase==="ready"&&(this.fileBrowserData=e.data,this._syncFileBrowserExpandBtn(),this.renderFileBrowserTree(e.sessionId),this._renderFileBrowserNormalStatus(e.data,e.showHidden))}},_validateFileBrowserTreeEnvelope(e){if(!e||typeof e!="object"||e.success!==!0)return null;const t=e.data;if(!t||typeof t!="object"||!Array.isArray(t.tree)||t.mode==="search"||typeof t.totalFiles!="number"||!Number.isFinite(t.totalFiles)||t.totalFiles<0||typeof t.totalDirectories!="number"||!Number.isFinite(t.totalDirectories)||t.totalDirectories<0||typeof t.truncated!="boolean")return null;const s=n=>n.every(i=>!(!i||typeof i!="object"||typeof i.name!="string"||typeof i.path!="string"||i.type!=="file"&&i.type!=="directory"||i.size!==void 0&&(typeof i.size!="number"||!Number.isFinite(i.size))||i.extension!==void 0&&typeof i.extension!="string"||i.children!==void 0&&(!Array.isArray(i.children)||!s(i.children))));return s(t.tree)?t:null},_normalizeFileBrowserTreeError(e){return typeof e?.message=="string"&&e.message?e.message:"Failed to load files"},_validateFileBrowserSearchEnvelope(e){if(!e||typeof e!="object"||e.success!==!0)return null;const t=e.data;if(!t||typeof t!="object"||t.mode!=="search"||!Array.isArray(t.matches)||typeof t.truncated!="boolean"||t.matchCount!==void 0&&(typeof t.matchCount!="number"||!Number.isFinite(t.matchCount)||t.matchCount<0))return null;for(const s of t.matches)if(!s||typeof s!="object"||typeof s.name!="string"||typeof s.path!="string"||s.type!=="file"&&s.type!=="directory"||s.size!==void 0&&(typeof s.size!="number"||!Number.isFinite(s.size))||s.extension!==void 0&&typeof s.extension!="string")return null;return t},_canRenderFileBrowserSearch(e){const t=this._ensureFileBrowserState(),s=this.$("fileBrowserPanel");return t.searchEpoch===e.epoch&&t.ownerSessionId===e.ownerSessionId&&this.activeSessionId===e.ownerSessionId&&this.fileBrowserShowHidden===!0===e.showHidden&&t.filter===e.rawInput&&s?.classList.contains("visible")===!0},_renderFileBrowserSearchError(){const e=this.$("fileBrowserTree"),t=this.$("fileBrowserStatus"),s="Search failed";e&&(e.innerHTML=`<div class="file-browser-empty">${escapeHtml(s)}</div>`),t&&(t.textContent=s)},_canContinueFileBrowserHiddenReload(e,t){const s=this._ensureFileBrowserState(),n=this.$?.("fileBrowserSearch"),i=typeof n?.value=="string"?n.value:s.filter;return s.view==="normal"&&s.searchEpoch===e.searchEpoch&&s.treeEpoch===e.treeEpoch&&s.ownerSessionId===e.ownerSessionId&&this.activeSessionId===e.ownerSessionId&&this.fileBrowserShowHidden===!0===e.showHidden&&s.filter===e.rawInput&&i===e.rawInput&&i.trim()===e.query&&this.$?.("fileBrowserPanel")?.classList.contains("visible")===!0&&t?.phase==="ready"&&this._isFileBrowserNormalCompatible(t,e.ownerSessionId,e.showHidden,e.treeEpoch)},async toggleFileBrowserHidden(){const e=this._ensureFileBrowserState(),t=typeof e.filter=="string"?e.filter:"",s=t.trim();this.fileBrowserShowHidden=!this.fileBrowserShowHidden;try{localStorage.setItem(FILE_BROWSER_SHOW_HIDDEN_KEY,this.fileBrowserShowHidden?"1":"0")}catch{}this._syncFileBrowserHiddenBtn(),e.inFlight?.timer!==void 0&&e.inFlight?.timer!==null&&clearTimeout(e.inFlight.timer),e.searchEpoch++,e.inFlight=null,e.matches=[],e.deferredDirectoryTarget=null,e.normalState=null,this.fileBrowserData=null,s.length<=256&&(e.view="normal"),this._syncFileBrowserExpandBtn();const n=e.ownerSessionId||this.activeSessionId;if(!n||this.activeSessionId!==n)return;const i=e.searchEpoch,a=this.fileBrowserShowHidden===!0,r=this.loadFileBrowser(n,{force:!0}),o=e.treeEpoch;if(!r?.then||(await r,!s||s.length>256))return;const l={ownerSessionId:n,showHidden:a,treeEpoch:o,searchEpoch:i,rawInput:t,query:s};this._canContinueFileBrowserHiddenReload(l,e.normalState)&&this.filterFileBrowser(t)},loadFileBrowser(e,{force:t=!1}={}){if(!e)return;const s=this._ensureFileBrowserState(),n=this.$("fileBrowserTree");if(this._syncFileBrowserHiddenBtn(),!n||(s.ownerSessionId||(s.ownerSessionId=e),s.ownerSessionId!==e))return;t&&s.treeEpoch++;const i=this.fileBrowserShowHidden===!0,a=s.treeEpoch,r=s.treeInFlight;if(!t&&this._isFileBrowserNormalCompatible(r,e,i,a))return r.promise;const o=s.normalState;if(!t&&this._isFileBrowserNormalCompatible(o,e,i,a)&&(o.phase==="ready"||o.phase==="error"))return o.phase==="ready"&&(this.fileBrowserData=o.data),this._renderFileBrowserNormalState(o),Promise.resolve(o);const l={sessionId:e,showHidden:i,treeEpoch:a,phase:"loading"};s.normalState=l,this.fileBrowserData=null,this._renderFileBrowserNormalState(l);const c={sessionId:e,showHidden:i,treeEpoch:a,promise:null},h=(async()=>{try{const u=await fetch(`/api/sessions/${encodeURIComponent(e)}/files?depth=5&showHidden=${i}`);if(!u.ok)throw new Error("Failed to load files");const d=await u.json(),p=this._validateFileBrowserTreeEnvelope(d);if(!p){const y=d&&typeof d=="object"&&typeof d.error=="string"?d.error:"Failed to load files";throw new Error(y)}if(!this._isFileBrowserTreeContextCurrent(c,!0))return;const m={sessionId:e,showHidden:i,treeEpoch:a,phase:"ready",data:p};s.normalState=m,this.fileBrowserData=p,this._completeDeferredFileBrowserDirectory?.(m)===!0||this._renderFileBrowserNormalState(m)}catch(u){if(!this._isFileBrowserTreeContextCurrent(c,!0))return;const d={sessionId:e,showHidden:i,treeEpoch:a,phase:"error",error:this._normalizeFileBrowserTreeError(u)};s.normalState=d,this.fileBrowserData=null,this._completeDeferredFileBrowserDirectory?.(d),console.error("Failed to load file browser:",u),this._renderFileBrowserNormalState(d)}})();return c.promise=h.finally(()=>{s.treeInFlight===c&&(s.treeInFlight=null)}),s.treeInFlight=c,c.promise},renderFileBrowserTree(e){const t=this.$("fileBrowserTree");if(!t||!this.fileBrowserData)return;const s=this._ensureFileBrowserState(),n=e||s.normalState?.sessionId||s.ownerSessionId||this.activeSessionId;if(!n)return;const{tree:i}=this.fileBrowserData;if(!i||i.length===0){t.innerHTML='<div class="file-browser-empty">No files found</div>';return}const a=[],r=(o,l)=>{const c=o.type==="directory",h=this.fileBrowserExpandedDirs.has(o.path),u=c?h?"\u{1F4C2}":"\u{1F4C1}":this.getFileIcon(o.extension),d=c?`<span class="file-tree-expand${h?" expanded":""}">\u25B6</span>`:'<span class="file-tree-expand"></span>',p=!c&&o.size!==void 0?`<span class="file-tree-size">${this.formatFileSize(o.size)}</span>`:"",m=c?"file-tree-name directory":"file-tree-name",g=c?"":`<a class="file-tree-download" href="${escapeHtml(CodemanBase.url(`/api/sessions/${encodeURIComponent(n)}/file-raw?path=${encodeURIComponent(o.path)}&download=true`))}" title="Download" onclick="event.stopPropagation()">⬇</a>`;if(a.push(`
|
|
224
224
|
<div class="file-tree-item" data-path="${escapeHtml(o.path)}" data-type="${escapeHtml(o.type)}" data-depth="${l}">
|
|
225
225
|
${d}
|
|
226
226
|
<span class="file-tree-icon">${u}</span>
|
|
@@ -228,7 +228,7 @@
|
|
|
228
228
|
${p}
|
|
229
229
|
${g}
|
|
230
230
|
</div>
|
|
231
|
-
`),c&&h&&o.children)for(const y of o.children)r(y,l+1)};for(const o of i)r(o,0);t.innerHTML=a.join(""),t.querySelectorAll(".file-tree-item").forEach(o=>{o.addEventListener("click",()=>{const l=o.dataset.path;o.dataset.type==="directory"?this.toggleFileBrowserFolder(l):this.openFilePreview(l,n)})})},toggleFileBrowserFolder(e){this.fileBrowserExpandedDirs.has(e)?this.fileBrowserExpandedDirs.delete(e):this.fileBrowserExpandedDirs.add(e),this.renderFileBrowserTree()},filterFileBrowser(e){const t=this._ensureFileBrowserState(),s=String(e??""),n=s.trim();t.searchEpoch++,t.filter=s,t.deferredDirectoryTarget=null,this.fileBrowserFilter=s,this._syncFileBrowserExpandBtn(),t.inFlight?.timer!==void 0&&t.inFlight?.timer!==null&&clearTimeout(t.inFlight.timer),t.inFlight=null,!t.ownerSessionId&&this.activeSessionId&&(t.ownerSessionId=this.activeSessionId);const i=t.ownerSessionId||null;if(!this.activeSessionId||!i||this.activeSessionId!==i)return;if(!n){t.view="normal",t.matches=[],this._syncFileBrowserExpandBtn();const c=t.normalState;i&&this._isFileBrowserNormalCompatible(c,i,this.fileBrowserShowHidden===!0,t.treeEpoch)&&this._renderFileBrowserNormalState(c);return}if(n.length>256){const c="Search queries are limited to 256 characters";t.view="query-error",t.matches=[],this._syncFileBrowserExpandBtn();const h=this.$("fileBrowserTree"),u=this.$("fileBrowserStatus");h&&(h.innerHTML=`<div class="file-browser-empty">${escapeHtml(c)}</div>`),u&&(u.textContent=c);return}const a=this.$("fileBrowserPanel"),r=this.$("fileBrowserTree");if(!i||!a||!r)return;const o={epoch:t.searchEpoch,treeEpoch:t.treeEpoch,ownerSessionId:i,showHidden:this.fileBrowserShowHidden===!0,rawInput:s,query:n,timer:null};t.view="search-pending",t.matches=[],t.inFlight=o,this._syncFileBrowserExpandBtn(),r.innerHTML=`<div class="file-browser-loading">${escapeHtml("Searching...")}</div>`;const l=this.$("fileBrowserStatus");l&&(l.textContent="Searching..."),o.timer=setTimeout(async()=>{o.timer=null;try{const c=await fetch(`/api/sessions/${encodeURIComponent(i)}/files?depth=5&showHidden=${o.showHidden}&q=${encodeURIComponent(n)}`);if(!c.ok)throw new Error("Search failed");const h=await c.json(),u=this._validateFileBrowserSearchEnvelope(h);if(!u)throw new Error("Search failed");const d=this._canRenderFileBrowserSearch(o);if(t.inFlight===o&&(t.inFlight=null),!d)return;t.view="search-results",t.matches=u.matches,this._renderFileBrowserSearchResults(u.matches,i,u)}catch(c){const h=this._canRenderFileBrowserSearch(o);if(t.inFlight===o&&(t.inFlight=null),!h)return;console.error("Failed to search file browser:",c),t.view="search-error",t.matches=[],this._renderFileBrowserSearchError()}},250)},_renderFileBrowserSearchResults(e,t,s){const n=this.$("fileBrowserTree");if(!n||!t)return;const i=this._ensureFileBrowserState(),a={ownerSessionId:t,showHidden:this.fileBrowserShowHidden===!0,treeEpoch:i.treeEpoch,searchEpoch:i.searchEpoch,rawInput:i.filter,query:i.filter.trim(),view:i.view};if(e.length===0)n.innerHTML=`<div class="file-browser-empty">${escapeHtml("No matches")}</div>`;else{const o=encodeURIComponent(t);n.innerHTML=e.map(l=>{const c=l.type==="directory",h=c?"\u{1F4C1}":this.getFileIcon(l.extension||""),u=!c&&l.size!==void 0?`<span class="file-tree-size">${this.formatFileSize(l.size)}</span>`:"",d=c?"file-tree-name directory":"file-tree-name",p=c?"":`<a class="file-tree-download" href="${escapeHtml(`/api/sessions/${o}/file-raw?path=${encodeURIComponent(l.path)}&download=true`)}" title="Download" onclick="event.stopPropagation()">⬇</a>`;return`
|
|
231
|
+
`),c&&h&&o.children)for(const y of o.children)r(y,l+1)};for(const o of i)r(o,0);t.innerHTML=a.join(""),t.querySelectorAll(".file-tree-item").forEach(o=>{o.addEventListener("click",()=>{const l=o.dataset.path;o.dataset.type==="directory"?this.toggleFileBrowserFolder(l):this.openFilePreview(l,n)})})},toggleFileBrowserFolder(e){this.fileBrowserExpandedDirs.has(e)?this.fileBrowserExpandedDirs.delete(e):this.fileBrowserExpandedDirs.add(e),this.renderFileBrowserTree()},filterFileBrowser(e){const t=this._ensureFileBrowserState(),s=String(e??""),n=s.trim();t.searchEpoch++,t.filter=s,t.deferredDirectoryTarget=null,this.fileBrowserFilter=s,this._syncFileBrowserExpandBtn(),t.inFlight?.timer!==void 0&&t.inFlight?.timer!==null&&clearTimeout(t.inFlight.timer),t.inFlight=null,!t.ownerSessionId&&this.activeSessionId&&(t.ownerSessionId=this.activeSessionId);const i=t.ownerSessionId||null;if(!this.activeSessionId||!i||this.activeSessionId!==i)return;if(!n){t.view="normal",t.matches=[],this._syncFileBrowserExpandBtn();const c=t.normalState;i&&this._isFileBrowserNormalCompatible(c,i,this.fileBrowserShowHidden===!0,t.treeEpoch)&&this._renderFileBrowserNormalState(c);return}if(n.length>256){const c="Search queries are limited to 256 characters";t.view="query-error",t.matches=[],this._syncFileBrowserExpandBtn();const h=this.$("fileBrowserTree"),u=this.$("fileBrowserStatus");h&&(h.innerHTML=`<div class="file-browser-empty">${escapeHtml(c)}</div>`),u&&(u.textContent=c);return}const a=this.$("fileBrowserPanel"),r=this.$("fileBrowserTree");if(!i||!a||!r)return;const o={epoch:t.searchEpoch,treeEpoch:t.treeEpoch,ownerSessionId:i,showHidden:this.fileBrowserShowHidden===!0,rawInput:s,query:n,timer:null};t.view="search-pending",t.matches=[],t.inFlight=o,this._syncFileBrowserExpandBtn(),r.innerHTML=`<div class="file-browser-loading">${escapeHtml("Searching...")}</div>`;const l=this.$("fileBrowserStatus");l&&(l.textContent="Searching..."),o.timer=setTimeout(async()=>{o.timer=null;try{const c=await fetch(`/api/sessions/${encodeURIComponent(i)}/files?depth=5&showHidden=${o.showHidden}&q=${encodeURIComponent(n)}`);if(!c.ok)throw new Error("Search failed");const h=await c.json(),u=this._validateFileBrowserSearchEnvelope(h);if(!u)throw new Error("Search failed");const d=this._canRenderFileBrowserSearch(o);if(t.inFlight===o&&(t.inFlight=null),!d)return;t.view="search-results",t.matches=u.matches,this._renderFileBrowserSearchResults(u.matches,i,u)}catch(c){const h=this._canRenderFileBrowserSearch(o);if(t.inFlight===o&&(t.inFlight=null),!h)return;console.error("Failed to search file browser:",c),t.view="search-error",t.matches=[],this._renderFileBrowserSearchError()}},250)},_renderFileBrowserSearchResults(e,t,s){const n=this.$("fileBrowserTree");if(!n||!t)return;const i=this._ensureFileBrowserState(),a={ownerSessionId:t,showHidden:this.fileBrowserShowHidden===!0,treeEpoch:i.treeEpoch,searchEpoch:i.searchEpoch,rawInput:i.filter,query:i.filter.trim(),view:i.view};if(e.length===0)n.innerHTML=`<div class="file-browser-empty">${escapeHtml("No matches")}</div>`;else{const o=encodeURIComponent(t);n.innerHTML=e.map(l=>{const c=l.type==="directory",h=c?"\u{1F4C1}":this.getFileIcon(l.extension||""),u=!c&&l.size!==void 0?`<span class="file-tree-size">${this.formatFileSize(l.size)}</span>`:"",d=c?"file-tree-name directory":"file-tree-name",p=c?"":`<a class="file-tree-download" href="${escapeHtml(CodemanBase.url(`/api/sessions/${o}/file-raw?path=${encodeURIComponent(l.path)}&download=true`))}" title="Download" onclick="event.stopPropagation()">⬇</a>`;return`
|
|
232
232
|
<div class="file-tree-item" data-path="${escapeHtml(l.path)}" data-type="${escapeHtml(l.type)}" data-owner="${escapeHtml(t)}">
|
|
233
233
|
<span class="file-tree-expand"></span>
|
|
234
234
|
<span class="file-tree-icon">${h}</span>
|
|
@@ -236,10 +236,10 @@
|
|
|
236
236
|
${u}
|
|
237
237
|
${p}
|
|
238
238
|
</div>
|
|
239
|
-
`}).join("")}n.querySelectorAll(".file-tree-item").forEach(o=>{o.addEventListener("click",()=>{const l=o.dataset.path;o.dataset.type==="directory"?this._openFileBrowserSearchDirectory({...a,path:l}):this.openFilePreview(l,t)})});const r=this.$("fileBrowserStatus");if(r){const o=s.matchCount===void 0?e.length:s.matchCount;r.textContent=`${o} ${o===1?"match":"matches"}${s.truncated?" (truncated)":""}`}},_findFileBrowserDirectory(e,t,s=[]){if(!Array.isArray(e))return null;for(const n of e){if(!n||typeof n!="object")continue;if(n.type==="directory"&&n.path===t)return{target:n,ancestors:[...s]};if(n.type!=="directory"||!Array.isArray(n.children))continue;const i=this._findFileBrowserDirectory(n.children,t,[...s,n.path]);if(i)return i}return null},_isFileBrowserDirectoryContextCurrent(e){const t=this._ensureFileBrowserState(),s=this.$?.("fileBrowserSearch"),n=typeof s?.value=="string"?s.value:t.filter;return e&&t.ownerSessionId===e.ownerSessionId&&this.activeSessionId===e.ownerSessionId&&t.treeEpoch===e.treeEpoch&&t.searchEpoch===e.searchEpoch&&this.fileBrowserShowHidden===!0===e.showHidden&&t.filter===e.rawInput&&n===e.rawInput&&n.trim()===e.query&&t.view===e.view&&this.$?.("fileBrowserPanel")?.classList.contains("visible")===!0},_promptFileBrowserDirectoryReload(){this.showToast?.("Reload files before opening this folder","info")},_openFileBrowserSearchDirectory(e){if(!this._isFileBrowserDirectoryContextCurrent(e))return;const t=this._ensureFileBrowserState(),s=t.normalState;if(!this._isFileBrowserNormalCompatible(s,e.ownerSessionId,e.showHidden,e.treeEpoch)){t.deferredDirectoryTarget=null,this._promptFileBrowserDirectoryReload();return}if(s.phase==="loading"){t.deferredDirectoryTarget={...e};return}if(t.deferredDirectoryTarget=null,s.phase!=="ready"){this._promptFileBrowserDirectoryReload();return}const n=this._findFileBrowserDirectory(s.data?.tree,e.path);if(!n){this._promptFileBrowserDirectoryReload();return}this._leaveFileBrowserSearchForDirectory([...n.ancestors,n.target.path],s)},_completeDeferredFileBrowserDirectory(e){const t=this._ensureFileBrowserState(),s=t.deferredDirectoryTarget;if(!s)return!1;if(!this._isFileBrowserDirectoryContextCurrent(s))return t.deferredDirectoryTarget===s&&(t.deferredDirectoryTarget=null),!1;if(!this._isFileBrowserNormalCompatible(e,s.ownerSessionId,s.showHidden,s.treeEpoch)||e.phase!=="ready"&&e.phase!=="error")return!1;if(t.deferredDirectoryTarget=null,e.phase==="error")return this._promptFileBrowserDirectoryReload(),!1;const n=this._findFileBrowserDirectory(e.data?.tree,s.path);return n?(this._leaveFileBrowserSearchForDirectory([...n.ancestors,n.target.path],e),!0):(this._promptFileBrowserDirectoryReload(),!1)},_leaveFileBrowserSearchForDirectory(e,t){const s=this._ensureFileBrowserState();s.inFlight?.timer!==void 0&&s.inFlight?.timer!==null&&clearTimeout(s.inFlight.timer),s.searchEpoch++,s.inFlight=null,s.filter="",s.matches=[],s.deferredDirectoryTarget=null,s.view="normal",this.fileBrowserFilter="";const n=this.$?.("fileBrowserSearch");n&&(n.value=""),this._syncFileBrowserExpandBtn();for(const i of e)typeof i=="string"&&this.fileBrowserExpandedDirs?.add?.(i);this.fileBrowserData=t.data,this._renderFileBrowserNormalState(t)},expandAllDirectories(e){for(const t of e)t.type==="directory"&&(this.fileBrowserExpandedDirs.add(t.path),t.children&&this.expandAllDirectories(t.children))},collapseAllDirectories(){this.fileBrowserExpandedDirs.clear()},toggleFileBrowserExpand(){if(this._hasFileBrowserQuery()){this._syncFileBrowserExpandBtn();return}this.fileBrowserAllExpanded=!this.fileBrowserAllExpanded;const e=this.$("fileBrowserExpandBtn");this.fileBrowserAllExpanded?(this.expandAllDirectories(this.fileBrowserData?.tree||[]),e&&(e.innerHTML="\u229F")):(this.collapseAllDirectories(),e&&(e.innerHTML="\u229E")),this.renderFileBrowserTree()},refreshFileBrowser(){const e=this._ensureFileBrowserState();e.inFlight?.timer!==void 0&&e.inFlight?.timer!==null&&clearTimeout(e.inFlight.timer),e.inFlight=null,e.searchEpoch++,e.filter="",e.matches=[],e.deferredDirectoryTarget=null,e.view="normal",this.fileBrowserFilter="",this.fileBrowserExpandedDirs.clear(),this.fileBrowserAllExpanded=!1;const t=this.$("fileBrowserExpandBtn");t&&(t.innerHTML="\u229E");const s=this.$("fileBrowserSearch");s&&(s.value=""),this._syncFileBrowserExpandBtn();const n=e.ownerSessionId||this.activeSessionId;if(!(!n||this.activeSessionId!==n))return this.loadFileBrowser(n,{force:!0})},toggleFileBrowserButton(){const t=this.$("fileBrowserPanel")?.classList.contains("visible"),s=document.querySelector(".btn-file-viewer");if(t){this.closeFileBrowserPanel(),s&&s.setAttribute("aria-expanded","false");return}if(!this.activeSessionId){this.showToast("Open a session to browse its files","info");return}const n=this.loadAppSettingsFromStorage();n.showFileBrowser=!0,this.saveAppSettingsToStorage(n);const i=document.getElementById("appSettingsShowFileBrowser");i&&(i.checked=!0),this.applyMonitorVisibility(),s&&s.setAttribute("aria-expanded","true")},closeFileBrowserPanel(){const e=this.$("fileBrowserPanel");if(this._resetFileBrowserForHide(),e&&(e.classList.remove("visible"),e.style.left="",e.style.top="",e.style.bottom="",e.style.right=""),this.fileBrowserDragListeners){const i=this.fileBrowserDragListeners;document.removeEventListener("mousemove",i.move),document.removeEventListener("mouseup",i.up),document.removeEventListener("touchmove",i.touchMove),document.removeEventListener("touchend",i.up),document.removeEventListener("touchcancel",i.up),i.handle&&(i.handle.removeEventListener("mousedown",i.handleMouseDown),i.handle.removeEventListener("touchstart",i.handleTouchStart),i._onFirstDrag&&(i.handle.removeEventListener("mousedown",i._onFirstDrag),i.handle.removeEventListener("touchstart",i._onFirstDrag))),this.fileBrowserDragListeners=null}const t=this.loadAppSettingsFromStorage();t.showFileBrowser=!1,this.saveAppSettingsToStorage(t);const s=document.getElementById("appSettingsShowFileBrowser");s&&(s.checked=!1);const n=document.querySelector(".btn-file-viewer");n&&n.setAttribute("aria-expanded","false")},_isExternalPreviewPath(e,t){if(typeof e!="string"||!e.startsWith("/"))return!1;const s=this.sessions.get(t)?.workingDir;if(!s)return!1;const n=s.endsWith("/")?s:`${s}/`;return e!==s&&!e.startsWith(n)},async _registerExternalPreview(e,t){try{const s=await fetch(`/api/sessions/${t}/attachments`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({path:e,notify:!1})}),n=await s.json().catch(()=>null);if(s.ok&&n?.success&&n.data?.attachmentId)return{attachmentId:n.data.attachmentId,size:n.data.size||0};const i=n?.error||`Cannot open this file (HTTP ${s.status})`;return/unsupported/i.test(i)?{error:`Cannot preview .${(e.split(".").pop()||"").toLowerCase()} from outside the session workspace (images, video, audio, PDF, Office documents and text files only).`}:{error:i}}catch(s){return{error:s.message||"Cannot open this file"}}},async openFilePreview(e,t=this.activeSessionId,s=null){if(!t||!e)return;const n=this.$("filePreviewOverlay"),i=this.$("filePreviewTitle"),a=this.$("filePreviewBody"),r=this.$("filePreviewFooter");if(!n||!a)return;this._resetFilePreviewEdit(),this._stopFilePreviewMedia(),this.filePreviewDetachUrl="";const o=this.$("filePreviewDetachBtn");o&&(o.hidden=!0),n.classList.add("visible"),i.textContent=e,a.innerHTML='<div class="binary-message">Loading...</div>',r.textContent="";const l=(e.split(".").pop()||"").toLowerCase();let c="",h=0;if(!s&&this._isExternalPreviewPath(e,t)){const d=await this._registerExternalPreview(e,t);s=d.attachmentId||null,c=d.error||"",h=d.size||0}if(!s&&c){r.textContent="",a.innerHTML=`<div class="binary-message">${escapeHtml(c)}</div>`;return}const u=l==="docx"||l==="pptx";if(this.filePreviewDetachUrl=s?`/api/sessions/${t}/attachments/${encodeURIComponent(s)}/${u?"preview":"raw"}`:u?`/api/sessions/${t}/file-preview?path=${encodeURIComponent(e)}`:`/api/sessions/${t}/file-raw?path=${encodeURIComponent(e)}
|
|
239
|
+
`}).join("")}n.querySelectorAll(".file-tree-item").forEach(o=>{o.addEventListener("click",()=>{const l=o.dataset.path;o.dataset.type==="directory"?this._openFileBrowserSearchDirectory({...a,path:l}):this.openFilePreview(l,t)})});const r=this.$("fileBrowserStatus");if(r){const o=s.matchCount===void 0?e.length:s.matchCount;r.textContent=`${o} ${o===1?"match":"matches"}${s.truncated?" (truncated)":""}`}},_findFileBrowserDirectory(e,t,s=[]){if(!Array.isArray(e))return null;for(const n of e){if(!n||typeof n!="object")continue;if(n.type==="directory"&&n.path===t)return{target:n,ancestors:[...s]};if(n.type!=="directory"||!Array.isArray(n.children))continue;const i=this._findFileBrowserDirectory(n.children,t,[...s,n.path]);if(i)return i}return null},_isFileBrowserDirectoryContextCurrent(e){const t=this._ensureFileBrowserState(),s=this.$?.("fileBrowserSearch"),n=typeof s?.value=="string"?s.value:t.filter;return e&&t.ownerSessionId===e.ownerSessionId&&this.activeSessionId===e.ownerSessionId&&t.treeEpoch===e.treeEpoch&&t.searchEpoch===e.searchEpoch&&this.fileBrowserShowHidden===!0===e.showHidden&&t.filter===e.rawInput&&n===e.rawInput&&n.trim()===e.query&&t.view===e.view&&this.$?.("fileBrowserPanel")?.classList.contains("visible")===!0},_promptFileBrowserDirectoryReload(){this.showToast?.("Reload files before opening this folder","info")},_openFileBrowserSearchDirectory(e){if(!this._isFileBrowserDirectoryContextCurrent(e))return;const t=this._ensureFileBrowserState(),s=t.normalState;if(!this._isFileBrowserNormalCompatible(s,e.ownerSessionId,e.showHidden,e.treeEpoch)){t.deferredDirectoryTarget=null,this._promptFileBrowserDirectoryReload();return}if(s.phase==="loading"){t.deferredDirectoryTarget={...e};return}if(t.deferredDirectoryTarget=null,s.phase!=="ready"){this._promptFileBrowserDirectoryReload();return}const n=this._findFileBrowserDirectory(s.data?.tree,e.path);if(!n){this._promptFileBrowserDirectoryReload();return}this._leaveFileBrowserSearchForDirectory([...n.ancestors,n.target.path],s)},_completeDeferredFileBrowserDirectory(e){const t=this._ensureFileBrowserState(),s=t.deferredDirectoryTarget;if(!s)return!1;if(!this._isFileBrowserDirectoryContextCurrent(s))return t.deferredDirectoryTarget===s&&(t.deferredDirectoryTarget=null),!1;if(!this._isFileBrowserNormalCompatible(e,s.ownerSessionId,s.showHidden,s.treeEpoch)||e.phase!=="ready"&&e.phase!=="error")return!1;if(t.deferredDirectoryTarget=null,e.phase==="error")return this._promptFileBrowserDirectoryReload(),!1;const n=this._findFileBrowserDirectory(e.data?.tree,s.path);return n?(this._leaveFileBrowserSearchForDirectory([...n.ancestors,n.target.path],e),!0):(this._promptFileBrowserDirectoryReload(),!1)},_leaveFileBrowserSearchForDirectory(e,t){const s=this._ensureFileBrowserState();s.inFlight?.timer!==void 0&&s.inFlight?.timer!==null&&clearTimeout(s.inFlight.timer),s.searchEpoch++,s.inFlight=null,s.filter="",s.matches=[],s.deferredDirectoryTarget=null,s.view="normal",this.fileBrowserFilter="";const n=this.$?.("fileBrowserSearch");n&&(n.value=""),this._syncFileBrowserExpandBtn();for(const i of e)typeof i=="string"&&this.fileBrowserExpandedDirs?.add?.(i);this.fileBrowserData=t.data,this._renderFileBrowserNormalState(t)},expandAllDirectories(e){for(const t of e)t.type==="directory"&&(this.fileBrowserExpandedDirs.add(t.path),t.children&&this.expandAllDirectories(t.children))},collapseAllDirectories(){this.fileBrowserExpandedDirs.clear()},toggleFileBrowserExpand(){if(this._hasFileBrowserQuery()){this._syncFileBrowserExpandBtn();return}this.fileBrowserAllExpanded=!this.fileBrowserAllExpanded;const e=this.$("fileBrowserExpandBtn");this.fileBrowserAllExpanded?(this.expandAllDirectories(this.fileBrowserData?.tree||[]),e&&(e.innerHTML="\u229F")):(this.collapseAllDirectories(),e&&(e.innerHTML="\u229E")),this.renderFileBrowserTree()},refreshFileBrowser(){const e=this._ensureFileBrowserState();e.inFlight?.timer!==void 0&&e.inFlight?.timer!==null&&clearTimeout(e.inFlight.timer),e.inFlight=null,e.searchEpoch++,e.filter="",e.matches=[],e.deferredDirectoryTarget=null,e.view="normal",this.fileBrowserFilter="",this.fileBrowserExpandedDirs.clear(),this.fileBrowserAllExpanded=!1;const t=this.$("fileBrowserExpandBtn");t&&(t.innerHTML="\u229E");const s=this.$("fileBrowserSearch");s&&(s.value=""),this._syncFileBrowserExpandBtn();const n=e.ownerSessionId||this.activeSessionId;if(!(!n||this.activeSessionId!==n))return this.loadFileBrowser(n,{force:!0})},toggleFileBrowserButton(){const t=this.$("fileBrowserPanel")?.classList.contains("visible"),s=document.querySelector(".btn-file-viewer");if(t){this.closeFileBrowserPanel(),s&&s.setAttribute("aria-expanded","false");return}if(!this.activeSessionId){this.showToast("Open a session to browse its files","info");return}const n=this.loadAppSettingsFromStorage();n.showFileBrowser=!0,this.saveAppSettingsToStorage(n);const i=document.getElementById("appSettingsShowFileBrowser");i&&(i.checked=!0),this.applyMonitorVisibility(),s&&s.setAttribute("aria-expanded","true")},closeFileBrowserPanel(){const e=this.$("fileBrowserPanel");if(this._resetFileBrowserForHide(),e&&(e.classList.remove("visible"),e.style.left="",e.style.top="",e.style.bottom="",e.style.right=""),this.fileBrowserDragListeners){const i=this.fileBrowserDragListeners;document.removeEventListener("mousemove",i.move),document.removeEventListener("mouseup",i.up),document.removeEventListener("touchmove",i.touchMove),document.removeEventListener("touchend",i.up),document.removeEventListener("touchcancel",i.up),i.handle&&(i.handle.removeEventListener("mousedown",i.handleMouseDown),i.handle.removeEventListener("touchstart",i.handleTouchStart),i._onFirstDrag&&(i.handle.removeEventListener("mousedown",i._onFirstDrag),i.handle.removeEventListener("touchstart",i._onFirstDrag))),this.fileBrowserDragListeners=null}const t=this.loadAppSettingsFromStorage();t.showFileBrowser=!1,this.saveAppSettingsToStorage(t);const s=document.getElementById("appSettingsShowFileBrowser");s&&(s.checked=!1);const n=document.querySelector(".btn-file-viewer");n&&n.setAttribute("aria-expanded","false")},_isExternalPreviewPath(e,t){if(typeof e!="string"||!e.startsWith("/"))return!1;const s=this.sessions.get(t)?.workingDir;if(!s)return!1;const n=s.endsWith("/")?s:`${s}/`;return e!==s&&!e.startsWith(n)},async _registerExternalPreview(e,t){try{const s=await fetch(`/api/sessions/${t}/attachments`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({path:e,notify:!1})}),n=await s.json().catch(()=>null);if(s.ok&&n?.success&&n.data?.attachmentId)return{attachmentId:n.data.attachmentId,size:n.data.size||0};const i=n?.error||`Cannot open this file (HTTP ${s.status})`;return/unsupported/i.test(i)?{error:`Cannot preview .${(e.split(".").pop()||"").toLowerCase()} from outside the session workspace (images, video, audio, PDF, Office documents and text files only).`}:{error:i}}catch(s){return{error:s.message||"Cannot open this file"}}},async openFilePreview(e,t=this.activeSessionId,s=null){if(!t||!e)return;const n=this.$("filePreviewOverlay"),i=this.$("filePreviewTitle"),a=this.$("filePreviewBody"),r=this.$("filePreviewFooter");if(!n||!a)return;this._resetFilePreviewEdit(),this._stopFilePreviewMedia(),this.filePreviewDetachUrl="";const o=this.$("filePreviewDetachBtn");o&&(o.hidden=!0),n.classList.add("visible"),i.textContent=e,a.innerHTML='<div class="binary-message">Loading...</div>',r.textContent="";const l=(e.split(".").pop()||"").toLowerCase();let c="",h=0;if(!s&&this._isExternalPreviewPath(e,t)){const d=await this._registerExternalPreview(e,t);s=d.attachmentId||null,c=d.error||"",h=d.size||0}if(!s&&c){r.textContent="",a.innerHTML=`<div class="binary-message">${escapeHtml(c)}</div>`;return}const u=l==="docx"||l==="pptx";if(this.filePreviewDetachUrl=CodemanBase.url(s?`/api/sessions/${t}/attachments/${encodeURIComponent(s)}/${u?"preview":"raw"}`:u?`/api/sessions/${t}/file-preview?path=${encodeURIComponent(e)}`:`/api/sessions/${t}/file-raw?path=${encodeURIComponent(e)}`),o&&(o.hidden=!1),s){const d=CodemanBase.url(`/api/sessions/${t}/attachments/${encodeURIComponent(s)}`),p=new Set(["png","jpg","jpeg","gif","webp","bmp","svg"]),m=new Set(["mp4","webm","mov","m4v","ogv"]),g=new Set(["mp3","wav","ogg","oga","m4a","aac","flac","opus"]);if(r.textContent=h?`${this.formatFileSize(h)} \u2022 ${l}`:l.toUpperCase(),p.has(l))a.innerHTML=`<img src="${escapeHtml(`${d}/raw`)}" alt="${escapeHtml(e)}">`;else if(m.has(l))a.innerHTML=`<video src="${escapeHtml(`${d}/raw`)}" controls autoplay playsinline preload="metadata"></video>`;else if(g.has(l))a.innerHTML=`<audio src="${escapeHtml(`${d}/raw`)}" controls autoplay preload="metadata"></audio>`;else if(l==="pdf")a.innerHTML=`<iframe src="${escapeHtml(`${d}/raw`)}" title="${escapeHtml(e)}"></iframe>`;else if(l==="docx"||l==="pptx")a.innerHTML=`<iframe src="${escapeHtml(`${d}/preview`)}" title="${escapeHtml(e)}"></iframe>`;else try{const y=await fetch(`${d}/raw`,{headers:{Range:"bytes=0-524287"}});if(!y.ok)throw new Error("Failed to load attachment");const w=await y.text(),b=y.status===206&&w.length>=524288,$=w.split(`
|
|
240
240
|
`),f=$.length>500,S=f?$.slice(0,500).join(`
|
|
241
|
-
`):w;if(a.innerHTML=`<pre><code>${escapeHtml(S)}</code></pre>`,this.filePreviewContent=S,f||b){const T=f?"showing first 500 lines":"showing the start of the file";r.textContent=`${r.textContent} (${T})`}}catch(y){a.innerHTML=`<div class="binary-message">Error: ${escapeHtml(y.message)}</div>`}return}if(l==="docx"||l==="pptx"){r.textContent=l.toUpperCase();const d
|
|
242
|
-
OK overwrites it with your version; Cancel keeps your draft open.`)&&this.saveFilePreviewEdit(!0);return}if(!a||a.success!==!0){i(),this.showToast(`Save failed: ${a?.error||`HTTP ${r}`}`,"error");return}const{sessionId:o,filePath:l}=t;this._resetFilePreviewEdit(),this.showToast("Saved","success"),this.openFilePreview(l,o)},_onAttachmentDetected(e){if(console.log("[Attachment Detected]",e),this.addAttachmentCard(e),e.sessionId){const t=this.attachmentHistoryCounts.get(e.sessionId)??this.sessions.get(e.sessionId)?.attachmentHistory?.length??0;this.attachmentHistoryCounts.set(e.sessionId,Math.min(t+1,100)),e.sessionId===this.activeSessionId&&(this.updateAttachmentHistoryBadge(),this.attachmentHistoryDrawerOpen&&this._debouncedCall("attachmentHistoryRefresh",()=>{this.attachmentHistoryDrawerOpen&&this.activeSessionId===e.sessionId&&this.loadAttachmentHistory(e.sessionId)},250))}},ensureAttachmentCardStack(){let e=this.attachmentCardStack||document.getElementById("attachmentCardStack");return e||(e=document.createElement("div"),e.id="attachmentCardStack",e.className="attachment-card-stack",document.body.appendChild(e)),this.attachmentCardStack=e,e},openAttachmentInNewTab(e,t,s=null){const n=s?`/api/sessions/${e}/attachments/${encodeURIComponent(s)}/raw`:`/api/sessions/${e}/file-raw?path=${encodeURIComponent(t)}
|
|
241
|
+
`):w;if(a.innerHTML=`<pre><code>${escapeHtml(S)}</code></pre>`,this.filePreviewContent=S,f||b){const T=f?"showing first 500 lines":"showing the start of the file";r.textContent=`${r.textContent} (${T})`}}catch(y){a.innerHTML=`<div class="binary-message">Error: ${escapeHtml(y.message)}</div>`}return}if(l==="docx"||l==="pptx"){r.textContent=l.toUpperCase();const d=CodemanBase.url(`/api/sessions/${t}/file-preview?path=${encodeURIComponent(e)}`);a.innerHTML=`<iframe src="${escapeHtml(d)}" title="${escapeHtml(e)}"></iframe>`;return}if(l==="pdf"){r.textContent="PDF";const d=CodemanBase.url(`/api/sessions/${t}/file-raw?path=${encodeURIComponent(e)}`);a.innerHTML=`<iframe src="${escapeHtml(d)}" title="${escapeHtml(e)}"></iframe>`;return}if(l==="svg"){r.textContent="SVG";try{const d=await fetch(`/api/sessions/${t}/file-raw?path=${encodeURIComponent(e)}`);if(!d.ok)throw new Error("Failed to load image");const p=URL.createObjectURL(new Blob([await d.text()],{type:"image/svg+xml"}));a.innerHTML=`<img src="${p}" alt="${escapeHtml(e)}">`;const m=a.querySelector("img");m&&(m.onload=()=>URL.revokeObjectURL(p))}catch(d){a.innerHTML=`<div class="binary-message">Error: ${escapeHtml(d.message)}</div>`}return}try{const d=await fetch(`/api/sessions/${t}/file-content?path=${encodeURIComponent(e)}&lines=500`);if(!d.ok)throw new Error("Failed to load file");const p=await d.json();if(!p.success)throw new Error(p.error||"Failed to load file");const m=p.data;if(m.type==="image")a.innerHTML=`<img src="${escapeHtml(CodemanBase.url(m.url))}" alt="${escapeHtml(e)}">`,r.textContent=`${this.formatFileSize(m.size)} \u2022 ${m.extension}`;else if(m.type==="video")a.innerHTML=`<video src="${escapeHtml(CodemanBase.url(m.url))}" controls autoplay playsinline preload="metadata"></video>`,r.textContent=`${this.formatFileSize(m.size)} \u2022 ${m.extension}`;else if(m.type==="audio")a.innerHTML=`<audio src="${escapeHtml(CodemanBase.url(m.url))}" controls autoplay preload="metadata"></audio>`,r.textContent=`${this.formatFileSize(m.size)} \u2022 ${m.extension}`;else if(m.type==="binary"){const g=CodemanBase.url(`/api/sessions/${t}/file-raw?path=${encodeURIComponent(e)}&download=true`);a.innerHTML=`<div class="binary-message">Binary file (${this.formatFileSize(m.size)})<br>Cannot preview<br><a href="${escapeHtml(g)}" download>Download</a></div>`,r.textContent=m.extension||"binary"}else{this.filePreviewContent=m.content,a.innerHTML=`<pre><code>${escapeHtml(m.content)}</code></pre>`;const g=m.truncated?` (showing 500/${m.totalLines} lines)`:"";if(r.textContent=`${m.totalLines} lines \u2022 ${this.formatFileSize(m.size)}${g}`,m.editable){this.filePreviewEditTarget={sessionId:t,filePath:e};const y=this.$("filePreviewEditBtn");y&&(y.hidden=!1)}}}catch(d){console.error("Failed to preview file:",d),a.innerHTML=`<div class="binary-message">Error: ${escapeHtml(d.message)}</div>`}},closeFilePreview(){if(this.filePreviewEdit?.dirty&&!confirm("Discard unsaved changes?"))return;this._resetFilePreviewEdit();const e=this.$("filePreviewOverlay");e&&e.classList.remove("visible"),this._stopFilePreviewMedia(),this.filePreviewContent="",this.filePreviewDetachUrl="";const t=this.$("filePreviewDetachBtn");t&&(t.hidden=!0)},detachFilePreview(){if(!this.filePreviewDetachUrl)return;const e=window.open(this.filePreviewDetachUrl,"_blank");if(!e){this.showToast("Pop-up blocked: allow pop-ups for this site to detach previews","error");return}e.opener=null,this.closeFilePreview()},_stopFilePreviewMedia(){const e=this.$("filePreviewBody");if(e){for(const t of e.querySelectorAll("video, audio"))try{t.pause(),t.removeAttribute("src"),t.load()}catch(s){console.warn("Failed to stop preview media:",s)}e.innerHTML=""}},_resetFilePreviewEdit(){this.filePreviewEdit=null,this.filePreviewEditTarget=null;const e=this.$("filePreviewEditBtn");e&&(e.hidden=!0);const t=this.$("filePreviewEditBar");t&&(t.hidden=!0);const s=this.$("filePreviewDirty");s&&(s.hidden=!0);const n=this.$("filePreviewSaveBtn");n&&(n.disabled=!0,n.textContent="Save")},async enterFilePreviewEdit(){const e=this.filePreviewEditTarget;if(!e||this.filePreviewEdit)return;const t=this.$("filePreviewBody"),s=this.$("filePreviewFooter");if(!t)return;let n;try{const o=await fetch(`/api/sessions/${e.sessionId}/file-content?path=${encodeURIComponent(e.filePath)}&edit=1`),l=await o.json().catch(()=>null);if(!l||l.success!==!0)throw new Error(l?.error||`Failed to load file for editing (HTTP ${o.status})`);n=l.data}catch(o){this.showToast(o.message,"error");return}this.filePreviewEdit={sessionId:e.sessionId,filePath:e.filePath,baseHash:n.hash,eol:n.eol,original:n.content,dirty:!1,saving:!1};const i=document.createElement("textarea");i.className="file-preview-editor",i.spellcheck=!1,i.setAttribute("autocapitalize","off"),i.setAttribute("autocorrect","off"),i.setAttribute("autocomplete","off"),i.wrap="off",i.value=n.content,i.addEventListener("input",()=>this._onFilePreviewEditInput()),t.innerHTML="",t.appendChild(i);const a=this.$("filePreviewEditBtn");a&&(a.hidden=!0);const r=this.$("filePreviewEditBar");if(r&&(r.hidden=!1),s){const o=n.eol==="crlf"?" \u2022 CRLF":"";s.textContent=`Editing \u2022 ${n.totalLines} lines \u2022 ${this.formatFileSize(n.size)}${o}`}},_onFilePreviewEditInput(){const e=this.filePreviewEdit;if(!e)return;const t=this.$("filePreviewBody")?.querySelector("textarea.file-preview-editor");if(!t)return;e.dirty=t.value!==e.original;const s=this.$("filePreviewDirty");s&&(s.hidden=!e.dirty);const n=this.$("filePreviewSaveBtn");n&&(n.disabled=!e.dirty||e.saving)},cancelFilePreviewEdit(){const e=this.filePreviewEdit;if(!e||e.dirty&&!confirm("Discard unsaved changes?"))return;const{sessionId:t,filePath:s}=e;this._resetFilePreviewEdit(),this.openFilePreview(s,t)},async saveFilePreviewEdit(e=!1){const t=this.filePreviewEdit;if(!t||t.saving)return;const s=this.$("filePreviewBody")?.querySelector("textarea.file-preview-editor");if(!s)return;t.saving=!0;const n=this.$("filePreviewSaveBtn");n&&(n.disabled=!0,n.textContent="Saving\u2026");const i=()=>{t.saving=!1,n&&(n.textContent="Save"),this._onFilePreviewEditInput()};let a=null,r=0;try{const c=await fetch(`/api/sessions/${t.sessionId}/file-content`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({path:t.filePath,content:s.value,baseHash:t.baseHash,eol:t.eol??void 0,force:e||void 0})});r=c.status,a=await c.json().catch(()=>null)}catch(c){i(),this.showToast(`Save failed: ${c.message}`,"error");return}if(r===409||a?.errorCode==="CONFLICT"){i(),confirm(`File changed on disk since you loaded it.
|
|
242
|
+
OK overwrites it with your version; Cancel keeps your draft open.`)&&this.saveFilePreviewEdit(!0);return}if(!a||a.success!==!0){i(),this.showToast(`Save failed: ${a?.error||`HTTP ${r}`}`,"error");return}const{sessionId:o,filePath:l}=t;this._resetFilePreviewEdit(),this.showToast("Saved","success"),this.openFilePreview(l,o)},_onAttachmentDetected(e){if(console.log("[Attachment Detected]",e),this.addAttachmentCard(e),e.sessionId){const t=this.attachmentHistoryCounts.get(e.sessionId)??this.sessions.get(e.sessionId)?.attachmentHistory?.length??0;this.attachmentHistoryCounts.set(e.sessionId,Math.min(t+1,100)),e.sessionId===this.activeSessionId&&(this.updateAttachmentHistoryBadge(),this.attachmentHistoryDrawerOpen&&this._debouncedCall("attachmentHistoryRefresh",()=>{this.attachmentHistoryDrawerOpen&&this.activeSessionId===e.sessionId&&this.loadAttachmentHistory(e.sessionId)},250))}},ensureAttachmentCardStack(){let e=this.attachmentCardStack||document.getElementById("attachmentCardStack");return e||(e=document.createElement("div"),e.id="attachmentCardStack",e.className="attachment-card-stack",document.body.appendChild(e)),this.attachmentCardStack=e,e},openAttachmentInNewTab(e,t,s=null){const n=CodemanBase.url(s?`/api/sessions/${e}/attachments/${encodeURIComponent(s)}/raw`:`/api/sessions/${e}/file-raw?path=${encodeURIComponent(t)}`);window.open(n,"_blank")},addAttachmentCard(e){const{sessionId:t,relativePath:s,fileName:n,timestamp:i,size:a,attachmentType:r,extension:o,attachmentId:l,rawUrl:c,previewUrl:h,thumbnailUrl:u}=e,d=s||n,p=l||`${t}-${i}-${n}`;if(this.attachmentCards.has(p)){this.attachmentCards.get(p).element.focus?.();return}if(this.attachmentCards.size>=10){const D=this.attachmentCards.keys().next().value;D&&this.closeAttachmentCard(D)}const g=this.ensureAttachmentCardStack(),w=this.sessions.get(t)?.name||t.substring(0,8),b=CodemanBase.url(c||(l?`/api/sessions/${t}/attachments/${encodeURIComponent(l)}/raw`:`/api/sessions/${t}/file-raw?path=${encodeURIComponent(d)}`)),$=CodemanBase.url(h||(l?`/api/sessions/${t}/attachments/${encodeURIComponent(l)}/preview`:null)),f=CodemanBase.url(u||(l?`/api/sessions/${t}/attachments/${encodeURIComponent(l)}/thumbnail`:`/api/sessions/${t}/file-thumbnail?path=${encodeURIComponent(d)}`)),S=l?`${b}?download=true`:`${b}&download=true`,T=(o||r||"file").toUpperCase(),v=document.createElement("article");v.className=`attachment-card attachment-${escapeHtml(r||"file")}`,v.tabIndex=0,v.dataset.attachmentId=p,v.dataset.previewUrl=$||"",v.innerHTML=`
|
|
243
243
|
<div class="attachment-thumbnail">
|
|
244
244
|
${f?`<img class="attachment-thumbnail-img" src="${escapeHtml(f)}" alt="">`:""}
|
|
245
245
|
<div class="attachment-thumbnail-fallback ${f?"":"visible"}">${escapeHtml(T)}</div>
|
|
@@ -276,7 +276,7 @@ OK overwrites it with your version; Cancel keeps your draft open.`)&&this.saveFi
|
|
|
276
276
|
<code>codeman attach /absolute/path/to/file.pptx</code>
|
|
277
277
|
<div>Supports .pptx, .docx, .pdf, .png, .md, and .txt.</div>
|
|
278
278
|
</div>
|
|
279
|
-
`;return}s.innerHTML=e.map(i=>this.renderAttachmentHistoryItem(i)).join(""),s.querySelectorAll(".attachment-history-thumb-img").forEach(i=>{i.onerror=()=>{i.remove(),i.closest(".attachment-history-thumb")?.querySelector(".attachment-history-thumb-fallback")?.classList.add("visible")}}),s.querySelectorAll("[data-attachment-action]").forEach(i=>{i.addEventListener("click",()=>{const a=i.getAttribute("data-history-id"),r=i.getAttribute("data-attachment-action");!a||!r||(r==="preview"&&this.previewAttachmentHistoryItem(a),r==="download"&&this.downloadAttachmentHistoryItem(a),r==="open"&&this.openAttachmentHistoryItem(a),r==="reshow"&&this.reshowAttachmentCard(a))})})}},renderAttachmentHistoryItem(e){const t=(e.extension||e.attachmentType||"file").toUpperCase(),s=[e.source==="external"?"published":"workspace",this.formatFileSize(e.size||0),e.missing?"missing":""].filter(Boolean).join(" \u2022 "),n=e.thumbnailUrl&&!e.missing?`<img class="attachment-history-thumb-img" src="${escapeHtml(e.thumbnailUrl)}" alt="">`:"",i=e.missing?'disabled aria-disabled="true"':"";return`
|
|
279
|
+
`;return}s.innerHTML=e.map(i=>this.renderAttachmentHistoryItem(i)).join(""),s.querySelectorAll(".attachment-history-thumb-img").forEach(i=>{i.onerror=()=>{i.remove(),i.closest(".attachment-history-thumb")?.querySelector(".attachment-history-thumb-fallback")?.classList.add("visible")}}),s.querySelectorAll("[data-attachment-action]").forEach(i=>{i.addEventListener("click",()=>{const a=i.getAttribute("data-history-id"),r=i.getAttribute("data-attachment-action");!a||!r||(r==="preview"&&this.previewAttachmentHistoryItem(a),r==="download"&&this.downloadAttachmentHistoryItem(a),r==="open"&&this.openAttachmentHistoryItem(a),r==="reshow"&&this.reshowAttachmentCard(a))})})}},renderAttachmentHistoryItem(e){const t=(e.extension||e.attachmentType||"file").toUpperCase(),s=[e.source==="external"?"published":"workspace",this.formatFileSize(e.size||0),e.missing?"missing":""].filter(Boolean).join(" \u2022 "),n=e.thumbnailUrl&&!e.missing?`<img class="attachment-history-thumb-img" src="${escapeHtml(CodemanBase.url(e.thumbnailUrl))}" alt="">`:"",i=e.missing?'disabled aria-disabled="true"':"";return`
|
|
280
280
|
<div class="attachment-history-item ${e.missing?"missing":""}" data-history-item="${escapeHtml(e.id)}">
|
|
281
281
|
<div class="attachment-history-thumb">
|
|
282
282
|
${n}
|
|
@@ -293,7 +293,7 @@ OK overwrites it with your version; Cancel keeps your draft open.`)&&this.saveFi
|
|
|
293
293
|
</div>
|
|
294
294
|
</div>
|
|
295
295
|
</div>
|
|
296
|
-
`},getAttachmentHistoryItem(e){return(this.attachmentHistoryItems||[]).find(t=>t.id===e)||null},previewAttachmentHistoryItem(e){const t=this.getAttachmentHistoryItem(e);if(!t||t.missing)return;const s=t.relativePath||t.fileName;this.openFilePreview(s,t.sessionId,t.attachmentId||null),this.closeAttachmentHistory()},openAttachmentHistoryItem(e){const t=this.getAttachmentHistoryItem(e);if(!(!t||t.missing)){if(t.rawUrl||t.url){window.open(t.rawUrl||t.url,"_blank");return}this.openAttachmentInNewTab(t.sessionId,t.relativePath||t.fileName,t.attachmentId||null)}},downloadAttachmentHistoryItem(e){const t=this.getAttachmentHistoryItem(e);!t||t.missing||!t.downloadUrl||window.open(t.downloadUrl,"_blank")},reshowAttachmentCard(e){const t=this.getAttachmentHistoryItem(e);!t||t.missing||this.addAttachmentCard({sessionId:t.sessionId,relativePath:t.relativePath,fileName:t.fileName,timestamp:t.timestamp??Date.now(),size:t.size,attachmentType:t.attachmentType,extension:t.extension,attachmentId:t.attachmentId,rawUrl:t.rawUrl,previewUrl:t.previewUrl,thumbnailUrl:t.thumbnailUrl})},copyFilePreviewContent(){const e=this.filePreviewEdit?this.$("filePreviewBody")?.querySelector("textarea.file-preview-editor"):null,t=e?e.value:this.filePreviewContent;t?navigator.clipboard.writeText(t).then(()=>{this.showToast("Copied to clipboard","success")}).catch(()=>{this.showToast("Failed to copy","error")}):this.showToast("Nothing to copy in this preview","info")},getFileIcon(e){return e&&{ts:"\u{1F4D8}",tsx:"\u{1F4D8}",js:"\u{1F4D2}",jsx:"\u{1F4D2}",mjs:"\u{1F4D2}",cjs:"\u{1F4D2}",py:"\u{1F40D}",pyx:"\u{1F40D}",pyw:"\u{1F40D}",rs:"\u{1F980}",go:"\u{1F439}",c:"\u2699\uFE0F",cpp:"\u2699\uFE0F",h:"\u2699\uFE0F",hpp:"\u2699\uFE0F",html:"\u{1F310}",htm:"\u{1F310}",css:"\u{1F3A8}",scss:"\u{1F3A8}",sass:"\u{1F3A8}",less:"\u{1F3A8}",json:"\u{1F4CB}",yaml:"\u{1F4CB}",yml:"\u{1F4CB}",xml:"\u{1F4CB}",toml:"\u{1F4CB}",csv:"\u{1F4CB}",md:"\u{1F4DD}",markdown:"\u{1F4DD}",txt:"\u{1F4DD}",rst:"\u{1F4DD}",png:"\u{1F5BC}\uFE0F",jpg:"\u{1F5BC}\uFE0F",jpeg:"\u{1F5BC}\uFE0F",gif:"\u{1F5BC}\uFE0F",svg:"\u{1F5BC}\uFE0F",webp:"\u{1F5BC}\uFE0F",ico:"\u{1F5BC}\uFE0F",bmp:"\u{1F5BC}\uFE0F",mp4:"\u{1F3AC}",webm:"\u{1F3AC}",mov:"\u{1F3AC}",mp3:"\u{1F3B5}",wav:"\u{1F3B5}",ogg:"\u{1F3B5}",sh:"\u{1F4BB}",bash:"\u{1F4BB}",zsh:"\u{1F4BB}",env:"\u{1F510}",gitignore:"\u{1F6AB}",dockerfile:"\u{1F433}",lock:"\u{1F512}"}[e.toLowerCase()]||"\u{1F4C4}"},formatFileSize(e){return e==null?"":e<1024?`${e} B`:e<1024*1024?`${(e/1024).toFixed(1)} KB`:e<1024*1024*1024?`${(e/(1024*1024)).toFixed(1)} MB`:`${(e/(1024*1024*1024)).toFixed(1)} GB`},openLogViewerWindow(e,t){if(t=t||this.activeSessionId,!t)return;const s=`${t}-${e.replace(/[^a-zA-Z0-9]/g,"_")}`;if(this.logViewerWindows.has(s)){const h=this.logViewerWindows.get(s);h.element.style.zIndex=++this.logViewerWindowZIndex;return}const n=this.logViewerWindows.size,i=100+n%5*30,a=100+n%5*30,r=e.split("/").pop(),o=document.createElement("div");o.className="log-viewer-window",o.id=`log-viewer-window-${s}`,o.style.left=`${i}px`,o.style.top=`${a}px`,o.style.zIndex=++this.logViewerWindowZIndex,o.innerHTML=`
|
|
296
|
+
`},getAttachmentHistoryItem(e){return(this.attachmentHistoryItems||[]).find(t=>t.id===e)||null},previewAttachmentHistoryItem(e){const t=this.getAttachmentHistoryItem(e);if(!t||t.missing)return;const s=t.relativePath||t.fileName;this.openFilePreview(s,t.sessionId,t.attachmentId||null),this.closeAttachmentHistory()},openAttachmentHistoryItem(e){const t=this.getAttachmentHistoryItem(e);if(!(!t||t.missing)){if(t.rawUrl||t.url){window.open(CodemanBase.url(t.rawUrl||t.url),"_blank");return}this.openAttachmentInNewTab(t.sessionId,t.relativePath||t.fileName,t.attachmentId||null)}},downloadAttachmentHistoryItem(e){const t=this.getAttachmentHistoryItem(e);!t||t.missing||!t.downloadUrl||window.open(CodemanBase.url(t.downloadUrl),"_blank")},reshowAttachmentCard(e){const t=this.getAttachmentHistoryItem(e);!t||t.missing||this.addAttachmentCard({sessionId:t.sessionId,relativePath:t.relativePath,fileName:t.fileName,timestamp:t.timestamp??Date.now(),size:t.size,attachmentType:t.attachmentType,extension:t.extension,attachmentId:t.attachmentId,rawUrl:t.rawUrl,previewUrl:t.previewUrl,thumbnailUrl:t.thumbnailUrl})},copyFilePreviewContent(){const e=this.filePreviewEdit?this.$("filePreviewBody")?.querySelector("textarea.file-preview-editor"):null,t=e?e.value:this.filePreviewContent;t?navigator.clipboard.writeText(t).then(()=>{this.showToast("Copied to clipboard","success")}).catch(()=>{this.showToast("Failed to copy","error")}):this.showToast("Nothing to copy in this preview","info")},getFileIcon(e){return e&&{ts:"\u{1F4D8}",tsx:"\u{1F4D8}",js:"\u{1F4D2}",jsx:"\u{1F4D2}",mjs:"\u{1F4D2}",cjs:"\u{1F4D2}",py:"\u{1F40D}",pyx:"\u{1F40D}",pyw:"\u{1F40D}",rs:"\u{1F980}",go:"\u{1F439}",c:"\u2699\uFE0F",cpp:"\u2699\uFE0F",h:"\u2699\uFE0F",hpp:"\u2699\uFE0F",html:"\u{1F310}",htm:"\u{1F310}",css:"\u{1F3A8}",scss:"\u{1F3A8}",sass:"\u{1F3A8}",less:"\u{1F3A8}",json:"\u{1F4CB}",yaml:"\u{1F4CB}",yml:"\u{1F4CB}",xml:"\u{1F4CB}",toml:"\u{1F4CB}",csv:"\u{1F4CB}",md:"\u{1F4DD}",markdown:"\u{1F4DD}",txt:"\u{1F4DD}",rst:"\u{1F4DD}",png:"\u{1F5BC}\uFE0F",jpg:"\u{1F5BC}\uFE0F",jpeg:"\u{1F5BC}\uFE0F",gif:"\u{1F5BC}\uFE0F",svg:"\u{1F5BC}\uFE0F",webp:"\u{1F5BC}\uFE0F",ico:"\u{1F5BC}\uFE0F",bmp:"\u{1F5BC}\uFE0F",mp4:"\u{1F3AC}",webm:"\u{1F3AC}",mov:"\u{1F3AC}",mp3:"\u{1F3B5}",wav:"\u{1F3B5}",ogg:"\u{1F3B5}",sh:"\u{1F4BB}",bash:"\u{1F4BB}",zsh:"\u{1F4BB}",env:"\u{1F510}",gitignore:"\u{1F6AB}",dockerfile:"\u{1F433}",lock:"\u{1F512}"}[e.toLowerCase()]||"\u{1F4C4}"},formatFileSize(e){return e==null?"":e<1024?`${e} B`:e<1024*1024?`${(e/1024).toFixed(1)} KB`:e<1024*1024*1024?`${(e/(1024*1024)).toFixed(1)} MB`:`${(e/(1024*1024*1024)).toFixed(1)} GB`},openLogViewerWindow(e,t){if(t=t||this.activeSessionId,!t)return;const s=`${t}-${e.replace(/[^a-zA-Z0-9]/g,"_")}`;if(this.logViewerWindows.has(s)){const h=this.logViewerWindows.get(s);h.element.style.zIndex=++this.logViewerWindowZIndex;return}const n=this.logViewerWindows.size,i=100+n%5*30,a=100+n%5*30,r=e.split("/").pop(),o=document.createElement("div");o.className="log-viewer-window",o.id=`log-viewer-window-${s}`,o.style.left=`${i}px`,o.style.top=`${a}px`,o.style.zIndex=++this.logViewerWindowZIndex,o.innerHTML=`
|
|
297
297
|
<div class="log-viewer-window-header">
|
|
298
298
|
<div class="log-viewer-window-title" title="${escapeHtml(e)}">
|
|
299
299
|
<span class="icon">\u{1F4C4}</span>
|
|
@@ -307,7 +307,7 @@ OK overwrites it with your version; Cancel keeps your draft open.`)&&this.saveFi
|
|
|
307
307
|
<div class="log-viewer-window-body" id="log-viewer-body-${s}">
|
|
308
308
|
<div class="log-info">Connecting to ${escapeHtml(e)}...</div>
|
|
309
309
|
</div>
|
|
310
|
-
`,document.body.appendChild(o);const l=this.makeWindowDraggable(o,o.querySelector(".log-viewer-window-header")),c=new EventSource(`/api/sessions/${t}/tail-file?path=${encodeURIComponent(e)}&lines=50`);c.onmessage=h=>{const u=JSON.parse(h.data),d=document.getElementById(`log-viewer-body-${s}`);if(d)switch(u.type){case"connected":d.innerHTML="";break;case"data":const p=d.scrollTop+d.clientHeight>=d.scrollHeight-10,m=escapeHtml(u.content);d.innerHTML+=m,p&&(d.scrollTop=d.scrollHeight),d.innerHTML.length>5e5&&(d.innerHTML=d.innerHTML.slice(-4e5));break;case"end":this.updateLogViewerStatus(s,"disconnected","ended");break;case"error":d.innerHTML+=`<div class="log-error">${escapeHtml(u.error)}</div>`,this.updateLogViewerStatus(s,"error","error");break}},c.onerror=()=>{this.updateLogViewerStatus(s,"disconnected","connection error")},this.logViewerWindows.set(s,{element:o,eventSource:c,filePath:e,sessionId:t,dragListeners:l})},updateLogViewerStatus(e,t,s){const n=document.querySelector(`#log-viewer-window-${e} .status`);n&&(n.className=`status ${t}`,n.textContent=s)},closeLogViewerWindow(e){const t=this.logViewerWindows.get(e);t&&(t.eventSource&&t.eventSource.close(),t.dragListeners&&(document.removeEventListener("mousemove",t.dragListeners.move),document.removeEventListener("mouseup",t.dragListeners.up),t.dragListeners.handle&&(t.dragListeners.handle.removeEventListener("mousedown",t.dragListeners.handleMouseDown),t.dragListeners.handle.removeEventListener("touchstart",t.dragListeners.handleTouchStart))),t.element.remove(),this.logViewerWindows.delete(e))},closeSessionLogViewerWindows(e){const t=[];for(const[s,n]of this.logViewerWindows)n.sessionId===e&&t.push(s);for(const s of t)this.closeLogViewerWindow(s)},openImagePopup(e){const{sessionId:t,filePath:s,relativePath:n,fileName:i,timestamp:a,size:r}=e,o=`${t}-${a}`;if(this.imagePopups.has(o)){const f=this.imagePopups.get(o);f.element.style.zIndex=++this.imagePopupZIndex;return}if(this.imagePopups.size>=20){const f=this.imagePopups.keys().next().value;f&&this.closeImagePopup(f)}const c=this.imagePopups.size,h=(window.innerWidth-600)/2,u=(window.innerHeight-500)/2,d=h+c%5*30,p=u+c%5*30,g=this.sessions.get(t)?.name||t.substring(0,8),y=(r/1024).toFixed(1),w
|
|
310
|
+
`,document.body.appendChild(o);const l=this.makeWindowDraggable(o,o.querySelector(".log-viewer-window-header")),c=new EventSource(CodemanBase.url(`/api/sessions/${t}/tail-file?path=${encodeURIComponent(e)}&lines=50`));c.onmessage=h=>{const u=JSON.parse(h.data),d=document.getElementById(`log-viewer-body-${s}`);if(d)switch(u.type){case"connected":d.innerHTML="";break;case"data":const p=d.scrollTop+d.clientHeight>=d.scrollHeight-10,m=escapeHtml(u.content);d.innerHTML+=m,p&&(d.scrollTop=d.scrollHeight),d.innerHTML.length>5e5&&(d.innerHTML=d.innerHTML.slice(-4e5));break;case"end":this.updateLogViewerStatus(s,"disconnected","ended");break;case"error":d.innerHTML+=`<div class="log-error">${escapeHtml(u.error)}</div>`,this.updateLogViewerStatus(s,"error","error");break}},c.onerror=()=>{this.updateLogViewerStatus(s,"disconnected","connection error")},this.logViewerWindows.set(s,{element:o,eventSource:c,filePath:e,sessionId:t,dragListeners:l})},updateLogViewerStatus(e,t,s){const n=document.querySelector(`#log-viewer-window-${e} .status`);n&&(n.className=`status ${t}`,n.textContent=s)},closeLogViewerWindow(e){const t=this.logViewerWindows.get(e);t&&(t.eventSource&&t.eventSource.close(),t.dragListeners&&(document.removeEventListener("mousemove",t.dragListeners.move),document.removeEventListener("mouseup",t.dragListeners.up),t.dragListeners.handle&&(t.dragListeners.handle.removeEventListener("mousedown",t.dragListeners.handleMouseDown),t.dragListeners.handle.removeEventListener("touchstart",t.dragListeners.handleTouchStart))),t.element.remove(),this.logViewerWindows.delete(e))},closeSessionLogViewerWindows(e){const t=[];for(const[s,n]of this.logViewerWindows)n.sessionId===e&&t.push(s);for(const s of t)this.closeLogViewerWindow(s)},openImagePopup(e){const{sessionId:t,filePath:s,relativePath:n,fileName:i,timestamp:a,size:r}=e,o=`${t}-${a}`;if(this.imagePopups.has(o)){const f=this.imagePopups.get(o);f.element.style.zIndex=++this.imagePopupZIndex;return}if(this.imagePopups.size>=20){const f=this.imagePopups.keys().next().value;f&&this.closeImagePopup(f)}const c=this.imagePopups.size,h=(window.innerWidth-600)/2,u=(window.innerHeight-500)/2,d=h+c%5*30,p=u+c%5*30,g=this.sessions.get(t)?.name||t.substring(0,8),y=(r/1024).toFixed(1),w=CodemanBase.url(`/api/sessions/${t}/file-raw?path=${encodeURIComponent(n||i)}`),b=document.createElement("div");b.className="image-popup-window",b.id=`image-popup-${o}`,b.style.left=`${d}px`,b.style.top=`${p}px`,b.style.zIndex=++this.imagePopupZIndex,b.innerHTML=`
|
|
311
311
|
<div class="image-popup-header">
|
|
312
312
|
<div class="image-popup-title" title="${escapeHtml(s)}">
|
|
313
313
|
<span class="icon">\u{1F5BC}\uFE0F</span>
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|