livedesk 0.1.676 → 0.1.678
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/bin/livedesk.js +1 -1
- package/bootstrap/hub-self-agent.js +8 -8
- package/electron/desktop-auto-start.mjs +13 -1
- package/electron/desktop-clipboard-owner.mjs +1 -1
- package/electron/electron-builder.mac-arm64-dev.yml +0 -4
- package/electron/electron-builder.mac-arm64.yml +3 -2
- package/electron/electron-builder.mac-x64-dev.yml +0 -4
- package/electron/electron-builder.mac-x64.yml +3 -2
- package/electron/electron-builder.yml +8 -3
- package/electron/main.mjs +25 -14
- package/electron/oauth-pkce.mjs +11 -2
- package/package.json +1 -1
- package/web/dist/app.html +1 -1
- package/web/dist/app.webmanifest +1 -1
- package/web/dist/assets/{AgentSettingsTab-DX9JaXqu.js → AgentSettingsTab-WHlPq5WO.js} +1 -1
- package/web/dist/assets/{AgentsPage-moPvIoKQ.js → AgentsPage-CdnqnRRy.js} +1 -1
- package/web/dist/assets/{CaptureGallery-BfOwhCAq.js → CaptureGallery-r0hgHzWE.js} +1 -1
- package/web/dist/assets/{HubApp-CKaNzsQY.js → HubApp-D1-hYJ7F.js} +3 -3
- package/web/dist/assets/{MonitorStackIcon-D46aVCNK.js → MonitorStackIcon-D1k9mjDe.js} +1 -1
- package/web/dist/assets/{SettingsPage-DQNAHS6u.js → SettingsPage-BML3sxcB.js} +1 -1
- package/web/dist/assets/{ShareFilesPage-dIuZjSDm.js → ShareFilesPage-5yMuAAX8.js} +1 -1
- package/web/dist/assets/{SupportPage-DMFPXp4S.js → SupportPage-BYJoKypB.js} +1 -1
- package/web/dist/assets/{VuvoDeskApp-C_wF5Jvq.js → VuvoDeskApp-w5anguIc.js} +1 -1
- package/web/dist/assets/{app-DDHeEKsm.js → app-jQLAg5d2.js} +2 -2
- package/web/dist/assets/{main-BAUQ7nw4.js → main-BB-Bb6Vm.js} +2 -2
- package/web/dist/desktop-auth-callback.html +1 -1
- package/web/dist/desktop-auth-callback.js +11 -7
- package/web/dist/index.html +2 -2
- package/web/dist/sw.js +2 -2
- package/web/dist/vuvodesk-build-evidence.json +45 -45
package/bin/livedesk.js
CHANGED
|
@@ -2517,7 +2517,7 @@ async function runManager(args, resolvedRole = null, runtimeLock = null, updateH
|
|
|
2517
2517
|
LIVEDESK_HUB_UPDATE_RESULT_PATH: hubUpdateResultPath,
|
|
2518
2518
|
LIVEDESK_UDP_ENABLED: String(process.env.LIVEDESK_UDP_ENABLED || '1'),
|
|
2519
2519
|
LIVEDESK_UDP_PREFER_P2P: String(process.env.LIVEDESK_UDP_PREFER_P2P || '0'),
|
|
2520
|
-
LIVEDESK_UDP_RENDEZVOUS_HOST: String(process.env.LIVEDESK_UDP_RENDEZVOUS_HOST || '
|
|
2520
|
+
LIVEDESK_UDP_RENDEZVOUS_HOST: String(process.env.LIVEDESK_UDP_RENDEZVOUS_HOST || 'p2p.gnsoftech.com'),
|
|
2521
2521
|
LIVEDESK_UDP_RENDEZVOUS_PORT: String(process.env.LIVEDESK_UDP_RENDEZVOUS_PORT || '5199'),
|
|
2522
2522
|
REMOTE_HUB_PORT: String(remotePort),
|
|
2523
2523
|
REMOTE_HUB_PAIR_TOKEN: pairToken,
|
|
@@ -119,7 +119,7 @@ export function createHubSelfAgentSupervisor({
|
|
|
119
119
|
Math.max(100, Number(restartMaxDelayMs) || 8_000),
|
|
120
120
|
Math.max(100, Number(restartBaseDelayMs) || 1_000) * (2 ** Math.min(3, consecutiveFailures - 1))
|
|
121
121
|
);
|
|
122
|
-
report(`[
|
|
122
|
+
report(`[VuvoDesk Hub] Self Agent stopped unexpectedly; retrying in ${delayMs}ms.`, true);
|
|
123
123
|
restartTimer = setTimeout(() => {
|
|
124
124
|
restartTimer = null;
|
|
125
125
|
start();
|
|
@@ -136,7 +136,7 @@ export function createHubSelfAgentSupervisor({
|
|
|
136
136
|
try {
|
|
137
137
|
spawned = spawnImpl(launch.command, launch.args, launch.options);
|
|
138
138
|
} catch (error) {
|
|
139
|
-
report(`[
|
|
139
|
+
report(`[VuvoDesk Hub] Self Agent launch failed: ${error?.message || error}.`, true);
|
|
140
140
|
scheduleRestart();
|
|
141
141
|
return false;
|
|
142
142
|
}
|
|
@@ -148,13 +148,13 @@ export function createHubSelfAgentSupervisor({
|
|
|
148
148
|
spawned.on?.('message', message => {
|
|
149
149
|
if (message?.type !== SELF_AGENT_READY_MESSAGE) return;
|
|
150
150
|
consecutiveFailures = 0;
|
|
151
|
-
report(`[
|
|
151
|
+
report(`[VuvoDesk Hub] Self Agent ready pid=${spawned.pid || 'unknown'} manager=${launch.manager}.`);
|
|
152
152
|
});
|
|
153
153
|
spawned.once?.('error', error => {
|
|
154
154
|
if (settled) return;
|
|
155
155
|
settled = true;
|
|
156
156
|
if (child === spawned) child = null;
|
|
157
|
-
report(`[
|
|
157
|
+
report(`[VuvoDesk Hub] Self Agent process error: ${error?.message || error}.`, true);
|
|
158
158
|
scheduleRestart();
|
|
159
159
|
});
|
|
160
160
|
spawned.once?.('exit', (code, signal) => {
|
|
@@ -163,13 +163,13 @@ export function createHubSelfAgentSupervisor({
|
|
|
163
163
|
if (child === spawned) child = null;
|
|
164
164
|
if (!stopping) {
|
|
165
165
|
report(
|
|
166
|
-
`[
|
|
166
|
+
`[VuvoDesk Hub] Self Agent exited code=${code ?? 'none'} signal=${signal || 'none'}.`,
|
|
167
167
|
true
|
|
168
168
|
);
|
|
169
169
|
scheduleRestart();
|
|
170
170
|
}
|
|
171
171
|
});
|
|
172
|
-
report(`[
|
|
172
|
+
report(`[VuvoDesk Hub] Starting Self Agent pid=${spawned.pid || 'pending'} manager=${launch.manager}.`);
|
|
173
173
|
return true;
|
|
174
174
|
};
|
|
175
175
|
|
|
@@ -202,7 +202,7 @@ export function createHubSelfAgentSupervisor({
|
|
|
202
202
|
reason: normalizeText(reason).slice(0, 120)
|
|
203
203
|
});
|
|
204
204
|
} catch (error) {
|
|
205
|
-
report(`[
|
|
205
|
+
report(`[VuvoDesk Hub] Self Agent shutdown message failed: ${error?.message || error}.`, true);
|
|
206
206
|
}
|
|
207
207
|
hardStopTimer = setTimeout(() => {
|
|
208
208
|
if (ownedChild.exitCode !== null || ownedChild.signalCode) {
|
|
@@ -210,7 +210,7 @@ export function createHubSelfAgentSupervisor({
|
|
|
210
210
|
return;
|
|
211
211
|
}
|
|
212
212
|
report(
|
|
213
|
-
`[
|
|
213
|
+
`[VuvoDesk Hub] Self Agent pid=${ownedChild.pid || 'unknown'} exceeded graceful shutdown; force-stopping that exact child root.`,
|
|
214
214
|
true
|
|
215
215
|
);
|
|
216
216
|
try {
|
|
@@ -3,7 +3,8 @@ import { homedir } from 'node:os';
|
|
|
3
3
|
import { dirname, join, resolve, win32 } from 'node:path';
|
|
4
4
|
|
|
5
5
|
export const DESKTOP_AUTO_START_ARGUMENT = '--autostart';
|
|
6
|
-
export const DESKTOP_AUTO_START_ENTRY_NAME = '
|
|
6
|
+
export const DESKTOP_AUTO_START_ENTRY_NAME = 'VuvoDesk Desktop';
|
|
7
|
+
export const LEGACY_DESKTOP_AUTO_START_ENTRY_NAMES = Object.freeze(['LiveDesk Desktop']);
|
|
7
8
|
const DESKTOP_AUTO_START_PREFERENCE_VERSION = 1;
|
|
8
9
|
const SUPPORTED_PLATFORMS = new Set(['win32', 'darwin', 'linux']);
|
|
9
10
|
const AUTO_START_LOG_ORIGINS = new Set(['startup', 'settings', 'tray']);
|
|
@@ -165,6 +166,17 @@ export function createDesktopAutoStartOwner({
|
|
|
165
166
|
return;
|
|
166
167
|
}
|
|
167
168
|
if (platform === 'win32') {
|
|
169
|
+
for (const legacyName of LEGACY_DESKTOP_AUTO_START_ENTRY_NAMES) {
|
|
170
|
+
app.setLoginItemSettings({
|
|
171
|
+
openAtLogin: false,
|
|
172
|
+
name: legacyName,
|
|
173
|
+
...windowsLoginOptions
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
log(
|
|
177
|
+
`desktop-auto-start event=legacy-cleanup platform=win32 attempted=true count=${LEGACY_DESKTOP_AUTO_START_ENTRY_NAMES.length}`,
|
|
178
|
+
{ source: 'desktop-auto-start' }
|
|
179
|
+
);
|
|
168
180
|
app.setLoginItemSettings({
|
|
169
181
|
openAtLogin: enabled,
|
|
170
182
|
name: DESKTOP_AUTO_START_ENTRY_NAME,
|
|
@@ -361,7 +361,7 @@ export function createDesktopClipboardOwner({
|
|
|
361
361
|
writeOwners.clear();
|
|
362
362
|
// File clipboard entries refer to these exact local paths. Preserve the
|
|
363
363
|
// two bounded committed stages so Explorer/Finder can still paste after
|
|
364
|
-
// the
|
|
364
|
+
// the VuvoDesk window is hidden or the app exits.
|
|
365
365
|
};
|
|
366
366
|
|
|
367
367
|
return {
|
|
@@ -1,6 +1,11 @@
|
|
|
1
|
-
appId: com.livedesk.desktop
|
|
2
|
-
productName: VuvoDesk
|
|
3
|
-
artifactName: VuvoDesk-${version}-${arch}.${ext}
|
|
1
|
+
appId: com.livedesk.desktop
|
|
2
|
+
productName: VuvoDesk
|
|
3
|
+
artifactName: VuvoDesk-${version}-${arch}.${ext}
|
|
4
|
+
protocols:
|
|
5
|
+
- name: VuvoDesk
|
|
6
|
+
schemes:
|
|
7
|
+
- vuvodesk
|
|
8
|
+
- livedesk
|
|
4
9
|
asar: true
|
|
5
10
|
beforePack: packages/vuvodesk/electron/before-pack.cjs
|
|
6
11
|
afterPack: packages/vuvodesk/electron/after-pack.cjs
|
package/electron/main.mjs
CHANGED
|
@@ -61,6 +61,7 @@ import { createDesktopAutoStartOwner } from './desktop-auto-start.mjs';
|
|
|
61
61
|
app.commandLine.appendSwitch('disable-features', 'AudioServiceOutOfProcess');
|
|
62
62
|
|
|
63
63
|
const APP_NAME = 'VuvoDesk Desktop';
|
|
64
|
+
const DESKTOP_PROTOCOL_SCHEMES = Object.freeze(['vuvodesk', 'livedesk']);
|
|
64
65
|
const appWindowTitle = () => `${APP_NAME} · ${app.getVersion()}`;
|
|
65
66
|
const LOCAL_RUNTIME_PORT = Number(process.env.LIVEDESK_LOCAL_RUNTIME_PORT || 5179);
|
|
66
67
|
const LOCAL_RUNTIME_URL = `http://127.0.0.1:${Number.isInteger(LOCAL_RUNTIME_PORT) && LOCAL_RUNTIME_PORT > 0 ? LOCAL_RUNTIME_PORT : 5179}/`;
|
|
@@ -243,10 +244,12 @@ function isAllowedRuntimeUrl(value) {
|
|
|
243
244
|
}
|
|
244
245
|
}
|
|
245
246
|
|
|
246
|
-
function
|
|
247
|
-
try {
|
|
248
|
-
const url = new URL(String(value || ''));
|
|
249
|
-
return url.protocol
|
|
247
|
+
function isDesktopAuthCallbackUrl(value) {
|
|
248
|
+
try {
|
|
249
|
+
const url = new URL(String(value || ''));
|
|
250
|
+
return DESKTOP_PROTOCOL_SCHEMES.includes(url.protocol.replace(/:$/, ''))
|
|
251
|
+
&& url.hostname === 'auth'
|
|
252
|
+
&& url.pathname === '/callback';
|
|
250
253
|
} catch {
|
|
251
254
|
return false;
|
|
252
255
|
}
|
|
@@ -1137,9 +1140,11 @@ async function beginGoogleAuth() {
|
|
|
1137
1140
|
}
|
|
1138
1141
|
}
|
|
1139
1142
|
|
|
1140
|
-
async function handleProtocolUrl(rawUrl) {
|
|
1141
|
-
if (!
|
|
1142
|
-
const
|
|
1143
|
+
async function handleProtocolUrl(rawUrl) {
|
|
1144
|
+
if (!isDesktopAuthCallbackUrl(rawUrl)) return false;
|
|
1145
|
+
const callbackScheme = new URL(String(rawUrl)).protocol.replace(/:$/, '');
|
|
1146
|
+
log(`desktop-protocol event=callback scheme=${callbackScheme}`, { source: 'desktop-protocol' });
|
|
1147
|
+
const request = pendingOAuth;
|
|
1143
1148
|
if (!request) return true;
|
|
1144
1149
|
if (Date.now() - request.startedAt > OAUTH_PENDING_TTL_MS) {
|
|
1145
1150
|
pendingOAuth = null;
|
|
@@ -1507,8 +1512,8 @@ function createTray() {
|
|
|
1507
1512
|
}
|
|
1508
1513
|
|
|
1509
1514
|
app.on('open-url', (event, url) => {
|
|
1510
|
-
event.preventDefault();
|
|
1511
|
-
if (!
|
|
1515
|
+
event.preventDefault();
|
|
1516
|
+
if (!isDesktopAuthCallbackUrl(url)) return;
|
|
1512
1517
|
if (app.isReady()) void handleProtocolUrl(url);
|
|
1513
1518
|
else pendingProtocolUrl = url;
|
|
1514
1519
|
});
|
|
@@ -1522,13 +1527,19 @@ electronAutoUpdater.on('before-quit-for-update', () => {
|
|
|
1522
1527
|
if (!app.requestSingleInstanceLock()) {
|
|
1523
1528
|
app.quit();
|
|
1524
1529
|
} else {
|
|
1525
|
-
app.on('second-instance', (_event, commandLine) => {
|
|
1526
|
-
const protocolUrl = commandLine.find(argument =>
|
|
1530
|
+
app.on('second-instance', (_event, commandLine) => {
|
|
1531
|
+
const protocolUrl = commandLine.find(argument => isDesktopAuthCallbackUrl(argument));
|
|
1527
1532
|
if (protocolUrl) void handleProtocolUrl(protocolUrl);
|
|
1528
1533
|
showWindow();
|
|
1529
|
-
});
|
|
1534
|
+
});
|
|
1530
1535
|
app.whenReady().then(async () => {
|
|
1531
|
-
|
|
1536
|
+
for (const scheme of DESKTOP_PROTOCOL_SCHEMES) {
|
|
1537
|
+
const registered = app.setAsDefaultProtocolClient(scheme);
|
|
1538
|
+
log(`desktop-protocol event=register scheme=${scheme} registered=${registered === true}`, {
|
|
1539
|
+
source: 'desktop-protocol',
|
|
1540
|
+
level: registered === true ? 'info' : 'warn'
|
|
1541
|
+
});
|
|
1542
|
+
}
|
|
1532
1543
|
removeLegacyStartupEntries();
|
|
1533
1544
|
migrateLegacyPlaintextSession();
|
|
1534
1545
|
desktopAutoStartOwner = createDesktopAutoStartOwner({
|
|
@@ -1630,7 +1641,7 @@ if (!app.requestSingleInstanceLock()) {
|
|
|
1630
1641
|
pendingOAuth = { state, codeVerifier, authorizationUrl: '', startedAt: Date.now(), exchanging: false };
|
|
1631
1642
|
}
|
|
1632
1643
|
}
|
|
1633
|
-
const initialProtocolUrl = pendingProtocolUrl || process.argv.find(argument =>
|
|
1644
|
+
const initialProtocolUrl = pendingProtocolUrl || process.argv.find(argument => isDesktopAuthCallbackUrl(argument));
|
|
1634
1645
|
pendingProtocolUrl = '';
|
|
1635
1646
|
if (initialProtocolUrl) void handleProtocolUrl(initialProtocolUrl);
|
|
1636
1647
|
});
|
package/electron/oauth-pkce.mjs
CHANGED
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
import { createHash, randomBytes } from 'node:crypto';
|
|
2
2
|
import { AUTH_REQUEST_TIMEOUT_MS, fetchAuthResponse } from '../runtime-core/src/auth-http.js';
|
|
3
3
|
|
|
4
|
-
export { AUTH_REQUEST_TIMEOUT_MS } from '../runtime-core/src/auth-http.js';
|
|
4
|
+
export { AUTH_REQUEST_TIMEOUT_MS } from '../runtime-core/src/auth-http.js';
|
|
5
|
+
|
|
6
|
+
export const VUVODESK_DESKTOP_AUTH_SCHEME = 'vuvodesk:';
|
|
7
|
+
export const LEGACY_DESKTOP_AUTH_SCHEME = 'livedesk:';
|
|
8
|
+
const TRUSTED_DESKTOP_AUTH_SCHEMES = new Set([
|
|
9
|
+
VUVODESK_DESKTOP_AUTH_SCHEME,
|
|
10
|
+
LEGACY_DESKTOP_AUTH_SCHEME
|
|
11
|
+
]);
|
|
5
12
|
|
|
6
13
|
function base64Url(value) {
|
|
7
14
|
return Buffer.from(value).toString('base64url');
|
|
@@ -47,7 +54,9 @@ export function parsePkceCallbackUrl(value, expectedState, { allowMissingState =
|
|
|
47
54
|
} catch {
|
|
48
55
|
throw new Error('oauth-callback-url-invalid');
|
|
49
56
|
}
|
|
50
|
-
if (url.protocol
|
|
57
|
+
if (!TRUSTED_DESKTOP_AUTH_SCHEMES.has(url.protocol)
|
|
58
|
+
|| url.hostname !== 'auth'
|
|
59
|
+
|| url.pathname !== '/callback') {
|
|
51
60
|
throw new Error('oauth-callback-url-untrusted');
|
|
52
61
|
}
|
|
53
62
|
const state = url.searchParams.get('state') || '';
|
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-jQLAg5d2.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-D1k9mjDe.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-D1k9mjDe.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-D1-hYJ7F.js";import"./pwa-bootstrap-ljOQTt2e.js";import"./preload-helper-DD1OZmLC.js";import"./MonitorStackIcon-D1k9mjDe.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};
|