@av-pi-studio/web-client 0.0.8
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/.tsbuildinfo +1 -0
- package/dist/web/assets/BinaryFallbackViewer-BVnOJSh_.js +2 -0
- package/dist/web/assets/BinaryFallbackViewer-BVnOJSh_.js.map +1 -0
- package/dist/web/assets/BinaryFallbackViewer-CLiNWU_S.css +1 -0
- package/dist/web/assets/ChatPanel-BOR3MYdN.js +3 -0
- package/dist/web/assets/ChatPanel-BOR3MYdN.js.map +1 -0
- package/dist/web/assets/ChatPanel-DW5U4HRf.css +1 -0
- package/dist/web/assets/CodeView-BJb8T6q4.js +2 -0
- package/dist/web/assets/CodeView-BJb8T6q4.js.map +1 -0
- package/dist/web/assets/CodeView-CLRODhB8.css +1 -0
- package/dist/web/assets/DiffView-B4H-yHuX.js +3 -0
- package/dist/web/assets/DiffView-B4H-yHuX.js.map +1 -0
- package/dist/web/assets/DiffView-CRbeRztO.css +1 -0
- package/dist/web/assets/FilePanel-DIInFr3h.css +1 -0
- package/dist/web/assets/FilePanel-lERDJldp.js +3 -0
- package/dist/web/assets/FilePanel-lERDJldp.js.map +1 -0
- package/dist/web/assets/ImageViewer-Cnr0mhRu.js +2 -0
- package/dist/web/assets/ImageViewer-Cnr0mhRu.js.map +1 -0
- package/dist/web/assets/ImageViewer-ijzMsq8H.css +1 -0
- package/dist/web/assets/MarkdownFileViewer-BD5Ri_Fb.css +1 -0
- package/dist/web/assets/MarkdownFileViewer-CDHJBxdH.js +2 -0
- package/dist/web/assets/MarkdownFileViewer-CDHJBxdH.js.map +1 -0
- package/dist/web/assets/TerminalPanel-BQj62G6N.css +1 -0
- package/dist/web/assets/TerminalPanel-cnkK_YF5.js +2 -0
- package/dist/web/assets/TerminalPanel-cnkK_YF5.js.map +1 -0
- package/dist/web/assets/TextViewer-DWYO-J8z.js +2 -0
- package/dist/web/assets/TextViewer-DWYO-J8z.js.map +1 -0
- package/dist/web/assets/VideoViewer-BBuZ4wou.css +1 -0
- package/dist/web/assets/VideoViewer-D2ZnEQoA.js +2 -0
- package/dist/web/assets/VideoViewer-D2ZnEQoA.js.map +1 -0
- package/dist/web/assets/index-DnTTpAX5.js +3 -0
- package/dist/web/assets/index-DnTTpAX5.js.map +1 -0
- package/dist/web/assets/index-DrGTLQo0.css +1 -0
- package/dist/web/assets/markdown-BQwXm0MF.css +1 -0
- package/dist/web/assets/markdown-Biwdm3dP.js +2 -0
- package/dist/web/assets/markdown-Biwdm3dP.js.map +1 -0
- package/dist/web/assets/use-file-download-BpyWNVxA.js +2 -0
- package/dist/web/assets/use-file-download-BpyWNVxA.js.map +1 -0
- package/dist/web/assets/vendor-BFXtRv5b.js +83 -0
- package/dist/web/assets/vendor-BFXtRv5b.js.map +1 -0
- package/dist/web/assets/vendor-dnd-D9kA7FgH.js +6 -0
- package/dist/web/assets/vendor-dnd-D9kA7FgH.js.map +1 -0
- package/dist/web/assets/vendor-highlight-DaTzDdJW.js +5 -0
- package/dist/web/assets/vendor-highlight-DaTzDdJW.js.map +1 -0
- package/dist/web/assets/vendor-icons-DUloQbkI.js +182 -0
- package/dist/web/assets/vendor-icons-DUloQbkI.js.map +1 -0
- package/dist/web/assets/vendor-markdown-CpaoCv-a.js +36 -0
- package/dist/web/assets/vendor-markdown-CpaoCv-a.js.map +1 -0
- package/dist/web/assets/vendor-overlays-Bo99M0pM.js +2 -0
- package/dist/web/assets/vendor-overlays-Bo99M0pM.js.map +1 -0
- package/dist/web/assets/vendor-query-CAh-Aqig.js +2 -0
- package/dist/web/assets/vendor-query-CAh-Aqig.js.map +1 -0
- package/dist/web/assets/vendor-react-BoIQBqDW.js +50 -0
- package/dist/web/assets/vendor-react-BoIQBqDW.js.map +1 -0
- package/dist/web/assets/vendor-terminal-BhzX2_ts.js +10 -0
- package/dist/web/assets/vendor-terminal-BhzX2_ts.js.map +1 -0
- package/dist/web/assets/vendor-terminal-DYP7pi_n.css +32 -0
- package/dist/web/index.html +21 -0
- package/package.json +56 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
html,body{margin:0;padding:0}body{min-height:100vh;overflow:hidden;background:var(--pi-color-background, #0a0a0a);color:var(--pi-color-foreground, #fafafa);font-family:var(--pi-font-ui, system-ui, sans-serif)}#root{display:flex;flex-direction:column;min-height:100vh}*,*:before,*:after{box-sizing:border-box}::-webkit-scrollbar{width:6px;height:6px}::-webkit-scrollbar-track{background:transparent}::-webkit-scrollbar-thumb{background:var(--pi-color-border, #353b46);border-radius:3px}._btn_1chbg_4{display:inline-flex;align-items:center;justify-content:center;gap:8px;border-radius:var(--pi-radius-lg, 8px);border:1px solid transparent;font-family:var(--pi-font-ui, system-ui, sans-serif);font-weight:500;cursor:pointer;-webkit-user-select:none;user-select:none;white-space:nowrap;text-decoration:none;outline:none;transition:opacity .12s ease,background-color .12s ease,border-color .12s ease;box-sizing:border-box}._btn_1chbg_4:focus-visible{outline:2px solid var(--pi-color-accent, #2e5cb8);outline-offset:2px}._btn_1chbg_4:disabled,._btn_1chbg_4[aria-disabled=true]{cursor:not-allowed;pointer-events:none}._default_1chbg_35{background-color:var(--pi-color-accent, #2e5cb8);color:var(--pi-color-accentForeground, #ffffff);border-color:var(--pi-color-accent, #2e5cb8)}._default_1chbg_35:hover:not(:disabled){filter:brightness(1.08)}._secondary_1chbg_44{background-color:var(--pi-color-surface3, #3f3f46);color:var(--pi-color-foreground, #fafafa);border-color:var(--pi-color-border, #3f3f46)}._secondary_1chbg_44:hover:not(:disabled){background-color:var(--pi-color-surface2, #27272a)}._outline_1chbg_53{background-color:transparent;color:var(--pi-color-accentBright, #a2b4d7);border-color:var(--pi-color-accent, #2e5cb8)}._outline_1chbg_53:hover:not(:disabled){background-color:var(--pi-color-surface1, #18181b)}._ghost_1chbg_62{background-color:transparent;color:var(--pi-color-foregroundMuted, #a1a1aa);border-color:transparent}._ghost_1chbg_62:hover:not(:disabled){color:var(--pi-color-foreground, #fafafa);background-color:var(--pi-color-surface1, #18181b)}._destructive_1chbg_72{background-color:var(--pi-color-destructive, #991b1b);color:var(--pi-color-destructiveForeground, #fef2f2);border-color:var(--pi-color-destructive, #991b1b)}._destructive_1chbg_72:hover:not(:disabled){filter:brightness(1.1)}._iconOnly_1chbg_82{padding-left:0!important;padding-right:0!important;aspect-ratio:1}._loadingSpinner_1chbg_89{animation:_piSpin_1chbg_1 .75s linear infinite;flex-shrink:0}@keyframes _piSpin_1chbg_1{0%{transform:rotate(0)}to{transform:rotate(360deg)}}._input_a7qyq_3{width:100%;padding:8px 12px;border-radius:var(--pi-radius-md, 6px);border:1px solid var(--pi-color-border, #3f3f46);background-color:var(--pi-color-surface2, #27272a);color:var(--pi-color-foreground, #fafafa);font-size:var(--pi-font-size-base, 16px);font-family:var(--pi-font-ui, system-ui, sans-serif);outline:none;transition:border-color .12s ease;box-sizing:border-box}._input_a7qyq_3::placeholder{color:var(--pi-color-foregroundMuted, #a1a1aa)}._input_a7qyq_3:focus{border-color:var(--pi-color-accent, #2e5cb8);outline:2px solid var(--pi-color-accent, #2e5cb8);outline-offset:-1px}._input_a7qyq_3:disabled{opacity:.5;cursor:not-allowed}._textarea_a7qyq_32{resize:vertical;min-height:80px}._wrap_emmus_1{display:inline-flex;align-items:center;gap:6px;font-size:12px;color:var(--pi-color-foregroundMuted, #9aa0a6)}._dot_emmus_8{width:8px;height:8px;border-radius:50%;background:var(--pi-color-foregroundMuted, #9aa0a6);flex-shrink:0}._dot_emmus_8._open_emmus_15{background:var(--pi-color-statusSuccess, #3ecf8e)}._dot_emmus_8._connecting_emmus_18{background:var(--pi-color-statusWarning, #e0a030)}._dot_emmus_8._closed_emmus_21,._dot_emmus_8._idle_emmus_22,._dot_emmus_8._closing_emmus_23{background:var(--pi-color-statusDanger, #e5484d)}._toolbar_12zzc_1{display:flex;align-items:center;gap:10px;padding:6px 10px;border-bottom:1px solid var(--pi-color-border, #353b46);background:var(--pi-color-surface, #16181a);flex-shrink:0}._brand_12zzc_10{font-weight:600;font-size:13px;letter-spacing:.02em;white-space:nowrap}._sep_12zzc_16{width:1px;height:18px;background:var(--pi-color-border, #353b46);flex-shrink:0}._host_12zzc_22{width:190px}._password_12zzc_25{width:100px}._sidebarToggles_12zzc_28{display:flex;align-items:center;gap:4px;margin-left:auto}._dot_202py_3{display:inline-block;width:8px;height:8px;border-radius:9999px;flex-shrink:0}._wrap_sqws5_1{display:flex;flex-direction:column;min-height:0;height:100%}._header_sqws5_7{display:flex;align-items:center;justify-content:space-between;padding:8px 10px;border-bottom:1px solid var(--pi-color-border, #353b46);flex-shrink:0}._header_sqws5_7 h3{margin:0;font-size:12px;font-weight:600;color:var(--pi-color-foregroundMuted, #9aa0a6);text-transform:uppercase;letter-spacing:.04em}._list_sqws5_23{flex:1 1 auto;overflow-y:auto;min-height:0}._item_sqws5_28{position:relative;padding:8px 10px;cursor:pointer;border-bottom:1px solid transparent}._item_sqws5_28:hover{background:var(--pi-color-surfaceHover, #1e2124)}._item_sqws5_28._active_sqws5_37{background:var(--pi-color-surfaceSunken, #111)}._title_sqws5_40{display:flex;align-items:center;gap:6px;font-size:13px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}._meta_sqws5_49{margin-top:2px;font-size:11px;color:var(--pi-color-foregroundMuted, #9aa0a6);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}._menuBtn_sqws5_57{position:absolute;top:6px;right:6px;opacity:0;padding:2px 4px;background:none;border:none;border-radius:4px;cursor:pointer;color:var(--pi-color-foregroundMuted, #9aa0a6)}._item_sqws5_28:hover ._menuBtn_sqws5_57{opacity:1}._menuBtn_sqws5_57:hover{background:var(--pi-color-surfaceHover, #1e2124)}._workspaceGroup_sqws5_75{border-bottom:1px solid var(--pi-color-border, #353b46)}._workspaceHeader_sqws5_78{display:flex;align-items:center;gap:6px;padding:7px 10px;cursor:pointer;font-size:12px;font-weight:600;color:var(--pi-color-foreground, #e6e6e6)}._workspaceHeader_sqws5_78:hover{background:var(--pi-color-surfaceHover, #1e2124)}._workspaceChevron_sqws5_91{display:flex;align-items:center;justify-content:center;padding:0;background:none;border:none;cursor:pointer;color:var(--pi-color-foregroundMuted, #9aa0a6);flex-shrink:0}._workspaceIcon_sqws5_102{color:var(--pi-color-foregroundMuted, #9aa0a6);flex-shrink:0}._workspaceLabel_sqws5_106{flex:1 1 auto;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}._workspaceCount_sqws5_112{font-size:11px;font-weight:400;color:var(--pi-color-foregroundMuted, #9aa0a6)}._newSessionBtn_sqws5_117{flex-shrink:0;opacity:0;color:var(--pi-color-foregroundMuted, #9aa0a6)}._workspaceHeader_sqws5_78:hover ._newSessionBtn_sqws5_117{opacity:1}._newSessionBtn_sqws5_117:hover{background:var(--pi-color-surfaceHover, #1e2124);color:var(--pi-color-foreground, #e6e6e6)}._workspaceSessions_sqws5_129{padding-left:12px}._trigger_16o4s_1{position:fixed;width:1px;height:1px;pointer-events:none}._content_16o4s_7{min-width:160px;padding:4px;border-radius:var(--pi-borderRadius-md, 6px);background:var(--pi-color-surface, #16181a);border:1px solid var(--pi-color-border, #353b46);box-shadow:0 8px 24px #0006;z-index:1000}._item_16o4s_16{display:flex;align-items:center;padding:6px 10px;border-radius:4px;font-size:13px;cursor:pointer;outline:none}._item_16o4s_16:hover,._item_16o4s_16[data-highlighted]{background:var(--pi-color-surfaceHover, #1e2124)}._item_16o4s_16[data-disabled]{opacity:.4;cursor:default}._danger_16o4s_33{color:var(--pi-color-statusDanger, #e5484d)}._sep_16o4s_36{height:1px;margin:4px 0;background:var(--pi-color-border, #353b46)}._strip_cnwks_1{display:flex;align-items:center;gap:2px;padding:4px 6px 0;overflow-x:auto;flex-shrink:0;border-bottom:1px solid var(--pi-color-border, #353b46)}._tab_cnwks_10{display:flex;align-items:center;gap:6px;padding:6px 8px;border-radius:var(--pi-borderRadius-md, 6px) var(--pi-borderRadius-md, 6px) 0 0;font-size:12px;cursor:pointer;color:var(--pi-color-foregroundMuted, #9aa0a6);white-space:nowrap;flex-shrink:0;-webkit-user-select:none;user-select:none}._tab_cnwks_10:hover{background:var(--pi-color-surfaceHover, #1e2124)}._active_cnwks_26{background:var(--pi-color-surfaceSunken, #111);color:var(--pi-color-foreground, #fafafa)}._icon_cnwks_30{display:flex;align-items:center;flex-shrink:0}._label_cnwks_35{max-width:160px;overflow:hidden;text-overflow:ellipsis}._close_cnwks_40{display:flex;align-items:center;border-radius:3px;padding:1px;flex-shrink:0}._close_cnwks_40:hover{background:var(--pi-color-surfaceHover, #1e2124)}._spinner_1tgzp_3{display:inline-block;border-radius:9999px;border-style:solid;border-color:currentColor transparent transparent transparent;animation:_piSpinnerRotate_1tgzp_1 .7s linear infinite;flex-shrink:0}@keyframes _piSpinnerRotate_1tgzp_1{0%{transform:rotate(0)}to{transform:rotate(360deg)}}._area_1vzxd_1{position:relative;flex:1 1 auto;min-height:0;overflow:hidden}._panel_1vzxd_7{position:absolute;top:0;right:0;bottom:0;left:0;display:none;flex-direction:column;min-height:0}._active_1vzxd_14{display:flex}._empty_1vzxd_17{display:flex;align-items:center;justify-content:center;height:100%;color:var(--pi-color-foregroundMuted, #9aa0a6);font-size:13px}._list_1o67b_1{padding:4px 0}._upRow_1o67b_4{padding:4px 8px;font-size:11px;color:var(--pi-color-foregroundMuted, #9aa0a6);border-bottom:1px solid var(--pi-color-border, #353b46);margin-bottom:4px;cursor:pointer;display:flex;align-items:center;gap:6px;overflow:hidden}._upRow_1o67b_4 span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}._upRow_1o67b_4:hover{background:var(--pi-color-surfaceHover, #1e2124)}._item_1o67b_24{padding:4px 8px;font-size:12px;border-radius:3px;cursor:pointer;display:flex;align-items:center;gap:6px}._item_1o67b_24:hover{background:var(--pi-color-surfaceHover, #1e2124)}._icon_1o67b_36{display:flex;align-items:center;width:16px;flex-shrink:0;color:var(--pi-color-foregroundMuted, #9aa0a6)}._name_1o67b_43{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}._dirName_1o67b_48{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:var(--pi-color-accentBright, #a2b4d7)}._emptyState_1o67b_54{color:var(--pi-color-foregroundMuted, #9aa0a6);font-size:12px;text-align:center;padding:20px}._list_1pgby_1{padding:4px 0}._summary_1pgby_4{padding:4px 8px;font-size:11px;color:var(--pi-color-foregroundMuted, #9aa0a6);border-bottom:1px solid var(--pi-color-border, #353b46);margin-bottom:4px}._item_1pgby_11{padding:4px 8px;font-size:12px;border-radius:3px;cursor:pointer;display:flex;align-items:center;gap:6px}._item_1pgby_11:hover{background:var(--pi-color-surfaceHover, #1e2124)}._badge_1pgby_23{font-size:10px;padding:0 4px;border-radius:3px;font-weight:600;flex-shrink:0}._added_1pgby_30{background:color-mix(in srgb,var(--pi-color-statusSuccess, #4ade80) 20%,transparent);color:var(--pi-color-statusSuccess, #4ade80)}._modified_1pgby_34{background:color-mix(in srgb,var(--pi-color-statusWarning, #facc15) 20%,transparent);color:var(--pi-color-statusWarning, #facc15)}._deleted_1pgby_38{background:color-mix(in srgb,var(--pi-color-statusDanger, #ff8a80) 20%,transparent);color:var(--pi-color-statusDanger, #ff8a80)}._name_1pgby_42{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}._emptyState_1pgby_47{color:var(--pi-color-foregroundMuted, #9aa0a6);font-size:12px;text-align:center;padding:20px}._wrap_sx7p7_1{display:flex;flex-direction:column}._newTerminal_sx7p7_5{margin:6px 8px;justify-content:flex-start}._list_sx7p7_10{padding:4px 0}._summary_sx7p7_13{padding:4px 8px;font-size:11px;color:var(--pi-color-foregroundMuted, #9aa0a6);border-bottom:1px solid var(--pi-color-border, #353b46);margin-bottom:4px}._item_sx7p7_20{display:flex;align-items:center;gap:4px;padding-right:4px;border-radius:3px}._item_sx7p7_20:hover{background:var(--pi-color-surfaceHover, #1e2124)}._reattach_sx7p7_30{flex:1;min-width:0;display:flex;align-items:center;gap:6px;padding:4px 8px;font:inherit;font-size:12px;background:none;border:none;color:var(--pi-color-foreground, #fafafa);cursor:pointer;text-align:left}._icon_sx7p7_45{flex-shrink:0;color:var(--pi-color-foregroundMuted, #9aa0a6)}._name_sx7p7_49{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}._openBadge_sx7p7_54{flex-shrink:0;font-size:10px;padding:0 4px;border-radius:3px;color:var(--pi-color-statusSuccess, #4ade80);background:color-mix(in srgb,var(--pi-color-statusSuccess, #4ade80) 20%,transparent)}._kill_sx7p7_62{flex-shrink:0;display:flex;align-items:center;justify-content:center;width:20px;height:20px;padding:0;background:none;border:none;border-radius:3px;color:var(--pi-color-foregroundMuted, #9aa0a6);cursor:pointer}._kill_sx7p7_62:hover{color:var(--pi-color-statusDanger, #ff8a80);background:color-mix(in srgb,var(--pi-color-statusDanger, #ff8a80) 15%,transparent)}._emptyState_sx7p7_80{color:var(--pi-color-foregroundMuted, #9aa0a6);font-size:12px;text-align:center;padding:20px}._wrap_r37ok_1{display:flex;flex-direction:column;height:100%;min-height:0}._tabBar_r37ok_7{display:flex;align-items:center;border-bottom:1px solid var(--pi-color-border, #353b46);flex-shrink:0}._tabBtn_r37ok_13{font:inherit;font-size:12px;padding:8px 12px;background:none;border:none;color:var(--pi-color-foregroundMuted, #9aa0a6);cursor:pointer;border-bottom:2px solid transparent}._tabBtn_r37ok_13:hover{color:var(--pi-color-foreground, #fafafa)}._active_r37ok_26{color:var(--pi-color-foreground, #fafafa);border-bottom-color:var(--pi-color-accent, #2e5cb8)}._refreshBtn_r37ok_30{margin-left:auto;margin-right:6px}._content_r37ok_34{flex:1;overflow-y:auto;padding:8px;min-height:0}._wrapper_131x2_3{display:inline-flex;align-items:center;gap:8px;cursor:pointer;font-family:var(--pi-font-ui, system-ui);font-size:var(--pi-font-size-sm, 14px);color:var(--pi-color-foreground, #fafafa)}._wrapper_131x2_3[data-disabled=true]{opacity:.5;pointer-events:none}._box_131x2_18{width:16px;height:16px;border-radius:var(--pi-radius-sm, 3px);border:1.5px solid var(--pi-color-border, #3f3f46);background-color:transparent;display:flex;align-items:center;justify-content:center;transition:background-color .1s,border-color .1s;flex-shrink:0}._box_131x2_18[data-checked=true]{background-color:var(--pi-color-accent, #2e5cb8);border-color:var(--pi-color-accent, #2e5cb8)}._checkmark_131x2_36{color:var(--pi-color-accentForeground, #ffffff)}._nativeInput_131x2_41{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}._select_vj45v_3{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:var(--pi-color-surface1, #18181b);border:1px solid var(--pi-color-border, #3f3f46);border-radius:var(--pi-radius-base, 4px);padding:8px 32px 8px 10px;font-family:var(--pi-font-ui, system-ui);font-size:var(--pi-font-size-sm, 14px);color:var(--pi-color-foreground, #fafafa);width:100%;outline:none;transition:border-color .1s;cursor:pointer;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='%23a1a1aa' viewBox='0 0 24 24'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 10px center}._select_vj45v_3:focus{border-color:var(--pi-color-accent, #2e5cb8)}._select_vj45v_3:disabled{opacity:.5;cursor:not-allowed}._comboboxWrapper_vj45v_31{position:relative;width:100%}._comboboxInput_vj45v_36{width:100%;background-color:var(--pi-color-surface1, #18181b);border:1px solid var(--pi-color-border, #3f3f46);border-radius:var(--pi-radius-base, 4px);padding:8px 10px;font-family:var(--pi-font-ui, system-ui);font-size:var(--pi-font-size-sm, 14px);color:var(--pi-color-foreground, #fafafa);outline:none;box-sizing:border-box}._comboboxInput_vj45v_36:focus{border-color:var(--pi-color-accent, #2e5cb8)}._comboboxList_vj45v_53{position:absolute;top:100%;left:0;right:0;z-index:80;max-height:200px;overflow-y:auto;background-color:var(--pi-color-surface1, #18181b);border:1px solid var(--pi-color-border, #3f3f46);border-radius:var(--pi-radius-base, 4px);margin-top:4px;padding:4px;box-shadow:var(--pi-shadow-md, 0 4px 12px rgba(0,0,0,.4))}._comboboxOption_vj45v_69{padding:6px 8px;border-radius:var(--pi-radius-sm, 3px);font-size:var(--pi-font-size-sm, 14px);font-family:var(--pi-font-ui, system-ui);color:var(--pi-color-foreground, #fafafa);cursor:pointer;background:none;border:none;width:100%;text-align:left}._comboboxOption_vj45v_69:hover,._comboboxOptionHighlighted_vj45v_82{background-color:var(--pi-color-surface2, #27272a)}._overlay_1yaef_1{position:fixed;top:0;right:0;bottom:0;left:0;background:#0009;z-index:100}._contentWrapper_1yaef_7{position:fixed;top:0;right:0;bottom:0;left:0;z-index:101;display:flex;align-items:center;justify-content:center;pointer-events:none}._dialog_1yaef_16{pointer-events:auto;width:500px;max-width:90vw;max-height:70vh;background:var(--pi-color-surface, #16181a);border:1px solid var(--pi-color-border, #353b46);border-radius:var(--pi-radius-lg, 8px);display:flex;flex-direction:column;box-shadow:0 8px 32px #00000080}._header_1yaef_28{padding:12px 14px;border-bottom:1px solid var(--pi-color-border, #353b46);display:flex;align-items:center;gap:8px;flex-shrink:0}._title_1yaef_36{font-size:13px;margin:0;flex:1;color:var(--pi-color-foreground, #fafafa);font-weight:600}._closeBtn_1yaef_43{display:flex;align-items:center;background:none;border:none;color:var(--pi-color-foregroundMuted, #9aa0a6);cursor:pointer;padding:4px;border-radius:4px}._closeBtn_1yaef_43:hover{background:var(--pi-color-surfaceHover, #1e2124);color:var(--pi-color-foreground, #fafafa)}._body_1yaef_57{flex:1;display:flex;flex-direction:column;min-height:0}._footer_1yaef_63{padding:10px 14px;border-top:1px solid var(--pi-color-border, #353b46);display:flex;align-items:center;gap:8px;justify-content:flex-end;flex-shrink:0}._bare_1yaef_72{border:none;background:transparent;box-shadow:none;position:relative}._bareBody_1yaef_78{border-radius:var(--pi-radius-lg, 8px);overflow:hidden}._bareCloseBtn_1yaef_82{position:absolute;top:-12px;right:-12px;display:flex;align-items:center;justify-content:center;width:28px;height:28px;background:var(--pi-color-surface, #16181a);border:1px solid var(--pi-color-border, #353b46);border-radius:50%;color:var(--pi-color-foregroundMuted, #9aa0a6);cursor:pointer}._bareCloseBtn_1yaef_82:hover{background:var(--pi-color-surfaceHover, #1e2124);color:var(--pi-color-foreground, #fafafa)}._visuallyHidden_1yaef_101{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap}._handle_1ocv1_1{position:absolute;top:0;bottom:0;width:5px;cursor:col-resize;z-index:5;background:transparent;transition:background .12s ease}._handle_1ocv1_1:hover,._handle_1ocv1_1:active{background:var(--pi-color-accent, #2e5cb8)}._pathRow_9xphl_1{padding:8px 14px;display:flex;align-items:center;gap:6px;border-bottom:1px solid var(--pi-color-border, #353b46);flex-shrink:0}._pathInput_9xphl_9{flex:1;font-size:12px}._list_9xphl_13{flex:1;overflow-y:auto;padding:4px 0;min-height:200px;max-height:400px}._item_9xphl_20{padding:6px 14px;cursor:pointer;display:flex;align-items:center;gap:8px;font-size:12px;color:var(--pi-color-foreground, #fafafa)}._item_9xphl_20:hover{background:var(--pi-color-surfaceHover, #1e2124)}._name_9xphl_32{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}._emptyState_9xphl_37{color:var(--pi-color-foregroundMuted, #9aa0a6);font-size:12px;text-align:center;padding:20px}._shell_1m1nv_1{display:flex;flex-direction:column;height:100vh;min-height:0}._main_1m1nv_7{display:flex;flex:1 1 auto;min-height:0;overflow:hidden}._sidebarLeft_1m1nv_13{position:relative;flex-shrink:0;border-right:1px solid var(--pi-color-border, #353b46);display:flex;flex-direction:column;min-width:0}._leftHandle_1m1nv_21{right:-3px}._center_1m1nv_24{flex:1 1 auto;display:flex;flex-direction:column;min-width:0;min-height:0}._sidebarRight_1m1nv_31{position:relative;flex-shrink:0;border-left:1px solid var(--pi-color-border, #353b46);display:flex;flex-direction:column;min-width:0}._rightHandle_1m1nv_39{left:-3px}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
._prose_1ovsl_1{font-size:var(--pi-fontSize-base, 14px);line-height:1.5;color:var(--pi-color-foreground, #fafafa);word-break:break-word}._prose_1ovsl_1>:first-child{margin-top:0}._prose_1ovsl_1>:last-child{margin-bottom:0}._prose_1ovsl_1 p{margin:.5em 0}._prose_1ovsl_1 a{color:var(--pi-color-accentBright, #a2b4d7)}._prose_1ovsl_1 pre{margin:.5em 0;padding:10px 12px;border-radius:var(--pi-borderRadius-md, 6px);overflow-x:auto;background:var(--pi-color-surfaceSunken, #111)}._prose_1ovsl_1 pre code{font-family:var(--pi-font-mono, ui-monospace, monospace);font-size:var(--pi-fontSize-code, 13px);background:none;padding:0}._inlineCode_1ovsl_32{font-family:var(--pi-font-mono, ui-monospace, monospace);font-size:.9em;background:var(--pi-color-surfaceSunken, #111);border-radius:3px;padding:.1em .35em}._prose_1ovsl_1 table{border-collapse:collapse;margin:.5em 0}._prose_1ovsl_1 th,._prose_1ovsl_1 td{border:1px solid var(--pi-color-border, #353b46);padding:4px 8px}._prose_1ovsl_1 blockquote{margin:.5em 0;padding-left:10px;border-left:2px solid var(--pi-color-border, #353b46);color:var(--pi-color-foregroundMuted, #9aa0a6)}._prose_1ovsl_1 ul,._prose_1ovsl_1 ol{padding-left:1.4em}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{r as l,j as o}from"./vendor-react-BoIQBqDW.js";import{c as h}from"./vendor-highlight-DaTzDdJW.js";import{M as m,r as g}from"./vendor-markdown-CpaoCv-a.js";const d="github-dark";let a=null;const u=new Set(["plaintext"]);function f(){return a||(a=h({themes:[d],langs:["plaintext"]})),a}async function p(t,e){if(u.has(e))return e;try{return await t.loadLanguage(e),u.add(e),e}catch{return"plaintext"}}async function x(t,e){const n=await f(),r=await p(n,e);return n.codeToHtml(t,{lang:r,theme:d})}const j="_prose_1ovsl_1",k="_inlineCode_1ovsl_32",c={prose:j,inlineCode:k};function w({language:t,code:e}){const[n,r]=l.useState(null);return l.useEffect(()=>{let s=!1;return x(e,t).then(i=>{s||r(i)}),()=>{s=!0}},[e,t]),n?o.jsx("div",{className:c.prose,dangerouslySetInnerHTML:{__html:n}}):o.jsx("pre",{children:o.jsx("code",{children:e})})}function _({className:t,children:e,...n}){const r=/language-(\w+)/.exec(t??""),s=!!r,i=String(e).replace(/\n$/,"");return s&&r?o.jsx(w,{language:r[1]??"plaintext",code:i}):o.jsx("code",{className:c.inlineCode,...n,children:e})}const C=l.memo(function({text:e}){return o.jsx("div",{className:c.prose,children:o.jsx(m,{remarkPlugins:[g],components:{code:_},children:e})})});export{C as M};
|
|
2
|
+
//# sourceMappingURL=markdown-Biwdm3dP.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdown-Biwdm3dP.js","sources":["../../../src/timeline/highlight.ts","../../../src/timeline/markdown.tsx"],"sourcesContent":["/**\n * Shiki wrapper + lang-from-path map. Replaces the POC's CDN `highlight.js`\n * (POC_TO_APP_PLAN_UI.md §2, §4.8). Grammars/themes are loaded lazily and cached — the\n * highlighter is not paid for until a code block/file view actually renders.\n */\n\nimport { createHighlighter, type Highlighter } from \"shiki\";\n\n/** POC `getLangFromPath` extension → language map, ported verbatim. */\nconst EXT_TO_LANG: Record<string, string> = {\n js: \"javascript\",\n ts: \"typescript\",\n jsx: \"javascript\",\n tsx: \"typescript\",\n py: \"python\",\n rb: \"ruby\",\n rs: \"rust\",\n go: \"go\",\n java: \"java\",\n c: \"c\",\n cpp: \"cpp\",\n h: \"c\",\n hpp: \"cpp\",\n cs: \"csharp\",\n html: \"html\",\n css: \"css\",\n scss: \"scss\",\n json: \"json\",\n yaml: \"yaml\",\n yml: \"yaml\",\n toml: \"toml\",\n xml: \"xml\",\n md: \"markdown\",\n sh: \"bash\",\n bash: \"bash\",\n sql: \"sql\",\n swift: \"swift\",\n kt: \"kotlin\",\n dart: \"dart\",\n vue: \"xml\",\n svelte: \"xml\",\n};\n\nexport function langFromPath(path: string): string {\n const ext = path.split(\".\").pop()?.toLowerCase() ?? \"\";\n return EXT_TO_LANG[ext] ?? \"plaintext\";\n}\n\nconst THEME = \"github-dark\";\n\nlet highlighterPromise: Promise<Highlighter> | null = null;\nconst loadedLangs = new Set<string>([\"plaintext\"]);\n\nfunction getHighlighter(): Promise<Highlighter> {\n if (!highlighterPromise) {\n highlighterPromise = createHighlighter({ themes: [THEME], langs: [\"plaintext\"] });\n }\n return highlighterPromise;\n}\n\nasync function ensureLang(highlighter: Highlighter, lang: string): Promise<string> {\n if (loadedLangs.has(lang)) return lang;\n try {\n await highlighter.loadLanguage(lang as never);\n loadedLangs.add(lang);\n return lang;\n } catch {\n return \"plaintext\"; // unknown grammar to Shiki — fall back rather than throw\n }\n}\n\n/** Highlight `code` for `lang` (or a path via `langFromPath`) to sanitized HTML. */\nexport async function highlightToHtml(code: string, lang: string): Promise<string> {\n const highlighter = await getHighlighter();\n const resolved = await ensureLang(highlighter, lang);\n return highlighter.codeToHtml(code, { lang: resolved, theme: THEME });\n}\n","/**\n * react-markdown + remark-gfm rendering, replacing the POC's CDN `marked` + `innerHTML`\n * (POC_TO_APP_PLAN_UI.md §4.8). Sanitized by default — react-markdown never injects raw HTML.\n * Fenced code blocks highlight asynchronously via Shiki (`highlight.ts`).\n */\n\nimport { memo, useEffect, useState, type ComponentPropsWithoutRef } from \"react\";\nimport ReactMarkdown from \"react-markdown\";\nimport remarkGfm from \"remark-gfm\";\nimport { highlightToHtml } from \"./highlight.js\";\nimport styles from \"./markdown.module.css\";\n\ninterface CodeBlockProps {\n language: string;\n code: string;\n}\n\nfunction CodeBlock({ language, code }: CodeBlockProps) {\n const [html, setHtml] = useState<string | null>(null);\n\n useEffect(() => {\n let cancelled = false;\n void highlightToHtml(code, language).then((result) => {\n if (!cancelled) setHtml(result);\n });\n return () => {\n cancelled = true;\n };\n }, [code, language]);\n\n if (html) {\n // Shiki's output is generated HTML from a trusted local highlighter (no user HTML is ever\n // injected) — the only risk is `code`, which Shiki escapes internally before tokenizing.\n return <div className={styles.prose} dangerouslySetInnerHTML={{ __html: html }} />;\n }\n return (\n <pre>\n <code>{code}</code>\n </pre>\n );\n}\n\ntype MarkdownCodeProps = ComponentPropsWithoutRef<\"code\"> & { className?: string };\n\nfunction CodeRenderer({ className, children, ...rest }: MarkdownCodeProps) {\n const match = /language-(\\w+)/.exec(className ?? \"\");\n const isBlock = Boolean(match);\n const code = String(children).replace(/\\n$/, \"\");\n if (isBlock && match) {\n return <CodeBlock language={match[1] ?? \"plaintext\"} code={code} />;\n }\n return (\n <code className={styles.inlineCode} {...rest}>\n {children}\n </code>\n );\n}\n\nexport interface MarkdownProps {\n text: string;\n}\n\n/** Renders assistant/tool markdown text. Memoized — text is immutable once a turn finalizes. */\nexport const Markdown = memo(function Markdown({ text }: MarkdownProps) {\n return (\n <div className={styles.prose}>\n <ReactMarkdown remarkPlugins={[remarkGfm]} components={{ code: CodeRenderer }}>\n {text}\n </ReactMarkdown>\n </div>\n );\n});\n"],"names":["THEME","highlighterPromise","loadedLangs","getHighlighter","createHighlighter","ensureLang","highlighter","lang","highlightToHtml","code","resolved","CodeBlock","language","html","setHtml","useState","useEffect","cancelled","result","jsx","styles","CodeRenderer","className","children","rest","match","isBlock","Markdown","memo","text","ReactMarkdown","remarkGfm"],"mappings":"kKAgDA,MAAMA,EAAQ,cAEd,IAAIC,EAAkD,KACtD,MAAMC,EAAc,IAAI,IAAY,CAAC,WAAW,CAAC,EAEjD,SAASC,GAAuC,CAC9C,OAAKF,IACHA,EAAqBG,EAAkB,CAAE,OAAQ,CAACJ,CAAK,EAAG,MAAO,CAAC,WAAW,EAAG,GAE3EC,CACT,CAEA,eAAeI,EAAWC,EAA0BC,EAA+B,CACjF,GAAIL,EAAY,IAAIK,CAAI,EAAG,OAAOA,EAClC,GAAI,CACF,aAAMD,EAAY,aAAaC,CAAa,EAC5CL,EAAY,IAAIK,CAAI,EACbA,CACT,MAAQ,CACN,MAAO,WACT,CACF,CAGA,eAAsBC,EAAgBC,EAAcF,EAA+B,CACjF,MAAMD,EAAc,MAAMH,EAAA,EACpBO,EAAW,MAAML,EAAWC,EAAaC,CAAI,EACnD,OAAOD,EAAY,WAAWG,EAAM,CAAE,KAAMC,EAAU,MAAOV,EAAO,CACtE,4EC3DA,SAASW,EAAU,CAAE,SAAAC,EAAU,KAAAH,GAAwB,CACrD,KAAM,CAACI,EAAMC,CAAO,EAAIC,EAAAA,SAAwB,IAAI,EAYpD,OAVAC,EAAAA,UAAU,IAAM,CACd,IAAIC,EAAY,GAChB,OAAKT,EAAgBC,EAAMG,CAAQ,EAAE,KAAMM,GAAW,CAC/CD,GAAWH,EAAQI,CAAM,CAChC,CAAC,EACM,IAAM,CACXD,EAAY,EACd,CACF,EAAG,CAACR,EAAMG,CAAQ,CAAC,EAEfC,EAGKM,MAAC,OAAI,UAAWC,EAAO,MAAO,wBAAyB,CAAE,OAAQP,CAAA,EAAQ,EAGhFM,EAAAA,IAAC,MAAA,CACC,SAAAA,EAAAA,IAAC,OAAA,CAAM,WAAK,EACd,CAEJ,CAIA,SAASE,EAAa,CAAE,UAAAC,EAAW,SAAAC,EAAU,GAAGC,GAA2B,CACzE,MAAMC,EAAQ,iBAAiB,KAAKH,GAAa,EAAE,EAC7CI,EAAU,EAAQD,EAClBhB,EAAO,OAAOc,CAAQ,EAAE,QAAQ,MAAO,EAAE,EAC/C,OAAIG,GAAWD,QACLd,EAAA,CAAU,SAAUc,EAAM,CAAC,GAAK,YAAa,KAAAhB,EAAY,QAGhE,OAAA,CAAK,UAAWW,EAAO,WAAa,GAAGI,EACrC,SAAAD,EACH,CAEJ,CAOO,MAAMI,EAAWC,EAAAA,KAAK,SAAkB,CAAE,KAAAC,GAAuB,CACtE,aACG,MAAA,CAAI,UAAWT,EAAO,MACrB,eAACU,EAAA,CAAc,cAAe,CAACC,CAAS,EAAG,WAAY,CAAE,KAAMV,CAAA,EAC5D,WACH,EACF,CAEJ,CAAC"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
var m=Object.defineProperty;var p=(n,e,t)=>e in n?m(n,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):n[e]=t;var l=(n,e,t)=>p(n,typeof e!="symbol"?e+"":e,t);import{r as u}from"./vendor-react-BoIQBqDW.js";import{u as h}from"./vendor-query-CAh-Aqig.js";import{a as d,r as w}from"./index-DnTTpAX5.js";import"./vendor-BFXtRv5b.js";function y(n){const e=n.reduce((i,s)=>i+s.length,0),t=new Uint8Array(e);let o=0;for(const i of n)t.set(i,o),o+=i.length;return t}class g{constructor(e){l(this,"pending",new Map);l(this,"nextStream",1);l(this,"detach",null);this.daemon=e}start(){this.detach||(this.detach=this.daemon.onFileTransferFrame(e=>this.dispatch(e)))}stop(){var e;(e=this.detach)==null||e.call(this),this.detach=null;for(const[t,o]of this.pending)o.reject(new Error("file transfer router stopped")),this.pending.delete(t)}async download(e){const t=await this.daemon.request("file_download_token_request",{path:e});if(!t.ok||!t.token)throw new Error(t.error??"failed to issue download token");const o=this.nextStream++,i=new Promise((a,r)=>{this.pending.set(o,{chunks:[],meta:{},resolve:a,reject:r})}),s=await this.daemon.request("file_download_request",{token:t.token,stream:o});if(!s.ok)throw this.pending.delete(o),new Error(s.error??"download request failed");return i}dispatch(e){const t=this.pending.get(e.stream);if(t)switch(e.opcode){case"Begin":t.meta.fileName=e.meta.fileName,t.meta.mimeType=e.meta.mimeType;return;case"Chunk":t.chunks.push(e.data);return;case"End":this.pending.delete(e.stream),e.ok?t.resolve({bytes:y(t.chunks),...t.meta}):t.reject(new Error("download failed"));return;case"Error":this.pending.delete(e.stream),t.reject(new Error(e.message));return}}}const f=new WeakMap;function k(n){let e=f.get(n);return e||(e=new g(n),e.start(),f.set(n,e)),e}function q(n,e=!0){var a;const t=d(r=>r.client),o=d(r=>r.daemon),i=h({queryKey:w.fileDownload(n),queryFn:async()=>{if(!t||!o)throw new Error("not connected");const r=await k(o).download(n),c=new Blob([Uint8Array.from(r.bytes)],{type:r.mimeType||"application/octet-stream"});return{objectUrl:URL.createObjectURL(c),mimeType:r.mimeType,fileName:r.fileName}},enabled:!!t&&!!o&&!!n&&e,staleTime:1/0,gcTime:0}),s=u.useRef(null);return u.useEffect(()=>{var c;const r=((c=i.data)==null?void 0:c.objectUrl)??null;r&&s.current&&s.current!==r&&URL.revokeObjectURL(s.current),s.current=r},[(a=i.data)==null?void 0:a.objectUrl]),u.useEffect(()=>()=>{s.current&&URL.revokeObjectURL(s.current)},[]),i}export{q as u};
|
|
2
|
+
//# sourceMappingURL=use-file-download-BpyWNVxA.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-file-download-BpyWNVxA.js","sources":["../../../../client/src/file-transfer-client.ts","../../../src/hooks/use-file-download.ts"],"sourcesContent":["import { type FileTransferFrame } from \"@av-pi-studio/protocol\";\n\nimport type { DaemonClient } from \"./daemon-client.js\";\n\n/**\n * Client-side demux + assembly for binary file downloads (features/file-explorer-transfer.md\n * § Binary transfer frames). Mirrors `TerminalStreamRouter`'s inbound-frame-routing shape, but a\n * download is a one-shot request/response rather than a persistent per-slot subscription: request\n * a token, request the download, await the assembled bytes.\n */\n\nexport interface DownloadedFile {\n bytes: Uint8Array;\n fileName?: string;\n mimeType?: string;\n}\n\ninterface PendingDownload {\n chunks: Uint8Array[];\n meta: { fileName?: string; mimeType?: string };\n resolve: (file: DownloadedFile) => void;\n reject: (error: Error) => void;\n}\n\ninterface TokenResponse {\n ok: boolean;\n token?: string;\n error?: string;\n}\n\ninterface DownloadRequestResponse {\n ok: boolean;\n error?: string;\n}\n\nfunction concat(chunks: Uint8Array[]): Uint8Array {\n const total = chunks.reduce((sum, c) => sum + c.length, 0);\n const out = new Uint8Array(total);\n let offset = 0;\n for (const chunk of chunks) {\n out.set(chunk, offset);\n offset += chunk.length;\n }\n return out;\n}\n\nexport class FileTransferClient {\n private readonly pending = new Map<number, PendingDownload>();\n private nextStream = 1;\n private detach: (() => void) | null = null;\n\n constructor(private readonly daemon: DaemonClient) {}\n\n /** Begin routing inbound file-transfer frames. Idempotent. */\n start(): void {\n if (this.detach) return;\n this.detach = this.daemon.onFileTransferFrame((frame) => this.dispatch(frame));\n }\n\n /** Stop routing inbound frames. Any downloads still pending are rejected. */\n stop(): void {\n this.detach?.();\n this.detach = null;\n for (const [stream, pending] of this.pending) {\n pending.reject(new Error(\"file transfer router stopped\"));\n this.pending.delete(stream);\n }\n }\n\n /**\n * Download the file at `path`: requests a single-use token, then requests the chunked\n * transfer, assembling `Begin → Chunk* → End` frames into one buffer.\n */\n async download(path: string): Promise<DownloadedFile> {\n const tokenResponse = await this.daemon.request<TokenResponse>(\n \"file_download_token_request\",\n { path },\n );\n if (!tokenResponse.ok || !tokenResponse.token) {\n throw new Error(tokenResponse.error ?? \"failed to issue download token\");\n }\n\n const stream = this.nextStream++;\n const result = new Promise<DownloadedFile>((resolve, reject) => {\n this.pending.set(stream, { chunks: [], meta: {}, resolve, reject });\n });\n\n const requestResponse = await this.daemon.request<DownloadRequestResponse>(\n \"file_download_request\",\n { token: tokenResponse.token, stream },\n );\n if (!requestResponse.ok) {\n this.pending.delete(stream);\n throw new Error(requestResponse.error ?? \"download request failed\");\n }\n\n return result;\n }\n\n private dispatch(frame: FileTransferFrame): void {\n const pending = this.pending.get(frame.stream);\n if (!pending) return; // not a download stream we're tracking (e.g. an upload) — ignore\n switch (frame.opcode) {\n case \"Begin\":\n pending.meta.fileName = frame.meta.fileName;\n pending.meta.mimeType = frame.meta.mimeType;\n return;\n case \"Chunk\":\n pending.chunks.push(frame.data);\n return;\n case \"End\":\n this.pending.delete(frame.stream);\n if (frame.ok) {\n pending.resolve({ bytes: concat(pending.chunks), ...pending.meta });\n } else {\n pending.reject(new Error(\"download failed\"));\n }\n return;\n case \"Error\":\n this.pending.delete(frame.stream);\n pending.reject(new Error(frame.message));\n return;\n }\n }\n}\n","/**\n * `use-file-download` — TanStack Query wrapper over the binary file-transfer download path\n * (`file_download_token_request` → `file_download_request` → chunked `Begin`/`Chunk`/`End`\n * binary frames), for viewers that need raw bytes rather than the UTF-8 preview\n * `file_read_request` returns (images, video — POC_TO_APP_PLAN_UI.md §4.5 follow-up: modular\n * file preview). Resolves to an object URL, revoked once superseded by a new one or once this\n * consumer unmounts.\n */\n\nimport { useEffect, useRef } from \"react\";\nimport { useQuery } from \"@tanstack/react-query\";\nimport type { DaemonClient } from \"@av-pi-studio/client\";\nimport { FileTransferClient } from \"@av-pi-studio/client\";\nimport { useConnectionStore } from \"@pi-studio-ui/lib/connection/connection-store.js\";\nimport { rpcKeys } from \"@pi-studio-ui/lib/connection/rpc-keys.js\";\n\n// One FileTransferClient per daemon connection — mirrors `TerminalPanel.tsx`'s `routerFor`\n// (multiple viewers share the one frame demuxer over the shared socket).\nconst transferByDaemon = new WeakMap<DaemonClient, FileTransferClient>();\n\nfunction transferFor(daemon: DaemonClient): FileTransferClient {\n let transfer = transferByDaemon.get(daemon);\n if (!transfer) {\n transfer = new FileTransferClient(daemon);\n transfer.start();\n transferByDaemon.set(daemon, transfer);\n }\n return transfer;\n}\n\nexport interface FileDownload {\n objectUrl: string;\n mimeType?: string;\n fileName?: string;\n}\n\nexport function useFileDownload(path: string, enabled = true) {\n const client = useConnectionStore((s) => s.client);\n const daemon = useConnectionStore((s) => s.daemon);\n\n const query = useQuery({\n queryKey: rpcKeys.fileDownload(path),\n queryFn: async (): Promise<FileDownload> => {\n if (!client || !daemon) throw new Error(\"not connected\");\n const file = await transferFor(daemon).download(path);\n // `Blob`'s DOM typings require an `ArrayBuffer`-backed view; the assembled `Uint8Array`'s\n // `ArrayBufferLike` backing (a decode-time implementation detail) doesn't satisfy that on\n // its own, so copy into a plain `ArrayBuffer`-backed `Uint8Array` first.\n const blob = new Blob([Uint8Array.from(file.bytes)], {\n type: file.mimeType || \"application/octet-stream\",\n });\n return { objectUrl: URL.createObjectURL(blob), mimeType: file.mimeType, fileName: file.fileName };\n },\n enabled: Boolean(client) && Boolean(daemon) && Boolean(path) && enabled,\n // Object URLs are process-local, non-serializable browser resources — never persist them or\n // silently refetch behind this hook's back (that would leak the previous blob's URL).\n staleTime: Infinity,\n gcTime: 0,\n });\n\n // Revoke the previous object URL once a new one supersedes it, and the current one on unmount\n // — TanStack Query's cache has no notion that this value owns a browser resource to release.\n const urlRef = useRef<string | null>(null);\n useEffect(() => {\n const nextUrl = query.data?.objectUrl ?? null;\n if (nextUrl && urlRef.current && urlRef.current !== nextUrl) {\n URL.revokeObjectURL(urlRef.current);\n }\n urlRef.current = nextUrl;\n }, [query.data?.objectUrl]);\n\n useEffect(() => {\n return () => {\n if (urlRef.current) URL.revokeObjectURL(urlRef.current);\n };\n }, []);\n\n return query;\n}\n"],"names":["concat","chunks","total","sum","c","out","offset","chunk","FileTransferClient","daemon","__publicField","frame","_a","stream","pending","path","tokenResponse","result","resolve","reject","requestResponse","transferByDaemon","transferFor","transfer","useFileDownload","enabled","client","useConnectionStore","s","query","useQuery","rpcKeys","file","blob","urlRef","useRef","useEffect","nextUrl"],"mappings":"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"}
|