mirror of
https://github.com/openclaw/openclaw.git
synced 2026-07-22 22:51:15 +00:00
Catalog session rows (sidebar context menu + click), the built-in viewer header, and a new "Open Codex/Claude sessions in" preference can launch the native CLI (codex resume / claude --resume) in the operator terminal on the machine that owns the session. - Gateway-local sessions spawn through the existing terminal launch policy (sandbox/enabled gates preserved) with the resume command in the session cwd. - Paired-node sessions run through a new seq-ordered node PTY relay: a duplex node-host command streams PTY output via node.invoke.progress and receives keystrokes/resize via a new node.invoke.input event, behind the unchanged terminal.* client protocol (TerminalSessionManager gains a backend abstraction; node relay reuses the streaming-invoke controller). - Owner boundary: each plugin owns its resume command and builds argv from a validated thread id; the gateway routes node opens through the node command allowlist and plugin invoke policy (no advertisement-only trust), and nodes re-verify session eligibility before spawning. - UI setting catalogOpenTarget + canOpenTerminal capability gate every entry point; capability requires the owning host to actually have the CLI. Node PATH is normalized before command-availability probes, Windows .cmd/.bat shims spawn via ComSpec, and catalog terminal opens reattach persisted tabs before opening the new tab.
40 lines
1.6 KiB
TypeScript
40 lines
1.6 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;
|
|
};
|
|
|
|
type OpenClawPluginNodeHostCommandBase = {
|
|
command: string;
|
|
cap?: string;
|
|
dangerous?: boolean;
|
|
/** Return false to omit this command and capability from the node declaration. */
|
|
isAvailable?: (context: OpenClawPluginNodeHostCommandAvailabilityContext) => boolean;
|
|
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) => Promise<string>;
|
|
};
|