@integrity-labs/agt-cli 0.28.207 → 0.28.209

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.
@@ -5,6 +5,7 @@ import {
5
5
  expandTemplateVars,
6
6
  getFlagDefinition,
7
7
  getFramework,
8
+ isolationMode,
8
9
  listFlagDefinitions,
9
10
  normalizeFlagValue,
10
11
  parseEnvIntegrations,
@@ -17,7 +18,10 @@ import {
17
18
  resolveConnectivityProbe,
18
19
  worseConnectivityOutcome,
19
20
  wrapScheduledTaskPrompt
20
- } from "./chunk-ELBYWACS.js";
21
+ } from "./chunk-WFCCBTA6.js";
22
+ import {
23
+ parsePsRows
24
+ } from "./chunk-XWVM4KPK.js";
21
25
 
22
26
  // ../../packages/core/dist/provisioning/mcp-config-guards.js
23
27
  import { chmodSync, existsSync, readFileSync, renameSync, writeFileSync, unlinkSync } from "fs";
@@ -4153,14 +4157,14 @@ ${sections}`
4153
4157
  const augDir = join2(homeDir, ".augmented");
4154
4158
  const agents = /* @__PURE__ */ new Set();
4155
4159
  try {
4156
- const { readdirSync: readdirSync2, statSync: statSync2 } = await import("fs");
4160
+ const { readdirSync: readdirSync2, statSync: statSync3 } = await import("fs");
4157
4161
  const entries = readdirSync2(augDir);
4158
4162
  for (const entry of entries) {
4159
4163
  if (entry.startsWith("_") || entry.startsWith("."))
4160
4164
  continue;
4161
4165
  const agentRoot = join2(augDir, entry);
4162
4166
  try {
4163
- if (!statSync2(agentRoot).isDirectory())
4167
+ if (!statSync3(agentRoot).isDirectory())
4164
4168
  continue;
4165
4169
  } catch {
4166
4170
  continue;
@@ -5525,7 +5529,7 @@ function requireHost() {
5525
5529
  }
5526
5530
 
5527
5531
  // src/lib/api-client.ts
5528
- var agtCliVersion = true ? "0.28.207" : "dev";
5532
+ var agtCliVersion = true ? "0.28.209" : "dev";
5529
5533
  var lastConfigHash = null;
5530
5534
  function setConfigHash(hash) {
5531
5535
  lastConfigHash = hash && hash.length > 0 ? hash : null;
@@ -5920,22 +5924,558 @@ var HostFlagStore = class {
5920
5924
  }
5921
5925
  };
5922
5926
 
5923
- // ../../packages/core/dist/provisioning/provisioner.js
5924
- import { createHash } from "crypto";
5925
- function sha256(content) {
5926
- return createHash("sha256").update(content, "utf8").digest("hex");
5927
+ // src/lib/stale-mcp-reaper.ts
5928
+ import { execFileSync } from "child_process";
5929
+ var rotationTimestamps = /* @__PURE__ */ new Map();
5930
+ var DEFAULT_ROTATION_GRACE_MS = 15e3;
5931
+ function rotationKey(codeName, serverKey) {
5932
+ return `${codeName}\0${serverKey}`;
5933
+ }
5934
+ function recordStaleRotation(codeName, serverKeys, now = Date.now) {
5935
+ const ts = now();
5936
+ for (const key of serverKeys) {
5937
+ rotationTimestamps.set(rotationKey(codeName, key), ts);
5938
+ }
5939
+ }
5940
+ function wasRecentlyRotated(codeName, serverKey, withinMs, now = Date.now) {
5941
+ const k = rotationKey(codeName, serverKey);
5942
+ const ts = rotationTimestamps.get(k);
5943
+ if (ts === void 0) return false;
5944
+ if (now() - ts < withinMs) return true;
5945
+ rotationTimestamps.delete(k);
5946
+ return false;
5947
+ }
5948
+ function parseEnvIntegrationsEntries(content) {
5949
+ const entries = /* @__PURE__ */ new Map();
5950
+ for (const raw of content.split(/\r?\n/)) {
5951
+ const line = raw.trim();
5952
+ if (!line || line.startsWith("#")) continue;
5953
+ const eq = line.indexOf("=");
5954
+ if (eq <= 0) continue;
5955
+ const name = line.slice(0, eq).trim();
5956
+ if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(name)) continue;
5957
+ const value = line.slice(eq + 1);
5958
+ entries.set(name, value);
5959
+ }
5960
+ return entries;
5961
+ }
5962
+ function diffEnvIntegrations(oldContent, newContent) {
5963
+ const oldEntries = oldContent === void 0 ? /* @__PURE__ */ new Map() : parseEnvIntegrationsEntries(oldContent);
5964
+ const newEntries = parseEnvIntegrationsEntries(newContent);
5965
+ const changed = /* @__PURE__ */ new Set();
5966
+ for (const [name, value] of newEntries) {
5967
+ if (oldEntries.get(name) !== value) changed.add(name);
5968
+ }
5969
+ for (const name of oldEntries.keys()) {
5970
+ if (!newEntries.has(name)) changed.add(name);
5971
+ }
5972
+ return [...changed];
5973
+ }
5974
+ function findMcpServersUsingVars(mcp, changedVars) {
5975
+ const changedSet = new Set(changedVars);
5976
+ if (!mcp?.mcpServers || changedSet.size === 0) return [];
5977
+ const result = [];
5978
+ for (const [serverKey, entry] of Object.entries(mcp.mcpServers)) {
5979
+ if (!entry || typeof entry !== "object") continue;
5980
+ const env = entry.env;
5981
+ if (!env || typeof env !== "object") continue;
5982
+ let matches = false;
5983
+ for (const value of Object.values(env)) {
5984
+ if (typeof value !== "string") continue;
5985
+ const placeholderMatches = value.match(/\$\{([A-Za-z_][A-Za-z0-9_]*)\}/g);
5986
+ if (placeholderMatches) {
5987
+ for (const ph of placeholderMatches) {
5988
+ const name = ph.slice(2, -1);
5989
+ if (changedSet.has(name)) {
5990
+ matches = true;
5991
+ break;
5992
+ }
5993
+ }
5994
+ }
5995
+ if (matches) break;
5996
+ }
5997
+ if (matches) result.push(serverKey);
5998
+ }
5999
+ return result;
5927
6000
  }
5928
- function provision(input, frameworkId = "claude-code") {
5929
- const adapter = getFramework(frameworkId);
5930
- const artifacts = adapter.buildArtifacts(input);
5931
- const charterHash = sha256(input.charterContent);
5932
- const toolsHash = sha256(input.toolsContent);
5933
- const teamDir = `.augmented/${input.agent.code_name}`;
6001
+ function buildArgvMatchersForEntry(key, entry) {
6002
+ const escapeRe = (s) => s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
6003
+ const patterns = [];
6004
+ const args = entry?.args ?? [];
6005
+ for (let i = args.length - 1; i >= 0; i--) {
6006
+ const arg = args[i];
6007
+ if (typeof arg !== "string" || !arg) continue;
6008
+ if (arg.startsWith("-")) continue;
6009
+ const stripped = arg.replace(
6010
+ /@[^/@]*$/,
6011
+ (m) => (
6012
+ // @latest, @1.2.3, etc. — drop. But @scope at the START of a
6013
+ // package spec must NOT be stripped, so we only strip a tail
6014
+ // `@...` if it doesn't itself start with a slash inside.
6015
+ // The regex above only matches a single trailing `@...`
6016
+ // segment after the last `/`, so this is safe for `@scope/pkg`.
6017
+ m.includes("/") ? m : ""
6018
+ )
6019
+ );
6020
+ const tail = "(?![A-Za-z0-9_-])";
6021
+ if (/^@?[a-z0-9]([a-z0-9._-]*\/)?[a-z0-9._-]+$/i.test(stripped)) {
6022
+ patterns.push(new RegExp(`${escapeRe(stripped)}${tail}`));
6023
+ const basename = stripped.split("/").pop();
6024
+ if (basename && basename !== stripped) {
6025
+ patterns.push(new RegExp(`${escapeRe(basename)}${tail}`));
6026
+ }
6027
+ break;
6028
+ }
6029
+ if (stripped.includes("/")) {
6030
+ const basename = stripped.split("/").pop();
6031
+ if (basename) {
6032
+ patterns.push(new RegExp(`${escapeRe(basename)}${tail}`));
6033
+ break;
6034
+ }
6035
+ }
6036
+ }
6037
+ if (patterns.length === 0) {
6038
+ const safe = escapeRe(key);
6039
+ patterns.push(new RegExp(`(?<![A-Za-z0-9_])${safe}(?![A-Za-z0-9_])`));
6040
+ if (safe.includes("_")) {
6041
+ const dashed = safe.replace(/_/g, "-");
6042
+ patterns.push(new RegExp(`(?<![A-Za-z0-9_])${dashed}(?![A-Za-z0-9_])`));
6043
+ }
6044
+ }
6045
+ return patterns;
6046
+ }
6047
+ function buildClaudeAgentMatcher(codeName) {
6048
+ const safe = codeName.replace(/[^A-Za-z0-9_-]/g, "");
6049
+ return new RegExp(`\\bclaude\\b.*--name\\s+agt-${safe}(?=\\s|$)`);
6050
+ }
6051
+ function findMcpChildrenForAgent(args) {
6052
+ const { rows, codeName, serverKeys, mcpJson } = args;
6053
+ const maxDepth = args.maxDepth ?? 8;
6054
+ const inContainer = args.inContainer ?? false;
6055
+ if (serverKeys.length === 0 || rows.length === 0) return [];
6056
+ const claudeMatcher = inContainer ? /\bclaude\b/ : buildClaudeAgentMatcher(codeName);
6057
+ const argvMatchers = [];
6058
+ for (const key of serverKeys) {
6059
+ const entry = mcpJson?.mcpServers?.[key];
6060
+ argvMatchers.push(...buildArgvMatchersForEntry(key, entry));
6061
+ }
6062
+ const byPid = new Map(rows.map((r) => [r.pid, r]));
6063
+ const matched = [];
6064
+ for (const row of rows) {
6065
+ if (!argvMatchers.some((re) => re.test(row.args))) continue;
6066
+ if (/\bclaude\b/.test(row.args) && row.args.includes(`--name agt-${codeName}`)) continue;
6067
+ let cur = byPid.get(row.ppid);
6068
+ let belongs = false;
6069
+ for (let depth = 0; depth < maxDepth && cur; depth++) {
6070
+ if (claudeMatcher.test(cur.args)) {
6071
+ belongs = true;
6072
+ break;
6073
+ }
6074
+ if (cur.pid === 1) break;
6075
+ cur = byPid.get(cur.ppid);
6076
+ }
6077
+ if (belongs) matched.push(row.pid);
6078
+ }
6079
+ return matched;
6080
+ }
6081
+ function reapStaleMcpChildren(args) {
6082
+ const { log, codeName, serverKeys, mcpJson, graceMs = 5e3, isolated = false } = args;
6083
+ if (serverKeys.length === 0) return [];
6084
+ const runPs = args.runPs ?? (isolated ? () => execFileSync("docker", ["exec", `agt-${codeName}`, "ps", "-eo", "pid,ppid,args"], {
6085
+ encoding: "utf-8",
6086
+ timeout: 8e3
6087
+ }) : () => execFileSync("ps", ["-eo", "pid,ppid,args"], { encoding: "utf-8", timeout: 5e3 }));
6088
+ const killProcess = args.killProcess ?? (isolated ? (pid, signal) => {
6089
+ try {
6090
+ execFileSync(
6091
+ "docker",
6092
+ ["exec", `agt-${codeName}`, "kill", signal === "SIGKILL" ? "-KILL" : "-TERM", String(pid)],
6093
+ { timeout: 8e3, stdio: "ignore" }
6094
+ );
6095
+ } catch {
6096
+ }
6097
+ } : (pid, signal) => {
6098
+ try {
6099
+ process.kill(pid, signal);
6100
+ } catch {
6101
+ }
6102
+ });
6103
+ const isAlive = args.isAlive ?? (isolated ? (pid) => {
6104
+ try {
6105
+ execFileSync("docker", ["exec", `agt-${codeName}`, "kill", "-0", String(pid)], {
6106
+ timeout: 8e3,
6107
+ stdio: "ignore"
6108
+ });
6109
+ return true;
6110
+ } catch {
6111
+ return false;
6112
+ }
6113
+ } : (pid) => {
6114
+ try {
6115
+ process.kill(pid, 0);
6116
+ return true;
6117
+ } catch {
6118
+ return false;
6119
+ }
6120
+ });
6121
+ let psOutput;
6122
+ try {
6123
+ psOutput = runPs();
6124
+ } catch (err) {
6125
+ log(`[stale-mcp-reaper] ps invocation failed for '${codeName}': ${err.message} \u2014 skipping reap`);
6126
+ return [];
6127
+ }
6128
+ const rows = parsePsRows(psOutput);
6129
+ const targets = findMcpChildrenForAgent({ rows, codeName, serverKeys, mcpJson, inContainer: isolated });
6130
+ if (targets.length === 0) return [];
6131
+ const byPid = new Map(rows.map((r) => [r.pid, r]));
6132
+ const describe = (pid) => {
6133
+ const argv = byPid.get(pid)?.args ?? "";
6134
+ const pkgMatch = argv.match(/(@[a-z0-9_-]+\/[a-z0-9_-]+|[a-z0-9_-]+-mcp-server|[a-z0-9_-]+-mcp\b)/i);
6135
+ return pkgMatch ? `${pkgMatch[1]} (pid ${pid})` : `pid ${pid}`;
6136
+ };
6137
+ log(
6138
+ `[stale-mcp-reaper] '${codeName}': rotating ${targets.length} stale MCP child(ren) for [${serverKeys.join(", ")}]: ${targets.map(describe).join(", ")}`
6139
+ );
6140
+ for (const pid of targets) {
6141
+ killProcess(pid, "SIGTERM");
6142
+ }
6143
+ const killedKeys = /* @__PURE__ */ new Set();
6144
+ for (const pid of targets) {
6145
+ const argv = byPid.get(pid)?.args ?? "";
6146
+ for (const key of serverKeys) {
6147
+ const entry = mcpJson?.mcpServers?.[key];
6148
+ const matchers = buildArgvMatchersForEntry(key, entry);
6149
+ if (matchers.some((re) => re.test(argv))) killedKeys.add(key);
6150
+ }
6151
+ }
6152
+ if (killedKeys.size > 0) recordStaleRotation(codeName, killedKeys);
6153
+ setTimeout(() => {
6154
+ try {
6155
+ let freshPsOutput;
6156
+ try {
6157
+ freshPsOutput = runPs();
6158
+ } catch (err) {
6159
+ log(`[stale-mcp-reaper] '${codeName}': fresh ps for SIGKILL re-verify failed: ${err.message} \u2014 skipping SIGKILL pass`);
6160
+ return;
6161
+ }
6162
+ const stillOwned = new Set(
6163
+ findMcpChildrenForAgent({
6164
+ rows: parsePsRows(freshPsOutput),
6165
+ codeName,
6166
+ serverKeys,
6167
+ mcpJson,
6168
+ inContainer: isolated
6169
+ })
6170
+ );
6171
+ const stragglers = targets.filter((pid) => isAlive(pid) && stillOwned.has(pid));
6172
+ if (stragglers.length === 0) return;
6173
+ log(
6174
+ `[stale-mcp-reaper] '${codeName}': ${stragglers.length} child(ren) survived SIGTERM; sending SIGKILL: ${stragglers.map(describe).join(", ")}`
6175
+ );
6176
+ for (const pid of stragglers) {
6177
+ killProcess(pid, "SIGKILL");
6178
+ }
6179
+ } catch (err) {
6180
+ log(`[stale-mcp-reaper] '${codeName}': error in SIGKILL pass: ${err.message}`);
6181
+ }
6182
+ }, graceMs).unref();
6183
+ return targets;
6184
+ }
6185
+
6186
+ // src/lib/mcp-presence-reaper.ts
6187
+ import { execFileSync as execFileSync2 } from "child_process";
6188
+ var DEFAULT_COLD_START_GRACE_MS = 9e4;
6189
+ var MAX_PRESENCE_RESTART_ATTEMPTS = 3;
6190
+ var BACKOFF_AFTER_RESTARTS = MAX_PRESENCE_RESTART_ATTEMPTS;
6191
+ var BACKOFF_BASE_MS = 6e4;
6192
+ var BACKOFF_MAX_MS = 30 * 6e4;
6193
+ var BACKOFF_WINDOW_MS = 60 * 6e4;
6194
+ var BACKOFF_GIVE_UP_RESTARTS = 2 * MAX_PRESENCE_RESTART_ATTEMPTS;
6195
+ var BACKOFF_STABLE_RESET_MS = 5 * 6e4;
6196
+ var presenceReaperState = /* @__PURE__ */ new Map();
6197
+ function stateKey(codeName, serverKey) {
6198
+ return `${codeName}\0${serverKey}`;
6199
+ }
6200
+ function clearPresenceReaperState(codeName) {
6201
+ const prefix = `${codeName}\0`;
6202
+ for (const key of presenceReaperState.keys()) {
6203
+ if (key.startsWith(prefix)) presenceReaperState.delete(key);
6204
+ }
6205
+ }
6206
+ function clearPresenceReaperStateForKeys(codeName, keys) {
6207
+ for (const key of keys) {
6208
+ presenceReaperState.delete(stateKey(codeName, key));
6209
+ }
6210
+ }
6211
+ function givenUpMcpServerKeys(codeName) {
6212
+ const prefix = `${codeName}\0`;
6213
+ const out = /* @__PURE__ */ new Set();
6214
+ for (const [key, st] of presenceReaperState) {
6215
+ if (key.startsWith(prefix) && (st.gaveUp || st.attempts >= MAX_PRESENCE_RESTART_ATTEMPTS)) {
6216
+ out.add(key.slice(prefix.length));
6217
+ }
6218
+ }
6219
+ return out;
6220
+ }
6221
+ function findMissingMcpServers(args) {
6222
+ const { rows, codeName, mcpJson, inContainer } = args;
6223
+ const servers = mcpJson?.mcpServers ?? {};
6224
+ const declared = Object.keys(servers);
6225
+ if (declared.length === 0) return [];
6226
+ const missing = [];
6227
+ for (const key of declared) {
6228
+ const entry = servers[key];
6229
+ const isStdio = typeof entry?.command === "string";
6230
+ if (!isStdio) continue;
6231
+ const live = findMcpChildrenForAgent({
6232
+ rows,
6233
+ codeName,
6234
+ serverKeys: [key],
6235
+ mcpJson,
6236
+ inContainer
6237
+ });
6238
+ if (live.length === 0) missing.push(key);
6239
+ }
6240
+ return missing;
6241
+ }
6242
+ function reapMissingMcpSessions(args) {
6243
+ const {
6244
+ log,
6245
+ codeName,
6246
+ mcpJson,
6247
+ sessionStartedAt,
6248
+ restartPending = false,
6249
+ stopSession,
6250
+ graceMs = DEFAULT_COLD_START_GRACE_MS,
6251
+ rotationGraceMs = DEFAULT_ROTATION_GRACE_MS,
6252
+ onGiveUp,
6253
+ onRestart,
6254
+ // ENG-5932: defaults make quarantine a strict no-op (classify everything
6255
+ // essential, mode off) so legacy callers/tests are unaffected.
6256
+ classifyKey = () => "essential",
6257
+ quarantineDwellMs = 0,
6258
+ quarantineMode = "off",
6259
+ onQuarantine,
6260
+ isolated = false
6261
+ } = args;
6262
+ const now = args.now ?? Date.now;
6263
+ const runPs = args.runPs ?? (isolated ? () => execFileSync2("docker", ["exec", `agt-${codeName}`, "ps", "-eo", "pid,ppid,args"], {
6264
+ encoding: "utf-8",
6265
+ timeout: 8e3
6266
+ }) : () => execFileSync2("ps", ["-eo", "pid,ppid,args"], { encoding: "utf-8", timeout: 5e3 }));
6267
+ if (!mcpJson?.mcpServers) {
6268
+ return { missing: [], restarted: false, reason: "no-mcp-json" };
6269
+ }
6270
+ const declaredCount = Object.keys(mcpJson.mcpServers).length;
6271
+ if (declaredCount === 0) {
6272
+ return { missing: [], restarted: false, reason: "no-declared-servers" };
6273
+ }
6274
+ if (restartPending) {
6275
+ return { missing: [], restarted: false, reason: "restart-pending" };
6276
+ }
6277
+ if (sessionStartedAt === null) {
6278
+ return { missing: [], restarted: false, reason: "session-start-unknown" };
6279
+ }
6280
+ if (now() - sessionStartedAt < graceMs) {
6281
+ return { missing: [], restarted: false, reason: "cold-start" };
6282
+ }
6283
+ let psOutput;
6284
+ try {
6285
+ psOutput = runPs();
6286
+ } catch (err) {
6287
+ log(`[mcp-presence-reaper] ps invocation failed for '${codeName}': ${err.message} \u2014 skipping`);
6288
+ return { missing: [], restarted: false, reason: "healthy" };
6289
+ }
6290
+ const rows = parsePsRows(psOutput);
6291
+ const missingRaw = findMissingMcpServers({ rows, codeName, mcpJson, inContainer: isolated });
6292
+ const rotationGraced = [];
6293
+ const missing = [];
6294
+ for (const key of missingRaw) {
6295
+ if (wasRecentlyRotated(codeName, key, rotationGraceMs, now)) {
6296
+ rotationGraced.push(key);
6297
+ } else {
6298
+ missing.push(key);
6299
+ }
6300
+ }
6301
+ if (rotationGraced.length > 0) {
6302
+ log(
6303
+ `[mcp-presence-reaper] '${codeName}': skipping [${rotationGraced.join(", ")}] within rotation grace window (${rotationGraceMs}ms) \u2014 child(ren) just SIGTERM'd by stale-mcp-reaper, awaiting respawn on next tool call (ENG-5344)`
6304
+ );
6305
+ }
6306
+ const declared = mcpJson.mcpServers ?? {};
6307
+ const liveKeys = /* @__PURE__ */ new Set();
6308
+ for (const key of Object.keys(declared)) {
6309
+ const entry = declared[key];
6310
+ if (typeof entry?.command !== "string") continue;
6311
+ if (!missingRaw.includes(key)) liveKeys.add(key);
6312
+ }
6313
+ for (const key of liveKeys) {
6314
+ const state = presenceReaperState.get(stateKey(codeName, key));
6315
+ if (state) {
6316
+ state.attempts = 0;
6317
+ state.lastSeenLiveAt = now();
6318
+ state.lastAttemptedSessionStartedAt = null;
6319
+ state.gaveUpLogged = false;
6320
+ state.firstMissingAt = null;
6321
+ state.quarantineLogged = false;
6322
+ state.gaveUp = false;
6323
+ if (state.stableLiveSince === null) state.stableLiveSince = now();
6324
+ if (now() - state.stableLiveSince >= BACKOFF_STABLE_RESET_MS) {
6325
+ state.restartHistory = [];
6326
+ }
6327
+ }
6328
+ }
6329
+ if (missing.length === 0) {
6330
+ return {
6331
+ missing,
6332
+ restarted: false,
6333
+ reason: "healthy",
6334
+ rotationGraced: rotationGraced.length > 0 ? rotationGraced : void 0
6335
+ };
6336
+ }
6337
+ const nowMs = now();
6338
+ const givenUp = [];
6339
+ const active = [];
6340
+ const backingOff = [];
6341
+ const newGenerationKeys = /* @__PURE__ */ new Set();
6342
+ const quarantined = [];
6343
+ const wouldQuarantine = [];
6344
+ for (const key of missing) {
6345
+ const sk = stateKey(codeName, key);
6346
+ const state = presenceReaperState.get(sk) ?? {
6347
+ attempts: 0,
6348
+ lastSeenLiveAt: null,
6349
+ lastAttemptedSessionStartedAt: null,
6350
+ gaveUpLogged: false,
6351
+ firstMissingAt: null,
6352
+ quarantineLogged: false,
6353
+ restartHistory: [],
6354
+ stableLiveSince: null,
6355
+ gaveUp: false
6356
+ };
6357
+ if (state.firstMissingAt === null) state.firstMissingAt = nowMs;
6358
+ state.stableLiveSince = null;
6359
+ if (state.lastAttemptedSessionStartedAt !== sessionStartedAt) {
6360
+ state.attempts += 1;
6361
+ state.lastAttemptedSessionStartedAt = sessionStartedAt;
6362
+ newGenerationKeys.add(key);
6363
+ }
6364
+ state.restartHistory = state.restartHistory.filter((t) => nowMs - t < BACKOFF_WINDOW_MS);
6365
+ const restartsInWindow = state.restartHistory.length;
6366
+ presenceReaperState.set(sk, state);
6367
+ const overAttemptsCap = state.attempts > MAX_PRESENCE_RESTART_ATTEMPTS;
6368
+ const overRateCap = restartsInWindow >= BACKOFF_GIVE_UP_RESTARTS;
6369
+ if (overAttemptsCap || overRateCap) {
6370
+ givenUp.push(key);
6371
+ state.gaveUp = true;
6372
+ if (!state.gaveUpLogged) {
6373
+ const cause = overAttemptsCap ? `${MAX_PRESENCE_RESTART_ATTEMPTS} consecutive failed restarts \u2014 declared but never recovers (likely orphaned config; see ENG-5279)` : `${restartsInWindow} restarts within ${Math.round(BACKOFF_WINDOW_MS / 6e4)}m \u2014 persistently flapping (crash-loop; ENG-6480)`;
6374
+ log(
6375
+ `[mcp-presence-reaper] giving up on '${codeName}:${key}' after ${cause}`
6376
+ );
6377
+ state.gaveUpLogged = true;
6378
+ if (onGiveUp) {
6379
+ try {
6380
+ onGiveUp(codeName, key);
6381
+ } catch (err) {
6382
+ log(
6383
+ `[mcp-presence-reaper] onGiveUp callback threw for '${codeName}:${key}' (suppressed; reaper continues): ${err.message}`
6384
+ );
6385
+ }
6386
+ }
6387
+ }
6388
+ if (quarantineMode !== "off" && !state.quarantineLogged && classifyKey(key) === "optional") {
6389
+ const dwellElapsed = quarantineDwellMs <= 0 || state.firstMissingAt !== null && nowMs - state.firstMissingAt >= quarantineDwellMs;
6390
+ if (dwellElapsed) {
6391
+ state.quarantineLogged = true;
6392
+ if (quarantineMode === "enforce") {
6393
+ quarantined.push(key);
6394
+ log(
6395
+ `[mcp-presence-reaper] QUARANTINE '${codeName}:${key}' \u2014 optional channel dead past restart budget + ${quarantineDwellMs}ms dwell; dropping from provisioned set so the dead channel stops restarting the whole session (ENG-5932)`
6396
+ );
6397
+ if (onQuarantine) {
6398
+ try {
6399
+ onQuarantine(codeName, key);
6400
+ } catch (err) {
6401
+ log(
6402
+ `[mcp-presence-reaper] onQuarantine callback threw for '${codeName}:${key}' (suppressed; reaper continues): ${err.message}`
6403
+ );
6404
+ }
6405
+ }
6406
+ } else {
6407
+ wouldQuarantine.push(key);
6408
+ log(
6409
+ `[mcp-presence-reaper] SHADOW would-quarantine '${codeName}:${key}' \u2014 optional channel dead past restart budget + ${quarantineDwellMs}ms dwell; no action taken (ENG-5932 shadow mode)`
6410
+ );
6411
+ }
6412
+ }
6413
+ }
6414
+ } else {
6415
+ const backoffMs = restartsInWindow < BACKOFF_AFTER_RESTARTS ? 0 : Math.min(
6416
+ BACKOFF_BASE_MS * 2 ** (restartsInWindow - BACKOFF_AFTER_RESTARTS),
6417
+ BACKOFF_MAX_MS
6418
+ );
6419
+ const lastRestartAt = state.restartHistory[state.restartHistory.length - 1] ?? null;
6420
+ if (lastRestartAt !== null && nowMs - lastRestartAt < backoffMs) {
6421
+ backingOff.push(key);
6422
+ } else {
6423
+ active.push(key);
6424
+ }
6425
+ }
6426
+ }
6427
+ if (active.length === 0) {
6428
+ const reason = backingOff.length > 0 ? "backoff" : "all-keys-over-cap";
6429
+ if (backingOff.length > 0) {
6430
+ log(
6431
+ `[mcp-presence-reaper] '${codeName}': holding off restart for [${backingOff.join(", ")}] \u2014 escalating backoff interval not yet elapsed (ENG-6480)${givenUp.length > 0 ? ` (given up: [${givenUp.join(", ")}])` : ""}`
6432
+ );
6433
+ }
6434
+ return {
6435
+ missing,
6436
+ restarted: false,
6437
+ reason,
6438
+ givenUp,
6439
+ backingOff: backingOff.length > 0 ? backingOff : void 0,
6440
+ rotationGraced: rotationGraced.length > 0 ? rotationGraced : void 0,
6441
+ quarantined: quarantined.length > 0 ? quarantined : void 0,
6442
+ wouldQuarantine: wouldQuarantine.length > 0 ? wouldQuarantine : void 0
6443
+ };
6444
+ }
6445
+ const givenUpSuffix = givenUp.length > 0 ? ` (skipping over-cap: [${givenUp.join(", ")}])` : "";
6446
+ log(
6447
+ `[mcp-presence-reaper] '${codeName}': declared MCP(s) [${active.join(", ")}] have no live children \u2014 restarting session${givenUpSuffix}`
6448
+ );
6449
+ if (onRestart) {
6450
+ try {
6451
+ const maybePromise = onRestart(codeName, { activeKeys: active, givenUpKeys: givenUp });
6452
+ if (maybePromise && typeof maybePromise.then === "function") {
6453
+ void maybePromise.then(void 0, (err) => {
6454
+ log(
6455
+ `[mcp-presence-reaper] onRestart callback rejected for '${codeName}' (suppressed; restart proceeds): ${err.message}`
6456
+ );
6457
+ });
6458
+ }
6459
+ } catch (err) {
6460
+ log(
6461
+ `[mcp-presence-reaper] onRestart callback threw for '${codeName}' (suppressed; restart proceeds): ${err.message}`
6462
+ );
6463
+ }
6464
+ }
6465
+ stopSession(codeName, { activeKeys: active });
6466
+ for (const key of active) {
6467
+ if (!newGenerationKeys.has(key)) continue;
6468
+ const st = presenceReaperState.get(stateKey(codeName, key));
6469
+ if (st) st.restartHistory.push(nowMs);
6470
+ }
5934
6471
  return {
5935
- teamDir,
5936
- artifacts,
5937
- charterHash,
5938
- toolsHash
6472
+ missing,
6473
+ restarted: true,
6474
+ givenUp: givenUp.length > 0 ? givenUp : void 0,
6475
+ backingOff: backingOff.length > 0 ? backingOff : void 0,
6476
+ rotationGraced: rotationGraced.length > 0 ? rotationGraced : void 0,
6477
+ quarantined: quarantined.length > 0 ? quarantined : void 0,
6478
+ wouldQuarantine: wouldQuarantine.length > 0 ? wouldQuarantine : void 0
5939
6479
  };
5940
6480
  }
5941
6481
 
@@ -6097,23 +6637,229 @@ function buildConnectivityProbeDeps(projectDir, probeEnv) {
6097
6637
  };
6098
6638
  }
6099
6639
 
6640
+ // src/lib/session-tool-bind-probe-host.ts
6641
+ import { execFileSync as syncExecFile } from "child_process";
6642
+ import { readFileSync as readFileSync7, statSync as statSync2 } from "fs";
6643
+ import { join as join6 } from "path";
6644
+
6645
+ // src/lib/session-tool-probe.ts
6646
+ function classifyMcpServer(entry) {
6647
+ if (!entry || typeof entry !== "object") return "unknown";
6648
+ const e = entry;
6649
+ if (typeof e.command === "string") return "stdio";
6650
+ if (typeof e.url === "string") return "http";
6651
+ return "unknown";
6652
+ }
6653
+ function splitServerKeysByKind(mcpJson, serverKeys) {
6654
+ const servers = mcpJson?.mcpServers ?? {};
6655
+ const stdio = [];
6656
+ const http = [];
6657
+ for (const key of serverKeys) {
6658
+ const kind = classifyMcpServer(servers[key]);
6659
+ if (kind === "stdio") stdio.push(key);
6660
+ else if (kind === "http") http.push(key);
6661
+ }
6662
+ return { stdio, http };
6663
+ }
6664
+ function computeSessionToolBindStatus(input) {
6665
+ const { stdioServerKeys, httpServerKeys, missingStdioKeys, httpReachable, httpSessionLoaded } = input;
6666
+ if (stdioServerKeys.length === 0 && httpServerKeys.length === 0) return "unknown";
6667
+ if (stdioServerKeys.some((k) => missingStdioKeys.has(k))) return "missing";
6668
+ let anyHttpUnconfirmed = false;
6669
+ for (const k of httpServerKeys) {
6670
+ const reachable = httpReachable.get(k);
6671
+ if (reachable === false) return "unreachable";
6672
+ if (reachable === void 0) {
6673
+ anyHttpUnconfirmed = true;
6674
+ } else if (!httpSessionLoaded) {
6675
+ anyHttpUnconfirmed = true;
6676
+ }
6677
+ }
6678
+ if (anyHttpUnconfirmed && stdioServerKeys.length === 0) return "unknown";
6679
+ return "bound";
6680
+ }
6681
+
6682
+ // src/lib/session-tool-bind-runner.ts
6683
+ var DEFAULT_INTERVAL_MS = 60 * 60 * 1e3;
6684
+ var DEFAULT_MAX_PER_RUN = 25;
6685
+ function sanitizeServerKey(definitionId) {
6686
+ return definitionId.replace(/[^a-z0-9]/gi, "_").toLowerCase();
6687
+ }
6688
+ function resolveIntegrationServerKeys(definitionId, declaredKeys, hint) {
6689
+ const declared = new Set(declaredKeys);
6690
+ const candidates = [hint, definitionId, sanitizeServerKey(definitionId)].filter(
6691
+ (k) => typeof k === "string" && k.length > 0
6692
+ );
6693
+ const out = /* @__PURE__ */ new Set();
6694
+ for (const c of candidates) if (declared.has(c)) out.add(c);
6695
+ return [...out];
6696
+ }
6697
+ function isDue(last, now, intervalMs) {
6698
+ if (!last) return true;
6699
+ const t = Date.parse(last);
6700
+ if (Number.isNaN(t)) return true;
6701
+ return now - t >= intervalMs;
6702
+ }
6703
+ async function runSessionToolBindProbes(integrations, options) {
6704
+ const now = (options.now?.() ?? /* @__PURE__ */ new Date()).getTime();
6705
+ const intervalMs = options.intervalMs ?? DEFAULT_INTERVAL_MS;
6706
+ const maxPerRun = options.maxPerRun ?? DEFAULT_MAX_PER_RUN;
6707
+ const due = integrations.filter((i) => isDue(i.last_session_tool_bind_at, now, intervalMs)).sort((a, b) => {
6708
+ const ta = a.last_session_tool_bind_at ? Date.parse(a.last_session_tool_bind_at) : 0;
6709
+ const tb = b.last_session_tool_bind_at ? Date.parse(b.last_session_tool_bind_at) : 0;
6710
+ return ta - tb;
6711
+ });
6712
+ const batch = due.slice(0, maxPerRun);
6713
+ const declaredKeys = Object.keys(options.mcpJson?.mcpServers ?? {});
6714
+ const reports = [];
6715
+ let skipped = 0;
6716
+ let probed = 0;
6717
+ for (const integ of batch) {
6718
+ const keys = resolveIntegrationServerKeys(
6719
+ integ.definition_id,
6720
+ declaredKeys,
6721
+ integ.mcp_server_key
6722
+ );
6723
+ if (keys.length === 0) {
6724
+ skipped += 1;
6725
+ continue;
6726
+ }
6727
+ probed += 1;
6728
+ const { stdio, http } = splitServerKeysByKind(options.mcpJson, keys);
6729
+ const httpReachable = /* @__PURE__ */ new Map();
6730
+ for (const key of http) {
6731
+ let reachable;
6732
+ try {
6733
+ reachable = await options.probeHttp(key);
6734
+ } catch {
6735
+ reachable = void 0;
6736
+ }
6737
+ if (reachable !== void 0) httpReachable.set(key, reachable);
6738
+ }
6739
+ const status = computeSessionToolBindStatus({
6740
+ stdioServerKeys: stdio,
6741
+ httpServerKeys: http,
6742
+ missingStdioKeys: options.missingStdioKeys,
6743
+ httpReachable,
6744
+ httpSessionLoaded: options.httpSessionLoaded ?? false
6745
+ });
6746
+ if (status === "unknown") {
6747
+ skipped += 1;
6748
+ continue;
6749
+ }
6750
+ reports.push({ integration_id: integ.id, scope: integ.scope, status });
6751
+ }
6752
+ return { reports, due: due.length, probed, skipped };
6753
+ }
6754
+
6755
+ // src/lib/session-tool-bind-probe-host.ts
6756
+ async function gatherSessionToolBindProbe(agent, integrations, projectDir, opts) {
6757
+ if (integrations.length === 0) return null;
6758
+ let mcpJson = null;
6759
+ try {
6760
+ mcpJson = JSON.parse(readFileSync7(join6(projectDir, ".mcp.json"), "utf-8"));
6761
+ } catch {
6762
+ return null;
6763
+ }
6764
+ if (!mcpJson?.mcpServers || Object.keys(mcpJson.mcpServers).length === 0) return null;
6765
+ const isolated = isolationMode(agent.code_name) === "docker";
6766
+ const hasDeclaredStdio = Object.values(mcpJson.mcpServers).some(
6767
+ (entry) => typeof entry?.command === "string"
6768
+ );
6769
+ let missingStdioKeys = /* @__PURE__ */ new Set();
6770
+ try {
6771
+ const psOutput = isolated ? syncExecFile("docker", ["exec", `agt-${agent.code_name}`, "ps", "-eo", "pid,ppid,args"], {
6772
+ encoding: "utf-8",
6773
+ timeout: 8e3
6774
+ }) : syncExecFile("ps", ["-eo", "pid,ppid,args"], { encoding: "utf-8", timeout: 5e3 });
6775
+ missingStdioKeys = new Set(
6776
+ findMissingMcpServers({
6777
+ rows: parsePsRows(psOutput),
6778
+ codeName: agent.code_name,
6779
+ mcpJson,
6780
+ inContainer: isolated
6781
+ })
6782
+ );
6783
+ } catch {
6784
+ if (hasDeclaredStdio) return null;
6785
+ }
6786
+ const probeEnv = buildProbeEnv(projectDir);
6787
+ const probeDeps = buildConnectivityProbeDeps(projectDir, probeEnv);
6788
+ const probeHttp = async (serverKey) => {
6789
+ if (!probeDeps.mcpProbe) return void 0;
6790
+ const outcome = await probeDeps.mcpProbe({ serverKey, definitionId: serverKey });
6791
+ if (outcome.status === "ok") return true;
6792
+ if (outcome.status === "down") return false;
6793
+ return void 0;
6794
+ };
6795
+ let httpSessionLoaded = false;
6796
+ try {
6797
+ const mcpMtimeMs = statSync2(join6(projectDir, ".mcp.json")).mtimeMs;
6798
+ httpSessionLoaded = opts.sessionStartedMs != null && opts.sessionStartedMs >= mcpMtimeMs;
6799
+ } catch {
6800
+ }
6801
+ return runSessionToolBindProbes(
6802
+ integrations.map((i) => ({
6803
+ id: i.id,
6804
+ definition_id: i.definition_id,
6805
+ scope: i.scope,
6806
+ last_session_tool_bind_at: i.last_session_tool_bind_at ?? null,
6807
+ // Server-key hint for managed/remote-MCP kinds; the runner also tries the
6808
+ // raw + sanitised definition_id against the real `.mcp.json` keys.
6809
+ mcp_server_key: deriveMcpServerKey({
6810
+ definitionId: i.definition_id,
6811
+ sourceType: i.source_type ?? null,
6812
+ authType: i.auth_type,
6813
+ connectivityTest: i.connectivity_test ?? null
6814
+ })
6815
+ })),
6816
+ {
6817
+ mcpJson,
6818
+ missingStdioKeys,
6819
+ probeHttp,
6820
+ httpSessionLoaded,
6821
+ intervalMs: opts.intervalMs,
6822
+ ...opts.maxPerRun !== void 0 ? { maxPerRun: opts.maxPerRun } : {}
6823
+ }
6824
+ );
6825
+ }
6826
+
6827
+ // ../../packages/core/dist/provisioning/provisioner.js
6828
+ import { createHash } from "crypto";
6829
+ function sha256(content) {
6830
+ return createHash("sha256").update(content, "utf8").digest("hex");
6831
+ }
6832
+ function provision(input, frameworkId = "claude-code") {
6833
+ const adapter = getFramework(frameworkId);
6834
+ const artifacts = adapter.buildArtifacts(input);
6835
+ const charterHash = sha256(input.charterContent);
6836
+ const toolsHash = sha256(input.toolsContent);
6837
+ const teamDir = `.augmented/${input.agent.code_name}`;
6838
+ return {
6839
+ teamDir,
6840
+ artifacts,
6841
+ charterHash,
6842
+ toolsHash
6843
+ };
6844
+ }
6845
+
6100
6846
  // src/commands/manager.ts
6101
6847
  import chalk3 from "chalk";
6102
6848
  import { existsSync as existsSync8, realpathSync } from "fs";
6103
- import { join as join7 } from "path";
6849
+ import { join as join8 } from "path";
6104
6850
  import { homedir as homedir4, userInfo } from "os";
6105
6851
  import { spawn as spawn2 } from "child_process";
6106
6852
 
6107
6853
  // src/lib/watchdog.ts
6108
- import { readFileSync as readFileSync7, writeFileSync as writeFileSync5, unlinkSync as unlinkSync3, existsSync as existsSync7, mkdirSync as mkdirSync5, openSync as openSync2, closeSync as closeSync2, chmodSync as chmodSync4 } from "fs";
6109
- import { join as join6 } from "path";
6110
- import { spawn, execFileSync } from "child_process";
6111
- var DEFAULT_CONFIG_DIR = join6(process.env["HOME"] ?? "/tmp", ".augmented");
6854
+ import { readFileSync as readFileSync8, writeFileSync as writeFileSync5, unlinkSync as unlinkSync3, existsSync as existsSync7, mkdirSync as mkdirSync5, openSync as openSync2, closeSync as closeSync2, chmodSync as chmodSync4 } from "fs";
6855
+ import { join as join7 } from "path";
6856
+ import { spawn, execFileSync as execFileSync3 } from "child_process";
6857
+ var DEFAULT_CONFIG_DIR = join7(process.env["HOME"] ?? "/tmp", ".augmented");
6112
6858
  function getManagerPaths(configDir) {
6113
6859
  return {
6114
- pidFile: join6(configDir, "manager.pid"),
6115
- stateFile: join6(configDir, "manager-state.json"),
6116
- logFile: join6(configDir, "manager.log")
6860
+ pidFile: join7(configDir, "manager.pid"),
6861
+ stateFile: join7(configDir, "manager-state.json"),
6862
+ logFile: join7(configDir, "manager.log")
6117
6863
  };
6118
6864
  }
6119
6865
  function ensureDir(configDir) {
@@ -6127,7 +6873,7 @@ function writePidFile(configDir, pid) {
6127
6873
  }
6128
6874
  function readPidFile(configDir) {
6129
6875
  try {
6130
- const raw = readFileSync7(getManagerPaths(configDir).pidFile, "utf-8").trim();
6876
+ const raw = readFileSync8(getManagerPaths(configDir).pidFile, "utf-8").trim();
6131
6877
  const pid = parseInt(raw, 10);
6132
6878
  return isNaN(pid) ? null : pid;
6133
6879
  } catch {
@@ -6158,14 +6904,14 @@ function findOtherManagerPids(pgrepImpl = defaultPgrep, selfPid = process.pid) {
6158
6904
  return out.split("\n").map((line) => parseInt(line.trim(), 10)).filter((pid) => !isNaN(pid) && pid !== selfPid);
6159
6905
  }
6160
6906
  function defaultPgrep() {
6161
- return execFileSync("pgrep", ["-f", "agt manager start"], {
6907
+ return execFileSync3("pgrep", ["-f", "agt manager start"], {
6162
6908
  encoding: "utf-8",
6163
6909
  stdio: ["ignore", "pipe", "ignore"]
6164
6910
  });
6165
6911
  }
6166
6912
  function readStateFile(configDir) {
6167
6913
  try {
6168
- const raw = readFileSync7(getManagerPaths(configDir).stateFile, "utf-8");
6914
+ const raw = readFileSync8(getManagerPaths(configDir).stateFile, "utf-8");
6169
6915
  return JSON.parse(raw);
6170
6916
  } catch {
6171
6917
  return null;
@@ -6349,7 +7095,7 @@ function managerStartCommand(opts) {
6349
7095
  process.exitCode = 1;
6350
7096
  return;
6351
7097
  }
6352
- const configDir = opts.configDir ?? join7(homedir4(), ".augmented");
7098
+ const configDir = opts.configDir ?? join8(homedir4(), ".augmented");
6353
7099
  if (opts.supervise) {
6354
7100
  if (json) {
6355
7101
  jsonOutput({ ok: false, error: "--supervise is not supported with --json" });
@@ -6445,7 +7191,7 @@ function runSupervisorLoop(intervalSec, configDir) {
6445
7191
  }
6446
7192
  async function managerStopCommand(opts = {}) {
6447
7193
  const json = isJsonMode();
6448
- const configDir = opts.configDir ?? join7(homedir4(), ".augmented");
7194
+ const configDir = opts.configDir ?? join8(homedir4(), ".augmented");
6449
7195
  try {
6450
7196
  const result = await stopWatchdog(configDir);
6451
7197
  if (!result.stopped && !result.pid) {
@@ -6473,7 +7219,7 @@ async function managerStopCommand(opts = {}) {
6473
7219
  }
6474
7220
  function managerStatusCommand(opts = {}) {
6475
7221
  const json = isJsonMode();
6476
- const configDir = opts.configDir ?? join7(homedir4(), ".augmented");
7222
+ const configDir = opts.configDir ?? join8(homedir4(), ".augmented");
6477
7223
  const status = getManagerStatus(configDir);
6478
7224
  if (!status) {
6479
7225
  if (json) {
@@ -6565,7 +7311,7 @@ async function managerInstallCommand(opts = {}) {
6565
7311
  process.exitCode = 1;
6566
7312
  return;
6567
7313
  }
6568
- const configDir = opts.configDir ?? join7(homedir4(), ".augmented");
7314
+ const configDir = opts.configDir ?? join8(homedir4(), ".augmented");
6569
7315
  const rawAgtBin = process.argv[1];
6570
7316
  if (!rawAgtBin) {
6571
7317
  const msg = "Could not resolve the agt binary path from argv. Re-run via the installed `agt` command.";
@@ -6578,7 +7324,7 @@ async function managerInstallCommand(opts = {}) {
6578
7324
  if (process.platform === "darwin") {
6579
7325
  const home = homedir4();
6580
7326
  const protectedRoots = ["Documents", "Downloads", "Desktop", "Movies", "Music", "Pictures"];
6581
- const offending = protectedRoots.map((r) => join7(home, r)).find((p) => agtBin === p || agtBin.startsWith(`${p}/`));
7327
+ const offending = protectedRoots.map((r) => join8(home, r)).find((p) => agtBin === p || agtBin.startsWith(`${p}/`));
6582
7328
  if (offending) {
6583
7329
  const msg = `agt binary at ${agtBin} sits inside a macOS TCC-protected folder (${offending}). launchd-spawned processes cannot read files there and the manager would EPERM on startup. Either install agt globally (\`npm install -g @integrity-labs/agt-cli\`) or copy the dist outside protected folders before running this command.`;
6584
7330
  if (json) jsonOutput({ ok: false, error: msg });
@@ -6646,7 +7392,7 @@ async function managerInstallSystemUnitCommand(opts = {}) {
6646
7392
  return;
6647
7393
  }
6648
7394
  const user = opts.user ?? "root";
6649
- const configDir = opts.configDir ?? (user === "root" ? "/root/.augmented" : join7("/home", user, ".augmented"));
7395
+ const configDir = opts.configDir ?? (user === "root" ? "/root/.augmented" : join8("/home", user, ".augmented"));
6650
7396
  const rawAgtBin = process.argv[1];
6651
7397
  if (!rawAgtBin) {
6652
7398
  const msg = "Could not resolve the agt binary path from argv. Re-run via the installed `agt` command.";
@@ -6817,11 +7563,19 @@ export {
6817
7563
  resolveFlagFromLayers,
6818
7564
  resolveAllFlags,
6819
7565
  HostFlagStore,
6820
- provision,
6821
- executeConnectivityProbe,
7566
+ diffEnvIntegrations,
7567
+ findMcpServersUsingVars,
7568
+ reapStaleMcpChildren,
7569
+ clearPresenceReaperState,
7570
+ clearPresenceReaperStateForKeys,
7571
+ givenUpMcpServerKeys,
7572
+ reapMissingMcpSessions,
6822
7573
  deriveMcpServerKey,
6823
7574
  buildProbeEnv,
6824
7575
  buildConnectivityProbeDeps,
7576
+ gatherSessionToolBindProbe,
7577
+ provision,
7578
+ executeConnectivityProbe,
6825
7579
  getManagerPaths,
6826
7580
  startWatchdog,
6827
7581
  managerStartCommand,
@@ -6833,4 +7587,4 @@ export {
6833
7587
  managerInstallSystemUnitCommand,
6834
7588
  managerUninstallSystemUnitCommand
6835
7589
  };
6836
- //# sourceMappingURL=chunk-TPFTAFG3.js.map
7590
+ //# sourceMappingURL=chunk-Z62QHIR3.js.map