@openclaw/acpx 2026.7.2-beta.1 → 2026.7.2-beta.3

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.
@@ -1,8 +1,8 @@
1
- import { n as createLazyAcpRuntimeProxy } from "./register.runtime-DBqbPx5P.js";
1
+ import { n as createLazyAcpRuntimeProxy } from "./register.runtime-BrVpU-xc.js";
2
2
  import "./config-schema-lrk5nlcV.js";
3
3
  import { a as createAcpxProcessLeaseStore, d as ACPX_GATEWAY_INSTANCE_KEY, f as ACPX_GATEWAY_INSTANCE_NAMESPACE, h as normalizeAcpxGatewayInstanceRecord, l as openAcpxProcessLeaseStateStore, n as OPENCLAW_ACPX_LEASE_ID_ENV, r as OPENCLAW_GATEWAY_INSTANCE_ID_ARG, t as OPENCLAW_ACPX_LEASE_ID_ARG } from "./process-lease-DiKkFj6F.js";
4
4
  import { registerAcpRuntimeBackend, unregisterAcpRuntimeBackend } from "./runtime-api.js";
5
- import { a as resolveAcpxPluginRoot, c as splitCommandParts, i as resolveAcpxPluginConfig, o as toAcpMcpServers, r as reapStaleOpenClawOwnedAcpxOrphans, s as quoteCommandPart, t as cleanupOpenClawOwnedAcpxProcessTree } from "./process-reaper-B29BzBk4.js";
5
+ import { a as resolveAcpxPluginRoot, c as splitCommandParts, d as LEGACY_CODEX_ACP_PACKAGE, f as OPENCLAW_CODEX_CONFIG_ARG, i as resolveAcpxPluginConfig, l as CODEX_ACP_BIN, o as toAcpMcpServers, r as reapStaleOpenClawOwnedAcpxOrphans, s as quoteCommandPart, t as cleanupOpenClawOwnedAcpxProcessTree, u as CODEX_ACP_PACKAGE } from "./process-reaper-CoGRyMJ_.js";
6
6
  import { createRequire } from "node:module";
7
7
  import { finiteSecondsToTimerSafeMilliseconds } from "openclaw/plugin-sdk/number-runtime";
8
8
  import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
@@ -15,6 +15,7 @@ import { randomUUID } from "node:crypto";
15
15
  import { inspect } from "node:util";
16
16
  import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
17
17
  import { readJsonFileWithFallback } from "openclaw/plugin-sdk/json-store";
18
+ import { parse, stringify } from "smol-toml";
18
19
  //#region extensions/acpx/src/codex-trust-config.ts
19
20
  /**
20
21
  * Builds isolated Codex config for ACPX sessions. It preserves safe inherited
@@ -225,8 +226,6 @@ function renderIsolatedCodexConfig(params) {
225
226
  * Prepares isolated Codex and Claude ACP wrapper commands for ACPX. The bridge
226
227
  * copies safe auth/config state into plugin-owned homes and redacts diagnostics.
227
228
  */
228
- const CODEX_ACP_PACKAGE = "@zed-industries/codex-acp";
229
- const CODEX_ACP_BIN = "codex-acp";
230
229
  const CLAUDE_ACP_PACKAGE = "@agentclientprotocol/claude-agent-acp";
231
230
  const CLAUDE_ACP_BIN = "claude-agent-acp";
232
231
  const RUN_CONFIGURED_COMMAND_SENTINEL = "--openclaw-run-configured";
@@ -382,7 +381,7 @@ function renderDiagnosticRedactionRuleSpecs() {
382
381
  }
383
382
  function buildAdapterWrapperScript(params) {
384
383
  return `#!/usr/bin/env node
385
- import { appendFileSync, existsSync, readFileSync, writeFileSync } from "node:fs";
384
+ import { appendFileSync, existsSync, readFileSync, rmSync, writeFileSync } from "node:fs";
386
385
  import path from "node:path";
387
386
  import { spawn } from "node:child_process";
388
387
  import { StringDecoder } from "node:string_decoder";
@@ -395,6 +394,7 @@ const stderrLogMaxChars = 256 * 1024;
395
394
  const openClawWrapperArgs = new Set([
396
395
  ${quoteCommandPart(OPENCLAW_ACPX_LEASE_ID_ARG)},
397
396
  ${quoteCommandPart(OPENCLAW_GATEWAY_INSTANCE_ID_ARG)},
397
+ ${(params.openClawWrapperArgs ?? []).map(quoteCommandPart).join(",\n ")}
398
398
  ]);
399
399
 
400
400
  function readOpenClawWrapperArg(args, name) {
@@ -406,6 +406,21 @@ function readOpenClawWrapperArg(args, name) {
406
406
  return typeof value === "string" && value.trim() ? value.trim() : undefined;
407
407
  }
408
408
 
409
+ function readOpenClawWrapperArgs(args, name) {
410
+ const values = [];
411
+ for (let index = 0; index < args.length; index += 1) {
412
+ if (args[index] !== name) {
413
+ continue;
414
+ }
415
+ const value = args[index + 1];
416
+ if (typeof value === "string" && value.trim()) {
417
+ values.push(value.trim());
418
+ }
419
+ index += 1;
420
+ }
421
+ return values;
422
+ }
423
+
409
424
  function safeDiagnosticFilePart(value) {
410
425
  const sanitized = String(value || "").replace(/[^A-Za-z0-9._-]/g, "_").slice(0, 120);
411
426
  return sanitized || "pid-" + process.pid;
@@ -550,14 +565,14 @@ function stripOpenClawWrapperArgs(args) {
550
565
  }
551
566
 
552
567
  const rawConfiguredArgs = process.argv.slice(2);
568
+ ${params.envConfigSetup ?? ""}
553
569
  const stderrLogPath = resolveStderrLogPath(rawConfiguredArgs);
554
-
555
- try {
556
- if (stderrLogPath) {
557
- writeFileSync(stderrLogPath, "", "utf8");
570
+ if (stderrLogPath) {
571
+ try {
572
+ rmSync(stderrLogPath, { force: true });
573
+ } catch {
574
+ // Diagnostic cleanup must never prevent the adapter from starting.
558
575
  }
559
- } catch {
560
- // Stderr capture is diagnostic-only; never break the ACP adapter.
561
576
  }
562
577
 
563
578
  const configuredArgs = stripOpenClawWrapperArgs(rawConfiguredArgs);
@@ -706,6 +721,7 @@ function buildCodexAcpWrapperScript(installedBinPath) {
706
721
  binName: CODEX_ACP_BIN,
707
722
  installedBinPath,
708
723
  stderrLogFileNamePrefix: "codex-acp-wrapper.stderr",
724
+ openClawWrapperArgs: [OPENCLAW_CODEX_CONFIG_ARG],
709
725
  envSetup: `const codexHome = fileURLToPath(new URL("./codex-home/", import.meta.url));
710
726
  const codexAuthPath = fileURLToPath(new URL("./codex-home/auth.json", import.meta.url));
711
727
  const codexApiKey = (process.env.CODEX_API_KEY || process.env.OPENAI_API_KEY || "").trim();
@@ -739,7 +755,59 @@ if (shouldWriteCodexApiKeyAuth) {
739
755
  const env = {
740
756
  ...process.env,
741
757
  CODEX_HOME: codexHome,
742
- };`
758
+ };`,
759
+ envConfigSetup: `function isCodexConfigObject(value) {
760
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
761
+ }
762
+
763
+ function mergeCodexConfig(base, override) {
764
+ const merged = Object.assign(Object.create(null), base);
765
+ for (const [key, value] of Object.entries(override)) {
766
+ const existing = merged[key];
767
+ merged[key] =
768
+ isCodexConfigObject(existing) && isCodexConfigObject(value)
769
+ ? mergeCodexConfig(existing, value)
770
+ : value;
771
+ }
772
+ return merged;
773
+ }
774
+
775
+ const openClawCodexConfigs = readOpenClawWrapperArgs(
776
+ rawConfiguredArgs,
777
+ ${quoteCommandPart(OPENCLAW_CODEX_CONFIG_ARG)},
778
+ );
779
+ if (openClawCodexConfigs.length > 0) {
780
+ let existingCodexConfig = {};
781
+ if (typeof env.CODEX_CONFIG === "string" && env.CODEX_CONFIG.trim()) {
782
+ try {
783
+ const parsedCodexConfig = JSON.parse(env.CODEX_CONFIG);
784
+ if (!parsedCodexConfig || typeof parsedCodexConfig !== "object" || Array.isArray(parsedCodexConfig)) {
785
+ throw new Error("CODEX_CONFIG must be a JSON object");
786
+ }
787
+ existingCodexConfig = parsedCodexConfig;
788
+ } catch {
789
+ console.error("[openclaw] CODEX_CONFIG must be a valid JSON object");
790
+ process.exit(1);
791
+ }
792
+ }
793
+ for (const openClawCodexConfig of openClawCodexConfigs) {
794
+ try {
795
+ const parsedOpenClawCodexConfig = JSON.parse(openClawCodexConfig);
796
+ if (
797
+ !parsedOpenClawCodexConfig ||
798
+ typeof parsedOpenClawCodexConfig !== "object" ||
799
+ Array.isArray(parsedOpenClawCodexConfig)
800
+ ) {
801
+ throw new Error("invalid OpenClaw Codex config");
802
+ }
803
+ existingCodexConfig = mergeCodexConfig(existingCodexConfig, parsedOpenClawCodexConfig);
804
+ } catch {
805
+ console.error("[openclaw] invalid generated Codex ACP startup config");
806
+ process.exit(1);
807
+ }
808
+ }
809
+ env.CODEX_CONFIG = JSON.stringify(existingCodexConfig);
810
+ }`
743
811
  });
744
812
  }
745
813
  function buildClaudeAcpWrapperScript(installedBinPath) {
@@ -826,15 +894,94 @@ function extractConfiguredAdapterArgs(params) {
826
894
  if (isAcpBinName(parts[0] ?? "", params.binName)) return parts.slice(1);
827
895
  if (basename(parts[0] ?? "") === "node" && isAcpBinName(parts[1] ?? "", params.binName)) return parts.slice(2);
828
896
  }
829
- function buildCodexAcpWrapperCommand(wrapperPath, configuredCommand) {
830
- const configuredAdapterArgs = extractConfiguredAdapterArgs({
897
+ function isConfigRecord(value) {
898
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
899
+ }
900
+ function mergeConfigRecords(base, override) {
901
+ const merged = { ...base };
902
+ for (const [key, value] of Object.entries(override)) {
903
+ const existing = merged[key];
904
+ const nextValue = isConfigRecord(existing) && isConfigRecord(value) ? mergeConfigRecords(existing, value) : value;
905
+ Object.defineProperty(merged, key, {
906
+ value: nextValue,
907
+ configurable: true,
908
+ enumerable: true,
909
+ writable: true
910
+ });
911
+ }
912
+ return merged;
913
+ }
914
+ function parseLegacyCodexConfigAssignment(assignment) {
915
+ const separator = assignment.indexOf("=");
916
+ if (separator <= 0) throw new Error(`Invalid legacy Codex ACP config override: ${assignment}`);
917
+ const rawKey = assignment.slice(0, separator).trim();
918
+ const key = rawKey === "use_legacy_landlock" ? "features.use_legacy_landlock" : rawKey;
919
+ const rawValue = assignment.slice(separator + 1).trim();
920
+ try {
921
+ return parse(`${key} = ${rawValue}`);
922
+ } catch {
923
+ const literal = rawValue.replace(/^["']+|["']+$/g, "");
924
+ return parse(`${key} = ${JSON.stringify(literal)}`);
925
+ }
926
+ }
927
+ function migrateLegacyCodexArgs(args) {
928
+ let config = {};
929
+ const forwardedArgs = [];
930
+ let hadOverrides = false;
931
+ for (let index = 0; index < args.length; index += 1) {
932
+ const arg = args[index] ?? "";
933
+ let assignment;
934
+ if (arg === "-c" || arg === "--config") assignment = args[index += 1];
935
+ else if (arg.startsWith("--config=")) assignment = arg.slice(9);
936
+ else if (arg.startsWith("-c=")) assignment = arg.slice(3);
937
+ else if (arg.startsWith("-c") && arg.length > 2) assignment = arg.slice(2);
938
+ else {
939
+ forwardedArgs.push(arg);
940
+ continue;
941
+ }
942
+ if (!assignment) throw new Error(`Missing value for legacy Codex ACP option ${arg}`);
943
+ hadOverrides = true;
944
+ config = mergeConfigRecords(config, parseLegacyCodexConfigAssignment(assignment));
945
+ }
946
+ return {
947
+ config,
948
+ forwardedArgs,
949
+ hadOverrides
950
+ };
951
+ }
952
+ function resolveCodexAdapterLaunch(configuredCommand) {
953
+ const legacyAdapterArgs = extractConfiguredAdapterArgs({
954
+ configuredCommand,
955
+ packageName: LEGACY_CODEX_ACP_PACKAGE,
956
+ binName: CODEX_ACP_BIN
957
+ });
958
+ if (legacyAdapterArgs) {
959
+ const migration = migrateLegacyCodexArgs(legacyAdapterArgs);
960
+ return {
961
+ args: [...migration.hadOverrides ? [OPENCLAW_CODEX_CONFIG_ARG, JSON.stringify(migration.config)] : [], ...migration.forwardedArgs],
962
+ ...migration.hadOverrides ? { migratedConfig: migration.config } : {}
963
+ };
964
+ }
965
+ const maintainedAdapterArgs = extractConfiguredAdapterArgs({
831
966
  configuredCommand,
832
967
  packageName: CODEX_ACP_PACKAGE,
833
968
  binName: CODEX_ACP_BIN
834
969
  });
835
- if (configuredAdapterArgs) return buildWrapperCommand(wrapperPath, configuredAdapterArgs);
970
+ if (!maintainedAdapterArgs) return;
971
+ return { args: maintainedAdapterArgs };
972
+ }
973
+ function buildCodexAcpWrapperCommand(wrapperPath, configuredCommand) {
974
+ const launch = resolveCodexAdapterLaunch(configuredCommand);
975
+ if (launch) return buildWrapperCommand(wrapperPath, launch.args);
836
976
  return buildWrapperCommand(wrapperPath, [RUN_CONFIGURED_COMMAND_SENTINEL, ...splitCommandParts(configuredCommand?.trim() ?? "")]);
837
977
  }
978
+ async function persistMigratedCodexMcpConfig(params) {
979
+ const mcpServers = params.migratedConfig?.mcp_servers;
980
+ if (!isConfigRecord(mcpServers)) return;
981
+ const configPath = path.join(params.codexHome, "config.toml");
982
+ const merged = mergeConfigRecords(parse(await fs$1.readFile(configPath, "utf8")), { mcp_servers: mcpServers });
983
+ await fs$1.writeFile(configPath, stringify(merged), "utf8");
984
+ }
838
985
  function buildClaudeAcpWrapperCommand(wrapperPath, configuredCommand) {
839
986
  const configuredAdapterArgs = extractConfiguredAdapterArgs({
840
987
  configuredCommand,
@@ -848,16 +995,20 @@ function buildClaudeAcpWrapperCommand(wrapperPath, configuredCommand) {
848
995
  async function prepareAcpxCodexAuthConfig(params) {
849
996
  params.logger;
850
997
  const codexBaseDir = path.join(params.stateDir, "acpx");
851
- await prepareIsolatedCodexHome({
852
- baseDir: codexBaseDir,
853
- workspaceDir: params.pluginConfig.cwd
998
+ const configuredCodexCommand = params.pluginConfig.agents.codex;
999
+ const configuredClaudeCommand = params.pluginConfig.agents.claude;
1000
+ const codexLaunch = resolveCodexAdapterLaunch(configuredCodexCommand);
1001
+ await persistMigratedCodexMcpConfig({
1002
+ codexHome: await prepareIsolatedCodexHome({
1003
+ baseDir: codexBaseDir,
1004
+ workspaceDir: params.pluginConfig.cwd
1005
+ }),
1006
+ migratedConfig: codexLaunch?.migratedConfig
854
1007
  });
855
1008
  const installedCodexBinPath = await (params.resolveInstalledCodexAcpBinPath ?? resolveInstalledCodexAcpBinPath)();
856
1009
  const installedClaudeBinPath = await (params.resolveInstalledClaudeAcpBinPath ?? resolveInstalledClaudeAcpBinPath)();
857
1010
  const wrapperPath = await writeCodexAcpWrapper(codexBaseDir, installedCodexBinPath);
858
1011
  const claudeWrapperPath = await writeClaudeAcpWrapper(codexBaseDir, installedClaudeBinPath);
859
- const configuredCodexCommand = params.pluginConfig.agents.codex;
860
- const configuredClaudeCommand = params.pluginConfig.agents.claude;
861
1012
  return {
862
1013
  ...params.pluginConfig,
863
1014
  agents: {
@@ -876,7 +1027,7 @@ async function prepareAcpxCodexAuthConfig(params) {
876
1027
  const ENABLE_STARTUP_PROBE_ENV = "OPENCLAW_ACPX_RUNTIME_STARTUP_PROBE";
877
1028
  const SKIP_RUNTIME_PROBE_ENV = "OPENCLAW_SKIP_ACPX_RUNTIME_PROBE";
878
1029
  const ACPX_BACKEND_ID = "acpx";
879
- const loadRuntimeModule = createLazyRuntimeModule(() => import("./runtime-D_fW1HnP.js"));
1030
+ const loadRuntimeModule = createLazyRuntimeModule(() => import("./runtime-CMARmJuS.js"));
880
1031
  /** Convert ACPX timeout seconds into timer-safe milliseconds. */
881
1032
  function resolveAcpxTimerTimeoutMs(timeoutSeconds) {
882
1033
  if (timeoutSeconds === void 0) return;
@@ -897,6 +1048,7 @@ function createLazyDefaultRuntime(params) {
897
1048
  agentRegistry: module.createAgentRegistry({ overrides: params.pluginConfig.agents }),
898
1049
  probeAgent: params.pluginConfig.probeAgent,
899
1050
  mcpServers: toAcpMcpServers(params.pluginConfig.mcpServers),
1051
+ pluginToolsMcpBridgeEnabled: params.pluginConfig.pluginToolsMcpBridge,
900
1052
  openclawToolsMcpBridgeEnabled: params.pluginConfig.openClawToolsMcpBridge,
901
1053
  permissionMode: params.pluginConfig.permissionMode,
902
1054
  nonInteractivePermissions: params.pluginConfig.nonInteractivePermissions,