fix: repair desktop launcher local view

This commit is contained in:
Simos Mikelatos
2026-06-19 14:20:23 +00:00
parent 4d70a2588c
commit f4c68942a5
7 changed files with 88 additions and 30 deletions

View File

@@ -52,6 +52,8 @@ export class ComputerAgentController {
this.connectedUrls = new Set();
this.currentTargets = [];
this.stdoutBuffer = '';
this.lastEvent = null;
this.lastError = null;
}
getSettings() {
@@ -65,6 +67,9 @@ export class ComputerAgentController {
running: Boolean(this.child),
connectedCount: this.connectedUrls.size,
targetCount: this.currentTargets.length,
targetUrls: [...this.currentTargets],
lastEvent: this.lastEvent,
lastError: this.lastError,
};
}
@@ -105,6 +110,7 @@ export class ComputerAgentController {
if (!this.settings.enabled || wsTargets.length === 0) {
this.stop();
this.currentTargets = [];
this.lastEvent = this.settings.enabled ? 'no-targets' : 'disabled';
return;
}
@@ -113,6 +119,8 @@ export class ComputerAgentController {
}
this.currentTargets = wsTargets;
this.lastEvent = 'restarting';
this.lastError = null;
this.restart(wsTargets);
}
@@ -140,6 +148,8 @@ export class ComputerAgentController {
this.child.once('error', (error) => {
console.error('[ComputerAgent] failed to start:', error.message);
this.lastEvent = 'start-error';
this.lastError = error.message;
this.child = null;
this.onChange?.();
});
@@ -147,12 +157,16 @@ export class ComputerAgentController {
this.child.stdout?.on('data', (chunk) => this.handleStdout(String(chunk)));
this.child.stderr?.on('data', (chunk) => {
for (const line of String(chunk).split(/\r?\n/)) {
if (line.trim()) console.error('[ComputerAgent]', line);
if (line.trim()) {
this.lastError = line.trim();
console.error('[ComputerAgent]', line);
}
}
});
this.child.once('exit', (code) => {
console.log(`[ComputerAgent] exited (code ${code ?? 'null'})`);
this.lastEvent = `exit:${code ?? 'null'}`;
this.child = null;
this.connectedUrls = new Set();
this.onChange?.();
@@ -185,10 +199,23 @@ export class ComputerAgentController {
switch (payload.type) {
case 'connected':
this.connectedUrls.add(payload.url);
this.lastEvent = 'connected';
this.lastError = null;
this.onChange?.();
break;
case 'disconnected':
this.connectedUrls.delete(payload.url);
this.lastEvent = 'disconnected';
this.onChange?.();
break;
case 'starting':
this.lastEvent = 'starting';
this.lastError = null;
this.onChange?.();
break;
case 'error':
this.lastEvent = 'error';
this.lastError = payload.message || 'Computer agent error.';
this.onChange?.();
break;
case 'consent-request': {

View File

@@ -181,19 +181,18 @@ window.__MOCK_STATE__ = {
function computerUseStatus(state) {
var computerUse = state && state.computerUse ? state.computerUse : {};
var connectedCount = computerUse.connectedCount || 0;
var environmentLabel = connectedCount + ' environment' + (connectedCount === 1 ? '' : 's');
if (!computerUse.enabled) {
return { label: 'Disabled', tone: 'idle', detail: 'CloudCLI cannot use this computer.' };
}
if (!computerUse.targetCount) {
return { label: 'Not linked', tone: 'warn', detail: 'No running cloud environment found for this account.' };
}
if (!computerUse.connectedCount) {
return { label: 'Connecting', tone: 'warn', detail: 'Trying to link to ' + computerUse.targetCount + ' running cloud environment' + (computerUse.targetCount === 1 ? '' : 's') + '.' };
if (!connectedCount) {
return { label: 'Not connected', tone: 'warn', detail: 'No environment connected.' };
}
if (computerUse.consentMode === 'auto') {
return { label: 'Linked', tone: 'warn', detail: 'Unattended access is on for ' + computerUse.connectedCount + ' cloud environment' + (computerUse.connectedCount === 1 ? '' : 's') + '.' };
return { label: 'Connected', tone: 'warn', detail: environmentLabel + ' connected. Unattended access is on.' };
}
return { label: 'Linked', tone: 'ok', detail: 'Approval prompts are ready for ' + computerUse.connectedCount + ' cloud environment' + (computerUse.connectedCount === 1 ? '' : 's') + '.' };
return { label: 'Connected', tone: 'ok', detail: environmentLabel + ' connected.' };
}
var CC = {
@@ -342,6 +341,11 @@ window.__MOCK_STATE__ = {
case 'set-theme-mode':
return CC.run('Saved', function () { return bridge.updateSetting('themeMode', node.value); });
case 'set-computer-mode':
CC.state.computerUse = {
...((CC.state && CC.state.computerUse) || {}),
enabled: true,
consentMode: node.value === 'auto' ? 'auto' : 'ask',
};
return CC.run('Saved', function () {
return bridge.updateComputerUse({
enabled: true,
@@ -349,6 +353,10 @@ window.__MOCK_STATE__ = {
});
});
case 'set-computer-enabled':
CC.state.computerUse = {
...((CC.state && CC.state.computerUse) || {}),
enabled: !!node.value,
};
return CC.run('Saved', function () {
var current = (CC.state && CC.state.computerUse) || { consentMode: 'ask' };
return bridge.updateComputerUse({
@@ -731,10 +739,11 @@ window.__MOCK_STATE__ = {
}
function localPane(state) {
var computerStatus = CC.computerUseStatus(state);
return '<div class="pane-h"><div><h2 class="pane-title">Local servers</h2><p class="pane-sub">Manage Local CloudCLI on this machine. No account required.</p></div></div>' +
'<div class="card"><div class="card-head"><div><div class="card-t">Local server</div><div class="card-sub mono">' + CC.esc(CC.localUrl(state) || 'Starts on demand') + '</div></div><div class="card-tools"><span class="dot" style="background:' + (state.localServerRunning ? 'var(--ok)' : 'var(--tx3)') + '"></span><button class="icon-btn" data-cc-action="local-settings-toggle" title="Local settings">' + CC.icon('gear', 16) + '</button></div></div>' +
'<div class="card-actions"><button class="btn pri" data-cc-action="local">' + CC.icon('play', 15) + 'Open Local CloudCLI</button><button class="btn" data-cc-action="open-web">' + CC.icon('arrow', 14) + 'Open in browser</button><button class="btn" data-cc-action="copy-web">' + CC.icon('copy', 14) + 'Copy URL</button></div></div>' +
'<div class="card"><div class="card-head"><div><div class="card-t">Computer Use</div><div class="card-sub">' + CC.esc(computerUseStatus(state).detail) + '</div></div><div class="card-tools"><span class="badge ' + CC.esc(computerUseStatus(state).tone) + '">' + CC.esc(computerUseStatus(state).label) + '</span><button class="icon-btn" data-cc-action="computer-settings-toggle" title="Computer Use settings">' + CC.icon('monitor', 16) + '</button></div></div>' +
'<div class="card"><div class="card-head"><div><div class="card-t">Computer Use</div><div class="card-sub">' + CC.esc(computerStatus.detail) + '</div></div><div class="card-tools"><span class="badge ' + CC.esc(computerStatus.tone) + '">' + CC.esc(computerStatus.label) + '</span><button class="icon-btn" data-cc-action="computer-settings-toggle" title="Computer Use settings">' + CC.icon('monitor', 16) + '</button></div></div>' +
'<div class="card-actions"><button class="btn" data-cc-action="refresh-environments">' + CC.icon('refresh', 14) + 'Refresh / relink</button><button class="btn" data-cc-action="computer-settings-toggle">' + CC.icon('settings', 14) + 'Open settings</button></div></div>';
}

View File

@@ -278,6 +278,11 @@ function getDiagnosticsText() {
cloudConnected: Boolean(cloudAccount?.apiKey),
cloudEmail: cloudAccount?.email || null,
cloudEnvironmentCount: cloud.getEnvironments().length,
cloudRunningEnvironmentCount: getRunningEnvironmentUrls().length,
cloudAuthState: cloud.getAuthState(),
computerUse: computerAgent?.getState() || null,
computerUseSettingsPath: getComputerUseSettingsPath(),
cloudAccountPath: getStorePath(),
controlPlaneUrl: CLOUDCLI_CONTROL_PLANE_URL,
}, null, 2);
}