livedesk 0.1.681 → 0.1.682
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/electron/after-pack.cjs +41 -0
- package/electron/macos-permission-onboarding.mjs +5 -8
- package/electron/macos-screen-recording-permission.swift +13 -0
- package/electron/main.mjs +62 -5
- package/package.json +1 -1
- package/web/dist/app.html +1 -1
- package/web/dist/app.webmanifest +1 -1
- package/web/dist/assets/{AgentSettingsTab-DNeJ6MYv.js → AgentSettingsTab-4AvQvAzL.js} +1 -1
- package/web/dist/assets/{AgentsPage-BecUuDhp.js → AgentsPage-DubRELnZ.js} +1 -1
- package/web/dist/assets/{CaptureGallery-BGrMCJyi.js → CaptureGallery-pxID4Nzq.js} +1 -1
- package/web/dist/assets/{HubApp-CVaXT8PJ.js → HubApp-DJVoFO6h.js} +3 -3
- package/web/dist/assets/{MonitorStackIcon-Bnu-aE9X.js → MonitorStackIcon-CAj6nVrZ.js} +1 -1
- package/web/dist/assets/{SettingsPage-RIiBLrwL.js → SettingsPage-DYC7ETb1.js} +1 -1
- package/web/dist/assets/{ShareFilesPage-4_r2kZEK.js → ShareFilesPage-Cg2seH07.js} +1 -1
- package/web/dist/assets/{SupportPage-BuucN-JV.js → SupportPage-DcxrwVU9.js} +1 -1
- package/web/dist/assets/{VuvoDeskApp-DQavlXQk.js → VuvoDeskApp-9Ex7qnd7.js} +1 -1
- package/web/dist/assets/{app-C0wgDWxx.js → app-DRl6qm_l.js} +2 -2
- package/web/dist/assets/{main-DNCd9BVT.js → main-16UlVMG9.js} +2 -2
- package/web/dist/index.html +2 -2
- package/web/dist/sw.js +2 -2
- package/web/dist/vuvodesk-build-evidence.json +48 -48
package/electron/after-pack.cjs
CHANGED
|
@@ -1,12 +1,53 @@
|
|
|
1
|
+
const { execFileSync } = require('node:child_process');
|
|
1
2
|
const { chmodSync, existsSync, statSync } = require('node:fs');
|
|
2
3
|
const { dirname, join } = require('node:path');
|
|
3
4
|
|
|
5
|
+
const MACOS_SCREEN_PERMISSION_HELPER = 'vuvodesk-macos-screen-permission';
|
|
6
|
+
|
|
7
|
+
function buildMacosScreenPermissionHelper(context) {
|
|
8
|
+
const sourcePath = join(__dirname, 'macos-screen-recording-permission.swift');
|
|
9
|
+
const resourcesRoot = join(
|
|
10
|
+
context.appOutDir,
|
|
11
|
+
`${context.packager.appInfo.productFilename}.app`,
|
|
12
|
+
'Contents',
|
|
13
|
+
'Resources'
|
|
14
|
+
);
|
|
15
|
+
const outputPath = join(resourcesRoot, MACOS_SCREEN_PERMISSION_HELPER);
|
|
16
|
+
const target = context.arch === 1 || context.arch === 'x64'
|
|
17
|
+
? 'x86_64-apple-macos10.15'
|
|
18
|
+
: context.arch === 3 || context.arch === 'arm64'
|
|
19
|
+
? 'arm64-apple-macos11.0'
|
|
20
|
+
: '';
|
|
21
|
+
if (!target) {
|
|
22
|
+
throw new Error(`Unsupported macOS permission-helper architecture: ${context.arch}.`);
|
|
23
|
+
}
|
|
24
|
+
execFileSync('/usr/bin/xcrun', [
|
|
25
|
+
'swiftc',
|
|
26
|
+
'-parse-as-library',
|
|
27
|
+
'-O',
|
|
28
|
+
'-target',
|
|
29
|
+
target,
|
|
30
|
+
'-framework',
|
|
31
|
+
'CoreGraphics',
|
|
32
|
+
sourcePath,
|
|
33
|
+
'-o',
|
|
34
|
+
outputPath
|
|
35
|
+
], { stdio: 'inherit' });
|
|
36
|
+
chmodSync(outputPath, 0o755);
|
|
37
|
+
const executableMode = statSync(outputPath).mode & 0o777;
|
|
38
|
+
if ((executableMode & 0o111) !== 0o111) {
|
|
39
|
+
throw new Error(`Packaged macOS permission helper must be executable; mode=${executableMode.toString(8)}`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
4
43
|
module.exports = async function afterPack(context) {
|
|
5
44
|
const platform = String(context.electronPlatformName || '');
|
|
6
45
|
if (platform !== 'linux' && platform !== 'darwin') {
|
|
7
46
|
return;
|
|
8
47
|
}
|
|
9
48
|
|
|
49
|
+
if (platform === 'darwin') buildMacosScreenPermissionHelper(context);
|
|
50
|
+
|
|
10
51
|
const unpackedRoot = platform === 'darwin'
|
|
11
52
|
? join(
|
|
12
53
|
context.appOutDir,
|
|
@@ -27,7 +27,7 @@ function claimOnce(path) {
|
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
export function createMacosPermissionOnboardingOwner({
|
|
30
|
-
|
|
30
|
+
requestScreenRecording,
|
|
31
31
|
systemPreferences,
|
|
32
32
|
stateRoot,
|
|
33
33
|
runtimeStateDir,
|
|
@@ -116,13 +116,10 @@ export function createMacosPermissionOnboardingOwner({
|
|
|
116
116
|
try {
|
|
117
117
|
if (claimOnce(screenMarkerPath)) {
|
|
118
118
|
screenRequested = true;
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
thumbnailSize: { width: 0, height: 0 },
|
|
124
|
-
fetchWindowIcons: false
|
|
125
|
-
});
|
|
119
|
+
if (typeof requestScreenRecording !== 'function') {
|
|
120
|
+
throw new Error('macos-screen-requester-unavailable');
|
|
121
|
+
}
|
|
122
|
+
await requestScreenRecording();
|
|
126
123
|
}
|
|
127
124
|
} catch {
|
|
128
125
|
error ||= 'screen-request-failed';
|
package/electron/main.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { app, autoUpdater as electronAutoUpdater, BrowserWindow, clipboard,
|
|
1
|
+
import { app, autoUpdater as electronAutoUpdater, BrowserWindow, clipboard, dialog, ipcMain, Menu, nativeImage, powerMonitor, safeStorage, shell, systemPreferences, Tray } from 'electron';
|
|
2
2
|
import { existsSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
|
|
3
3
|
import { homedir } from 'node:os';
|
|
4
4
|
import { dirname, join, resolve } from 'node:path';
|
|
@@ -95,7 +95,9 @@ const logDir = join(stateRoot, 'logs');
|
|
|
95
95
|
const logPath = join(logDir, 'desktop.log');
|
|
96
96
|
const authSessionPath = join(stateRoot, 'auth-session.json');
|
|
97
97
|
const authSessionBackupPath = join(stateRoot, 'auth-session.backup.json');
|
|
98
|
-
const runtimeStateDir = process.env.LIVEDESK_STATE_DIR || join(homedir(), '.livedesk');
|
|
98
|
+
const runtimeStateDir = process.env.LIVEDESK_STATE_DIR || join(homedir(), '.livedesk');
|
|
99
|
+
const MACOS_SCREEN_PERMISSION_HELPER = 'vuvodesk-macos-screen-permission';
|
|
100
|
+
const MACOS_SCREEN_PERMISSION_TIMEOUT_MS = 120000;
|
|
99
101
|
try { app.setPath('userData', stateRoot); } catch { /* Electron may reject late path changes in embedded test hosts. */ }
|
|
100
102
|
const appPath = app.getAppPath();
|
|
101
103
|
const unpackedAppPath = appPath.replace(/app\.asar([\\/]|$)/, 'app.asar.unpacked$1');
|
|
@@ -180,6 +182,57 @@ let lastKnownDesktopSession = null;
|
|
|
180
182
|
let desktopClipboardOwner = null;
|
|
181
183
|
let runtimeWindowLoadOwner = null;
|
|
182
184
|
let desktopAutoStartOwner = null;
|
|
185
|
+
let macosScreenPermissionChild = null;
|
|
186
|
+
|
|
187
|
+
function requestMacosScreenRecordingAccess() {
|
|
188
|
+
if (process.platform !== 'darwin' || !app.isPackaged) return Promise.resolve(false);
|
|
189
|
+
const helperPath = join(process.resourcesPath, MACOS_SCREEN_PERMISSION_HELPER);
|
|
190
|
+
if (!existsSync(helperPath)) {
|
|
191
|
+
return Promise.reject(new Error('macos-screen-permission-helper-unavailable'));
|
|
192
|
+
}
|
|
193
|
+
if (macosScreenPermissionChild) {
|
|
194
|
+
return Promise.reject(new Error('macos-screen-permission-helper-already-running'));
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
return new Promise((resolvePermission, rejectPermission) => {
|
|
198
|
+
const child = spawn(helperPath, [], {
|
|
199
|
+
stdio: ['ignore', 'ignore', 'ignore'],
|
|
200
|
+
windowsHide: true
|
|
201
|
+
});
|
|
202
|
+
macosScreenPermissionChild = child;
|
|
203
|
+
let settled = false;
|
|
204
|
+
const finish = (callback, value) => {
|
|
205
|
+
if (settled) return;
|
|
206
|
+
settled = true;
|
|
207
|
+
clearTimeout(timeout);
|
|
208
|
+
if (macosScreenPermissionChild === child) macosScreenPermissionChild = null;
|
|
209
|
+
callback(value);
|
|
210
|
+
};
|
|
211
|
+
const timeout = setTimeout(() => {
|
|
212
|
+
try { child.kill('SIGTERM'); } catch { /* already terminal */ }
|
|
213
|
+
finish(rejectPermission, new Error('macos-screen-permission-helper-timeout'));
|
|
214
|
+
}, MACOS_SCREEN_PERMISSION_TIMEOUT_MS);
|
|
215
|
+
timeout.unref?.();
|
|
216
|
+
child.once('error', error => finish(rejectPermission, error));
|
|
217
|
+
child.once('exit', (code, signal) => {
|
|
218
|
+
if (code === 0 || code === 2) {
|
|
219
|
+
finish(resolvePermission, code === 0);
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
finish(
|
|
223
|
+
rejectPermission,
|
|
224
|
+
new Error(`macos-screen-permission-helper-exit-${code ?? 'signal'}-${signal || 'none'}`)
|
|
225
|
+
);
|
|
226
|
+
});
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
function stopMacosScreenPermissionRequest() {
|
|
231
|
+
const child = macosScreenPermissionChild;
|
|
232
|
+
macosScreenPermissionChild = null;
|
|
233
|
+
if (!child || child.killed) return;
|
|
234
|
+
try { child.kill('SIGTERM'); } catch { /* already terminal */ }
|
|
235
|
+
}
|
|
183
236
|
const desktopAuthInvalidationGuard = createDesktopAuthInvalidationGuard();
|
|
184
237
|
const installerQuitGate = createInstallerQuitGate({
|
|
185
238
|
requestQuit: () => app.quit()
|
|
@@ -1551,7 +1604,7 @@ if (!app.requestSingleInstanceLock()) {
|
|
|
1551
1604
|
});
|
|
1552
1605
|
desktopAutoStartOwner.reconcile('startup');
|
|
1553
1606
|
const macosPermissionOnboardingOwner = createMacosPermissionOnboardingOwner({
|
|
1554
|
-
|
|
1607
|
+
requestScreenRecording: requestMacosScreenRecordingAccess,
|
|
1555
1608
|
systemPreferences,
|
|
1556
1609
|
stateRoot,
|
|
1557
1610
|
runtimeStateDir,
|
|
@@ -1668,9 +1721,13 @@ if (!app.requestSingleInstanceLock()) {
|
|
|
1668
1721
|
event.preventDefault();
|
|
1669
1722
|
return;
|
|
1670
1723
|
}
|
|
1671
|
-
if (installerQuitDecision === InstallerQuitDecision.ALLOW)
|
|
1724
|
+
if (installerQuitDecision === InstallerQuitDecision.ALLOW) {
|
|
1725
|
+
stopMacosScreenPermissionRequest();
|
|
1726
|
+
return;
|
|
1727
|
+
}
|
|
1672
1728
|
event.preventDefault();
|
|
1673
|
-
recurringProductUpdates?.stop();
|
|
1729
|
+
recurringProductUpdates?.stop();
|
|
1730
|
+
stopMacosScreenPermissionRequest();
|
|
1674
1731
|
quitSequenceStarted = true;
|
|
1675
1732
|
isQuitting = true;
|
|
1676
1733
|
void quiesceDesktopAuthOwner('application-quit').then(() => {
|
package/package.json
CHANGED
package/web/dist/app.html
CHANGED
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
.vuvodesk-static-boot [hidden] { display: none; }
|
|
53
53
|
@keyframes vuvodesk-static-boot-spin { to { transform: rotate(360deg); } }
|
|
54
54
|
</style>
|
|
55
|
-
<script type="module" crossorigin src="/assets/app-
|
|
55
|
+
<script type="module" crossorigin src="/assets/app-DRl6qm_l.js" data-vuvodesk-entry></script>
|
|
56
56
|
<link rel="modulepreload" crossorigin href="/assets/preload-helper-DD1OZmLC.js">
|
|
57
57
|
<link rel="modulepreload" crossorigin href="/assets/pwa-bootstrap-ljOQTt2e.js">
|
|
58
58
|
</head>
|
package/web/dist/app.webmanifest
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{j as t}from"./pwa-startup-DvbrYEQi.js";import{r as c,d as A,S as q,T as I,e as z}from"./icons-CuXJn-Hz.js";import{h as x}from"./MonitorStackIcon-
|
|
1
|
+
import{j as t}from"./pwa-startup-DvbrYEQi.js";import{r as c,d as A,S as q,T as I,e as z}from"./icons-CuXJn-Hz.js";import{h as x}from"./MonitorStackIcon-CAj6nVrZ.js";import"./pwa-bootstrap-ljOQTt2e.js";const E={enabled:!0};function w(i){return{enabled:i?.enabled===!0}}async function L(i,p,f){let l=null;for(let s=0;s<2;s+=1){const g=await x("/api/settings",{signal:f},p);if(g.settings.agent?.enabled===i)return;try{await x("/api/settings",{method:"PATCH",signal:f,body:JSON.stringify({revision:g.revision,agent:{enabled:i}})},p);return}catch(a){if(l=a,s!==0||!String(a instanceof Error?a.message:a).startsWith("409 "))throw a}}throw l}function H({hubUrl:i,showToast:p}){const[f,l]=c.useState(E),[s,g]=c.useState(null),[a,m]=c.useState(""),[j,v]=c.useState(""),[y,d]=c.useState(""),b=c.useRef(0),u=c.useRef(null);c.useEffect(()=>{let e=!0;u.current?.abort();const n=new AbortController;u.current=n;const h=++b.current;return g(null),l(E),m(""),d(""),v(""),x("/api/settings/agent",{signal:n.signal},i).then(o=>{!e||n.signal.aborted||h!==b.current||(g(o.settings),l(w(o.settings)))}).catch(o=>{e&&!n.signal.aborted&&h===b.current&&d(o instanceof Error?o.message:String(o))}),()=>{e=!1,n.abort(),u.current===n&&(u.current=null)}},[i]);const k=(e,n)=>l(h=>({...h,[e]:n})),C=e=>{g(e),l(w(e))},S=()=>({generation:b.current,controller:u.current}),r=e=>e.generation===b.current&&e.controller!==null&&e.controller===u.current&&!e.controller.signal.aborted,R=async()=>{if(!s){d("Agent settings are not available yet.");return}const e=S();if(r(e)){m("save"),d(""),v("");try{if(await L(f.enabled,i,e.controller.signal),!r(e))return;const n=await x("/api/settings/agent",{signal:e.controller.signal},i);if(!r(e))return;C(n.settings),v("Codex Agent settings saved.")}catch(n){r(e)&&d(n instanceof Error?n.message:String(n))}finally{r(e)&&m("")}}},T=async()=>{const e=S();if(r(e)){m("test"),d(""),v("");try{const n=await x("/api/settings/agent/test",{method:"POST",signal:e.controller.signal,body:JSON.stringify({})},i);if(!r(e))return;const h=await x("/api/settings/agent",{signal:e.controller.signal},i);if(!r(e))return;C(h.settings);const o=Number.isFinite(n.connection?.latencyMs)?Math.max(0,Math.round(n.connection.latencyMs)):null;p(`Codex Agent connection verified${o!==null?` in ${o} ms.`:"."}`,"success")}catch(n){r(e)&&d(n instanceof Error?n.message:String(n))}finally{r(e)&&m("")}}},D=s?.codexInstallation==="installed"&&s.codexAuth==="signed-in",N=s!==null;return t.jsxs("div",{className:"settings-tab-content agent-settings-content",children:[t.jsxs("section",{className:"settings-section-card agent-enable-card",children:[t.jsxs("label",{className:"settings-toggle agent-enable-toggle",children:[t.jsx("input",{type:"checkbox",checked:f.enabled,onChange:e=>k("enabled",e.target.checked),disabled:!N||a!==""}),t.jsx("span",{children:"Enable Codex Agent"})]}),t.jsxs("p",{className:"settings-help",children:[t.jsx(A,{size:12})," Enabled by default. Agent commands use only the Codex account signed in on this Hub."]})]}),y&&t.jsx("div",{className:"agent-settings-alert error",role:"alert",children:y}),j&&t.jsx("div",{className:"agent-settings-alert success",role:"status",children:j}),t.jsxs("section",{className:"settings-section-card",children:[t.jsxs("div",{className:"settings-section-heading",children:[t.jsxs("div",{children:[t.jsx("span",{children:"Connection"}),t.jsx("h3",{children:"Codex SDK / CLI"})]}),t.jsx(q,{size:20})]}),t.jsxs("div",{className:"agent-connection-row",children:[t.jsx("span",{className:`agent-connection-dot ${D?"connected":s?.codexAuth==="not-signed-in"?"unavailable":""}`}),t.jsx("span",{children:s?.codexInstallation==="not-installed"?"Codex SDK not installed":s?.codexAuth==="signed-in"?"Codex CLI signed in":s?.codexAuth==="not-signed-in"?"Codex CLI sign-in required":"Codex status not tested"}),t.jsxs("button",{className:"settings-reset",onClick:()=>{T()},disabled:a!=="",type:"button",children:[t.jsx(I,{size:15})," ",a==="test"?"Testing":"Test connection"]})]}),t.jsxs("p",{className:"settings-help",children:[t.jsx(A,{size:12})," The Hub uses the installed Codex SDK / CLI to plan approved commands and run them through VuvoDesk Agent tools on selected computers. VuvoDesk never asks for separate credentials."]})]}),t.jsx("div",{className:"settings-action-row agent-settings-actions",children:t.jsxs("button",{className:"text-button primary",onClick:()=>{R()},disabled:!N||a!=="",type:"button",children:[t.jsx(z,{size:15})," ",a==="save"?"Saving":"Save Agent settings"]})})]})}export{H as AgentSettingsTab};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{j as t}from"./pwa-startup-DvbrYEQi.js";import{r as d,ae as ht,af as Ce,z as yt,G as ee,X as xe,ag as vt,ah as wt,ai as Ze,aj as kt,ak as bt,al as Se,b as H,am as Ct,p as xt,an as _e,o as St,ao as jt,S as Je,ap as At,a9 as Rt,c as Nt,aq as Pt,ar as It,A as Tt,as as ue,M as Xe}from"./icons-CuXJn-Hz.js";import{r as Et,h as F}from"./MonitorStackIcon-
|
|
1
|
+
import{j as t}from"./pwa-startup-DvbrYEQi.js";import{r as d,ae as ht,af as Ce,z as yt,G as ee,X as xe,ag as vt,ah as wt,ai as Ze,aj as kt,ak as bt,al as Se,b as H,am as Ct,p as xt,an as _e,o as St,ao as jt,S as Je,ap as At,a9 as Rt,c as Nt,aq as Pt,ar as It,A as Tt,as as ue,M as Xe}from"./icons-CuXJn-Hz.js";import{r as Et,h as F}from"./MonitorStackIcon-CAj6nVrZ.js";import"./pwa-bootstrap-ljOQTt2e.js";const Ot=d.forwardRef(function({value:s,onChange:n,onSubmit:r,onOpenSuggestedTasks:i,suggestedOpen:f=!1,suggestedTaskCount:c,disabled:v=!1,placeholder:S="Ask VuvoDesk to work across your machines...",compact:g=!1},x){return t.jsxs("form",{className:"agents-composer",onSubmit:w=>{w.preventDefault(),r()},children:[t.jsx("button",{className:`agents-suggested-trigger ${f?"active":""}`,type:"button","aria-label":c===void 0?"Open Suggested tasks":`Open Suggested tasks (${c} available)`,"aria-expanded":f,onClick:i,disabled:v,children:t.jsx(ht,{size:17})}),t.jsx("textarea",{ref:x,value:s,onChange:w=>n(w.target.value.slice(0,4e3)),placeholder:S,"aria-label":"Ask VuvoDesk",rows:g?1:2,disabled:v}),t.jsxs("button",{className:"agents-run-button",type:"submit",disabled:v||!s.trim(),children:[v?t.jsx(Ce,{className:"spin",size:16}):t.jsx(yt,{size:16}),v?"Running":"Run"]})]})}),$t=["read","processControl","serviceControl","applicationControl","fileRead","fileWrite","fileDelete","shell","script","softwareInstall","network","systemPower","systemConfiguration","userAccount"];function de(e){return e.deviceName?.trim()||e.hostname?.trim()||e.deviceId}function pe(e){return e.connected!==!0?!1:e.synthetic===!0?!0:!e.channels||e.channels.control===!0}function Dt(e){return e==="running"||e==="completed"||e==="failed"||e==="cancelled"?e:"queued"}function _t(e){switch(e){case"process.list":return"Process list";case"system.health":return"System health";case"gpu.status":return"GPU status";case"disk.status":return"Disk status";case"service.status":return"Service status";case"diagnostics.collect":return"Diagnostics";case"process.control":return"Process control";case"service.control":return"Service control";case"application.launch":return"Launch application";case"application.close":return"Close application";case"file.read":return"Read file";case"file.write":return"Write file";case"file.delete":return"Delete file";case"file.list":return"List directory";case"command.run":return"Run command";case"script.run":return"Run script";case"software.install":return"Install software";case"network.status":return"Network status";case"system.power":return"Power action";case"system.configure":return"System configuration";case"logs.collect":return"Collect logs"}}const Mt=64*1024,Me="[Earlier log output hidden by PWA display limit.]",Qe=new TextEncoder,zt=new TextDecoder("utf-8",{fatal:!0}),ze=16*1024,Lt=200,Le="(?:access[_-]?(?:token|key)|refresh[_-]?token|id[_-]?token|pair[_-]?(?:token|key)|authorization|api[_-]?key|private[_-]?key|connection[_-]?string|credential|password|passwd|secret|cookie|set-cookie)",Ft="(?:access[_-]?(?:token|key)|refresh[_-]?token|id[_-]?token|pair[_-]?(?:token|key)|token|authorization|api[_-]?key|private[_-]?key|connection[_-]?string|credential|password|passwd|secret|cookie|set-cookie)",Bt="(?:access[_-]?(?:token|key)|refresh[_-]?token|id[_-]?token|pair[_-]?(?:token|key)|token|authorization|api[_-]?key|credential|password|secret|cookie)",qt=/\b(?:sk-(?:proj-|ant-)?[A-Za-z0-9_-]{8,}|gh[pousr]_[A-Za-z0-9]{8,}|github_pat_[A-Za-z0-9_]{8,}|(?:AKIA|ASIA)[A-Z0-9]{16}|AIza[A-Za-z0-9_-]{35}|npm_[A-Za-z0-9]{8,}|xox[a-z]-[A-Za-z0-9-]{8,}|(?:sk|rk)_(?:live|test)_[A-Za-z0-9]{8,})\b/g;function Ut(e){return e&&typeof e=="object"&&!Array.isArray(e)?e:null}function Fe(e){return Qe.encode(e).byteLength}function Be(e,s){const n=Qe.encode(e);if(n.byteLength<=s)return{value:e,truncated:!1};let r=n.byteLength-s;for(;r<n.byteLength&&(n[r]&192)===128;)r+=1;let i=zt.decode(n.subarray(r));const f=i.indexOf(`
|
|
2
2
|
`);return f>=0&&f<i.length-1&&(i=i.slice(f+1)),{value:i,truncated:!0}}function et(e){return e.replace(/-----BEGIN [^-\r\n]*PRIVATE KEY-----[\s\S]*?-----END [^-\r\n]*PRIVATE KEY-----/gi,"[REDACTED PRIVATE KEY]").replace(/\b(?:proxy-)?authorization\s*[:=]\s*[^\r\n]*|\b(?:set-)?cookie\s*[:=]\s*[^\r\n]*/gi,"credential-header=[REDACTED]").replace(/\bBearer\s+(?:"[^"]*"|'[^']*'|[^\s,;]+)/gi,"Bearer [REDACTED]").replace(new RegExp(`("${Le}"\\s*:\\s*")[^"\\r\\n]*(")`,"gi"),"$1[REDACTED]$2").replace(new RegExp(`('${Le}'\\s*:\\s*')[^'\\r\\n]*(')`,"gi"),"$1[REDACTED]$2").replace(new RegExp(`((?:[A-Za-z0-9.-]+[_-])?${Ft}\\s*[:=]\\s*)(?!\\[REDACTED\\])[^\\s,;&]+`,"gi"),"$1[REDACTED]").replace(new RegExp(`([?&]${Bt}=)[^&\\s]+`,"gi"),"$1[REDACTED]").replace(/\b(?:eyJ|[A-Za-z0-9_-]{8,}\.)[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\b/g,"[REDACTED TOKEN]").replace(qt,"[REDACTED KEY]")}function Gt(e){return typeof e!="string"?"source unknown":et(e).replace(/[\u0000-\u001f\u007f]/g," ").trim().slice(0,64)||"source unknown"}function qe(e){return typeof e=="number"&&Number.isSafeInteger(e)&&e>=0?Math.floor(e):null}function Vt(e){if(typeof e!="string"||e.length===0)return{output:"",displayTruncated:!1};const s=Be(e.replace(/\r\n?/g,`
|
|
3
3
|
`),Mt);let n=et(s.value).replace(/[\u0000-\u0008\u000b\u000c\u000e-\u001f\u007f]/g," ").trim(),r=s.truncated;const i=n?n.split(`
|
|
4
4
|
`):[];if(i.length>Lt-1&&(n=i.slice(-199).join(`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{j as e}from"./pwa-startup-DvbrYEQi.js";import{r as i,R as x,E as j,D as u,f as g,h as f}from"./icons-CuXJn-Hz.js";import{l as b,c as d,d as y}from"./HubApp-
|
|
1
|
+
import{j as e}from"./pwa-startup-DvbrYEQi.js";import{r as i,R as x,E as j,D as u,f as g,h as f}from"./icons-CuXJn-Hz.js";import{l as b,c as d,d as y}from"./HubApp-DJVoFO6h.js";import"./pwa-bootstrap-ljOQTt2e.js";import"./preload-helper-DD1OZmLC.js";import"./MonitorStackIcon-CAj6nVrZ.js";import"./supabase-C7qjtLN3.js";import"./frame-lifecycle-D91nchvm.js";function z({hubUrl:s,onToast:n}){const[o,m]=i.useState([]),[h,c]=i.useState(!0),r=i.useCallback(async()=>{c(!0);try{m((await b(s)).captures||[])}catch(t){n(t instanceof Error?t.message:String(t))}finally{c(!1)}},[s,n]);i.useEffect(()=>{r()},[r]);const p=async t=>{const a=d(t.id,s);if(navigator.share)try{await navigator.share({title:t.fileName,url:a});return}catch{}window.open(a,"_blank","noopener,noreferrer")};return e.jsxs("section",{className:"capture-gallery",children:[e.jsxs("header",{children:[e.jsxs("div",{children:[e.jsx("span",{className:"settings-eyebrow",children:"Capture Gallery"}),e.jsx("h2",{children:"Saved captures"})]}),e.jsxs("button",{className:"text-button",onClick:()=>{r()},type:"button",children:[e.jsx(x,{size:15})," Refresh"]})]}),h?e.jsx("p",{className:"settings-help",children:"Loading captures..."}):o.length===0?e.jsx("p",{className:"settings-help",children:"No captures saved yet."}):e.jsx("div",{className:"capture-gallery-grid",children:o.map(t=>{const a=d(t.id,s);return e.jsxs("article",{className:"capture-gallery-card",children:[t.mimeType.startsWith("image/")?e.jsx("img",{src:a,alt:t.target.label}):e.jsx("video",{src:a,controls:!0,preload:"metadata"}),e.jsxs("div",{className:"capture-gallery-card-body",children:[e.jsx("strong",{children:t.fileName}),e.jsxs("small",{children:[t.target.label," · ",new Date(t.createdAt).toLocaleString()," · ",Math.ceil(t.sizeBytes/1024)," KB"]}),e.jsxs("div",{children:[e.jsx("button",{className:"icon-button",title:"Open","aria-label":"Open",onClick:()=>window.open(a,"_blank","noopener,noreferrer"),type:"button",children:e.jsx(j,{size:15})}),e.jsx("a",{className:"icon-button",title:"Download","aria-label":"Download",href:`${a}?download=1`,download:t.fileName,children:e.jsx(u,{size:15})}),e.jsx("button",{className:"icon-button",title:"Share","aria-label":"Share",onClick:()=>{p(t)},type:"button",children:e.jsx(g,{size:15})}),e.jsx("button",{className:"icon-button danger",title:"Delete","aria-label":"Delete",onClick:()=>{window.confirm(`Delete ${t.fileName}?`)&&y(t.id,s).then(()=>r()).catch(l=>n(l instanceof Error?l.message:String(l)))},type:"button",children:e.jsx(f,{size:15})})]})]})]},t.id)})})]})}export{z as CaptureGallery};
|