Files
openclaw/extensions/crabbox/src/crabbox-worker-command-error.ts
Peter Steinberger b5d5ec340f feat(cloud-workers): add desktop apps and browser autonomy (#121475)
* feat(cloud-workers): add desktop apps and browser autonomy

provider-attested Browser/Terminal launchers, shared visible loopback CDP Browser tool, no MCP/cookies/generic command.

* feat(ui): add cloud desktop app launcher

* docs(gateway): document cloud desktop apps and browser autonomy

* perf(ui): trim desktop launcher startup copy

* refactor(ui): simplify desktop launch feedback

* perf(ui): reuse desktop app labels

* fix(ui): keep desktop launch failures actionable

* fix(crabbox): allow browser bootstrap to finish

* fix(cloud-workers): honor provider provision budgets

* fix(cloud-workers): persist browser screenshot receipts

* fix(cloud-workers): bound browser screenshot lifecycle

* fix(cloud-workers): avoid replaying desktop launches

* test(cloud-workers): isolate browser runtime integration

* refactor(cloud-workers): tighten desktop runtime boundaries

* test(cloud-workers): keep browser runtime mock synchronous

* fix(cloud-workers): break gateway type import cycle

* fix(ci): settle admitted setup sessions in tests

* build(plugin-sdk): refresh desktop app contract

* ci: refresh merge-tree validation

* build(plugin-sdk): regenerate desktop app baseline

* style(gateway): format merged method order test
2026-08-10 20:31:07 -07:00

34 lines
1.2 KiB
TypeScript

import { redactSensitiveText } from "openclaw/plugin-sdk/logging-core";
import { WorkerProviderError } from "openclaw/plugin-sdk/plugin-entry";
import type { SpawnResult } from "openclaw/plugin-sdk/process-runtime";
import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
const MAX_COMMAND_DETAIL_CHARS = 512;
function crabboxCommandDetail(result: SpawnResult): string {
const raw = (result.stderr || result.stdout).trim();
if (!raw) {
return "";
}
const compressed = redactSensitiveText(raw).replace(/\s+/gu, " ");
const redacted = truncateUtf16Safe(compressed, MAX_COMMAND_DETAIL_CHARS);
return redacted ? `: ${redacted}` : "";
}
export function crabboxCommandError(action: string, result: SpawnResult): Error {
if (result.termination !== "exit") {
return new Error(`Crabbox ${action} did not exit normally (${result.termination})`);
}
const exitCode = result.code === null ? "unknown" : String(result.code);
return new Error(
`Crabbox ${action} failed with exit code ${exitCode}${crabboxCommandDetail(result)}`,
);
}
export function permanentCrabboxCommandError(
action: string,
result: SpawnResult,
): WorkerProviderError {
return new WorkerProviderError(crabboxCommandError(action, result).message);
}