@openclaw/acpx 2026.10.10-beta.5 → 2026.11.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.
@@ -1,12 +1,13 @@
1
- import { a as isClaudeAcpCommand, c as renderAgentCommand, d as CODEX_ACP_BIN, f as CODEX_ACP_PACKAGE, i as toAcpMcpServers, l as resolveAgentCommand, m as OPENCLAW_CODEX_CONFIG_ARG, n as resolveAcpxPluginRoot, o as isCodexAcpCommand, p as LEGACY_CODEX_ACP_PACKAGE, r as resolveOpenClawRoot, s as isOpenClawBridgeCommand, t as resolveAcpxPluginConfig, u as splitCommandParts } from "./config-D0ATuiVJ.mjs";
1
+ import { a as isClaudeAcpCommand, c as renderAgentCommand, d as CODEX_ACP_BIN, f as CODEX_ACP_PACKAGE, i as toAcpMcpServers, l as resolveAgentCommand, m as OPENCLAW_CODEX_CONFIG_ARG, n as resolveAcpxPluginRoot, o as isCodexAcpCommand, p as LEGACY_CODEX_ACP_PACKAGE, r as resolveOpenClawRoot, s as isOpenClawBridgeCommand, t as resolveAcpxPluginConfig, u as splitCommandParts } from "./config-Cplh34lQ.mjs";
2
2
  import { AcpRuntimeError } from "../runtime-api.js";
3
- import { t as resolveAcpxSessionResource } from "./session-resource-DKJsUJPu.mjs";
4
- import { a as hashAcpxProcessCommand, adoptAcpxStateDirectory, c as withAcpxLeaseArgs, d as normalizeAcpxGatewayInstanceRecord, i as createAcpxProcessLeaseStore, l as ACPX_GATEWAY_INSTANCE_KEY, n as OPENCLAW_ACPX_LEASE_ID_ARG, o as openAcpxProcessLeaseStateStore, r as OPENCLAW_GATEWAY_INSTANCE_ID_ARG, s as readAcpxProcessLeaseIdentity, t as ACPX_PROBE_LEASE_SESSION_KEY, u as ACPX_GATEWAY_INSTANCE_NAMESPACE } from "./session-owner-migration-duvwZfxk.mjs";
3
+ import { t as resolveAcpxSessionResource } from "./session-resource-D_tXKvcv.mjs";
4
+ import { a as hashAcpxProcessCommand, adoptAcpxStateDirectory, c as withAcpxLeaseArgs, d as normalizeAcpxGatewayInstanceRecord, i as createAcpxProcessLeaseStore, l as ACPX_GATEWAY_INSTANCE_KEY, n as OPENCLAW_ACPX_LEASE_ID_ARG, o as openAcpxProcessLeaseStateStore, r as OPENCLAW_GATEWAY_INSTANCE_ID_ARG, s as readAcpxProcessLeaseIdentity, t as ACPX_PROBE_LEASE_SESSION_KEY, u as ACPX_GATEWAY_INSTANCE_NAMESPACE } from "./session-owner-migration-CQA7L68K.mjs";
5
5
  import { createRequire } from "node:module";
6
- import { finiteSecondsToTimerSafeMilliseconds, parseStrictPositiveInteger } from "openclaw/plugin-sdk/number-runtime";
6
+ import { finiteSecondsToTimerSafeMilliseconds } from "openclaw/plugin-sdk/number-runtime";
7
7
  import fs from "node:fs";
8
8
  import path from "node:path";
9
- import { asOptionalObjectRecord, isRecord, normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, normalizeOptionalString, normalizeStringEntries } from "openclaw/plugin-sdk/string-coerce-runtime";
9
+ import { isPidAlive, runExec } from "openclaw/plugin-sdk/process-runtime";
10
+ import { isRecord, normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, normalizeStringEntries } from "openclaw/plugin-sdk/string-coerce-runtime";
10
11
  import os, { availableParallelism } from "node:os";
11
12
  import { randomUUID } from "node:crypto";
12
13
  import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
@@ -17,12 +18,11 @@ import { raceWithTimeout } from "openclaw/plugin-sdk/time-runtime";
17
18
  import { tryReadJson } from "@openclaw/fs-safe/json";
18
19
  import { parse, stringify } from "smol-toml";
19
20
  import { setTimeout } from "node:timers/promises";
20
- import { isPidAlive, runExec } from "openclaw/plugin-sdk/process-runtime";
21
21
  import { AsyncLocalStorage } from "node:async_hooks";
22
22
  import { isDeepStrictEqual } from "node:util";
23
23
  import { redactSensitiveText } from "openclaw/plugin-sdk/security-runtime";
24
24
  import { KeyedAsyncQueue } from "openclaw/plugin-sdk/keyed-async-queue";
25
- //#region extensions/acpx/src/adapter-wrapper-script.ts
25
+ // extensions/acpx/src/adapter-wrapper-script.ts
26
26
  const RUN_CONFIGURED_COMMAND_SENTINEL = "--openclaw-run-configured";
27
27
  const DIAGNOSTIC_REDACTION_RULES = [
28
28
  {
@@ -441,9 +441,7 @@ const parentWatcher =
441
441
  return;
442
442
  }
443
443
  orphanCleanupStarted = true;
444
- if (parentWatcher) {
445
- clearInterval(parentWatcher);
446
- }
444
+ clearInterval(parentWatcher);
447
445
  killChildTree("SIGTERM");
448
446
  // Keep the wrapper alive long enough for stubborn adapters to receive
449
447
  // a forced fallback signal after SIGTERM.
@@ -479,9 +477,7 @@ child.on("exit", (code, signal) => {
479
477
 
480
478
  child.on("close", () => {
481
479
  finishStderrLog();
482
- if (parentWatcher) {
483
- clearInterval(parentWatcher);
484
- }
480
+ clearInterval(parentWatcher);
485
481
  childClosed = true;
486
482
  finishWrapper();
487
483
  });
@@ -489,123 +485,7 @@ child.on("close", () => {
489
485
  main();
490
486
  `;
491
487
  }
492
- //#endregion
493
- //#region extensions/acpx/src/codex-trust-config.ts
494
- function stripTomlComment(line) {
495
- let quote = null;
496
- let escaping = false;
497
- for (let index = 0; index < line.length; index += 1) {
498
- const ch = line[index];
499
- if (escaping) {
500
- escaping = false;
501
- continue;
502
- }
503
- if (quote === "\"" && ch === "\\") {
504
- escaping = true;
505
- continue;
506
- }
507
- if (quote) {
508
- if (ch === quote) quote = null;
509
- continue;
510
- }
511
- if (ch === "'" || ch === "\"") {
512
- quote = ch;
513
- continue;
514
- }
515
- if (ch === "#") return line.slice(0, index);
516
- }
517
- return line;
518
- }
519
- function parseTomlString(value) {
520
- const trimmed = value.trim();
521
- if (trimmed.startsWith("\"") && trimmed.endsWith("\"")) try {
522
- return JSON.parse(trimmed);
523
- } catch {
524
- return;
525
- }
526
- if (trimmed.startsWith("'") && trimmed.endsWith("'")) return trimmed.slice(1, -1);
527
- }
528
- function parseTomlDottedKey(value) {
529
- const parts = [];
530
- let current = "";
531
- let quote = null;
532
- let escaping = false;
533
- for (const ch of value.trim()) {
534
- if (escaping) {
535
- current += ch;
536
- escaping = false;
537
- continue;
538
- }
539
- if (quote === "\"" && ch === "\\") {
540
- current += ch;
541
- escaping = true;
542
- continue;
543
- }
544
- if (quote) {
545
- current += ch;
546
- if (ch === quote) quote = null;
547
- continue;
548
- }
549
- if (ch === "'" || ch === "\"") {
550
- quote = ch;
551
- current += ch;
552
- continue;
553
- }
554
- if (ch === ".") {
555
- parts.push(current.trim());
556
- current = "";
557
- continue;
558
- }
559
- current += ch;
560
- }
561
- if (current.trim()) parts.push(current.trim());
562
- return parts.map((part) => parseTomlString(part) ?? part);
563
- }
564
- function parseProjectHeader(line) {
565
- const parts = parseTableHeader(line);
566
- return parts?.length === 2 && parts[0] === "projects" ? parts[1] : void 0;
567
- }
568
- function parseTrustedInlineProjectEntries(value) {
569
- const trusted = [];
570
- for (const match of value.matchAll(/(?<key>"(?:\\.|[^"\\])*"|'[^']*'|[A-Za-z0-9_\-/.~:]+)\s*=\s*\{(?<body>[^{}]*(?:\{[^{}]*\}[^{}]*)*)\}/g)) {
571
- const key = match.groups?.key;
572
- const body = match.groups?.body;
573
- if (!key || !body || !/\btrust_level\s*=\s*["']trusted["']/.test(body)) continue;
574
- const projectPath = parseTomlString(key) ?? key.trim();
575
- if (projectPath) trusted.push(projectPath);
576
- }
577
- return trusted;
578
- }
579
- function extractTrustedCodexProjectPaths(configToml) {
580
- const trusted = /* @__PURE__ */ new Set();
581
- let currentProjectPath;
582
- let inProjectsTable = false;
583
- for (const rawLine of configToml.split(/\r?\n/)) {
584
- const line = stripTomlComment(rawLine).trim();
585
- if (!line) continue;
586
- if (line.startsWith("[")) {
587
- currentProjectPath = parseProjectHeader(line);
588
- inProjectsTable = line === "[projects]";
589
- continue;
590
- }
591
- if (currentProjectPath && /^trust_level\s*=\s*["']trusted["']\s*$/.test(line)) {
592
- trusted.add(currentProjectPath);
593
- continue;
594
- }
595
- const assignment = /^(?<key>"(?:\\.|[^"\\])*"|'[^']*'|[A-Za-z0-9_\-/.~:]+)\s*=\s*(?<value>.+)$/.exec(line);
596
- const rawKey = assignment?.groups?.key;
597
- const rawValue = assignment?.groups?.value;
598
- if (!rawKey || rawValue === void 0) continue;
599
- const key = parseTomlString(rawKey) ?? rawKey;
600
- const value = rawValue.trim();
601
- if (inProjectsTable && /^\{.*\}$/.test(value)) {
602
- if (/\btrust_level\s*=\s*["']trusted["']/.test(value) && key) trusted.add(key);
603
- continue;
604
- }
605
- if (key === "projects" || inProjectsTable) for (const projectPath of parseTrustedInlineProjectEntries(value)) trusted.add(projectPath);
606
- }
607
- return Array.from(trusted);
608
- }
488
+ // extensions/acpx/src/codex-trust-config.ts
609
489
  const INHERITED_TOP_LEVEL_CODEX_CONFIG_KEYS = /* @__PURE__ */ new Set([
610
490
  "model",
611
491
  "model_provider",
@@ -623,61 +503,30 @@ const INHERITED_MODEL_PROVIDER_CONFIG_KEYS = /* @__PURE__ */ new Set([
623
503
  "stream_max_retries",
624
504
  "stream_idle_timeout_ms"
625
505
  ]);
626
- function parseTableHeader(line) {
627
- const trimmed = line.trim();
628
- if (!trimmed.startsWith("[") || !trimmed.endsWith("]") || trimmed.startsWith("[[")) return;
629
- return parseTomlDottedKey(trimmed.slice(1, -1));
630
- }
631
- function isInheritedModelProviderTable(parts) {
632
- return parts?.[0] === "model_providers" && parts.length === 2;
633
- }
634
- function parseTopLevelAssignmentKey(line) {
635
- return /^(?<key>[A-Za-z0-9_-]+)\s*=\s*(?<value>.+)$/.exec(line)?.groups?.key;
636
- }
637
- function extractInheritedCodexRuntimeConfig(configToml) {
638
- const inheritedLines = [];
639
- let inAnyTable = false;
640
- let inInheritedTable = false;
641
- let pendingInheritedTableHeader = "";
642
- function flushInheritedTableHeader() {
643
- if (!pendingInheritedTableHeader) return;
644
- if (inheritedLines.length > 0 && inheritedLines[inheritedLines.length - 1] !== "") inheritedLines.push("");
645
- inheritedLines.push(pendingInheritedTableHeader);
646
- pendingInheritedTableHeader = "";
647
- }
648
- for (const rawLine of configToml.split(/\r?\n/)) {
649
- const trimmedLine = rawLine.trim();
650
- const semanticLine = stripTomlComment(rawLine).trim();
651
- if (trimmedLine.startsWith("[")) {
652
- const tableParts = parseTableHeader(trimmedLine);
653
- inAnyTable = true;
654
- inInheritedTable = isInheritedModelProviderTable(tableParts);
655
- if (inInheritedTable) pendingInheritedTableHeader = rawLine.trimEnd();
656
- else pendingInheritedTableHeader = "";
657
- continue;
658
- }
659
- if (inInheritedTable) {
660
- if (!semanticLine) continue;
661
- const key = parseTopLevelAssignmentKey(semanticLine);
662
- if (!key || !INHERITED_MODEL_PROVIDER_CONFIG_KEYS.has(key)) continue;
663
- flushInheritedTableHeader();
664
- inheritedLines.push(rawLine.trimEnd());
665
- continue;
666
- }
667
- if (inAnyTable) continue;
668
- const key = parseTopLevelAssignmentKey(semanticLine);
669
- if (!key) continue;
670
- if (!INHERITED_TOP_LEVEL_CODEX_CONFIG_KEYS.has(key)) continue;
671
- inheritedLines.push(rawLine.trimEnd());
672
- }
673
- return inheritedLines.join("\n");
674
- }
675
506
  function renderIsolatedCodexConfig(params) {
676
- 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));
507
+ let source = {};
508
+ if (params.sourceConfigToml) try {
509
+ source = parse(params.sourceConfigToml, { integersAsBigInt: true });
510
+ } catch {
511
+ throw new Error("Codex config.toml must be valid TOML before starting an ACP session.");
512
+ }
513
+ const providers = /* @__PURE__ */ new Map();
514
+ if (isRecord(source.model_providers)) for (const [name, provider] of Object.entries(source.model_providers)) {
515
+ if (!isRecord(provider)) continue;
516
+ const config = Object.fromEntries(Object.entries(provider).filter(([key]) => INHERITED_MODEL_PROVIDER_CONFIG_KEYS.has(key)));
517
+ if (Object.keys(config).length) providers.set(name, config);
518
+ }
519
+ const inherited = {
520
+ ...Object.fromEntries(Object.entries(source).filter(([key]) => INHERITED_TOP_LEVEL_CODEX_CONFIG_KEYS.has(key))),
521
+ ...providers.size ? { model_providers: Object.fromEntries(providers) } : {},
522
+ ...params.mcpServers ? { mcp_servers: params.mcpServers } : {}
523
+ };
524
+ const trustedProjects = isRecord(source.projects) ? Object.entries(source.projects).filter(([, project]) => isRecord(project) && project.trust_level === "trusted").map(([projectPath]) => projectPath) : [];
525
+ const projectPaths = Array.from(new Set([...params.projectPaths, ...trustedProjects].map((projectPath) => projectPath.trim()).filter(Boolean).map((projectPath) => path.resolve(projectPath)))).toSorted((left, right) => left.localeCompare(right));
677
526
  return [
678
527
  "# Generated by OpenClaw for Codex ACP sessions.",
679
- params.sourceConfigToml ? extractInheritedCodexRuntimeConfig(params.sourceConfigToml) : "",
680
- ...normalized.flatMap((projectPath) => [
528
+ stringify(inherited, { numbersAsFloat: true }).trimEnd(),
529
+ ...projectPaths.flatMap((projectPath) => [
681
530
  "",
682
531
  `[projects.${JSON.stringify(projectPath)}]`,
683
532
  "trust_level = \"trusted\""
@@ -685,8 +534,7 @@ function renderIsolatedCodexConfig(params) {
685
534
  ""
686
535
  ].filter((line, index, lines) => !(line === "" && lines[index - 1] === "")).join("\n");
687
536
  }
688
- //#endregion
689
- //#region extensions/acpx/src/codex-auth-bridge.ts
537
+ // extensions/acpx/src/codex-auth-bridge.ts
690
538
  /**
691
539
  * Prepares isolated Codex and Claude ACP wrapper commands for ACPX. The bridge
692
540
  * copies safe auth/config state into plugin-owned homes and redacts diagnostics.
@@ -846,17 +694,15 @@ async function readSourceCodexConfig(codexHome) {
846
694
  }
847
695
  async function prepareIsolatedCodexHome(params) {
848
696
  const sourceConfig = await readSourceCodexConfig(process.env.CODEX_HOME || path.join(os.homedir(), ".codex"));
849
- const trustedProjectPaths = [...sourceConfig ? extractTrustedCodexProjectPaths(sourceConfig) : [], params.workspaceDir];
850
697
  const codexHome = path.join(params.baseDir, "codex-home");
851
698
  await fs$1.mkdir(codexHome, { recursive: true });
852
699
  await fs$1.writeFile(path.join(codexHome, "config.toml"), renderIsolatedCodexConfig({
853
700
  sourceConfigToml: sourceConfig,
854
- projectPaths: trustedProjectPaths
701
+ projectPaths: [params.workspaceDir],
702
+ mcpServers: isRecord(params.migratedConfig?.mcp_servers) ? params.migratedConfig.mcp_servers : void 0
855
703
  }), "utf8");
856
- return codexHome;
857
704
  }
858
705
  async function writeAdapterWrapper(baseDir, fileName, script) {
859
- await fs$1.mkdir(baseDir, { recursive: true });
860
706
  const wrapperPath = path.join(baseDir, fileName);
861
707
  await fs$1.writeFile(wrapperPath, script, { encoding: "utf8" });
862
708
  try {
@@ -968,13 +814,6 @@ function resolveCodexAdapterLaunch(configuredCommand) {
968
814
  if (!maintainedAdapterArgs) return;
969
815
  return { args: maintainedAdapterArgs };
970
816
  }
971
- async function persistMigratedCodexMcpConfig(params) {
972
- const mcpServers = params.migratedConfig?.mcp_servers;
973
- if (!isRecord(mcpServers)) return;
974
- const configPath = path.join(params.codexHome, "config.toml");
975
- const merged = mergeConfigRecords(parse(await fs$1.readFile(configPath, "utf8")), { mcp_servers: mcpServers });
976
- await fs$1.writeFile(configPath, stringify(merged), "utf8");
977
- }
978
817
  function buildClaudeAcpWrapperCommand(wrapperPath, configuredCommand) {
979
818
  const configuredAdapterArgs = extractConfiguredAdapterArgs({
980
819
  configuredCommand,
@@ -990,17 +829,15 @@ async function prepareAcpxCodexAuthConfig(params) {
990
829
  const configuredCodexCommand = params.pluginConfig.agents.codex;
991
830
  const configuredClaudeCommand = params.pluginConfig.agents.claude;
992
831
  const codexLaunch = resolveCodexAdapterLaunch(configuredCodexCommand);
993
- await persistMigratedCodexMcpConfig({
994
- codexHome: await prepareIsolatedCodexHome({
995
- baseDir: codexBaseDir,
996
- workspaceDir: params.pluginConfig.cwd
997
- }),
832
+ await prepareIsolatedCodexHome({
833
+ baseDir: codexBaseDir,
834
+ workspaceDir: params.pluginConfig.cwd,
998
835
  migratedConfig: codexLaunch?.migratedConfig
999
836
  });
1000
- const installedCodexBinPath = await (params.resolveInstalledCodexAcpBinPath ? params.resolveInstalledCodexAcpBinPath() : resolveInstalledAcpPackageBinPath(CODEX_ACP_PACKAGE, CODEX_ACP_BIN));
1001
- const installedClaudeBinPath = await (params.resolveInstalledClaudeAcpBinPath ? params.resolveInstalledClaudeAcpBinPath() : resolveInstalledAcpPackageBinPath(CLAUDE_ACP_PACKAGE, CLAUDE_ACP_BIN));
1002
- const wrapperPath = await writeAdapterWrapper(codexBaseDir, "codex-acp-wrapper.mjs", buildCodexAcpWrapperScript(installedCodexBinPath));
1003
- const claudeWrapperPath = await writeAdapterWrapper(codexBaseDir, "claude-agent-acp-wrapper.mjs", buildClaudeAcpWrapperScript(installedClaudeBinPath));
837
+ const codexBinPath = await resolveInstalledAcpPackageBinPath(CODEX_ACP_PACKAGE, CODEX_ACP_BIN);
838
+ const claudeBinPath = await resolveInstalledAcpPackageBinPath(CLAUDE_ACP_PACKAGE, CLAUDE_ACP_BIN);
839
+ const wrapperPath = await writeAdapterWrapper(codexBaseDir, "codex-acp-wrapper.mjs", buildCodexAcpWrapperScript(codexBinPath));
840
+ const claudeWrapperPath = await writeAdapterWrapper(codexBaseDir, "claude-agent-acp-wrapper.mjs", buildClaudeAcpWrapperScript(claudeBinPath));
1004
841
  return {
1005
842
  ...params.pluginConfig,
1006
843
  agents: {
@@ -1010,8 +847,7 @@ async function prepareAcpxCodexAuthConfig(params) {
1010
847
  }
1011
848
  };
1012
849
  }
1013
- //#endregion
1014
- //#region extensions/acpx/src/process-reaper.ts
850
+ // extensions/acpx/src/process-reaper.ts
1015
851
  /**
1016
852
  * ACPX process ownership checks and cleanup. The reaper only terminates
1017
853
  * OpenClaw-owned wrapper trees after validating paths, packages, and lease ids.
@@ -1127,12 +963,16 @@ function parseProcessList(stdout) {
1127
963
  }
1128
964
  async function listPlatformProcesses() {
1129
965
  if (process.platform === "win32") return [];
1130
- const { stdout } = await runExec("ps", ["-axo", "pid=,ppid=,command="], {
1131
- logOutput: false,
1132
- maxBuffer: 8388608,
1133
- timeoutMs: ACPX_PROCESS_LIST_TIMEOUT_MS
1134
- });
1135
- return parseProcessList(stdout);
966
+ try {
967
+ const { stdout } = await runExec("ps", ["-axo", "pid=,ppid=,command="], {
968
+ logOutput: false,
969
+ maxBuffer: 8388608,
970
+ timeoutMs: ACPX_PROCESS_LIST_TIMEOUT_MS
971
+ });
972
+ return parseProcessList(stdout);
973
+ } catch {
974
+ return;
975
+ }
1136
976
  }
1137
977
  function collectProcessTree(processes, rootPid) {
1138
978
  const childrenByParent = /* @__PURE__ */ new Map();
@@ -1141,7 +981,7 @@ function collectProcessTree(processes, rootPid) {
1141
981
  children.push(processInfo);
1142
982
  childrenByParent.set(processInfo.ppid, children);
1143
983
  }
1144
- const root = new Map(processes.map((processInfo) => [processInfo.pid, processInfo])).get(rootPid);
984
+ const root = processes.find((processInfo) => processInfo.pid === rootPid);
1145
985
  const collected = [];
1146
986
  if (root) collected.push(root);
1147
987
  const queue = [...childrenByParent.get(rootPid) ?? []];
@@ -1179,28 +1019,20 @@ async function terminatePids(pids, assertCurrent) {
1179
1019
  async function cleanupOpenClawOwnedAcpxProcessTree(params) {
1180
1020
  const rootPid = params.rootPid;
1181
1021
  if (!rootPid || rootPid <= 0 || rootPid === process.pid) return {
1182
- inspectedPids: [],
1183
1022
  terminatedPids: [],
1184
1023
  skippedReason: "missing-root"
1185
1024
  };
1186
1025
  if (process.platform === "win32") return {
1187
- inspectedPids: [],
1188
1026
  terminatedPids: [],
1189
1027
  skippedReason: "unsupported-platform"
1190
1028
  };
1191
- let processes;
1192
- try {
1193
- processes = await listPlatformProcesses();
1194
- } catch {
1195
- return {
1196
- inspectedPids: [],
1197
- terminatedPids: [],
1198
- skippedReason: "process-list-unavailable"
1199
- };
1200
- }
1029
+ const processes = await listPlatformProcesses();
1030
+ if (!processes) return {
1031
+ terminatedPids: [],
1032
+ skippedReason: "process-list-unavailable"
1033
+ };
1201
1034
  const listedTree = collectProcessTree(processes, rootPid);
1202
1035
  if (listedTree.length === 0) return {
1203
- inspectedPids: [],
1204
1036
  terminatedPids: [],
1205
1037
  skippedReason: "unverified-root"
1206
1038
  };
@@ -1215,88 +1047,58 @@ async function cleanupOpenClawOwnedAcpxProcessTree(params) {
1215
1047
  expectedLeaseId: params.expectedLeaseId,
1216
1048
  expectedGatewayInstanceId: params.expectedGatewayInstanceId
1217
1049
  })) return {
1218
- inspectedPids: listedTree.map((processInfo) => processInfo.pid),
1219
1050
  terminatedPids: [],
1220
1051
  skippedReason: "not-openclaw-owned"
1221
1052
  };
1222
- const pids = uniquePids(listedTree.toReversed());
1223
- return {
1224
- inspectedPids: uniquePids(listedTree),
1225
- terminatedPids: await terminatePids(pids, params.assertCurrent)
1226
- };
1053
+ return { terminatedPids: await terminatePids(uniquePids(listedTree.toReversed()), params.assertCurrent) };
1227
1054
  }
1228
1055
  /** Recover a pending lease by matching its exact live wrapper identity. */
1229
1056
  async function cleanupOpenClawOwnedAcpxPendingLease(params) {
1230
1057
  if (process.platform === "win32") return {
1231
- inspectedPids: [],
1232
1058
  terminatedPids: [],
1233
1059
  skippedReason: "unsupported-platform"
1234
1060
  };
1235
1061
  if (!params.wrapperPath || !wrapperPathBelongsToRoot(params.wrapperPath, params.wrapperRoot)) return {
1236
- inspectedPids: [],
1237
1062
  terminatedPids: [],
1238
1063
  skippedReason: "unverified-root"
1239
1064
  };
1240
- let processes;
1241
- try {
1242
- processes = await listPlatformProcesses();
1243
- } catch {
1244
- return {
1245
- inspectedPids: [],
1246
- terminatedPids: [],
1247
- skippedReason: "process-list-unavailable"
1248
- };
1249
- }
1065
+ const processes = await listPlatformProcesses();
1066
+ if (!processes) return {
1067
+ terminatedPids: [],
1068
+ skippedReason: "process-list-unavailable"
1069
+ };
1250
1070
  const matchingRoots = processes.filter((processInfo) => commandContainsExactWrapperPath(processInfo.command, params.wrapperPath) && liveCommandMatchesLeaseIdentity({
1251
1071
  command: processInfo.command,
1252
1072
  expectedLeaseId: params.leaseId,
1253
1073
  expectedGatewayInstanceId: params.gatewayInstanceId
1254
1074
  }));
1255
1075
  if (matchingRoots.length === 0) return {
1256
- inspectedPids: [],
1257
1076
  terminatedPids: [],
1258
1077
  skippedReason: "missing-root"
1259
1078
  };
1260
1079
  if (matchingRoots.length > 1) return {
1261
- inspectedPids: uniquePids(matchingRoots),
1262
1080
  terminatedPids: [],
1263
1081
  skippedReason: "ambiguous-root"
1264
1082
  };
1265
- const listedTree = collectProcessTree(processes, matchingRoots[0].pid);
1266
- const pids = uniquePids(listedTree.toReversed());
1267
- return {
1268
- inspectedPids: uniquePids(listedTree),
1269
- terminatedPids: await terminatePids(pids, params.assertCurrent)
1270
- };
1083
+ return { terminatedPids: await terminatePids(uniquePids(collectProcessTree(processes, matchingRoots[0].pid).toReversed()), params.assertCurrent) };
1271
1084
  }
1272
1085
  /** Reap orphaned OpenClaw-owned ACPX wrapper trees during runtime startup. */
1273
1086
  async function reapStaleOpenClawOwnedAcpxOrphans(params) {
1274
1087
  if (process.platform === "win32") return {
1275
- inspectedPids: [],
1276
1088
  terminatedPids: [],
1277
1089
  skippedReason: "unsupported-platform"
1278
1090
  };
1279
- let processes;
1280
- try {
1281
- processes = await listPlatformProcesses();
1282
- } catch {
1283
- return {
1284
- inspectedPids: [],
1285
- terminatedPids: [],
1286
- skippedReason: "process-list-unavailable"
1287
- };
1288
- }
1289
- const orphanTrees = processes.filter((processInfo) => processInfo.ppid === 1 && !readAcpxProcessLeaseIdentity(processInfo.command) && isOpenClawOwnedAcpxProcessCommand({
1091
+ const processes = await listPlatformProcesses();
1092
+ if (!processes) return {
1093
+ terminatedPids: [],
1094
+ skippedReason: "process-list-unavailable"
1095
+ };
1096
+ return { terminatedPids: await terminatePids(uniquePids(processes.filter((processInfo) => processInfo.ppid === 1 && !readAcpxProcessLeaseIdentity(processInfo.command) && isOpenClawOwnedAcpxProcessCommand({
1290
1097
  command: processInfo.command,
1291
1098
  wrapperRoot: params.wrapperRoot
1292
- })).map((orphan) => collectProcessTree(processes, orphan.pid));
1293
- return {
1294
- inspectedPids: uniquePids(orphanTrees.flat()),
1295
- terminatedPids: await terminatePids(uniquePids(orphanTrees.flatMap((tree) => tree.toReversed())), params.assertCurrent)
1296
- };
1099
+ })).map((orphan) => collectProcessTree(processes, orphan.pid)).flatMap((tree) => tree.toReversed())), params.assertCurrent) };
1297
1100
  }
1298
- //#endregion
1299
- //#region extensions/acpx/src/model-ref.ts
1101
+ // extensions/acpx/src/model-ref.ts
1300
1102
  function withAcpxSessionOptions(input) {
1301
1103
  const model = input.model?.trim() || input.sessionOptions?.model;
1302
1104
  const sessionOptions = model ? {
@@ -1335,8 +1137,7 @@ async function ensureSessionWithModelRef(ensureSession, input) {
1335
1137
  };
1336
1138
  }
1337
1139
  }
1338
- //#endregion
1339
- //#region extensions/acpx/src/runtime-generations.ts
1140
+ // extensions/acpx/src/runtime-generations.ts
1340
1141
  var AcpxGenerationRegistry = class {
1341
1142
  constructor(sessionStore, delegate, createDelegate) {
1342
1143
  this.sessionStore = sessionStore;
@@ -1461,8 +1262,7 @@ var AcpxGenerationRegistry = class {
1461
1262
  this.isolatedSessionResources.clear();
1462
1263
  }
1463
1264
  };
1464
- //#endregion
1465
- //#region extensions/acpx/src/runtime-probe.ts
1265
+ // extensions/acpx/src/runtime-probe.ts
1466
1266
  var AcpxRuntimeProbe = class {
1467
1267
  constructor(params) {
1468
1268
  this.params = params;
@@ -1495,8 +1295,7 @@ var AcpxRuntimeProbe = class {
1495
1295
  await this.tail;
1496
1296
  }
1497
1297
  };
1498
- //#endregion
1499
- //#region extensions/acpx/src/runtime-session-store.ts
1298
+ // extensions/acpx/src/runtime-session-store.ts
1500
1299
  /** Generation-bound persistence and process-lease metadata for ACPX resets. */
1501
1300
  function withOpenClawLeaseSessionMetadata(record, lease) {
1502
1301
  return {
@@ -1511,30 +1310,9 @@ function captureGenerationRecord(generation, record) {
1511
1310
  }
1512
1311
  const acpxGenerationKey = Symbol("openclaw.acpxGeneration");
1513
1312
  const acpxOperationScope = new AsyncLocalStorage();
1514
- function readSessionRecordName(record) {
1515
- return normalizeOptionalString(asOptionalObjectRecord(record)?.name) ?? "";
1516
- }
1517
1313
  function readRecordAgentCommand(record) {
1518
1314
  return record?.agentArgv ?? record?.agentCommand;
1519
1315
  }
1520
- function readRecordCwd(record) {
1521
- return normalizeOptionalString(asOptionalObjectRecord(record)?.cwd);
1522
- }
1523
- function readRecordResetOnNextEnsure(record) {
1524
- return asOptionalObjectRecord(asOptionalObjectRecord(record)?.acpx)?.reset_on_next_ensure === true;
1525
- }
1526
- function readRecordAgentPid(record) {
1527
- const { pid, processId } = asOptionalObjectRecord(record) ?? {};
1528
- const rawPid = pid ?? processId;
1529
- const numericPid = typeof rawPid === "number" ? rawPid : typeof rawPid === "string" ? parseStrictPositiveInteger(rawPid) : void 0;
1530
- return numericPid && Number.isInteger(numericPid) && numericPid > 0 ? numericPid : void 0;
1531
- }
1532
- function readOpenClawLeaseIdFromRecord(record) {
1533
- return normalizeOptionalString(asOptionalObjectRecord(record)?.openclawLeaseId);
1534
- }
1535
- function readOpenClawGatewayInstanceIdFromRecord(record) {
1536
- return normalizeOptionalString(asOptionalObjectRecord(record)?.openclawGatewayInstanceId);
1537
- }
1538
1316
  function extractGeneratedWrapperPath(command) {
1539
1317
  return splitCommandParts(command ?? "").find((part) => (part.split(/[\\/]/).pop() ?? "") === "codex-acp-wrapper.mjs" || (part.split(/[\\/]/).pop() ?? "") === "claude-agent-acp-wrapper.mjs") ?? "";
1540
1318
  }
@@ -1563,11 +1341,11 @@ function createResetAwareSessionStore(baseStore, params) {
1563
1341
  const record = await baseStore.load(sessionId);
1564
1342
  if (scope && record) captureGenerationRecord(scope.generation, record);
1565
1343
  if (!record || !params?.leaseStore || !params.gatewayInstanceId) return record;
1566
- const sessionName = readSessionRecordName(record) || normalized;
1344
+ const sessionName = record.name || normalized;
1567
1345
  const lease = selectCurrentSessionLease({
1568
1346
  leases: await params.leaseStore.listOpen(params.gatewayInstanceId),
1569
1347
  sessionKeys: [sessionName, normalized],
1570
- rootPid: readRecordAgentPid(record)
1348
+ rootPid: record.pid
1571
1349
  });
1572
1350
  if (!lease) return record;
1573
1351
  const leasedRecord = withOpenClawLeaseSessionMetadata(record, lease);
@@ -1589,7 +1367,7 @@ function createResetAwareSessionStore(baseStore, params) {
1589
1367
  }
1590
1368
  let recordToSave = record;
1591
1369
  const launch = params?.launchScope?.getStore();
1592
- const sessionName = readSessionRecordName(record);
1370
+ const sessionName = record.name;
1593
1371
  const agentCommand = readRecordAgentCommand(record);
1594
1372
  const leasedCommand = launch?.leasedCommand ?? agentCommand;
1595
1373
  const leaseIdentity = launch ?? readAcpxProcessLeaseIdentity(leasedCommand);
@@ -1638,17 +1416,16 @@ function createResetAwareSessionStore(baseStore, params) {
1638
1416
  }
1639
1417
  };
1640
1418
  }
1641
- //#endregion
1642
- //#region extensions/acpx/src/runtime-process-cleanup.ts
1419
+ // extensions/acpx/src/runtime-process-cleanup.ts
1643
1420
  /** Capture OpenClaw wrapper cleanup ownership before a backend close can yield. */
1644
1421
  async function prepareAcpxProcessCleanup(params) {
1645
1422
  const { leaseStore, gatewayInstanceId, wrapperRoot } = params;
1646
- const rootPid = readRecordAgentPid(params.record);
1423
+ const rootPid = params.record?.pid;
1647
1424
  const rootCommand = params.command ? renderAgentCommand(params.command) : void 0;
1648
1425
  const identity = readAcpxProcessLeaseIdentity(params.command);
1649
- const leaseId = readOpenClawLeaseIdFromRecord(params.record) ?? identity?.leaseId;
1650
- const expectedGatewayInstanceId = readOpenClawGatewayInstanceIdFromRecord(params.record) ?? identity?.gatewayInstanceId;
1651
- const sessionKeys = [params.sessionKey, readSessionRecordName(params.record)];
1426
+ const leaseId = params.record?.openclawLeaseId ?? identity?.leaseId;
1427
+ const expectedGatewayInstanceId = params.record?.openclawGatewayInstanceId ?? identity?.gatewayInstanceId;
1428
+ const sessionKeys = [params.sessionKey, params.record?.name ?? ""];
1652
1429
  const openLeases = rootPid && gatewayInstanceId && leaseStore ? await leaseStore.listOpen(gatewayInstanceId) : [];
1653
1430
  const selectedLease = rootPid ? selectCurrentSessionLease({
1654
1431
  leases: openLeases,
@@ -1656,8 +1433,7 @@ async function prepareAcpxProcessCleanup(params) {
1656
1433
  rootPid
1657
1434
  }) : void 0;
1658
1435
  const loadedLease = leaseId ? await leaseStore?.load(leaseId) : void 0;
1659
- const ownedLease = selectedLease ?? (loadedLease && loadedLease.gatewayInstanceId === gatewayInstanceId && (!rootPid || loadedLease.rootPid === rootPid) && sessionKeys.includes(loadedLease.sessionKey) ? loadedLease : void 0);
1660
- const lease = ownedLease ? { ...ownedLease } : void 0;
1436
+ const lease = selectedLease ?? (loadedLease && loadedLease.gatewayInstanceId === gatewayInstanceId && (!rootPid || loadedLease.rootPid === rootPid) && sessionKeys.includes(loadedLease.sessionKey) ? loadedLease : void 0);
1661
1437
  return async () => {
1662
1438
  if (lease && lease.gatewayInstanceId === gatewayInstanceId) {
1663
1439
  await leaseStore?.markState(lease.leaseId, "closing");
@@ -1686,8 +1462,7 @@ async function prepareAcpxProcessCleanup(params) {
1686
1462
  });
1687
1463
  };
1688
1464
  }
1689
- //#endregion
1690
- //#region extensions/acpx/src/session-owner.ts
1465
+ // extensions/acpx/src/session-owner.ts
1691
1466
  function requireAcpxOwnerMigration(sessionKey) {
1692
1467
  throw new AcpRuntimeError("ACP_SESSION_INIT_FAILED", `ACP session "${sessionKey}" has an unqualified or unverifiable backend locator. Stop the Gateway and run "openclaw doctor --fix" to migrate ownership without losing history, then restart.`, { detailCode: "SESSION_OWNER_MIGRATION_REQUIRED" });
1693
1468
  }
@@ -1716,8 +1491,7 @@ function toAcpxResourceInput(input) {
1716
1491
  }
1717
1492
  };
1718
1493
  }
1719
- //#endregion
1720
- //#region extensions/acpx/src/runtime.ts
1494
+ // extensions/acpx/src/runtime.ts
1721
1495
  /**
1722
1496
  * OpenClaw ACPX runtime adapter. It wraps the upstream acpx runtime with
1723
1497
  * OpenClaw session metadata, lease tracking, model scoping, and cleanup policy.
@@ -1857,35 +1631,9 @@ function appendCodexAcpConfigOverrides(command, override) {
1857
1631
  JSON.stringify(config)
1858
1632
  ];
1859
1633
  }
1860
- function withManagedToolsMcpSessionEnv(params) {
1861
- const sessionKey = params.sessionKey.trim();
1862
- if (!params.pluginToolsEnabled && !params.openclawToolsEnabled || !sessionKey || !params.mcpServers?.length) return params.mcpServers;
1863
- let changed = false;
1864
- const nextServers = params.mcpServers.map((server) => {
1865
- const isManagedPluginTools = params.pluginToolsEnabled && server.name === ACPX_PLUGIN_TOOLS_MCP_SERVER_NAME;
1866
- const isManagedOpenClawTools = params.openclawToolsEnabled && server.name === ACPX_OPENCLAW_TOOLS_MCP_SERVER_NAME;
1867
- if (!isManagedPluginTools && !isManagedOpenClawTools || !("command" in server)) return server;
1868
- changed = true;
1869
- const env = [...server.env.filter((entry) => entry.name !== OPENCLAW_TOOLS_MCP_AGENT_SESSION_KEY_ENV), {
1870
- name: OPENCLAW_TOOLS_MCP_AGENT_SESSION_KEY_ENV,
1871
- value: sessionKey
1872
- }];
1873
- return {
1874
- ...server,
1875
- env,
1876
- args: params.agentId ? [
1877
- ...server.args,
1878
- "--openclaw-agent-id",
1879
- params.agentId
1880
- ] : server.args
1881
- };
1882
- });
1883
- return changed ? nextServers : params.mcpServers;
1884
- }
1885
1634
  function resolveBridgeSession(handle) {
1886
1635
  return handle.bridgeSession === void 0 ? handle : handle.bridgeSession;
1887
1636
  }
1888
- /** OpenClaw-managed ACP runtime implementation backed by the upstream acpx runtime. */
1889
1637
  var AcpxRuntime$1 = class {
1890
1638
  constructor(options, testOptions) {
1891
1639
  this.ownerAwareSessions = 1;
@@ -1935,12 +1683,29 @@ var AcpxRuntime$1 = class {
1935
1683
  if (target === null) return [];
1936
1684
  if (!this.managedToolsMcpBridgeEnabled) return servers;
1937
1685
  if (!target) throw new AcpRuntimeError("ACP_SESSION_INIT_FAILED", "ACP tool bridge has no session owner");
1938
- return withManagedToolsMcpSessionEnv({
1939
- pluginToolsEnabled: this.pluginToolsMcpBridgeEnabled,
1940
- openclawToolsEnabled: this.openclawToolsMcpBridgeEnabled,
1941
- mcpServers: servers,
1942
- ...target
1686
+ const sessionKey = target.sessionKey.trim();
1687
+ if (!this.pluginToolsMcpBridgeEnabled && !this.openclawToolsMcpBridgeEnabled || !sessionKey || !servers?.length) return servers;
1688
+ let changed = false;
1689
+ const nextServers = servers.map((server) => {
1690
+ const isManagedPluginTools = this.pluginToolsMcpBridgeEnabled && server.name === ACPX_PLUGIN_TOOLS_MCP_SERVER_NAME;
1691
+ const isManagedOpenClawTools = this.openclawToolsMcpBridgeEnabled && server.name === ACPX_OPENCLAW_TOOLS_MCP_SERVER_NAME;
1692
+ if (!isManagedPluginTools && !isManagedOpenClawTools || !("command" in server)) return server;
1693
+ changed = true;
1694
+ const env = [...server.env.filter((entry) => entry.name !== OPENCLAW_TOOLS_MCP_AGENT_SESSION_KEY_ENV), {
1695
+ name: OPENCLAW_TOOLS_MCP_AGENT_SESSION_KEY_ENV,
1696
+ value: sessionKey
1697
+ }];
1698
+ return {
1699
+ ...server,
1700
+ env,
1701
+ args: target.agentId ? [
1702
+ ...server.args,
1703
+ "--openclaw-agent-id",
1704
+ target.agentId
1705
+ ] : server.args
1706
+ };
1943
1707
  });
1708
+ return changed ? nextServers : servers;
1944
1709
  },
1945
1710
  processLifecycle: {
1946
1711
  onBeforeSpawn: async (launch) => {
@@ -2033,9 +1798,9 @@ var AcpxRuntime$1 = class {
2033
1798
  const recordId = oneShot ? persistedHandle?.acpxRecordId : sessionKey;
2034
1799
  if (!recordId) return;
2035
1800
  const record = await this.sessionStore.load(recordId);
2036
- if (!record || readRecordResetOnNextEnsure(record)) return;
2037
- if (oneShot && (record.acpxRecordId !== recordId || readSessionRecordName(record) !== sessionKey || record.acpSessionId !== (persistedHandle?.backendSessionId ?? decoded?.backendSessionId) || !record.agentCapabilities?.loadSession && !record.agentCapabilities?.sessionCapabilities?.resume || record.lastPromptAt !== void 0 || record.messages.some((message) => typeof message !== "string" && "User" in message))) return;
2038
- const recordCwd = readRecordCwd(record);
1801
+ if (!record || record.acpx?.reset_on_next_ensure === true) return;
1802
+ if (oneShot && (record.acpxRecordId !== recordId || record.name !== sessionKey || record.acpSessionId !== (persistedHandle?.backendSessionId ?? decoded?.backendSessionId) || !record.agentCapabilities?.loadSession && !record.agentCapabilities?.sessionCapabilities?.resume || record.lastPromptAt !== void 0 || record.messages.some((message) => typeof message !== "string" && "User" in message))) return;
1803
+ const recordCwd = record.cwd?.trim();
2039
1804
  const recordCommand = readRecordAgentCommand(record);
2040
1805
  if (!recordCwd || !recordCommand || path.resolve(recordCwd) !== path.resolve(input.cwd?.trim() || this.cwd) || !oneShot && resumeSessionId && record.acpSessionId !== resumeSessionId) return;
2041
1806
  const lease = readAcpxProcessLeaseIdentity(recordCommand);
@@ -2126,7 +1891,7 @@ var AcpxRuntime$1 = class {
2126
1891
  const record = await this.sessionStore.load(params.handle.acpxRecordId ?? resolveAcpxSessionResource(params.handle));
2127
1892
  return readCodexWrapperStderrTail({
2128
1893
  wrapperRoot: this.wrapperRoot,
2129
- leaseId: readOpenClawLeaseIdFromRecord(record)
1894
+ leaseId: record?.openclawLeaseId
2130
1895
  });
2131
1896
  }
2132
1897
  async findSession(input) {
@@ -2454,8 +2219,7 @@ var AcpxRuntime$1 = class {
2454
2219
  });
2455
2220
  }
2456
2221
  };
2457
- //#endregion
2458
- //#region extensions/acpx/src/service.ts
2222
+ // extensions/acpx/src/service.ts
2459
2223
  const ENABLE_STARTUP_PROBE_ENV = "OPENCLAW_ACPX_RUNTIME_STARTUP_PROBE";
2460
2224
  const SKIP_RUNTIME_PROBE_ENV = "OPENCLAW_SKIP_ACPX_RUNTIME_PROBE";
2461
2225
  const MAX_ACPX_TOKIO_WORKER_THREADS = 8;
@@ -2467,36 +2231,6 @@ function resolveAgentProcessEnv() {
2467
2231
  if (process.env.TOKIO_WORKER_THREADS?.trim()) return;
2468
2232
  return { TOKIO_WORKER_THREADS: String(Math.min(availableParallelism(), MAX_ACPX_TOKIO_WORKER_THREADS)) };
2469
2233
  }
2470
- async function createDefaultRuntime(params) {
2471
- const names = await fs$1.readdir(path.join(params.pluginConfig.stateDir, "sessions")).catch((error) => {
2472
- if (error instanceof Error && "code" in error && error.code === "ENOENT") return [];
2473
- throw error;
2474
- });
2475
- const legacyBareSessionKeys = /* @__PURE__ */ new Set();
2476
- for (const name of names) {
2477
- if (!name.endsWith(".json")) continue;
2478
- const recordId = decodeURIComponent(name.slice(0, -5));
2479
- if (!recordId.startsWith("agent:") && !recordId.startsWith(".openclaw-owner-") && !recordId.includes(":oneshot:")) legacyBareSessionKeys.add(recordId.toLowerCase());
2480
- }
2481
- return new AcpxRuntime$1({
2482
- cwd: params.pluginConfig.cwd,
2483
- agentProcessEnv: resolveAgentProcessEnv(),
2484
- openclawLegacyBareSessionKeys: legacyBareSessionKeys,
2485
- openclawGatewayInstanceId: params.gatewayInstanceId,
2486
- openclawProcessLeaseStore: params.processLeaseStore,
2487
- openclawWrapperRoot: params.wrapperRoot,
2488
- sessionStore: createFileSessionStore({ stateDir: params.pluginConfig.stateDir }),
2489
- agentRegistry: createAgentRegistry({ overrides: params.pluginConfig.agents }),
2490
- getProbeAgent: params.getProbeAgent,
2491
- mcpServers: toAcpMcpServers(params.pluginConfig.mcpServers),
2492
- pluginToolsMcpBridgeEnabled: params.pluginConfig.pluginToolsMcpBridge,
2493
- openclawToolsMcpBridgeEnabled: params.pluginConfig.openClawToolsMcpBridge,
2494
- permissionMode: params.pluginConfig.permissionMode,
2495
- nonInteractivePermissions: params.pluginConfig.nonInteractivePermissions,
2496
- elicitationModes: ["form", "url"],
2497
- timeoutMs: resolveAcpxTimerTimeoutMs(params.pluginConfig.timeoutSeconds)
2498
- });
2499
- }
2500
2234
  function formatDoctorFailureMessage(report) {
2501
2235
  const detailText = report.details?.map((detail) => detail.trim()).filter(Boolean).join("; ");
2502
2236
  return detailText ? `${report.message} (${detailText})` : report.message;
@@ -2524,7 +2258,6 @@ async function resolveGatewayInstanceId(openKeyedStore) {
2524
2258
  async function reapOpenAcpxProcessLeases(params) {
2525
2259
  const { assertCurrent } = params;
2526
2260
  const leases = await params.leaseStore.listOpen(params.gatewayInstanceId);
2527
- const inspectedPids = [];
2528
2261
  const terminatedPids = [];
2529
2262
  const legacyWrapperRoots = /* @__PURE__ */ new Set();
2530
2263
  for (const lease of leases) {
@@ -2544,7 +2277,6 @@ async function reapOpenAcpxProcessLeases(params) {
2544
2277
  wrapperRoot: lease.wrapperRoot,
2545
2278
  assertCurrent
2546
2279
  });
2547
- inspectedPids.push(...result.inspectedPids);
2548
2280
  terminatedPids.push(...result.terminatedPids);
2549
2281
  const retryableEvidenceFailure = result.skippedReason === "process-list-unavailable" || result.skippedReason === "unsupported-platform" || pending && (result.skippedReason === "ambiguous-root" || result.skippedReason === "unverified-root" || lease.sessionKey === "openclaw:acpx:probe" && result.skippedReason === "missing-root");
2550
2282
  await params.leaseStore.markState(lease.leaseId, retryableEvidenceFailure ? "open" : result.terminatedPids.length > 0 ? "closed" : "lost");
@@ -2554,13 +2286,9 @@ async function reapOpenAcpxProcessLeases(params) {
2554
2286
  wrapperRoot,
2555
2287
  assertCurrent
2556
2288
  });
2557
- inspectedPids.push(...legacyResult.inspectedPids);
2558
2289
  terminatedPids.push(...legacyResult.terminatedPids);
2559
2290
  }
2560
- return {
2561
- inspectedPids,
2562
- terminatedPids
2563
- };
2291
+ return { terminatedPids };
2564
2292
  }
2565
2293
  function createAcpxRuntimeService(params) {
2566
2294
  let runtime = null;
@@ -2591,7 +2319,6 @@ function createAcpxRuntimeService(params) {
2591
2319
  return;
2592
2320
  }
2593
2321
  const openKeyedStore = params.openKeyedStore;
2594
- if (!openKeyedStore) throw new Error("ACPX runtime service requires plugin keyed state");
2595
2322
  const basePluginConfig = await measureAcpxStartup(ctx, "config.resolve", () => resolveAcpxPluginConfig({
2596
2323
  rawConfig: params.pluginConfig,
2597
2324
  workspaceDir: ctx.workspaceDir,
@@ -2626,14 +2353,38 @@ function createAcpxRuntimeService(params) {
2626
2353
  if (params.startupPurpose !== "inspection") await promote(ctx);
2627
2354
  const getAllowedAgents = params.getAllowedAgents ?? (() => ctx.config.acp?.allowedAgents);
2628
2355
  const getProbeAgent = () => pluginConfig.probeAgent ?? getAllowedAgents()?.map(normalizeLowercaseStringOrEmpty).find(Boolean);
2629
- const startedRuntime = await measureAcpxStartup(ctx, "runtime.create", () => (params.runtimeFactory ?? createDefaultRuntime)({
2630
- pluginConfig,
2631
- getProbeAgent,
2632
- gatewayInstanceId,
2633
- processLeaseStore,
2634
- wrapperRoot,
2635
- logger: ctx.logger
2636
- }));
2356
+ const startedRuntime = await measureAcpxStartup(ctx, "runtime.create", async () => {
2357
+ const names = await fs$1.readdir(path.join(pluginConfig.stateDir, "sessions")).catch((error) => {
2358
+ if (error instanceof Error && "code" in error && error.code === "ENOENT") return [];
2359
+ throw error;
2360
+ });
2361
+ const legacyBareSessionKeys = /* @__PURE__ */ new Set();
2362
+ for (const name of names) {
2363
+ if (!name.endsWith(".json")) continue;
2364
+ const recordId = decodeURIComponent(name.slice(0, -5));
2365
+ if (!recordId.startsWith("agent:") && !recordId.startsWith(".openclaw-owner-") && !recordId.includes(":oneshot:")) legacyBareSessionKeys.add(recordId.toLowerCase());
2366
+ }
2367
+ return new AcpxRuntime$1({
2368
+ cwd: pluginConfig.cwd,
2369
+ agentProcessEnv: resolveAgentProcessEnv(),
2370
+ agentProcessEnvAllow: pluginConfig.agentProcessEnvAllow,
2371
+ agentProcessEnvBlock: pluginConfig.agentProcessEnvBlock,
2372
+ openclawLegacyBareSessionKeys: legacyBareSessionKeys,
2373
+ openclawGatewayInstanceId: gatewayInstanceId,
2374
+ openclawProcessLeaseStore: processLeaseStore,
2375
+ openclawWrapperRoot: wrapperRoot,
2376
+ sessionStore: createFileSessionStore({ stateDir: pluginConfig.stateDir }),
2377
+ agentRegistry: createAgentRegistry({ overrides: pluginConfig.agents }),
2378
+ getProbeAgent,
2379
+ mcpServers: toAcpMcpServers(pluginConfig.mcpServers),
2380
+ pluginToolsMcpBridgeEnabled: pluginConfig.pluginToolsMcpBridge,
2381
+ openclawToolsMcpBridgeEnabled: pluginConfig.openClawToolsMcpBridge,
2382
+ permissionMode: pluginConfig.permissionMode,
2383
+ nonInteractivePermissions: pluginConfig.nonInteractivePermissions,
2384
+ elicitationModes: ["form", "url"],
2385
+ timeoutMs: resolveAcpxTimerTimeoutMs(pluginConfig.timeoutSeconds)
2386
+ });
2387
+ });
2637
2388
  runtime = startedRuntime;
2638
2389
  const shouldProbeRuntime = params.probeAtStartup !== false && shouldProbeRuntimeAtStartup();
2639
2390
  ctx.startupTrace?.detail?.("probe-policy", [["startupProbeEnabledCount", shouldProbeRuntime ? 1 : 0], ["probeAgent", getProbeAgent() ?? "default"]]);
@@ -2676,5 +2427,4 @@ function createAcpxRuntimeService(params) {
2676
2427
  }
2677
2428
  };
2678
2429
  }
2679
- //#endregion
2680
2430
  export { createAcpxRuntimeService };