aicodeman 1.47.0 → 1.48.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -0
- package/dist/cli-notify.d.ts +34 -0
- package/dist/cli-notify.d.ts.map +1 -0
- package/dist/cli-notify.js +100 -0
- package/dist/cli-notify.js.map +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +16 -0
- package/dist/cli.js.map +1 -1
- package/dist/config/cli-registry/patterns.d.ts +1 -1
- package/dist/config/cli-registry/patterns.d.ts.map +1 -1
- package/dist/config/cli-registry/patterns.js +4 -0
- package/dist/config/cli-registry/patterns.js.map +1 -1
- package/dist/config/cli-registry/schema.d.ts +6 -0
- package/dist/config/cli-registry/schema.d.ts.map +1 -1
- package/dist/config/cli-registry/schema.js +62 -2
- 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 +43 -26
- package/dist/config/cli-registry/stock.js.map +1 -1
- package/dist/config/cli-registry/types.d.ts +47 -17
- package/dist/config/cli-registry/types.d.ts.map +1 -1
- package/dist/config/path-probe.d.ts +6 -0
- package/dist/config/path-probe.d.ts.map +1 -1
- package/dist/config/path-probe.js +6 -0
- package/dist/config/path-probe.js.map +1 -1
- package/dist/config-backup.d.ts +1 -1
- package/dist/config-backup.d.ts.map +1 -1
- package/dist/config-backup.js +2 -0
- package/dist/config-backup.js.map +1 -1
- package/dist/custom-model-hosts.d.ts +32 -8
- package/dist/custom-model-hosts.d.ts.map +1 -1
- package/dist/custom-model-hosts.js +10 -0
- package/dist/custom-model-hosts.js.map +1 -1
- package/dist/custom-model-injection-apply.d.ts +19 -5
- package/dist/custom-model-injection-apply.d.ts.map +1 -1
- package/dist/custom-model-injection-apply.js +88 -8
- package/dist/custom-model-injection-apply.js.map +1 -1
- package/dist/custom-model-injection.d.ts +6 -0
- package/dist/custom-model-injection.d.ts.map +1 -1
- package/dist/custom-model-injection.js +92 -10
- package/dist/custom-model-injection.js.map +1 -1
- package/dist/discord-bridge.d.ts +338 -0
- package/dist/discord-bridge.d.ts.map +1 -0
- package/dist/discord-bridge.js +1256 -0
- package/dist/discord-bridge.js.map +1 -0
- package/dist/edit-history-local-source.d.ts +83 -0
- package/dist/edit-history-local-source.d.ts.map +1 -0
- package/dist/edit-history-local-source.js +198 -0
- package/dist/edit-history-local-source.js.map +1 -0
- package/dist/edit-history-parse.d.ts +114 -0
- package/dist/edit-history-parse.d.ts.map +1 -0
- package/dist/edit-history-parse.js +312 -0
- package/dist/edit-history-parse.js.map +1 -0
- package/dist/edit-history-store.d.ts +209 -0
- package/dist/edit-history-store.d.ts.map +1 -0
- package/dist/edit-history-store.js +599 -0
- package/dist/edit-history-store.js.map +1 -0
- package/dist/git-clone.d.ts +6 -1
- package/dist/git-clone.d.ts.map +1 -1
- package/dist/git-clone.js +79 -14
- package/dist/git-clone.js.map +1 -1
- package/dist/image-watcher.js +4 -4
- package/dist/image-watcher.js.map +1 -1
- package/dist/mux-interface.d.ts +10 -1
- package/dist/mux-interface.d.ts.map +1 -1
- package/dist/session-cli-registry-bridge.d.ts.map +1 -1
- package/dist/session-cli-registry-bridge.js +4 -0
- package/dist/session-cli-registry-bridge.js.map +1 -1
- package/dist/session.d.ts +70 -3
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +147 -4
- package/dist/session.js.map +1 -1
- package/dist/tmux-manager.d.ts +40 -0
- package/dist/tmux-manager.d.ts.map +1 -1
- package/dist/tmux-manager.js +62 -0
- package/dist/tmux-manager.js.map +1 -1
- package/dist/types/discord.d.ts +55 -0
- package/dist/types/discord.d.ts.map +1 -0
- package/dist/types/discord.js +18 -0
- package/dist/types/discord.js.map +1 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -1
- package/dist/types/session.d.ts +13 -0
- package/dist/types/session.d.ts.map +1 -1
- package/dist/types/session.js.map +1 -1
- package/dist/web/case-path.d.ts +2 -0
- package/dist/web/case-path.d.ts.map +1 -1
- package/dist/web/case-path.js +3 -3
- package/dist/web/case-path.js.map +1 -1
- package/dist/web/edit-history-sync.d.ts +158 -0
- package/dist/web/edit-history-sync.d.ts.map +1 -0
- package/dist/web/edit-history-sync.js +445 -0
- package/dist/web/edit-history-sync.js.map +1 -0
- package/dist/web/paste-image-gc.d.ts +6 -0
- package/dist/web/paste-image-gc.d.ts.map +1 -1
- package/dist/web/paste-image-gc.js +6 -0
- package/dist/web/paste-image-gc.js.map +1 -1
- package/dist/web/ports/session-port.d.ts +13 -0
- package/dist/web/ports/session-port.d.ts.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.fe8a6b4c.js → app.963b5ba8.js} +6 -6
- package/dist/web/public/app.963b5ba8.js.br +0 -0
- package/dist/web/public/app.963b5ba8.js.gz +0 -0
- package/dist/web/public/approvals-ui.js.gz +0 -0
- package/dist/web/public/{constants.affcdde6.js → constants.782170e1.js} +114 -25
- package/dist/web/public/constants.782170e1.js.br +0 -0
- package/dist/web/public/constants.782170e1.js.gz +0 -0
- package/dist/web/public/cron-ui.js.gz +0 -0
- package/dist/web/public/edit-history-ui.js +630 -0
- package/dist/web/public/edit-history-ui.js.br +0 -0
- package/dist/web/public/edit-history-ui.js.gz +0 -0
- package/dist/web/public/entrance-animations.js.gz +0 -0
- package/dist/web/public/git-status-ui.js.gz +0 -0
- package/dist/web/public/header-divider.eb2d2463.js.gz +0 -0
- package/dist/web/public/home-sessions.js.gz +0 -0
- package/dist/web/public/host-wake-ui.js.gz +0 -0
- package/dist/web/public/i18n.33f930d7.js +2 -0
- package/dist/web/public/i18n.33f930d7.js.br +0 -0
- package/dist/web/public/i18n.33f930d7.js.gz +0 -0
- package/dist/web/public/image-input.a5d0f8f3.js.gz +0 -0
- package/dist/web/public/index.html +160 -14
- package/dist/web/public/index.html.br +0 -0
- package/dist/web/public/index.html.gz +0 -0
- package/dist/web/public/input-cjk.8bc46081.js.gz +0 -0
- package/dist/web/public/{keyboard-accessory.ff64fafc.js → keyboard-accessory.d4ec5957.js} +72 -1
- package/dist/web/public/keyboard-accessory.d4ec5957.js.br +0 -0
- package/dist/web/public/keyboard-accessory.d4ec5957.js.gz +0 -0
- package/dist/web/public/mobile-handlers.f7c3f692.js.gz +0 -0
- package/dist/web/public/mobile-ime-preview.2dbaf262.js.gz +0 -0
- package/dist/web/public/mobile-overview.js.gz +0 -0
- package/dist/web/public/mobile.5ef2ce85.css +1 -0
- package/dist/web/public/mobile.5ef2ce85.css.br +0 -0
- package/dist/web/public/mobile.5ef2ce85.css.gz +0 -0
- package/dist/web/public/notification-manager.feb82c04.js.gz +0 -0
- package/dist/web/public/orchestrator-panel.js.gz +0 -0
- package/dist/web/public/{panels-ui.4a56ee63.js → panels-ui.b100727d.js} +2 -2
- package/dist/web/public/panels-ui.b100727d.js.br +0 -0
- package/dist/web/public/{panels-ui.4a56ee63.js.gz → panels-ui.b100727d.js.gz} +0 -0
- package/dist/web/public/ralph-panel.b350e2ef.js.gz +0 -0
- package/dist/web/public/ralph-wizard.b6c0dd19.js.gz +0 -0
- package/dist/web/public/readmymind-ui.js.gz +0 -0
- package/dist/web/public/reboot-restore-ui.js.gz +0 -0
- package/dist/web/public/{respawn-ui.d7adcf6a.js → respawn-ui.304ba0d4.js} +1 -1
- package/dist/web/public/respawn-ui.304ba0d4.js.br +0 -0
- package/dist/web/public/respawn-ui.304ba0d4.js.gz +0 -0
- package/dist/web/public/sanitize-html.e7147e76.js.gz +0 -0
- package/dist/web/public/security-notices.json +1 -21
- package/dist/web/public/session-lineage.js.gz +0 -0
- package/dist/web/public/{session-ui.426fb671.js → session-ui.5ac82f2c.js} +30 -30
- package/dist/web/public/session-ui.5ac82f2c.js.br +0 -0
- package/dist/web/public/session-ui.5ac82f2c.js.gz +0 -0
- package/dist/web/public/settings-ui.d1d4fb99.js +106 -0
- package/dist/web/public/settings-ui.d1d4fb99.js.br +0 -0
- package/dist/web/public/settings-ui.d1d4fb99.js.gz +0 -0
- package/dist/web/public/spreadsheet-preview-worker.js.gz +0 -0
- package/dist/web/public/spreadsheet-preview.75c751de.js.gz +0 -0
- package/dist/web/public/spreadsheet-xlsx-core.js.gz +0 -0
- package/dist/web/public/styles.77dc538f.css +1 -0
- package/dist/web/public/styles.77dc538f.css.br +0 -0
- package/dist/web/public/styles.77dc538f.css.gz +0 -0
- package/dist/web/public/subagent-windows.07277a58.js.gz +0 -0
- package/dist/web/public/sw.js +2 -2
- package/dist/web/public/sw.js.br +0 -0
- package/dist/web/public/sw.js.gz +0 -0
- package/dist/web/public/tab-layout-browser.2d6189f7.js.gz +0 -0
- package/dist/web/public/tab-rail-resize.b5cdceaf.js.gz +0 -0
- package/dist/web/public/terminal-keycode229-recovery.98843069.js.gz +0 -0
- package/dist/web/public/terminal-split.js.gz +0 -0
- package/dist/web/public/terminal-tile.js.gz +0 -0
- package/dist/web/public/{terminal-ui.7e787829.js → terminal-ui.d7c75ce8.js} +3 -3
- package/dist/web/public/terminal-ui.d7c75ce8.js.br +0 -0
- package/dist/web/public/terminal-ui.d7c75ce8.js.gz +0 -0
- package/dist/web/public/tile-grid.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/vendor/dompurify.min.js.gz +0 -0
- package/dist/web/public/vendor/exceljs.min.js.gz +0 -0
- package/dist/web/public/vendor/fflate.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.276b11d9.js.gz +0 -0
- package/dist/web/public/vendor/xterm-zerolag-input.1be42307.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.2342c37b.js.gz +0 -0
- package/dist/web/public/voice-pcm-worklet.js.gz +0 -0
- package/dist/web/public/webview-tabs.js.gz +0 -0
- package/dist/web/public/whats-new.json +9 -8
- package/dist/web/routes/case-routes.d.ts.map +1 -1
- package/dist/web/routes/case-routes.js +104 -8
- package/dist/web/routes/case-routes.js.map +1 -1
- package/dist/web/routes/config-backup-routes.d.ts +5 -1
- package/dist/web/routes/config-backup-routes.d.ts.map +1 -1
- package/dist/web/routes/config-backup-routes.js +4 -1
- package/dist/web/routes/config-backup-routes.js.map +1 -1
- package/dist/web/routes/custom-model-routes.d.ts +7 -2
- package/dist/web/routes/custom-model-routes.d.ts.map +1 -1
- package/dist/web/routes/custom-model-routes.js +51 -6
- package/dist/web/routes/custom-model-routes.js.map +1 -1
- package/dist/web/routes/discord-routes.d.ts +25 -0
- package/dist/web/routes/discord-routes.d.ts.map +1 -0
- package/dist/web/routes/discord-routes.js +206 -0
- package/dist/web/routes/discord-routes.js.map +1 -0
- package/dist/web/routes/edit-history-routes.d.ts +43 -0
- package/dist/web/routes/edit-history-routes.d.ts.map +1 -0
- package/dist/web/routes/edit-history-routes.js +106 -0
- package/dist/web/routes/edit-history-routes.js.map +1 -0
- package/dist/web/routes/file-routes.d.ts.map +1 -1
- package/dist/web/routes/file-routes.js +62 -2
- package/dist/web/routes/file-routes.js.map +1 -1
- package/dist/web/routes/index.d.ts +2 -0
- package/dist/web/routes/index.d.ts.map +1 -1
- package/dist/web/routes/index.js +2 -0
- package/dist/web/routes/index.js.map +1 -1
- package/dist/web/routes/session-routes.d.ts +17 -0
- package/dist/web/routes/session-routes.d.ts.map +1 -1
- package/dist/web/routes/session-routes.js +87 -37
- package/dist/web/routes/session-routes.js.map +1 -1
- package/dist/web/routes/system-routes.d.ts.map +1 -1
- package/dist/web/routes/system-routes.js +1 -0
- package/dist/web/routes/system-routes.js.map +1 -1
- package/dist/web/schemas.d.ts +68 -1
- package/dist/web/schemas.d.ts.map +1 -1
- package/dist/web/schemas.js +77 -1
- package/dist/web/schemas.js.map +1 -1
- package/dist/web/sensitive-path.d.ts.map +1 -1
- package/dist/web/sensitive-path.js +15 -0
- package/dist/web/sensitive-path.js.map +1 -1
- package/dist/web/server.d.ts +43 -0
- package/dist/web/server.d.ts.map +1 -1
- package/dist/web/server.js +219 -11
- package/dist/web/server.js.map +1 -1
- package/package.json +1 -1
- package/dist/web/public/app.fe8a6b4c.js.br +0 -0
- package/dist/web/public/app.fe8a6b4c.js.gz +0 -0
- package/dist/web/public/constants.affcdde6.js.br +0 -0
- package/dist/web/public/constants.affcdde6.js.gz +0 -0
- package/dist/web/public/i18n.a618ef4e.js +0 -2
- package/dist/web/public/i18n.a618ef4e.js.br +0 -0
- package/dist/web/public/i18n.a618ef4e.js.gz +0 -0
- package/dist/web/public/keyboard-accessory.ff64fafc.js.br +0 -0
- package/dist/web/public/keyboard-accessory.ff64fafc.js.gz +0 -0
- package/dist/web/public/mobile.1bbd2d67.css +0 -1
- package/dist/web/public/mobile.1bbd2d67.css.br +0 -0
- package/dist/web/public/mobile.1bbd2d67.css.gz +0 -0
- package/dist/web/public/panels-ui.4a56ee63.js.br +0 -0
- package/dist/web/public/respawn-ui.d7adcf6a.js.br +0 -0
- package/dist/web/public/respawn-ui.d7adcf6a.js.gz +0 -0
- package/dist/web/public/session-ui.426fb671.js.br +0 -0
- package/dist/web/public/session-ui.426fb671.js.gz +0 -0
- package/dist/web/public/settings-ui.a191154e.js +0 -106
- package/dist/web/public/settings-ui.a191154e.js.br +0 -0
- package/dist/web/public/settings-ui.a191154e.js.gz +0 -0
- package/dist/web/public/styles.4f0c67a0.css +0 -1
- package/dist/web/public/styles.4f0c67a0.css.br +0 -0
- package/dist/web/public/styles.4f0c67a0.css.gz +0 -0
- package/dist/web/public/terminal-ui.7e787829.js.br +0 -0
- package/dist/web/public/terminal-ui.7e787829.js.gz +0 -0
|
@@ -242,9 +242,9 @@
|
|
|
242
242
|
${d}
|
|
243
243
|
${p}
|
|
244
244
|
</div>
|
|
245
|
-
`}).join("")}n.querySelectorAll(".file-tree-item").forEach(a=>{a.addEventListener("click",()=>{const r=a.dataset.path;a.dataset.type==="directory"?this._openFileBrowserSearchDirectory({...o,path:r}):this.openFilePreview(r,t)})});const l=this.$("fileBrowserStatus");if(l){const a=s.matchCount===void 0?e.length:s.matchCount;l.textContent=`${a} ${a===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!0;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,n={}){if(!t||!e)return;const i=n.folderFile||null;!i&&this.folderGrid&&(this.folderGrid.index=null),this._updateFolderPreviewNav(i?null:this._previewFolderPath(e,t,s));const o=this.$("filePreviewOverlay"),l=this.$("filePreviewTitle"),a=this.$("filePreviewBody"),r=this.$("filePreviewFooter");if(!o||!a)return;this._recordFilePreviewHistory(e,t,s,n),this._bindFilePreviewChrome();const c=this._filePreviewLoad=(this._filePreviewLoad||0)+1,h=()=>c!==this._filePreviewLoad;this._resetFilePreviewEdit(),this._stopFilePreviewMedia(),this.filePreviewDetachUrl="";const d=this.$("filePreviewDetachBtn");d&&(d.hidden=!0),this.filePreviewText=null,this.filePreviewPage=null,this.filePreviewPageRefused=!1,this._updateFilePreviewToolbar("none"),o.classList.add("visible"),this._applyFilePreviewExpanded(),l.textContent=e,a.innerHTML='<div class="binary-message">Loading...</div>',r.textContent="";const u=(e.split(".").pop()||"").toLowerCase();if(!s&&rendersAsPage(e)&&this._filePreviewPref("htmlRendered")){const g=await this._mintHtmlViewUrl(e,t);if(g){r.textContent="HTML",this.filePreviewPage={filePath:e,sessionId:t},this.filePreviewDetachUrl=g,d&&(d.hidden=!1),a.innerHTML=`<iframe src="${escapeHtml(g)}" title="${escapeHtml(e)}" sandbox="allow-scripts allow-forms allow-popups allow-modals allow-downloads"></iframe>`,this._updateFilePreviewToolbar("page");return}this.filePreviewPageRefused=!0}let p="",f=0;if(!s&&!i&&this._isExternalPreviewPath(e,t)){const g=await this._registerExternalPreview(e,t);if(h())return;s=g.attachmentId||null,p=g.error||"",f=g.size||0}if(!s&&p){r.textContent="",a.innerHTML=`<div class="binary-message">${escapeHtml(p)}</div>`;return}const w=u==="docx"||u==="pptx",y=s?`/api/sessions/${t}/attachments/${encodeURIComponent(s)}`:i?`/api/sessions/${t}/folders/${encodeURIComponent(i.folderId)}/files/${encodeURIComponent(i.name)}`:null;if(this.filePreviewDetachUrl=CodemanBase.url(y?`${y}/${w?"preview":"raw"}`:w?`/api/sessions/${t}/file-preview?path=${encodeURIComponent(e)}`:`/api/sessions/${t}/file-raw?path=${encodeURIComponent(e)}`),d&&(d.hidden=!1),y){const g=CodemanBase.url(y),C=new Set(["png","jpg","jpeg","gif","webp","bmp","svg"]),m=new Set(["mp4","webm","mov","m4v","ogv"]),S=new Set(["mp3","wav","ogg","oga","m4a","aac","flac","opus"]);if(i&&!f&&(f=n.size||0),r.textContent=f?`${this.formatFileSize(f)} \u2022 ${u}`:u.toUpperCase(),C.has(u))a.innerHTML=`<img src="${escapeHtml(`${g}/raw`)}" alt="${escapeHtml(e)}">`;else if(m.has(u))a.innerHTML=`<video src="${escapeHtml(`${g}/raw`)}" controls autoplay playsinline preload="metadata"></video>`;else if(S.has(u))a.innerHTML=`<audio src="${escapeHtml(`${g}/raw`)}" controls autoplay preload="metadata"></audio>`;else if(u==="pdf")a.innerHTML=`<iframe src="${escapeHtml(`${g}/raw`)}" title="${escapeHtml(e)}"></iframe>`;else if(u==="docx"||u==="pptx")a.innerHTML=`<iframe src="${escapeHtml(`${g}/preview`)}" title="${escapeHtml(e)}"></iframe>`;else if(u==="xlsx")this._openSpreadsheetPreview(a,`${g}/raw`,f);else try{const $=await fetch(`${g}/raw`,{headers:{Range:"bytes=0-524287"}});if(!$.ok)throw new Error("Failed to load attachment");const b=await $.text();if(h())return;const T=$.status===206&&b.length>=524288,E=b.split(`
|
|
245
|
+
`}).join("")}n.querySelectorAll(".file-tree-item").forEach(a=>{a.addEventListener("click",()=>{const r=a.dataset.path;a.dataset.type==="directory"?this._openFileBrowserSearchDirectory({...o,path:r}):this.openFilePreview(r,t)})});const l=this.$("fileBrowserStatus");if(l){const a=s.matchCount===void 0?e.length:s.matchCount;l.textContent=`${a} ${a===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!0;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})`;if(/unsupported/i.test(i)){const o=(e.split(".").pop()||"").toLowerCase(),l=this._isExternalPreviewPath(e,t)?`.${o} from outside the session workspace`:`"${e}" through the attachment lookup`;return{status:s.status,error:`Cannot preview ${l} (images, video, audio, PDF, Office documents and text files only).`}}return{error:i,status:s.status}}catch(s){return{error:s.message||"Cannot open this file"}}},async openFilePreview(e,t=this.activeSessionId,s=null,n={}){if(!t||!e)return;const i=n.folderFile||null;!i&&this.folderGrid&&(this.folderGrid.index=null),this._updateFolderPreviewNav(i?null:this._previewFolderPath(e,t,s));const o=this.$("filePreviewOverlay"),l=this.$("filePreviewTitle"),a=this.$("filePreviewBody"),r=this.$("filePreviewFooter");if(!o||!a)return;this._recordFilePreviewHistory(e,t,s,n),this._bindFilePreviewChrome();const c=this._filePreviewLoad=(this._filePreviewLoad||0)+1,h=()=>c!==this._filePreviewLoad;this._resetFilePreviewEdit(),this._stopFilePreviewMedia(),this.filePreviewDetachUrl="";const d=this.$("filePreviewDetachBtn");d&&(d.hidden=!0),this.filePreviewText=null,this.filePreviewPage=null,this.filePreviewPageRefused=!1,this._updateFilePreviewToolbar("none"),o.classList.add("visible"),this._applyFilePreviewExpanded(),l.textContent=e,a.innerHTML='<div class="binary-message">Loading...</div>',r.textContent="";const u=(e.split(".").pop()||"").toLowerCase();if(!s&&rendersAsPage(e)&&this._filePreviewPref("htmlRendered")){const g=await this._mintHtmlViewUrl(e,t);if(g){r.textContent="HTML",this.filePreviewPage={filePath:e,sessionId:t},this.filePreviewDetachUrl=g,d&&(d.hidden=!1),a.innerHTML=`<iframe src="${escapeHtml(g)}" title="${escapeHtml(e)}" sandbox="allow-scripts allow-forms allow-popups allow-modals allow-downloads"></iframe>`,this._updateFilePreviewToolbar("page");return}this.filePreviewPageRefused=!0}let p="",f=0;if(!s&&!i&&this._isExternalPreviewPath(e,t)){const g=await this._registerExternalPreview(e,t);if(h())return;s=g.attachmentId||null,p=g.error||"",f=g.size||0}if(!s&&p){r.textContent="",a.innerHTML=`<div class="binary-message">${escapeHtml(p)}</div>`;return}const w=u==="docx"||u==="pptx",y=s?`/api/sessions/${t}/attachments/${encodeURIComponent(s)}`:i?`/api/sessions/${t}/folders/${encodeURIComponent(i.folderId)}/files/${encodeURIComponent(i.name)}`:null;if(this.filePreviewDetachUrl=CodemanBase.url(y?`${y}/${w?"preview":"raw"}`:w?`/api/sessions/${t}/file-preview?path=${encodeURIComponent(e)}`:`/api/sessions/${t}/file-raw?path=${encodeURIComponent(e)}`),d&&(d.hidden=!1),y){const g=CodemanBase.url(y),C=new Set(["png","jpg","jpeg","gif","webp","bmp","svg"]),m=new Set(["mp4","webm","mov","m4v","ogv"]),S=new Set(["mp3","wav","ogg","oga","m4a","aac","flac","opus"]);if(i&&!f&&(f=n.size||0),r.textContent=f?`${this.formatFileSize(f)} \u2022 ${u}`:u.toUpperCase(),C.has(u))a.innerHTML=`<img src="${escapeHtml(`${g}/raw`)}" alt="${escapeHtml(e)}">`;else if(m.has(u))a.innerHTML=`<video src="${escapeHtml(`${g}/raw`)}" controls autoplay playsinline preload="metadata"></video>`;else if(S.has(u))a.innerHTML=`<audio src="${escapeHtml(`${g}/raw`)}" controls autoplay preload="metadata"></audio>`;else if(u==="pdf")a.innerHTML=`<iframe src="${escapeHtml(`${g}/raw`)}" title="${escapeHtml(e)}"></iframe>`;else if(u==="docx"||u==="pptx")a.innerHTML=`<iframe src="${escapeHtml(`${g}/preview`)}" title="${escapeHtml(e)}"></iframe>`;else if(u==="xlsx")this._openSpreadsheetPreview(a,`${g}/raw`,f);else try{const $=await fetch(`${g}/raw`,{headers:{Range:"bytes=0-524287"}});if(!$.ok)throw new Error("Failed to load attachment");const b=await $.text();if(h())return;const T=$.status===206&&b.length>=524288,E=b.split(`
|
|
246
246
|
`),I=MARKDOWN_EXTS.has(u)?1/0:500,P=E.length>I,B=P?E.slice(0,I).join(`
|
|
247
|
-
`):b;if(this.filePreviewContent=B,this.filePreviewText={ext:u,sessionId:t,filePath:e,attachmentId:s||i?.folderId},this._renderFilePreviewText(),P||T){const x=P?`showing first ${I} lines`:"showing the start of the file";r.textContent=`${r.textContent} (${x})`}}catch($){if(h())return;a.innerHTML=`<div class="binary-message">Error: ${escapeHtml($.message)}</div>`}return}if(u==="docx"||u==="pptx"){r.textContent=u.toUpperCase();const g=CodemanBase.url(`/api/sessions/${t}/file-preview?path=${encodeURIComponent(e)}`);a.innerHTML=`<iframe src="${escapeHtml(g)}" title="${escapeHtml(e)}"></iframe>`;return}if(u==="pdf"){r.textContent="PDF";const g=CodemanBase.url(`/api/sessions/${t}/file-raw?path=${encodeURIComponent(e)}`);a.innerHTML=`<iframe src="${escapeHtml(g)}" title="${escapeHtml(e)}"></iframe>`;return}if(u==="svg"){r.textContent="SVG";try{const g=await fetch(`/api/sessions/${t}/file-raw?path=${encodeURIComponent(e)}`);if(!g.ok)throw new Error("Failed to load image");const C=await g.text();if(h())return;const m=URL.createObjectURL(new Blob([C],{type:"image/svg+xml"}));a.innerHTML=`<img src="${m}" alt="${escapeHtml(e)}">`;const S=a.querySelector("img");S&&(S.onload=()=>URL.revokeObjectURL(m))}catch(g){if(h())return;a.innerHTML=`<div class="binary-message">Error: ${escapeHtml(g.message)}</div>`}return}const v=MARKDOWN_EXTS.has(u)?1e4:500;try{const g=await fetch(`/api/sessions/${t}/file-content?path=${encodeURIComponent(e)}&lines=${v}`);if(!g.ok)throw new Error("Failed to load file");const C=await g.json();if(h())return;if(!C.success)throw new Error(C.error||"Failed to load file");const m=C.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==="spreadsheet")this._openSpreadsheetPreview(a,CodemanBase.url(m.url),m.size),r.textContent=`${this.formatFileSize(m.size)} \u2022 ${m.extension}`;else if(m.type==="binary"){const S=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(S)}" download>Download</a></div>`,r.textContent=m.extension||"binary"}else{this.filePreviewContent=m.content,this.filePreviewText={ext:u,sessionId:t,filePath:e},this._renderFilePreviewText();const S=m.truncated?` (showing ${v}/${m.totalLines} lines)`:"";if(r.textContent=`${m.totalLines} lines \u2022 ${this.formatFileSize(m.size)}${S}`,m.editable){this.filePreviewEditTarget={sessionId:t,filePath:e};const $=this.$("filePreviewEditBtn");$&&($.hidden=!1)}}}catch(g){if(h())return;console.error("Failed to preview file:",g),a.innerHTML=`<div class="binary-message">Error: ${escapeHtml(g.message)}</div>`}},async openFolderGrid(e,t=this.activeSessionId){if(!t||!e)return;const s=this.$("folderGridOverlay"),n=this.$("folderGridBody");if(!s||!n)return;this._bindFolderGridKeys();const i=this._folderGridLoad=(this._folderGridLoad||0)+1;let o=null,l=0;try{const a=await fetch(`/api/sessions/${t}/folders`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({path:e})});l=a.status,o=await a.json().catch(()=>null)}catch(a){if(i!==this._folderGridLoad)return;this.showToast(`Cannot open folder: ${a.message||a}`,"error");return}if(i===this._folderGridLoad){if(!o?.success||!o.data){const a=o?.error||`HTTP ${l}`;if(l===400&&/not a folder/i.test(a)){this.openFilePreview(e,t);return}this.showToast(`Cannot open folder ${e}: ${a}`,"error");return}this.folderGrid={sessionId:t,...o.data,index:null},this._renderFolderGrid(),s.classList.add("visible"),n.scrollTop=0}},closeFolderGrid(){this._folderGridLoad=(this._folderGridLoad||0)+1,this.$("folderGridOverlay")?.classList.remove("visible");const e=this.$("folderGridBody");e&&(e.innerHTML=""),this.folderGrid=null,this._updateFolderPreviewNav(null)},folderGridUp(){const e=this.folderGrid;!e||e.path==="/"||this.openFolderGrid(e.path.slice(0,e.path.lastIndexOf("/"))||"/",e.sessionId)},_renderFolderGrid(){const e=this.folderGrid;if(!e)return;const t=this.$("folderGridTitle"),s=this.$("folderGridFolders"),n=this.$("folderGridBody"),i=this.$("folderGridFooter");t.textContent=e.path,t.title=e.path;const o=this.$("folderGridUpBtn");o&&(o.disabled=e.path==="/"),s.innerHTML="";for(const r of e.folders){const c=document.createElement("button");c.type="button",c.className="folder-grid-chip",c.textContent=`${r}/`,c.onclick=()=>this.openFolderGrid(`${e.path==="/"?"":e.path}/${r}`,e.sessionId),s.appendChild(c)}if(n.innerHTML="",e.files.length===0){const r=document.createElement("div");r.className="folder-grid-empty",r.textContent="No previewable files in this folder.",n.appendChild(r)}e.files.forEach((r,c)=>{const h=document.createElement("button");h.type="button",h.className="folder-grid-tile",h.title=`${r.name} \u2022 ${this.formatFileSize(r.size)}`,h.dataset.index=String(c);const d=document.createElement("div");d.className="folder-grid-thumb";const u=r.extension.toUpperCase(),p=this._folderFileUrl(e,r.name,""),f=r.attachmentType==="image"?`${p}/raw`:["pdf","docx","pptx"].includes(r.extension)?`${p}/thumbnail`:null;if(f){const y=document.createElement("img");y.loading="lazy",y.decoding="async",y.alt=r.name,y.src=f,y.onerror=()=>{d.textContent=u},d.appendChild(y)}else d.textContent=u;const w=document.createElement("span");w.className="folder-grid-name",w.textContent=r.name,h.append(d,w),h.onclick=()=>this._openFolderGridFile(c),n.appendChild(h)});const l=`${e.files.length} file${e.files.length===1?"":"s"}`,a=e.folders.length?` \u2022 ${e.folders.length} folder${e.folders.length===1?"":"s"}`:"";i.textContent=`${l}${a}${e.truncated?" (folder too large \u2014 showing the first entries)":""}`},_folderFileUrl(e,t,s){return CodemanBase.url(`/api/sessions/${e.sessionId}/folders/${encodeURIComponent(e.folderId)}/files/${encodeURIComponent(t)}${s}`)},_openFolderGridFile(e){const t=this.folderGrid,s=t?.files[e];if(!s)return;const n=this.$("folderGridBody");n?.querySelectorAll(".folder-grid-tile.current").forEach(o=>o.classList.remove("current"));const i=n?.querySelector(`.folder-grid-tile[data-index="${e}"]`);i?.classList.add("current"),i?.scrollIntoView({block:"nearest"}),this.openFilePreview(`${t.path==="/"?"":t.path}/${s.name}`,t.sessionId,null,{folderFile:{folderId:t.folderId,name:s.name},size:s.size}),t.index=e,t.lastIndex=e,this._updateFolderPreviewNav(null)},stepFolderPreview(e){const t=this.folderGrid;if(!t||t.index===null||t.files.length===0||this.filePreviewEdit?.dirty&&!confirm("Discard unsaved changes?"))return;const s=(t.index+e+t.files.length)%t.files.length;this._openFolderGridFile(s)},_recordFilePreviewHistory(e,t,s,n){const i=this.filePreviewHistory=this.filePreviewHistory||{entries:[],index:-1};if(!this._filePreviewHistoryStepping){const o=i.entries[i.index];o&&o.filePath===e&&o.sessionId===t&&(o.attachmentId||null)===(s||null)||(i.entries.length=i.index+1,i.entries.push({filePath:e,sessionId:t,attachmentId:s||null,options:n}),i.entries.length>FILE_PREVIEW_HISTORY_MAX&&i.entries.shift(),i.index=i.entries.length-1)}this._updateFilePreviewHistoryNav()},stepFilePreviewHistory(e){const t=this.filePreviewHistory;if(!t)return;const s=t.index+e;if(s<0||s>=t.entries.length||this.filePreviewEdit?.dirty&&!confirm("Discard unsaved changes?"))return;t.index=s;const n=t.entries[s];this._filePreviewHistoryStepping=!0;try{const i=n.options?.folderFile;if(i&&i.folderId===this.folderGrid?.folderId){const o=this.folderGrid.files.findIndex(l=>l.name===i.name);if(o!==-1)return this._openFolderGridFile(o)}return this.openFilePreview(n.filePath,n.sessionId,n.attachmentId,n.options||{})}finally{this._filePreviewHistoryStepping=!1}},_updateFilePreviewHistoryNav(){const e=this.filePreviewHistory,t=!!e&&e.entries.length>1,s=this.$("filePreviewBackBtn"),n=this.$("filePreviewForwardBtn");s&&(s.hidden=!t,s.disabled=!t||e.index<=0),n&&(n.hidden=!t,n.disabled=!t||e.index>=e.entries.length-1)},toggleFilePreviewExpanded(){this._setFilePreviewPref("expanded",!this._filePreviewPref("expanded")),this._applyFilePreviewExpanded()},_applyFilePreviewExpanded(){const e=this._filePreviewPref("expanded");this.$("filePreviewOverlay")?.querySelector?.(".file-preview-window")?.classList?.toggle("expanded",e),this.$("filePreviewExpandBtn")?.setAttribute("aria-pressed",e?"true":"false")},_bindFilePreviewChrome(){this._filePreviewChromeBound||(this._filePreviewChromeBound=!0,document.addEventListener("keydown",e=>{if(!e.altKey||e.ctrlKey||e.metaKey||e.shiftKey||e.key!=="ArrowLeft"&&e.key!=="ArrowRight"||!this.$("filePreviewOverlay")?.classList.contains("visible"))return;const t=e.target;if(t&&(t.isContentEditable||/^(INPUT|TEXTAREA|SELECT)$/.test(t.tagName)&&!t.classList?.contains("xterm-helper-textarea")))return;e.preventDefault(),e.stopPropagation();const s=this.filePreviewHistory,n=e.key==="ArrowLeft"?-1:1;!s||s.index+n<0||s.index+n>=s.entries.length||this.stepFilePreviewHistory(n)},!0),this._bindFilePreviewResize())},_bindFilePreviewResize(){const e=this.$("filePreviewResize"),t=e?.parentElement;!e||!t||e.addEventListener("pointerdown",s=>{if(s.button!==0)return;s.preventDefault();const n=s.clientX,i=s.clientY,o=t.offsetWidth,l=t.offsetHeight;e.setPointerCapture?.(s.pointerId);const a=c=>{const h=Math.max(320,Math.min(window.innerWidth*.96,o+2*(c.clientX-n))),d=Math.max(240,Math.min(window.innerHeight*.94,l+2*(c.clientY-i)));t.style.width=`${Math.round(h)}px`,t.style.height=`${Math.round(d)}px`},r=()=>{e.removeEventListener("pointermove",a),e.removeEventListener("pointerup",r),e.removeEventListener("pointercancel",r)};e.addEventListener("pointermove",a),e.addEventListener("pointerup",r),e.addEventListener("pointercancel",r)})},openFolderOfPreview(){const e=this.filePreviewFolderTarget;e&&(this.closeFilePreview(),this.openFolderGrid(e.dir,e.sessionId))},_previewFolderPath(e,t,s){if(typeof e!="string"||s&&!e.includes("/"))return null;const n=this.sessions?.get?.(t)?.workingDir,i=typeof resolveLinkedFilePath=="function"?resolveLinkedFilePath(e,n):e;if(!i.startsWith("/")&&!i.startsWith("~/"))return null;const o=i.lastIndexOf("/");return{dir:i.slice(0,o)||"/",sessionId:t}},_updateFolderPreviewNav(e){const t=!!this.folderGrid&&this.folderGrid.index!==null&&this.folderGrid.files.length>1,s=this.$("filePreviewPrevBtn"),n=this.$("filePreviewNextBtn");s&&(s.hidden=!t),n&&(n.hidden=!t),e!==void 0&&(this.filePreviewFolderTarget=e);const i=!!this.folderGrid&&this.folderGrid.index!==null,o=this.$("filePreviewFolderBtn");o&&(o.hidden=i||!this.filePreviewFolderTarget)},_bindFolderGridKeys(){this._folderGridKeysBound||(this._folderGridKeysBound=!0,document.addEventListener("keydown",e=>{const t=this.folderGrid;if(!t||e.altKey||e.ctrlKey||e.metaKey)return;const s=this.$("filePreviewOverlay")?.classList.contains("visible");if(!this.$("folderGridOverlay")?.classList.contains("visible"))return;const i=e.target;if(i&&(i.isContentEditable||/^(INPUT|TEXTAREA|SELECT)$/.test(i.tagName)&&!i.classList?.contains("xterm-helper-textarea"))||this.filePreviewEdit)return;let l=!0;s&&t.index!==null&&e.key==="ArrowLeft"?this.stepFolderPreview(-1):s&&t.index!==null&&e.key==="ArrowRight"?this.stepFolderPreview(1):!s&&(e.key==="ArrowLeft"||e.key==="ArrowRight")&&t.files.length?this._openFolderGridFile(t.lastIndex??0):e.key==="Escape"?s?this.closeFilePreview():this.closeFolderGrid():l=!1,l&&(e.preventDefault(),e.stopPropagation())},!0))},closeFilePreview(){if(this.filePreviewEdit?.dirty&&!confirm("Discard unsaved changes?"))return;this._resetFilePreviewEdit(),this.folderGrid&&(this.folderGrid.index=null),this._updateFolderPreviewNav(null),this.filePreviewHistory=null,this._updateFilePreviewHistoryNav();const e=this.$("filePreviewOverlay");e&&e.classList.remove("visible"),this._stopFilePreviewMedia(),this.filePreviewContent="",this.filePreviewText=null,this._updateFilePreviewToolbar("none"),this.filePreviewDetachUrl="";const t=this.$("filePreviewDetachBtn");t&&(t.hidden=!0)},detachFilePreview(){if(!this.filePreviewDetachUrl)return;const e=this.openInHostWindow?.(this.filePreviewDetachUrl)??null;if(e!==null){e?this.closeFilePreview():this.showToast("Could not open a new window for this preview","error");return}const t=window.open(this.filePreviewDetachUrl,"_blank");if(!t){this.showToast("Pop-up blocked: allow pop-ups for this site to detach previews","error");return}t.opener=null,this.closeFilePreview()},_stopFilePreviewMedia(){this._disposeSpreadsheetPreview();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=""}},_openSpreadsheetPreview(e,t,s){this._disposeSpreadsheetPreview();const n=window.CodemanSpreadsheetPreview;if(!n?.open){e.innerHTML='<div class="binary-message">Spreadsheet preview is unavailable.</div>';return}e.textContent="";const i={};this._spreadsheetPreviewToken=i,this._spreadsheetPreview=n.open({container:e,url:t,size:s,isCurrent:()=>this._spreadsheetPreviewToken===i})},_disposeSpreadsheetPreview(){const e=this._spreadsheetPreview;this._spreadsheetPreview=null,this._spreadsheetPreviewToken=null;try{e?.dispose()}catch(t){console.warn("Failed to dispose spreadsheet preview:",t)}},_filePreviewPref(e){try{const t=localStorage.getItem(FILE_PREVIEW_PREF_KEYS[e]);if(t==="1")return!0;if(t==="0")return!1}catch{}return FILE_PREVIEW_PREF_DEFAULTS[e]},_setFilePreviewPref(e,t){try{localStorage.setItem(FILE_PREVIEW_PREF_KEYS[e],t?"1":"0")}catch{}},_renderFilePreviewText(){const e=this.filePreviewText,t=this.$("filePreviewBody");if(!e||!t)return;const n=MARKDOWN_EXTS.has(e.ext)&&this._filePreviewPref("mdRendered");if(n){const i=document.createElement("template");i.innerHTML=`<div class="rv-text file-preview-md" data-i18n-skip>${this._renderMarkdown(this.filePreviewContent,{breaks:!1})}</div>`;const o=i.content.firstElementChild;this._rebaseFilePreviewMarkdownRefs(o,e),this._linkifyFilePaths(o);for(const l of o.querySelectorAll("a.rv-path:not([data-session-id])"))l.dataset.sessionId=e.sessionId;t.replaceChildren(i.content),this._bindResponseViewerInteractions(t)}else{const i=document.createElement("pre");i.className="file-preview-text",i.classList.toggle("wrap",this._filePreviewPref("wrap")),i.classList.toggle("show-lines",this._filePreviewPref("lineNumbers"));const o=document.createElement("code");o.innerHTML=this.filePreviewContent.split(`
|
|
247
|
+
`):b;if(this.filePreviewContent=B,this.filePreviewText={ext:u,sessionId:t,filePath:e,attachmentId:s||i?.folderId},this._renderFilePreviewText(),P||T){const _=P?`showing first ${I} lines`:"showing the start of the file";r.textContent=`${r.textContent} (${_})`}}catch($){if(h())return;a.innerHTML=`<div class="binary-message">Error: ${escapeHtml($.message)}</div>`}return}if(u==="docx"||u==="pptx"){r.textContent=u.toUpperCase();const g=CodemanBase.url(`/api/sessions/${t}/file-preview?path=${encodeURIComponent(e)}`);a.innerHTML=`<iframe src="${escapeHtml(g)}" title="${escapeHtml(e)}"></iframe>`;return}if(u==="pdf"){r.textContent="PDF";const g=CodemanBase.url(`/api/sessions/${t}/file-raw?path=${encodeURIComponent(e)}`);a.innerHTML=`<iframe src="${escapeHtml(g)}" title="${escapeHtml(e)}"></iframe>`;return}if(u==="svg"){r.textContent="SVG";try{const g=await fetch(`/api/sessions/${t}/file-raw?path=${encodeURIComponent(e)}`);if(!g.ok)throw new Error("Failed to load image");const C=await g.text();if(h())return;const m=URL.createObjectURL(new Blob([C],{type:"image/svg+xml"}));a.innerHTML=`<img src="${m}" alt="${escapeHtml(e)}">`;const S=a.querySelector("img");S&&(S.onload=()=>URL.revokeObjectURL(m))}catch(g){if(h())return;a.innerHTML=`<div class="binary-message">Error: ${escapeHtml(g.message)}</div>`}return}const v=MARKDOWN_EXTS.has(u)?1e4:500;try{const g=await fetch(`/api/sessions/${t}/file-content?path=${encodeURIComponent(e)}&lines=${v}`);if(!g.ok)throw new Error("Failed to load file");const C=await g.json();if(h())return;if(!C.success)throw new Error(C.error||"Failed to load file");const m=C.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==="spreadsheet")this._openSpreadsheetPreview(a,CodemanBase.url(m.url),m.size),r.textContent=`${this.formatFileSize(m.size)} \u2022 ${m.extension}`;else if(m.type==="binary"){const S=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(S)}" download>Download</a></div>`,r.textContent=m.extension||"binary"}else{this.filePreviewContent=m.content,this.filePreviewText={ext:u,sessionId:t,filePath:e},this._renderFilePreviewText();const S=m.truncated?` (showing ${v}/${m.totalLines} lines)`:"";if(r.textContent=`${m.totalLines} lines \u2022 ${this.formatFileSize(m.size)}${S}`,m.editable){this.filePreviewEditTarget={sessionId:t,filePath:e};const $=this.$("filePreviewEditBtn");$&&($.hidden=!1)}}}catch(g){if(h())return;console.error("Failed to preview file:",g),a.innerHTML=`<div class="binary-message">Error: ${escapeHtml(g.message)}</div>`}},async openFolderGrid(e,t=this.activeSessionId){if(!t||!e)return;const s=this.$("folderGridOverlay"),n=this.$("folderGridBody");if(!s||!n)return;this._bindFolderGridKeys();const i=this._folderGridLoad=(this._folderGridLoad||0)+1;let o=null,l=0;try{const a=await fetch(`/api/sessions/${t}/folders`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({path:e})});l=a.status,o=await a.json().catch(()=>null)}catch(a){if(i!==this._folderGridLoad)return;this.showToast(`Cannot open folder: ${a.message||a}`,"error");return}if(i===this._folderGridLoad){if(!o?.success||!o.data){const a=o?.error||`HTTP ${l}`;if(l===400&&/not a folder/i.test(a)){this.openFilePreview(e,t);return}this.showToast(`Cannot open folder ${e}: ${a}`,"error");return}this.folderGrid={sessionId:t,...o.data,index:null},this._renderFolderGrid(),s.classList.add("visible"),n.scrollTop=0}},closeFolderGrid(){this._folderGridLoad=(this._folderGridLoad||0)+1,this.$("folderGridOverlay")?.classList.remove("visible");const e=this.$("folderGridBody");e&&(e.innerHTML=""),this.folderGrid=null,this._updateFolderPreviewNav(null)},folderGridUp(){const e=this.folderGrid;!e||e.path==="/"||this.openFolderGrid(e.path.slice(0,e.path.lastIndexOf("/"))||"/",e.sessionId)},_renderFolderGrid(){const e=this.folderGrid;if(!e)return;const t=this.$("folderGridTitle"),s=this.$("folderGridFolders"),n=this.$("folderGridBody"),i=this.$("folderGridFooter");t.textContent=e.path,t.title=e.path;const o=this.$("folderGridUpBtn");o&&(o.disabled=e.path==="/"),s.innerHTML="";for(const r of e.folders){const c=document.createElement("button");c.type="button",c.className="folder-grid-chip",c.textContent=`${r}/`,c.onclick=()=>this.openFolderGrid(`${e.path==="/"?"":e.path}/${r}`,e.sessionId),s.appendChild(c)}if(n.innerHTML="",e.files.length===0){const r=document.createElement("div");r.className="folder-grid-empty",r.textContent="No previewable files in this folder.",n.appendChild(r)}e.files.forEach((r,c)=>{const h=document.createElement("button");h.type="button",h.className="folder-grid-tile",h.title=`${r.name} \u2022 ${this.formatFileSize(r.size)}`,h.dataset.index=String(c);const d=document.createElement("div");d.className="folder-grid-thumb";const u=r.extension.toUpperCase(),p=this._folderFileUrl(e,r.name,""),f=r.attachmentType==="image"?`${p}/raw`:["pdf","docx","pptx"].includes(r.extension)?`${p}/thumbnail`:null;if(f){const y=document.createElement("img");y.loading="lazy",y.decoding="async",y.alt=r.name,y.src=f,y.onerror=()=>{d.textContent=u},d.appendChild(y)}else d.textContent=u;const w=document.createElement("span");w.className="folder-grid-name",w.textContent=r.name,h.append(d,w),h.onclick=()=>this._openFolderGridFile(c),n.appendChild(h)});const l=`${e.files.length} file${e.files.length===1?"":"s"}`,a=e.folders.length?` \u2022 ${e.folders.length} folder${e.folders.length===1?"":"s"}`:"";i.textContent=`${l}${a}${e.truncated?" (folder too large \u2014 showing the first entries)":""}`},_folderFileUrl(e,t,s){return CodemanBase.url(`/api/sessions/${e.sessionId}/folders/${encodeURIComponent(e.folderId)}/files/${encodeURIComponent(t)}${s}`)},_openFolderGridFile(e){const t=this.folderGrid,s=t?.files[e];if(!s)return;const n=this.$("folderGridBody");n?.querySelectorAll(".folder-grid-tile.current").forEach(o=>o.classList.remove("current"));const i=n?.querySelector(`.folder-grid-tile[data-index="${e}"]`);i?.classList.add("current"),i?.scrollIntoView({block:"nearest"}),this.openFilePreview(`${t.path==="/"?"":t.path}/${s.name}`,t.sessionId,null,{folderFile:{folderId:t.folderId,name:s.name},size:s.size}),t.index=e,t.lastIndex=e,this._updateFolderPreviewNav(null)},stepFolderPreview(e){const t=this.folderGrid;if(!t||t.index===null||t.files.length===0||this.filePreviewEdit?.dirty&&!confirm("Discard unsaved changes?"))return;const s=(t.index+e+t.files.length)%t.files.length;this._openFolderGridFile(s)},_recordFilePreviewHistory(e,t,s,n){const i=this.filePreviewHistory=this.filePreviewHistory||{entries:[],index:-1};if(!this._filePreviewHistoryStepping){const o=i.entries[i.index];o&&o.filePath===e&&o.sessionId===t&&(o.attachmentId||null)===(s||null)||(i.entries.length=i.index+1,i.entries.push({filePath:e,sessionId:t,attachmentId:s||null,options:n}),i.entries.length>FILE_PREVIEW_HISTORY_MAX&&i.entries.shift(),i.index=i.entries.length-1)}this._updateFilePreviewHistoryNav()},stepFilePreviewHistory(e){const t=this.filePreviewHistory;if(!t)return;const s=t.index+e;if(s<0||s>=t.entries.length||this.filePreviewEdit?.dirty&&!confirm("Discard unsaved changes?"))return;t.index=s;const n=t.entries[s];this._filePreviewHistoryStepping=!0;try{const i=n.options?.folderFile;if(i&&i.folderId===this.folderGrid?.folderId){const o=this.folderGrid.files.findIndex(l=>l.name===i.name);if(o!==-1)return this._openFolderGridFile(o)}return this.openFilePreview(n.filePath,n.sessionId,n.attachmentId,n.options||{})}finally{this._filePreviewHistoryStepping=!1}},_updateFilePreviewHistoryNav(){const e=this.filePreviewHistory,t=!!e&&e.entries.length>1,s=this.$("filePreviewBackBtn"),n=this.$("filePreviewForwardBtn");s&&(s.hidden=!t,s.disabled=!t||e.index<=0),n&&(n.hidden=!t,n.disabled=!t||e.index>=e.entries.length-1)},toggleFilePreviewExpanded(){this._setFilePreviewPref("expanded",!this._filePreviewPref("expanded")),this._applyFilePreviewExpanded()},_applyFilePreviewExpanded(){const e=this._filePreviewPref("expanded");this.$("filePreviewOverlay")?.querySelector?.(".file-preview-window")?.classList?.toggle("expanded",e),this.$("filePreviewExpandBtn")?.setAttribute("aria-pressed",e?"true":"false")},_bindFilePreviewChrome(){this._filePreviewChromeBound||(this._filePreviewChromeBound=!0,document.addEventListener("keydown",e=>{if(!e.altKey||e.ctrlKey||e.metaKey||e.shiftKey||e.key!=="ArrowLeft"&&e.key!=="ArrowRight"||!this.$("filePreviewOverlay")?.classList.contains("visible"))return;const t=e.target;if(t&&(t.isContentEditable||/^(INPUT|TEXTAREA|SELECT)$/.test(t.tagName)&&!t.classList?.contains("xterm-helper-textarea")))return;e.preventDefault(),e.stopPropagation();const s=this.filePreviewHistory,n=e.key==="ArrowLeft"?-1:1;!s||s.index+n<0||s.index+n>=s.entries.length||this.stepFilePreviewHistory(n)},!0),this._bindFilePreviewResize())},_bindFilePreviewResize(){const e=this.$("filePreviewResize"),t=e?.parentElement;!e||!t||e.addEventListener("pointerdown",s=>{if(s.button!==0)return;s.preventDefault();const n=s.clientX,i=s.clientY,o=t.offsetWidth,l=t.offsetHeight;e.setPointerCapture?.(s.pointerId);const a=c=>{const h=Math.max(320,Math.min(window.innerWidth*.96,o+2*(c.clientX-n))),d=Math.max(240,Math.min(window.innerHeight*.94,l+2*(c.clientY-i)));t.style.width=`${Math.round(h)}px`,t.style.height=`${Math.round(d)}px`},r=()=>{e.removeEventListener("pointermove",a),e.removeEventListener("pointerup",r),e.removeEventListener("pointercancel",r)};e.addEventListener("pointermove",a),e.addEventListener("pointerup",r),e.addEventListener("pointercancel",r)})},openFolderOfPreview(){const e=this.filePreviewFolderTarget;e&&(this.closeFilePreview(),this.openFolderGrid(e.dir,e.sessionId))},_previewFolderPath(e,t,s){if(typeof e!="string"||s&&!e.includes("/"))return null;const n=this.sessions?.get?.(t)?.workingDir,i=typeof resolveLinkedFilePath=="function"?resolveLinkedFilePath(e,n):e;if(!i.startsWith("/")&&!i.startsWith("~/"))return null;const o=i.lastIndexOf("/");return{dir:i.slice(0,o)||"/",sessionId:t}},_updateFolderPreviewNav(e){const t=!!this.folderGrid&&this.folderGrid.index!==null&&this.folderGrid.files.length>1,s=this.$("filePreviewPrevBtn"),n=this.$("filePreviewNextBtn");s&&(s.hidden=!t),n&&(n.hidden=!t),e!==void 0&&(this.filePreviewFolderTarget=e);const i=!!this.folderGrid&&this.folderGrid.index!==null,o=this.$("filePreviewFolderBtn");o&&(o.hidden=i||!this.filePreviewFolderTarget)},_bindFolderGridKeys(){this._folderGridKeysBound||(this._folderGridKeysBound=!0,document.addEventListener("keydown",e=>{const t=this.folderGrid;if(!t||e.altKey||e.ctrlKey||e.metaKey)return;const s=this.$("filePreviewOverlay")?.classList.contains("visible");if(!this.$("folderGridOverlay")?.classList.contains("visible"))return;const i=e.target;if(i&&(i.isContentEditable||/^(INPUT|TEXTAREA|SELECT)$/.test(i.tagName)&&!i.classList?.contains("xterm-helper-textarea"))||this.filePreviewEdit)return;let l=!0;s&&t.index!==null&&e.key==="ArrowLeft"?this.stepFolderPreview(-1):s&&t.index!==null&&e.key==="ArrowRight"?this.stepFolderPreview(1):!s&&(e.key==="ArrowLeft"||e.key==="ArrowRight")&&t.files.length?this._openFolderGridFile(t.lastIndex??0):e.key==="Escape"?s?this.closeFilePreview():this.closeFolderGrid():l=!1,l&&(e.preventDefault(),e.stopPropagation())},!0))},closeFilePreview(){if(this.filePreviewEdit?.dirty&&!confirm("Discard unsaved changes?"))return;this._resetFilePreviewEdit(),this.folderGrid&&(this.folderGrid.index=null),this._updateFolderPreviewNav(null),this.filePreviewHistory=null,this._updateFilePreviewHistoryNav();const e=this.$("filePreviewOverlay");e&&e.classList.remove("visible"),this._stopFilePreviewMedia(),this.filePreviewContent="",this.filePreviewText=null,this._updateFilePreviewToolbar("none"),this.filePreviewDetachUrl="";const t=this.$("filePreviewDetachBtn");t&&(t.hidden=!0)},detachFilePreview(){if(!this.filePreviewDetachUrl)return;const e=this.openInHostWindow?.(this.filePreviewDetachUrl)??null;if(e!==null){e?this.closeFilePreview():this.showToast("Could not open a new window for this preview","error");return}const t=window.open(this.filePreviewDetachUrl,"_blank");if(!t){this.showToast("Pop-up blocked: allow pop-ups for this site to detach previews","error");return}t.opener=null,this.closeFilePreview()},_stopFilePreviewMedia(){this._disposeSpreadsheetPreview();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=""}},_openSpreadsheetPreview(e,t,s){this._disposeSpreadsheetPreview();const n=window.CodemanSpreadsheetPreview;if(!n?.open){e.innerHTML='<div class="binary-message">Spreadsheet preview is unavailable.</div>';return}e.textContent="";const i={};this._spreadsheetPreviewToken=i,this._spreadsheetPreview=n.open({container:e,url:t,size:s,isCurrent:()=>this._spreadsheetPreviewToken===i})},_disposeSpreadsheetPreview(){const e=this._spreadsheetPreview;this._spreadsheetPreview=null,this._spreadsheetPreviewToken=null;try{e?.dispose()}catch(t){console.warn("Failed to dispose spreadsheet preview:",t)}},_filePreviewPref(e){try{const t=localStorage.getItem(FILE_PREVIEW_PREF_KEYS[e]);if(t==="1")return!0;if(t==="0")return!1}catch{}return FILE_PREVIEW_PREF_DEFAULTS[e]},_setFilePreviewPref(e,t){try{localStorage.setItem(FILE_PREVIEW_PREF_KEYS[e],t?"1":"0")}catch{}},_renderFilePreviewText(){const e=this.filePreviewText,t=this.$("filePreviewBody");if(!e||!t)return;const n=MARKDOWN_EXTS.has(e.ext)&&this._filePreviewPref("mdRendered");if(n){const i=document.createElement("template");i.innerHTML=`<div class="rv-text file-preview-md" data-i18n-skip>${this._renderMarkdown(this.filePreviewContent,{breaks:!1})}</div>`;const o=i.content.firstElementChild;this._rebaseFilePreviewMarkdownRefs(o,e),this._linkifyFilePaths(o);for(const l of o.querySelectorAll("a.rv-path:not([data-session-id])"))l.dataset.sessionId=e.sessionId;t.replaceChildren(i.content),this._bindResponseViewerInteractions(t)}else{const i=document.createElement("pre");i.className="file-preview-text",i.classList.toggle("wrap",this._filePreviewPref("wrap")),i.classList.toggle("show-lines",this._filePreviewPref("lineNumbers"));const o=document.createElement("code");o.innerHTML=this.filePreviewContent.split(`
|
|
248
248
|
`).map(l=>`<span class="fp-line">${escapeHtml(l)}</span>`).join(`
|
|
249
249
|
`),i.appendChild(o),t.replaceChildren(i)}this._updateFilePreviewToolbar(n?"markdown":"text")},_rebaseFilePreviewMarkdownRefs(e,{sessionId:t,filePath:s,attachmentId:n}){const i=s.includes("/")?s.slice(0,s.lastIndexOf("/")+1):"",o=!!n&&!s.startsWith("/"),l=r=>!!r&&!/^[a-z][a-z0-9+.-]*:/i.test(r)&&!r.startsWith("//")&&!r.startsWith("#"),a=r=>{let c=r.split("#")[0].split("?")[0];try{c=decodeURIComponent(c)}catch{}const h=[];for(const d of(c.startsWith("/")?c.slice(1):i+c).split("/"))d==="."||d===""&&h.length||(d===".."&&h.length&&h[h.length-1]!==".."&&h[h.length-1]!==""?h.pop():h.push(d));return h.join("/")};for(const r of e.querySelectorAll("img[src]")){const c=r.getAttribute("src")||"";if(o&&l(c)){r.replaceWith(r.getAttribute("alt")||c);continue}if(l(c)){const h=a(c);r.setAttribute("src",CodemanBase.url(`/api/sessions/${t}/file-raw?path=${encodeURIComponent(h)}`))}r.addEventListener("error",()=>r.replaceWith(r.getAttribute("alt")||c),{once:!0})}for(const r of e.querySelectorAll("a[href]")){const c=r.getAttribute("href")||"";if(l(c)){if(o){r.replaceWith(...r.childNodes);continue}r.className="rv-path",r.dataset.path=a(c),r.dataset.sessionId=t,r.setAttribute("href","#"),r.removeAttribute("target"),r.removeAttribute("rel")}}},_updateFilePreviewToolbar(e){const t=(o,l,a)=>{const r=this.$(o);r&&(r.hidden=!l,l&&r.setAttribute("aria-pressed",String(a)))},s=e!=="none"&&MARKDOWN_EXTS.has(this.filePreviewText?.ext||"");t("filePreviewMdBtn",s,e==="markdown");const n=this.filePreviewText,i=e==="text"&&!this.filePreviewPageRefused&&rendersAsPage(n?.filePath)&&(!n.attachmentId||n.filePath.startsWith("/"));t("filePreviewPageBtn",e==="page"||i,e==="page"),t("filePreviewLinesBtn",e==="text",this._filePreviewPref("lineNumbers")),t("filePreviewWrapBtn",e==="text",this._filePreviewPref("wrap"))},async _mintHtmlViewUrl(e,t){try{const s=await fetch(`/api/sessions/${t}/html-view`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({path:e})}),n=await s.json().catch(()=>({}));return s.ok&&n.success?CodemanBase.url(n.data.url):null}catch{return null}},toggleFilePreviewPage(){const e=this.filePreviewPage||this.filePreviewText;if(e)return this._setFilePreviewPref("htmlRendered",!this._filePreviewPref("htmlRendered")),this.openFilePreview(e.filePath,e.sessionId)},toggleFilePreviewMd(){this._setFilePreviewPref("mdRendered",!this._filePreviewPref("mdRendered")),this._renderFilePreviewText()},toggleFilePreviewLines(){this._toggleFilePreviewTextClass("lineNumbers","show-lines")},toggleFilePreviewWrap(){this._toggleFilePreviewTextClass("wrap","wrap")},_toggleFilePreviewTextClass(e,t){const s=!this._filePreviewPref(e);this._setFilePreviewPref(e,s);const n=this.$("filePreviewBody")?.querySelector(":scope > pre.file-preview-text");n&&n.classList.toggle(t,s),this._updateFilePreviewToolbar("text")},_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 a=await fetch(`/api/sessions/${e.sessionId}/file-content?path=${encodeURIComponent(e.filePath)}&edit=1`),r=await a.json().catch(()=>null);if(!r||r.success!==!0)throw new Error(r?.error||`Failed to load file for editing (HTTP ${a.status})`);n=r.data}catch(a){this.showToast(a.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),this._updateFilePreviewToolbar("none");const o=this.$("filePreviewEditBtn");o&&(o.hidden=!0);const l=this.$("filePreviewEditBar");if(l&&(l.hidden=!1),s){const a=n.eol==="crlf"?" \u2022 CRLF":"";s.textContent=`Editing \u2022 ${n.totalLines} lines \u2022 ${this.formatFileSize(n.size)}${a}`}},_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 o=null,l=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})});l=c.status,o=await c.json().catch(()=>null)}catch(c){i(),this.showToast(`Save failed: ${c.message}`,"error");return}if(l===409||o?.errorCode==="CONFLICT"){i(),confirm(`File changed on disk since you loaded it.
|
|
250
250
|
OK overwrites it with your version; Cancel keeps your draft open.`)&&this.saveFilePreviewEdit(!0);return}if(!o||o.success!==!0){i(),this.showToast(`Save failed: ${o?.error||`HTTP ${l}`}`,"error");return}const{sessionId:a,filePath:r}=t;this._resetFilePreviewEdit(),this.showToast("Saved","success"),this.openFilePreview(r,a)},_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:o,attachmentType:l,extension:a,attachmentId:r,rawUrl:c,previewUrl:h,thumbnailUrl:d}=e,u=s||n,p=r||`${t}-${i}-${n}`;if(this.attachmentCards.has(p)){this.attachmentCards.get(p).element.focus?.();return}if(this.attachmentCards.size>=10){const E=this.attachmentCards.keys().next().value;E&&this.closeAttachmentCard(E)}const w=this.ensureAttachmentCardStack(),v=this.sessions.get(t)?.name||t.substring(0,8),g=CodemanBase.url(c||(r?`/api/sessions/${t}/attachments/${encodeURIComponent(r)}/raw`:`/api/sessions/${t}/file-raw?path=${encodeURIComponent(u)}`)),C=CodemanBase.url(h||(r?`/api/sessions/${t}/attachments/${encodeURIComponent(r)}/preview`:null)),m=CodemanBase.url(d||(r?`/api/sessions/${t}/attachments/${encodeURIComponent(r)}/thumbnail`:`/api/sessions/${t}/file-thumbnail?path=${encodeURIComponent(u)}`)),S=r?`${g}?download=true`:`${g}&download=true`,$=(a||l||"file").toUpperCase(),b=document.createElement("article");b.className=`attachment-card attachment-${escapeHtml(l||"file")}`,b.tabIndex=0,b.dataset.attachmentId=p,b.dataset.previewUrl=C||"",b.innerHTML=`
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
<span class="action-time">${i}</span>
|
|
9
9
|
<span class="action-type">[${n.type}]</span>
|
|
10
10
|
<span class="action-detail">${escapeHtml(n.detail)}</span>
|
|
11
|
-
</div>`}e.innerHTML=s},clearCountdownTimers(e){delete this.respawnCountdownTimers[e],delete this.respawnActionLogs[e],e===this.activeSessionId&&(this.updateCountdownTimerDisplay(),this.updateActionLogDisplay())},async stopRespawn(){if(this.activeSessionId)try{await this._apiPost(`/api/sessions/${this.activeSessionId}/respawn/stop`,{}),delete this.respawnTimers[this.activeSessionId],this.clearCountdownTimers(this.activeSessionId)}catch{this.showToast("Failed to stop respawn","error")}},loadRespawnPresets(){const e=this._serverRespawnPresets;if(e)return[...BUILTIN_RESPAWN_PRESETS,...e];const t=localStorage.getItem("codeman-respawn-presets"),s=t?JSON.parse(t):[];return[...BUILTIN_RESPAWN_PRESETS,...s]},saveRespawnPresets(e){const t=e.filter(s=>!s.builtIn);if(this._serverRespawnPresets=t,localStorage.setItem("codeman-respawn-presets",JSON.stringify(t)),this._settingsReadOnly?.()){this._rememberOwnSetting?.("respawnPresets",t);return}this._apiPut("/api/settings",{respawnPresets:t}).then(s=>this.
|
|
11
|
+
</div>`}e.innerHTML=s},clearCountdownTimers(e){delete this.respawnCountdownTimers[e],delete this.respawnActionLogs[e],e===this.activeSessionId&&(this.updateCountdownTimerDisplay(),this.updateActionLogDisplay())},async stopRespawn(){if(this.activeSessionId)try{await this._apiPost(`/api/sessions/${this.activeSessionId}/respawn/stop`,{}),delete this.respawnTimers[this.activeSessionId],this.clearCountdownTimers(this.activeSessionId)}catch{this.showToast("Failed to stop respawn","error")}},loadRespawnPresets(){const e=this._serverRespawnPresets;if(e)return[...BUILTIN_RESPAWN_PRESETS,...e];const t=localStorage.getItem("codeman-respawn-presets"),s=t?JSON.parse(t):[];return[...BUILTIN_RESPAWN_PRESETS,...s]},saveRespawnPresets(e){const t=e.filter(s=>!s.builtIn);if(this._serverRespawnPresets=t,localStorage.setItem("codeman-respawn-presets",JSON.stringify(t)),this._settingsReadOnly?.()){this._rememberOwnSetting?.("respawnPresets",t);return}this._apiPut("/api/settings",{respawnPresets:t}).then(s=>this._noteSettingsWriteResult?.(s,"Respawn presets")).catch(()=>{})},renderPresetDropdown(){const e=this.loadRespawnPresets(),t=document.getElementById("builtinPresetsGroup"),s=document.getElementById("customPresetsGroup");!t||!s||(t.innerHTML="",s.innerHTML="",e.forEach(n=>{const i=document.createElement("option");i.value=n.id,i.textContent=n.name,n.builtIn?t.appendChild(i):s.appendChild(i)}))},updatePresetDescription(){const e=document.getElementById("respawnPresetSelect"),t=document.getElementById("presetDescriptionHint");if(!e||!t)return;const s=e.value;if(!s){t.textContent="";return}const i=this.loadRespawnPresets().find(a=>a.id===s);t.textContent=i?.description||""},loadRespawnPreset(){const e=document.getElementById("respawnPresetSelect"),t=e?.value;if(!t){this.showToast("Please select a preset first","warning");return}const n=this.loadRespawnPresets().find(i=>i.id===t);n&&(document.getElementById("modalRespawnPrompt").value=n.config.updatePrompt||"",document.getElementById("modalRespawnSendClear").checked=n.config.sendClear??!1,document.getElementById("modalRespawnSendInit").checked=n.config.sendInit??!1,document.getElementById("modalRespawnKickstart").value=n.config.kickstartPrompt||"",document.getElementById("modalRespawnAutoAccept").checked=n.config.autoAcceptPrompts??!0,n.durationMinutes&&this.selectDurationPreset(String(n.durationMinutes)),e.value="",document.getElementById("presetDescriptionHint").textContent="",this.showToast(`Loaded preset: ${n.name}`,"info"))},saveCurrentAsPreset(){document.getElementById("savePresetModal").classList.add("active"),document.getElementById("presetNameInput").value="",document.getElementById("presetDescriptionInput").value="",document.getElementById("presetNameInput").focus()},closeSavePresetModal(){document.getElementById("savePresetModal").classList.remove("active")},confirmSavePreset(){const e=document.getElementById("presetNameInput").value.trim();if(!e){this.showToast("Please enter a preset name","error");return}const t=document.getElementById("modalRespawnPrompt").value,s=document.getElementById("modalRespawnSendClear").checked,n=document.getElementById("modalRespawnSendInit").checked,i=document.getElementById("modalRespawnKickstart").value.trim()||void 0,a=this.getSelectedDuration(),c={id:"custom-"+Date.now(),name:e,description:document.getElementById("presetDescriptionInput").value.trim()||void 0,config:{idleTimeoutMs:5e3,updatePrompt:t,interStepDelayMs:3e3,sendClear:s,sendInit:n,kickstartPrompt:i},durationMinutes:a||void 0,builtIn:!1,createdAt:Date.now()},l=this.loadRespawnPresets();l.push(c),this.saveRespawnPresets(l),this.renderPresetDropdown(),this.closeSavePresetModal(),this.showToast(`Saved preset: ${e}`,"success")},deletePreset(e){const t=this.loadRespawnPresets(),s=t.find(i=>i.id===e);if(!s||s.builtIn){this.showToast("Cannot delete built-in presets","warning");return}const n=t.filter(i=>i.id!==e);this.saveRespawnPresets(n),this.renderPresetDropdown(),this.showToast(`Deleted preset: ${s.name}`,"success")},getModalRespawnConfig(){const e=document.getElementById("modalRespawnPrompt").value,t=document.getElementById("modalRespawnSendClear").checked,s=document.getElementById("modalRespawnSendInit").checked,n=document.getElementById("modalRespawnKickstart").value.trim()||void 0,i=document.getElementById("modalRespawnAutoAccept").checked,a=this.getSelectedDuration(),c=document.getElementById("modalAutoCompactEnabled").checked,l=parseInt(document.getElementById("modalAutoCompactThreshold").value)||11e4,r=document.getElementById("modalAutoCompactPrompt").value.trim()||void 0,o=document.getElementById("modalAutoClearEnabled").checked,d=parseInt(document.getElementById("modalAutoClearThreshold").value)||14e4;return{respawnConfig:{enabled:!0,updatePrompt:e,sendClear:t,sendInit:s,kickstartPrompt:n,autoAcceptPrompts:i},durationMinutes:a,autoCompactEnabled:c,autoCompactThreshold:l,autoCompactPrompt:r,autoClearEnabled:o,autoClearThreshold:d}},async enableRespawnFromModal(){if(!this.editingSessionId){this.showToast("No session selected","warning");return}const{respawnConfig:e,durationMinutes:t,autoCompactEnabled:s,autoCompactThreshold:n,autoCompactPrompt:i,autoClearEnabled:a,autoClearThreshold:c}=this.getModalRespawnConfig();try{const r=await(await fetch(`/api/sessions/${this.editingSessionId}/respawn/enable`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({config:e,durationMinutes:t??void 0})})).json();if(r.error)throw new Error(r.error);s&&await fetch(`/api/sessions/${this.editingSessionId}/auto-compact`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({enabled:!0,threshold:n,prompt:i})}),a&&await fetch(`/api/sessions/${this.editingSessionId}/auto-clear`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({enabled:!0,threshold:c})});const o=document.getElementById("sessionRespawnStatus");o.classList.add("active"),o.querySelector(".respawn-status-text").textContent="WATCHING",document.getElementById("modalEnableRespawnBtn").style.display="none",document.getElementById("modalStopRespawnBtn").style.display="",this.showToast("Respawn enabled","success")}catch(l){this.showToast("Failed to enable respawn: "+l.message,"error")}},async stopRespawnFromModal(){if(this.editingSessionId)try{await fetch(`/api/sessions/${this.editingSessionId}/respawn/stop`,{method:"POST"}),delete this.respawnTimers[this.editingSessionId];const e=document.getElementById("sessionRespawnStatus");e.classList.remove("active"),e.querySelector(".respawn-status-text").textContent="Not active",document.getElementById("modalEnableRespawnBtn").style.display="",document.getElementById("modalStopRespawnBtn").style.display="none",this.showToast("Respawn stopped","success")}catch{this.showToast("Failed to stop respawn","error")}},closeSessionOptions(){const e=document.getElementById("sessionOptionsModal"),t=document.activeElement;t&&e&&e.contains(t)&&typeof t.blur=="function"&&t.blur(),this.editingSessionId=null,this.stopRunSummaryAutoRefresh(),document.getElementById("sessionOptionsModal").classList.remove("active"),this.activeFocusTrap&&(this.activeFocusTrap.deactivate(),this.activeFocusTrap=null)},setupColorPicker(){const e=document.getElementById("sessionColorPicker");e&&e.addEventListener("click",t=>{const s=t.target.closest(".color-swatch");if(!s||!this.editingSessionId)return;const n=s.dataset.color;this.setSessionColor(this.editingSessionId,n)})},async setSessionColor(e,t){try{if((await fetch(`/api/sessions/${e}/color`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({color:t})})).ok){const n=this.sessions.get(e);n&&(n.color=t,this.renderSessionTabs());const i=document.getElementById("sessionColorPicker");i&&i.querySelectorAll(".color-swatch").forEach(a=>{a.classList.toggle("selected",a.dataset.color===t)})}else this.showToast("Failed to set session color","error")}catch{this.showToast("Failed to set session color","error")}},async openRunSummary(e){this.openSessionOptions(e),this.switchOptionsTab("summary"),this.runSummarySessionId=e,this.runSummaryFilter="all",document.querySelectorAll(".run-summary-filters .filter-btn").forEach(t=>{t.classList.toggle("active",t.dataset.filter==="all")}),await this.loadRunSummary(e)},closeRunSummary(){this.runSummarySessionId=null,this.stopRunSummaryAutoRefresh(),this.closeSessionOptions()},async refreshRunSummary(){const e=this.runSummarySessionId||this.editingSessionId;e&&await this.loadRunSummary(e)},toggleRunSummaryAutoRefresh(){document.getElementById("runSummaryAutoRefresh").checked?this.startRunSummaryAutoRefresh():this.stopRunSummaryAutoRefresh()},startRunSummaryAutoRefresh(){this.runSummaryAutoRefreshTimer||(this.runSummaryAutoRefreshTimer=setInterval(()=>{this.runSummarySessionId&&this.loadRunSummary(this.runSummarySessionId)},5e3))},stopRunSummaryAutoRefresh(){this.runSummaryAutoRefreshTimer&&(clearInterval(this.runSummaryAutoRefreshTimer),this.runSummaryAutoRefreshTimer=null);const e=document.getElementById("runSummaryAutoRefresh");e&&(e.checked=!1)},exportRunSummary(e){if(!this.runSummaryData){this.showToast("No summary data to export","error");return}const{stats:t,events:s,sessionName:n,startedAt:i,lastUpdatedAt:a}=this.runSummaryData,c=new Date().toISOString().slice(0,19).replace(/:/g,"-"),l=`run-summary-${n||"session"}-${c}`;if(e==="json"){const r=JSON.stringify(this.runSummaryData,null,2);this.downloadFile(`${l}.json`,r,"application/json")}else if(e==="md"){const r=a-i;let o=`# Run Summary: ${n||"Session"}
|
|
12
12
|
|
|
13
13
|
`;if(o+=`**Duration**: ${this.formatDuration(r)}
|
|
14
14
|
`,o+=`**Started**: ${new Date(i).toLocaleString()}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1,21 +1 @@
|
|
|
1
|
-
{
|
|
2
|
-
"notices": [
|
|
3
|
-
{
|
|
4
|
-
"id": "opencode-console-breach-2026-10",
|
|
5
|
-
"severity": "warning",
|
|
6
|
-
"cli": "opencode",
|
|
7
|
-
"published": "2026-10-17",
|
|
8
|
-
"expires": "2026-12-31",
|
|
9
|
-
"title": "OpenCode Console breach: check your API keys",
|
|
10
|
-
"message": "OpenCode reported unauthorized access to a legacy system on 17 October. Provider API keys (OpenAI, Anthropic and others) saved in some OpenCode Console workspaces may have been exposed. If OpenCode emailed you about it, revoke and replace those keys and check their recent usage. If you got no email, OpenCode says you were not affected.",
|
|
11
|
-
"link": { "label": "Read OpenCode's notice", "url": "https://x.com/opencode/status/2111519637049319818" },
|
|
12
|
-
"i18n": {
|
|
13
|
-
"zh-CN": {
|
|
14
|
-
"title": "OpenCode Console 遭入侵:请检查你的 API 密钥",
|
|
15
|
-
"message": "OpenCode 于 10 月 17 日报告,其一个旧系统遭到未授权访问,部分用户保存在 OpenCode Console 工作区中的提供商 API 密钥(OpenAI、Anthropic 等)可能已泄露。如果你收到了 OpenCode 的相关邮件,请撤销并更换这些密钥,同时检查近期用量。OpenCode 表示,没有收到邮件的用户不受影响。",
|
|
16
|
-
"label": "查看 OpenCode 公告"
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
]
|
|
21
|
-
}
|
|
1
|
+
{ "notices": [] }
|
|
Binary file
|