mirror of
https://github.com/openclaw/openclaw.git
synced 2026-07-23 14:11:18 +00:00
* feat(linux): canvas via CLI-node + Tauri app IPC bridge * refactor: extract gateway helper modules * build(linux-canvas): register plugin package in lockfile * fix(linux-canvas): move canvas advertise test out of core, regen docs/protocol/deadcode * fix(gateway): break node-catalog/registry import cycle via leaf normalize module; add canvas glossary term * style: oxfmt invoke.ts and runtime.ts after buildNodeEventParams extraction * fix(linux): load Canvas WebView via dedicated data_directory context Wry's Linux/WebKitGTK incognito mode discards Tauri's registered WebContext (wry webkitgtk/mod.rs), so the Canvas window got a fresh ephemeral context without the openclaw-canvas:// scheme handler — the bundled A2UI page never committed (stayed about:blank) and every A2UI command timed out. Use an isolated cache-backed data_directory instead, which keeps the protocol handler while still isolating Canvas storage from the dashboard window. * fix(linux): keep Canvas WebView ephemeral via incognito + data_directory Autoreview flagged that a dedicated data_directory alone persists Canvas browser state (cookies, localStorage, IndexedDB, service workers) across restarts, so an agent that navigates Canvas to a site could leak an authenticated session into a later session. iOS uses a non-persistent store; Linux should match. Add .incognito(true) alongside .data_directory(): the distinct directory gives Tauri a fresh WebContext key so it still attaches the openclaw-canvas:// protocol closure, and incognito makes Wry swap in a fresh *ephemeral* context carrying those protocols. Live-verified on a Wayland/WebKitGTK box: the bundled page still loads (location.href=openclaw-canvas://localhost/index.html, openclawA2UI present, A2UI renders) and the canvas-webview dir holds no persistent cookie/storage files.
56 lines
2.1 KiB
TypeScript
56 lines
2.1 KiB
TypeScript
// Node-host plugin command contracts, including the opt-in duplex transport.
|
|
import type { OpenClawConfig } from "../config/types.openclaw.js";
|
|
|
|
export type OpenClawPluginNodeHostCommandAvailabilityContext = {
|
|
/** Node-local configuration used to build this host's Gateway declaration. */
|
|
config: OpenClawConfig;
|
|
/** Node-host process environment. */
|
|
env: NodeJS.ProcessEnv;
|
|
};
|
|
|
|
export type OpenClawPluginNodeHostCommandIo = {
|
|
emitChunk(chunk: string): Promise<void>;
|
|
onInput(callback: (payloadJSON: string) => void): void;
|
|
signal: AbortSignal;
|
|
};
|
|
|
|
export type OpenClawPluginNodeHostCommandContext = {
|
|
/** Emit one node-owned event through the active Gateway connection. */
|
|
sendNodeEvent(event: string, payload: unknown): Promise<unknown>;
|
|
/** Agent session that owns this invocation, when the caller supplied one. */
|
|
sessionKey?: string;
|
|
};
|
|
|
|
type OpenClawPluginNodeHostCommandBase = {
|
|
command: string;
|
|
cap?: string;
|
|
dangerous?: boolean;
|
|
/** Return false to omit this command and capability from the node declaration. */
|
|
isAvailable?: (context: OpenClawPluginNodeHostCommandAvailabilityContext) => boolean;
|
|
/** Watch node-local availability and request a fresh Gateway declaration. */
|
|
watchAvailability?: (
|
|
context: OpenClawPluginNodeHostCommandAvailabilityContext,
|
|
onChange: () => void,
|
|
) => (() => void) | void;
|
|
agentTool?: {
|
|
name: string;
|
|
description: string;
|
|
parameters?: Record<string, unknown>;
|
|
/** Platforms where this tool is allowlisted by default; omit for explicit config only. */
|
|
defaultPlatforms?: Array<"ios" | "android" | "macos" | "windows" | "linux" | "unknown">;
|
|
mcp?: { server: string; tool: string };
|
|
};
|
|
};
|
|
|
|
export type OpenClawPluginNodeHostCommand = OpenClawPluginNodeHostCommandBase & {
|
|
// Not a discriminated handle signature: a union of different arities makes
|
|
// plain `command.handle(params)` uncallable for consumers holding the union.
|
|
// The node host enforces io presence for duplex commands at runtime.
|
|
duplex?: boolean;
|
|
handle: (
|
|
paramsJSON?: string | null,
|
|
io?: OpenClawPluginNodeHostCommandIo,
|
|
context?: OpenClawPluginNodeHostCommandContext,
|
|
) => Promise<string>;
|
|
};
|