@openclaw/acpx 2026.6.2-beta.1 → 2026.6.5-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +5 -1
- package/dist/mcp-command-line.mjs +5 -0
- package/dist/mcp-proxy.mjs +5 -0
- package/dist/{process-reaper-Dr6ilvUG.js → process-reaper-CEUqe0IY.js} +39 -0
- package/dist/{register.runtime-BhLDvIMd.js → register.runtime-DVYJo9yv.js} +9 -1
- package/dist/register.runtime.js +1 -1
- package/dist/{runtime-DqAsRsX9.js → runtime-COFrLvHN.js} +7 -1
- package/dist/{service-DnQfb40X.js → service-8gUnMlij.js} +20 -3
- package/dist/setup-api.js +4 -0
- package/npm-shrinkwrap.json +2 -2
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
|
-
import { t as createAcpxRuntimeService } from "./register.runtime-
|
|
1
|
+
import { t as createAcpxRuntimeService } from "./register.runtime-DVYJo9yv.js";
|
|
2
2
|
import { tryDispatchAcpReplyHook } from "openclaw/plugin-sdk/acp-runtime-backend";
|
|
3
3
|
//#region extensions/acpx/index.ts
|
|
4
|
+
/**
|
|
5
|
+
* ACPX runtime plugin entry. It registers the embedded ACP backend service and
|
|
6
|
+
* wires reply-dispatch hooks into the plugin SDK runtime.
|
|
7
|
+
*/
|
|
4
8
|
const plugin = {
|
|
5
9
|
id: "acpx",
|
|
6
10
|
name: "ACPX Runtime",
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Command-line parser for ACPX MCP proxy targets. It handles simple quoting and
|
|
3
|
+
* Windows executable paths before spawning the configured MCP target.
|
|
4
|
+
*/
|
|
1
5
|
const WINDOWS_DIRECT_EXECUTABLE_PATH_RE =
|
|
2
6
|
/^(?<command>(?:[A-Za-z]:[\\/]|\\\\[^\\/]+[\\/][^\\/]+[\\/]).*?\.(?:exe|com))(?=\s|$)(?:\s+(?<rest>.*))?$/i;
|
|
3
7
|
|
|
@@ -106,6 +110,7 @@ function assertSupportedWindowsCommand(command, platform = process.platform) {
|
|
|
106
110
|
);
|
|
107
111
|
}
|
|
108
112
|
|
|
113
|
+
/** Split a configured command string into `{ command, args }` for child_process.spawn. */
|
|
109
114
|
export function splitCommandLine(value, platform = process.platform) {
|
|
110
115
|
const windowsCommand = splitWindowsExecutableCommand(value, platform);
|
|
111
116
|
const parts = windowsCommand ?? splitCommandParts(value, platform);
|
package/dist/mcp-proxy.mjs
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Stdio MCP proxy used by ACPX wrappers. It injects OpenClaw-provided MCP
|
|
5
|
+
* servers into session creation/load/fork requests before forwarding to target.
|
|
6
|
+
*/
|
|
3
7
|
import { spawn } from "node:child_process";
|
|
4
8
|
import path from "node:path";
|
|
5
9
|
import { createInterface } from "node:readline";
|
|
@@ -70,6 +74,7 @@ function rewriteLine(line, mcpServers) {
|
|
|
70
74
|
}
|
|
71
75
|
}
|
|
72
76
|
|
|
77
|
+
/** Build spawn options for the proxied MCP target process. */
|
|
73
78
|
export function createTargetSpawnOptions(platform = process.platform) {
|
|
74
79
|
const options = {
|
|
75
80
|
stdio: ["pipe", "pipe", "inherit"],
|
|
@@ -11,9 +11,15 @@ import { fileURLToPath } from "node:url";
|
|
|
11
11
|
import { formatPluginConfigIssue } from "openclaw/plugin-sdk/extension-shared";
|
|
12
12
|
import { z } from "zod";
|
|
13
13
|
//#region extensions/acpx/src/command-line.ts
|
|
14
|
+
/**
|
|
15
|
+
* Small shell-command helpers for ACPX-launched processes. Splitting supports
|
|
16
|
+
* simple quoted command strings from config without invoking a shell parser.
|
|
17
|
+
*/
|
|
18
|
+
/** Quote one command argument for display or config serialization. */
|
|
14
19
|
function quoteCommandPart(value) {
|
|
15
20
|
return JSON.stringify(value);
|
|
16
21
|
}
|
|
22
|
+
/** Split a command string into argv-like parts using simple quote/backslash rules. */
|
|
17
23
|
function splitCommandParts(value) {
|
|
18
24
|
const parts = [];
|
|
19
25
|
let current = "";
|
|
@@ -53,9 +59,17 @@ function splitCommandParts(value) {
|
|
|
53
59
|
}
|
|
54
60
|
//#endregion
|
|
55
61
|
//#region extensions/acpx/src/process-lease.ts
|
|
62
|
+
/**
|
|
63
|
+
* Persistent lease store for ACPX wrapper processes. Leases let OpenClaw attach
|
|
64
|
+
* gateway/session identity to spawned ACP processes and clean them up later.
|
|
65
|
+
*/
|
|
66
|
+
/** Environment variable carrying the ACPX process lease id. */
|
|
56
67
|
const OPENCLAW_ACPX_LEASE_ID_ENV = "OPENCLAW_ACPX_LEASE_ID";
|
|
68
|
+
/** Environment variable carrying the owning gateway instance id. */
|
|
57
69
|
const OPENCLAW_GATEWAY_INSTANCE_ID_ENV = "OPENCLAW_GATEWAY_INSTANCE_ID";
|
|
70
|
+
/** CLI argument carrying the ACPX process lease id for platforms without env wrapping. */
|
|
58
71
|
const OPENCLAW_ACPX_LEASE_ID_ARG = "--openclaw-acpx-lease-id";
|
|
72
|
+
/** CLI argument carrying the owning gateway instance id. */
|
|
59
73
|
const OPENCLAW_GATEWAY_INSTANCE_ID_ARG = "--openclaw-gateway-instance-id";
|
|
60
74
|
const LEASE_FILE = "process-leases.json";
|
|
61
75
|
function normalizeLease(value) {
|
|
@@ -93,6 +107,7 @@ async function readLeaseFile(filePath) {
|
|
|
93
107
|
function writeLeaseFile(filePath, value) {
|
|
94
108
|
return writeJsonFileAtomically(filePath, value);
|
|
95
109
|
}
|
|
110
|
+
/** Create a serialized JSON-backed ACPX process lease store. */
|
|
96
111
|
function createAcpxProcessLeaseStore(params) {
|
|
97
112
|
const filePath = path.join(params.stateDir, LEASE_FILE);
|
|
98
113
|
let updateQueue = Promise.resolve();
|
|
@@ -129,9 +144,11 @@ function createAcpxProcessLeaseStore(params) {
|
|
|
129
144
|
}
|
|
130
145
|
};
|
|
131
146
|
}
|
|
147
|
+
/** Create a unique lease id for one ACPX wrapper process. */
|
|
132
148
|
function createAcpxProcessLeaseId() {
|
|
133
149
|
return randomUUID();
|
|
134
150
|
}
|
|
151
|
+
/** Hash a wrapper command so process leases can detect command drift. */
|
|
135
152
|
function hashAcpxProcessCommand(command) {
|
|
136
153
|
return createHash("sha256").update(command).digest("hex");
|
|
137
154
|
}
|
|
@@ -147,6 +164,7 @@ function appendAcpxLeaseArgs(params) {
|
|
|
147
164
|
quoteEnvValue(params.gatewayInstanceId)
|
|
148
165
|
].join(" ");
|
|
149
166
|
}
|
|
167
|
+
/** Add ACPX lease identity to a command through env vars and portable args. */
|
|
150
168
|
function withAcpxLeaseEnvironment(params) {
|
|
151
169
|
if ((params.platform ?? process.platform) === "win32") return appendAcpxLeaseArgs(params);
|
|
152
170
|
return [
|
|
@@ -158,6 +176,10 @@ function withAcpxLeaseEnvironment(params) {
|
|
|
158
176
|
}
|
|
159
177
|
//#endregion
|
|
160
178
|
//#region extensions/acpx/src/config-schema.ts
|
|
179
|
+
/**
|
|
180
|
+
* ACPX plugin configuration schema and public config types. Runtime setup uses
|
|
181
|
+
* this file as the single source of truth for validation and defaulting.
|
|
182
|
+
*/
|
|
161
183
|
const ACPX_PERMISSION_MODES = [
|
|
162
184
|
"approve-all",
|
|
163
185
|
"approve-reads",
|
|
@@ -170,6 +192,7 @@ const McpServerConfigSchema = z.object({
|
|
|
170
192
|
args: z.array(z.string({ error: "args must be an array of strings" }), { error: "args must be an array of strings" }).optional().describe("Arguments to pass to the command"),
|
|
171
193
|
env: z.record(z.string(), z.string({ error: "env values must be strings" }), { error: "env must be an object of strings" }).optional().describe("Environment variables for the MCP server")
|
|
172
194
|
});
|
|
195
|
+
/** Zod schema for validating raw ACPX plugin config from OpenClaw config. */
|
|
173
196
|
const AcpxPluginConfigSchema = z.strictObject({
|
|
174
197
|
cwd: nonEmptyTrimmedString("cwd must be a non-empty string").optional(),
|
|
175
198
|
stateDir: nonEmptyTrimmedString("stateDir must be a non-empty string").optional(),
|
|
@@ -189,6 +212,10 @@ const AcpxPluginConfigSchema = z.strictObject({
|
|
|
189
212
|
});
|
|
190
213
|
//#endregion
|
|
191
214
|
//#region extensions/acpx/src/config.ts
|
|
215
|
+
/**
|
|
216
|
+
* Resolves ACPX plugin config from raw user configuration. It locates the
|
|
217
|
+
* plugin root, injects optional MCP bridge servers, and applies runtime defaults.
|
|
218
|
+
*/
|
|
192
219
|
const ACPX_PLUGIN_TOOLS_MCP_SERVER_NAME = "openclaw-plugin-tools";
|
|
193
220
|
const ACPX_OPENCLAW_TOOLS_MCP_SERVER_NAME = "openclaw-tools";
|
|
194
221
|
const requireFromHere$1 = createRequire(import.meta.url);
|
|
@@ -229,6 +256,7 @@ function resolveAcpxPluginRootFromOpenClawLayout(moduleUrl) {
|
|
|
229
256
|
}
|
|
230
257
|
return null;
|
|
231
258
|
}
|
|
259
|
+
/** Resolve the ACPX plugin root across source, dist, and dist-runtime layouts. */
|
|
232
260
|
function resolveAcpxPluginRoot(moduleUrl = import.meta.url) {
|
|
233
261
|
const resolvedRoot = resolveNearestAcpxPluginRoot(moduleUrl);
|
|
234
262
|
return resolveWorkspaceAcpxPluginRoot(resolvedRoot) ?? resolveRepoAcpxPluginRoot(resolvedRoot) ?? resolveAcpxPluginRootFromOpenClawLayout(moduleUrl) ?? resolvedRoot;
|
|
@@ -313,6 +341,7 @@ function resolveConfiguredMcpServers(params) {
|
|
|
313
341
|
if (params.openClawToolsMcpBridge) resolved[ACPX_OPENCLAW_TOOLS_MCP_SERVER_NAME] = resolveOpenClawToolsMcpServerConfig(params.moduleUrl);
|
|
314
342
|
return resolved;
|
|
315
343
|
}
|
|
344
|
+
/** Convert OpenClaw MCP server config into ACPX runtime MCP server entries. */
|
|
316
345
|
function toAcpMcpServers(mcpServers) {
|
|
317
346
|
return Object.entries(mcpServers).map(([name, server]) => ({
|
|
318
347
|
name,
|
|
@@ -324,6 +353,7 @@ function toAcpMcpServers(mcpServers) {
|
|
|
324
353
|
}))
|
|
325
354
|
}));
|
|
326
355
|
}
|
|
356
|
+
/** Validate and normalize raw ACPX plugin config for runtime startup. */
|
|
327
357
|
function resolveAcpxPluginConfig(params) {
|
|
328
358
|
const parsed = parseAcpxPluginConfig(params.rawConfig);
|
|
329
359
|
if (!parsed.ok) throw new Error(parsed.message);
|
|
@@ -367,6 +397,10 @@ function resolveAcpxPluginConfig(params) {
|
|
|
367
397
|
}
|
|
368
398
|
//#endregion
|
|
369
399
|
//#region extensions/acpx/src/process-reaper.ts
|
|
400
|
+
/**
|
|
401
|
+
* ACPX process ownership checks and cleanup. The reaper only terminates
|
|
402
|
+
* OpenClaw-owned wrapper trees after validating paths, packages, and lease ids.
|
|
403
|
+
*/
|
|
370
404
|
const execFileAsync = promisify(execFile);
|
|
371
405
|
const requireFromHere = createRequire(import.meta.url);
|
|
372
406
|
const GENERATED_WRAPPER_BASENAMES = new Set(["codex-acp-wrapper.mjs", "claude-agent-acp-wrapper.mjs"]);
|
|
@@ -422,6 +456,7 @@ function commandWrapperBelongsToRoot(command, wrapperRoot) {
|
|
|
422
456
|
const normalizedRoot = normalizePathLike(wrapperRoot).replace(/\/+$/, "");
|
|
423
457
|
return Array.from(GENERATED_WRAPPER_BASENAMES).some((basename) => normalizedCommand.includes(`${normalizedRoot}/${basename}`));
|
|
424
458
|
}
|
|
459
|
+
/** Check whether a command references an OpenClaw-generated ACPX wrapper path. */
|
|
425
460
|
function isOpenClawLeaseAwareAcpxProcessCommand(params) {
|
|
426
461
|
const command = params.command?.trim();
|
|
427
462
|
if (!command) return false;
|
|
@@ -442,6 +477,7 @@ function liveCommandMatchesLeaseIdentity(params) {
|
|
|
442
477
|
const parts = splitCommandParts(params.command ?? "");
|
|
443
478
|
return commandOptionEquals(parts, "--openclaw-acpx-lease-id", params.expectedLeaseId) && commandOptionEquals(parts, "--openclaw-gateway-instance-id", params.expectedGatewayInstanceId);
|
|
444
479
|
}
|
|
480
|
+
/** Check whether a command is owned by OpenClaw ACPX runtime packages or wrappers. */
|
|
445
481
|
function isOpenClawOwnedAcpxProcessCommand(params) {
|
|
446
482
|
const command = params.command?.trim();
|
|
447
483
|
if (!command) return false;
|
|
@@ -467,6 +503,7 @@ function parseProcessList(stdout) {
|
|
|
467
503
|
}
|
|
468
504
|
return processes;
|
|
469
505
|
}
|
|
506
|
+
/** List host processes in the compact shape needed by ACPX cleanup. */
|
|
470
507
|
async function listPlatformProcesses() {
|
|
471
508
|
if (process.platform === "win32") return [];
|
|
472
509
|
const { stdout } = await execFileAsync("ps", ["-axo", "pid=,ppid=,command="], { maxBuffer: 8 * 1024 * 1024 });
|
|
@@ -519,6 +556,7 @@ async function terminatePids(pids, deps) {
|
|
|
519
556
|
} catch {}
|
|
520
557
|
return terminated;
|
|
521
558
|
}
|
|
559
|
+
/** Terminate one validated OpenClaw-owned ACPX wrapper process tree. */
|
|
522
560
|
async function cleanupOpenClawOwnedAcpxProcessTree(params) {
|
|
523
561
|
const rootPid = params.rootPid;
|
|
524
562
|
if (!rootPid || rootPid <= 0 || rootPid === process.pid) return {
|
|
@@ -574,6 +612,7 @@ async function cleanupOpenClawOwnedAcpxProcessTree(params) {
|
|
|
574
612
|
terminatedPids: await terminatePids(pids, params.deps)
|
|
575
613
|
};
|
|
576
614
|
}
|
|
615
|
+
/** Reap orphaned OpenClaw-owned ACPX wrapper trees during runtime startup. */
|
|
577
616
|
async function reapStaleOpenClawOwnedAcpxOrphans(params) {
|
|
578
617
|
if (process.platform === "win32") return {
|
|
579
618
|
inspectedPids: [],
|
|
@@ -125,9 +125,11 @@ function legacyRunTurnAsStartTurn(runtime, input) {
|
|
|
125
125
|
}
|
|
126
126
|
};
|
|
127
127
|
}
|
|
128
|
+
/** Start an ACP turn, adapting legacy runTurn-only runtimes when needed. */
|
|
128
129
|
function startRuntimeTurn(runtime, input) {
|
|
129
130
|
return runtime.startTurn?.(input) ?? legacyRunTurnAsStartTurn(runtime, input);
|
|
130
131
|
}
|
|
132
|
+
/** Start an ACP turn through a lazy runtime resolver. */
|
|
131
133
|
function lazyStartRuntimeTurn(resolveRuntime, input) {
|
|
132
134
|
const turnPromise = resolveRuntime().then((runtime) => startRuntimeTurn(runtime, input));
|
|
133
135
|
return {
|
|
@@ -153,6 +155,7 @@ function toLintErrorObject(value, fallbackMessage) {
|
|
|
153
155
|
}
|
|
154
156
|
//#endregion
|
|
155
157
|
//#region extensions/acpx/src/runtime-proxy.ts
|
|
158
|
+
/** Create an ACP runtime facade backed by an async runtime resolver. */
|
|
156
159
|
function createLazyAcpRuntimeProxy(resolveRuntime) {
|
|
157
160
|
return {
|
|
158
161
|
async ensureSession(input) {
|
|
@@ -195,10 +198,14 @@ function createLazyAcpRuntimeProxy(resolveRuntime) {
|
|
|
195
198
|
}
|
|
196
199
|
//#endregion
|
|
197
200
|
//#region extensions/acpx/register.runtime.ts
|
|
201
|
+
/**
|
|
202
|
+
* Lazy ACPX runtime service registration. The plugin exposes an ACP backend
|
|
203
|
+
* immediately, then imports the heavier service only when a session needs it.
|
|
204
|
+
*/
|
|
198
205
|
const ACPX_BACKEND_ID = "acpx";
|
|
199
206
|
let serviceModulePromise = null;
|
|
200
207
|
function loadServiceModule() {
|
|
201
|
-
serviceModulePromise ??= import("./service-
|
|
208
|
+
serviceModulePromise ??= import("./service-8gUnMlij.js");
|
|
202
209
|
return serviceModulePromise;
|
|
203
210
|
}
|
|
204
211
|
async function startRealService(state) {
|
|
@@ -226,6 +233,7 @@ function createDeferredRuntime(state) {
|
|
|
226
233
|
const resolveRuntime = () => startRealService(state);
|
|
227
234
|
return createLazyAcpRuntimeProxy(resolveRuntime);
|
|
228
235
|
}
|
|
236
|
+
/** Creates the plugin service that registers ACPX as an ACP runtime backend. */
|
|
229
237
|
function createAcpxRuntimeService(params = {}) {
|
|
230
238
|
const state = {
|
|
231
239
|
ctx: null,
|
package/dist/register.runtime.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as createAcpxRuntimeService } from "./register.runtime-
|
|
1
|
+
import { t as createAcpxRuntimeService } from "./register.runtime-DVYJo9yv.js";
|
|
2
2
|
export { createAcpxRuntimeService };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { AcpRuntimeError } from "./runtime-api.js";
|
|
2
|
-
import { f as hashAcpxProcessCommand, h as splitCommandParts, n as isOpenClawLeaseAwareAcpxProcessCommand, p as withAcpxLeaseEnvironment, t as cleanupOpenClawOwnedAcpxProcessTree, u as createAcpxProcessLeaseId } from "./process-reaper-
|
|
2
|
+
import { f as hashAcpxProcessCommand, h as splitCommandParts, n as isOpenClawLeaseAwareAcpxProcessCommand, p as withAcpxLeaseEnvironment, t as cleanupOpenClawOwnedAcpxProcessTree, u as createAcpxProcessLeaseId } from "./process-reaper-CEUqe0IY.js";
|
|
3
3
|
import { normalizeStringEntries } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
4
4
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
5
5
|
import fs from "node:fs/promises";
|
|
@@ -8,6 +8,10 @@ import { ACPX_BACKEND_ID, AcpxRuntime as AcpxRuntime$1, createAcpRuntime, create
|
|
|
8
8
|
import { parseStrictPositiveInteger } from "openclaw/plugin-sdk/number-runtime";
|
|
9
9
|
import { redactSensitiveText } from "openclaw/plugin-sdk/security-runtime";
|
|
10
10
|
//#region extensions/acpx/src/runtime.ts
|
|
11
|
+
/**
|
|
12
|
+
* OpenClaw ACPX runtime adapter. It wraps the upstream acpx runtime with
|
|
13
|
+
* OpenClaw session metadata, lease tracking, model scoping, and cleanup policy.
|
|
14
|
+
*/
|
|
11
15
|
function withOpenClawManagedTurnTimeout(input) {
|
|
12
16
|
return {
|
|
13
17
|
...input,
|
|
@@ -343,6 +347,7 @@ function shouldUseDistinctBridgeDelegate(options) {
|
|
|
343
347
|
const { mcpServers } = options;
|
|
344
348
|
return Array.isArray(mcpServers) && mcpServers.length > 0;
|
|
345
349
|
}
|
|
350
|
+
/** OpenClaw-managed ACP runtime implementation backed by the upstream acpx runtime. */
|
|
346
351
|
var AcpxRuntime = class {
|
|
347
352
|
constructor(options, testOptions) {
|
|
348
353
|
this.codexAcpModelOverrideScope = new AsyncLocalStorage();
|
|
@@ -712,6 +717,7 @@ var AcpxRuntime = class {
|
|
|
712
717
|
if (closeSucceeded && input.discardPersistentState) this.sessionStore.markFresh(input.handle.sessionKey);
|
|
713
718
|
}
|
|
714
719
|
};
|
|
720
|
+
/** Test-only hooks for ACPX runtime behavior that is otherwise private. */
|
|
715
721
|
const testing = {
|
|
716
722
|
appendCodexAcpConfigOverrides,
|
|
717
723
|
assertSupportedRuntimeSessionMode,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { n as createLazyAcpRuntimeProxy } from "./register.runtime-
|
|
1
|
+
import { n as createLazyAcpRuntimeProxy } from "./register.runtime-DVYJo9yv.js";
|
|
2
2
|
import { registerAcpRuntimeBackend, unregisterAcpRuntimeBackend } from "./runtime-api.js";
|
|
3
|
-
import { a as resolveAcpxPluginRoot, c as OPENCLAW_ACPX_LEASE_ID_ENV, d as createAcpxProcessLeaseStore, h as splitCommandParts, i as resolveAcpxPluginConfig, l as OPENCLAW_GATEWAY_INSTANCE_ID_ARG, m as quoteCommandPart, o as toAcpMcpServers, r as reapStaleOpenClawOwnedAcpxOrphans, s as OPENCLAW_ACPX_LEASE_ID_ARG, t as cleanupOpenClawOwnedAcpxProcessTree } from "./process-reaper-
|
|
3
|
+
import { a as resolveAcpxPluginRoot, c as OPENCLAW_ACPX_LEASE_ID_ENV, d as createAcpxProcessLeaseStore, h as splitCommandParts, i as resolveAcpxPluginConfig, l as OPENCLAW_GATEWAY_INSTANCE_ID_ARG, m as quoteCommandPart, o as toAcpMcpServers, r as reapStaleOpenClawOwnedAcpxOrphans, s as OPENCLAW_ACPX_LEASE_ID_ARG, t as cleanupOpenClawOwnedAcpxProcessTree } from "./process-reaper-CEUqe0IY.js";
|
|
4
4
|
import { createRequire } from "node:module";
|
|
5
5
|
import fs from "node:fs/promises";
|
|
6
6
|
import path from "node:path";
|
|
@@ -12,6 +12,10 @@ import fsSync from "node:fs";
|
|
|
12
12
|
import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
|
|
13
13
|
import os from "node:os";
|
|
14
14
|
//#region extensions/acpx/src/codex-trust-config.ts
|
|
15
|
+
/**
|
|
16
|
+
* Builds isolated Codex config for ACPX sessions. It preserves safe inherited
|
|
17
|
+
* runtime options while rendering only trusted project entries for the session.
|
|
18
|
+
*/
|
|
15
19
|
function stripTomlComment(line) {
|
|
16
20
|
let quote = null;
|
|
17
21
|
let escaping = false;
|
|
@@ -99,6 +103,7 @@ function parseTrustedInlineProjectEntries(value) {
|
|
|
99
103
|
}
|
|
100
104
|
return trusted;
|
|
101
105
|
}
|
|
106
|
+
/** Extract trusted project paths from Codex TOML config. */
|
|
102
107
|
function extractTrustedCodexProjectPaths(configToml) {
|
|
103
108
|
const trusted = /* @__PURE__ */ new Set();
|
|
104
109
|
let currentProjectPath;
|
|
@@ -194,6 +199,7 @@ function extractInheritedCodexRuntimeConfig(configToml) {
|
|
|
194
199
|
while (inheritedLines.length > 0 && inheritedLines[inheritedLines.length - 1] === "") inheritedLines.pop();
|
|
195
200
|
return inheritedLines.join("\n");
|
|
196
201
|
}
|
|
202
|
+
/** Render a session-local Codex config with inherited runtime settings and trust entries. */
|
|
197
203
|
function renderIsolatedCodexConfig(params) {
|
|
198
204
|
const normalized = Array.from(new Set(params.projectPaths.map((projectPath) => projectPath.trim()).filter(Boolean).map((projectPath) => path.resolve(projectPath)))).toSorted((left, right) => left.localeCompare(right));
|
|
199
205
|
return [
|
|
@@ -209,6 +215,10 @@ function renderIsolatedCodexConfig(params) {
|
|
|
209
215
|
}
|
|
210
216
|
//#endregion
|
|
211
217
|
//#region extensions/acpx/src/codex-auth-bridge.ts
|
|
218
|
+
/**
|
|
219
|
+
* Prepares isolated Codex and Claude ACP wrapper commands for ACPX. The bridge
|
|
220
|
+
* copies safe auth/config state into plugin-owned homes and redacts diagnostics.
|
|
221
|
+
*/
|
|
212
222
|
const CODEX_ACP_PACKAGE = "@zed-industries/codex-acp";
|
|
213
223
|
const CODEX_ACP_BIN = "codex-acp";
|
|
214
224
|
const CLAUDE_ACP_PACKAGE = "@agentclientprotocol/claude-agent-acp";
|
|
@@ -802,6 +812,7 @@ function buildClaudeAcpWrapperCommand(wrapperPath, configuredCommand) {
|
|
|
802
812
|
if (configuredAdapterArgs) return buildWrapperCommand(wrapperPath, configuredAdapterArgs);
|
|
803
813
|
return configuredCommand?.trim() || buildWrapperCommand(wrapperPath);
|
|
804
814
|
}
|
|
815
|
+
/** Prepare ACPX agent commands and isolated auth homes for Codex/Claude adapters. */
|
|
805
816
|
async function prepareAcpxCodexAuthConfig(params) {
|
|
806
817
|
params.logger;
|
|
807
818
|
const codexBaseDir = path.join(params.stateDir, "acpx");
|
|
@@ -826,14 +837,19 @@ async function prepareAcpxCodexAuthConfig(params) {
|
|
|
826
837
|
}
|
|
827
838
|
//#endregion
|
|
828
839
|
//#region extensions/acpx/src/service.ts
|
|
840
|
+
/**
|
|
841
|
+
* ACPX plugin service lifecycle. It resolves config, prepares isolated adapter
|
|
842
|
+
* wrappers, registers the ACP backend, and manages startup/cleanup probes.
|
|
843
|
+
*/
|
|
829
844
|
const ENABLE_STARTUP_PROBE_ENV = "OPENCLAW_ACPX_RUNTIME_STARTUP_PROBE";
|
|
830
845
|
const SKIP_RUNTIME_PROBE_ENV = "OPENCLAW_SKIP_ACPX_RUNTIME_PROBE";
|
|
831
846
|
const ACPX_BACKEND_ID = "acpx";
|
|
832
847
|
let runtimeModulePromise = null;
|
|
833
848
|
function loadRuntimeModule() {
|
|
834
|
-
runtimeModulePromise ??= import("./runtime-
|
|
849
|
+
runtimeModulePromise ??= import("./runtime-COFrLvHN.js");
|
|
835
850
|
return runtimeModulePromise;
|
|
836
851
|
}
|
|
852
|
+
/** Convert ACPX timeout seconds into timer-safe milliseconds. */
|
|
837
853
|
function resolveAcpxTimerTimeoutMs(timeoutSeconds) {
|
|
838
854
|
if (timeoutSeconds === void 0) return;
|
|
839
855
|
return finiteSecondsToTimerSafeMilliseconds(timeoutSeconds) ?? 1;
|
|
@@ -990,6 +1006,7 @@ async function reapOpenAcpxProcessLeases(params) {
|
|
|
990
1006
|
terminatedPids
|
|
991
1007
|
};
|
|
992
1008
|
}
|
|
1009
|
+
/** Create the ACPX plugin service that owns runtime registration and cleanup. */
|
|
993
1010
|
function createAcpxRuntimeService(params = {}) {
|
|
994
1011
|
let runtime = null;
|
|
995
1012
|
let lifecycleRevision = 0;
|
package/dist/setup-api.js
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
|
|
2
2
|
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
3
3
|
//#region extensions/acpx/setup-api.ts
|
|
4
|
+
/**
|
|
5
|
+
* ACPX setup plugin entry. It auto-enables setup when ACP config already points
|
|
6
|
+
* at the embedded ACPX runtime backend.
|
|
7
|
+
*/
|
|
4
8
|
var setup_api_default = definePluginEntry({
|
|
5
9
|
id: "acpx",
|
|
6
10
|
name: "ACPX Setup",
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openclaw/acpx",
|
|
3
|
-
"version": "2026.6.
|
|
3
|
+
"version": "2026.6.5-beta.1",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@openclaw/acpx",
|
|
9
|
-
"version": "2026.6.
|
|
9
|
+
"version": "2026.6.5-beta.1",
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"@agentclientprotocol/claude-agent-acp": "0.39.0",
|
|
12
12
|
"@zed-industries/codex-acp": "0.15.0",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openclaw/acpx",
|
|
3
|
-
"version": "2026.6.
|
|
3
|
+
"version": "2026.6.5-beta.1",
|
|
4
4
|
"description": "OpenClaw ACP runtime backend with plugin-owned session and transport management.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -26,10 +26,10 @@
|
|
|
26
26
|
"minHostVersion": ">=2026.4.25"
|
|
27
27
|
},
|
|
28
28
|
"compat": {
|
|
29
|
-
"pluginApi": ">=2026.6.
|
|
29
|
+
"pluginApi": ">=2026.6.5-beta.1"
|
|
30
30
|
},
|
|
31
31
|
"build": {
|
|
32
|
-
"openclawVersion": "2026.6.
|
|
32
|
+
"openclawVersion": "2026.6.5-beta.1",
|
|
33
33
|
"staticAssets": [
|
|
34
34
|
{
|
|
35
35
|
"source": "./src/runtime-internals/mcp-proxy.mjs",
|
|
@@ -58,7 +58,7 @@
|
|
|
58
58
|
"skills/**"
|
|
59
59
|
],
|
|
60
60
|
"peerDependencies": {
|
|
61
|
-
"openclaw": ">=2026.6.
|
|
61
|
+
"openclaw": ">=2026.6.5-beta.1"
|
|
62
62
|
},
|
|
63
63
|
"peerDependenciesMeta": {
|
|
64
64
|
"openclaw": {
|