@openclaw/acpx 2026.10.10 → 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-CE-ej7LM.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-Cv-RAA6y.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-WmiXoSmh.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,7 +18,6 @@ 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";
@@ -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
  });
@@ -490,121 +486,6 @@ main();
490
486
  `;
491
487
  }
492
488
  // extensions/acpx/src/codex-trust-config.ts
493
- function stripTomlComment(line) {
494
- let quote = null;
495
- let escaping = false;
496
- for (let index = 0; index < line.length; index += 1) {
497
- const ch = line[index];
498
- if (escaping) {
499
- escaping = false;
500
- continue;
501
- }
502
- if (quote === "\"" && ch === "\\") {
503
- escaping = true;
504
- continue;
505
- }
506
- if (quote) {
507
- if (ch === quote) quote = null;
508
- continue;
509
- }
510
- if (ch === "'" || ch === "\"") {
511
- quote = ch;
512
- continue;
513
- }
514
- if (ch === "#") return line.slice(0, index);
515
- }
516
- return line;
517
- }
518
- function parseTomlString(value) {
519
- const trimmed = value.trim();
520
- if (trimmed.startsWith("\"") && trimmed.endsWith("\"")) try {
521
- return JSON.parse(trimmed);
522
- } catch {
523
- return;
524
- }
525
- if (trimmed.startsWith("'") && trimmed.endsWith("'")) return trimmed.slice(1, -1);
526
- }
527
- function parseTomlDottedKey(value) {
528
- const parts = [];
529
- let current = "";
530
- let quote = null;
531
- let escaping = false;
532
- for (const ch of value.trim()) {
533
- if (escaping) {
534
- current += ch;
535
- escaping = false;
536
- continue;
537
- }
538
- if (quote === "\"" && ch === "\\") {
539
- current += ch;
540
- escaping = true;
541
- continue;
542
- }
543
- if (quote) {
544
- current += ch;
545
- if (ch === quote) quote = null;
546
- continue;
547
- }
548
- if (ch === "'" || ch === "\"") {
549
- quote = ch;
550
- current += ch;
551
- continue;
552
- }
553
- if (ch === ".") {
554
- parts.push(current.trim());
555
- current = "";
556
- continue;
557
- }
558
- current += ch;
559
- }
560
- if (current.trim()) parts.push(current.trim());
561
- return parts.map((part) => parseTomlString(part) ?? part);
562
- }
563
- function parseProjectHeader(line) {
564
- const parts = parseTableHeader(line);
565
- return parts?.length === 2 && parts[0] === "projects" ? parts[1] : void 0;
566
- }
567
- function parseTrustedInlineProjectEntries(value) {
568
- const trusted = [];
569
- for (const match of value.matchAll(/(?<key>"(?:\\.|[^"\\])*"|'[^']*'|[A-Za-z0-9_\-/.~:]+)\s*=\s*\{(?<body>[^{}]*(?:\{[^{}]*\}[^{}]*)*)\}/g)) {
570
- const key = match.groups?.key;
571
- const body = match.groups?.body;
572
- if (!key || !body || !/\btrust_level\s*=\s*["']trusted["']/.test(body)) continue;
573
- const projectPath = parseTomlString(key) ?? key.trim();
574
- if (projectPath) trusted.push(projectPath);
575
- }
576
- return trusted;
577
- }
578
- function extractTrustedCodexProjectPaths(configToml) {
579
- const trusted = /* @__PURE__ */ new Set();
580
- let currentProjectPath;
581
- let inProjectsTable = false;
582
- for (const rawLine of configToml.split(/\r?\n/)) {
583
- const line = stripTomlComment(rawLine).trim();
584
- if (!line) continue;
585
- if (line.startsWith("[")) {
586
- currentProjectPath = parseProjectHeader(line);
587
- inProjectsTable = line === "[projects]";
588
- continue;
589
- }
590
- if (currentProjectPath && /^trust_level\s*=\s*["']trusted["']\s*$/.test(line)) {
591
- trusted.add(currentProjectPath);
592
- continue;
593
- }
594
- const assignment = /^(?<key>"(?:\\.|[^"\\])*"|'[^']*'|[A-Za-z0-9_\-/.~:]+)\s*=\s*(?<value>.+)$/.exec(line);
595
- const rawKey = assignment?.groups?.key;
596
- const rawValue = assignment?.groups?.value;
597
- if (!rawKey || rawValue === void 0) continue;
598
- const key = parseTomlString(rawKey) ?? rawKey;
599
- const value = rawValue.trim();
600
- if (inProjectsTable && /^\{.*\}$/.test(value)) {
601
- if (/\btrust_level\s*=\s*["']trusted["']/.test(value) && key) trusted.add(key);
602
- continue;
603
- }
604
- if (key === "projects" || inProjectsTable) for (const projectPath of parseTrustedInlineProjectEntries(value)) trusted.add(projectPath);
605
- }
606
- return Array.from(trusted);
607
- }
608
489
  const INHERITED_TOP_LEVEL_CODEX_CONFIG_KEYS = /* @__PURE__ */ new Set([
609
490
  "model",
610
491
  "model_provider",
@@ -622,61 +503,30 @@ const INHERITED_MODEL_PROVIDER_CONFIG_KEYS = /* @__PURE__ */ new Set([
622
503
  "stream_max_retries",
623
504
  "stream_idle_timeout_ms"
624
505
  ]);
625
- function parseTableHeader(line) {
626
- const trimmed = line.trim();
627
- if (!trimmed.startsWith("[") || !trimmed.endsWith("]") || trimmed.startsWith("[[")) return;
628
- return parseTomlDottedKey(trimmed.slice(1, -1));
629
- }
630
- function isInheritedModelProviderTable(parts) {
631
- return parts?.[0] === "model_providers" && parts.length === 2;
632
- }
633
- function parseTopLevelAssignmentKey(line) {
634
- return /^(?<key>[A-Za-z0-9_-]+)\s*=\s*(?<value>.+)$/.exec(line)?.groups?.key;
635
- }
636
- function extractInheritedCodexRuntimeConfig(configToml) {
637
- const inheritedLines = [];
638
- let inAnyTable = false;
639
- let inInheritedTable = false;
640
- let pendingInheritedTableHeader = "";
641
- function flushInheritedTableHeader() {
642
- if (!pendingInheritedTableHeader) return;
643
- if (inheritedLines.length > 0 && inheritedLines[inheritedLines.length - 1] !== "") inheritedLines.push("");
644
- inheritedLines.push(pendingInheritedTableHeader);
645
- pendingInheritedTableHeader = "";
646
- }
647
- for (const rawLine of configToml.split(/\r?\n/)) {
648
- const trimmedLine = rawLine.trim();
649
- const semanticLine = stripTomlComment(rawLine).trim();
650
- if (trimmedLine.startsWith("[")) {
651
- const tableParts = parseTableHeader(trimmedLine);
652
- inAnyTable = true;
653
- inInheritedTable = isInheritedModelProviderTable(tableParts);
654
- if (inInheritedTable) pendingInheritedTableHeader = rawLine.trimEnd();
655
- else pendingInheritedTableHeader = "";
656
- continue;
657
- }
658
- if (inInheritedTable) {
659
- if (!semanticLine) continue;
660
- const key = parseTopLevelAssignmentKey(semanticLine);
661
- if (!key || !INHERITED_MODEL_PROVIDER_CONFIG_KEYS.has(key)) continue;
662
- flushInheritedTableHeader();
663
- inheritedLines.push(rawLine.trimEnd());
664
- continue;
665
- }
666
- if (inAnyTable) continue;
667
- const key = parseTopLevelAssignmentKey(semanticLine);
668
- if (!key) continue;
669
- if (!INHERITED_TOP_LEVEL_CODEX_CONFIG_KEYS.has(key)) continue;
670
- inheritedLines.push(rawLine.trimEnd());
671
- }
672
- return inheritedLines.join("\n");
673
- }
674
506
  function renderIsolatedCodexConfig(params) {
675
- 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));
676
526
  return [
677
527
  "# Generated by OpenClaw for Codex ACP sessions.",
678
- params.sourceConfigToml ? extractInheritedCodexRuntimeConfig(params.sourceConfigToml) : "",
679
- ...normalized.flatMap((projectPath) => [
528
+ stringify(inherited, { numbersAsFloat: true }).trimEnd(),
529
+ ...projectPaths.flatMap((projectPath) => [
680
530
  "",
681
531
  `[projects.${JSON.stringify(projectPath)}]`,
682
532
  "trust_level = \"trusted\""
@@ -844,17 +694,15 @@ async function readSourceCodexConfig(codexHome) {
844
694
  }
845
695
  async function prepareIsolatedCodexHome(params) {
846
696
  const sourceConfig = await readSourceCodexConfig(process.env.CODEX_HOME || path.join(os.homedir(), ".codex"));
847
- const trustedProjectPaths = [...sourceConfig ? extractTrustedCodexProjectPaths(sourceConfig) : [], params.workspaceDir];
848
697
  const codexHome = path.join(params.baseDir, "codex-home");
849
698
  await fs$1.mkdir(codexHome, { recursive: true });
850
699
  await fs$1.writeFile(path.join(codexHome, "config.toml"), renderIsolatedCodexConfig({
851
700
  sourceConfigToml: sourceConfig,
852
- projectPaths: trustedProjectPaths
701
+ projectPaths: [params.workspaceDir],
702
+ mcpServers: isRecord(params.migratedConfig?.mcp_servers) ? params.migratedConfig.mcp_servers : void 0
853
703
  }), "utf8");
854
- return codexHome;
855
704
  }
856
705
  async function writeAdapterWrapper(baseDir, fileName, script) {
857
- await fs$1.mkdir(baseDir, { recursive: true });
858
706
  const wrapperPath = path.join(baseDir, fileName);
859
707
  await fs$1.writeFile(wrapperPath, script, { encoding: "utf8" });
860
708
  try {
@@ -966,13 +814,6 @@ function resolveCodexAdapterLaunch(configuredCommand) {
966
814
  if (!maintainedAdapterArgs) return;
967
815
  return { args: maintainedAdapterArgs };
968
816
  }
969
- async function persistMigratedCodexMcpConfig(params) {
970
- const mcpServers = params.migratedConfig?.mcp_servers;
971
- if (!isRecord(mcpServers)) return;
972
- const configPath = path.join(params.codexHome, "config.toml");
973
- const merged = mergeConfigRecords(parse(await fs$1.readFile(configPath, "utf8")), { mcp_servers: mcpServers });
974
- await fs$1.writeFile(configPath, stringify(merged), "utf8");
975
- }
976
817
  function buildClaudeAcpWrapperCommand(wrapperPath, configuredCommand) {
977
818
  const configuredAdapterArgs = extractConfiguredAdapterArgs({
978
819
  configuredCommand,
@@ -988,17 +829,15 @@ async function prepareAcpxCodexAuthConfig(params) {
988
829
  const configuredCodexCommand = params.pluginConfig.agents.codex;
989
830
  const configuredClaudeCommand = params.pluginConfig.agents.claude;
990
831
  const codexLaunch = resolveCodexAdapterLaunch(configuredCodexCommand);
991
- await persistMigratedCodexMcpConfig({
992
- codexHome: await prepareIsolatedCodexHome({
993
- baseDir: codexBaseDir,
994
- workspaceDir: params.pluginConfig.cwd
995
- }),
832
+ await prepareIsolatedCodexHome({
833
+ baseDir: codexBaseDir,
834
+ workspaceDir: params.pluginConfig.cwd,
996
835
  migratedConfig: codexLaunch?.migratedConfig
997
836
  });
998
- const installedCodexBinPath = await (params.resolveInstalledCodexAcpBinPath ? params.resolveInstalledCodexAcpBinPath() : resolveInstalledAcpPackageBinPath(CODEX_ACP_PACKAGE, CODEX_ACP_BIN));
999
- const installedClaudeBinPath = await (params.resolveInstalledClaudeAcpBinPath ? params.resolveInstalledClaudeAcpBinPath() : resolveInstalledAcpPackageBinPath(CLAUDE_ACP_PACKAGE, CLAUDE_ACP_BIN));
1000
- const wrapperPath = await writeAdapterWrapper(codexBaseDir, "codex-acp-wrapper.mjs", buildCodexAcpWrapperScript(installedCodexBinPath));
1001
- 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));
1002
841
  return {
1003
842
  ...params.pluginConfig,
1004
843
  agents: {
@@ -1124,12 +963,16 @@ function parseProcessList(stdout) {
1124
963
  }
1125
964
  async function listPlatformProcesses() {
1126
965
  if (process.platform === "win32") return [];
1127
- const { stdout } = await runExec("ps", ["-axo", "pid=,ppid=,command="], {
1128
- logOutput: false,
1129
- maxBuffer: 8388608,
1130
- timeoutMs: ACPX_PROCESS_LIST_TIMEOUT_MS
1131
- });
1132
- 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
+ }
1133
976
  }
1134
977
  function collectProcessTree(processes, rootPid) {
1135
978
  const childrenByParent = /* @__PURE__ */ new Map();
@@ -1138,7 +981,7 @@ function collectProcessTree(processes, rootPid) {
1138
981
  children.push(processInfo);
1139
982
  childrenByParent.set(processInfo.ppid, children);
1140
983
  }
1141
- const root = new Map(processes.map((processInfo) => [processInfo.pid, processInfo])).get(rootPid);
984
+ const root = processes.find((processInfo) => processInfo.pid === rootPid);
1142
985
  const collected = [];
1143
986
  if (root) collected.push(root);
1144
987
  const queue = [...childrenByParent.get(rootPid) ?? []];
@@ -1176,28 +1019,20 @@ async function terminatePids(pids, assertCurrent) {
1176
1019
  async function cleanupOpenClawOwnedAcpxProcessTree(params) {
1177
1020
  const rootPid = params.rootPid;
1178
1021
  if (!rootPid || rootPid <= 0 || rootPid === process.pid) return {
1179
- inspectedPids: [],
1180
1022
  terminatedPids: [],
1181
1023
  skippedReason: "missing-root"
1182
1024
  };
1183
1025
  if (process.platform === "win32") return {
1184
- inspectedPids: [],
1185
1026
  terminatedPids: [],
1186
1027
  skippedReason: "unsupported-platform"
1187
1028
  };
1188
- let processes;
1189
- try {
1190
- processes = await listPlatformProcesses();
1191
- } catch {
1192
- return {
1193
- inspectedPids: [],
1194
- terminatedPids: [],
1195
- skippedReason: "process-list-unavailable"
1196
- };
1197
- }
1029
+ const processes = await listPlatformProcesses();
1030
+ if (!processes) return {
1031
+ terminatedPids: [],
1032
+ skippedReason: "process-list-unavailable"
1033
+ };
1198
1034
  const listedTree = collectProcessTree(processes, rootPid);
1199
1035
  if (listedTree.length === 0) return {
1200
- inspectedPids: [],
1201
1036
  terminatedPids: [],
1202
1037
  skippedReason: "unverified-root"
1203
1038
  };
@@ -1212,85 +1047,56 @@ async function cleanupOpenClawOwnedAcpxProcessTree(params) {
1212
1047
  expectedLeaseId: params.expectedLeaseId,
1213
1048
  expectedGatewayInstanceId: params.expectedGatewayInstanceId
1214
1049
  })) return {
1215
- inspectedPids: listedTree.map((processInfo) => processInfo.pid),
1216
1050
  terminatedPids: [],
1217
1051
  skippedReason: "not-openclaw-owned"
1218
1052
  };
1219
- const pids = uniquePids(listedTree.toReversed());
1220
- return {
1221
- inspectedPids: uniquePids(listedTree),
1222
- terminatedPids: await terminatePids(pids, params.assertCurrent)
1223
- };
1053
+ return { terminatedPids: await terminatePids(uniquePids(listedTree.toReversed()), params.assertCurrent) };
1224
1054
  }
1225
1055
  /** Recover a pending lease by matching its exact live wrapper identity. */
1226
1056
  async function cleanupOpenClawOwnedAcpxPendingLease(params) {
1227
1057
  if (process.platform === "win32") return {
1228
- inspectedPids: [],
1229
1058
  terminatedPids: [],
1230
1059
  skippedReason: "unsupported-platform"
1231
1060
  };
1232
1061
  if (!params.wrapperPath || !wrapperPathBelongsToRoot(params.wrapperPath, params.wrapperRoot)) return {
1233
- inspectedPids: [],
1234
1062
  terminatedPids: [],
1235
1063
  skippedReason: "unverified-root"
1236
1064
  };
1237
- let processes;
1238
- try {
1239
- processes = await listPlatformProcesses();
1240
- } catch {
1241
- return {
1242
- inspectedPids: [],
1243
- terminatedPids: [],
1244
- skippedReason: "process-list-unavailable"
1245
- };
1246
- }
1065
+ const processes = await listPlatformProcesses();
1066
+ if (!processes) return {
1067
+ terminatedPids: [],
1068
+ skippedReason: "process-list-unavailable"
1069
+ };
1247
1070
  const matchingRoots = processes.filter((processInfo) => commandContainsExactWrapperPath(processInfo.command, params.wrapperPath) && liveCommandMatchesLeaseIdentity({
1248
1071
  command: processInfo.command,
1249
1072
  expectedLeaseId: params.leaseId,
1250
1073
  expectedGatewayInstanceId: params.gatewayInstanceId
1251
1074
  }));
1252
1075
  if (matchingRoots.length === 0) return {
1253
- inspectedPids: [],
1254
1076
  terminatedPids: [],
1255
1077
  skippedReason: "missing-root"
1256
1078
  };
1257
1079
  if (matchingRoots.length > 1) return {
1258
- inspectedPids: uniquePids(matchingRoots),
1259
1080
  terminatedPids: [],
1260
1081
  skippedReason: "ambiguous-root"
1261
1082
  };
1262
- const listedTree = collectProcessTree(processes, matchingRoots[0].pid);
1263
- const pids = uniquePids(listedTree.toReversed());
1264
- return {
1265
- inspectedPids: uniquePids(listedTree),
1266
- terminatedPids: await terminatePids(pids, params.assertCurrent)
1267
- };
1083
+ return { terminatedPids: await terminatePids(uniquePids(collectProcessTree(processes, matchingRoots[0].pid).toReversed()), params.assertCurrent) };
1268
1084
  }
1269
1085
  /** Reap orphaned OpenClaw-owned ACPX wrapper trees during runtime startup. */
1270
1086
  async function reapStaleOpenClawOwnedAcpxOrphans(params) {
1271
1087
  if (process.platform === "win32") return {
1272
- inspectedPids: [],
1273
1088
  terminatedPids: [],
1274
1089
  skippedReason: "unsupported-platform"
1275
1090
  };
1276
- let processes;
1277
- try {
1278
- processes = await listPlatformProcesses();
1279
- } catch {
1280
- return {
1281
- inspectedPids: [],
1282
- terminatedPids: [],
1283
- skippedReason: "process-list-unavailable"
1284
- };
1285
- }
1286
- 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({
1287
1097
  command: processInfo.command,
1288
1098
  wrapperRoot: params.wrapperRoot
1289
- })).map((orphan) => collectProcessTree(processes, orphan.pid));
1290
- return {
1291
- inspectedPids: uniquePids(orphanTrees.flat()),
1292
- terminatedPids: await terminatePids(uniquePids(orphanTrees.flatMap((tree) => tree.toReversed())), params.assertCurrent)
1293
- };
1099
+ })).map((orphan) => collectProcessTree(processes, orphan.pid)).flatMap((tree) => tree.toReversed())), params.assertCurrent) };
1294
1100
  }
1295
1101
  // extensions/acpx/src/model-ref.ts
1296
1102
  function withAcpxSessionOptions(input) {
@@ -1504,30 +1310,9 @@ function captureGenerationRecord(generation, record) {
1504
1310
  }
1505
1311
  const acpxGenerationKey = Symbol("openclaw.acpxGeneration");
1506
1312
  const acpxOperationScope = new AsyncLocalStorage();
1507
- function readSessionRecordName(record) {
1508
- return normalizeOptionalString(asOptionalObjectRecord(record)?.name) ?? "";
1509
- }
1510
1313
  function readRecordAgentCommand(record) {
1511
1314
  return record?.agentArgv ?? record?.agentCommand;
1512
1315
  }
1513
- function readRecordCwd(record) {
1514
- return normalizeOptionalString(asOptionalObjectRecord(record)?.cwd);
1515
- }
1516
- function readRecordResetOnNextEnsure(record) {
1517
- return asOptionalObjectRecord(asOptionalObjectRecord(record)?.acpx)?.reset_on_next_ensure === true;
1518
- }
1519
- function readRecordAgentPid(record) {
1520
- const { pid, processId } = asOptionalObjectRecord(record) ?? {};
1521
- const rawPid = pid ?? processId;
1522
- const numericPid = typeof rawPid === "number" ? rawPid : typeof rawPid === "string" ? parseStrictPositiveInteger(rawPid) : void 0;
1523
- return numericPid && Number.isInteger(numericPid) && numericPid > 0 ? numericPid : void 0;
1524
- }
1525
- function readOpenClawLeaseIdFromRecord(record) {
1526
- return normalizeOptionalString(asOptionalObjectRecord(record)?.openclawLeaseId);
1527
- }
1528
- function readOpenClawGatewayInstanceIdFromRecord(record) {
1529
- return normalizeOptionalString(asOptionalObjectRecord(record)?.openclawGatewayInstanceId);
1530
- }
1531
1316
  function extractGeneratedWrapperPath(command) {
1532
1317
  return splitCommandParts(command ?? "").find((part) => (part.split(/[\\/]/).pop() ?? "") === "codex-acp-wrapper.mjs" || (part.split(/[\\/]/).pop() ?? "") === "claude-agent-acp-wrapper.mjs") ?? "";
1533
1318
  }
@@ -1556,11 +1341,11 @@ function createResetAwareSessionStore(baseStore, params) {
1556
1341
  const record = await baseStore.load(sessionId);
1557
1342
  if (scope && record) captureGenerationRecord(scope.generation, record);
1558
1343
  if (!record || !params?.leaseStore || !params.gatewayInstanceId) return record;
1559
- const sessionName = readSessionRecordName(record) || normalized;
1344
+ const sessionName = record.name || normalized;
1560
1345
  const lease = selectCurrentSessionLease({
1561
1346
  leases: await params.leaseStore.listOpen(params.gatewayInstanceId),
1562
1347
  sessionKeys: [sessionName, normalized],
1563
- rootPid: readRecordAgentPid(record)
1348
+ rootPid: record.pid
1564
1349
  });
1565
1350
  if (!lease) return record;
1566
1351
  const leasedRecord = withOpenClawLeaseSessionMetadata(record, lease);
@@ -1582,7 +1367,7 @@ function createResetAwareSessionStore(baseStore, params) {
1582
1367
  }
1583
1368
  let recordToSave = record;
1584
1369
  const launch = params?.launchScope?.getStore();
1585
- const sessionName = readSessionRecordName(record);
1370
+ const sessionName = record.name;
1586
1371
  const agentCommand = readRecordAgentCommand(record);
1587
1372
  const leasedCommand = launch?.leasedCommand ?? agentCommand;
1588
1373
  const leaseIdentity = launch ?? readAcpxProcessLeaseIdentity(leasedCommand);
@@ -1635,12 +1420,12 @@ function createResetAwareSessionStore(baseStore, params) {
1635
1420
  /** Capture OpenClaw wrapper cleanup ownership before a backend close can yield. */
1636
1421
  async function prepareAcpxProcessCleanup(params) {
1637
1422
  const { leaseStore, gatewayInstanceId, wrapperRoot } = params;
1638
- const rootPid = readRecordAgentPid(params.record);
1423
+ const rootPid = params.record?.pid;
1639
1424
  const rootCommand = params.command ? renderAgentCommand(params.command) : void 0;
1640
1425
  const identity = readAcpxProcessLeaseIdentity(params.command);
1641
- const leaseId = readOpenClawLeaseIdFromRecord(params.record) ?? identity?.leaseId;
1642
- const expectedGatewayInstanceId = readOpenClawGatewayInstanceIdFromRecord(params.record) ?? identity?.gatewayInstanceId;
1643
- 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 ?? ""];
1644
1429
  const openLeases = rootPid && gatewayInstanceId && leaseStore ? await leaseStore.listOpen(gatewayInstanceId) : [];
1645
1430
  const selectedLease = rootPid ? selectCurrentSessionLease({
1646
1431
  leases: openLeases,
@@ -1648,8 +1433,7 @@ async function prepareAcpxProcessCleanup(params) {
1648
1433
  rootPid
1649
1434
  }) : void 0;
1650
1435
  const loadedLease = leaseId ? await leaseStore?.load(leaseId) : void 0;
1651
- const ownedLease = selectedLease ?? (loadedLease && loadedLease.gatewayInstanceId === gatewayInstanceId && (!rootPid || loadedLease.rootPid === rootPid) && sessionKeys.includes(loadedLease.sessionKey) ? loadedLease : void 0);
1652
- 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);
1653
1437
  return async () => {
1654
1438
  if (lease && lease.gatewayInstanceId === gatewayInstanceId) {
1655
1439
  await leaseStore?.markState(lease.leaseId, "closing");
@@ -1847,35 +1631,9 @@ function appendCodexAcpConfigOverrides(command, override) {
1847
1631
  JSON.stringify(config)
1848
1632
  ];
1849
1633
  }
1850
- function withManagedToolsMcpSessionEnv(params) {
1851
- const sessionKey = params.sessionKey.trim();
1852
- if (!params.pluginToolsEnabled && !params.openclawToolsEnabled || !sessionKey || !params.mcpServers?.length) return params.mcpServers;
1853
- let changed = false;
1854
- const nextServers = params.mcpServers.map((server) => {
1855
- const isManagedPluginTools = params.pluginToolsEnabled && server.name === ACPX_PLUGIN_TOOLS_MCP_SERVER_NAME;
1856
- const isManagedOpenClawTools = params.openclawToolsEnabled && server.name === ACPX_OPENCLAW_TOOLS_MCP_SERVER_NAME;
1857
- if (!isManagedPluginTools && !isManagedOpenClawTools || !("command" in server)) return server;
1858
- changed = true;
1859
- const env = [...server.env.filter((entry) => entry.name !== OPENCLAW_TOOLS_MCP_AGENT_SESSION_KEY_ENV), {
1860
- name: OPENCLAW_TOOLS_MCP_AGENT_SESSION_KEY_ENV,
1861
- value: sessionKey
1862
- }];
1863
- return {
1864
- ...server,
1865
- env,
1866
- args: params.agentId ? [
1867
- ...server.args,
1868
- "--openclaw-agent-id",
1869
- params.agentId
1870
- ] : server.args
1871
- };
1872
- });
1873
- return changed ? nextServers : params.mcpServers;
1874
- }
1875
1634
  function resolveBridgeSession(handle) {
1876
1635
  return handle.bridgeSession === void 0 ? handle : handle.bridgeSession;
1877
1636
  }
1878
- /** OpenClaw-managed ACP runtime implementation backed by the upstream acpx runtime. */
1879
1637
  var AcpxRuntime$1 = class {
1880
1638
  constructor(options, testOptions) {
1881
1639
  this.ownerAwareSessions = 1;
@@ -1925,12 +1683,29 @@ var AcpxRuntime$1 = class {
1925
1683
  if (target === null) return [];
1926
1684
  if (!this.managedToolsMcpBridgeEnabled) return servers;
1927
1685
  if (!target) throw new AcpRuntimeError("ACP_SESSION_INIT_FAILED", "ACP tool bridge has no session owner");
1928
- return withManagedToolsMcpSessionEnv({
1929
- pluginToolsEnabled: this.pluginToolsMcpBridgeEnabled,
1930
- openclawToolsEnabled: this.openclawToolsMcpBridgeEnabled,
1931
- mcpServers: servers,
1932
- ...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
+ };
1933
1707
  });
1708
+ return changed ? nextServers : servers;
1934
1709
  },
1935
1710
  processLifecycle: {
1936
1711
  onBeforeSpawn: async (launch) => {
@@ -2023,9 +1798,9 @@ var AcpxRuntime$1 = class {
2023
1798
  const recordId = oneShot ? persistedHandle?.acpxRecordId : sessionKey;
2024
1799
  if (!recordId) return;
2025
1800
  const record = await this.sessionStore.load(recordId);
2026
- if (!record || readRecordResetOnNextEnsure(record)) return;
2027
- 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;
2028
- 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();
2029
1804
  const recordCommand = readRecordAgentCommand(record);
2030
1805
  if (!recordCwd || !recordCommand || path.resolve(recordCwd) !== path.resolve(input.cwd?.trim() || this.cwd) || !oneShot && resumeSessionId && record.acpSessionId !== resumeSessionId) return;
2031
1806
  const lease = readAcpxProcessLeaseIdentity(recordCommand);
@@ -2116,7 +1891,7 @@ var AcpxRuntime$1 = class {
2116
1891
  const record = await this.sessionStore.load(params.handle.acpxRecordId ?? resolveAcpxSessionResource(params.handle));
2117
1892
  return readCodexWrapperStderrTail({
2118
1893
  wrapperRoot: this.wrapperRoot,
2119
- leaseId: readOpenClawLeaseIdFromRecord(record)
1894
+ leaseId: record?.openclawLeaseId
2120
1895
  });
2121
1896
  }
2122
1897
  async findSession(input) {
@@ -2456,36 +2231,6 @@ function resolveAgentProcessEnv() {
2456
2231
  if (process.env.TOKIO_WORKER_THREADS?.trim()) return;
2457
2232
  return { TOKIO_WORKER_THREADS: String(Math.min(availableParallelism(), MAX_ACPX_TOKIO_WORKER_THREADS)) };
2458
2233
  }
2459
- async function createDefaultRuntime(params) {
2460
- const names = await fs$1.readdir(path.join(params.pluginConfig.stateDir, "sessions")).catch((error) => {
2461
- if (error instanceof Error && "code" in error && error.code === "ENOENT") return [];
2462
- throw error;
2463
- });
2464
- const legacyBareSessionKeys = /* @__PURE__ */ new Set();
2465
- for (const name of names) {
2466
- if (!name.endsWith(".json")) continue;
2467
- const recordId = decodeURIComponent(name.slice(0, -5));
2468
- if (!recordId.startsWith("agent:") && !recordId.startsWith(".openclaw-owner-") && !recordId.includes(":oneshot:")) legacyBareSessionKeys.add(recordId.toLowerCase());
2469
- }
2470
- return new AcpxRuntime$1({
2471
- cwd: params.pluginConfig.cwd,
2472
- agentProcessEnv: resolveAgentProcessEnv(),
2473
- openclawLegacyBareSessionKeys: legacyBareSessionKeys,
2474
- openclawGatewayInstanceId: params.gatewayInstanceId,
2475
- openclawProcessLeaseStore: params.processLeaseStore,
2476
- openclawWrapperRoot: params.wrapperRoot,
2477
- sessionStore: createFileSessionStore({ stateDir: params.pluginConfig.stateDir }),
2478
- agentRegistry: createAgentRegistry({ overrides: params.pluginConfig.agents }),
2479
- getProbeAgent: params.getProbeAgent,
2480
- mcpServers: toAcpMcpServers(params.pluginConfig.mcpServers),
2481
- pluginToolsMcpBridgeEnabled: params.pluginConfig.pluginToolsMcpBridge,
2482
- openclawToolsMcpBridgeEnabled: params.pluginConfig.openClawToolsMcpBridge,
2483
- permissionMode: params.pluginConfig.permissionMode,
2484
- nonInteractivePermissions: params.pluginConfig.nonInteractivePermissions,
2485
- elicitationModes: ["form", "url"],
2486
- timeoutMs: resolveAcpxTimerTimeoutMs(params.pluginConfig.timeoutSeconds)
2487
- });
2488
- }
2489
2234
  function formatDoctorFailureMessage(report) {
2490
2235
  const detailText = report.details?.map((detail) => detail.trim()).filter(Boolean).join("; ");
2491
2236
  return detailText ? `${report.message} (${detailText})` : report.message;
@@ -2513,7 +2258,6 @@ async function resolveGatewayInstanceId(openKeyedStore) {
2513
2258
  async function reapOpenAcpxProcessLeases(params) {
2514
2259
  const { assertCurrent } = params;
2515
2260
  const leases = await params.leaseStore.listOpen(params.gatewayInstanceId);
2516
- const inspectedPids = [];
2517
2261
  const terminatedPids = [];
2518
2262
  const legacyWrapperRoots = /* @__PURE__ */ new Set();
2519
2263
  for (const lease of leases) {
@@ -2533,7 +2277,6 @@ async function reapOpenAcpxProcessLeases(params) {
2533
2277
  wrapperRoot: lease.wrapperRoot,
2534
2278
  assertCurrent
2535
2279
  });
2536
- inspectedPids.push(...result.inspectedPids);
2537
2280
  terminatedPids.push(...result.terminatedPids);
2538
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");
2539
2282
  await params.leaseStore.markState(lease.leaseId, retryableEvidenceFailure ? "open" : result.terminatedPids.length > 0 ? "closed" : "lost");
@@ -2543,13 +2286,9 @@ async function reapOpenAcpxProcessLeases(params) {
2543
2286
  wrapperRoot,
2544
2287
  assertCurrent
2545
2288
  });
2546
- inspectedPids.push(...legacyResult.inspectedPids);
2547
2289
  terminatedPids.push(...legacyResult.terminatedPids);
2548
2290
  }
2549
- return {
2550
- inspectedPids,
2551
- terminatedPids
2552
- };
2291
+ return { terminatedPids };
2553
2292
  }
2554
2293
  function createAcpxRuntimeService(params) {
2555
2294
  let runtime = null;
@@ -2580,7 +2319,6 @@ function createAcpxRuntimeService(params) {
2580
2319
  return;
2581
2320
  }
2582
2321
  const openKeyedStore = params.openKeyedStore;
2583
- if (!openKeyedStore) throw new Error("ACPX runtime service requires plugin keyed state");
2584
2322
  const basePluginConfig = await measureAcpxStartup(ctx, "config.resolve", () => resolveAcpxPluginConfig({
2585
2323
  rawConfig: params.pluginConfig,
2586
2324
  workspaceDir: ctx.workspaceDir,
@@ -2615,14 +2353,38 @@ function createAcpxRuntimeService(params) {
2615
2353
  if (params.startupPurpose !== "inspection") await promote(ctx);
2616
2354
  const getAllowedAgents = params.getAllowedAgents ?? (() => ctx.config.acp?.allowedAgents);
2617
2355
  const getProbeAgent = () => pluginConfig.probeAgent ?? getAllowedAgents()?.map(normalizeLowercaseStringOrEmpty).find(Boolean);
2618
- const startedRuntime = await measureAcpxStartup(ctx, "runtime.create", () => (params.runtimeFactory ?? createDefaultRuntime)({
2619
- pluginConfig,
2620
- getProbeAgent,
2621
- gatewayInstanceId,
2622
- processLeaseStore,
2623
- wrapperRoot,
2624
- logger: ctx.logger
2625
- }));
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
+ });
2626
2388
  runtime = startedRuntime;
2627
2389
  const shouldProbeRuntime = params.probeAtStartup !== false && shouldProbeRuntimeAtStartup();
2628
2390
  ctx.startupTrace?.detail?.("probe-policy", [["startupProbeEnabledCount", shouldProbeRuntime ? 1 : 0], ["probeAgent", getProbeAgent() ?? "default"]]);