import type { Command } from "commander" ;
import { runAcpClientInteractive } from "../acp/client.js" ;
import { serveAcpGateway } from "../acp/server.js" ;
import { normalizeAcpProvenanceMode } from "../acp/types.js" ;
import { defaultRuntime } from "../runtime.js" ;
import { formatDocsLink } from "../terminal/links.js" ;
import { theme } from "../terminal/theme.js" ;
import { inheritOptionFromParent } from "./command-options.js" ;
import { resolveGatewayAuthOptions } from "./gateway-secret-options.js" ;
export function registerAcpCli(program: Command) {
const acp = program.command("acp" ).description("Run an ACP bridge backed by the Gateway" );
acp
.option("--url <url>" , "Gateway WebSocket URL (defaults to gateway.remote.url when configured)" )
.option("--token <token>" , "Gateway token (if required)" )
.option("--token-file <path>" , "Read gateway token from file" )
.option("--password <password>" , "Gateway password (if required)" )
.option("--password-file <path>" , "Read gateway password from file" )
.option("--session <key>" , "Default session key (e.g. agent:main:main)" )
.option("--session-label <label>" , "Default session label to resolve" )
.option("--require-existing" , "Fail if the session key/label does not exist" , false )
.option("--reset-session" , "Reset the session key before first use" , false )
.option("--no-prefix-cwd" , "Do not prefix prompts with the working directory" , false )
.option("--provenance <mode>" , "ACP provenance mode: off, meta, or meta+receipt" )
.option("-v, --verbose" , "Verbose logging to stderr" , false )
.addHelpText(
"after" ,
() => `\n${theme.muted("Docs:" )} ${formatDocsLink("/cli/acp" , "docs.openclaw.ai/cli/acp" )}\n`,
)
.action(async (opts) => {
try {
const { gatewayToken, gatewayPassword } = resolveGatewayAuthOptions(opts);
const provenanceMode = normalizeAcpProvenanceMode(opts.provenance as string | undefined);
if (opts.provenance && !provenanceMode) {
throw new Error("Invalid --provenance value. Use off, meta, or meta+receipt." );
}
await serveAcpGateway({
gatewayUrl: opts.url as string | undefined,
gatewayToken,
gatewayPassword,
defaultSessionKey: opts.session as string | undefined,
defaultSessionLabel: opts.sessionLabel as string | undefined,
requireExistingSession: Boolean (opts.requireExisting),
resetSession: Boolean (opts.resetSession),
prefixCwd: !opts.noPrefixCwd,
provenanceMode,
verbose: Boolean (opts.verbose),
});
} catch (err) {
defaultRuntime.error(String(err));
defaultRuntime.exit(1 );
}
});
acp
.command("client" )
.description("Run an interactive ACP client against the local ACP bridge" )
.option("--cwd <dir>" , "Working directory for the ACP session" )
.option("--server <command>" , "ACP server command (default: openclaw)" )
.option("--server-args <args...>" , "Extra arguments for the ACP server" )
.option("--server-verbose" , "Enable verbose logging on the ACP server" , false )
.option("-v, --verbose" , "Verbose client logging" , false )
.action(async (opts, command) => {
const inheritedVerbose = inheritOptionFromParent<boolean >(command, "verbose" );
try {
await runAcpClientInteractive({
cwd: opts.cwd as string | undefined,
serverCommand: opts.server as string | undefined,
serverArgs: opts.serverArgs as string[] | undefined,
serverVerbose: Boolean (opts.serverVerbose),
verbose: Boolean (opts.verbose || inheritedVerbose),
});
} catch (err) {
defaultRuntime.error(String(err));
defaultRuntime.exit(1 );
}
});
}
Messung V0.5 in Prozent C=94 H=94 G=93
¤ Dauer der Verarbeitung: 0.11 Sekunden
(vorverarbeitet am 2026-06-04)
¤
*© Formatika GbR, Deutschland