@openclaw/acpx 2026.7.1 → 2026.7.2-beta.2

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,18 +1,21 @@
1
- import { n as createLazyAcpRuntimeProxy } from "./register.runtime-Yz704dK5.js";
1
+ import { n as createLazyAcpRuntimeProxy } from "./register.runtime-CysfMsSr.js";
2
+ import "./config-schema-lrk5nlcV.js";
2
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";
3
4
  import { registerAcpRuntimeBackend, unregisterAcpRuntimeBackend } from "./runtime-api.js";
4
- 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-cncoDfwV.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";
5
6
  import { createRequire } from "node:module";
7
+ import { finiteSecondsToTimerSafeMilliseconds } from "openclaw/plugin-sdk/number-runtime";
6
8
  import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
7
- import fs from "node:fs/promises";
9
+ import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/string-coerce-runtime";
10
+ import fs from "node:fs";
11
+ import fs$1 from "node:fs/promises";
8
12
  import path from "node:path";
13
+ import os from "node:os";
9
14
  import { randomUUID } from "node:crypto";
10
- import { finiteSecondsToTimerSafeMilliseconds } from "openclaw/plugin-sdk/number-runtime";
11
15
  import { inspect } from "node:util";
12
- import fs$1 from "node:fs";
13
16
  import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
14
- import os from "node:os";
15
17
  import { readJsonFileWithFallback } from "openclaw/plugin-sdk/json-store";
18
+ import { parse, stringify } from "smol-toml";
16
19
  //#region extensions/acpx/src/codex-trust-config.ts
17
20
  /**
18
21
  * Builds isolated Codex config for ACPX sessions. It preserves safe inherited
@@ -123,9 +126,11 @@ function extractTrustedCodexProjectPaths(configToml) {
123
126
  continue;
124
127
  }
125
128
  const assignment = /^(?<key>"(?:\\.|[^"\\])*"|'[^']*'|[A-Za-z0-9_\-/.~:]+)\s*=\s*(?<value>.+)$/.exec(line);
126
- if (!assignment?.groups) continue;
127
- const key = parseTomlString(assignment.groups.key) ?? assignment.groups.key;
128
- const value = assignment.groups.value.trim();
129
+ const rawKey = assignment?.groups?.key;
130
+ const rawValue = assignment?.groups?.value;
131
+ if (!rawKey || rawValue === void 0) continue;
132
+ const key = parseTomlString(rawKey) ?? rawKey;
133
+ const value = rawValue.trim();
129
134
  if (inProjectsTable && /^\{.*\}$/.test(value)) {
130
135
  if (/\btrust_level\s*=\s*["']trusted["']/.test(value) && key) trusted.add(key);
131
136
  continue;
@@ -221,15 +226,13 @@ function renderIsolatedCodexConfig(params) {
221
226
  * Prepares isolated Codex and Claude ACP wrapper commands for ACPX. The bridge
222
227
  * copies safe auth/config state into plugin-owned homes and redacts diagnostics.
223
228
  */
224
- const CODEX_ACP_PACKAGE = "@zed-industries/codex-acp";
225
- const CODEX_ACP_BIN = "codex-acp";
226
229
  const CLAUDE_ACP_PACKAGE = "@agentclientprotocol/claude-agent-acp";
227
230
  const CLAUDE_ACP_BIN = "claude-agent-acp";
228
231
  const RUN_CONFIGURED_COMMAND_SENTINEL = "--openclaw-run-configured";
229
232
  const requireFromHere = createRequire(import.meta.url);
230
233
  function readSelfManifest() {
231
234
  const manifestPath = path.join(resolveAcpxPluginRoot(import.meta.url), "package.json");
232
- return JSON.parse(fs$1.readFileSync(manifestPath, "utf8"));
235
+ return JSON.parse(fs.readFileSync(manifestPath, "utf8"));
233
236
  }
234
237
  function readManifestDependencyVersion(packageName) {
235
238
  const version = readSelfManifest().dependencies?.[packageName];
@@ -254,7 +257,7 @@ async function resolveInstalledAcpPackageBinPath(packageName, binName) {
254
257
  if (manifest.name !== packageName) return;
255
258
  const binPath = resolvePackageBinPath(packageJsonPath, manifest, binName);
256
259
  if (!binPath) return;
257
- await fs.access(binPath);
260
+ await fs$1.access(binPath);
258
261
  return binPath;
259
262
  } catch {
260
263
  return;
@@ -378,9 +381,10 @@ function renderDiagnosticRedactionRuleSpecs() {
378
381
  }
379
382
  function buildAdapterWrapperScript(params) {
380
383
  return `#!/usr/bin/env node
381
- import { appendFileSync, existsSync, readFileSync, writeFileSync } from "node:fs";
384
+ import { appendFileSync, existsSync, readFileSync, rmSync, writeFileSync } from "node:fs";
382
385
  import path from "node:path";
383
386
  import { spawn } from "node:child_process";
387
+ import { StringDecoder } from "node:string_decoder";
384
388
  import { fileURLToPath } from "node:url";
385
389
 
386
390
  ${params.envSetup}
@@ -390,6 +394,7 @@ const stderrLogMaxChars = 256 * 1024;
390
394
  const openClawWrapperArgs = new Set([
391
395
  ${quoteCommandPart(OPENCLAW_ACPX_LEASE_ID_ARG)},
392
396
  ${quoteCommandPart(OPENCLAW_GATEWAY_INSTANCE_ID_ARG)},
397
+ ${(params.openClawWrapperArgs ?? []).map(quoteCommandPart).join(",\n ")}
393
398
  ]);
394
399
 
395
400
  function readOpenClawWrapperArg(args, name) {
@@ -401,6 +406,21 @@ function readOpenClawWrapperArg(args, name) {
401
406
  return typeof value === "string" && value.trim() ? value.trim() : undefined;
402
407
  }
403
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
+
404
424
  function safeDiagnosticFilePart(value) {
405
425
  const sanitized = String(value || "").replace(/[^A-Za-z0-9._-]/g, "_").slice(0, 120);
406
426
  return sanitized || "pid-" + process.pid;
@@ -431,7 +451,25 @@ function redactDiagnosticText(text) {
431
451
  return redacted;
432
452
  }
433
453
 
454
+ function tailUtf16Safe(text, maxChars) {
455
+ let start = Math.max(0, text.length - maxChars);
456
+ const startsInsideSurrogatePair =
457
+ start > 0 &&
458
+ start < text.length &&
459
+ text.charCodeAt(start) >= 0xdc00 &&
460
+ text.charCodeAt(start) <= 0xdfff &&
461
+ text.charCodeAt(start - 1) >= 0xd800 &&
462
+ text.charCodeAt(start - 1) <= 0xdbff;
463
+ if (startsInsideSurrogatePair) {
464
+ start += 1;
465
+ }
466
+ return text.slice(start);
467
+ }
468
+
434
469
  let pendingStderrLogText = "";
470
+ // Pipe chunks can split a UTF-8 sequence. Preserve decoder state so diagnostic
471
+ // capture does not manufacture replacement characters between chunks.
472
+ const stderrDecoder = new StringDecoder("utf8");
435
473
  const stderrPrivateKeyEndPattern = /-----END [A-Z ]*PRIVATE KEY-----/;
436
474
 
437
475
  function hasUnclosedPrivateKeyBlock(text) {
@@ -456,7 +494,7 @@ function writeRedactedStderrLog(text) {
456
494
  appendFileSync(stderrLogPath, redactDiagnosticText(text), "utf8");
457
495
  const current = readFileSync(stderrLogPath, "utf8");
458
496
  if (current.length > stderrLogMaxChars) {
459
- writeFileSync(stderrLogPath, current.slice(-stderrLogMaxChars), "utf8");
497
+ writeFileSync(stderrLogPath, tailUtf16Safe(current, stderrLogMaxChars), "utf8");
460
498
  }
461
499
  } catch {
462
500
  // Stderr capture is diagnostic-only; never break the ACP adapter.
@@ -475,7 +513,7 @@ function flushFinalizedStderrLogText() {
475
513
  const lastLineBreak = pendingStderrLogText.lastIndexOf("\\n");
476
514
  if (lastLineBreak === -1) {
477
515
  if (pendingStderrLogText.length > stderrLogMaxChars) {
478
- pendingStderrLogText = pendingStderrLogText.slice(-stderrLogMaxChars);
516
+ pendingStderrLogText = tailUtf16Safe(pendingStderrLogText, stderrLogMaxChars);
479
517
  }
480
518
  return;
481
519
  }
@@ -488,7 +526,7 @@ function flushFinalizedStderrLogText() {
488
526
  }
489
527
  if (flushEnd <= 0) {
490
528
  if (pendingStderrLogText.length > stderrLogMaxChars) {
491
- pendingStderrLogText = pendingStderrLogText.slice(-stderrLogMaxChars);
529
+ pendingStderrLogText = tailUtf16Safe(pendingStderrLogText, stderrLogMaxChars);
492
530
  }
493
531
  return;
494
532
  }
@@ -498,7 +536,7 @@ function flushFinalizedStderrLogText() {
498
536
  }
499
537
 
500
538
  function appendStderrLog(chunk) {
501
- const text = typeof chunk === "string" ? chunk : chunk.toString("utf8");
539
+ const text = stderrDecoder.write(chunk);
502
540
  if (!text) {
503
541
  return;
504
542
  }
@@ -507,6 +545,7 @@ function appendStderrLog(chunk) {
507
545
  }
508
546
 
509
547
  function finishStderrLog() {
548
+ pendingStderrLogText += stderrDecoder.end();
510
549
  const text = redactIncompletePrivateKeyTail(pendingStderrLogText);
511
550
  pendingStderrLogText = "";
512
551
  writeRedactedStderrLog(text);
@@ -526,14 +565,14 @@ function stripOpenClawWrapperArgs(args) {
526
565
  }
527
566
 
528
567
  const rawConfiguredArgs = process.argv.slice(2);
568
+ ${params.envConfigSetup ?? ""}
529
569
  const stderrLogPath = resolveStderrLogPath(rawConfiguredArgs);
530
-
531
- try {
532
- if (stderrLogPath) {
533
- 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.
534
575
  }
535
- } catch {
536
- // Stderr capture is diagnostic-only; never break the ACP adapter.
537
576
  }
538
577
 
539
578
  const configuredArgs = stripOpenClawWrapperArgs(rawConfiguredArgs);
@@ -682,6 +721,7 @@ function buildCodexAcpWrapperScript(installedBinPath) {
682
721
  binName: CODEX_ACP_BIN,
683
722
  installedBinPath,
684
723
  stderrLogFileNamePrefix: "codex-acp-wrapper.stderr",
724
+ openClawWrapperArgs: [OPENCLAW_CODEX_CONFIG_ARG],
685
725
  envSetup: `const codexHome = fileURLToPath(new URL("./codex-home/", import.meta.url));
686
726
  const codexAuthPath = fileURLToPath(new URL("./codex-home/auth.json", import.meta.url));
687
727
  const codexApiKey = (process.env.CODEX_API_KEY || process.env.OPENAI_API_KEY || "").trim();
@@ -715,7 +755,59 @@ if (shouldWriteCodexApiKeyAuth) {
715
755
  const env = {
716
756
  ...process.env,
717
757
  CODEX_HOME: codexHome,
718
- };`
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
+ }`
719
811
  });
720
812
  }
721
813
  function buildClaudeAcpWrapperScript(installedBinPath) {
@@ -731,7 +823,7 @@ function buildClaudeAcpWrapperScript(installedBinPath) {
731
823
  }
732
824
  async function readSourceCodexConfig(codexHome) {
733
825
  try {
734
- return await fs.readFile(path.join(codexHome, "config.toml"), "utf8");
826
+ return await fs$1.readFile(path.join(codexHome, "config.toml"), "utf8");
735
827
  } catch (error) {
736
828
  if (error.code === "ENOENT") return;
737
829
  throw error;
@@ -741,8 +833,8 @@ async function prepareIsolatedCodexHome(params) {
741
833
  const sourceConfig = await readSourceCodexConfig(process.env.CODEX_HOME || path.join(os.homedir(), ".codex"));
742
834
  const trustedProjectPaths = [...sourceConfig ? extractTrustedCodexProjectPaths(sourceConfig) : [], params.workspaceDir];
743
835
  const codexHome = path.join(params.baseDir, "codex-home");
744
- await fs.mkdir(codexHome, { recursive: true });
745
- await fs.writeFile(path.join(codexHome, "config.toml"), renderIsolatedCodexConfig({
836
+ await fs$1.mkdir(codexHome, { recursive: true });
837
+ await fs$1.writeFile(path.join(codexHome, "config.toml"), renderIsolatedCodexConfig({
746
838
  sourceConfigToml: sourceConfig,
747
839
  projectPaths: trustedProjectPaths
748
840
  }), "utf8");
@@ -750,20 +842,20 @@ async function prepareIsolatedCodexHome(params) {
750
842
  }
751
843
  async function makeGeneratedWrapperExecutableIfPossible(wrapperPath) {
752
844
  try {
753
- await fs.chmod(wrapperPath, 493);
845
+ await fs$1.chmod(wrapperPath, 493);
754
846
  } catch {}
755
847
  }
756
848
  async function writeCodexAcpWrapper(baseDir, installedBinPath) {
757
- await fs.mkdir(baseDir, { recursive: true });
849
+ await fs$1.mkdir(baseDir, { recursive: true });
758
850
  const wrapperPath = path.join(baseDir, "codex-acp-wrapper.mjs");
759
- await fs.writeFile(wrapperPath, buildCodexAcpWrapperScript(installedBinPath), { encoding: "utf8" });
851
+ await fs$1.writeFile(wrapperPath, buildCodexAcpWrapperScript(installedBinPath), { encoding: "utf8" });
760
852
  await makeGeneratedWrapperExecutableIfPossible(wrapperPath);
761
853
  return wrapperPath;
762
854
  }
763
855
  async function writeClaudeAcpWrapper(baseDir, installedBinPath) {
764
- await fs.mkdir(baseDir, { recursive: true });
856
+ await fs$1.mkdir(baseDir, { recursive: true });
765
857
  const wrapperPath = path.join(baseDir, "claude-agent-acp-wrapper.mjs");
766
- await fs.writeFile(wrapperPath, buildClaudeAcpWrapperScript(installedBinPath), { encoding: "utf8" });
858
+ await fs$1.writeFile(wrapperPath, buildClaudeAcpWrapperScript(installedBinPath), { encoding: "utf8" });
767
859
  await makeGeneratedWrapperExecutableIfPossible(wrapperPath);
768
860
  return wrapperPath;
769
861
  }
@@ -802,15 +894,94 @@ function extractConfiguredAdapterArgs(params) {
802
894
  if (isAcpBinName(parts[0] ?? "", params.binName)) return parts.slice(1);
803
895
  if (basename(parts[0] ?? "") === "node" && isAcpBinName(parts[1] ?? "", params.binName)) return parts.slice(2);
804
896
  }
805
- function buildCodexAcpWrapperCommand(wrapperPath, configuredCommand) {
806
- 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({
807
966
  configuredCommand,
808
967
  packageName: CODEX_ACP_PACKAGE,
809
968
  binName: CODEX_ACP_BIN
810
969
  });
811
- 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);
812
976
  return buildWrapperCommand(wrapperPath, [RUN_CONFIGURED_COMMAND_SENTINEL, ...splitCommandParts(configuredCommand?.trim() ?? "")]);
813
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
+ }
814
985
  function buildClaudeAcpWrapperCommand(wrapperPath, configuredCommand) {
815
986
  const configuredAdapterArgs = extractConfiguredAdapterArgs({
816
987
  configuredCommand,
@@ -824,16 +995,20 @@ function buildClaudeAcpWrapperCommand(wrapperPath, configuredCommand) {
824
995
  async function prepareAcpxCodexAuthConfig(params) {
825
996
  params.logger;
826
997
  const codexBaseDir = path.join(params.stateDir, "acpx");
827
- await prepareIsolatedCodexHome({
828
- baseDir: codexBaseDir,
829
- 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
830
1007
  });
831
1008
  const installedCodexBinPath = await (params.resolveInstalledCodexAcpBinPath ?? resolveInstalledCodexAcpBinPath)();
832
1009
  const installedClaudeBinPath = await (params.resolveInstalledClaudeAcpBinPath ?? resolveInstalledClaudeAcpBinPath)();
833
1010
  const wrapperPath = await writeCodexAcpWrapper(codexBaseDir, installedCodexBinPath);
834
1011
  const claudeWrapperPath = await writeClaudeAcpWrapper(codexBaseDir, installedClaudeBinPath);
835
- const configuredCodexCommand = params.pluginConfig.agents.codex;
836
- const configuredClaudeCommand = params.pluginConfig.agents.claude;
837
1012
  return {
838
1013
  ...params.pluginConfig,
839
1014
  agents: {
@@ -852,7 +1027,7 @@ async function prepareAcpxCodexAuthConfig(params) {
852
1027
  const ENABLE_STARTUP_PROBE_ENV = "OPENCLAW_ACPX_RUNTIME_STARTUP_PROBE";
853
1028
  const SKIP_RUNTIME_PROBE_ENV = "OPENCLAW_SKIP_ACPX_RUNTIME_PROBE";
854
1029
  const ACPX_BACKEND_ID = "acpx";
855
- const loadRuntimeModule = createLazyRuntimeModule(() => import("./runtime-WjNm2DKO.js"));
1030
+ const loadRuntimeModule = createLazyRuntimeModule(() => import("./runtime-BEOGc4Ik.js"));
856
1031
  /** Convert ACPX timeout seconds into timer-safe milliseconds. */
857
1032
  function resolveAcpxTimerTimeoutMs(timeoutSeconds) {
858
1033
  if (timeoutSeconds === void 0) return;
@@ -873,6 +1048,7 @@ function createLazyDefaultRuntime(params) {
873
1048
  agentRegistry: module.createAgentRegistry({ overrides: params.pluginConfig.agents }),
874
1049
  probeAgent: params.pluginConfig.probeAgent,
875
1050
  mcpServers: toAcpMcpServers(params.pluginConfig.mcpServers),
1051
+ pluginToolsMcpBridgeEnabled: params.pluginConfig.pluginToolsMcpBridge,
876
1052
  openclawToolsMcpBridgeEnabled: params.pluginConfig.openClawToolsMcpBridge,
877
1053
  permissionMode: params.pluginConfig.permissionMode,
878
1054
  nonInteractivePermissions: params.pluginConfig.nonInteractivePermissions,
@@ -924,13 +1100,9 @@ function formatDoctorFailureMessage(report) {
924
1100
  const detailText = report.details?.map(formatDoctorDetail).filter(Boolean).join("; ").trim();
925
1101
  return detailText ? `${report.message} (${detailText})` : report.message;
926
1102
  }
927
- function normalizeProbeAgent(value) {
928
- const normalized = value?.trim().toLowerCase();
929
- return normalized ? normalized : void 0;
930
- }
931
1103
  function resolveAllowedAgentsProbeAgent(ctx) {
932
1104
  for (const agent of ctx.config.acp?.allowedAgents ?? []) {
933
- const normalized = normalizeProbeAgent(agent);
1105
+ const normalized = normalizeLowercaseStringOrEmpty(agent);
934
1106
  if (normalized) return normalized;
935
1107
  }
936
1108
  }
@@ -1043,8 +1215,8 @@ function createAcpxRuntimeService(params = {}) {
1043
1215
  }));
1044
1216
  const wrapperRoot = path.join(ctx.stateDir, "acpx");
1045
1217
  await measureAcpxStartup(ctx, "filesystem.prepare", async () => {
1046
- await fs.mkdir(pluginConfig.stateDir, { recursive: true });
1047
- await fs.mkdir(wrapperRoot, { recursive: true });
1218
+ await fs$1.mkdir(pluginConfig.stateDir, { recursive: true });
1219
+ await fs$1.mkdir(wrapperRoot, { recursive: true });
1048
1220
  });
1049
1221
  const gatewayInstanceId = await measureAcpxStartup(ctx, "gateway-instance-id", () => resolveGatewayInstanceId(openKeyedStore));
1050
1222
  const processLeaseStore = createAcpxProcessLeaseStore({ store: openAcpxProcessLeaseStateStore(openKeyedStore) });
package/dist/setup-api.js CHANGED
@@ -1,5 +1,5 @@
1
- import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
2
1
  import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/string-coerce-runtime";
2
+ import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
3
3
  //#region extensions/acpx/setup-api.ts
4
4
  /**
5
5
  * ACPX setup plugin entry. It auto-enables setup when ACP config already points