@integrity-labs/agt-cli 0.28.1005 → 0.28.1006

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.
Files changed (24) hide show
  1. package/dist/bin/agt.js +5 -5
  2. package/dist/{chunk-TGTUE7Y2.js → chunk-O6R6HS2Z.js} +2 -2
  3. package/dist/{chunk-DVSYT4MU.js → chunk-XWMUQR65.js} +52 -1
  4. package/dist/{chunk-DVSYT4MU.js.map → chunk-XWMUQR65.js.map} +1 -1
  5. package/dist/{chunk-6U4NB3LJ.js → chunk-Z5UDL4AB.js} +35 -5
  6. package/dist/{chunk-6U4NB3LJ.js.map → chunk-Z5UDL4AB.js.map} +1 -1
  7. package/dist/{claude-pair-runtime-DDSYAHQW.js → claude-pair-runtime-AW4N6NEE.js} +157 -18
  8. package/dist/claude-pair-runtime-AW4N6NEE.js.map +1 -0
  9. package/dist/lib/manager-worker.js +609 -304
  10. package/dist/lib/manager-worker.js.map +1 -1
  11. package/dist/mcp/direct-chat-channel.js +57 -2
  12. package/dist/mcp/index.js +51 -0
  13. package/dist/mcp/origami.js +51 -0
  14. package/dist/mcp/slack-channel.js +57 -2
  15. package/dist/mcp/telegram-channel.js +57 -2
  16. package/dist/{persistent-session-4PP3ON7H.js → persistent-session-K4DLZ7KF.js} +3 -3
  17. package/dist/{responsiveness-probe-6NWZAXIZ.js → responsiveness-probe-DXPEIUH6.js} +3 -3
  18. package/dist/{session-auth-dead-2V2BOXAG.js → session-auth-dead-4SE5Q7MU.js} +2 -2
  19. package/package.json +1 -1
  20. package/dist/claude-pair-runtime-DDSYAHQW.js.map +0 -1
  21. /package/dist/{chunk-TGTUE7Y2.js.map → chunk-O6R6HS2Z.js.map} +0 -0
  22. /package/dist/{persistent-session-4PP3ON7H.js.map → persistent-session-K4DLZ7KF.js.map} +0 -0
  23. /package/dist/{responsiveness-probe-6NWZAXIZ.js.map → responsiveness-probe-DXPEIUH6.js.map} +0 -0
  24. /package/dist/{session-auth-dead-2V2BOXAG.js.map → session-auth-dead-4SE5Q7MU.js.map} +0 -0
@@ -1,6 +1,7 @@
1
1
  import {
2
2
  ApiError,
3
3
  COMPUTER_USE_MCP_KEY,
4
+ DEAD_CHANNEL_MS,
4
5
  FIRST_CONNECT_WINDOW_MS,
5
6
  HostFlagStore,
6
7
  RestartBreaker,
@@ -63,7 +64,7 @@ import {
63
64
  safeWriteJsonAtomic,
64
65
  setConfigHash,
65
66
  tripClass
66
- } from "../chunk-6U4NB3LJ.js";
67
+ } from "../chunk-Z5UDL4AB.js";
67
68
  import {
68
69
  getProjectDir as getProjectDir2,
69
70
  getReadyTasks,
@@ -141,7 +142,7 @@ import {
141
142
  takeZombieDetection,
142
143
  toOpencodeModel,
143
144
  writeEgressAllowlist
144
- } from "../chunk-TGTUE7Y2.js";
145
+ } from "../chunk-O6R6HS2Z.js";
145
146
  import {
146
147
  ACCOUNT_ENFORCEMENT_MARKER_FILENAME,
147
148
  AnchorSessionClient,
@@ -240,7 +241,7 @@ import {
240
241
  subagentActivityAgeSeconds,
241
242
  sumTranscriptUsageInWindow,
242
243
  transcriptActivityAgeSeconds
243
- } from "../chunk-DVSYT4MU.js";
244
+ } from "../chunk-XWMUQR65.js";
244
245
  import "../chunk-DHWNVVX4.js";
245
246
  import {
246
247
  reapOrphanChannelMcps
@@ -249,7 +250,7 @@ import "../chunk-DGUM43GV.js";
249
250
 
250
251
  // src/lib/manager-worker.ts
251
252
  import { createHash as createHash20 } from "crypto";
252
- import { readFileSync as readFileSync33, writeFileSync as writeFileSync18, mkdirSync as mkdirSync15, existsSync as existsSync19, rmSync as rmSync8, readdirSync as readdirSync12, statSync as statSync13, unlinkSync as unlinkSync6, renameSync as renameSync11, utimesSync as utimesSync4 } from "fs";
253
+ import { readFileSync as readFileSync34, writeFileSync as writeFileSync18, mkdirSync as mkdirSync15, existsSync as existsSync19, rmSync as rmSync8, readdirSync as readdirSync12, statSync as statSync13, unlinkSync as unlinkSync6, renameSync as renameSync11, utimesSync as utimesSync4 } from "fs";
253
254
 
254
255
  // src/lib/atomic-file-replace.ts
255
256
  import { copyFileSync, renameSync, unlinkSync } from "fs";
@@ -275,7 +276,7 @@ function defaultUnique() {
275
276
 
276
277
  // src/lib/manager-worker.ts
277
278
  import { execFileSync as syncExecFile } from "child_process";
278
- import { join as join42, dirname as dirname11, delimiter as pathDelimiter } from "path";
279
+ import { join as join43, dirname as dirname11, delimiter as pathDelimiter } from "path";
279
280
  import { homedir as homedir18 } from "os";
280
281
  import { fileURLToPath as fileURLToPath2 } from "url";
281
282
 
@@ -1053,9 +1054,157 @@ function clearOnboardingDriveMarker(path) {
1053
1054
  }
1054
1055
  }
1055
1056
 
1056
- // src/lib/channel-quarantine.ts
1057
+ // src/lib/channel-auto-resume.ts
1057
1058
  import { readFileSync as readFileSync3 } from "fs";
1058
1059
  import { join as join3 } from "path";
1060
+ var AUTO_RESUME_BASE_MS = 2 * 60 * 6e4;
1061
+ var AUTO_RESUME_MAX_MS = 24 * 60 * 6e4;
1062
+ var AUTO_RESUME_MAX_ATTEMPTS = 5;
1063
+ var QUARANTINE_DWELL_FLOOR_MS = 18e4;
1064
+ var AUTO_RESUME_SUCCESS_GRACE_MS = 2 * (DEAD_CHANNEL_MS + QUARANTINE_DWELL_FLOOR_MS);
1065
+ function defaultResumeHistoryPath(configDir) {
1066
+ return join3(configDir, "channel-quarantine-resumes.json");
1067
+ }
1068
+ function isResumeFile(value) {
1069
+ if (!value || typeof value !== "object" || Array.isArray(value)) return false;
1070
+ for (const forAgent of Object.values(value)) {
1071
+ if (!forAgent || typeof forAgent !== "object" || Array.isArray(forAgent)) return false;
1072
+ for (const entry of Object.values(forAgent)) {
1073
+ if (!entry || typeof entry !== "object") return false;
1074
+ const e = entry;
1075
+ if (e.gaveUpLogged !== void 0 && typeof e.gaveUpLogged !== "boolean") return false;
1076
+ const attempts = e.attempts;
1077
+ const lastAttemptAt = e.lastAttemptAt;
1078
+ if (typeof attempts !== "number" || !Number.isSafeInteger(attempts) || attempts < 0 || typeof lastAttemptAt !== "number" || !Number.isSafeInteger(lastAttemptAt) || lastAttemptAt < 0) {
1079
+ return false;
1080
+ }
1081
+ }
1082
+ }
1083
+ return true;
1084
+ }
1085
+ var ChannelResumeHistoryStore = class {
1086
+ path;
1087
+ cache = null;
1088
+ constructor(path) {
1089
+ this.path = path;
1090
+ }
1091
+ load() {
1092
+ if (this.cache) return this.cache;
1093
+ try {
1094
+ const parsed = JSON.parse(readFileSync3(this.path, "utf-8"));
1095
+ this.cache = isResumeFile(parsed) ? parsed : {};
1096
+ } catch {
1097
+ this.cache = {};
1098
+ }
1099
+ return this.cache;
1100
+ }
1101
+ persist() {
1102
+ atomicWriteFileSync(this.path, JSON.stringify(this.cache ?? {}, null, 2));
1103
+ }
1104
+ get(codeName, serverKey) {
1105
+ return this.load()[codeName]?.[serverKey];
1106
+ }
1107
+ /**
1108
+ * Every recorded key for one agent, as [storedKey, entry] pairs.
1109
+ *
1110
+ * Needed because the success sweep asks about channels that are NOT in the
1111
+ * quarantine store — a trial that worked leaves history behind and no marker,
1112
+ * so a loop over quarantine entries can never reach it. Returns the STORED
1113
+ * key (see `resumeHistoryKey`), not the channel key, because the caller is
1114
+ * the only thing that knows which namespace it is working in.
1115
+ */
1116
+ entriesFor(codeName) {
1117
+ return Object.entries(this.load()[codeName] ?? {});
1118
+ }
1119
+ /** Record a trial. Returns the entry as written. */
1120
+ recordAttempt(codeName, serverKey, now) {
1121
+ const file = this.load();
1122
+ const forAgent = file[codeName] ??= {};
1123
+ const prior = forAgent[serverKey];
1124
+ const next = {
1125
+ attempts: (prior?.attempts ?? 0) + 1,
1126
+ lastAttemptAt: now,
1127
+ // Carried, not reset: a further trial inside the same episode must not
1128
+ // re-arm the give-up line. It clears with the entry itself on forget().
1129
+ ...prior?.gaveUpLogged ? { gaveUpLogged: true } : {}
1130
+ };
1131
+ forAgent[serverKey] = next;
1132
+ this.persist();
1133
+ return next;
1134
+ }
1135
+ /**
1136
+ * Forget a key's history — called when an OPERATOR clears the quarantine.
1137
+ *
1138
+ * A human pressing Re-enable is a statement that the underlying fault was
1139
+ * addressed, so the next automatic trial should start from a clean two hours
1140
+ * rather than inheriting strikes from before the fix. Without this an
1141
+ * operator could fix a channel, watch it break again for an unrelated reason
1142
+ * weeks later, and find auto-resume already exhausted.
1143
+ */
1144
+ forget(codeName, serverKey) {
1145
+ const file = this.load();
1146
+ const forAgent = file[codeName];
1147
+ if (!forAgent || !forAgent[serverKey]) return false;
1148
+ delete forAgent[serverKey];
1149
+ if (Object.keys(forAgent).length === 0) delete file[codeName];
1150
+ this.persist();
1151
+ return true;
1152
+ }
1153
+ /**
1154
+ * Latch the give-up line for this key. Returns whether it had ALREADY been
1155
+ * logged, so the caller logs only on the first call of an episode.
1156
+ *
1157
+ * Returns true (already logged) when there is no entry at all: with no
1158
+ * history there are no strikes, so there is nothing to have given up ON, and
1159
+ * announcing an abandonment would be false.
1160
+ */
1161
+ noteGaveUpLogged(codeName, serverKey) {
1162
+ const file = this.load();
1163
+ const entry = file[codeName]?.[serverKey];
1164
+ if (!entry) return true;
1165
+ if (entry.gaveUpLogged) return true;
1166
+ entry.gaveUpLogged = true;
1167
+ this.persist();
1168
+ return false;
1169
+ }
1170
+ __invalidateCacheForTests() {
1171
+ this.cache = null;
1172
+ }
1173
+ };
1174
+ function resumeHistoryKey(mode, serverKey) {
1175
+ return mode === "shadow" ? `shadow:${serverKey}` : serverKey;
1176
+ }
1177
+ function backoffForAttempt(attemptsAlreadyMade) {
1178
+ const doubled = AUTO_RESUME_BASE_MS * 2 ** Math.max(0, attemptsAlreadyMade);
1179
+ return Math.min(doubled, AUTO_RESUME_MAX_MS);
1180
+ }
1181
+ function resolveAutoResumeEffectiveMode(autoResume, quarantine) {
1182
+ if (autoResume === "enforce" && quarantine !== "enforce") return "shadow";
1183
+ return autoResume;
1184
+ }
1185
+ function autoResumeSuccessGraceMs(configuredDwellMs) {
1186
+ const dwell = typeof configuredDwellMs === "number" && Number.isFinite(configuredDwellMs) && configuredDwellMs > QUARANTINE_DWELL_FLOOR_MS ? configuredDwellMs : QUARANTINE_DWELL_FLOOR_MS;
1187
+ return 2 * (DEAD_CHANNEL_MS + dwell);
1188
+ }
1189
+ function shouldForgetResumeHistory(input) {
1190
+ if (input.isQuarantined) return false;
1191
+ const history = input.history;
1192
+ if (!history || history.attempts === 0) return false;
1193
+ return input.now - history.lastAttemptAt >= autoResumeSuccessGraceMs(input.configuredDwellMs);
1194
+ }
1195
+ function decideChannelAutoResume(input) {
1196
+ const attempts = input.history?.attempts ?? 0;
1197
+ if (attempts >= AUTO_RESUME_MAX_ATTEMPTS) return { action: "give-up", attempts };
1198
+ const since = Math.max(input.quarantinedAt, input.history?.lastAttemptAt ?? 0);
1199
+ const waited = input.now - since;
1200
+ const need = backoffForAttempt(attempts);
1201
+ if (waited >= need) return { action: "resume", waitedMs: waited, attempt: attempts + 1 };
1202
+ return { action: "wait", dueInMs: need - waited, attempt: attempts + 1 };
1203
+ }
1204
+
1205
+ // src/lib/channel-quarantine.ts
1206
+ import { readFileSync as readFileSync4 } from "fs";
1207
+ import { join as join4 } from "path";
1059
1208
  var ESSENTIAL_CHANNEL_KEYS = /* @__PURE__ */ new Set(["direct-chat", "augmented"]);
1060
1209
  var OPTIONAL_CHANNEL_KEYS = /* @__PURE__ */ new Set([
1061
1210
  "telegram",
@@ -1087,7 +1236,7 @@ function classifyChannelCriticality(serverKey, entry) {
1087
1236
  return "essential";
1088
1237
  }
1089
1238
  function defaultQuarantinePath(configDir) {
1090
- return join3(configDir, "channel-quarantine.json");
1239
+ return join4(configDir, "channel-quarantine.json");
1091
1240
  }
1092
1241
  var ChannelQuarantineStore = class {
1093
1242
  path;
@@ -1098,7 +1247,7 @@ var ChannelQuarantineStore = class {
1098
1247
  load() {
1099
1248
  if (this.cache) return this.cache;
1100
1249
  try {
1101
- const raw = readFileSync3(this.path, "utf-8");
1250
+ const raw = readFileSync4(this.path, "utf-8");
1102
1251
  const parsed = JSON.parse(raw);
1103
1252
  this.cache = isQuarantineFile(parsed) ? parsed : {};
1104
1253
  } catch {
@@ -1186,13 +1335,13 @@ function isQuarantineFile(value) {
1186
1335
  }
1187
1336
 
1188
1337
  // src/lib/claude-md-size.ts
1189
- import { readFileSync as readFileSync4 } from "fs";
1190
- import { join as join4 } from "path";
1338
+ import { readFileSync as readFileSync5 } from "fs";
1339
+ import { join as join5 } from "path";
1191
1340
  function measureClaudeMd(configDir, codeName, ceiling = CLAUDE_MD_CONTEXT_ALARM_CHARS) {
1192
1341
  let chars;
1193
1342
  let bytes;
1194
1343
  try {
1195
- const buf = readFileSync4(join4(configDir, codeName, "project", "CLAUDE.md"));
1344
+ const buf = readFileSync5(join5(configDir, codeName, "project", "CLAUDE.md"));
1196
1345
  chars = buf.toString("utf8").length;
1197
1346
  bytes = buf.length;
1198
1347
  } catch {
@@ -1212,8 +1361,8 @@ function measureClaudeMd(configDir, codeName, ceiling = CLAUDE_MD_CONTEXT_ALARM_
1212
1361
  function measureCoreKnowledgeDescription(configDir, codeName) {
1213
1362
  let text;
1214
1363
  try {
1215
- text = readFileSync4(
1216
- join4(configDir, codeName, "project", ".claude", "skills", "core-knowledge", "SKILL.md"),
1364
+ text = readFileSync5(
1365
+ join5(configDir, codeName, "project", ".claude", "skills", "core-knowledge", "SKILL.md"),
1217
1366
  "utf8"
1218
1367
  );
1219
1368
  } catch {
@@ -1247,16 +1396,16 @@ function logClaudeMdCeilingTransition(codeName, report, log2) {
1247
1396
  }
1248
1397
 
1249
1398
  // ../../packages/core/dist/integrations/forwarded-tools-report.js
1250
- import { readFileSync as readFileSync5, writeFileSync as writeFileSync3 } from "fs";
1251
- import { join as join5 } from "path";
1399
+ import { readFileSync as readFileSync6, writeFileSync as writeFileSync3 } from "fs";
1400
+ import { join as join6 } from "path";
1252
1401
  var FORWARDED_TOOLS_REPORT_FILENAME = "forwarded-tools.json";
1253
1402
  function forwardedToolsReportPath(agentDir) {
1254
- return join5(agentDir, FORWARDED_TOOLS_REPORT_FILENAME);
1403
+ return join6(agentDir, FORWARDED_TOOLS_REPORT_FILENAME);
1255
1404
  }
1256
1405
  function readForwardedToolsReport(agentDir) {
1257
1406
  let raw;
1258
1407
  try {
1259
- raw = readFileSync5(forwardedToolsReportPath(agentDir), "utf-8");
1408
+ raw = readFileSync6(forwardedToolsReportPath(agentDir), "utf-8");
1260
1409
  } catch {
1261
1410
  return null;
1262
1411
  }
@@ -1873,9 +2022,9 @@ var DependencyRecoveryLedger = class {
1873
2022
  // src/lib/mcp-assets-ready.ts
1874
2023
  import { existsSync as nodeExistsSync, readFileSync as nodeReadFileSync } from "fs";
1875
2024
  import { homedir as homedir2 } from "os";
1876
- import { join as join6, resolve, sep } from "path";
2025
+ import { join as join7, resolve, sep } from "path";
1877
2026
  function getSharedMcpDir(homeDir = homedir2()) {
1878
- return join6(homeDir, ".augmented", "_mcp");
2027
+ return join7(homeDir, ".augmented", "_mcp");
1879
2028
  }
1880
2029
  function isPathInsideDir(candidate, dir) {
1881
2030
  const resolvedDir = resolve(dir);
@@ -1885,11 +2034,11 @@ function isPathInsideDir(candidate, dir) {
1885
2034
  }
1886
2035
  function findMissingMcpBundles(mcpConfigPath, deps = {}) {
1887
2036
  const existsSync20 = deps.existsSync ?? nodeExistsSync;
1888
- const readFileSync34 = deps.readFileSync ?? nodeReadFileSync;
2037
+ const readFileSync35 = deps.readFileSync ?? nodeReadFileSync;
1889
2038
  const mcpDir = deps.mcpDir ?? getSharedMcpDir();
1890
2039
  let parsed;
1891
2040
  try {
1892
- parsed = JSON.parse(readFileSync34(mcpConfigPath, "utf-8"));
2041
+ parsed = JSON.parse(readFileSync35(mcpConfigPath, "utf-8"));
1893
2042
  } catch {
1894
2043
  return [];
1895
2044
  }
@@ -1927,7 +2076,7 @@ function formatMissingMcpBundles(missing) {
1927
2076
  }
1928
2077
 
1929
2078
  // src/lib/self-update-coalesce.ts
1930
- import { readFileSync as readFileSync6, writeFileSync as writeFileSync4, mkdirSync as mkdirSync3 } from "fs";
2079
+ import { readFileSync as readFileSync7, writeFileSync as writeFileSync4, mkdirSync as mkdirSync3 } from "fs";
1931
2080
  import { dirname as dirname4 } from "path";
1932
2081
  var DEFAULT_SELF_UPDATE_COALESCE_MS = 30 * 60 * 1e3;
1933
2082
  function resolveCoalesceWindowMs(env = process.env) {
@@ -1937,7 +2086,7 @@ function resolveCoalesceWindowMs(env = process.env) {
1937
2086
  if (!Number.isFinite(parsed) || parsed < 0) return DEFAULT_SELF_UPDATE_COALESCE_MS;
1938
2087
  return Math.trunc(parsed);
1939
2088
  }
1940
- function readLastSelfUpdateAppliedMs(markerPath, now = Date.now(), read = (p) => readFileSync6(p, "utf-8")) {
2089
+ function readLastSelfUpdateAppliedMs(markerPath, now = Date.now(), read = (p) => readFileSync7(p, "utf-8")) {
1941
2090
  let raw;
1942
2091
  try {
1943
2092
  raw = read(markerPath);
@@ -2242,11 +2391,11 @@ async function reportModelApiError(opts) {
2242
2391
  }
2243
2392
 
2244
2393
  // src/lib/claude-pid-tracker.ts
2245
- import { existsSync, readFileSync as readFileSync7 } from "fs";
2394
+ import { existsSync, readFileSync as readFileSync8 } from "fs";
2246
2395
  function readPidFile(path) {
2247
2396
  if (!existsSync(path)) return { version: 1, spawns: [] };
2248
2397
  try {
2249
- const raw = JSON.parse(readFileSync7(path, "utf-8"));
2398
+ const raw = JSON.parse(readFileSync8(path, "utf-8"));
2250
2399
  if (raw.version !== 1 || !Array.isArray(raw.spawns)) return { version: 1, spawns: [] };
2251
2400
  const spawns = raw.spawns.filter(
2252
2401
  (s) => !!s && typeof s.pid === "number" && Number.isFinite(s.pid) && s.pid > 0
@@ -2346,14 +2495,14 @@ async function killSessionsConcurrently(sessions, killOne) {
2346
2495
  }
2347
2496
 
2348
2497
  // src/lib/direct-chat-delivery.ts
2349
- import { join as join7 } from "path";
2498
+ import { join as join8 } from "path";
2350
2499
  var DEFAULT_DIRECT_CHAT_MAX_AGE_MS = 30 * 6e4;
2351
2500
  function directChatMaxAgeMs() {
2352
2501
  const raw = parseInt(process.env["AGT_DIRECT_CHAT_MAX_AGE_MS"] ?? "", 10);
2353
2502
  return Number.isFinite(raw) && raw >= 0 ? raw : DEFAULT_DIRECT_CHAT_MAX_AGE_MS;
2354
2503
  }
2355
2504
  function directChatDoorbellPath(agentId, home) {
2356
- return join7(home, ".augmented", agentId, "direct-chat-doorbell");
2505
+ return join8(home, ".augmented", agentId, "direct-chat-doorbell");
2357
2506
  }
2358
2507
  function isDirectChatMessageExpired(createdAt, nowMs, maxAgeMs) {
2359
2508
  if (!maxAgeMs || maxAgeMs <= 0) return false;
@@ -2364,8 +2513,8 @@ function isDirectChatMessageExpired(createdAt, nowMs, maxAgeMs) {
2364
2513
  }
2365
2514
 
2366
2515
  // src/lib/review-poster-asset.ts
2367
- import { copyFileSync as copyFileSync2, chmodSync, existsSync as existsSync2, mkdirSync as mkdirSync4, readFileSync as readFileSync8 } from "fs";
2368
- import { dirname as dirname5, join as join8 } from "path";
2516
+ import { copyFileSync as copyFileSync2, chmodSync, existsSync as existsSync2, mkdirSync as mkdirSync4, readFileSync as readFileSync9 } from "fs";
2517
+ import { dirname as dirname5, join as join9 } from "path";
2369
2518
  import { fileURLToPath } from "url";
2370
2519
  var POSTER_FILENAME = "post-review-findings.mjs";
2371
2520
  var AUTH_FILENAME = "obiwan-auth.mjs";
@@ -2378,14 +2527,14 @@ function resolveBundledReviewAssetDir() {
2378
2527
  const moduleDir = dirname5(fileURLToPath(import.meta.url));
2379
2528
  const candidates = [
2380
2529
  // Built output: dist/<chunk>.js → dist/assets/review
2381
- join8(moduleDir, "assets", REVIEW_ASSET_DIRNAME),
2530
+ join9(moduleDir, "assets", REVIEW_ASSET_DIRNAME),
2382
2531
  // Built output sibling case: dist/<sub>/<chunk>.js → dist/assets/review
2383
- join8(moduleDir, "..", "assets", REVIEW_ASSET_DIRNAME),
2532
+ join9(moduleDir, "..", "assets", REVIEW_ASSET_DIRNAME),
2384
2533
  // Dev source: src/lib/review-poster-asset.ts → ../../assets/review
2385
- join8(moduleDir, "..", "..", "assets", REVIEW_ASSET_DIRNAME)
2534
+ join9(moduleDir, "..", "..", "assets", REVIEW_ASSET_DIRNAME)
2386
2535
  ];
2387
2536
  for (const candidate of candidates) {
2388
- if (existsSync2(join8(candidate, POSTER_FILENAME))) return candidate;
2537
+ if (existsSync2(join9(candidate, POSTER_FILENAME))) return candidate;
2389
2538
  }
2390
2539
  throw new Error(
2391
2540
  `[review-poster] could not locate bundled assets; tried:
@@ -2393,18 +2542,18 @@ function resolveBundledReviewAssetDir() {
2393
2542
  );
2394
2543
  }
2395
2544
  function reviewPosterDir(codeName) {
2396
- return join8(getFramework("claude-code").getAgentDir(codeName), REVIEW_ASSET_DIRNAME);
2545
+ return join9(getFramework("claude-code").getAgentDir(codeName), REVIEW_ASSET_DIRNAME);
2397
2546
  }
2398
2547
  function provisionReviewPoster(codeName, sourceDir = resolveBundledReviewAssetDir()) {
2399
2548
  const destDir = reviewPosterDir(codeName);
2400
2549
  mkdirSync4(destDir, { recursive: true });
2401
2550
  for (const [name, mode] of ASSET_FILES) {
2402
- const src = join8(sourceDir, name);
2403
- const dest = join8(destDir, name);
2551
+ const src = join9(sourceDir, name);
2552
+ const dest = join9(destDir, name);
2404
2553
  if (!existsSync2(src)) {
2405
2554
  throw new Error(`[review-poster] bundled asset missing: ${src}`);
2406
2555
  }
2407
- if (!existsSync2(dest) || !readFileSync8(src).equals(readFileSync8(dest))) {
2556
+ if (!existsSync2(dest) || !readFileSync9(src).equals(readFileSync9(dest))) {
2408
2557
  copyFileSync2(src, dest);
2409
2558
  }
2410
2559
  chmodSync(dest, mode);
@@ -2413,7 +2562,7 @@ function provisionReviewPoster(codeName, sourceDir = resolveBundledReviewAssetDi
2413
2562
 
2414
2563
  // src/lib/id-keyed-migration.ts
2415
2564
  import { existsSync as existsSync3, lstatSync, readlinkSync, renameSync as renameSync2 } from "fs";
2416
- import { join as join9 } from "path";
2565
+ import { join as join10 } from "path";
2417
2566
  import { homedir as homedir3 } from "os";
2418
2567
  var ID_KEYED_MIGRATION_FLAG = "id-keyed-layout-migration";
2419
2568
  function agentHasActiveWhatsapp(channelConfigs, codeNameDir) {
@@ -2421,7 +2570,7 @@ function agentHasActiveWhatsapp(channelConfigs, codeNameDir) {
2421
2570
  return true;
2422
2571
  }
2423
2572
  try {
2424
- if (existsSync3(join9(codeNameDir, "whatsapp-pending-inbound"))) return true;
2573
+ if (existsSync3(join10(codeNameDir, "whatsapp-pending-inbound"))) return true;
2425
2574
  } catch {
2426
2575
  }
2427
2576
  return false;
@@ -2453,10 +2602,10 @@ function finishTranscriptMove(oldCwd, newCwd, codeName, log2) {
2453
2602
  function maybeMigrateAgentToIdKeyedLayout(agent, deps) {
2454
2603
  const home = deps.home ?? homedir3();
2455
2604
  const { code_name: codeName, agent_id: agentId } = agent;
2456
- const codeNamePath = join9(home, ".augmented", codeName);
2457
- const idPath = join9(home, ".augmented", agentId);
2458
- const oldCwd = join9(home, ".augmented", codeName, "project");
2459
- const newCwd = join9(idPath, "project");
2605
+ const codeNamePath = join10(home, ".augmented", codeName);
2606
+ const idPath = join10(home, ".augmented", agentId);
2607
+ const oldCwd = join10(home, ".augmented", codeName, "project");
2608
+ const newCwd = join10(idPath, "project");
2460
2609
  let codeNameKind;
2461
2610
  try {
2462
2611
  codeNameKind = lstatSync(codeNamePath).isSymbolicLink() ? "symlink" : "realdir";
@@ -2583,8 +2732,8 @@ function collectEnvGates(env) {
2583
2732
  }
2584
2733
 
2585
2734
  // ../../packages/core/dist/direct-chat/cursor-advance-telemetry.js
2586
- import { readFileSync as readFileSync9, writeFileSync as writeFileSync5 } from "fs";
2587
- import { join as join10 } from "path";
2735
+ import { readFileSync as readFileSync10, writeFileSync as writeFileSync5 } from "fs";
2736
+ import { join as join11 } from "path";
2588
2737
  var CURSOR_SHORTFALL_COUNTER_SUFFIX = "-cursor-advance-classifications.json";
2589
2738
  function recordCursorAdvanceOutcome(agentDir, source, route, verdict) {
2590
2739
  if (!agentDir)
@@ -2592,10 +2741,10 @@ function recordCursorAdvanceOutcome(agentDir, source, route, verdict) {
2592
2741
  const key = cursorAdvanceCounterKey(route, verdict);
2593
2742
  if (key === null)
2594
2743
  return;
2595
- const path = join10(agentDir, `${source}${CURSOR_SHORTFALL_COUNTER_SUFFIX}`);
2744
+ const path = join11(agentDir, `${source}${CURSOR_SHORTFALL_COUNTER_SUFFIX}`);
2596
2745
  const counts = {};
2597
2746
  try {
2598
- const parsed = JSON.parse(readFileSync9(path, "utf-8"));
2747
+ const parsed = JSON.parse(readFileSync10(path, "utf-8"));
2599
2748
  if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
2600
2749
  for (const [k, v] of Object.entries(parsed)) {
2601
2750
  if (typeof v === "number" && Number.isInteger(v) && v >= 0)
@@ -2612,7 +2761,7 @@ function recordCursorAdvanceOutcome(agentDir, source, route, verdict) {
2612
2761
  }
2613
2762
 
2614
2763
  // src/lib/artifact-stream.ts
2615
- import { join as join11 } from "path";
2764
+ import { join as join12 } from "path";
2616
2765
  import { homedir as homedir4 } from "os";
2617
2766
  import { readdir, stat, readFile } from "fs/promises";
2618
2767
  var ARTEFACT_ENTRY_FILE = "index.html";
@@ -2698,7 +2847,7 @@ var ArtifactStreamScanner = class {
2698
2847
  return;
2699
2848
  }
2700
2849
  for (const name of names) {
2701
- const file = join11(this.artifactsDir, name, ARTEFACT_ENTRY_FILE);
2850
+ const file = join12(this.artifactsDir, name, ARTEFACT_ENTRY_FILE);
2702
2851
  const mtime = await this.fsDeps.mtimeMs(file).catch(() => null);
2703
2852
  if (mtime === null) continue;
2704
2853
  if (this.seenMtime.get(name) === mtime) continue;
@@ -2729,7 +2878,7 @@ var ArtifactStreamScanner = class {
2729
2878
  }
2730
2879
  };
2731
2880
  function artifactsDirFor(codeName) {
2732
- return join11(homedir4(), ".augmented", codeName, "artifacts");
2881
+ return join12(homedir4(), ".augmented", codeName, "artifacts");
2733
2882
  }
2734
2883
  var nodeArtifactFs = {
2735
2884
  async listArtefactNames(artifactsDir) {
@@ -3005,12 +3154,12 @@ async function maybePollHostUsage(deps) {
3005
3154
  import { createHash as createHash6 } from "crypto";
3006
3155
  import { readFile as readFile3, readdir as readdir3 } from "fs/promises";
3007
3156
  import { homedir as homedir6, platform as platform2 } from "os";
3008
- import { dirname as dirname6, join as join13 } from "path";
3157
+ import { dirname as dirname6, join as join14 } from "path";
3009
3158
 
3010
3159
  // src/lib/claude-auth-detect.ts
3011
3160
  import { readFile as readFile2, readdir as readdir2 } from "fs/promises";
3012
3161
  import { homedir as homedir5, platform } from "os";
3013
- import { join as join12 } from "path";
3162
+ import { join as join13 } from "path";
3014
3163
  import { execFile } from "child_process";
3015
3164
  import { promisify } from "util";
3016
3165
  var execFileAsync = promisify(execFile);
@@ -3025,16 +3174,16 @@ async function detectClaudeAuth() {
3025
3174
  }
3026
3175
  async function findClaudeCredentialsPaths() {
3027
3176
  const candidates = [
3028
- join12(homedir5(), ".claude", ".credentials.json"),
3029
- join12(homedir5(), ".claude", "credentials.json")
3177
+ join13(homedir5(), ".claude", ".credentials.json"),
3178
+ join13(homedir5(), ".claude", "credentials.json")
3030
3179
  ];
3031
3180
  const isLinuxRoot = platform() === "linux" && typeof process.getuid === "function" && process.getuid() === 0;
3032
3181
  if (isLinuxRoot) {
3033
3182
  try {
3034
3183
  const entries = await readdir2("/home", { withFileTypes: true });
3035
3184
  for (const entry of entries.filter((entry2) => entry2.isDirectory()).sort((a, b) => a.name.localeCompare(b.name))) {
3036
- candidates.push(join12("/home", entry.name, ".claude", ".credentials.json"));
3037
- candidates.push(join12("/home", entry.name, ".claude", "credentials.json"));
3185
+ candidates.push(join13("/home", entry.name, ".claude", ".credentials.json"));
3186
+ candidates.push(join13("/home", entry.name, ".claude", "credentials.json"));
3038
3187
  }
3039
3188
  } catch {
3040
3189
  }
@@ -3118,7 +3267,7 @@ async function candidateHomes() {
3118
3267
  try {
3119
3268
  const entries = await readdir3("/home", { withFileTypes: true });
3120
3269
  for (const entry of entries.filter((e) => e.isDirectory()).sort((a, b) => a.name.localeCompare(b.name))) {
3121
- homes.push(join13("/home", entry.name));
3270
+ homes.push(join14("/home", entry.name));
3122
3271
  }
3123
3272
  } catch {
3124
3273
  }
@@ -3138,11 +3287,11 @@ async function homeOfActiveCredentials() {
3138
3287
  async function claudeConfigCandidatePaths() {
3139
3288
  const paths = [];
3140
3289
  const configDir = process.env["CLAUDE_CONFIG_DIR"]?.trim();
3141
- if (configDir) paths.push(join13(configDir, ".claude.json"));
3290
+ if (configDir) paths.push(join14(configDir, ".claude.json"));
3142
3291
  const activeHome = await homeOfActiveCredentials();
3143
- if (activeHome) paths.push(join13(activeHome, ".claude.json"));
3292
+ if (activeHome) paths.push(join14(activeHome, ".claude.json"));
3144
3293
  for (const home of await candidateHomes()) {
3145
- const path = join13(home, ".claude.json");
3294
+ const path = join14(home, ".claude.json");
3146
3295
  if (!paths.includes(path)) paths.push(path);
3147
3296
  }
3148
3297
  return paths;
@@ -3261,9 +3410,9 @@ function diffAuthTuples(recorded, current) {
3261
3410
  // src/lib/account-enforcement-marker.ts
3262
3411
  import { mkdirSync as mkdirSync5, renameSync as renameSync3, rmSync as rmSync2, writeFileSync as writeFileSync6 } from "fs";
3263
3412
  import { homedir as homedir7 } from "os";
3264
- import { join as join14 } from "path";
3413
+ import { join as join15 } from "path";
3265
3414
  function accountEnforcementMarkerPath(codeName) {
3266
- return join14(homedir7(), ".augmented", codeName, ACCOUNT_ENFORCEMENT_MARKER_FILENAME);
3415
+ return join15(homedir7(), ".augmented", codeName, ACCOUNT_ENFORCEMENT_MARKER_FILENAME);
3267
3416
  }
3268
3417
  function syncAccountEnforcementMarker(codeName, level, log2 = (m) => process.stderr.write(`${m}
3269
3418
  `), text) {
@@ -3271,8 +3420,8 @@ function syncAccountEnforcementMarker(codeName, level, log2 = (m) => process.std
3271
3420
  clearAccountEnforcementMarker(codeName, log2);
3272
3421
  return;
3273
3422
  }
3274
- const dir = join14(homedir7(), ".augmented", codeName);
3275
- const path = join14(dir, ACCOUNT_ENFORCEMENT_MARKER_FILENAME);
3423
+ const dir = join15(homedir7(), ".augmented", codeName);
3424
+ const path = join15(dir, ACCOUNT_ENFORCEMENT_MARKER_FILENAME);
3276
3425
  const tempPath = `${path}.${process.pid}.tmp`;
3277
3426
  try {
3278
3427
  mkdirSync5(dir, { recursive: true });
@@ -3297,8 +3446,8 @@ function clearAccountEnforcementMarker(codeName, log2 = (m) => process.stderr.wr
3297
3446
  }
3298
3447
 
3299
3448
  // src/lib/token-usage-monitor.ts
3300
- import { readdirSync, readFileSync as readFileSync10, statSync } from "fs";
3301
- import { join as join15 } from "path";
3449
+ import { readdirSync, readFileSync as readFileSync11, statSync } from "fs";
3450
+ import { join as join16 } from "path";
3302
3451
  var MIN_CHECK_INTERVAL_MS2 = 6e4;
3303
3452
  var TRANSCRIPT_MTIME_WINDOW_MS = 2 * 24 * 60 * 60 * 1e3;
3304
3453
  var MAX_ENTRIES_PER_POST = 200;
@@ -3327,7 +3476,7 @@ async function maybeReportTokenUsage(args) {
3327
3476
  if (!name.endsWith(".jsonl")) continue;
3328
3477
  const sessionId = name.slice(0, -".jsonl".length);
3329
3478
  if (!sessionId) continue;
3330
- const path = join15(dir, name);
3479
+ const path = join16(dir, name);
3331
3480
  let st;
3332
3481
  try {
3333
3482
  st = statSync(path);
@@ -3343,7 +3492,7 @@ async function maybeReportTokenUsage(args) {
3343
3492
  }
3344
3493
  let content;
3345
3494
  try {
3346
- content = readFileSync10(path, "utf-8");
3495
+ content = readFileSync11(path, "utf-8");
3347
3496
  } catch (err) {
3348
3497
  log2(`[token-usage] read failed for '${codeName}/${name}': ${err.message}`);
3349
3498
  continue;
@@ -3424,8 +3573,8 @@ async function maybeReportTokenUsage(args) {
3424
3573
  }
3425
3574
 
3426
3575
  // src/lib/workflow-run-reconciler.ts
3427
- import { readdirSync as readdirSync2, readFileSync as readFileSync11, statSync as statSync2 } from "fs";
3428
- import { join as join16 } from "path";
3576
+ import { readdirSync as readdirSync2, readFileSync as readFileSync12, statSync as statSync2 } from "fs";
3577
+ import { join as join17 } from "path";
3429
3578
  var MIN_CHECK_INTERVAL_MS3 = 5 * 6e4;
3430
3579
  var SETTLE_MS = 3e4;
3431
3580
  var TRANSCRIPT_MTIME_WINDOW_MS2 = 2 * 24 * 60 * 60 * 1e3;
@@ -3444,7 +3593,7 @@ function collectJsonlRecursive(dir, minMtimeMs, out, depth) {
3444
3593
  return;
3445
3594
  }
3446
3595
  for (const name of entries) {
3447
- const p = join16(dir, name);
3596
+ const p = join17(dir, name);
3448
3597
  let st;
3449
3598
  try {
3450
3599
  st = statSync2(p);
@@ -3467,7 +3616,7 @@ function enumerateTranscriptFiles(transcriptDir, nowMs, minMtimeMs = nowMs - TRA
3467
3616
  return out;
3468
3617
  }
3469
3618
  for (const name of entries) {
3470
- const path = join16(transcriptDir, name);
3619
+ const path = join17(transcriptDir, name);
3471
3620
  let st;
3472
3621
  try {
3473
3622
  st = statSync2(path);
@@ -3479,7 +3628,7 @@ function enumerateTranscriptFiles(transcriptDir, nowMs, minMtimeMs = nowMs - TRA
3479
3628
  continue;
3480
3629
  }
3481
3630
  if (st.isDirectory()) {
3482
- collectJsonlRecursive(join16(path, "subagents"), minMtimeMs, out, 0);
3631
+ collectJsonlRecursive(join17(path, "subagents"), minMtimeMs, out, 0);
3483
3632
  }
3484
3633
  }
3485
3634
  return out;
@@ -3524,7 +3673,7 @@ async function maybeReconcileWorkflowRunTokens(args) {
3524
3673
  const contents = [];
3525
3674
  for (const path of files) {
3526
3675
  try {
3527
- contents.push(readFileSync11(path, "utf-8"));
3676
+ contents.push(readFileSync12(path, "utf-8"));
3528
3677
  } catch {
3529
3678
  }
3530
3679
  }
@@ -3569,8 +3718,8 @@ async function maybeReconcileWorkflowRunTokens(args) {
3569
3718
  }
3570
3719
 
3571
3720
  // src/lib/conversation-evaluator.ts
3572
- import { readdirSync as readdirSync3, readFileSync as readFileSync12, statSync as statSync3 } from "fs";
3573
- import { join as join17 } from "path";
3721
+ import { readdirSync as readdirSync3, readFileSync as readFileSync13, statSync as statSync3 } from "fs";
3722
+ import { join as join18 } from "path";
3574
3723
 
3575
3724
  // src/lib/detect-meta-egress.ts
3576
3725
  var REPOST_PREAMBLE_WINDOW = 200;
@@ -4055,7 +4204,7 @@ function readRecentTurns(dir, nowMs) {
4055
4204
  return;
4056
4205
  }
4057
4206
  for (const ent of entries) {
4058
- const full = join17(d, ent.name);
4207
+ const full = join18(d, ent.name);
4059
4208
  if (ent.isDirectory()) {
4060
4209
  visit(full);
4061
4210
  continue;
@@ -4070,7 +4219,7 @@ function readRecentTurns(dir, nowMs) {
4070
4219
  if (nowMs - mtimeMs > TRANSCRIPT_MTIME_WINDOW_MS3) continue;
4071
4220
  let content;
4072
4221
  try {
4073
- content = readFileSync12(full, "utf8");
4222
+ content = readFileSync13(full, "utf8");
4074
4223
  } catch {
4075
4224
  continue;
4076
4225
  }
@@ -4443,22 +4592,22 @@ async function reportSkip2(api2, agentId, conversationId, log2, codeName) {
4443
4592
 
4444
4593
  // src/lib/tool-call-audit.ts
4445
4594
  import { homedir as homedir11 } from "os";
4446
- import { join as join22 } from "path";
4595
+ import { join as join23 } from "path";
4447
4596
 
4448
4597
  // src/lib/agent-logging-mode.ts
4449
- import { readFileSync as readFileSync13 } from "fs";
4598
+ import { readFileSync as readFileSync14 } from "fs";
4450
4599
  import { homedir as homedir8 } from "os";
4451
- import { join as join18 } from "path";
4600
+ import { join as join19 } from "path";
4452
4601
  var LOGGING_MODES = ["hash-only", "redacted", "full-local"];
4453
4602
  function charterPath(codeName, homeDir) {
4454
4603
  const home = homeDir ?? (process.env["HOME"]?.trim() || homedir8());
4455
4604
  const key = agentRuntimeKey(codeName, homeDir);
4456
- return join18(home, ".augmented", key, "provision", "CHARTER.md");
4605
+ return join19(home, ".augmented", key, "provision", "CHARTER.md");
4457
4606
  }
4458
4607
  function readAgentLoggingMode(codeName, homeDir) {
4459
4608
  let raw;
4460
4609
  try {
4461
- raw = readFileSync13(charterPath(codeName, homeDir), "utf-8");
4610
+ raw = readFileSync14(charterPath(codeName, homeDir), "utf-8");
4462
4611
  } catch {
4463
4612
  return { mode: null, reason: "no-charter" };
4464
4613
  }
@@ -4482,15 +4631,15 @@ function loggingModeWithholdsTargets(reading) {
4482
4631
 
4483
4632
  // src/lib/tool-call-path-salt.ts
4484
4633
  import { randomBytes } from "crypto";
4485
- import { existsSync as existsSync4, mkdirSync as mkdirSync6, readFileSync as readFileSync14, renameSync as renameSync4, unlinkSync as unlinkSync2, writeFileSync as writeFileSync7 } from "fs";
4634
+ import { existsSync as existsSync4, mkdirSync as mkdirSync6, readFileSync as readFileSync15, renameSync as renameSync4, unlinkSync as unlinkSync2, writeFileSync as writeFileSync7 } from "fs";
4486
4635
  import { homedir as homedir9 } from "os";
4487
- import { dirname as dirname7, join as join19 } from "path";
4636
+ import { dirname as dirname7, join as join20 } from "path";
4488
4637
  var SALT_BYTES = 32;
4489
4638
  var SALT_RE = /^[0-9a-f]{64}$/;
4490
4639
  function pathSaltPath(codeName, homeDir) {
4491
4640
  const home = homeDir ?? (process.env["HOME"]?.trim() || homedir9());
4492
4641
  const key = agentRuntimeKey(codeName, homeDir);
4493
- return join19(home, ".augmented", key, "tool-call-path-salt");
4642
+ return join20(home, ".augmented", key, "tool-call-path-salt");
4494
4643
  }
4495
4644
  function readToolCallPathSalt(codeName, homeDir) {
4496
4645
  let file;
@@ -4501,7 +4650,7 @@ function readToolCallPathSalt(codeName, homeDir) {
4501
4650
  }
4502
4651
  try {
4503
4652
  if (existsSync4(file)) {
4504
- const existing = readFileSync14(file, "utf-8").trim();
4653
+ const existing = readFileSync15(file, "utf-8").trim();
4505
4654
  if (SALT_RE.test(existing)) return existing;
4506
4655
  }
4507
4656
  } catch {
@@ -4527,8 +4676,8 @@ function readToolCallPathSalt(codeName, homeDir) {
4527
4676
  import { statSync as statSync4 } from "fs";
4528
4677
 
4529
4678
  // src/lib/tool-call-extractor.ts
4530
- import { closeSync, fstatSync, openSync, readFileSync as readFileSync15, readSync, readdirSync as readdirSync4 } from "fs";
4531
- import { basename as basename2, join as join20, relative } from "path";
4679
+ import { closeSync, fstatSync, openSync, readFileSync as readFileSync16, readSync, readdirSync as readdirSync4 } from "fs";
4680
+ import { basename as basename2, join as join21, relative } from "path";
4532
4681
  import { StringDecoder } from "string_decoder";
4533
4682
 
4534
4683
  // src/lib/tool-call-redaction.ts
@@ -4657,7 +4806,7 @@ function redactToolTargetInner(toolName, input, ctx) {
4657
4806
  var EXTRACTOR_VERSION = "e1";
4658
4807
  function enumerateSessionTranscripts(transcriptDir, sessionId, projectsRoot) {
4659
4808
  const files = [];
4660
- const mainAbs = join20(transcriptDir, `${sessionId}.jsonl`);
4809
+ const mainAbs = join21(transcriptDir, `${sessionId}.jsonl`);
4661
4810
  files.push({
4662
4811
  absPath: mainAbs,
4663
4812
  relPath: relative(projectsRoot, mainAbs),
@@ -4665,7 +4814,7 @@ function enumerateSessionTranscripts(transcriptDir, sessionId, projectsRoot) {
4665
4814
  isSubagent: false,
4666
4815
  subagentId: null
4667
4816
  });
4668
- const subDir = join20(transcriptDir, sessionId, "subagents");
4817
+ const subDir = join21(transcriptDir, sessionId, "subagents");
4669
4818
  let entries;
4670
4819
  try {
4671
4820
  entries = readdirSync4(subDir);
@@ -4674,7 +4823,7 @@ function enumerateSessionTranscripts(transcriptDir, sessionId, projectsRoot) {
4674
4823
  }
4675
4824
  for (const name of entries) {
4676
4825
  if (!name.endsWith(".jsonl")) continue;
4677
- const abs = join20(subDir, name);
4826
+ const abs = join21(subDir, name);
4678
4827
  const stem = basename2(name, ".jsonl");
4679
4828
  files.push({
4680
4829
  absPath: abs,
@@ -4872,9 +5021,9 @@ function extractTranscriptWindow(file, opts, from) {
4872
5021
  }
4873
5022
 
4874
5023
  // src/lib/tool-call-cursor.ts
4875
- import { existsSync as existsSync5, readFileSync as readFileSync16 } from "fs";
5024
+ import { existsSync as existsSync5, readFileSync as readFileSync17 } from "fs";
4876
5025
  import { homedir as homedir10 } from "os";
4877
- import { join as join21 } from "path";
5026
+ import { join as join22 } from "path";
4878
5027
  var COVERAGE_DISPOSITIONS = [
4879
5028
  "ok",
4880
5029
  "not_entitled",
@@ -4929,13 +5078,13 @@ function parseCursorKey(key) {
4929
5078
  function cursorStatePath(codeName, homeDir) {
4930
5079
  const home = homeDir ?? (process.env["HOME"]?.trim() || homedir10());
4931
5080
  const key = agentRuntimeKey(codeName, homeDir);
4932
- return join21(home, ".augmented", key, "tool-call-cursors.json");
5081
+ return join22(home, ".augmented", key, "tool-call-cursors.json");
4933
5082
  }
4934
5083
  function loadCursors(path) {
4935
5084
  const out = /* @__PURE__ */ new Map();
4936
5085
  if (!existsSync5(path)) return out;
4937
5086
  try {
4938
- const parsed = JSON.parse(readFileSync16(path, "utf-8"));
5087
+ const parsed = JSON.parse(readFileSync17(path, "utf-8"));
4939
5088
  if (!parsed || parsed.version !== 1 || typeof parsed.files !== "object") return out;
4940
5089
  for (const [k, v] of Object.entries(parsed.files)) {
4941
5090
  if (!v || typeof v !== "object") continue;
@@ -5342,7 +5491,7 @@ async function maybeScanToolCalls(args) {
5342
5491
  log2(`[tool-call-audit] ${codeName}: no path-hash salt available \u2014 file targets withheld`);
5343
5492
  }
5344
5493
  const home = args.homeDir ?? (process.env["HOME"]?.trim() || homedir11());
5345
- const projectsRoot = args.projectsRoot ?? join22(home, ".claude", "projects");
5494
+ const projectsRoot = args.projectsRoot ?? join23(home, ".claude", "projects");
5346
5495
  const transcriptDir = args.transcriptDir ?? sessionTranscriptDir(getProjectDir(codeName));
5347
5496
  const current = peekCurrentSession(codeName);
5348
5497
  const sessionIds = current ? [current.sessionId] : [];
@@ -5371,11 +5520,11 @@ async function maybeScanToolCalls(args) {
5371
5520
  }
5372
5521
 
5373
5522
  // src/lib/activity-cache-monitor.ts
5374
- import { existsSync as existsSync6, readFileSync as readFileSync17 } from "fs";
5523
+ import { existsSync as existsSync6, readFileSync as readFileSync18 } from "fs";
5375
5524
  import { homedir as homedir12 } from "os";
5376
- import { join as join23 } from "path";
5525
+ import { join as join24 } from "path";
5377
5526
  var MIN_CHECK_INTERVAL_MS7 = 6e4;
5378
- var STATS_CACHE_PATH = join23(homedir12(), ".claude", "stats-cache.json");
5527
+ var STATS_CACHE_PATH = join24(homedir12(), ".claude", "stats-cache.json");
5379
5528
  var ISO_DATE_RE = /^\d{4}-\d{2}-\d{2}$/;
5380
5529
  var state7 = { lastObservedDate: null, lastCheckedAt: 0 };
5381
5530
  function selectNewDailyRows(raw, lastObservedDate) {
@@ -5423,7 +5572,7 @@ async function maybeReportActivityCache(args) {
5423
5572
  }
5424
5573
  let raw;
5425
5574
  try {
5426
- raw = readFileSync17(STATS_CACHE_PATH, "utf-8");
5575
+ raw = readFileSync18(STATS_CACHE_PATH, "utf-8");
5427
5576
  } catch (err) {
5428
5577
  log2(`[activity-cache] readFileSync failed: ${err.message}`);
5429
5578
  return;
@@ -5726,7 +5875,7 @@ import { createHash as createHash9 } from "crypto";
5726
5875
  import {
5727
5876
  existsSync as existsSync7,
5728
5877
  mkdirSync as mkdirSync7,
5729
- readFileSync as readFileSync18,
5878
+ readFileSync as readFileSync19,
5730
5879
  readdirSync as readdirSync5,
5731
5880
  renameSync as renameSync5,
5732
5881
  rmSync as rmSync3,
@@ -5734,7 +5883,7 @@ import {
5734
5883
  utimesSync,
5735
5884
  writeFileSync as writeFileSync8
5736
5885
  } from "fs";
5737
- import { join as join24 } from "path";
5886
+ import { join as join25 } from "path";
5738
5887
  var KNOWLEDGE_FETCH_CHUNK = 100;
5739
5888
  var CACHE_TTL_MS = 30 * 24 * 60 * 60 * 1e3;
5740
5889
  var SWEEP_INTERVAL_MS = 24 * 60 * 60 * 1e3;
@@ -5743,12 +5892,12 @@ function knowledgeHash(content) {
5743
5892
  return createHash9("sha256").update(content, "utf8").digest("hex");
5744
5893
  }
5745
5894
  function cachePath(cacheDir, hash) {
5746
- return join24(cacheDir, hash);
5895
+ return join25(cacheDir, hash);
5747
5896
  }
5748
5897
  function readCachedKnowledge(cacheDir, hash) {
5749
5898
  const path = cachePath(cacheDir, hash);
5750
5899
  try {
5751
- const content = readFileSync18(path, "utf-8");
5900
+ const content = readFileSync19(path, "utf-8");
5752
5901
  try {
5753
5902
  const now = /* @__PURE__ */ new Date();
5754
5903
  utimesSync(path, now, now);
@@ -5777,7 +5926,7 @@ function sweepKnowledgeCache(cacheDir, now = Date.now()) {
5777
5926
  try {
5778
5927
  if (!existsSync7(cacheDir)) return;
5779
5928
  for (const name of readdirSync5(cacheDir)) {
5780
- const path = join24(cacheDir, name);
5929
+ const path = join25(cacheDir, name);
5781
5930
  try {
5782
5931
  if (now - statSync6(path).mtimeMs > CACHE_TTL_MS) rmSync3(path, { force: true });
5783
5932
  } catch {
@@ -5829,7 +5978,7 @@ import { createHash as createHash10 } from "crypto";
5829
5978
  import {
5830
5979
  existsSync as existsSync8,
5831
5980
  mkdirSync as mkdirSync8,
5832
- readFileSync as readFileSync19,
5981
+ readFileSync as readFileSync20,
5833
5982
  readdirSync as readdirSync6,
5834
5983
  renameSync as renameSync6,
5835
5984
  rmSync as rmSync4,
@@ -5837,7 +5986,7 @@ import {
5837
5986
  utimesSync as utimesSync2,
5838
5987
  writeFileSync as writeFileSync9
5839
5988
  } from "fs";
5840
- import { join as join25 } from "path";
5989
+ import { join as join26 } from "path";
5841
5990
  var MEMORY_FETCH_CHUNK = 100;
5842
5991
  var CACHE_TTL_MS2 = 30 * 24 * 60 * 60 * 1e3;
5843
5992
  var SWEEP_INTERVAL_MS2 = 24 * 60 * 60 * 1e3;
@@ -5846,12 +5995,12 @@ function memoryHash(content) {
5846
5995
  return createHash10("sha256").update(content, "utf8").digest("hex");
5847
5996
  }
5848
5997
  function cachePath2(cacheDir, hash) {
5849
- return join25(cacheDir, hash);
5998
+ return join26(cacheDir, hash);
5850
5999
  }
5851
6000
  function readCachedMemory(cacheDir, hash) {
5852
6001
  const path = cachePath2(cacheDir, hash);
5853
6002
  try {
5854
- const content = readFileSync19(path, "utf-8");
6003
+ const content = readFileSync20(path, "utf-8");
5855
6004
  try {
5856
6005
  const now = /* @__PURE__ */ new Date();
5857
6006
  utimesSync2(path, now, now);
@@ -5880,7 +6029,7 @@ function sweepMemoryCache(cacheDir, now = Date.now()) {
5880
6029
  try {
5881
6030
  if (!existsSync8(cacheDir)) return;
5882
6031
  for (const name of readdirSync6(cacheDir)) {
5883
- const path = join25(cacheDir, name);
6032
+ const path = join26(cacheDir, name);
5884
6033
  try {
5885
6034
  if (now - statSync7(path).mtimeMs > CACHE_TTL_MS2) rmSync4(path, { force: true });
5886
6035
  } catch {
@@ -5938,7 +6087,7 @@ import { createHash as createHash11 } from "crypto";
5938
6087
  import {
5939
6088
  existsSync as existsSync9,
5940
6089
  mkdirSync as mkdirSync9,
5941
- readFileSync as readFileSync20,
6090
+ readFileSync as readFileSync21,
5942
6091
  readdirSync as readdirSync7,
5943
6092
  renameSync as renameSync7,
5944
6093
  rmSync as rmSync5,
@@ -5946,7 +6095,7 @@ import {
5946
6095
  utimesSync as utimesSync3,
5947
6096
  writeFileSync as writeFileSync10
5948
6097
  } from "fs";
5949
- import { join as join26 } from "path";
6098
+ import { join as join27 } from "path";
5950
6099
  var SKILL_FETCH_CHUNK = 100;
5951
6100
  var CACHE_TTL_MS3 = 30 * 24 * 60 * 60 * 1e3;
5952
6101
  var SWEEP_INTERVAL_MS3 = 24 * 60 * 60 * 1e3;
@@ -5955,12 +6104,12 @@ function skillHash(content) {
5955
6104
  return createHash11("sha256").update(content, "utf8").digest("hex");
5956
6105
  }
5957
6106
  function cachePath3(cacheDir, hash) {
5958
- return join26(cacheDir, hash);
6107
+ return join27(cacheDir, hash);
5959
6108
  }
5960
6109
  function readCachedSkill(cacheDir, hash) {
5961
6110
  const path = cachePath3(cacheDir, hash);
5962
6111
  try {
5963
- const content = readFileSync20(path, "utf-8");
6112
+ const content = readFileSync21(path, "utf-8");
5964
6113
  try {
5965
6114
  const now = /* @__PURE__ */ new Date();
5966
6115
  utimesSync3(path, now, now);
@@ -5989,7 +6138,7 @@ function sweepSkillCache(cacheDir, now = Date.now()) {
5989
6138
  try {
5990
6139
  if (!existsSync9(cacheDir)) return;
5991
6140
  for (const name of readdirSync7(cacheDir)) {
5992
- const path = join26(cacheDir, name);
6141
+ const path = join27(cacheDir, name);
5993
6142
  try {
5994
6143
  if (now - statSync8(path).mtimeMs > CACHE_TTL_MS3) rmSync5(path, { force: true });
5995
6144
  } catch {
@@ -6276,18 +6425,18 @@ function resolveConditionalResponse(wire, hasCachedBody) {
6276
6425
  }
6277
6426
 
6278
6427
  // src/lib/channel-hash-cache.ts
6279
- import { existsSync as existsSync10, readFileSync as readFileSync21, writeFileSync as writeFileSync11 } from "fs";
6280
- import { join as join27 } from "path";
6428
+ import { existsSync as existsSync10, readFileSync as readFileSync22, writeFileSync as writeFileSync11 } from "fs";
6429
+ import { join as join28 } from "path";
6281
6430
  var CACHE_FILENAME = "channel-hash-cache.json";
6282
6431
  function getChannelHashCacheFile(configDir) {
6283
- return join27(configDir, CACHE_FILENAME);
6432
+ return join28(configDir, CACHE_FILENAME);
6284
6433
  }
6285
6434
  function loadChannelHashCache(target, configDir) {
6286
6435
  const path = getChannelHashCacheFile(configDir);
6287
6436
  if (!existsSync10(path)) return;
6288
6437
  let parsed;
6289
6438
  try {
6290
- parsed = JSON.parse(readFileSync21(path, "utf-8"));
6439
+ parsed = JSON.parse(readFileSync22(path, "utf-8"));
6291
6440
  } catch {
6292
6441
  return;
6293
6442
  }
@@ -6307,8 +6456,8 @@ function saveChannelHashCache(source, configDir) {
6307
6456
  }
6308
6457
 
6309
6458
  // src/lib/sender-policy-baseline.ts
6310
- import { existsSync as existsSync11, readFileSync as readFileSync22 } from "fs";
6311
- import { join as join28 } from "path";
6459
+ import { existsSync as existsSync11, readFileSync as readFileSync23 } from "fs";
6460
+ import { join as join29 } from "path";
6312
6461
  var BASELINE_FILENAME = "sender-policy-baseline.json";
6313
6462
  var SENDER_POLICY_BASELINE_VERSION = 1;
6314
6463
  var BASELINE_CONCERNS = [
@@ -6346,14 +6495,14 @@ function createDeliveryBaselineMaps() {
6346
6495
  };
6347
6496
  }
6348
6497
  function getSenderPolicyBaselineFile(configDir) {
6349
- return join28(configDir, BASELINE_FILENAME);
6498
+ return join29(configDir, BASELINE_FILENAME);
6350
6499
  }
6351
6500
  function loadSenderPolicyBaseline(target, configDir, log2) {
6352
6501
  const path = getSenderPolicyBaselineFile(configDir);
6353
6502
  if (!existsSync11(path)) return;
6354
6503
  let parsed;
6355
6504
  try {
6356
- parsed = JSON.parse(readFileSync22(path, "utf-8"));
6505
+ parsed = JSON.parse(readFileSync23(path, "utf-8"));
6357
6506
  } catch (err) {
6358
6507
  log2?.(
6359
6508
  `[sender-policy] discarding corrupt ${BASELINE_FILENAME} (${err.message}) - restrictive-policy agents will take one fail-closed restart`
@@ -6402,8 +6551,8 @@ function saveSenderPolicyBaseline(source, configDir, log2) {
6402
6551
  }
6403
6552
 
6404
6553
  // src/lib/stuck-streak-store.ts
6405
- import { existsSync as existsSync12, readFileSync as readFileSync23 } from "fs";
6406
- import { join as join29 } from "path";
6554
+ import { existsSync as existsSync12, readFileSync as readFileSync24 } from "fs";
6555
+ import { join as join30 } from "path";
6407
6556
  var STORE_FILENAME = "stuck-streaks.json";
6408
6557
  var STUCK_STREAK_STORE_VERSION = 1;
6409
6558
  var STUCK_STREAK_CONCERNS = ["channelSync", "realtimeRebind"];
@@ -6411,7 +6560,7 @@ function createStuckStreakMaps() {
6411
6560
  return { channelSync: /* @__PURE__ */ new Map(), realtimeRebind: /* @__PURE__ */ new Map() };
6412
6561
  }
6413
6562
  function getStuckStreakStoreFile(configDir) {
6414
- return join29(configDir, STORE_FILENAME);
6563
+ return join30(configDir, STORE_FILENAME);
6415
6564
  }
6416
6565
  function isValidPersistedStreak(value) {
6417
6566
  if (!value || typeof value !== "object" || Array.isArray(value)) return false;
@@ -6453,7 +6602,7 @@ function loadStuckStreaks(target, configDir, log2) {
6453
6602
  if (!existsSync12(path)) return;
6454
6603
  let parsed;
6455
6604
  try {
6456
- parsed = JSON.parse(readFileSync23(path, "utf-8"));
6605
+ parsed = JSON.parse(readFileSync24(path, "utf-8"));
6457
6606
  } catch (err) {
6458
6607
  log2?.(
6459
6608
  `[stuck-streaks] discarding corrupt ${STORE_FILENAME} (${err.message}) \u2014 stuck-streak ages restart from zero and one spurious "recovered" close may follow`
@@ -6496,11 +6645,11 @@ function pruneStuckStreaksToAgents(maps, activeAgentIds) {
6496
6645
  }
6497
6646
 
6498
6647
  // src/lib/claude-device-state.ts
6499
- import { readFileSync as readFileSync24, statSync as statSync9 } from "fs";
6648
+ import { readFileSync as readFileSync25, statSync as statSync9 } from "fs";
6500
6649
  import { homedir as homedir13 } from "os";
6501
- import { join as join30 } from "path";
6650
+ import { join as join31 } from "path";
6502
6651
  function claudeDeviceStatePath(env = process.env) {
6503
- return join30(env.HOME?.trim() || homedir13(), ".claude.json");
6652
+ return join31(env.HOME?.trim() || homedir13(), ".claude.json");
6504
6653
  }
6505
6654
  function probeClaudeDeviceStatePresence(path = claudeDeviceStatePath()) {
6506
6655
  try {
@@ -6523,7 +6672,7 @@ function checkClaudeDeviceState(path = claudeDeviceStatePath()) {
6523
6672
  }
6524
6673
  let raw;
6525
6674
  try {
6526
- raw = readFileSync24(path, "utf-8");
6675
+ raw = readFileSync25(path, "utf-8");
6527
6676
  } catch {
6528
6677
  return { usable: false, reason: "unreadable" };
6529
6678
  }
@@ -7201,7 +7350,7 @@ function planGlobalSkillSync(globalSkills, prevIds, hashOf, knownHash, options)
7201
7350
  }
7202
7351
 
7203
7352
  // src/lib/manager/integration-skill-cache.ts
7204
- import { join as join31 } from "path";
7353
+ import { join as join32 } from "path";
7205
7354
  function integrationSkillHashKey(agentId, skillId) {
7206
7355
  return `plugin-skill:${agentId}:${skillId}`;
7207
7356
  }
@@ -7217,21 +7366,21 @@ function forgetIntegrationSkill(cache2, agentId, skillId) {
7217
7366
  function removeIntegrationSkillFolder(opts) {
7218
7367
  forgetIntegrationSkill(opts.cache, opts.agentId, opts.entry);
7219
7368
  for (const dir of opts.dirs) {
7220
- opts.removeDir(join31(dir, opts.entry));
7369
+ opts.removeDir(join32(dir, opts.entry));
7221
7370
  }
7222
7371
  }
7223
7372
 
7224
7373
  // src/lib/manager/managed-skill-manifest.ts
7225
- import { existsSync as existsSync13, mkdirSync as mkdirSync10, readFileSync as readFileSync25, writeFileSync as writeFileSync12 } from "fs";
7226
- import { dirname as dirname8, join as join32 } from "path";
7374
+ import { existsSync as existsSync13, mkdirSync as mkdirSync10, readFileSync as readFileSync26, writeFileSync as writeFileSync12 } from "fs";
7375
+ import { dirname as dirname8, join as join33 } from "path";
7227
7376
  var MANIFEST_VERSION = 1;
7228
7377
  function managedSkillManifestPath(agentRootDir) {
7229
- return join32(agentRootDir, "managed-skills.json");
7378
+ return join33(agentRootDir, "managed-skills.json");
7230
7379
  }
7231
7380
  function readManagedSkillManifest(path) {
7232
7381
  try {
7233
7382
  if (!existsSync13(path)) return /* @__PURE__ */ new Set();
7234
- const parsed = JSON.parse(readFileSync25(path, "utf-8"));
7383
+ const parsed = JSON.parse(readFileSync26(path, "utf-8"));
7235
7384
  const ids = Array.isArray(parsed?.globalSkillIds) ? parsed.globalSkillIds : [];
7236
7385
  return new Set(ids.filter((id) => typeof id === "string" && id.length > 0));
7237
7386
  } catch {
@@ -7361,7 +7510,7 @@ function resolveModelChain(refreshData) {
7361
7510
 
7362
7511
  // src/lib/manager/claude-auth.ts
7363
7512
  import { existsSync as existsSync14, rmSync as rmSync6 } from "fs";
7364
- import { join as join33 } from "path";
7513
+ import { join as join34 } from "path";
7365
7514
  import { homedir as homedir14 } from "os";
7366
7515
  async function applyClaudeAuthToEnv(childEnv, label) {
7367
7516
  const apiKey = getApiKey();
@@ -7374,9 +7523,9 @@ async function applyClaudeAuthToEnv(childEnv, label) {
7374
7523
  throw new Error("claude_auth_mode=api_key but /host/exchange returned no decrypted key");
7375
7524
  }
7376
7525
  childEnv.ANTHROPIC_API_KEY = exchange.anthropicApiKey;
7377
- const claudeDir = join33(homedir14(), ".claude");
7526
+ const claudeDir = join34(homedir14(), ".claude");
7378
7527
  for (const filename of [".credentials.json", "credentials.json"]) {
7379
- const p = join33(claudeDir, filename);
7528
+ const p = join34(claudeDir, filename);
7380
7529
  if (existsSync14(p)) {
7381
7530
  try {
7382
7531
  rmSync6(p, { force: true });
@@ -7732,19 +7881,19 @@ function formatBoardForPrompt(items, template) {
7732
7881
  }
7733
7882
 
7734
7883
  // src/lib/manager/kanban/nudge-state-cache.ts
7735
- import { existsSync as existsSync15, readFileSync as readFileSync26, writeFileSync as writeFileSync13 } from "fs";
7736
- import { join as join34 } from "path";
7884
+ import { existsSync as existsSync15, readFileSync as readFileSync27, writeFileSync as writeFileSync13 } from "fs";
7885
+ import { join as join35 } from "path";
7737
7886
  var CACHE_FILENAME2 = "kanban-nudge-state.json";
7738
7887
  var KANBAN_NUDGE_STATE_VERSION = 1;
7739
7888
  function getKanbanNudgeStateFile(configDir) {
7740
- return join34(configDir, CACHE_FILENAME2);
7889
+ return join35(configDir, CACHE_FILENAME2);
7741
7890
  }
7742
7891
  function loadKanbanNudgeState(target, configDir) {
7743
7892
  const path = getKanbanNudgeStateFile(configDir);
7744
7893
  if (!existsSync15(path)) return;
7745
7894
  let parsed;
7746
7895
  try {
7747
- parsed = JSON.parse(readFileSync26(path, "utf-8"));
7896
+ parsed = JSON.parse(readFileSync27(path, "utf-8"));
7748
7897
  } catch {
7749
7898
  return;
7750
7899
  }
@@ -8362,9 +8511,9 @@ function closeSessionRunForCode(codeName, outcome, reason) {
8362
8511
 
8363
8512
  // src/lib/manager/scheduler/kanban-route.ts
8364
8513
  import { createHash as createHash15 } from "crypto";
8365
- import { writeFileSync as writeFileSync14, renameSync as renameSync8, mkdirSync as mkdirSync11, readFileSync as readFileSync27, unlinkSync as unlinkSync3 } from "fs";
8514
+ import { writeFileSync as writeFileSync14, renameSync as renameSync8, mkdirSync as mkdirSync11, readFileSync as readFileSync28, unlinkSync as unlinkSync3 } from "fs";
8366
8515
  import { homedir as homedir15 } from "os";
8367
- import { join as join35, dirname as dirname9 } from "path";
8516
+ import { join as join36, dirname as dirname9 } from "path";
8368
8517
 
8369
8518
  // src/lib/manager/scheduler/notify.ts
8370
8519
  import { createHash as createHash14 } from "crypto";
@@ -8723,7 +8872,7 @@ function resolveScheduledSlackTarget(task) {
8723
8872
  }
8724
8873
  function stampScheduledTurnMarker(codeName, taskId, target) {
8725
8874
  try {
8726
- const file = join35(homedir15(), ".augmented", codeName, SCHEDULED_TURN_MARKER_FILENAME);
8875
+ const file = join36(homedir15(), ".augmented", codeName, SCHEDULED_TURN_MARKER_FILENAME);
8727
8876
  const marker = { ts: Date.now(), task_id: taskId, ...target ? { target } : {} };
8728
8877
  const tmp = `${file}.tmp`;
8729
8878
  writeFileSync14(tmp, JSON.stringify(marker), "utf8");
@@ -8733,9 +8882,9 @@ function stampScheduledTurnMarker(codeName, taskId, target) {
8733
8882
  }
8734
8883
  }
8735
8884
  function clearScheduledTurnMarkerForTask(codeName, taskId) {
8736
- const file = join35(homedir15(), ".augmented", codeName, SCHEDULED_TURN_MARKER_FILENAME);
8885
+ const file = join36(homedir15(), ".augmented", codeName, SCHEDULED_TURN_MARKER_FILENAME);
8737
8886
  try {
8738
- const raw = JSON.parse(readFileSync27(file, "utf8"));
8887
+ const raw = JSON.parse(readFileSync28(file, "utf8"));
8739
8888
  if (typeof raw?.task_id !== "string" || raw.task_id !== taskId) return;
8740
8889
  unlinkSync3(file);
8741
8890
  log(`[scheduled-kanban] scheduled-turn marker cleared for '${codeName}' (task ${taskId} complete)`);
@@ -8951,11 +9100,11 @@ async function processClaudeTaskResult(codeName, agentId, templateId, rawOutput,
8951
9100
  // src/lib/manager/scheduler/execution.ts
8952
9101
  import { createHash as createHash16 } from "crypto";
8953
9102
  import { homedir as homedir16 } from "os";
8954
- import { join as join37 } from "path";
9103
+ import { join as join38 } from "path";
8955
9104
 
8956
9105
  // src/lib/agent-serving-probe.ts
8957
- import { readFileSync as readFileSync28, readdirSync as readdirSync8, statSync as statSync10 } from "fs";
8958
- import { join as join36 } from "path";
9106
+ import { readFileSync as readFileSync29, readdirSync as readdirSync8, statSync as statSync10 } from "fs";
9107
+ import { join as join37 } from "path";
8959
9108
  var RATE_LIMIT_WINDOW_MS = 6 * 60 * 60 * 1e3;
8960
9109
  function probeRateLimit(args) {
8961
9110
  const now = args.now ?? /* @__PURE__ */ new Date();
@@ -8971,7 +9120,7 @@ function probeRateLimit(args) {
8971
9120
  let newest = UNKNOWN_RATE_LIMIT;
8972
9121
  for (const name of entries) {
8973
9122
  if (!name.endsWith(".jsonl")) continue;
8974
- const path = join36(dir, name);
9123
+ const path = join37(dir, name);
8975
9124
  try {
8976
9125
  const st = statSync10(path);
8977
9126
  if (!st.isFile() || st.mtimeMs < startMs) continue;
@@ -8980,7 +9129,7 @@ function probeRateLimit(args) {
8980
9129
  }
8981
9130
  let content;
8982
9131
  try {
8983
- content = readFileSync28(path, "utf-8");
9132
+ content = readFileSync29(path, "utf-8");
8984
9133
  } catch {
8985
9134
  continue;
8986
9135
  }
@@ -9042,7 +9191,7 @@ function shouldLogUsageCapDeferral(site, codeName, limitedUntil) {
9042
9191
 
9043
9192
  // src/lib/manager/scheduler/execution.ts
9044
9193
  function claudePidFilePath() {
9045
- return join37(homedir16(), ".augmented", "manager-claude-pids.json");
9194
+ return join38(homedir16(), ".augmented", "manager-claude-pids.json");
9046
9195
  }
9047
9196
  var inFlightClaudePids = /* @__PURE__ */ new Map();
9048
9197
  function registerClaudeSpawn(record) {
@@ -9113,7 +9262,7 @@ async function syncAndCheckClaudeScheduler(agent, tasks, boardItems, refreshData
9113
9262
 
9114
9263
  // src/lib/occupancy-gate.ts
9115
9264
  import { closeSync as closeSync2, openSync as openSync2, readdirSync as readdirSync9, readSync as readSync2, statSync as statSync11 } from "fs";
9116
- import { join as join38 } from "path";
9265
+ import { join as join39 } from "path";
9117
9266
  function rostersMeasuredZero(mode, attested, runtimeRunning) {
9118
9267
  return mode === "enforce" && attested && runtimeRunning;
9119
9268
  }
@@ -9204,10 +9353,10 @@ function candidateTranscriptPaths(dir) {
9204
9353
  let complete = true;
9205
9354
  for (const name of top) {
9206
9355
  if (name.endsWith(".jsonl")) {
9207
- paths.push(join38(dir, name));
9356
+ paths.push(join39(dir, name));
9208
9357
  continue;
9209
9358
  }
9210
- const subDir = join38(dir, name, "subagents");
9359
+ const subDir = join39(dir, name, "subagents");
9211
9360
  let subs;
9212
9361
  try {
9213
9362
  subs = readdirSync9(subDir);
@@ -9216,7 +9365,7 @@ function candidateTranscriptPaths(dir) {
9216
9365
  continue;
9217
9366
  }
9218
9367
  for (const sub of subs) {
9219
- if (sub.endsWith(".jsonl")) paths.push(join38(subDir, sub));
9368
+ if (sub.endsWith(".jsonl")) paths.push(join39(subDir, sub));
9220
9369
  }
9221
9370
  }
9222
9371
  return { paths, complete };
@@ -9442,7 +9591,7 @@ function stopPaneOccupancySampler() {
9442
9591
  }
9443
9592
 
9444
9593
  // src/lib/pid-pressure-sampler.ts
9445
- import { existsSync as existsSync16, readFileSync as readFileSync29 } from "fs";
9594
+ import { existsSync as existsSync16, readFileSync as readFileSync30 } from "fs";
9446
9595
  var SAMPLE_INTERVAL_MS2 = 3e4;
9447
9596
  function warnFraction() {
9448
9597
  const raw = Number(process.env.AGT_PID_PRESSURE_WARN_FRACTION);
@@ -9470,7 +9619,7 @@ function parseMemoryEvents(text) {
9470
9619
  }
9471
9620
  function readTextReal(path) {
9472
9621
  try {
9473
- return readFileSync29(path, "utf-8");
9622
+ return readFileSync30(path, "utf-8");
9474
9623
  } catch {
9475
9624
  return null;
9476
9625
  }
@@ -10753,9 +10902,9 @@ async function fireOpencodeScheduledTask(agent, task) {
10753
10902
 
10754
10903
  // src/lib/opencode-telegram-ingest.ts
10755
10904
  import { createHash as createHash19 } from "crypto";
10756
- import { existsSync as existsSync17, mkdirSync as mkdirSync12, readFileSync as readFileSync30, renameSync as renameSync9, unlinkSync as unlinkSync4, writeFileSync as writeFileSync15 } from "fs";
10905
+ import { existsSync as existsSync17, mkdirSync as mkdirSync12, readFileSync as readFileSync31, renameSync as renameSync9, unlinkSync as unlinkSync4, writeFileSync as writeFileSync15 } from "fs";
10757
10906
  import { randomUUID } from "crypto";
10758
- import { join as join39 } from "path";
10907
+ import { join as join40 } from "path";
10759
10908
 
10760
10909
  // src/lib/telegram-ingest.ts
10761
10910
  import https2 from "https";
@@ -11312,7 +11461,7 @@ function createFileOffsetStore(codeName, log2, currentBotId) {
11312
11461
  let filePath;
11313
11462
  try {
11314
11463
  dir = getFramework("opencode").getAgentDir(codeName);
11315
- filePath = join39(dir, "telegram-getupdates-offset-opencode.json");
11464
+ filePath = join40(dir, "telegram-getupdates-offset-opencode.json");
11316
11465
  } catch {
11317
11466
  dir = null;
11318
11467
  filePath = null;
@@ -11321,7 +11470,7 @@ function createFileOffsetStore(codeName, log2, currentBotId) {
11321
11470
  load() {
11322
11471
  if (!filePath) return 0;
11323
11472
  try {
11324
- const parsed = JSON.parse(readFileSync30(filePath, "utf-8"));
11473
+ const parsed = JSON.parse(readFileSync31(filePath, "utf-8"));
11325
11474
  if (currentBotId != null && typeof parsed?.bot_id === "number" && parsed.bot_id !== currentBotId) {
11326
11475
  log2(`[telegram-ingest:${codeName}] offset cursor belongs to a different bot; ignoring (bot swap)`);
11327
11476
  return 0;
@@ -11595,15 +11744,15 @@ function partitionActionableByPoison(actionable, states, config2) {
11595
11744
  }
11596
11745
 
11597
11746
  // src/lib/restart-flags.ts
11598
- import { existsSync as existsSync18, mkdirSync as mkdirSync13, readdirSync as readdirSync10, readFileSync as readFileSync31, renameSync as renameSync10, rmSync as rmSync7, writeFileSync as writeFileSync16 } from "fs";
11747
+ import { existsSync as existsSync18, mkdirSync as mkdirSync13, readdirSync as readdirSync10, readFileSync as readFileSync32, renameSync as renameSync10, rmSync as rmSync7, writeFileSync as writeFileSync16 } from "fs";
11599
11748
  import { homedir as homedir17 } from "os";
11600
- import { join as join40 } from "path";
11749
+ import { join as join41 } from "path";
11601
11750
  import { randomUUID as randomUUID2 } from "crypto";
11602
11751
  function restartFlagsDir() {
11603
- return join40(homedir17(), ".augmented", "restart-flags");
11752
+ return join41(homedir17(), ".augmented", "restart-flags");
11604
11753
  }
11605
11754
  function flagPath(codeName) {
11606
- return join40(restartFlagsDir(), `${codeName}.flag`);
11755
+ return join41(restartFlagsDir(), `${codeName}.flag`);
11607
11756
  }
11608
11757
  function readRestartFlags() {
11609
11758
  const dir = restartFlagsDir();
@@ -11612,7 +11761,7 @@ function readRestartFlags() {
11612
11761
  for (const entry of readdirSync10(dir)) {
11613
11762
  if (!entry.endsWith(".flag")) continue;
11614
11763
  try {
11615
- const raw = readFileSync31(join40(dir, entry), "utf8");
11764
+ const raw = readFileSync32(join41(dir, entry), "utf8");
11616
11765
  const parsed = JSON.parse(raw);
11617
11766
  if (typeof parsed.codeName !== "string" || parsed.codeName.length === 0) {
11618
11767
  parsed.codeName = entry.replace(/\.flag$/, "");
@@ -11730,8 +11879,8 @@ async function sendError(flag, opts, text) {
11730
11879
  }
11731
11880
 
11732
11881
  // src/lib/restart-context.ts
11733
- import { readdirSync as readdirSync11, readFileSync as readFileSync32, writeFileSync as writeFileSync17, mkdirSync as mkdirSync14, unlinkSync as unlinkSync5 } from "fs";
11734
- import { dirname as dirname10, join as join41 } from "path";
11882
+ import { readdirSync as readdirSync11, readFileSync as readFileSync33, writeFileSync as writeFileSync17, mkdirSync as mkdirSync14, unlinkSync as unlinkSync5 } from "fs";
11883
+ import { dirname as dirname10, join as join42 } from "path";
11735
11884
  var SLACK_PENDING_INBOUND_DIRNAME = "slack-pending-inbound";
11736
11885
  var SLACK_RESTART_CONTEXT_DIRNAME = "slack-restart-context";
11737
11886
  var MAX_TOPIC_CHARS = 140;
@@ -11743,10 +11892,10 @@ function augmentedAgentDir(codeName) {
11743
11892
  return dirname10(getProjectDir(codeName));
11744
11893
  }
11745
11894
  function slackPendingInboundDir(codeName) {
11746
- return join41(augmentedAgentDir(codeName), SLACK_PENDING_INBOUND_DIRNAME);
11895
+ return join42(augmentedAgentDir(codeName), SLACK_PENDING_INBOUND_DIRNAME);
11747
11896
  }
11748
11897
  function slackRestartContextDir(codeName) {
11749
- return join41(augmentedAgentDir(codeName), SLACK_RESTART_CONTEXT_DIRNAME);
11898
+ return join42(augmentedAgentDir(codeName), SLACK_RESTART_CONTEXT_DIRNAME);
11750
11899
  }
11751
11900
  function sanitizeTopic(raw) {
11752
11901
  const cleaned = raw.replace(/\s+/g, " ").trim().replace(/[<>]/g, " ").replace(/\s+/g, " ").trim();
@@ -11788,7 +11937,7 @@ function safeReaddir(dir) {
11788
11937
  }
11789
11938
  function readStrandedMarker(path) {
11790
11939
  try {
11791
- const parsed = JSON.parse(readFileSync32(path, "utf-8"));
11940
+ const parsed = JSON.parse(readFileSync33(path, "utf-8"));
11792
11941
  if (typeof parsed.channel === "string" && typeof parsed.thread_ts === "string") {
11793
11942
  return { channel: parsed.channel, thread_ts: parsed.thread_ts };
11794
11943
  }
@@ -11806,7 +11955,7 @@ function pruneHintsExcept(codeName, freshFilenames) {
11806
11955
  if (!filename.endsWith(".json")) continue;
11807
11956
  if (freshFilenames.has(filename)) continue;
11808
11957
  try {
11809
- unlinkSync5(join41(ctxDir, filename));
11958
+ unlinkSync5(join42(ctxDir, filename));
11810
11959
  } catch {
11811
11960
  }
11812
11961
  }
@@ -11827,7 +11976,7 @@ function refreshSlackRestartContextHints(codeNames, opts = {}) {
11827
11976
  }
11828
11977
  const markers = [];
11829
11978
  for (const filename of markerFilenames.slice(0, cap)) {
11830
- const parsed = readStrandedMarker(join41(markerDir, filename));
11979
+ const parsed = readStrandedMarker(join42(markerDir, filename));
11831
11980
  if (parsed) markers.push({ filename, channel: parsed.channel, thread_ts: parsed.thread_ts });
11832
11981
  }
11833
11982
  if (markers.length === 0) {
@@ -11841,7 +11990,7 @@ function refreshSlackRestartContextHints(codeNames, opts = {}) {
11841
11990
  const freshFilenames = /* @__PURE__ */ new Set();
11842
11991
  for (const { filename, hint } of hints) {
11843
11992
  try {
11844
- writeHintFile(join41(ctxDir, filename), ctxDir, hint);
11993
+ writeHintFile(join42(ctxDir, filename), ctxDir, hint);
11845
11994
  freshFilenames.add(filename);
11846
11995
  } catch (err) {
11847
11996
  log2(`[restart-context] ${codeName}: hint write failed for ${filename}: ${err.message}`);
@@ -13311,7 +13460,7 @@ var pendingDayRolloverReset = /* @__PURE__ */ new Set();
13311
13460
  var dayRolloverInboundHold = /* @__PURE__ */ new Map();
13312
13461
  var INBOUND_HOLD_EPISODE_GAP_MS = 12e4;
13313
13462
  async function channelInboundActivityAgeSecondsFor(codeName) {
13314
- const { newestPendingInboundActivityMtimeMs } = await import("../responsiveness-probe-6NWZAXIZ.js");
13463
+ const { newestPendingInboundActivityMtimeMs } = await import("../responsiveness-probe-DXPEIUH6.js");
13315
13464
  const newest = newestPendingInboundActivityMtimeMs(dirname11(paneLogPath(codeName)));
13316
13465
  if (newest === null) return null;
13317
13466
  return Math.max(0, Math.floor((Date.now() - newest) / 1e3));
@@ -13636,7 +13785,7 @@ var runningChannelSecretHashes = /* @__PURE__ */ new Map();
13636
13785
  var sessionLaunchManagedStructure = /* @__PURE__ */ new Map();
13637
13786
  function projectMcpHash(_codeName, projectDir) {
13638
13787
  try {
13639
- const raw = readFileSync33(join42(projectDir, ".mcp.json"), "utf-8");
13788
+ const raw = readFileSync34(join43(projectDir, ".mcp.json"), "utf-8");
13640
13789
  return createHash20("sha256").update(canonicalJson(JSON.parse(raw))).digest("hex");
13641
13790
  } catch {
13642
13791
  return null;
@@ -13644,7 +13793,7 @@ function projectMcpHash(_codeName, projectDir) {
13644
13793
  }
13645
13794
  function projectMcpKeys(_codeName, projectDir) {
13646
13795
  try {
13647
- const raw = readFileSync33(join42(projectDir, ".mcp.json"), "utf-8");
13796
+ const raw = readFileSync34(join43(projectDir, ".mcp.json"), "utf-8");
13648
13797
  const parsed = JSON.parse(raw);
13649
13798
  const servers = parsed.mcpServers;
13650
13799
  if (!servers || typeof servers !== "object") return /* @__PURE__ */ new Set();
@@ -13662,7 +13811,7 @@ function seedSessionLaunchBaselines(codeName, projectDir) {
13662
13811
  else runningMcpServerKeys.delete(codeName);
13663
13812
  let launchStructure = null;
13664
13813
  try {
13665
- const raw = readFileSync33(join42(projectDir, ".mcp.json"), "utf-8");
13814
+ const raw = readFileSync34(join43(projectDir, ".mcp.json"), "utf-8");
13666
13815
  launchStructure = managedMcpStructureHashFromFile(
13667
13816
  JSON.parse(raw),
13668
13817
  isManagedMcpServerKey
@@ -13797,7 +13946,7 @@ async function runAgentSessionToolBindProbes(agent, integrations, projectDir, op
13797
13946
  if (result && result.rebindCandidates.length > 0 && hostFlagStore().getBoolean("session-tool-rebind")) {
13798
13947
  let mcpJsonForRebind = null;
13799
13948
  try {
13800
- mcpJsonForRebind = JSON.parse(readFileSync33(join42(projectDir, ".mcp.json"), "utf-8"));
13949
+ mcpJsonForRebind = JSON.parse(readFileSync34(join43(projectDir, ".mcp.json"), "utf-8"));
13801
13950
  } catch {
13802
13951
  mcpJsonForRebind = null;
13803
13952
  }
@@ -13945,7 +14094,7 @@ function shouldInjectChannelSecrets(agentId) {
13945
14094
  function projectChannelSecretHash(projectDir) {
13946
14095
  try {
13947
14096
  const entries = parseEnvIntegrations(
13948
- readFileSync33(join42(projectDir, ".env.integrations"), "utf-8")
14097
+ readFileSync34(join43(projectDir, ".env.integrations"), "utf-8")
13949
14098
  );
13950
14099
  return channelSecretValueHash(entries, CHANNEL_SECRET_ENV_KEYS);
13951
14100
  } catch {
@@ -14054,7 +14203,7 @@ var agentRestartTimezoneInputs = /* @__PURE__ */ new Map();
14054
14203
  var lastVersionCheckAt = 0;
14055
14204
  var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
14056
14205
  var lastResponsivenessProbeAt = 0;
14057
- var agtCliVersion = true ? "0.28.1005" : "dev";
14206
+ var agtCliVersion = true ? "0.28.1006" : "dev";
14058
14207
  function resolveBrewPath(execFileSync2) {
14059
14208
  try {
14060
14209
  const out = execFileSync2("which", ["brew"], { timeout: 5e3 }).toString().trim();
@@ -14381,7 +14530,7 @@ function runAsync(cmd, args, opts) {
14381
14530
  });
14382
14531
  }
14383
14532
  function claudeManagedSettingsPath() {
14384
- return join42(CLAUDE_MANAGED_SETTINGS_DIR, "managed-settings.json");
14533
+ return join43(CLAUDE_MANAGED_SETTINGS_DIR, "managed-settings.json");
14385
14534
  }
14386
14535
  var MANAGED_SETTINGS_KEYS = ["channelsEnabled", "enableAllProjectMcpServers"];
14387
14536
  var MANAGED_SETTINGS_ENV = { DISABLE_AUTOUPDATER: "1" };
@@ -14389,7 +14538,7 @@ function ensureClaudeManagedSettings(path = claudeManagedSettingsPath()) {
14389
14538
  try {
14390
14539
  let settings = {};
14391
14540
  if (existsSync19(path)) {
14392
- const raw = readFileSync33(path, "utf-8").trim();
14541
+ const raw = readFileSync34(path, "utf-8").trim();
14393
14542
  if (raw) {
14394
14543
  let parsed;
14395
14544
  try {
@@ -14456,7 +14605,7 @@ async function ensureOpencodeBinary() {
14456
14605
  try {
14457
14606
  const prefix = execFileSync2("npm", ["prefix", "-g"], { encoding: "utf-8", timeout: 1e4 }).trim();
14458
14607
  if (prefix) {
14459
- const npmBin = join42(prefix, "bin");
14608
+ const npmBin = join43(prefix, "bin");
14460
14609
  const current = (process.env.PATH ?? "").split(pathDelimiter);
14461
14610
  if (!current.includes(npmBin)) {
14462
14611
  process.env.PATH = [npmBin, ...current.filter(Boolean)].join(pathDelimiter);
@@ -14596,7 +14745,7 @@ async function maybeUpgradeClaudeCode() {
14596
14745
  }
14597
14746
  var UPDATE_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
14598
14747
  function selfUpdateAppliedMarkerPath() {
14599
- return join42(homedir18(), ".augmented", ".last-self-update-applied");
14748
+ return join43(homedir18(), ".augmented", ".last-self-update-applied");
14600
14749
  }
14601
14750
  var selfUpdateUpToDateLogged = false;
14602
14751
  var selfUpdatePinnedLogged = false;
@@ -14647,7 +14796,7 @@ async function checkAndUpdateCli(opts) {
14647
14796
  const isNpmGlobal = !isBrewFormula && resolvedPath.includes("node_modules");
14648
14797
  if (!isBrewFormula && !isNpmGlobal) return "noop";
14649
14798
  const { readFileSync: readF, writeFileSync: writeF } = await import("fs");
14650
- const markerPath = join42(homedir18(), ".augmented", ".last-update-check");
14799
+ const markerPath = join43(homedir18(), ".augmented", ".last-update-check");
14651
14800
  if (!force) {
14652
14801
  try {
14653
14802
  const lastCheck = parseInt(readF(markerPath, "utf-8").trim(), 10);
@@ -15145,12 +15294,12 @@ async function checkClaudeAuth() {
15145
15294
  var evalEmptyMcpConfigPath = null;
15146
15295
  function ensureEvalEmptyMcpConfig() {
15147
15296
  if (evalEmptyMcpConfigPath && existsSync19(evalEmptyMcpConfigPath)) return evalEmptyMcpConfigPath;
15148
- const dir = join42(homedir18(), ".augmented");
15297
+ const dir = join43(homedir18(), ".augmented");
15149
15298
  try {
15150
15299
  mkdirSync15(dir, { recursive: true });
15151
15300
  } catch {
15152
15301
  }
15153
- const p = join42(dir, ".eval-empty-mcp.json");
15302
+ const p = join43(dir, ".eval-empty-mcp.json");
15154
15303
  writeFileSync18(p, JSON.stringify({ mcpServers: {} }));
15155
15304
  evalEmptyMcpConfigPath = p;
15156
15305
  return p;
@@ -15245,10 +15394,10 @@ function resolveConversationEvalBackend() {
15245
15394
  return conversationEvalBackend;
15246
15395
  }
15247
15396
  function getStateFile() {
15248
- return join42(config?.configDir ?? join42(process.env["HOME"] ?? "/tmp", ".augmented"), "manager-state.json");
15397
+ return join43(config?.configDir ?? join43(process.env["HOME"] ?? "/tmp", ".augmented"), "manager-state.json");
15249
15398
  }
15250
15399
  function channelHashCacheDir() {
15251
- return config?.configDir ?? join42(process.env["HOME"] ?? "/tmp", ".augmented");
15400
+ return config?.configDir ?? join43(process.env["HOME"] ?? "/tmp", ".augmented");
15252
15401
  }
15253
15402
  function loadChannelHashCache2() {
15254
15403
  loadChannelHashCache(agentState.knownChannelConfigHashes, channelHashCacheDir());
@@ -15461,11 +15610,29 @@ function removeDeliveryBaselineEntries(agentId) {
15461
15610
  var _channelQuarantineStore = null;
15462
15611
  function channelQuarantineStore() {
15463
15612
  if (!_channelQuarantineStore) {
15464
- const dir = config?.configDir ?? join42(process.env["HOME"] ?? "/tmp", ".augmented");
15613
+ const dir = config?.configDir ?? join43(process.env["HOME"] ?? "/tmp", ".augmented");
15465
15614
  _channelQuarantineStore = new ChannelQuarantineStore(defaultQuarantinePath(dir));
15466
15615
  }
15467
15616
  return _channelQuarantineStore;
15468
15617
  }
15618
+ var _channelResumeHistoryStore = null;
15619
+ function channelResumeHistoryStore() {
15620
+ if (!_channelResumeHistoryStore) {
15621
+ const dir = config?.configDir ?? join43(process.env["HOME"] ?? "/tmp", ".augmented");
15622
+ _channelResumeHistoryStore = new ChannelResumeHistoryStore(defaultResumeHistoryPath(dir));
15623
+ }
15624
+ return _channelResumeHistoryStore;
15625
+ }
15626
+ var autoResumeDowngradeLogged = /* @__PURE__ */ new Set();
15627
+ function shouldLogAutoResumeModeDowngrade(autoResume, quarantine) {
15628
+ const key = `${autoResume}->${quarantine}`;
15629
+ if (autoResumeDowngradeLogged.has(key)) return false;
15630
+ autoResumeDowngradeLogged.add(key);
15631
+ return true;
15632
+ }
15633
+ function channelQuarantineAutoResumeMode() {
15634
+ return hostFlagStore().getString("channel-quarantine-auto-resume");
15635
+ }
15469
15636
  function quarantineEntriesFor(codeName) {
15470
15637
  return channelQuarantineStore().getQuarantineEntries(codeName);
15471
15638
  }
@@ -15477,12 +15644,12 @@ function claudeMdSizeFor(codeName) {
15477
15644
  }
15478
15645
  function forwardedToolsFor(codeName) {
15479
15646
  if (!config?.configDir) return null;
15480
- return readForwardedToolsReport(join42(config.configDir, codeName));
15647
+ return readForwardedToolsReport(join43(config.configDir, codeName));
15481
15648
  }
15482
15649
  var _hostFlagStore = null;
15483
15650
  function hostFlagStore() {
15484
15651
  if (!_hostFlagStore) {
15485
- const dir = config?.configDir ?? join42(process.env["HOME"] ?? "/tmp", ".augmented");
15652
+ const dir = config?.configDir ?? join43(process.env["HOME"] ?? "/tmp", ".augmented");
15486
15653
  _hostFlagStore = new HostFlagStore({ cachePath: defaultFlagsCachePath(dir), log });
15487
15654
  }
15488
15655
  return _hostFlagStore;
@@ -15556,12 +15723,12 @@ function parseSkillFrontmatter(content) {
15556
15723
  }
15557
15724
  async function refreshSkillsIndexInClaudeMd(configDir, codeName, log2) {
15558
15725
  const { readdirSync: readdirSync13, readFileSync: rfs, existsSync: ex, writeFileSync: writeFileSync19 } = await import("fs");
15559
- const skillsDir = join42(configDir, codeName, "project", ".claude", "skills");
15560
- const claudeMdPath = join42(configDir, codeName, "project", "CLAUDE.md");
15726
+ const skillsDir = join43(configDir, codeName, "project", ".claude", "skills");
15727
+ const claudeMdPath = join43(configDir, codeName, "project", "CLAUDE.md");
15561
15728
  if (!ex(skillsDir) || !ex(claudeMdPath)) return;
15562
15729
  const entries = [];
15563
15730
  for (const dir of readdirSync13(skillsDir).sort()) {
15564
- const skillFile = join42(skillsDir, dir, "SKILL.md");
15731
+ const skillFile = join43(skillsDir, dir, "SKILL.md");
15565
15732
  if (!ex(skillFile)) continue;
15566
15733
  try {
15567
15734
  const { name, description } = parseSkillFrontmatter(rfs(skillFile, "utf-8"));
@@ -15670,7 +15837,7 @@ function flushRestartedAgentDiagnostics(hostId, codeNames) {
15670
15837
  if (codeNames.length === 0) return;
15671
15838
  void (async () => {
15672
15839
  try {
15673
- const { collectDiagnostics } = await import("../persistent-session-4PP3ON7H.js");
15840
+ const { collectDiagnostics } = await import("../persistent-session-K4DLZ7KF.js");
15674
15841
  await api.post("/host/heartbeat", {
15675
15842
  host_id: hostId,
15676
15843
  agent_diagnostics: collectDiagnostics(codeNames, quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor)
@@ -15812,7 +15979,7 @@ async function pollCycleInner() {
15812
15979
  }
15813
15980
  try {
15814
15981
  const { detectHostSecurity } = await import("../host-security-KQYYZZVW.js");
15815
- const { collectDiagnostics } = await import("../persistent-session-4PP3ON7H.js");
15982
+ const { collectDiagnostics } = await import("../persistent-session-K4DLZ7KF.js");
15816
15983
  const diagCodeNames = [...agentState.persistentSessionAgents];
15817
15984
  const agentDiagnostics = diagCodeNames.length > 0 ? collectDiagnostics(diagCodeNames, quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor) : void 0;
15818
15985
  let tailscaleHostname;
@@ -15988,7 +16155,7 @@ async function pollCycleInner() {
15988
16155
  collectPanelessActivityProbes,
15989
16156
  getResponsivenessIntervalMs,
15990
16157
  occupancyQualificationClassifications
15991
- } = await import("../responsiveness-probe-6NWZAXIZ.js");
16158
+ } = await import("../responsiveness-probe-DXPEIUH6.js");
15992
16159
  const probeIntervalMs = getResponsivenessIntervalMs();
15993
16160
  if (now - lastResponsivenessProbeAt > probeIntervalMs) {
15994
16161
  const probeCodeNames = [...agentState.persistentSessionAgents];
@@ -16105,7 +16272,7 @@ async function pollCycleInner() {
16105
16272
  collectResponsivenessProbes,
16106
16273
  livePendingInboundOldestAgeSeconds,
16107
16274
  parkPendingInbound
16108
- } = await import("../responsiveness-probe-6NWZAXIZ.js");
16275
+ } = await import("../responsiveness-probe-DXPEIUH6.js");
16109
16276
  const { getProjectDir: wedgeProjectDir } = await import("../scheduler-engine-M6AFZWNU.js");
16110
16277
  const wedgeNow = /* @__PURE__ */ new Date();
16111
16278
  const liveAgents = agentState.persistentSessionAgents;
@@ -16194,13 +16361,13 @@ async function pollCycleInner() {
16194
16361
  );
16195
16362
  if (hostFlagStore().getBoolean("wedge-transient-notice")) {
16196
16363
  try {
16197
- const paneTail = readFileSync33(paneLogPath(codeName), "utf8").slice(-65536);
16364
+ const paneTail = readFileSync34(paneLogPath(codeName), "utf8").slice(-65536);
16198
16365
  const transient = detectTransientApiErrorInLog(paneTail);
16199
16366
  if (transient) {
16200
- const wedgeHome = join42(homedir18(), ".augmented", codeName);
16367
+ const wedgeHome = join43(homedir18(), ".augmented", codeName);
16201
16368
  if (existsSync19(wedgeHome)) {
16202
16369
  atomicWriteFileSync(
16203
- join42(wedgeHome, "watchdog-give-up.json"),
16370
+ join43(wedgeHome, "watchdog-give-up.json"),
16204
16371
  JSON.stringify({
16205
16372
  gave_up_at: wedgeNow.toISOString(),
16206
16373
  reason: "transient_overload"
@@ -16261,7 +16428,7 @@ async function pollCycleInner() {
16261
16428
  }
16262
16429
  try {
16263
16430
  const { scrapeMcpFailedBannerCount } = await import("../pane-mcp-banner-scraper-VR5QGP3J.js");
16264
- const { probeSessionAuth } = await import("../session-auth-dead-2V2BOXAG.js");
16431
+ const { probeSessionAuth } = await import("../session-auth-dead-4SE5Q7MU.js");
16265
16432
  const observations = [];
16266
16433
  const pendingCacheCommits = [];
16267
16434
  const modelApiErrorReportingOn = hostFlagStore().getBoolean("model-api-error-reporting");
@@ -16417,6 +16584,12 @@ async function pollCycleInner() {
16417
16584
  agent.code_name,
16418
16585
  clear.channel_id
16419
16586
  );
16587
+ for (const mode of ["enforce", "shadow"]) {
16588
+ channelResumeHistoryStore().forget(
16589
+ agent.code_name,
16590
+ resumeHistoryKey(mode, clear.channel_id)
16591
+ );
16592
+ }
16420
16593
  log(
16421
16594
  `[channel-reenable] ${removed ? "cleared" : "no marker for"} '${clear.channel_id}' on '${agent.code_name}' (operator re-enable)`
16422
16595
  );
@@ -16431,6 +16604,92 @@ async function pollCycleInner() {
16431
16604
  );
16432
16605
  }
16433
16606
  }
16607
+ const autoResumeMode = channelQuarantineAutoResumeMode();
16608
+ const quarantineMode = channelQuarantineMode();
16609
+ const autoResumeEffective = resolveAutoResumeEffectiveMode(autoResumeMode, quarantineMode);
16610
+ if (autoResumeMode === "enforce" && autoResumeEffective === "shadow") {
16611
+ if (shouldLogAutoResumeModeDowngrade(autoResumeMode, quarantineMode)) {
16612
+ log(
16613
+ `[channel-auto-resume] channel-quarantine-auto-resume is 'enforce' but channel-quarantine-mode is '${quarantineMode}', so the reaper writes no quarantine marker and a failed trial could never be observed - every trial would score a success and permanently un-quarantine a dead channel. Running in SHADOW instead (bookkeeping only, nothing cleared). Set channel-quarantine-mode to 'enforce' first.`
16614
+ );
16615
+ }
16616
+ }
16617
+ if (autoResumeEffective !== "off") {
16618
+ const nowMs = Date.now();
16619
+ for (const agent of agents) {
16620
+ if (agent.status !== "active") continue;
16621
+ try {
16622
+ const quarantineEntries = channelQuarantineStore().getQuarantineEntries(agent.code_name);
16623
+ const quarantinedKeys = new Set(quarantineEntries.map((e) => e.serverKey));
16624
+ for (const [storedKey, history] of channelResumeHistoryStore().entriesFor(agent.code_name)) {
16625
+ const isShadowKey = storedKey.startsWith("shadow:");
16626
+ if (isShadowKey !== (autoResumeEffective === "shadow")) continue;
16627
+ const serverKey = isShadowKey ? storedKey.slice("shadow:".length) : storedKey;
16628
+ if (!shouldForgetResumeHistory({
16629
+ isQuarantined: quarantinedKeys.has(serverKey),
16630
+ history,
16631
+ now: nowMs,
16632
+ // THE CONFIGURED DWELL, NOT THE FLOOR (obi-wan `7414dbf3d758`).
16633
+ // A host that raised AGT_CHANNEL_QUARANTINE_DWELL_MS pushes
16634
+ // re-quarantine PAST the floor-derived grace, so a failed trial
16635
+ // read as a success and wiped the strikes - restarting the
16636
+ // five-attempt budget every episode, forever.
16637
+ configuredDwellMs: channelQuarantineDwellMs()
16638
+ })) {
16639
+ continue;
16640
+ }
16641
+ channelResumeHistoryStore().forget(agent.code_name, storedKey);
16642
+ log(
16643
+ `[channel-auto-resume] trial SUCCEEDED for '${serverKey}' on '${agent.code_name}' \u2014 un-quarantined for ${Math.round((nowMs - history.lastAttemptAt) / 6e4)}m, clearing ${history.attempts} strike(s) so the next episode starts from a full budget` + (autoResumeEffective === "shadow" ? " (shadow bookkeeping)" : "")
16644
+ );
16645
+ }
16646
+ for (const entry of quarantineEntries) {
16647
+ const historyKeyFor = (key) => resumeHistoryKey(autoResumeEffective, key);
16648
+ const historyKey = historyKeyFor(entry.serverKey);
16649
+ const history = channelResumeHistoryStore().get(agent.code_name, historyKey);
16650
+ const decision = decideChannelAutoResume({
16651
+ quarantinedAt: entry.quarantinedAt,
16652
+ history,
16653
+ now: nowMs
16654
+ });
16655
+ if (decision.action === "wait") continue;
16656
+ if (decision.action === "give-up") {
16657
+ if (!channelResumeHistoryStore().noteGaveUpLogged(agent.code_name, historyKeyFor(entry.serverKey))) {
16658
+ log(
16659
+ autoResumeEffective === "shadow" ? `[channel-auto-resume] WOULD HAVE GIVEN UP on '${entry.serverKey}' for '${agent.code_name}' \u2014 ${decision.attempts} shadow trials recorded, which is the cap. No trial ran and nothing is abandoned: the strikes are in the shadow namespace, so enforcing would start this key at attempt 1 (shadow bookkeeping)` : `[channel-auto-resume] GIVING UP on '${entry.serverKey}' for '${agent.code_name}' \u2014 ${decision.attempts} trials over ~2 days all ended in re-quarantine, so it will NOT be retried automatically again. It stays quarantined until a human presses Re-enable, which also clears the strike count.`
16660
+ );
16661
+ }
16662
+ continue;
16663
+ }
16664
+ const quarantineAgeMin = Math.round((nowMs - entry.quarantinedAt) / 6e4);
16665
+ const waitedMin = Math.round(decision.waitedMs / 6e4);
16666
+ const recorded = channelResumeHistoryStore().recordAttempt(
16667
+ agent.code_name,
16668
+ historyKey,
16669
+ nowMs
16670
+ );
16671
+ if (autoResumeEffective === "shadow") {
16672
+ log(
16673
+ `[channel-auto-resume] WOULD resume '${entry.serverKey}' on '${agent.code_name}' (attempt ${recorded.attempts}/${AUTO_RESUME_MAX_ATTEMPTS}, quarantined ${quarantineAgeMin}m ago, waited ${waitedMin}m since the last trial) \u2014 shadow mode, not acting`
16674
+ );
16675
+ continue;
16676
+ }
16677
+ const cleared = channelQuarantineStore().clearQuarantine(
16678
+ agent.code_name,
16679
+ entry.serverKey
16680
+ );
16681
+ log(
16682
+ `[channel-auto-resume] ${cleared ? "resumed" : "no marker for"} '${entry.serverKey}' on '${agent.code_name}' for a TRIAL run (attempt ${recorded.attempts}/${AUTO_RESUME_MAX_ATTEMPTS}, quarantined ${quarantineAgeMin}m ago, waited ${waitedMin}m since the last trial). The reaper will re-quarantine it if it is still dead.`
16683
+ );
16684
+ }
16685
+ } catch (err) {
16686
+ log(
16687
+ `[channel-auto-resume] a write FAILED partway through '${agent.code_name}' \u2014 ${err instanceof Error ? err.message : String(err)}. Skipping the REST of auto-resume for this agent this cycle; every other agent still gets its poll. State is PARTIAL, not untouched: entries processed before the throw have already been written (channel-resume-history.json, channel-quarantine.json). Every strike is recorded before its marker is cleared, so the failure direction is a wasted strike rather than a trial nobody paid for - but do not read this as "nothing happened".`
16688
+ );
16689
+ continue;
16690
+ }
16691
+ }
16692
+ }
16434
16693
  const frameworksThisCycle = new Set(agents.map((a) => a.framework).filter(Boolean));
16435
16694
  for (const fw of frameworksThisCycle) {
16436
16695
  await ensureFrameworkBinary(fw);
@@ -16550,7 +16809,7 @@ async function pollCycleInner() {
16550
16809
  `[drain-flush] FAILED for '${prev.codeName}': ${err.message} \u2014 proceeding to teardown; this session was NOT shipped (ENG-9491)`
16551
16810
  );
16552
16811
  }
16553
- const agentDir = join42(adapter.getAgentDir(prev.codeName), "provision");
16812
+ const agentDir = join43(adapter.getAgentDir(prev.codeName), "provision");
16554
16813
  await cleanupAgentFiles(prev.codeName, agentDir);
16555
16814
  clearAgentCaches(prev.agentId, prev.codeName);
16556
16815
  }
@@ -16637,10 +16896,10 @@ async function pollCycleInner() {
16637
16896
  // pending-inbound marker. Best-effort: a write failure is logged by
16638
16897
  // the watchdog, never fails the poll cycle.
16639
16898
  signalGiveUp: (codeName) => {
16640
- const dir = join42(homedir18(), ".augmented", codeName);
16899
+ const dir = join43(homedir18(), ".augmented", codeName);
16641
16900
  if (!existsSync19(dir)) return;
16642
16901
  atomicWriteFileSync(
16643
- join42(dir, "watchdog-give-up.json"),
16902
+ join43(dir, "watchdog-give-up.json"),
16644
16903
  JSON.stringify({ gave_up_at: (/* @__PURE__ */ new Date()).toISOString() })
16645
16904
  );
16646
16905
  },
@@ -16661,7 +16920,7 @@ async function pollCycleInner() {
16661
16920
  const dir = getFramework("claude-code").getAgentDir(codeName);
16662
16921
  if (!existsSync19(dir)) return;
16663
16922
  atomicWriteFileSync(
16664
- join42(dir, "watchdog-give-up.json"),
16923
+ join43(dir, "watchdog-give-up.json"),
16665
16924
  JSON.stringify({
16666
16925
  gave_up_at: (/* @__PURE__ */ new Date()).toISOString(),
16667
16926
  reason: "usage_limit",
@@ -16926,7 +17185,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
16926
17185
  }
16927
17186
  const now = (/* @__PURE__ */ new Date()).toISOString();
16928
17187
  const adapter = resolveAgentFramework(agent.code_name);
16929
- let agentDir = join42(adapter.getAgentDir(agent.code_name), "provision");
17188
+ let agentDir = join43(adapter.getAgentDir(agent.code_name), "provision");
16930
17189
  if (agent.status === "draft" || agent.status === "paused") {
16931
17190
  forgetChannelSyncState(agent.agent_id);
16932
17191
  if (previousKnownStatus !== agent.status) {
@@ -17073,7 +17332,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
17073
17332
  if (refreshData.knowledge_manifest) {
17074
17333
  const resolved = await resolveKnowledgeFromManifest({
17075
17334
  manifest: refreshData.knowledge_manifest,
17076
- cacheDir: join42(config.configDir, "_knowledge"),
17335
+ cacheDir: join43(config.configDir, "_knowledge"),
17077
17336
  delivery: refreshData.agent?.knowledge_delivery ?? "both",
17078
17337
  fetchContents: async (hashes) => {
17079
17338
  const res = await api.post(
@@ -17090,7 +17349,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
17090
17349
  const resolvedSkills = await resolveSkillsFromManifest({
17091
17350
  globals: refreshData.global_skills_manifest ?? [],
17092
17351
  shared: refreshData.shared_skills_manifest ?? [],
17093
- cacheDir: join42(config.configDir, "_skills"),
17352
+ cacheDir: join43(config.configDir, "_skills"),
17094
17353
  fetchContents: async (hashes) => {
17095
17354
  const res = await api.post(
17096
17355
  "/host/skills/contents",
@@ -17108,7 +17367,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
17108
17367
  if (refreshData.integration_skills_manifest) {
17109
17368
  const resolvedIntegrationSkills = await resolveIntegrationSkillsFromManifest({
17110
17369
  manifest: refreshData.integration_skills_manifest,
17111
- cacheDir: join42(config.configDir, "_skills"),
17370
+ cacheDir: join43(config.configDir, "_skills"),
17112
17371
  fetchContents: async (hashes) => {
17113
17372
  const res = await api.post(
17114
17373
  "/host/skills/contents",
@@ -17170,7 +17429,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
17170
17429
  const frameworkId = refreshData.agent.framework ?? DEFAULT_FRAMEWORK;
17171
17430
  agentFrameworkCache.set(agent.code_name, frameworkId);
17172
17431
  const frameworkAdapter = getFramework(frameworkId);
17173
- agentDir = join42(frameworkAdapter.getAgentDir(agent.code_name), "provision");
17432
+ agentDir = join43(frameworkAdapter.getAgentDir(agent.code_name), "provision");
17174
17433
  cacheAgentDeliveryMetadata(agent.code_name, refreshData);
17175
17434
  agentRestartTimezoneInputs.set(agent.code_name, {
17176
17435
  agentTimezone: typeof refreshData.agent.timezone === "string" ? refreshData.agent.timezone : null,
@@ -17229,7 +17488,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
17229
17488
  const changedFiles = [];
17230
17489
  mkdirSync15(agentDir, { recursive: true });
17231
17490
  for (const artifact of artifacts) {
17232
- const filePath = join42(agentDir, artifact.relativePath);
17491
+ const filePath = join43(agentDir, artifact.relativePath);
17233
17492
  let existingHash;
17234
17493
  let newHash;
17235
17494
  let writeContent = artifact.content;
@@ -17248,8 +17507,8 @@ async function processAgent(agent, agentStates, managedToolkits) {
17248
17507
  };
17249
17508
  newHash = sha256(stripDynamicSections(artifact.content));
17250
17509
  try {
17251
- const projectClaudeMd = join42(config.configDir, agent.code_name, "project", "CLAUDE.md");
17252
- const existing = readFileSync33(projectClaudeMd, "utf-8");
17510
+ const projectClaudeMd = join43(config.configDir, agent.code_name, "project", "CLAUDE.md");
17511
+ const existing = readFileSync34(projectClaudeMd, "utf-8");
17253
17512
  existingHash = sha256(stripDynamicSections(existing));
17254
17513
  } catch {
17255
17514
  existingHash = null;
@@ -17267,7 +17526,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
17267
17526
  const generatorKeys = Object.keys(generatorServers);
17268
17527
  let existingRaw = "";
17269
17528
  try {
17270
- existingRaw = readFileSync33(filePath, "utf-8");
17529
+ existingRaw = readFileSync34(filePath, "utf-8");
17271
17530
  } catch {
17272
17531
  }
17273
17532
  const existingServers = parseMcp(existingRaw);
@@ -17283,7 +17542,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
17283
17542
  } else if (artifact.relativePath === "opencode.json") {
17284
17543
  let existingRaw = null;
17285
17544
  try {
17286
- existingRaw = readFileSync33(filePath, "utf-8");
17545
+ existingRaw = readFileSync34(filePath, "utf-8");
17287
17546
  } catch {
17288
17547
  }
17289
17548
  const mergeResult = mergeOpencodeConfigArtifact(artifact.content, existingRaw);
@@ -17299,12 +17558,12 @@ async function processAgent(agent, agentStates, managedToolkits) {
17299
17558
  }
17300
17559
  }
17301
17560
  if (changedFiles.length > 0) {
17302
- const isFirst = !existsSync19(join42(agentDir, "CHARTER.md"));
17561
+ const isFirst = !existsSync19(join43(agentDir, "CHARTER.md"));
17303
17562
  const verb = isFirst ? "Provisioning" : "Updating";
17304
17563
  const fileNames = changedFiles.map((f) => f.relativePath).join(", ");
17305
17564
  log(`${verb} '${agent.code_name}': ${fileNames}`);
17306
17565
  for (const file of changedFiles) {
17307
- const filePath = join42(agentDir, file.relativePath);
17566
+ const filePath = join43(agentDir, file.relativePath);
17308
17567
  mkdirSync15(dirname11(filePath), { recursive: true });
17309
17568
  if (file.relativePath === ".mcp.json") {
17310
17569
  safeWriteJsonAtomic(filePath, file.content, { mode: 384 });
@@ -17313,12 +17572,12 @@ async function processAgent(agent, agentStates, managedToolkits) {
17313
17572
  }
17314
17573
  }
17315
17574
  try {
17316
- const provSkillsDir = join42(agentDir, ".claude", "skills");
17575
+ const provSkillsDir = join43(agentDir, ".claude", "skills");
17317
17576
  if (existsSync19(provSkillsDir)) {
17318
17577
  for (const folder of readdirSync12(provSkillsDir)) {
17319
17578
  if (folder.startsWith("knowledge-")) {
17320
17579
  try {
17321
- rmSync8(join42(provSkillsDir, folder), { recursive: true });
17580
+ rmSync8(join43(provSkillsDir, folder), { recursive: true });
17322
17581
  } catch {
17323
17582
  }
17324
17583
  }
@@ -17331,7 +17590,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
17331
17590
  const trackedFiles2 = frameworkAdapter.driftTrackedFiles();
17332
17591
  const hashes = /* @__PURE__ */ new Map();
17333
17592
  for (const file of trackedFiles2) {
17334
- const h = hashFile(join42(agentDir, file));
17593
+ const h = hashFile(join43(agentDir, file));
17335
17594
  if (h) hashes.set(file, h);
17336
17595
  }
17337
17596
  agentState.writtenHashes.set(agent.agent_id, hashes);
@@ -17349,14 +17608,14 @@ async function processAgent(agent, agentStates, managedToolkits) {
17349
17608
  }
17350
17609
  if (Array.isArray(refreshData.workflows)) {
17351
17610
  try {
17352
- const provWorkflowsDir = join42(agentDir, ".claude", "workflows");
17611
+ const provWorkflowsDir = join43(agentDir, ".claude", "workflows");
17353
17612
  if (existsSync19(provWorkflowsDir)) {
17354
17613
  const expected = new Set(refreshData.workflows.map((w) => `${w.name}.js`));
17355
17614
  for (const file of readdirSync12(provWorkflowsDir)) {
17356
17615
  if (!file.endsWith(".js")) continue;
17357
17616
  if (expected.has(file)) continue;
17358
17617
  try {
17359
- rmSync8(join42(provWorkflowsDir, file));
17618
+ rmSync8(join43(provWorkflowsDir, file));
17360
17619
  } catch {
17361
17620
  }
17362
17621
  }
@@ -17438,7 +17697,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
17438
17697
  if (written && existsSync19(agentDir)) {
17439
17698
  const driftedFiles = [];
17440
17699
  for (const [file, expectedHash] of written) {
17441
- const localHash = hashFile(join42(agentDir, file));
17700
+ const localHash = hashFile(join43(agentDir, file));
17442
17701
  if (localHash && localHash !== expectedHash) {
17443
17702
  driftedFiles.push(file);
17444
17703
  }
@@ -17449,7 +17708,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
17449
17708
  try {
17450
17709
  const localHashes = {};
17451
17710
  for (const file of driftedFiles) {
17452
- localHashes[file] = hashFile(join42(agentDir, file));
17711
+ localHashes[file] = hashFile(join43(agentDir, file));
17453
17712
  }
17454
17713
  await api.post("/host/drift", {
17455
17714
  agent_id: agent.agent_id,
@@ -17727,7 +17986,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
17727
17986
  const addedChannels = [...restartDecision.added];
17728
17987
  const writeDmNoticeMarkers = isChannelAddRestart ? () => {
17729
17988
  try {
17730
- const agentAugmentedDir = join42(homedir18(), ".augmented", agent.code_name);
17989
+ const agentAugmentedDir = join43(homedir18(), ".augmented", agent.code_name);
17731
17990
  mkdirSync15(agentAugmentedDir, { recursive: true });
17732
17991
  const markerJson = JSON.stringify({
17733
17992
  version: 1,
@@ -17735,7 +17994,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
17735
17994
  added: addedChannels
17736
17995
  });
17737
17996
  for (const file of ["slack-channel-add-restart.json", "telegram-channel-add-restart.json"]) {
17738
- atomicWriteFileSync(join42(agentAugmentedDir, file), markerJson);
17997
+ atomicWriteFileSync(join43(agentAugmentedDir, file), markerJson);
17739
17998
  }
17740
17999
  } catch (err) {
17741
18000
  log(`[hot-reload] channel-add DM-notice marker write failed for '${agent.code_name}' (non-fatal): ${err.message}`);
@@ -18034,18 +18293,18 @@ async function processAgent(agent, agentStates, managedToolkits) {
18034
18293
  if (agentSessionMode === "persistent" && (agentFrameworkCache.get(agent.code_name) ?? DEFAULT_FRAMEWORK) === "claude-code") {
18035
18294
  try {
18036
18295
  const agentProvisionDir = agentDir;
18037
- const projectDir = join42(homedir18(), ".augmented", agent.code_name, "project");
18296
+ const projectDir = join43(homedir18(), ".augmented", agent.code_name, "project");
18038
18297
  mkdirSync15(agentProvisionDir, { recursive: true });
18039
18298
  mkdirSync15(projectDir, { recursive: true });
18040
- const provisionMcpPath = join42(agentProvisionDir, ".mcp.json");
18041
- const projectMcpPath = join42(projectDir, ".mcp.json");
18299
+ const provisionMcpPath = join43(agentProvisionDir, ".mcp.json");
18300
+ const projectMcpPath = join43(projectDir, ".mcp.json");
18042
18301
  let mcpConfig = { mcpServers: {} };
18043
18302
  try {
18044
- mcpConfig = JSON.parse(readFileSync33(provisionMcpPath, "utf-8"));
18303
+ mcpConfig = JSON.parse(readFileSync34(provisionMcpPath, "utf-8"));
18045
18304
  if (!mcpConfig.mcpServers) mcpConfig.mcpServers = {};
18046
18305
  } catch {
18047
18306
  }
18048
- const localDirectChatChannel = join42(homedir18(), ".augmented", "_mcp", "direct-chat-channel.js");
18307
+ const localDirectChatChannel = join43(homedir18(), ".augmented", "_mcp", "direct-chat-channel.js");
18049
18308
  const directChatTeamSettings = refreshData.team?.settings;
18050
18309
  const directChatTz = (() => {
18051
18310
  const tz = directChatTeamSettings?.["timezone"];
@@ -18071,7 +18330,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
18071
18330
  // ~/.augmented/<codeName>/.current-turn-initiator.json. Note getAgentDir
18072
18331
  // returns the agent root (NOT the /provision subdir `agentDir` points at),
18073
18332
  // so it byte-matches the broker readers' path.
18074
- AGT_TURN_INITIATOR_FILE: join42(
18333
+ AGT_TURN_INITIATOR_FILE: join43(
18075
18334
  frameworkAdapter.getAgentDir(agent.code_name),
18076
18335
  ".current-turn-initiator.json"
18077
18336
  )
@@ -18091,7 +18350,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
18091
18350
  log(`Channel credentials written for '${agent.code_name}/direct-chat'`);
18092
18351
  }
18093
18352
  }
18094
- const staleChannelsPath = join42(projectDir, ".mcp-channels.json");
18353
+ const staleChannelsPath = join43(projectDir, ".mcp-channels.json");
18095
18354
  if (existsSync19(staleChannelsPath)) {
18096
18355
  try {
18097
18356
  rmSync8(staleChannelsPath, { force: true });
@@ -18204,7 +18463,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
18204
18463
  }
18205
18464
  if (hostFlagStore().getBoolean("connectivity-probe")) {
18206
18465
  try {
18207
- const probeProjectDir = join42(homedir18(), ".augmented", agent.code_name, "project");
18466
+ const probeProjectDir = join43(homedir18(), ".augmented", agent.code_name, "project");
18208
18467
  let probeSet = integrations;
18209
18468
  const fetchQuarantined = async () => {
18210
18469
  const quarantined = await api.post("/host/agent-integrations/quarantined", { agent_id: agent.agent_id });
@@ -18264,7 +18523,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
18264
18523
  const forceDue = attemptsLeft > 0;
18265
18524
  let probeRan = false;
18266
18525
  try {
18267
- const probeProjectDir = join42(homedir18(), ".augmented", agent.code_name, "project");
18526
+ const probeProjectDir = join43(homedir18(), ".augmented", agent.code_name, "project");
18268
18527
  probeRan = await runAgentSessionToolBindProbes(agent, integrations, probeProjectDir, { forceDue });
18269
18528
  } catch (err) {
18270
18529
  log(`Session-tool-bind probe failed for '${agent.code_name}': ${err.message}`);
@@ -18341,11 +18600,11 @@ async function processAgent(agent, agentStates, managedToolkits) {
18341
18600
  const intHash = computeIntegrationsHash(integrations);
18342
18601
  const prevIntHash = agentState.knownIntegrationHashes.get(agent.agent_id);
18343
18602
  if (intHash !== prevIntHash) {
18344
- const projectDir = join42(homedir18(), ".augmented", agent.code_name, "project");
18345
- const envIntPath = join42(projectDir, ".env.integrations");
18603
+ const projectDir = join43(homedir18(), ".augmented", agent.code_name, "project");
18604
+ const envIntPath = join43(projectDir, ".env.integrations");
18346
18605
  let preWriteEnv;
18347
18606
  try {
18348
- preWriteEnv = readFileSync33(envIntPath, "utf-8");
18607
+ preWriteEnv = readFileSync34(envIntPath, "utf-8");
18349
18608
  } catch {
18350
18609
  preWriteEnv = void 0;
18351
18610
  }
@@ -18364,9 +18623,9 @@ async function processAgent(agent, agentStates, managedToolkits) {
18364
18623
  }
18365
18624
  if (fw === "claude-code" && isSessionHealthy(agent.code_name)) {
18366
18625
  try {
18367
- const projectMcpPath = join42(projectDir, ".mcp.json");
18368
- const postWriteEnv = readFileSync33(envIntPath, "utf-8");
18369
- const mcpContent = readFileSync33(projectMcpPath, "utf-8");
18626
+ const projectMcpPath = join43(projectDir, ".mcp.json");
18627
+ const postWriteEnv = readFileSync34(envIntPath, "utf-8");
18628
+ const mcpContent = readFileSync34(projectMcpPath, "utf-8");
18370
18629
  const changedVars = diffEnvIntegrations(preWriteEnv, postWriteEnv);
18371
18630
  const mcpJsonForReap = JSON.parse(mcpContent);
18372
18631
  const affectedServerKeys = findMcpServersUsingVars(mcpJsonForReap, changedVars);
@@ -18669,12 +18928,12 @@ async function processAgent(agent, agentStates, managedToolkits) {
18669
18928
  const frameworkId2 = frameworkAdapter.id;
18670
18929
  const candidateSkillDirs = [
18671
18930
  // Claude Code — framework runtime tree
18672
- join42(homedir19(), ".augmented", agent.code_name, "skills"),
18931
+ join43(homedir19(), ".augmented", agent.code_name, "skills"),
18673
18932
  // Claude Code — project tree
18674
- join42(homedir19(), ".augmented", agent.code_name, "project", ".claude", "skills"),
18933
+ join43(homedir19(), ".augmented", agent.code_name, "project", ".claude", "skills"),
18675
18934
  // Defensive: legacy provision-side path, not currently an
18676
18935
  // install target but cheap to sweep.
18677
- join42(agentDir, ".claude", "skills")
18936
+ join43(agentDir, ".claude", "skills")
18678
18937
  ];
18679
18938
  const existingDirs = candidateSkillDirs.filter((d) => existsSync19(d));
18680
18939
  const discoveredEntries = /* @__PURE__ */ new Set();
@@ -18717,7 +18976,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
18717
18976
  const sharedSkillsPayload = refreshAny.shared_skills;
18718
18977
  const desiredResolved = globalSkillsPayload !== void 0 || sharedSkillsPayload !== void 0;
18719
18978
  const manifestPath = managedSkillManifestPath(
18720
- join42(homedir18(), ".augmented", agent.code_name)
18979
+ join43(homedir18(), ".augmented", agent.code_name)
18721
18980
  );
18722
18981
  const prevIds = /* @__PURE__ */ new Set([
18723
18982
  ...agentState.knownGlobalSkillIds.get(agent.agent_id) ?? /* @__PURE__ */ new Set(),
@@ -18737,15 +18996,15 @@ async function processAgent(agent, agentStates, managedToolkits) {
18737
18996
  }
18738
18997
  if (plan.removes.length) {
18739
18998
  const globalSkillDirs = [
18740
- join42(homedir18(), ".augmented", agent.code_name, "skills"),
18741
- join42(homedir18(), ".augmented", agent.code_name, "project", ".claude", "skills"),
18742
- join42(agentDir, ".claude", "skills")
18999
+ join43(homedir18(), ".augmented", agent.code_name, "skills"),
19000
+ join43(homedir18(), ".augmented", agent.code_name, "project", ".claude", "skills"),
19001
+ join43(agentDir, ".claude", "skills")
18743
19002
  ];
18744
19003
  for (const id of plan.removes) {
18745
19004
  let prunedAny = false;
18746
19005
  for (const dir of globalSkillDirs) {
18747
- const p = join42(dir, id);
18748
- if (existsSync19(p) && existsSync19(join42(p, "SKILL.md"))) {
19006
+ const p = join43(dir, id);
19007
+ if (existsSync19(p) && existsSync19(join43(p, "SKILL.md"))) {
18749
19008
  rmSync8(p, { recursive: true, force: true });
18750
19009
  prunedAny = true;
18751
19010
  }
@@ -19001,8 +19260,8 @@ async function processAgent(agent, agentStates, managedToolkits) {
19001
19260
  const sess = getSessionState(agent.code_name);
19002
19261
  let mcpJsonParsed = null;
19003
19262
  try {
19004
- const mcpPath = join42(getProjectDir(agent.code_name), ".mcp.json");
19005
- mcpJsonParsed = JSON.parse(readFileSync33(mcpPath, "utf-8"));
19263
+ const mcpPath = join43(getProjectDir(agent.code_name), ".mcp.json");
19264
+ mcpJsonParsed = JSON.parse(readFileSync34(mcpPath, "utf-8"));
19006
19265
  } catch {
19007
19266
  }
19008
19267
  const computerUseIsolated = isolationMode(agent.code_name) === "docker";
@@ -19494,7 +19753,7 @@ Retried to the limit after repeated stalls \u2014 needs a look.`).catch(() => {
19494
19753
  if (trackedFiles.length > 0 && existsSync19(agentDir)) {
19495
19754
  const hashes = /* @__PURE__ */ new Map();
19496
19755
  for (const file of trackedFiles) {
19497
- const h = hashFile(join42(agentDir, file));
19756
+ const h = hashFile(join43(agentDir, file));
19498
19757
  if (h) hashes.set(file, h);
19499
19758
  }
19500
19759
  agentState.writtenHashes.set(agent.agent_id, hashes);
@@ -19509,7 +19768,7 @@ Retried to the limit after repeated stalls \u2014 needs a look.`).catch(() => {
19509
19768
  refreshData.agent.onboarding_state
19510
19769
  );
19511
19770
  const obStep = obState.step;
19512
- const markerPath = join42(homedir18(), ".augmented", agent.code_name, "onboarding-drive.json");
19771
+ const markerPath = join43(homedir18(), ".augmented", agent.code_name, "onboarding-drive.json");
19513
19772
  const marker = readOnboardingDriveMarker(markerPath);
19514
19773
  const obContactRaw = refreshData.agent.manager_last_contacted_at;
19515
19774
  const obContact = typeof obContactRaw === "string" && obContactRaw ? obContactRaw : null;
@@ -19624,7 +19883,7 @@ async function ensureOpencodeRuntime(agent, refreshData, agentTimezone) {
19624
19883
  }
19625
19884
  stopOpencodeSlackIngest(codeName, log);
19626
19885
  stopOpencodeTelegramIngest(codeName, log);
19627
- const opencodeProjectDir = join42(getFramework("opencode").getAgentDir(codeName), "provision");
19886
+ const opencodeProjectDir = join43(getFramework("opencode").getAgentDir(codeName), "provision");
19628
19887
  const serveEnv = {
19629
19888
  AGT_HOST: requireHost(),
19630
19889
  AGT_API_KEY: getApiKey() ?? void 0,
@@ -19684,8 +19943,8 @@ async function ensurePersistentSessionUnchecked(agent, tasks, boardItems, refres
19684
19943
  });
19685
19944
  }
19686
19945
  const projectDir = getProjectDir(codeName);
19687
- const mcpConfigPath = join42(projectDir, ".mcp.json");
19688
- const claudeMdPath = join42(projectDir, "CLAUDE.md");
19946
+ const mcpConfigPath = join43(projectDir, ".mcp.json");
19947
+ const claudeMdPath = join43(projectDir, "CLAUDE.md");
19689
19948
  if (restartBreaker.isTripped(codeName)) {
19690
19949
  const trip = restartBreaker.getTrip(codeName);
19691
19950
  return {
@@ -20549,7 +20808,7 @@ async function handleRestartDoorbell(agentId, requestedAt, restartReason) {
20549
20808
  try {
20550
20809
  const freshId = rotateSessionForWedge(codeName);
20551
20810
  consecutiveWedgeCycles.delete(codeName);
20552
- const { parkPendingInbound: parkForRestart } = await import("../responsiveness-probe-6NWZAXIZ.js");
20811
+ const { parkPendingInbound: parkForRestart } = await import("../responsiveness-probe-DXPEIUH6.js");
20553
20812
  const { parked, deadLettered } = parkForRestart(codeName, /* @__PURE__ */ new Date());
20554
20813
  const parkNote = parked > 0 ? `, ${parked} inbound parked` : "";
20555
20814
  const deadNote = deadLettered > 0 ? `, ${deadLettered} undeliverable dead-lettered` : "";
@@ -20592,7 +20851,7 @@ async function handleRestartDoorbell(agentId, requestedAt, restartReason) {
20592
20851
  void api.post("/host/restart-ack", { host_id: hostId, agent_id: agentId, restart_requested_at: requestedAt }).catch((err) => log(`[restart-lane] ack failed for '${codeName}': ${err.message}`));
20593
20852
  void (async () => {
20594
20853
  try {
20595
- const { collectDiagnostics } = await import("../persistent-session-4PP3ON7H.js");
20854
+ const { collectDiagnostics } = await import("../persistent-session-K4DLZ7KF.js");
20596
20855
  await api.post("/host/heartbeat", {
20597
20856
  host_id: hostId,
20598
20857
  agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor)
@@ -20643,7 +20902,7 @@ async function respawnAgentAfterMcpStop(codeName, reason) {
20643
20902
  }
20644
20903
  try {
20645
20904
  const hostId = await getHostId();
20646
- const { collectDiagnostics } = await import("../persistent-session-4PP3ON7H.js");
20905
+ const { collectDiagnostics } = await import("../persistent-session-K4DLZ7KF.js");
20647
20906
  await api.post("/host/heartbeat", {
20648
20907
  host_id: hostId,
20649
20908
  agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor)
@@ -21302,8 +21561,19 @@ async function processClaudePairSessions(agents) {
21302
21561
  spawnPairSession,
21303
21562
  killPairSession,
21304
21563
  pairTmuxSession,
21305
- finalizeClaudePairOnboarding
21306
- } = await import("../claude-pair-runtime-DDSYAHQW.js");
21564
+ finalizeClaudePairOnboarding,
21565
+ // ENG-10862: the failure vocabulary lives beside the loop that produces it,
21566
+ // so the code the console stores and the message the operator reads cannot
21567
+ // drift from the reason finalize actually returned.
21568
+ PAIR_FINALIZE_ERROR_CODES,
21569
+ describePairFinalizeFailure,
21570
+ // ENG-10862: the last-chance re-read before a failure is reported.
21571
+ confirmPairFailure,
21572
+ // ENG-10862: the pre-submit mtime baseline. Taken here because finalize
21573
+ // cannot take it for itself — by the time it runs, the write it is looking
21574
+ // for may already have happened.
21575
+ snapshotPairConfig
21576
+ } = await import("../claude-pair-runtime-AW4N6NEE.js");
21307
21577
  for (const pairId of pendingResp.cancelled_pair_ids ?? []) {
21308
21578
  log(`[claude-pair] sweeping orphan tmux session for pair ${pairId.slice(0, 8)}`);
21309
21579
  const killed = await killPairSession(pairTmuxSession(pairId));
@@ -21323,7 +21593,8 @@ async function processClaudePairSessions(agents) {
21323
21593
  async function reportAndCleanup(pairId, body) {
21324
21594
  await api.post("/host/claude-pair/result", { pair_id: pairId, ...body });
21325
21595
  if (typeof body.status === "string" && TERMINAL.has(body.status)) {
21326
- if (body.status === "success") {
21596
+ const isOnboardingFailure = typeof body.error_code === "string" && body.error_code.startsWith("onboarding_");
21597
+ if (body.status === "success" || isOnboardingFailure) {
21327
21598
  await new Promise((r) => setTimeout(r, 3e3));
21328
21599
  }
21329
21600
  const killed = await killPairSession(pairTmuxSession(pairId));
@@ -21375,16 +21646,50 @@ async function processClaudePairSessions(agents) {
21375
21646
  }
21376
21647
  } else if (session.status === "code_submitted" && session.code) {
21377
21648
  log(`[claude-pair] submitting code (pair ${session.pair_id.slice(0, 8)})`);
21649
+ const configBaseline = snapshotPairConfig();
21378
21650
  const result = await submitClaudePairCode({
21379
21651
  session: pairSession,
21380
21652
  code: session.code
21381
21653
  });
21382
21654
  if (result.kind === "success") {
21383
- const finalize = await finalizeClaudePairOnboarding(pairSession, log);
21384
- if (!finalize.finalized) {
21385
- log(`[claude-pair] WARN: ~/.claude.json was not updated during onboarding (pair ${session.pair_id.slice(0, 8)}) \u2014 first agent launch may show the login picker`);
21655
+ const finalize = await finalizeClaudePairOnboarding(pairSession, log, {
21656
+ baseline: configBaseline
21657
+ });
21658
+ const pairShort = session.pair_id.slice(0, 8);
21659
+ const confirmed = finalize.finalized ? "landed-after-all" : await confirmPairFailure({
21660
+ configPath: finalize.configPath,
21661
+ sinceMtimeMs: configBaseline.mtimeMs,
21662
+ log
21663
+ });
21664
+ if (!finalize.finalized && confirmed === "confirmed") {
21665
+ const reason = finalize.reason ?? "not-flushed";
21666
+ const errorCode = PAIR_FINALIZE_ERROR_CODES[reason];
21667
+ log(
21668
+ `[claude-pair] onboarding did NOT persist (pair ${pairShort}) reason=${reason} code=${errorCode} iterations=${finalize.iterations} graceWaits=${finalize.graceWaits} consumerTerms=${finalize.counts.consumerTerms} dialogEnter=${finalize.counts.dialogEnter} noMatch=${finalize.counts.noMatch} \u2014 reporting the pairing as FAILED`
21669
+ );
21670
+ await reportAndCleanup(session.pair_id, {
21671
+ status: "failure",
21672
+ error_code: errorCode,
21673
+ // The path finalize actually watched, returned by it rather than
21674
+ // recomputed here — two copies of that rule is how the operator
21675
+ // ends up reading about a file the flow never looked at.
21676
+ error_message: describePairFinalizeFailure(reason, finalize.configPath),
21677
+ // AC5: the loop's own accounting, so "do real pairings need more
21678
+ // than 10 dismissals?" stops being unanswerable. Counts only —
21679
+ // never pane text, which carries `Logged in as <email>`. These
21680
+ // are NOT stored on the pair row (no column, by decision); the
21681
+ // route forwards them into the alert payload, which is jsonb.
21682
+ finalize_iterations: finalize.iterations,
21683
+ finalize_grace_waits: finalize.graceWaits,
21684
+ finalize_dialog_counts: finalize.counts
21685
+ });
21686
+ } else {
21687
+ const lateness = finalize.finalized ? "" : ` (late: finalize said ${finalize.reason}, config landed during the confirm window)`;
21688
+ log(
21689
+ `[claude-pair] onboarding persisted (pair ${pairShort}) iterations=${finalize.iterations} graceWaits=${finalize.graceWaits} consumerTerms=${finalize.counts.consumerTerms} dialogEnter=${finalize.counts.dialogEnter} noMatch=${finalize.counts.noMatch}${lateness}`
21690
+ );
21691
+ await reportAndCleanup(session.pair_id, { status: "success" });
21386
21692
  }
21387
- await reportAndCleanup(session.pair_id, { status: "success" });
21388
21693
  } else if (result.kind === "failure") {
21389
21694
  await reportAndCleanup(session.pair_id, {
21390
21695
  status: "failure",
@@ -21535,17 +21840,17 @@ var lastLocalFileHash = /* @__PURE__ */ new Map();
21535
21840
  var lastMemoriesBody = /* @__PURE__ */ new Map();
21536
21841
  var memoryManifests = /* @__PURE__ */ new Map();
21537
21842
  function memoryRetirementDir(configDir, codeName) {
21538
- return join42(configDir, "_memory-retirement", codeName);
21843
+ return join43(configDir, "_memory-retirement", codeName);
21539
21844
  }
21540
21845
  function memoryManifestPath(configDir, codeName) {
21541
- return join42(memoryRetirementDir(configDir, codeName), "manifest.json");
21846
+ return join43(memoryRetirementDir(configDir, codeName), "manifest.json");
21542
21847
  }
21543
21848
  function loadMemoryManifest(agentId, configDir, codeName) {
21544
21849
  const cached = memoryManifests.get(agentId);
21545
21850
  if (cached) return cached;
21546
21851
  let manifest = {};
21547
21852
  try {
21548
- const raw = readFileSync33(memoryManifestPath(configDir, codeName), "utf-8");
21853
+ const raw = readFileSync34(memoryManifestPath(configDir, codeName), "utf-8");
21549
21854
  const parsed = JSON.parse(raw);
21550
21855
  if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
21551
21856
  for (const [name, entry] of Object.entries(parsed)) {
@@ -21573,7 +21878,7 @@ function saveMemoryManifest(agentId, configDir, codeName) {
21573
21878
  }
21574
21879
  }
21575
21880
  function retiredMemoryDir(configDir, codeName) {
21576
- return join42(memoryRetirementDir(configDir, codeName), "retired");
21881
+ return join43(memoryRetirementDir(configDir, codeName), "retired");
21577
21882
  }
21578
21883
  var RETIRED_MEMORY_TTL_MS = 30 * 24 * 60 * 60 * 1e3;
21579
21884
  var lastRetirementReport = /* @__PURE__ */ new Map();
@@ -21652,7 +21957,7 @@ function applyMemoryTombstones(opts) {
21652
21957
  log2(`[memory-retire] ${agent.code_name}: KEPT '${tomb.name}' \u2014 no write record, not ours to remove`);
21653
21958
  continue;
21654
21959
  }
21655
- const filePath = join42(memoryDir, entry.file);
21960
+ const filePath = join43(memoryDir, entry.file);
21656
21961
  if (!existsSync19(filePath)) {
21657
21962
  outcomes.already_gone++;
21658
21963
  delete manifest[tomb.name];
@@ -21660,7 +21965,7 @@ function applyMemoryTombstones(opts) {
21660
21965
  continue;
21661
21966
  }
21662
21967
  try {
21663
- const actual = createHash20("sha256").update(readFileSync33(filePath)).digest("hex");
21968
+ const actual = createHash20("sha256").update(readFileSync34(filePath)).digest("hex");
21664
21969
  if (actual !== entry.sha) {
21665
21970
  outcomes.kept_modified++;
21666
21971
  outcomes.unapplied.push({ name: tomb.name, reason: "kept_modified" });
@@ -21672,9 +21977,9 @@ function applyMemoryTombstones(opts) {
21672
21977
  const destDir = retiredMemoryDir(configDir, agent.code_name);
21673
21978
  mkdirSync15(destDir, { recursive: true });
21674
21979
  const stamp = Date.now();
21675
- let dest = join42(destDir, `${entry.file}.${stamp}.retired`);
21980
+ let dest = join43(destDir, `${entry.file}.${stamp}.retired`);
21676
21981
  for (let n = 1; existsSync19(dest); n++) {
21677
- dest = join42(destDir, `${entry.file}.${stamp}-${n}.retired`);
21982
+ dest = join43(destDir, `${entry.file}.${stamp}-${n}.retired`);
21678
21983
  }
21679
21984
  renameSync11(filePath, dest);
21680
21985
  try {
@@ -21713,7 +22018,7 @@ function reapRetiredMemories(configDir, codeName, log2) {
21713
22018
  try {
21714
22019
  for (const file of readdirSync12(dir)) {
21715
22020
  if (!file.endsWith(".retired")) continue;
21716
- const path = join42(dir, file);
22021
+ const path = join43(dir, file);
21717
22022
  try {
21718
22023
  if (statSync13(path).mtimeMs < cutoff) {
21719
22024
  unlinkSync6(path);
@@ -21728,8 +22033,8 @@ function reapRetiredMemories(configDir, codeName, log2) {
21728
22033
  if (reaped > 0) log2(`[memory-retire] ${codeName}: reaped ${reaped} retired memory file(s) past TTL`);
21729
22034
  }
21730
22035
  async function syncMemories(agent, configDir, log2) {
21731
- const projectDir = join42(configDir, agent.code_name, "project");
21732
- const memoryDir = join42(projectDir, "memory");
22036
+ const projectDir = join43(configDir, agent.code_name, "project");
22037
+ const memoryDir = join43(projectDir, "memory");
21733
22038
  const isFreshSync = pendingFreshMemorySync.has(agent.agent_id);
21734
22039
  if (isFreshSync) {
21735
22040
  log2(`[memory-sync] Fresh-sync requested for '${agent.code_name}' \u2014 pulling DB first`);
@@ -21760,7 +22065,7 @@ async function syncMemories(agent, configDir, log2) {
21760
22065
  for (const file of readdirSync12(memoryDir)) {
21761
22066
  if (!file.endsWith(".md")) continue;
21762
22067
  try {
21763
- const raw = readFileSync33(join42(memoryDir, file), "utf-8");
22068
+ const raw = readFileSync34(join43(memoryDir, file), "utf-8");
21764
22069
  const fileHash = createHash20("sha256").update(raw).digest("hex").slice(0, 16);
21765
22070
  currentHashes.set(file, fileHash);
21766
22071
  if (prevHashes.get(file) === fileHash) continue;
@@ -21785,7 +22090,7 @@ async function syncMemories(agent, configDir, log2) {
21785
22090
  } catch (err) {
21786
22091
  for (const mem of changedMemories) {
21787
22092
  for (const [file] of currentHashes) {
21788
- const parsed = parseMemoryFile(readFileSync33(join42(memoryDir, file), "utf-8"), file.replace(/\.md$/, ""));
22093
+ const parsed = parseMemoryFile(readFileSync34(join43(memoryDir, file), "utf-8"), file.replace(/\.md$/, ""));
21789
22094
  if (parsed?.name === mem.name) currentHashes.delete(file);
21790
22095
  }
21791
22096
  }
@@ -21866,7 +22171,7 @@ async function downloadMemories(agent, memoryDir, log2, { force, configDir }) {
21866
22171
  // Per-agent, not host-wide: memories are agent-private, so a shared
21867
22172
  // store would buy almost no dedupe while exposing one agent's content
21868
22173
  // to every other agent on the host. See memory-cache.ts's header.
21869
- cacheDir: join42(configDir, agent.code_name, "_memory_bodies"),
22174
+ cacheDir: join43(configDir, agent.code_name, "_memory_bodies"),
21870
22175
  fetchContents: async (hashes) => {
21871
22176
  const res = await api.post(
21872
22177
  "/host/memories/contents",
@@ -21904,7 +22209,7 @@ async function downloadMemories(agent, memoryDir, log2, { force, configDir }) {
21904
22209
  const rawSlug = mem.name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)/g, "").slice(0, 60);
21905
22210
  const slug = rawSlug || `memory-${i}`;
21906
22211
  const fileName = `${slug}.md`;
21907
- const filePath = join42(memoryDir, fileName);
22212
+ const filePath = join43(memoryDir, fileName);
21908
22213
  const desired = `---
21909
22214
  name: ${JSON.stringify(mem.name)}
21910
22215
  type: ${mem.type}
@@ -21924,7 +22229,7 @@ ${mem.content}
21924
22229
  if (existsSync19(filePath)) {
21925
22230
  let existing = "";
21926
22231
  try {
21927
- existing = readFileSync33(filePath, "utf-8");
22232
+ existing = readFileSync34(filePath, "utf-8");
21928
22233
  } catch {
21929
22234
  }
21930
22235
  if (existing === desired) {
@@ -22304,7 +22609,7 @@ function startManager(opts) {
22304
22609
  try {
22305
22610
  const stateFile = getStateFile();
22306
22611
  if (existsSync19(stateFile)) {
22307
- const raw = readFileSync33(stateFile, "utf-8");
22612
+ const raw = readFileSync34(stateFile, "utf-8");
22308
22613
  const parsed = JSON.parse(raw);
22309
22614
  if (Array.isArray(parsed.agents)) {
22310
22615
  state8.agents = parsed.agents;
@@ -22331,7 +22636,7 @@ function startManager(opts) {
22331
22636
  log(`[startup] state rehydration failed (continuing with empty state): ${err.message}`);
22332
22637
  }
22333
22638
  log(
22334
- `[startup] worker pid=${process.pid} ppid=${process.ppid} node=${process.version} log=${join42(homedir18(), ".augmented", "manager.log")}`
22639
+ `[startup] worker pid=${process.pid} ppid=${process.ppid} node=${process.version} log=${join43(homedir18(), ".augmented", "manager.log")}`
22335
22640
  );
22336
22641
  deployMcpAssets();
22337
22642
  reapOrphanChannelMcps({ log });
@@ -22360,7 +22665,7 @@ async function reapOrphanedClaudePids() {
22360
22665
  const looksLikeClaude = (pid) => {
22361
22666
  if (process.platform !== "linux") return true;
22362
22667
  try {
22363
- const comm = readFileSync33(`/proc/${pid}/comm`, "utf-8").trim().toLowerCase();
22668
+ const comm = readFileSync34(`/proc/${pid}/comm`, "utf-8").trim().toLowerCase();
22364
22669
  return comm.includes("claude");
22365
22670
  } catch {
22366
22671
  return false;
@@ -22457,14 +22762,14 @@ function restartRunningChannelMcps(basenames) {
22457
22762
  }
22458
22763
  }
22459
22764
  function deployMcpAssets() {
22460
- const targetDir = join42(homedir18(), ".augmented", "_mcp");
22765
+ const targetDir = join43(homedir18(), ".augmented", "_mcp");
22461
22766
  mkdirSync15(targetDir, { recursive: true });
22462
22767
  const moduleDir = dirname11(fileURLToPath2(import.meta.url));
22463
22768
  let mcpSourceDir = "";
22464
22769
  let dir = moduleDir;
22465
22770
  for (let i = 0; i < 6; i++) {
22466
- const candidate = join42(dir, "dist", "mcp");
22467
- if (existsSync19(join42(candidate, "index.js"))) {
22771
+ const candidate = join43(dir, "dist", "mcp");
22772
+ if (existsSync19(join43(candidate, "index.js"))) {
22468
22773
  mcpSourceDir = candidate;
22469
22774
  break;
22470
22775
  }
@@ -22482,7 +22787,7 @@ function deployMcpAssets() {
22482
22787
  const fileHash = (p) => {
22483
22788
  try {
22484
22789
  if (!existsSync19(p)) return null;
22485
- return createHash20("sha256").update(readFileSync33(p)).digest("hex");
22790
+ return createHash20("sha256").update(readFileSync34(p)).digest("hex");
22486
22791
  } catch {
22487
22792
  return null;
22488
22793
  }
@@ -22564,8 +22869,8 @@ function deployMcpAssets() {
22564
22869
  // natural session restart.
22565
22870
  "computer-use-proxy.js"
22566
22871
  ]) {
22567
- const src = join42(mcpSourceDir, file);
22568
- const dst = join42(targetDir, file);
22872
+ const src = join43(mcpSourceDir, file);
22873
+ const dst = join43(targetDir, file);
22569
22874
  if (!existsSync19(src)) continue;
22570
22875
  attemptedFiles.push(file);
22571
22876
  const before = fileHash(dst);
@@ -22591,16 +22896,16 @@ function deployMcpAssets() {
22591
22896
  log(`[manager] Bundle(s) updated: ${changedBasenames.join(", ")} \u2014 signalling running instances to restart`);
22592
22897
  restartRunningChannelMcps(changedBasenames);
22593
22898
  }
22594
- const localMcpPath = join42(targetDir, "index.js");
22899
+ const localMcpPath = join43(targetDir, "index.js");
22595
22900
  try {
22596
- const agentsDir = join42(homedir18(), ".augmented", "agents");
22901
+ const agentsDir = join43(homedir18(), ".augmented", "agents");
22597
22902
  if (existsSync19(agentsDir)) {
22598
22903
  for (const entry of readdirSync12(agentsDir, { withFileTypes: true })) {
22599
22904
  if (!entry.isDirectory()) continue;
22600
22905
  for (const subdir of ["provision", "project"]) {
22601
- const mcpJsonPath = join42(agentsDir, entry.name, subdir, ".mcp.json");
22906
+ const mcpJsonPath = join43(agentsDir, entry.name, subdir, ".mcp.json");
22602
22907
  try {
22603
- const raw = readFileSync33(mcpJsonPath, "utf-8");
22908
+ const raw = readFileSync34(mcpJsonPath, "utf-8");
22604
22909
  if (!raw.includes("@integrity-labs/augmented-mcp")) continue;
22605
22910
  const mcpConfig = JSON.parse(raw);
22606
22911
  const augServer = mcpConfig.mcpServers?.["augmented"];