mirror of
https://github.com/siteboon/claudecodeui.git
synced 2026-06-28 07:15:35 +08:00
fix: respect cloud computer use setting
This commit is contained in:
@@ -739,12 +739,9 @@ window.__MOCK_STATE__ = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function localPane(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>' +
|
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"><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-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(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>';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function envRow(environment) {
|
function envRow(environment) {
|
||||||
|
|||||||
@@ -125,12 +125,12 @@ function getOrCreateMcpToken(): string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getSetupMessage(settings: ComputerUseSettings, readiness: RuntimeReadiness): string {
|
function getSetupMessage(settings: ComputerUseSettings, readiness: RuntimeReadiness): string {
|
||||||
if (getRuntime() === 'cloud') {
|
|
||||||
return 'Open CloudCLI Desktop on this computer, connect the same account, and enable Computer Use.';
|
|
||||||
}
|
|
||||||
if (!settings.enabled) {
|
if (!settings.enabled) {
|
||||||
return 'Computer Use is disabled in settings.';
|
return 'Computer Use is disabled in settings.';
|
||||||
}
|
}
|
||||||
|
if (getRuntime() === 'cloud') {
|
||||||
|
return 'Open CloudCLI Desktop on this computer, connect the same account, and enable Computer Use.';
|
||||||
|
}
|
||||||
if (!readiness.nutInstalled || !readiness.screenshotInstalled) {
|
if (!readiness.nutInstalled || !readiness.screenshotInstalled) {
|
||||||
return 'Install the desktop control runtime to capture the screen and drive the mouse and keyboard.';
|
return 'Install the desktop control runtime to capture the screen and drive the mouse and keyboard.';
|
||||||
}
|
}
|
||||||
@@ -416,22 +416,25 @@ function assertReady(session: ComputerUseSession): void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether agent tools may operate right now. Cloud mode depends purely on a
|
|
||||||
* connected desktop agent; local mode depends on the single feature setting.
|
|
||||||
*/
|
|
||||||
function agentToolsAvailable(): boolean {
|
function agentToolsAvailable(): boolean {
|
||||||
|
const settings = readSettings();
|
||||||
|
if (!settings.enabled) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (getRuntime() === 'cloud') {
|
if (getRuntime() === 'cloud') {
|
||||||
return desktopAgentRelay.isConnected();
|
return desktopAgentRelay.isConnected();
|
||||||
}
|
}
|
||||||
const settings = readSettings();
|
return true;
|
||||||
return settings.enabled;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function assertAgentToolsAvailable(): void {
|
function assertAgentToolsAvailable(): void {
|
||||||
if (agentToolsAvailable()) {
|
if (agentToolsAvailable()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
const settings = readSettings();
|
||||||
|
if (!settings.enabled) {
|
||||||
|
throw new Error('Computer Use agent tools are disabled.');
|
||||||
|
}
|
||||||
throw new Error(
|
throw new Error(
|
||||||
getRuntime() === 'cloud'
|
getRuntime() === 'cloud'
|
||||||
? 'No desktop is linked. Open CloudCLI Desktop on this computer, connect the same account, and enable Computer Use.'
|
? 'No desktop is linked. Open CloudCLI Desktop on this computer, connect the same account, and enable Computer Use.'
|
||||||
@@ -439,6 +442,16 @@ function assertAgentToolsAvailable(): void {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function stopSessions(lastAction: string, message: string): void {
|
||||||
|
for (const session of sessions.values()) {
|
||||||
|
session.status = 'stopped';
|
||||||
|
session.agentAccessEnabled = false;
|
||||||
|
session.updatedAt = new Date().toISOString();
|
||||||
|
session.lastAction = lastAction;
|
||||||
|
session.message = message;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export const computerUseService = {
|
export const computerUseService = {
|
||||||
async getSettings() {
|
async getSettings() {
|
||||||
return readSettings();
|
return readSettings();
|
||||||
@@ -450,8 +463,9 @@ export const computerUseService = {
|
|||||||
const next = writeSettings({ enabled });
|
const next = writeSettings({ enabled });
|
||||||
if (next.enabled) {
|
if (next.enabled) {
|
||||||
await this.registerAgentMcp();
|
await this.registerAgentMcp();
|
||||||
} else if (current.enabled) {
|
} else {
|
||||||
await this.unregisterAgentMcp();
|
await this.unregisterAgentMcp();
|
||||||
|
stopSessions('settings:disabled', 'Computer Use was disabled in settings.');
|
||||||
}
|
}
|
||||||
return next;
|
return next;
|
||||||
},
|
},
|
||||||
@@ -461,16 +475,16 @@ export const computerUseService = {
|
|||||||
const readiness = getRuntimeReadiness();
|
const readiness = getRuntimeReadiness();
|
||||||
const isCloud = getRuntime() === 'cloud';
|
const isCloud = getRuntime() === 'cloud';
|
||||||
const runtimeReady = readiness.nutInstalled && readiness.screenshotInstalled;
|
const runtimeReady = readiness.nutInstalled && readiness.screenshotInstalled;
|
||||||
// Cloud availability is purely a function of a connected desktop agent; the
|
// Cloud mode still respects the saved feature setting. When enabled, cloud
|
||||||
// hosted server has no screen of its own. Local availability needs the
|
// availability comes from a linked desktop agent because the hosted server
|
||||||
// in-process nut-js runtime installed and the feature enabled.
|
// has no screen of its own.
|
||||||
const desktopAgentConnected = desktopAgentRelay.isConnected();
|
const desktopAgentConnected = desktopAgentRelay.isConnected();
|
||||||
const available = isCloud
|
const available = settings.enabled && (isCloud
|
||||||
? desktopAgentConnected
|
? desktopAgentConnected
|
||||||
: settings.enabled && runtimeReady;
|
: runtimeReady);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
enabled: isCloud ? true : settings.enabled,
|
enabled: settings.enabled,
|
||||||
runtime: getRuntime(),
|
runtime: getRuntime(),
|
||||||
available,
|
available,
|
||||||
desktopAgentConnected,
|
desktopAgentConnected,
|
||||||
@@ -571,9 +585,9 @@ export const computerUseService = {
|
|||||||
const readiness = getRuntimeReadiness();
|
const readiness = getRuntimeReadiness();
|
||||||
const isCloud = getRuntime() === 'cloud';
|
const isCloud = getRuntime() === 'cloud';
|
||||||
const runtimeReady = readiness.nutInstalled && readiness.screenshotInstalled;
|
const runtimeReady = readiness.nutInstalled && readiness.screenshotInstalled;
|
||||||
const ready = isCloud
|
const ready = settings.enabled && (isCloud
|
||||||
? desktopAgentRelay.isConnected()
|
? desktopAgentRelay.isConnected()
|
||||||
: settings.enabled && runtimeReady;
|
: runtimeReady);
|
||||||
|
|
||||||
if (!ready) {
|
if (!ready) {
|
||||||
session.message = getSetupMessage(settings, readiness);
|
session.message = getSetupMessage(settings, readiness);
|
||||||
@@ -856,14 +870,15 @@ export const computerUseService = {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Cloud only: when a desktop agent links to this hosted environment, expose
|
* Cloud only: when a desktop agent links to this hosted environment, expose
|
||||||
* the computer_* MCP tools to every provider so the running agent can use
|
* the computer_* MCP tools only if the user enabled Computer Use in settings.
|
||||||
* them. Mirrors `registerAgentMcp` but is driven by relay connectivity rather
|
|
||||||
* than a settings toggle.
|
|
||||||
*/
|
*/
|
||||||
async onDesktopAgentConnected() {
|
async onDesktopAgentConnected() {
|
||||||
if (getRuntime() !== 'cloud') {
|
if (getRuntime() !== 'cloud') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (!readSettings().enabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
await this.registerAgentMcp();
|
await this.registerAgentMcp();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -888,13 +903,7 @@ export const computerUseService = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
async stopAllSessions() {
|
async stopAllSessions() {
|
||||||
for (const session of sessions.values()) {
|
stopSessions('shutdown', 'Computer Use session stopped during server shutdown.');
|
||||||
session.status = 'stopped';
|
|
||||||
session.agentAccessEnabled = false;
|
|
||||||
session.updatedAt = new Date().toISOString();
|
|
||||||
session.lastAction = 'shutdown';
|
|
||||||
session.message = 'Computer Use session stopped during server shutdown.';
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -130,7 +130,21 @@ export default function ComputerUseSettingsTab() {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{isCloud ? (
|
<SettingsRow
|
||||||
|
label="Enable Computer Use"
|
||||||
|
description={isCloud
|
||||||
|
? 'Registers Computer Use MCP servers for supported agents and allows cloud agents to request guarded access to a linked desktop.'
|
||||||
|
: 'Registers Computer Use for supported agents and allows CloudCLI to create guarded desktop control sessions on this machine.'}
|
||||||
|
>
|
||||||
|
<SettingsToggle
|
||||||
|
checked={settings.enabled}
|
||||||
|
onChange={(value) => void updateSettings({ enabled: value })}
|
||||||
|
ariaLabel="Enable Computer Use"
|
||||||
|
disabled={isLoading || isSaving}
|
||||||
|
/>
|
||||||
|
</SettingsRow>
|
||||||
|
|
||||||
|
{isCloud && (
|
||||||
<SettingsRow
|
<SettingsRow
|
||||||
label="Cloud desktop access"
|
label="Cloud desktop access"
|
||||||
description={status?.desktopAgentConnected
|
description={status?.desktopAgentConnected
|
||||||
@@ -160,18 +174,6 @@ export default function ComputerUseSettingsTab() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</SettingsRow>
|
</SettingsRow>
|
||||||
) : (
|
|
||||||
<SettingsRow
|
|
||||||
label="Enable Computer Use"
|
|
||||||
description="Registers Computer Use for supported agents and allows CloudCLI to create guarded desktop control sessions on this machine."
|
|
||||||
>
|
|
||||||
<SettingsToggle
|
|
||||||
checked={settings.enabled}
|
|
||||||
onChange={(value) => void updateSettings({ enabled: value })}
|
|
||||||
ariaLabel="Enable Computer Use"
|
|
||||||
disabled={isLoading || isSaving}
|
|
||||||
/>
|
|
||||||
</SettingsRow>
|
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{(needsRuntime || isCloud || error) && (
|
{(needsRuntime || isCloud || error) && (
|
||||||
|
|||||||
Reference in New Issue
Block a user