@integrity-labs/agt-cli 0.28.1005 → 0.28.1007

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 (32) hide show
  1. package/dist/bin/agt.js +6 -5
  2. package/dist/bin/agt.js.map +1 -1
  3. package/dist/chunk-EL5MWGGH.js +160 -0
  4. package/dist/chunk-EL5MWGGH.js.map +1 -0
  5. package/dist/{chunk-6U4NB3LJ.js → chunk-FLJNRC3D.js} +71 -9
  6. package/dist/chunk-FLJNRC3D.js.map +1 -0
  7. package/dist/{chunk-TGTUE7Y2.js → chunk-SQX4ZGD5.js} +73 -8
  8. package/dist/chunk-SQX4ZGD5.js.map +1 -0
  9. package/dist/{chunk-DVSYT4MU.js → chunk-XWMUQR65.js} +52 -1
  10. package/dist/{chunk-DVSYT4MU.js.map → chunk-XWMUQR65.js.map} +1 -1
  11. package/dist/{claude-code-updater-45MB2AXE.js → claude-code-updater-NEJCTT7S.js} +7 -3
  12. package/dist/claude-code-updater-NEJCTT7S.js.map +1 -0
  13. package/dist/{claude-pair-runtime-DDSYAHQW.js → claude-pair-runtime-X27QVAXL.js} +172 -18
  14. package/dist/claude-pair-runtime-X27QVAXL.js.map +1 -0
  15. package/dist/lib/manager-worker.js +547 -227
  16. package/dist/lib/manager-worker.js.map +1 -1
  17. package/dist/mcp/direct-chat-channel.js +57 -2
  18. package/dist/mcp/index.js +51 -0
  19. package/dist/mcp/origami.js +51 -0
  20. package/dist/mcp/slack-channel.js +57 -2
  21. package/dist/mcp/telegram-channel.js +57 -2
  22. package/dist/{persistent-session-4PP3ON7H.js → persistent-session-5KWYODZB.js} +6 -3
  23. package/dist/{responsiveness-probe-6NWZAXIZ.js → responsiveness-probe-J2DYGC7T.js} +4 -3
  24. package/dist/{responsiveness-probe-6NWZAXIZ.js.map → responsiveness-probe-J2DYGC7T.js.map} +1 -1
  25. package/dist/{session-auth-dead-2V2BOXAG.js → session-auth-dead-4SE5Q7MU.js} +2 -2
  26. package/package.json +1 -1
  27. package/dist/chunk-6U4NB3LJ.js.map +0 -1
  28. package/dist/chunk-TGTUE7Y2.js.map +0 -1
  29. package/dist/claude-code-updater-45MB2AXE.js.map +0 -1
  30. package/dist/claude-pair-runtime-DDSYAHQW.js.map +0 -1
  31. /package/dist/{persistent-session-4PP3ON7H.js.map → persistent-session-5KWYODZB.js.map} +0 -0
  32. /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-FLJNRC3D.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-SQX4ZGD5.js";
145
146
  import {
146
147
  ACCOUNT_ENFORCEMENT_MARKER_FILENAME,
147
148
  AnchorSessionClient,
@@ -240,16 +241,23 @@ 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
247
248
  } from "../chunk-XWVM4KPK.js";
249
+ import {
250
+ CLAUDE_CONFIG_DIR_ENV,
251
+ claudeConfigDirFor,
252
+ claudeConfigDirIsReady,
253
+ effectiveClaudeJsonPath,
254
+ seedClaudeConfigFromLegacy
255
+ } from "../chunk-EL5MWGGH.js";
248
256
  import "../chunk-DGUM43GV.js";
249
257
 
250
258
  // src/lib/manager-worker.ts
251
259
  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";
260
+ 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
261
 
254
262
  // src/lib/atomic-file-replace.ts
255
263
  import { copyFileSync, renameSync, unlinkSync } from "fs";
@@ -276,7 +284,7 @@ function defaultUnique() {
276
284
  // src/lib/manager-worker.ts
277
285
  import { execFileSync as syncExecFile } from "child_process";
278
286
  import { join as join42, dirname as dirname11, delimiter as pathDelimiter } from "path";
279
- import { homedir as homedir18 } from "os";
287
+ import { homedir as homedir17 } from "os";
280
288
  import { fileURLToPath as fileURLToPath2 } from "url";
281
289
 
282
290
  // ../../packages/core/dist/provisioning/channel-policy-env.js
@@ -1053,9 +1061,157 @@ function clearOnboardingDriveMarker(path) {
1053
1061
  }
1054
1062
  }
1055
1063
 
1056
- // src/lib/channel-quarantine.ts
1064
+ // src/lib/channel-auto-resume.ts
1057
1065
  import { readFileSync as readFileSync3 } from "fs";
1058
1066
  import { join as join3 } from "path";
1067
+ var AUTO_RESUME_BASE_MS = 2 * 60 * 6e4;
1068
+ var AUTO_RESUME_MAX_MS = 24 * 60 * 6e4;
1069
+ var AUTO_RESUME_MAX_ATTEMPTS = 5;
1070
+ var QUARANTINE_DWELL_FLOOR_MS = 18e4;
1071
+ var AUTO_RESUME_SUCCESS_GRACE_MS = 2 * (DEAD_CHANNEL_MS + QUARANTINE_DWELL_FLOOR_MS);
1072
+ function defaultResumeHistoryPath(configDir) {
1073
+ return join3(configDir, "channel-quarantine-resumes.json");
1074
+ }
1075
+ function isResumeFile(value) {
1076
+ if (!value || typeof value !== "object" || Array.isArray(value)) return false;
1077
+ for (const forAgent of Object.values(value)) {
1078
+ if (!forAgent || typeof forAgent !== "object" || Array.isArray(forAgent)) return false;
1079
+ for (const entry of Object.values(forAgent)) {
1080
+ if (!entry || typeof entry !== "object") return false;
1081
+ const e = entry;
1082
+ if (e.gaveUpLogged !== void 0 && typeof e.gaveUpLogged !== "boolean") return false;
1083
+ const attempts = e.attempts;
1084
+ const lastAttemptAt = e.lastAttemptAt;
1085
+ if (typeof attempts !== "number" || !Number.isSafeInteger(attempts) || attempts < 0 || typeof lastAttemptAt !== "number" || !Number.isSafeInteger(lastAttemptAt) || lastAttemptAt < 0) {
1086
+ return false;
1087
+ }
1088
+ }
1089
+ }
1090
+ return true;
1091
+ }
1092
+ var ChannelResumeHistoryStore = class {
1093
+ path;
1094
+ cache = null;
1095
+ constructor(path) {
1096
+ this.path = path;
1097
+ }
1098
+ load() {
1099
+ if (this.cache) return this.cache;
1100
+ try {
1101
+ const parsed = JSON.parse(readFileSync3(this.path, "utf-8"));
1102
+ this.cache = isResumeFile(parsed) ? parsed : {};
1103
+ } catch {
1104
+ this.cache = {};
1105
+ }
1106
+ return this.cache;
1107
+ }
1108
+ persist() {
1109
+ atomicWriteFileSync(this.path, JSON.stringify(this.cache ?? {}, null, 2));
1110
+ }
1111
+ get(codeName, serverKey) {
1112
+ return this.load()[codeName]?.[serverKey];
1113
+ }
1114
+ /**
1115
+ * Every recorded key for one agent, as [storedKey, entry] pairs.
1116
+ *
1117
+ * Needed because the success sweep asks about channels that are NOT in the
1118
+ * quarantine store — a trial that worked leaves history behind and no marker,
1119
+ * so a loop over quarantine entries can never reach it. Returns the STORED
1120
+ * key (see `resumeHistoryKey`), not the channel key, because the caller is
1121
+ * the only thing that knows which namespace it is working in.
1122
+ */
1123
+ entriesFor(codeName) {
1124
+ return Object.entries(this.load()[codeName] ?? {});
1125
+ }
1126
+ /** Record a trial. Returns the entry as written. */
1127
+ recordAttempt(codeName, serverKey, now) {
1128
+ const file = this.load();
1129
+ const forAgent = file[codeName] ??= {};
1130
+ const prior = forAgent[serverKey];
1131
+ const next = {
1132
+ attempts: (prior?.attempts ?? 0) + 1,
1133
+ lastAttemptAt: now,
1134
+ // Carried, not reset: a further trial inside the same episode must not
1135
+ // re-arm the give-up line. It clears with the entry itself on forget().
1136
+ ...prior?.gaveUpLogged ? { gaveUpLogged: true } : {}
1137
+ };
1138
+ forAgent[serverKey] = next;
1139
+ this.persist();
1140
+ return next;
1141
+ }
1142
+ /**
1143
+ * Forget a key's history — called when an OPERATOR clears the quarantine.
1144
+ *
1145
+ * A human pressing Re-enable is a statement that the underlying fault was
1146
+ * addressed, so the next automatic trial should start from a clean two hours
1147
+ * rather than inheriting strikes from before the fix. Without this an
1148
+ * operator could fix a channel, watch it break again for an unrelated reason
1149
+ * weeks later, and find auto-resume already exhausted.
1150
+ */
1151
+ forget(codeName, serverKey) {
1152
+ const file = this.load();
1153
+ const forAgent = file[codeName];
1154
+ if (!forAgent || !forAgent[serverKey]) return false;
1155
+ delete forAgent[serverKey];
1156
+ if (Object.keys(forAgent).length === 0) delete file[codeName];
1157
+ this.persist();
1158
+ return true;
1159
+ }
1160
+ /**
1161
+ * Latch the give-up line for this key. Returns whether it had ALREADY been
1162
+ * logged, so the caller logs only on the first call of an episode.
1163
+ *
1164
+ * Returns true (already logged) when there is no entry at all: with no
1165
+ * history there are no strikes, so there is nothing to have given up ON, and
1166
+ * announcing an abandonment would be false.
1167
+ */
1168
+ noteGaveUpLogged(codeName, serverKey) {
1169
+ const file = this.load();
1170
+ const entry = file[codeName]?.[serverKey];
1171
+ if (!entry) return true;
1172
+ if (entry.gaveUpLogged) return true;
1173
+ entry.gaveUpLogged = true;
1174
+ this.persist();
1175
+ return false;
1176
+ }
1177
+ __invalidateCacheForTests() {
1178
+ this.cache = null;
1179
+ }
1180
+ };
1181
+ function resumeHistoryKey(mode, serverKey) {
1182
+ return mode === "shadow" ? `shadow:${serverKey}` : serverKey;
1183
+ }
1184
+ function backoffForAttempt(attemptsAlreadyMade) {
1185
+ const doubled = AUTO_RESUME_BASE_MS * 2 ** Math.max(0, attemptsAlreadyMade);
1186
+ return Math.min(doubled, AUTO_RESUME_MAX_MS);
1187
+ }
1188
+ function resolveAutoResumeEffectiveMode(autoResume, quarantine) {
1189
+ if (autoResume === "enforce" && quarantine !== "enforce") return "shadow";
1190
+ return autoResume;
1191
+ }
1192
+ function autoResumeSuccessGraceMs(configuredDwellMs) {
1193
+ const dwell = typeof configuredDwellMs === "number" && Number.isFinite(configuredDwellMs) && configuredDwellMs > QUARANTINE_DWELL_FLOOR_MS ? configuredDwellMs : QUARANTINE_DWELL_FLOOR_MS;
1194
+ return 2 * (DEAD_CHANNEL_MS + dwell);
1195
+ }
1196
+ function shouldForgetResumeHistory(input) {
1197
+ if (input.isQuarantined) return false;
1198
+ const history = input.history;
1199
+ if (!history || history.attempts === 0) return false;
1200
+ return input.now - history.lastAttemptAt >= autoResumeSuccessGraceMs(input.configuredDwellMs);
1201
+ }
1202
+ function decideChannelAutoResume(input) {
1203
+ const attempts = input.history?.attempts ?? 0;
1204
+ if (attempts >= AUTO_RESUME_MAX_ATTEMPTS) return { action: "give-up", attempts };
1205
+ const since = Math.max(input.quarantinedAt, input.history?.lastAttemptAt ?? 0);
1206
+ const waited = input.now - since;
1207
+ const need = backoffForAttempt(attempts);
1208
+ if (waited >= need) return { action: "resume", waitedMs: waited, attempt: attempts + 1 };
1209
+ return { action: "wait", dueInMs: need - waited, attempt: attempts + 1 };
1210
+ }
1211
+
1212
+ // src/lib/channel-quarantine.ts
1213
+ import { readFileSync as readFileSync4 } from "fs";
1214
+ import { join as join4 } from "path";
1059
1215
  var ESSENTIAL_CHANNEL_KEYS = /* @__PURE__ */ new Set(["direct-chat", "augmented"]);
1060
1216
  var OPTIONAL_CHANNEL_KEYS = /* @__PURE__ */ new Set([
1061
1217
  "telegram",
@@ -1087,7 +1243,7 @@ function classifyChannelCriticality(serverKey, entry) {
1087
1243
  return "essential";
1088
1244
  }
1089
1245
  function defaultQuarantinePath(configDir) {
1090
- return join3(configDir, "channel-quarantine.json");
1246
+ return join4(configDir, "channel-quarantine.json");
1091
1247
  }
1092
1248
  var ChannelQuarantineStore = class {
1093
1249
  path;
@@ -1098,7 +1254,7 @@ var ChannelQuarantineStore = class {
1098
1254
  load() {
1099
1255
  if (this.cache) return this.cache;
1100
1256
  try {
1101
- const raw = readFileSync3(this.path, "utf-8");
1257
+ const raw = readFileSync4(this.path, "utf-8");
1102
1258
  const parsed = JSON.parse(raw);
1103
1259
  this.cache = isQuarantineFile(parsed) ? parsed : {};
1104
1260
  } catch {
@@ -1186,13 +1342,13 @@ function isQuarantineFile(value) {
1186
1342
  }
1187
1343
 
1188
1344
  // src/lib/claude-md-size.ts
1189
- import { readFileSync as readFileSync4 } from "fs";
1190
- import { join as join4 } from "path";
1345
+ import { readFileSync as readFileSync5 } from "fs";
1346
+ import { join as join5 } from "path";
1191
1347
  function measureClaudeMd(configDir, codeName, ceiling = CLAUDE_MD_CONTEXT_ALARM_CHARS) {
1192
1348
  let chars;
1193
1349
  let bytes;
1194
1350
  try {
1195
- const buf = readFileSync4(join4(configDir, codeName, "project", "CLAUDE.md"));
1351
+ const buf = readFileSync5(join5(configDir, codeName, "project", "CLAUDE.md"));
1196
1352
  chars = buf.toString("utf8").length;
1197
1353
  bytes = buf.length;
1198
1354
  } catch {
@@ -1212,8 +1368,8 @@ function measureClaudeMd(configDir, codeName, ceiling = CLAUDE_MD_CONTEXT_ALARM_
1212
1368
  function measureCoreKnowledgeDescription(configDir, codeName) {
1213
1369
  let text;
1214
1370
  try {
1215
- text = readFileSync4(
1216
- join4(configDir, codeName, "project", ".claude", "skills", "core-knowledge", "SKILL.md"),
1371
+ text = readFileSync5(
1372
+ join5(configDir, codeName, "project", ".claude", "skills", "core-knowledge", "SKILL.md"),
1217
1373
  "utf8"
1218
1374
  );
1219
1375
  } catch {
@@ -1247,16 +1403,16 @@ function logClaudeMdCeilingTransition(codeName, report, log2) {
1247
1403
  }
1248
1404
 
1249
1405
  // ../../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";
1406
+ import { readFileSync as readFileSync6, writeFileSync as writeFileSync3 } from "fs";
1407
+ import { join as join6 } from "path";
1252
1408
  var FORWARDED_TOOLS_REPORT_FILENAME = "forwarded-tools.json";
1253
1409
  function forwardedToolsReportPath(agentDir) {
1254
- return join5(agentDir, FORWARDED_TOOLS_REPORT_FILENAME);
1410
+ return join6(agentDir, FORWARDED_TOOLS_REPORT_FILENAME);
1255
1411
  }
1256
1412
  function readForwardedToolsReport(agentDir) {
1257
1413
  let raw;
1258
1414
  try {
1259
- raw = readFileSync5(forwardedToolsReportPath(agentDir), "utf-8");
1415
+ raw = readFileSync6(forwardedToolsReportPath(agentDir), "utf-8");
1260
1416
  } catch {
1261
1417
  return null;
1262
1418
  }
@@ -1873,9 +2029,9 @@ var DependencyRecoveryLedger = class {
1873
2029
  // src/lib/mcp-assets-ready.ts
1874
2030
  import { existsSync as nodeExistsSync, readFileSync as nodeReadFileSync } from "fs";
1875
2031
  import { homedir as homedir2 } from "os";
1876
- import { join as join6, resolve, sep } from "path";
2032
+ import { join as join7, resolve, sep } from "path";
1877
2033
  function getSharedMcpDir(homeDir = homedir2()) {
1878
- return join6(homeDir, ".augmented", "_mcp");
2034
+ return join7(homeDir, ".augmented", "_mcp");
1879
2035
  }
1880
2036
  function isPathInsideDir(candidate, dir) {
1881
2037
  const resolvedDir = resolve(dir);
@@ -1885,11 +2041,11 @@ function isPathInsideDir(candidate, dir) {
1885
2041
  }
1886
2042
  function findMissingMcpBundles(mcpConfigPath, deps = {}) {
1887
2043
  const existsSync20 = deps.existsSync ?? nodeExistsSync;
1888
- const readFileSync34 = deps.readFileSync ?? nodeReadFileSync;
2044
+ const readFileSync35 = deps.readFileSync ?? nodeReadFileSync;
1889
2045
  const mcpDir = deps.mcpDir ?? getSharedMcpDir();
1890
2046
  let parsed;
1891
2047
  try {
1892
- parsed = JSON.parse(readFileSync34(mcpConfigPath, "utf-8"));
2048
+ parsed = JSON.parse(readFileSync35(mcpConfigPath, "utf-8"));
1893
2049
  } catch {
1894
2050
  return [];
1895
2051
  }
@@ -1927,7 +2083,7 @@ function formatMissingMcpBundles(missing) {
1927
2083
  }
1928
2084
 
1929
2085
  // src/lib/self-update-coalesce.ts
1930
- import { readFileSync as readFileSync6, writeFileSync as writeFileSync4, mkdirSync as mkdirSync3 } from "fs";
2086
+ import { readFileSync as readFileSync7, writeFileSync as writeFileSync4, mkdirSync as mkdirSync3 } from "fs";
1931
2087
  import { dirname as dirname4 } from "path";
1932
2088
  var DEFAULT_SELF_UPDATE_COALESCE_MS = 30 * 60 * 1e3;
1933
2089
  function resolveCoalesceWindowMs(env = process.env) {
@@ -1937,7 +2093,7 @@ function resolveCoalesceWindowMs(env = process.env) {
1937
2093
  if (!Number.isFinite(parsed) || parsed < 0) return DEFAULT_SELF_UPDATE_COALESCE_MS;
1938
2094
  return Math.trunc(parsed);
1939
2095
  }
1940
- function readLastSelfUpdateAppliedMs(markerPath, now = Date.now(), read = (p) => readFileSync6(p, "utf-8")) {
2096
+ function readLastSelfUpdateAppliedMs(markerPath, now = Date.now(), read = (p) => readFileSync7(p, "utf-8")) {
1941
2097
  let raw;
1942
2098
  try {
1943
2099
  raw = read(markerPath);
@@ -2242,11 +2398,11 @@ async function reportModelApiError(opts) {
2242
2398
  }
2243
2399
 
2244
2400
  // src/lib/claude-pid-tracker.ts
2245
- import { existsSync, readFileSync as readFileSync7 } from "fs";
2401
+ import { existsSync, readFileSync as readFileSync8 } from "fs";
2246
2402
  function readPidFile(path) {
2247
2403
  if (!existsSync(path)) return { version: 1, spawns: [] };
2248
2404
  try {
2249
- const raw = JSON.parse(readFileSync7(path, "utf-8"));
2405
+ const raw = JSON.parse(readFileSync8(path, "utf-8"));
2250
2406
  if (raw.version !== 1 || !Array.isArray(raw.spawns)) return { version: 1, spawns: [] };
2251
2407
  const spawns = raw.spawns.filter(
2252
2408
  (s) => !!s && typeof s.pid === "number" && Number.isFinite(s.pid) && s.pid > 0
@@ -2346,14 +2502,14 @@ async function killSessionsConcurrently(sessions, killOne) {
2346
2502
  }
2347
2503
 
2348
2504
  // src/lib/direct-chat-delivery.ts
2349
- import { join as join7 } from "path";
2505
+ import { join as join8 } from "path";
2350
2506
  var DEFAULT_DIRECT_CHAT_MAX_AGE_MS = 30 * 6e4;
2351
2507
  function directChatMaxAgeMs() {
2352
2508
  const raw = parseInt(process.env["AGT_DIRECT_CHAT_MAX_AGE_MS"] ?? "", 10);
2353
2509
  return Number.isFinite(raw) && raw >= 0 ? raw : DEFAULT_DIRECT_CHAT_MAX_AGE_MS;
2354
2510
  }
2355
2511
  function directChatDoorbellPath(agentId, home) {
2356
- return join7(home, ".augmented", agentId, "direct-chat-doorbell");
2512
+ return join8(home, ".augmented", agentId, "direct-chat-doorbell");
2357
2513
  }
2358
2514
  function isDirectChatMessageExpired(createdAt, nowMs, maxAgeMs) {
2359
2515
  if (!maxAgeMs || maxAgeMs <= 0) return false;
@@ -2364,8 +2520,8 @@ function isDirectChatMessageExpired(createdAt, nowMs, maxAgeMs) {
2364
2520
  }
2365
2521
 
2366
2522
  // 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";
2523
+ import { copyFileSync as copyFileSync2, chmodSync, existsSync as existsSync2, mkdirSync as mkdirSync4, readFileSync as readFileSync9 } from "fs";
2524
+ import { dirname as dirname5, join as join9 } from "path";
2369
2525
  import { fileURLToPath } from "url";
2370
2526
  var POSTER_FILENAME = "post-review-findings.mjs";
2371
2527
  var AUTH_FILENAME = "obiwan-auth.mjs";
@@ -2378,14 +2534,14 @@ function resolveBundledReviewAssetDir() {
2378
2534
  const moduleDir = dirname5(fileURLToPath(import.meta.url));
2379
2535
  const candidates = [
2380
2536
  // Built output: dist/<chunk>.js → dist/assets/review
2381
- join8(moduleDir, "assets", REVIEW_ASSET_DIRNAME),
2537
+ join9(moduleDir, "assets", REVIEW_ASSET_DIRNAME),
2382
2538
  // Built output sibling case: dist/<sub>/<chunk>.js → dist/assets/review
2383
- join8(moduleDir, "..", "assets", REVIEW_ASSET_DIRNAME),
2539
+ join9(moduleDir, "..", "assets", REVIEW_ASSET_DIRNAME),
2384
2540
  // Dev source: src/lib/review-poster-asset.ts → ../../assets/review
2385
- join8(moduleDir, "..", "..", "assets", REVIEW_ASSET_DIRNAME)
2541
+ join9(moduleDir, "..", "..", "assets", REVIEW_ASSET_DIRNAME)
2386
2542
  ];
2387
2543
  for (const candidate of candidates) {
2388
- if (existsSync2(join8(candidate, POSTER_FILENAME))) return candidate;
2544
+ if (existsSync2(join9(candidate, POSTER_FILENAME))) return candidate;
2389
2545
  }
2390
2546
  throw new Error(
2391
2547
  `[review-poster] could not locate bundled assets; tried:
@@ -2393,18 +2549,18 @@ function resolveBundledReviewAssetDir() {
2393
2549
  );
2394
2550
  }
2395
2551
  function reviewPosterDir(codeName) {
2396
- return join8(getFramework("claude-code").getAgentDir(codeName), REVIEW_ASSET_DIRNAME);
2552
+ return join9(getFramework("claude-code").getAgentDir(codeName), REVIEW_ASSET_DIRNAME);
2397
2553
  }
2398
2554
  function provisionReviewPoster(codeName, sourceDir = resolveBundledReviewAssetDir()) {
2399
2555
  const destDir = reviewPosterDir(codeName);
2400
2556
  mkdirSync4(destDir, { recursive: true });
2401
2557
  for (const [name, mode] of ASSET_FILES) {
2402
- const src = join8(sourceDir, name);
2403
- const dest = join8(destDir, name);
2558
+ const src = join9(sourceDir, name);
2559
+ const dest = join9(destDir, name);
2404
2560
  if (!existsSync2(src)) {
2405
2561
  throw new Error(`[review-poster] bundled asset missing: ${src}`);
2406
2562
  }
2407
- if (!existsSync2(dest) || !readFileSync8(src).equals(readFileSync8(dest))) {
2563
+ if (!existsSync2(dest) || !readFileSync9(src).equals(readFileSync9(dest))) {
2408
2564
  copyFileSync2(src, dest);
2409
2565
  }
2410
2566
  chmodSync(dest, mode);
@@ -2413,7 +2569,7 @@ function provisionReviewPoster(codeName, sourceDir = resolveBundledReviewAssetDi
2413
2569
 
2414
2570
  // src/lib/id-keyed-migration.ts
2415
2571
  import { existsSync as existsSync3, lstatSync, readlinkSync, renameSync as renameSync2 } from "fs";
2416
- import { join as join9 } from "path";
2572
+ import { join as join10 } from "path";
2417
2573
  import { homedir as homedir3 } from "os";
2418
2574
  var ID_KEYED_MIGRATION_FLAG = "id-keyed-layout-migration";
2419
2575
  function agentHasActiveWhatsapp(channelConfigs, codeNameDir) {
@@ -2421,7 +2577,7 @@ function agentHasActiveWhatsapp(channelConfigs, codeNameDir) {
2421
2577
  return true;
2422
2578
  }
2423
2579
  try {
2424
- if (existsSync3(join9(codeNameDir, "whatsapp-pending-inbound"))) return true;
2580
+ if (existsSync3(join10(codeNameDir, "whatsapp-pending-inbound"))) return true;
2425
2581
  } catch {
2426
2582
  }
2427
2583
  return false;
@@ -2453,10 +2609,10 @@ function finishTranscriptMove(oldCwd, newCwd, codeName, log2) {
2453
2609
  function maybeMigrateAgentToIdKeyedLayout(agent, deps) {
2454
2610
  const home = deps.home ?? homedir3();
2455
2611
  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");
2612
+ const codeNamePath = join10(home, ".augmented", codeName);
2613
+ const idPath = join10(home, ".augmented", agentId);
2614
+ const oldCwd = join10(home, ".augmented", codeName, "project");
2615
+ const newCwd = join10(idPath, "project");
2460
2616
  let codeNameKind;
2461
2617
  try {
2462
2618
  codeNameKind = lstatSync(codeNamePath).isSymbolicLink() ? "symlink" : "realdir";
@@ -2583,8 +2739,8 @@ function collectEnvGates(env) {
2583
2739
  }
2584
2740
 
2585
2741
  // ../../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";
2742
+ import { readFileSync as readFileSync10, writeFileSync as writeFileSync5 } from "fs";
2743
+ import { join as join11 } from "path";
2588
2744
  var CURSOR_SHORTFALL_COUNTER_SUFFIX = "-cursor-advance-classifications.json";
2589
2745
  function recordCursorAdvanceOutcome(agentDir, source, route, verdict) {
2590
2746
  if (!agentDir)
@@ -2592,10 +2748,10 @@ function recordCursorAdvanceOutcome(agentDir, source, route, verdict) {
2592
2748
  const key = cursorAdvanceCounterKey(route, verdict);
2593
2749
  if (key === null)
2594
2750
  return;
2595
- const path = join10(agentDir, `${source}${CURSOR_SHORTFALL_COUNTER_SUFFIX}`);
2751
+ const path = join11(agentDir, `${source}${CURSOR_SHORTFALL_COUNTER_SUFFIX}`);
2596
2752
  const counts = {};
2597
2753
  try {
2598
- const parsed = JSON.parse(readFileSync9(path, "utf-8"));
2754
+ const parsed = JSON.parse(readFileSync10(path, "utf-8"));
2599
2755
  if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
2600
2756
  for (const [k, v] of Object.entries(parsed)) {
2601
2757
  if (typeof v === "number" && Number.isInteger(v) && v >= 0)
@@ -2612,7 +2768,7 @@ function recordCursorAdvanceOutcome(agentDir, source, route, verdict) {
2612
2768
  }
2613
2769
 
2614
2770
  // src/lib/artifact-stream.ts
2615
- import { join as join11 } from "path";
2771
+ import { join as join12 } from "path";
2616
2772
  import { homedir as homedir4 } from "os";
2617
2773
  import { readdir, stat, readFile } from "fs/promises";
2618
2774
  var ARTEFACT_ENTRY_FILE = "index.html";
@@ -2698,7 +2854,7 @@ var ArtifactStreamScanner = class {
2698
2854
  return;
2699
2855
  }
2700
2856
  for (const name of names) {
2701
- const file = join11(this.artifactsDir, name, ARTEFACT_ENTRY_FILE);
2857
+ const file = join12(this.artifactsDir, name, ARTEFACT_ENTRY_FILE);
2702
2858
  const mtime = await this.fsDeps.mtimeMs(file).catch(() => null);
2703
2859
  if (mtime === null) continue;
2704
2860
  if (this.seenMtime.get(name) === mtime) continue;
@@ -2729,7 +2885,7 @@ var ArtifactStreamScanner = class {
2729
2885
  }
2730
2886
  };
2731
2887
  function artifactsDirFor(codeName) {
2732
- return join11(homedir4(), ".augmented", codeName, "artifacts");
2888
+ return join12(homedir4(), ".augmented", codeName, "artifacts");
2733
2889
  }
2734
2890
  var nodeArtifactFs = {
2735
2891
  async listArtefactNames(artifactsDir) {
@@ -3005,12 +3161,12 @@ async function maybePollHostUsage(deps) {
3005
3161
  import { createHash as createHash6 } from "crypto";
3006
3162
  import { readFile as readFile3, readdir as readdir3 } from "fs/promises";
3007
3163
  import { homedir as homedir6, platform as platform2 } from "os";
3008
- import { dirname as dirname6, join as join13 } from "path";
3164
+ import { dirname as dirname6, join as join14 } from "path";
3009
3165
 
3010
3166
  // src/lib/claude-auth-detect.ts
3011
3167
  import { readFile as readFile2, readdir as readdir2 } from "fs/promises";
3012
3168
  import { homedir as homedir5, platform } from "os";
3013
- import { join as join12 } from "path";
3169
+ import { join as join13 } from "path";
3014
3170
  import { execFile } from "child_process";
3015
3171
  import { promisify } from "util";
3016
3172
  var execFileAsync = promisify(execFile);
@@ -3025,16 +3181,16 @@ async function detectClaudeAuth() {
3025
3181
  }
3026
3182
  async function findClaudeCredentialsPaths() {
3027
3183
  const candidates = [
3028
- join12(homedir5(), ".claude", ".credentials.json"),
3029
- join12(homedir5(), ".claude", "credentials.json")
3184
+ join13(homedir5(), ".claude", ".credentials.json"),
3185
+ join13(homedir5(), ".claude", "credentials.json")
3030
3186
  ];
3031
3187
  const isLinuxRoot = platform() === "linux" && typeof process.getuid === "function" && process.getuid() === 0;
3032
3188
  if (isLinuxRoot) {
3033
3189
  try {
3034
3190
  const entries = await readdir2("/home", { withFileTypes: true });
3035
3191
  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"));
3192
+ candidates.push(join13("/home", entry.name, ".claude", ".credentials.json"));
3193
+ candidates.push(join13("/home", entry.name, ".claude", "credentials.json"));
3038
3194
  }
3039
3195
  } catch {
3040
3196
  }
@@ -3118,7 +3274,7 @@ async function candidateHomes() {
3118
3274
  try {
3119
3275
  const entries = await readdir3("/home", { withFileTypes: true });
3120
3276
  for (const entry of entries.filter((e) => e.isDirectory()).sort((a, b) => a.name.localeCompare(b.name))) {
3121
- homes.push(join13("/home", entry.name));
3277
+ homes.push(join14("/home", entry.name));
3122
3278
  }
3123
3279
  } catch {
3124
3280
  }
@@ -3138,11 +3294,11 @@ async function homeOfActiveCredentials() {
3138
3294
  async function claudeConfigCandidatePaths() {
3139
3295
  const paths = [];
3140
3296
  const configDir = process.env["CLAUDE_CONFIG_DIR"]?.trim();
3141
- if (configDir) paths.push(join13(configDir, ".claude.json"));
3297
+ if (configDir) paths.push(join14(configDir, ".claude.json"));
3142
3298
  const activeHome = await homeOfActiveCredentials();
3143
- if (activeHome) paths.push(join13(activeHome, ".claude.json"));
3299
+ if (activeHome) paths.push(join14(activeHome, ".claude.json"));
3144
3300
  for (const home of await candidateHomes()) {
3145
- const path = join13(home, ".claude.json");
3301
+ const path = join14(home, ".claude.json");
3146
3302
  if (!paths.includes(path)) paths.push(path);
3147
3303
  }
3148
3304
  return paths;
@@ -3261,9 +3417,9 @@ function diffAuthTuples(recorded, current) {
3261
3417
  // src/lib/account-enforcement-marker.ts
3262
3418
  import { mkdirSync as mkdirSync5, renameSync as renameSync3, rmSync as rmSync2, writeFileSync as writeFileSync6 } from "fs";
3263
3419
  import { homedir as homedir7 } from "os";
3264
- import { join as join14 } from "path";
3420
+ import { join as join15 } from "path";
3265
3421
  function accountEnforcementMarkerPath(codeName) {
3266
- return join14(homedir7(), ".augmented", codeName, ACCOUNT_ENFORCEMENT_MARKER_FILENAME);
3422
+ return join15(homedir7(), ".augmented", codeName, ACCOUNT_ENFORCEMENT_MARKER_FILENAME);
3267
3423
  }
3268
3424
  function syncAccountEnforcementMarker(codeName, level, log2 = (m) => process.stderr.write(`${m}
3269
3425
  `), text) {
@@ -3271,8 +3427,8 @@ function syncAccountEnforcementMarker(codeName, level, log2 = (m) => process.std
3271
3427
  clearAccountEnforcementMarker(codeName, log2);
3272
3428
  return;
3273
3429
  }
3274
- const dir = join14(homedir7(), ".augmented", codeName);
3275
- const path = join14(dir, ACCOUNT_ENFORCEMENT_MARKER_FILENAME);
3430
+ const dir = join15(homedir7(), ".augmented", codeName);
3431
+ const path = join15(dir, ACCOUNT_ENFORCEMENT_MARKER_FILENAME);
3276
3432
  const tempPath = `${path}.${process.pid}.tmp`;
3277
3433
  try {
3278
3434
  mkdirSync5(dir, { recursive: true });
@@ -3297,8 +3453,8 @@ function clearAccountEnforcementMarker(codeName, log2 = (m) => process.stderr.wr
3297
3453
  }
3298
3454
 
3299
3455
  // src/lib/token-usage-monitor.ts
3300
- import { readdirSync, readFileSync as readFileSync10, statSync } from "fs";
3301
- import { join as join15 } from "path";
3456
+ import { readdirSync, readFileSync as readFileSync11, statSync } from "fs";
3457
+ import { join as join16 } from "path";
3302
3458
  var MIN_CHECK_INTERVAL_MS2 = 6e4;
3303
3459
  var TRANSCRIPT_MTIME_WINDOW_MS = 2 * 24 * 60 * 60 * 1e3;
3304
3460
  var MAX_ENTRIES_PER_POST = 200;
@@ -3327,7 +3483,7 @@ async function maybeReportTokenUsage(args) {
3327
3483
  if (!name.endsWith(".jsonl")) continue;
3328
3484
  const sessionId = name.slice(0, -".jsonl".length);
3329
3485
  if (!sessionId) continue;
3330
- const path = join15(dir, name);
3486
+ const path = join16(dir, name);
3331
3487
  let st;
3332
3488
  try {
3333
3489
  st = statSync(path);
@@ -3343,7 +3499,7 @@ async function maybeReportTokenUsage(args) {
3343
3499
  }
3344
3500
  let content;
3345
3501
  try {
3346
- content = readFileSync10(path, "utf-8");
3502
+ content = readFileSync11(path, "utf-8");
3347
3503
  } catch (err) {
3348
3504
  log2(`[token-usage] read failed for '${codeName}/${name}': ${err.message}`);
3349
3505
  continue;
@@ -3424,8 +3580,8 @@ async function maybeReportTokenUsage(args) {
3424
3580
  }
3425
3581
 
3426
3582
  // 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";
3583
+ import { readdirSync as readdirSync2, readFileSync as readFileSync12, statSync as statSync2 } from "fs";
3584
+ import { join as join17 } from "path";
3429
3585
  var MIN_CHECK_INTERVAL_MS3 = 5 * 6e4;
3430
3586
  var SETTLE_MS = 3e4;
3431
3587
  var TRANSCRIPT_MTIME_WINDOW_MS2 = 2 * 24 * 60 * 60 * 1e3;
@@ -3444,7 +3600,7 @@ function collectJsonlRecursive(dir, minMtimeMs, out, depth) {
3444
3600
  return;
3445
3601
  }
3446
3602
  for (const name of entries) {
3447
- const p = join16(dir, name);
3603
+ const p = join17(dir, name);
3448
3604
  let st;
3449
3605
  try {
3450
3606
  st = statSync2(p);
@@ -3467,7 +3623,7 @@ function enumerateTranscriptFiles(transcriptDir, nowMs, minMtimeMs = nowMs - TRA
3467
3623
  return out;
3468
3624
  }
3469
3625
  for (const name of entries) {
3470
- const path = join16(transcriptDir, name);
3626
+ const path = join17(transcriptDir, name);
3471
3627
  let st;
3472
3628
  try {
3473
3629
  st = statSync2(path);
@@ -3479,7 +3635,7 @@ function enumerateTranscriptFiles(transcriptDir, nowMs, minMtimeMs = nowMs - TRA
3479
3635
  continue;
3480
3636
  }
3481
3637
  if (st.isDirectory()) {
3482
- collectJsonlRecursive(join16(path, "subagents"), minMtimeMs, out, 0);
3638
+ collectJsonlRecursive(join17(path, "subagents"), minMtimeMs, out, 0);
3483
3639
  }
3484
3640
  }
3485
3641
  return out;
@@ -3524,7 +3680,7 @@ async function maybeReconcileWorkflowRunTokens(args) {
3524
3680
  const contents = [];
3525
3681
  for (const path of files) {
3526
3682
  try {
3527
- contents.push(readFileSync11(path, "utf-8"));
3683
+ contents.push(readFileSync12(path, "utf-8"));
3528
3684
  } catch {
3529
3685
  }
3530
3686
  }
@@ -3569,8 +3725,8 @@ async function maybeReconcileWorkflowRunTokens(args) {
3569
3725
  }
3570
3726
 
3571
3727
  // 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";
3728
+ import { readdirSync as readdirSync3, readFileSync as readFileSync13, statSync as statSync3 } from "fs";
3729
+ import { join as join18 } from "path";
3574
3730
 
3575
3731
  // src/lib/detect-meta-egress.ts
3576
3732
  var REPOST_PREAMBLE_WINDOW = 200;
@@ -4055,7 +4211,7 @@ function readRecentTurns(dir, nowMs) {
4055
4211
  return;
4056
4212
  }
4057
4213
  for (const ent of entries) {
4058
- const full = join17(d, ent.name);
4214
+ const full = join18(d, ent.name);
4059
4215
  if (ent.isDirectory()) {
4060
4216
  visit(full);
4061
4217
  continue;
@@ -4070,7 +4226,7 @@ function readRecentTurns(dir, nowMs) {
4070
4226
  if (nowMs - mtimeMs > TRANSCRIPT_MTIME_WINDOW_MS3) continue;
4071
4227
  let content;
4072
4228
  try {
4073
- content = readFileSync12(full, "utf8");
4229
+ content = readFileSync13(full, "utf8");
4074
4230
  } catch {
4075
4231
  continue;
4076
4232
  }
@@ -4443,22 +4599,22 @@ async function reportSkip2(api2, agentId, conversationId, log2, codeName) {
4443
4599
 
4444
4600
  // src/lib/tool-call-audit.ts
4445
4601
  import { homedir as homedir11 } from "os";
4446
- import { join as join22 } from "path";
4602
+ import { join as join23 } from "path";
4447
4603
 
4448
4604
  // src/lib/agent-logging-mode.ts
4449
- import { readFileSync as readFileSync13 } from "fs";
4605
+ import { readFileSync as readFileSync14 } from "fs";
4450
4606
  import { homedir as homedir8 } from "os";
4451
- import { join as join18 } from "path";
4607
+ import { join as join19 } from "path";
4452
4608
  var LOGGING_MODES = ["hash-only", "redacted", "full-local"];
4453
4609
  function charterPath(codeName, homeDir) {
4454
4610
  const home = homeDir ?? (process.env["HOME"]?.trim() || homedir8());
4455
4611
  const key = agentRuntimeKey(codeName, homeDir);
4456
- return join18(home, ".augmented", key, "provision", "CHARTER.md");
4612
+ return join19(home, ".augmented", key, "provision", "CHARTER.md");
4457
4613
  }
4458
4614
  function readAgentLoggingMode(codeName, homeDir) {
4459
4615
  let raw;
4460
4616
  try {
4461
- raw = readFileSync13(charterPath(codeName, homeDir), "utf-8");
4617
+ raw = readFileSync14(charterPath(codeName, homeDir), "utf-8");
4462
4618
  } catch {
4463
4619
  return { mode: null, reason: "no-charter" };
4464
4620
  }
@@ -4482,15 +4638,15 @@ function loggingModeWithholdsTargets(reading) {
4482
4638
 
4483
4639
  // src/lib/tool-call-path-salt.ts
4484
4640
  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";
4641
+ import { existsSync as existsSync4, mkdirSync as mkdirSync6, readFileSync as readFileSync15, renameSync as renameSync4, unlinkSync as unlinkSync2, writeFileSync as writeFileSync7 } from "fs";
4486
4642
  import { homedir as homedir9 } from "os";
4487
- import { dirname as dirname7, join as join19 } from "path";
4643
+ import { dirname as dirname7, join as join20 } from "path";
4488
4644
  var SALT_BYTES = 32;
4489
4645
  var SALT_RE = /^[0-9a-f]{64}$/;
4490
4646
  function pathSaltPath(codeName, homeDir) {
4491
4647
  const home = homeDir ?? (process.env["HOME"]?.trim() || homedir9());
4492
4648
  const key = agentRuntimeKey(codeName, homeDir);
4493
- return join19(home, ".augmented", key, "tool-call-path-salt");
4649
+ return join20(home, ".augmented", key, "tool-call-path-salt");
4494
4650
  }
4495
4651
  function readToolCallPathSalt(codeName, homeDir) {
4496
4652
  let file;
@@ -4501,7 +4657,7 @@ function readToolCallPathSalt(codeName, homeDir) {
4501
4657
  }
4502
4658
  try {
4503
4659
  if (existsSync4(file)) {
4504
- const existing = readFileSync14(file, "utf-8").trim();
4660
+ const existing = readFileSync15(file, "utf-8").trim();
4505
4661
  if (SALT_RE.test(existing)) return existing;
4506
4662
  }
4507
4663
  } catch {
@@ -4527,8 +4683,8 @@ function readToolCallPathSalt(codeName, homeDir) {
4527
4683
  import { statSync as statSync4 } from "fs";
4528
4684
 
4529
4685
  // 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";
4686
+ import { closeSync, fstatSync, openSync, readFileSync as readFileSync16, readSync, readdirSync as readdirSync4 } from "fs";
4687
+ import { basename as basename2, join as join21, relative } from "path";
4532
4688
  import { StringDecoder } from "string_decoder";
4533
4689
 
4534
4690
  // src/lib/tool-call-redaction.ts
@@ -4657,7 +4813,7 @@ function redactToolTargetInner(toolName, input, ctx) {
4657
4813
  var EXTRACTOR_VERSION = "e1";
4658
4814
  function enumerateSessionTranscripts(transcriptDir, sessionId, projectsRoot) {
4659
4815
  const files = [];
4660
- const mainAbs = join20(transcriptDir, `${sessionId}.jsonl`);
4816
+ const mainAbs = join21(transcriptDir, `${sessionId}.jsonl`);
4661
4817
  files.push({
4662
4818
  absPath: mainAbs,
4663
4819
  relPath: relative(projectsRoot, mainAbs),
@@ -4665,7 +4821,7 @@ function enumerateSessionTranscripts(transcriptDir, sessionId, projectsRoot) {
4665
4821
  isSubagent: false,
4666
4822
  subagentId: null
4667
4823
  });
4668
- const subDir = join20(transcriptDir, sessionId, "subagents");
4824
+ const subDir = join21(transcriptDir, sessionId, "subagents");
4669
4825
  let entries;
4670
4826
  try {
4671
4827
  entries = readdirSync4(subDir);
@@ -4674,7 +4830,7 @@ function enumerateSessionTranscripts(transcriptDir, sessionId, projectsRoot) {
4674
4830
  }
4675
4831
  for (const name of entries) {
4676
4832
  if (!name.endsWith(".jsonl")) continue;
4677
- const abs = join20(subDir, name);
4833
+ const abs = join21(subDir, name);
4678
4834
  const stem = basename2(name, ".jsonl");
4679
4835
  files.push({
4680
4836
  absPath: abs,
@@ -4872,9 +5028,9 @@ function extractTranscriptWindow(file, opts, from) {
4872
5028
  }
4873
5029
 
4874
5030
  // src/lib/tool-call-cursor.ts
4875
- import { existsSync as existsSync5, readFileSync as readFileSync16 } from "fs";
5031
+ import { existsSync as existsSync5, readFileSync as readFileSync17 } from "fs";
4876
5032
  import { homedir as homedir10 } from "os";
4877
- import { join as join21 } from "path";
5033
+ import { join as join22 } from "path";
4878
5034
  var COVERAGE_DISPOSITIONS = [
4879
5035
  "ok",
4880
5036
  "not_entitled",
@@ -4929,13 +5085,13 @@ function parseCursorKey(key) {
4929
5085
  function cursorStatePath(codeName, homeDir) {
4930
5086
  const home = homeDir ?? (process.env["HOME"]?.trim() || homedir10());
4931
5087
  const key = agentRuntimeKey(codeName, homeDir);
4932
- return join21(home, ".augmented", key, "tool-call-cursors.json");
5088
+ return join22(home, ".augmented", key, "tool-call-cursors.json");
4933
5089
  }
4934
5090
  function loadCursors(path) {
4935
5091
  const out = /* @__PURE__ */ new Map();
4936
5092
  if (!existsSync5(path)) return out;
4937
5093
  try {
4938
- const parsed = JSON.parse(readFileSync16(path, "utf-8"));
5094
+ const parsed = JSON.parse(readFileSync17(path, "utf-8"));
4939
5095
  if (!parsed || parsed.version !== 1 || typeof parsed.files !== "object") return out;
4940
5096
  for (const [k, v] of Object.entries(parsed.files)) {
4941
5097
  if (!v || typeof v !== "object") continue;
@@ -5342,7 +5498,7 @@ async function maybeScanToolCalls(args) {
5342
5498
  log2(`[tool-call-audit] ${codeName}: no path-hash salt available \u2014 file targets withheld`);
5343
5499
  }
5344
5500
  const home = args.homeDir ?? (process.env["HOME"]?.trim() || homedir11());
5345
- const projectsRoot = args.projectsRoot ?? join22(home, ".claude", "projects");
5501
+ const projectsRoot = args.projectsRoot ?? join23(home, ".claude", "projects");
5346
5502
  const transcriptDir = args.transcriptDir ?? sessionTranscriptDir(getProjectDir(codeName));
5347
5503
  const current = peekCurrentSession(codeName);
5348
5504
  const sessionIds = current ? [current.sessionId] : [];
@@ -5371,11 +5527,11 @@ async function maybeScanToolCalls(args) {
5371
5527
  }
5372
5528
 
5373
5529
  // src/lib/activity-cache-monitor.ts
5374
- import { existsSync as existsSync6, readFileSync as readFileSync17 } from "fs";
5530
+ import { existsSync as existsSync6, readFileSync as readFileSync18 } from "fs";
5375
5531
  import { homedir as homedir12 } from "os";
5376
- import { join as join23 } from "path";
5532
+ import { join as join24 } from "path";
5377
5533
  var MIN_CHECK_INTERVAL_MS7 = 6e4;
5378
- var STATS_CACHE_PATH = join23(homedir12(), ".claude", "stats-cache.json");
5534
+ var STATS_CACHE_PATH = join24(homedir12(), ".claude", "stats-cache.json");
5379
5535
  var ISO_DATE_RE = /^\d{4}-\d{2}-\d{2}$/;
5380
5536
  var state7 = { lastObservedDate: null, lastCheckedAt: 0 };
5381
5537
  function selectNewDailyRows(raw, lastObservedDate) {
@@ -5423,7 +5579,7 @@ async function maybeReportActivityCache(args) {
5423
5579
  }
5424
5580
  let raw;
5425
5581
  try {
5426
- raw = readFileSync17(STATS_CACHE_PATH, "utf-8");
5582
+ raw = readFileSync18(STATS_CACHE_PATH, "utf-8");
5427
5583
  } catch (err) {
5428
5584
  log2(`[activity-cache] readFileSync failed: ${err.message}`);
5429
5585
  return;
@@ -5726,7 +5882,7 @@ import { createHash as createHash9 } from "crypto";
5726
5882
  import {
5727
5883
  existsSync as existsSync7,
5728
5884
  mkdirSync as mkdirSync7,
5729
- readFileSync as readFileSync18,
5885
+ readFileSync as readFileSync19,
5730
5886
  readdirSync as readdirSync5,
5731
5887
  renameSync as renameSync5,
5732
5888
  rmSync as rmSync3,
@@ -5734,7 +5890,7 @@ import {
5734
5890
  utimesSync,
5735
5891
  writeFileSync as writeFileSync8
5736
5892
  } from "fs";
5737
- import { join as join24 } from "path";
5893
+ import { join as join25 } from "path";
5738
5894
  var KNOWLEDGE_FETCH_CHUNK = 100;
5739
5895
  var CACHE_TTL_MS = 30 * 24 * 60 * 60 * 1e3;
5740
5896
  var SWEEP_INTERVAL_MS = 24 * 60 * 60 * 1e3;
@@ -5743,12 +5899,12 @@ function knowledgeHash(content) {
5743
5899
  return createHash9("sha256").update(content, "utf8").digest("hex");
5744
5900
  }
5745
5901
  function cachePath(cacheDir, hash) {
5746
- return join24(cacheDir, hash);
5902
+ return join25(cacheDir, hash);
5747
5903
  }
5748
5904
  function readCachedKnowledge(cacheDir, hash) {
5749
5905
  const path = cachePath(cacheDir, hash);
5750
5906
  try {
5751
- const content = readFileSync18(path, "utf-8");
5907
+ const content = readFileSync19(path, "utf-8");
5752
5908
  try {
5753
5909
  const now = /* @__PURE__ */ new Date();
5754
5910
  utimesSync(path, now, now);
@@ -5777,7 +5933,7 @@ function sweepKnowledgeCache(cacheDir, now = Date.now()) {
5777
5933
  try {
5778
5934
  if (!existsSync7(cacheDir)) return;
5779
5935
  for (const name of readdirSync5(cacheDir)) {
5780
- const path = join24(cacheDir, name);
5936
+ const path = join25(cacheDir, name);
5781
5937
  try {
5782
5938
  if (now - statSync6(path).mtimeMs > CACHE_TTL_MS) rmSync3(path, { force: true });
5783
5939
  } catch {
@@ -5829,7 +5985,7 @@ import { createHash as createHash10 } from "crypto";
5829
5985
  import {
5830
5986
  existsSync as existsSync8,
5831
5987
  mkdirSync as mkdirSync8,
5832
- readFileSync as readFileSync19,
5988
+ readFileSync as readFileSync20,
5833
5989
  readdirSync as readdirSync6,
5834
5990
  renameSync as renameSync6,
5835
5991
  rmSync as rmSync4,
@@ -5837,7 +5993,7 @@ import {
5837
5993
  utimesSync as utimesSync2,
5838
5994
  writeFileSync as writeFileSync9
5839
5995
  } from "fs";
5840
- import { join as join25 } from "path";
5996
+ import { join as join26 } from "path";
5841
5997
  var MEMORY_FETCH_CHUNK = 100;
5842
5998
  var CACHE_TTL_MS2 = 30 * 24 * 60 * 60 * 1e3;
5843
5999
  var SWEEP_INTERVAL_MS2 = 24 * 60 * 60 * 1e3;
@@ -5846,12 +6002,12 @@ function memoryHash(content) {
5846
6002
  return createHash10("sha256").update(content, "utf8").digest("hex");
5847
6003
  }
5848
6004
  function cachePath2(cacheDir, hash) {
5849
- return join25(cacheDir, hash);
6005
+ return join26(cacheDir, hash);
5850
6006
  }
5851
6007
  function readCachedMemory(cacheDir, hash) {
5852
6008
  const path = cachePath2(cacheDir, hash);
5853
6009
  try {
5854
- const content = readFileSync19(path, "utf-8");
6010
+ const content = readFileSync20(path, "utf-8");
5855
6011
  try {
5856
6012
  const now = /* @__PURE__ */ new Date();
5857
6013
  utimesSync2(path, now, now);
@@ -5880,7 +6036,7 @@ function sweepMemoryCache(cacheDir, now = Date.now()) {
5880
6036
  try {
5881
6037
  if (!existsSync8(cacheDir)) return;
5882
6038
  for (const name of readdirSync6(cacheDir)) {
5883
- const path = join25(cacheDir, name);
6039
+ const path = join26(cacheDir, name);
5884
6040
  try {
5885
6041
  if (now - statSync7(path).mtimeMs > CACHE_TTL_MS2) rmSync4(path, { force: true });
5886
6042
  } catch {
@@ -5938,7 +6094,7 @@ import { createHash as createHash11 } from "crypto";
5938
6094
  import {
5939
6095
  existsSync as existsSync9,
5940
6096
  mkdirSync as mkdirSync9,
5941
- readFileSync as readFileSync20,
6097
+ readFileSync as readFileSync21,
5942
6098
  readdirSync as readdirSync7,
5943
6099
  renameSync as renameSync7,
5944
6100
  rmSync as rmSync5,
@@ -5946,7 +6102,7 @@ import {
5946
6102
  utimesSync as utimesSync3,
5947
6103
  writeFileSync as writeFileSync10
5948
6104
  } from "fs";
5949
- import { join as join26 } from "path";
6105
+ import { join as join27 } from "path";
5950
6106
  var SKILL_FETCH_CHUNK = 100;
5951
6107
  var CACHE_TTL_MS3 = 30 * 24 * 60 * 60 * 1e3;
5952
6108
  var SWEEP_INTERVAL_MS3 = 24 * 60 * 60 * 1e3;
@@ -5955,12 +6111,12 @@ function skillHash(content) {
5955
6111
  return createHash11("sha256").update(content, "utf8").digest("hex");
5956
6112
  }
5957
6113
  function cachePath3(cacheDir, hash) {
5958
- return join26(cacheDir, hash);
6114
+ return join27(cacheDir, hash);
5959
6115
  }
5960
6116
  function readCachedSkill(cacheDir, hash) {
5961
6117
  const path = cachePath3(cacheDir, hash);
5962
6118
  try {
5963
- const content = readFileSync20(path, "utf-8");
6119
+ const content = readFileSync21(path, "utf-8");
5964
6120
  try {
5965
6121
  const now = /* @__PURE__ */ new Date();
5966
6122
  utimesSync3(path, now, now);
@@ -5989,7 +6145,7 @@ function sweepSkillCache(cacheDir, now = Date.now()) {
5989
6145
  try {
5990
6146
  if (!existsSync9(cacheDir)) return;
5991
6147
  for (const name of readdirSync7(cacheDir)) {
5992
- const path = join26(cacheDir, name);
6148
+ const path = join27(cacheDir, name);
5993
6149
  try {
5994
6150
  if (now - statSync8(path).mtimeMs > CACHE_TTL_MS3) rmSync5(path, { force: true });
5995
6151
  } catch {
@@ -6276,18 +6432,18 @@ function resolveConditionalResponse(wire, hasCachedBody) {
6276
6432
  }
6277
6433
 
6278
6434
  // 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";
6435
+ import { existsSync as existsSync10, readFileSync as readFileSync22, writeFileSync as writeFileSync11 } from "fs";
6436
+ import { join as join28 } from "path";
6281
6437
  var CACHE_FILENAME = "channel-hash-cache.json";
6282
6438
  function getChannelHashCacheFile(configDir) {
6283
- return join27(configDir, CACHE_FILENAME);
6439
+ return join28(configDir, CACHE_FILENAME);
6284
6440
  }
6285
6441
  function loadChannelHashCache(target, configDir) {
6286
6442
  const path = getChannelHashCacheFile(configDir);
6287
6443
  if (!existsSync10(path)) return;
6288
6444
  let parsed;
6289
6445
  try {
6290
- parsed = JSON.parse(readFileSync21(path, "utf-8"));
6446
+ parsed = JSON.parse(readFileSync22(path, "utf-8"));
6291
6447
  } catch {
6292
6448
  return;
6293
6449
  }
@@ -6307,8 +6463,8 @@ function saveChannelHashCache(source, configDir) {
6307
6463
  }
6308
6464
 
6309
6465
  // src/lib/sender-policy-baseline.ts
6310
- import { existsSync as existsSync11, readFileSync as readFileSync22 } from "fs";
6311
- import { join as join28 } from "path";
6466
+ import { existsSync as existsSync11, readFileSync as readFileSync23 } from "fs";
6467
+ import { join as join29 } from "path";
6312
6468
  var BASELINE_FILENAME = "sender-policy-baseline.json";
6313
6469
  var SENDER_POLICY_BASELINE_VERSION = 1;
6314
6470
  var BASELINE_CONCERNS = [
@@ -6346,14 +6502,14 @@ function createDeliveryBaselineMaps() {
6346
6502
  };
6347
6503
  }
6348
6504
  function getSenderPolicyBaselineFile(configDir) {
6349
- return join28(configDir, BASELINE_FILENAME);
6505
+ return join29(configDir, BASELINE_FILENAME);
6350
6506
  }
6351
6507
  function loadSenderPolicyBaseline(target, configDir, log2) {
6352
6508
  const path = getSenderPolicyBaselineFile(configDir);
6353
6509
  if (!existsSync11(path)) return;
6354
6510
  let parsed;
6355
6511
  try {
6356
- parsed = JSON.parse(readFileSync22(path, "utf-8"));
6512
+ parsed = JSON.parse(readFileSync23(path, "utf-8"));
6357
6513
  } catch (err) {
6358
6514
  log2?.(
6359
6515
  `[sender-policy] discarding corrupt ${BASELINE_FILENAME} (${err.message}) - restrictive-policy agents will take one fail-closed restart`
@@ -6402,8 +6558,8 @@ function saveSenderPolicyBaseline(source, configDir, log2) {
6402
6558
  }
6403
6559
 
6404
6560
  // src/lib/stuck-streak-store.ts
6405
- import { existsSync as existsSync12, readFileSync as readFileSync23 } from "fs";
6406
- import { join as join29 } from "path";
6561
+ import { existsSync as existsSync12, readFileSync as readFileSync24 } from "fs";
6562
+ import { join as join30 } from "path";
6407
6563
  var STORE_FILENAME = "stuck-streaks.json";
6408
6564
  var STUCK_STREAK_STORE_VERSION = 1;
6409
6565
  var STUCK_STREAK_CONCERNS = ["channelSync", "realtimeRebind"];
@@ -6411,7 +6567,7 @@ function createStuckStreakMaps() {
6411
6567
  return { channelSync: /* @__PURE__ */ new Map(), realtimeRebind: /* @__PURE__ */ new Map() };
6412
6568
  }
6413
6569
  function getStuckStreakStoreFile(configDir) {
6414
- return join29(configDir, STORE_FILENAME);
6570
+ return join30(configDir, STORE_FILENAME);
6415
6571
  }
6416
6572
  function isValidPersistedStreak(value) {
6417
6573
  if (!value || typeof value !== "object" || Array.isArray(value)) return false;
@@ -6453,7 +6609,7 @@ function loadStuckStreaks(target, configDir, log2) {
6453
6609
  if (!existsSync12(path)) return;
6454
6610
  let parsed;
6455
6611
  try {
6456
- parsed = JSON.parse(readFileSync23(path, "utf-8"));
6612
+ parsed = JSON.parse(readFileSync24(path, "utf-8"));
6457
6613
  } catch (err) {
6458
6614
  log2?.(
6459
6615
  `[stuck-streaks] discarding corrupt ${STORE_FILENAME} (${err.message}) \u2014 stuck-streak ages restart from zero and one spurious "recovered" close may follow`
@@ -6496,11 +6652,9 @@ function pruneStuckStreaksToAgents(maps, activeAgentIds) {
6496
6652
  }
6497
6653
 
6498
6654
  // src/lib/claude-device-state.ts
6499
- import { readFileSync as readFileSync24, statSync as statSync9 } from "fs";
6500
- import { homedir as homedir13 } from "os";
6501
- import { join as join30 } from "path";
6655
+ import { readFileSync as readFileSync25, statSync as statSync9 } from "fs";
6502
6656
  function claudeDeviceStatePath(env = process.env) {
6503
- return join30(env.HOME?.trim() || homedir13(), ".claude.json");
6657
+ return effectiveClaudeJsonPath(void 0, env);
6504
6658
  }
6505
6659
  function probeClaudeDeviceStatePresence(path = claudeDeviceStatePath()) {
6506
6660
  try {
@@ -6523,7 +6677,7 @@ function checkClaudeDeviceState(path = claudeDeviceStatePath()) {
6523
6677
  }
6524
6678
  let raw;
6525
6679
  try {
6526
- raw = readFileSync24(path, "utf-8");
6680
+ raw = readFileSync25(path, "utf-8");
6527
6681
  } catch {
6528
6682
  return { usable: false, reason: "unreadable" };
6529
6683
  }
@@ -7222,7 +7376,7 @@ function removeIntegrationSkillFolder(opts) {
7222
7376
  }
7223
7377
 
7224
7378
  // src/lib/manager/managed-skill-manifest.ts
7225
- import { existsSync as existsSync13, mkdirSync as mkdirSync10, readFileSync as readFileSync25, writeFileSync as writeFileSync12 } from "fs";
7379
+ import { existsSync as existsSync13, mkdirSync as mkdirSync10, readFileSync as readFileSync26, writeFileSync as writeFileSync12 } from "fs";
7226
7380
  import { dirname as dirname8, join as join32 } from "path";
7227
7381
  var MANIFEST_VERSION = 1;
7228
7382
  function managedSkillManifestPath(agentRootDir) {
@@ -7231,7 +7385,7 @@ function managedSkillManifestPath(agentRootDir) {
7231
7385
  function readManagedSkillManifest(path) {
7232
7386
  try {
7233
7387
  if (!existsSync13(path)) return /* @__PURE__ */ new Set();
7234
- const parsed = JSON.parse(readFileSync25(path, "utf-8"));
7388
+ const parsed = JSON.parse(readFileSync26(path, "utf-8"));
7235
7389
  const ids = Array.isArray(parsed?.globalSkillIds) ? parsed.globalSkillIds : [];
7236
7390
  return new Set(ids.filter((id) => typeof id === "string" && id.length > 0));
7237
7391
  } catch {
@@ -7362,7 +7516,7 @@ function resolveModelChain(refreshData) {
7362
7516
  // src/lib/manager/claude-auth.ts
7363
7517
  import { existsSync as existsSync14, rmSync as rmSync6 } from "fs";
7364
7518
  import { join as join33 } from "path";
7365
- import { homedir as homedir14 } from "os";
7519
+ import { homedir as homedir13 } from "os";
7366
7520
  async function applyClaudeAuthToEnv(childEnv, label) {
7367
7521
  const apiKey = getApiKey();
7368
7522
  if (!apiKey) {
@@ -7374,7 +7528,7 @@ async function applyClaudeAuthToEnv(childEnv, label) {
7374
7528
  throw new Error("claude_auth_mode=api_key but /host/exchange returned no decrypted key");
7375
7529
  }
7376
7530
  childEnv.ANTHROPIC_API_KEY = exchange.anthropicApiKey;
7377
- const claudeDir = join33(homedir14(), ".claude");
7531
+ const claudeDir = join33(homedir13(), ".claude");
7378
7532
  for (const filename of [".credentials.json", "credentials.json"]) {
7379
7533
  const p = join33(claudeDir, filename);
7380
7534
  if (existsSync14(p)) {
@@ -7732,7 +7886,7 @@ function formatBoardForPrompt(items, template) {
7732
7886
  }
7733
7887
 
7734
7888
  // src/lib/manager/kanban/nudge-state-cache.ts
7735
- import { existsSync as existsSync15, readFileSync as readFileSync26, writeFileSync as writeFileSync13 } from "fs";
7889
+ import { existsSync as existsSync15, readFileSync as readFileSync27, writeFileSync as writeFileSync13 } from "fs";
7736
7890
  import { join as join34 } from "path";
7737
7891
  var CACHE_FILENAME2 = "kanban-nudge-state.json";
7738
7892
  var KANBAN_NUDGE_STATE_VERSION = 1;
@@ -7744,7 +7898,7 @@ function loadKanbanNudgeState(target, configDir) {
7744
7898
  if (!existsSync15(path)) return;
7745
7899
  let parsed;
7746
7900
  try {
7747
- parsed = JSON.parse(readFileSync26(path, "utf-8"));
7901
+ parsed = JSON.parse(readFileSync27(path, "utf-8"));
7748
7902
  } catch {
7749
7903
  return;
7750
7904
  }
@@ -8362,8 +8516,8 @@ function closeSessionRunForCode(codeName, outcome, reason) {
8362
8516
 
8363
8517
  // src/lib/manager/scheduler/kanban-route.ts
8364
8518
  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";
8366
- import { homedir as homedir15 } from "os";
8519
+ import { writeFileSync as writeFileSync14, renameSync as renameSync8, mkdirSync as mkdirSync11, readFileSync as readFileSync28, unlinkSync as unlinkSync3 } from "fs";
8520
+ import { homedir as homedir14 } from "os";
8367
8521
  import { join as join35, dirname as dirname9 } from "path";
8368
8522
 
8369
8523
  // src/lib/manager/scheduler/notify.ts
@@ -8723,7 +8877,7 @@ function resolveScheduledSlackTarget(task) {
8723
8877
  }
8724
8878
  function stampScheduledTurnMarker(codeName, taskId, target) {
8725
8879
  try {
8726
- const file = join35(homedir15(), ".augmented", codeName, SCHEDULED_TURN_MARKER_FILENAME);
8880
+ const file = join35(homedir14(), ".augmented", codeName, SCHEDULED_TURN_MARKER_FILENAME);
8727
8881
  const marker = { ts: Date.now(), task_id: taskId, ...target ? { target } : {} };
8728
8882
  const tmp = `${file}.tmp`;
8729
8883
  writeFileSync14(tmp, JSON.stringify(marker), "utf8");
@@ -8733,9 +8887,9 @@ function stampScheduledTurnMarker(codeName, taskId, target) {
8733
8887
  }
8734
8888
  }
8735
8889
  function clearScheduledTurnMarkerForTask(codeName, taskId) {
8736
- const file = join35(homedir15(), ".augmented", codeName, SCHEDULED_TURN_MARKER_FILENAME);
8890
+ const file = join35(homedir14(), ".augmented", codeName, SCHEDULED_TURN_MARKER_FILENAME);
8737
8891
  try {
8738
- const raw = JSON.parse(readFileSync27(file, "utf8"));
8892
+ const raw = JSON.parse(readFileSync28(file, "utf8"));
8739
8893
  if (typeof raw?.task_id !== "string" || raw.task_id !== taskId) return;
8740
8894
  unlinkSync3(file);
8741
8895
  log(`[scheduled-kanban] scheduled-turn marker cleared for '${codeName}' (task ${taskId} complete)`);
@@ -8795,7 +8949,7 @@ async function routeScheduledTaskViaKanban(codeName, agentId, task, prompt, dura
8795
8949
  return false;
8796
8950
  }
8797
8951
  try {
8798
- const doorbell = directChatDoorbellPath(agentId, homedir15());
8952
+ const doorbell = directChatDoorbellPath(agentId, homedir14());
8799
8953
  mkdirSync11(dirname9(doorbell), { recursive: true });
8800
8954
  writeFileSync14(doorbell, String(Date.now()));
8801
8955
  } catch (err) {
@@ -8950,11 +9104,11 @@ async function processClaudeTaskResult(codeName, agentId, templateId, rawOutput,
8950
9104
 
8951
9105
  // src/lib/manager/scheduler/execution.ts
8952
9106
  import { createHash as createHash16 } from "crypto";
8953
- import { homedir as homedir16 } from "os";
9107
+ import { homedir as homedir15 } from "os";
8954
9108
  import { join as join37 } from "path";
8955
9109
 
8956
9110
  // src/lib/agent-serving-probe.ts
8957
- import { readFileSync as readFileSync28, readdirSync as readdirSync8, statSync as statSync10 } from "fs";
9111
+ import { readFileSync as readFileSync29, readdirSync as readdirSync8, statSync as statSync10 } from "fs";
8958
9112
  import { join as join36 } from "path";
8959
9113
  var RATE_LIMIT_WINDOW_MS = 6 * 60 * 60 * 1e3;
8960
9114
  function probeRateLimit(args) {
@@ -8980,7 +9134,7 @@ function probeRateLimit(args) {
8980
9134
  }
8981
9135
  let content;
8982
9136
  try {
8983
- content = readFileSync28(path, "utf-8");
9137
+ content = readFileSync29(path, "utf-8");
8984
9138
  } catch {
8985
9139
  continue;
8986
9140
  }
@@ -9042,7 +9196,7 @@ function shouldLogUsageCapDeferral(site, codeName, limitedUntil) {
9042
9196
 
9043
9197
  // src/lib/manager/scheduler/execution.ts
9044
9198
  function claudePidFilePath() {
9045
- return join37(homedir16(), ".augmented", "manager-claude-pids.json");
9199
+ return join37(homedir15(), ".augmented", "manager-claude-pids.json");
9046
9200
  }
9047
9201
  var inFlightClaudePids = /* @__PURE__ */ new Map();
9048
9202
  function registerClaudeSpawn(record) {
@@ -9442,7 +9596,7 @@ function stopPaneOccupancySampler() {
9442
9596
  }
9443
9597
 
9444
9598
  // src/lib/pid-pressure-sampler.ts
9445
- import { existsSync as existsSync16, readFileSync as readFileSync29 } from "fs";
9599
+ import { existsSync as existsSync16, readFileSync as readFileSync30 } from "fs";
9446
9600
  var SAMPLE_INTERVAL_MS2 = 3e4;
9447
9601
  function warnFraction() {
9448
9602
  const raw = Number(process.env.AGT_PID_PRESSURE_WARN_FRACTION);
@@ -9470,7 +9624,7 @@ function parseMemoryEvents(text) {
9470
9624
  }
9471
9625
  function readTextReal(path) {
9472
9626
  try {
9473
- return readFileSync29(path, "utf-8");
9627
+ return readFileSync30(path, "utf-8");
9474
9628
  } catch {
9475
9629
  return null;
9476
9630
  }
@@ -10753,7 +10907,7 @@ async function fireOpencodeScheduledTask(agent, task) {
10753
10907
 
10754
10908
  // src/lib/opencode-telegram-ingest.ts
10755
10909
  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";
10910
+ import { existsSync as existsSync17, mkdirSync as mkdirSync12, readFileSync as readFileSync31, renameSync as renameSync9, unlinkSync as unlinkSync4, writeFileSync as writeFileSync15 } from "fs";
10757
10911
  import { randomUUID } from "crypto";
10758
10912
  import { join as join39 } from "path";
10759
10913
 
@@ -11321,7 +11475,7 @@ function createFileOffsetStore(codeName, log2, currentBotId) {
11321
11475
  load() {
11322
11476
  if (!filePath) return 0;
11323
11477
  try {
11324
- const parsed = JSON.parse(readFileSync30(filePath, "utf-8"));
11478
+ const parsed = JSON.parse(readFileSync31(filePath, "utf-8"));
11325
11479
  if (currentBotId != null && typeof parsed?.bot_id === "number" && parsed.bot_id !== currentBotId) {
11326
11480
  log2(`[telegram-ingest:${codeName}] offset cursor belongs to a different bot; ignoring (bot swap)`);
11327
11481
  return 0;
@@ -11595,12 +11749,12 @@ function partitionActionableByPoison(actionable, states, config2) {
11595
11749
  }
11596
11750
 
11597
11751
  // 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";
11599
- import { homedir as homedir17 } from "os";
11752
+ import { existsSync as existsSync18, mkdirSync as mkdirSync13, readdirSync as readdirSync10, readFileSync as readFileSync32, renameSync as renameSync10, rmSync as rmSync7, writeFileSync as writeFileSync16 } from "fs";
11753
+ import { homedir as homedir16 } from "os";
11600
11754
  import { join as join40 } from "path";
11601
11755
  import { randomUUID as randomUUID2 } from "crypto";
11602
11756
  function restartFlagsDir() {
11603
- return join40(homedir17(), ".augmented", "restart-flags");
11757
+ return join40(homedir16(), ".augmented", "restart-flags");
11604
11758
  }
11605
11759
  function flagPath(codeName) {
11606
11760
  return join40(restartFlagsDir(), `${codeName}.flag`);
@@ -11612,7 +11766,7 @@ function readRestartFlags() {
11612
11766
  for (const entry of readdirSync10(dir)) {
11613
11767
  if (!entry.endsWith(".flag")) continue;
11614
11768
  try {
11615
- const raw = readFileSync31(join40(dir, entry), "utf8");
11769
+ const raw = readFileSync32(join40(dir, entry), "utf8");
11616
11770
  const parsed = JSON.parse(raw);
11617
11771
  if (typeof parsed.codeName !== "string" || parsed.codeName.length === 0) {
11618
11772
  parsed.codeName = entry.replace(/\.flag$/, "");
@@ -11730,7 +11884,7 @@ async function sendError(flag, opts, text) {
11730
11884
  }
11731
11885
 
11732
11886
  // src/lib/restart-context.ts
11733
- import { readdirSync as readdirSync11, readFileSync as readFileSync32, writeFileSync as writeFileSync17, mkdirSync as mkdirSync14, unlinkSync as unlinkSync5 } from "fs";
11887
+ import { readdirSync as readdirSync11, readFileSync as readFileSync33, writeFileSync as writeFileSync17, mkdirSync as mkdirSync14, unlinkSync as unlinkSync5 } from "fs";
11734
11888
  import { dirname as dirname10, join as join41 } from "path";
11735
11889
  var SLACK_PENDING_INBOUND_DIRNAME = "slack-pending-inbound";
11736
11890
  var SLACK_RESTART_CONTEXT_DIRNAME = "slack-restart-context";
@@ -11788,7 +11942,7 @@ function safeReaddir(dir) {
11788
11942
  }
11789
11943
  function readStrandedMarker(path) {
11790
11944
  try {
11791
- const parsed = JSON.parse(readFileSync32(path, "utf-8"));
11945
+ const parsed = JSON.parse(readFileSync33(path, "utf-8"));
11792
11946
  if (typeof parsed.channel === "string" && typeof parsed.thread_ts === "string") {
11793
11947
  return { channel: parsed.channel, thread_ts: parsed.thread_ts };
11794
11948
  }
@@ -13311,7 +13465,7 @@ var pendingDayRolloverReset = /* @__PURE__ */ new Set();
13311
13465
  var dayRolloverInboundHold = /* @__PURE__ */ new Map();
13312
13466
  var INBOUND_HOLD_EPISODE_GAP_MS = 12e4;
13313
13467
  async function channelInboundActivityAgeSecondsFor(codeName) {
13314
- const { newestPendingInboundActivityMtimeMs } = await import("../responsiveness-probe-6NWZAXIZ.js");
13468
+ const { newestPendingInboundActivityMtimeMs } = await import("../responsiveness-probe-J2DYGC7T.js");
13315
13469
  const newest = newestPendingInboundActivityMtimeMs(dirname11(paneLogPath(codeName)));
13316
13470
  if (newest === null) return null;
13317
13471
  return Math.max(0, Math.floor((Date.now() - newest) / 1e3));
@@ -13636,7 +13790,7 @@ var runningChannelSecretHashes = /* @__PURE__ */ new Map();
13636
13790
  var sessionLaunchManagedStructure = /* @__PURE__ */ new Map();
13637
13791
  function projectMcpHash(_codeName, projectDir) {
13638
13792
  try {
13639
- const raw = readFileSync33(join42(projectDir, ".mcp.json"), "utf-8");
13793
+ const raw = readFileSync34(join42(projectDir, ".mcp.json"), "utf-8");
13640
13794
  return createHash20("sha256").update(canonicalJson(JSON.parse(raw))).digest("hex");
13641
13795
  } catch {
13642
13796
  return null;
@@ -13644,7 +13798,7 @@ function projectMcpHash(_codeName, projectDir) {
13644
13798
  }
13645
13799
  function projectMcpKeys(_codeName, projectDir) {
13646
13800
  try {
13647
- const raw = readFileSync33(join42(projectDir, ".mcp.json"), "utf-8");
13801
+ const raw = readFileSync34(join42(projectDir, ".mcp.json"), "utf-8");
13648
13802
  const parsed = JSON.parse(raw);
13649
13803
  const servers = parsed.mcpServers;
13650
13804
  if (!servers || typeof servers !== "object") return /* @__PURE__ */ new Set();
@@ -13662,7 +13816,7 @@ function seedSessionLaunchBaselines(codeName, projectDir) {
13662
13816
  else runningMcpServerKeys.delete(codeName);
13663
13817
  let launchStructure = null;
13664
13818
  try {
13665
- const raw = readFileSync33(join42(projectDir, ".mcp.json"), "utf-8");
13819
+ const raw = readFileSync34(join42(projectDir, ".mcp.json"), "utf-8");
13666
13820
  launchStructure = managedMcpStructureHashFromFile(
13667
13821
  JSON.parse(raw),
13668
13822
  isManagedMcpServerKey
@@ -13797,7 +13951,7 @@ async function runAgentSessionToolBindProbes(agent, integrations, projectDir, op
13797
13951
  if (result && result.rebindCandidates.length > 0 && hostFlagStore().getBoolean("session-tool-rebind")) {
13798
13952
  let mcpJsonForRebind = null;
13799
13953
  try {
13800
- mcpJsonForRebind = JSON.parse(readFileSync33(join42(projectDir, ".mcp.json"), "utf-8"));
13954
+ mcpJsonForRebind = JSON.parse(readFileSync34(join42(projectDir, ".mcp.json"), "utf-8"));
13801
13955
  } catch {
13802
13956
  mcpJsonForRebind = null;
13803
13957
  }
@@ -13945,7 +14099,7 @@ function shouldInjectChannelSecrets(agentId) {
13945
14099
  function projectChannelSecretHash(projectDir) {
13946
14100
  try {
13947
14101
  const entries = parseEnvIntegrations(
13948
- readFileSync33(join42(projectDir, ".env.integrations"), "utf-8")
14102
+ readFileSync34(join42(projectDir, ".env.integrations"), "utf-8")
13949
14103
  );
13950
14104
  return channelSecretValueHash(entries, CHANNEL_SECRET_ENV_KEYS);
13951
14105
  } catch {
@@ -14054,7 +14208,7 @@ var agentRestartTimezoneInputs = /* @__PURE__ */ new Map();
14054
14208
  var lastVersionCheckAt = 0;
14055
14209
  var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
14056
14210
  var lastResponsivenessProbeAt = 0;
14057
- var agtCliVersion = true ? "0.28.1005" : "dev";
14211
+ var agtCliVersion = true ? "0.28.1007" : "dev";
14058
14212
  function resolveBrewPath(execFileSync2) {
14059
14213
  try {
14060
14214
  const out = execFileSync2("which", ["brew"], { timeout: 5e3 }).toString().trim();
@@ -14389,7 +14543,7 @@ function ensureClaudeManagedSettings(path = claudeManagedSettingsPath()) {
14389
14543
  try {
14390
14544
  let settings = {};
14391
14545
  if (existsSync19(path)) {
14392
- const raw = readFileSync33(path, "utf-8").trim();
14546
+ const raw = readFileSync34(path, "utf-8").trim();
14393
14547
  if (raw) {
14394
14548
  let parsed;
14395
14549
  try {
@@ -14596,7 +14750,7 @@ async function maybeUpgradeClaudeCode() {
14596
14750
  }
14597
14751
  var UPDATE_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
14598
14752
  function selfUpdateAppliedMarkerPath() {
14599
- return join42(homedir18(), ".augmented", ".last-self-update-applied");
14753
+ return join42(homedir17(), ".augmented", ".last-self-update-applied");
14600
14754
  }
14601
14755
  var selfUpdateUpToDateLogged = false;
14602
14756
  var selfUpdatePinnedLogged = false;
@@ -14647,7 +14801,7 @@ async function checkAndUpdateCli(opts) {
14647
14801
  const isNpmGlobal = !isBrewFormula && resolvedPath.includes("node_modules");
14648
14802
  if (!isBrewFormula && !isNpmGlobal) return "noop";
14649
14803
  const { readFileSync: readF, writeFileSync: writeF } = await import("fs");
14650
- const markerPath = join42(homedir18(), ".augmented", ".last-update-check");
14804
+ const markerPath = join42(homedir17(), ".augmented", ".last-update-check");
14651
14805
  if (!force) {
14652
14806
  try {
14653
14807
  const lastCheck = parseInt(readF(markerPath, "utf-8").trim(), 10);
@@ -15058,7 +15212,7 @@ async function runClaudeRuntimeAuthProbe() {
15058
15212
  ];
15059
15213
  try {
15060
15214
  const { stdout, stderr } = await execFilePromiseLong(resolveClaudeBinary(), args, {
15061
- cwd: homedir18(),
15215
+ cwd: homedir17(),
15062
15216
  timeout: RUNTIME_AUTH_PROBE_TIMEOUT_MS,
15063
15217
  stdin: "ignore",
15064
15218
  env: childEnv,
@@ -15098,7 +15252,7 @@ async function runHostUsageCommand() {
15098
15252
  ""
15099
15253
  ];
15100
15254
  const { stdout } = await execFilePromiseLong(resolveClaudeBinary(), args, {
15101
- cwd: homedir18(),
15255
+ cwd: homedir17(),
15102
15256
  timeout: HOST_USAGE_POLL_TIMEOUT_MS,
15103
15257
  stdin: "ignore",
15104
15258
  env: childEnv,
@@ -15145,7 +15299,7 @@ async function checkClaudeAuth() {
15145
15299
  var evalEmptyMcpConfigPath = null;
15146
15300
  function ensureEvalEmptyMcpConfig() {
15147
15301
  if (evalEmptyMcpConfigPath && existsSync19(evalEmptyMcpConfigPath)) return evalEmptyMcpConfigPath;
15148
- const dir = join42(homedir18(), ".augmented");
15302
+ const dir = join42(homedir17(), ".augmented");
15149
15303
  try {
15150
15304
  mkdirSync15(dir, { recursive: true });
15151
15305
  } catch {
@@ -15176,7 +15330,7 @@ async function runEvalClaude(prompt, model) {
15176
15330
  ""
15177
15331
  ];
15178
15332
  const { stdout } = await execFilePromiseLong(resolveClaudeBinary(), args, {
15179
- cwd: homedir18(),
15333
+ cwd: homedir17(),
15180
15334
  timeout: 12e4,
15181
15335
  stdin: "ignore",
15182
15336
  env: childEnv,
@@ -15466,6 +15620,24 @@ function channelQuarantineStore() {
15466
15620
  }
15467
15621
  return _channelQuarantineStore;
15468
15622
  }
15623
+ var _channelResumeHistoryStore = null;
15624
+ function channelResumeHistoryStore() {
15625
+ if (!_channelResumeHistoryStore) {
15626
+ const dir = config?.configDir ?? join42(process.env["HOME"] ?? "/tmp", ".augmented");
15627
+ _channelResumeHistoryStore = new ChannelResumeHistoryStore(defaultResumeHistoryPath(dir));
15628
+ }
15629
+ return _channelResumeHistoryStore;
15630
+ }
15631
+ var autoResumeDowngradeLogged = /* @__PURE__ */ new Set();
15632
+ function shouldLogAutoResumeModeDowngrade(autoResume, quarantine) {
15633
+ const key = `${autoResume}->${quarantine}`;
15634
+ if (autoResumeDowngradeLogged.has(key)) return false;
15635
+ autoResumeDowngradeLogged.add(key);
15636
+ return true;
15637
+ }
15638
+ function channelQuarantineAutoResumeMode() {
15639
+ return hostFlagStore().getString("channel-quarantine-auto-resume");
15640
+ }
15469
15641
  function quarantineEntriesFor(codeName) {
15470
15642
  return channelQuarantineStore().getQuarantineEntries(codeName);
15471
15643
  }
@@ -15670,7 +15842,7 @@ function flushRestartedAgentDiagnostics(hostId, codeNames) {
15670
15842
  if (codeNames.length === 0) return;
15671
15843
  void (async () => {
15672
15844
  try {
15673
- const { collectDiagnostics } = await import("../persistent-session-4PP3ON7H.js");
15845
+ const { collectDiagnostics } = await import("../persistent-session-5KWYODZB.js");
15674
15846
  await api.post("/host/heartbeat", {
15675
15847
  host_id: hostId,
15676
15848
  agent_diagnostics: collectDiagnostics(codeNames, quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor)
@@ -15812,7 +15984,7 @@ async function pollCycleInner() {
15812
15984
  }
15813
15985
  try {
15814
15986
  const { detectHostSecurity } = await import("../host-security-KQYYZZVW.js");
15815
- const { collectDiagnostics } = await import("../persistent-session-4PP3ON7H.js");
15987
+ const { collectDiagnostics } = await import("../persistent-session-5KWYODZB.js");
15816
15988
  const diagCodeNames = [...agentState.persistentSessionAgents];
15817
15989
  const agentDiagnostics = diagCodeNames.length > 0 ? collectDiagnostics(diagCodeNames, quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor) : void 0;
15818
15990
  let tailscaleHostname;
@@ -15968,7 +16140,7 @@ async function pollCycleInner() {
15968
16140
  try {
15969
16141
  const desiredClaudeCodeVersion = hbResp?.desired_claude_code_version?.trim();
15970
16142
  if (desiredClaudeCodeVersion && decideMaintenanceWindowGate({ window: cachedMaintenanceWindow, now: /* @__PURE__ */ new Date() }) === "proceed") {
15971
- const { maybeUpdateClaudeCode } = await import("../claude-code-updater-45MB2AXE.js");
16143
+ const { maybeUpdateClaudeCode } = await import("../claude-code-updater-NEJCTT7S.js");
15972
16144
  await maybeUpdateClaudeCode({
15973
16145
  desiredVersion: desiredClaudeCodeVersion,
15974
16146
  currentVersion: cachedFrameworkVersion,
@@ -15988,7 +16160,7 @@ async function pollCycleInner() {
15988
16160
  collectPanelessActivityProbes,
15989
16161
  getResponsivenessIntervalMs,
15990
16162
  occupancyQualificationClassifications
15991
- } = await import("../responsiveness-probe-6NWZAXIZ.js");
16163
+ } = await import("../responsiveness-probe-J2DYGC7T.js");
15992
16164
  const probeIntervalMs = getResponsivenessIntervalMs();
15993
16165
  if (now - lastResponsivenessProbeAt > probeIntervalMs) {
15994
16166
  const probeCodeNames = [...agentState.persistentSessionAgents];
@@ -16105,7 +16277,7 @@ async function pollCycleInner() {
16105
16277
  collectResponsivenessProbes,
16106
16278
  livePendingInboundOldestAgeSeconds,
16107
16279
  parkPendingInbound
16108
- } = await import("../responsiveness-probe-6NWZAXIZ.js");
16280
+ } = await import("../responsiveness-probe-J2DYGC7T.js");
16109
16281
  const { getProjectDir: wedgeProjectDir } = await import("../scheduler-engine-M6AFZWNU.js");
16110
16282
  const wedgeNow = /* @__PURE__ */ new Date();
16111
16283
  const liveAgents = agentState.persistentSessionAgents;
@@ -16194,10 +16366,10 @@ async function pollCycleInner() {
16194
16366
  );
16195
16367
  if (hostFlagStore().getBoolean("wedge-transient-notice")) {
16196
16368
  try {
16197
- const paneTail = readFileSync33(paneLogPath(codeName), "utf8").slice(-65536);
16369
+ const paneTail = readFileSync34(paneLogPath(codeName), "utf8").slice(-65536);
16198
16370
  const transient = detectTransientApiErrorInLog(paneTail);
16199
16371
  if (transient) {
16200
- const wedgeHome = join42(homedir18(), ".augmented", codeName);
16372
+ const wedgeHome = join42(homedir17(), ".augmented", codeName);
16201
16373
  if (existsSync19(wedgeHome)) {
16202
16374
  atomicWriteFileSync(
16203
16375
  join42(wedgeHome, "watchdog-give-up.json"),
@@ -16261,7 +16433,7 @@ async function pollCycleInner() {
16261
16433
  }
16262
16434
  try {
16263
16435
  const { scrapeMcpFailedBannerCount } = await import("../pane-mcp-banner-scraper-VR5QGP3J.js");
16264
- const { probeSessionAuth } = await import("../session-auth-dead-2V2BOXAG.js");
16436
+ const { probeSessionAuth } = await import("../session-auth-dead-4SE5Q7MU.js");
16265
16437
  const observations = [];
16266
16438
  const pendingCacheCommits = [];
16267
16439
  const modelApiErrorReportingOn = hostFlagStore().getBoolean("model-api-error-reporting");
@@ -16417,6 +16589,12 @@ async function pollCycleInner() {
16417
16589
  agent.code_name,
16418
16590
  clear.channel_id
16419
16591
  );
16592
+ for (const mode of ["enforce", "shadow"]) {
16593
+ channelResumeHistoryStore().forget(
16594
+ agent.code_name,
16595
+ resumeHistoryKey(mode, clear.channel_id)
16596
+ );
16597
+ }
16420
16598
  log(
16421
16599
  `[channel-reenable] ${removed ? "cleared" : "no marker for"} '${clear.channel_id}' on '${agent.code_name}' (operator re-enable)`
16422
16600
  );
@@ -16431,6 +16609,92 @@ async function pollCycleInner() {
16431
16609
  );
16432
16610
  }
16433
16611
  }
16612
+ const autoResumeMode = channelQuarantineAutoResumeMode();
16613
+ const quarantineMode = channelQuarantineMode();
16614
+ const autoResumeEffective = resolveAutoResumeEffectiveMode(autoResumeMode, quarantineMode);
16615
+ if (autoResumeMode === "enforce" && autoResumeEffective === "shadow") {
16616
+ if (shouldLogAutoResumeModeDowngrade(autoResumeMode, quarantineMode)) {
16617
+ log(
16618
+ `[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.`
16619
+ );
16620
+ }
16621
+ }
16622
+ if (autoResumeEffective !== "off") {
16623
+ const nowMs = Date.now();
16624
+ for (const agent of agents) {
16625
+ if (agent.status !== "active") continue;
16626
+ try {
16627
+ const quarantineEntries = channelQuarantineStore().getQuarantineEntries(agent.code_name);
16628
+ const quarantinedKeys = new Set(quarantineEntries.map((e) => e.serverKey));
16629
+ for (const [storedKey, history] of channelResumeHistoryStore().entriesFor(agent.code_name)) {
16630
+ const isShadowKey = storedKey.startsWith("shadow:");
16631
+ if (isShadowKey !== (autoResumeEffective === "shadow")) continue;
16632
+ const serverKey = isShadowKey ? storedKey.slice("shadow:".length) : storedKey;
16633
+ if (!shouldForgetResumeHistory({
16634
+ isQuarantined: quarantinedKeys.has(serverKey),
16635
+ history,
16636
+ now: nowMs,
16637
+ // THE CONFIGURED DWELL, NOT THE FLOOR (obi-wan `7414dbf3d758`).
16638
+ // A host that raised AGT_CHANNEL_QUARANTINE_DWELL_MS pushes
16639
+ // re-quarantine PAST the floor-derived grace, so a failed trial
16640
+ // read as a success and wiped the strikes - restarting the
16641
+ // five-attempt budget every episode, forever.
16642
+ configuredDwellMs: channelQuarantineDwellMs()
16643
+ })) {
16644
+ continue;
16645
+ }
16646
+ channelResumeHistoryStore().forget(agent.code_name, storedKey);
16647
+ log(
16648
+ `[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)" : "")
16649
+ );
16650
+ }
16651
+ for (const entry of quarantineEntries) {
16652
+ const historyKeyFor = (key) => resumeHistoryKey(autoResumeEffective, key);
16653
+ const historyKey = historyKeyFor(entry.serverKey);
16654
+ const history = channelResumeHistoryStore().get(agent.code_name, historyKey);
16655
+ const decision = decideChannelAutoResume({
16656
+ quarantinedAt: entry.quarantinedAt,
16657
+ history,
16658
+ now: nowMs
16659
+ });
16660
+ if (decision.action === "wait") continue;
16661
+ if (decision.action === "give-up") {
16662
+ if (!channelResumeHistoryStore().noteGaveUpLogged(agent.code_name, historyKeyFor(entry.serverKey))) {
16663
+ log(
16664
+ 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.`
16665
+ );
16666
+ }
16667
+ continue;
16668
+ }
16669
+ const quarantineAgeMin = Math.round((nowMs - entry.quarantinedAt) / 6e4);
16670
+ const waitedMin = Math.round(decision.waitedMs / 6e4);
16671
+ const recorded = channelResumeHistoryStore().recordAttempt(
16672
+ agent.code_name,
16673
+ historyKey,
16674
+ nowMs
16675
+ );
16676
+ if (autoResumeEffective === "shadow") {
16677
+ log(
16678
+ `[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`
16679
+ );
16680
+ continue;
16681
+ }
16682
+ const cleared = channelQuarantineStore().clearQuarantine(
16683
+ agent.code_name,
16684
+ entry.serverKey
16685
+ );
16686
+ log(
16687
+ `[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.`
16688
+ );
16689
+ }
16690
+ } catch (err) {
16691
+ log(
16692
+ `[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".`
16693
+ );
16694
+ continue;
16695
+ }
16696
+ }
16697
+ }
16434
16698
  const frameworksThisCycle = new Set(agents.map((a) => a.framework).filter(Boolean));
16435
16699
  for (const fw of frameworksThisCycle) {
16436
16700
  await ensureFrameworkBinary(fw);
@@ -16637,7 +16901,7 @@ async function pollCycleInner() {
16637
16901
  // pending-inbound marker. Best-effort: a write failure is logged by
16638
16902
  // the watchdog, never fails the poll cycle.
16639
16903
  signalGiveUp: (codeName) => {
16640
- const dir = join42(homedir18(), ".augmented", codeName);
16904
+ const dir = join42(homedir17(), ".augmented", codeName);
16641
16905
  if (!existsSync19(dir)) return;
16642
16906
  atomicWriteFileSync(
16643
16907
  join42(dir, "watchdog-give-up.json"),
@@ -17249,7 +17513,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
17249
17513
  newHash = sha256(stripDynamicSections(artifact.content));
17250
17514
  try {
17251
17515
  const projectClaudeMd = join42(config.configDir, agent.code_name, "project", "CLAUDE.md");
17252
- const existing = readFileSync33(projectClaudeMd, "utf-8");
17516
+ const existing = readFileSync34(projectClaudeMd, "utf-8");
17253
17517
  existingHash = sha256(stripDynamicSections(existing));
17254
17518
  } catch {
17255
17519
  existingHash = null;
@@ -17267,7 +17531,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
17267
17531
  const generatorKeys = Object.keys(generatorServers);
17268
17532
  let existingRaw = "";
17269
17533
  try {
17270
- existingRaw = readFileSync33(filePath, "utf-8");
17534
+ existingRaw = readFileSync34(filePath, "utf-8");
17271
17535
  } catch {
17272
17536
  }
17273
17537
  const existingServers = parseMcp(existingRaw);
@@ -17283,7 +17547,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
17283
17547
  } else if (artifact.relativePath === "opencode.json") {
17284
17548
  let existingRaw = null;
17285
17549
  try {
17286
- existingRaw = readFileSync33(filePath, "utf-8");
17550
+ existingRaw = readFileSync34(filePath, "utf-8");
17287
17551
  } catch {
17288
17552
  }
17289
17553
  const mergeResult = mergeOpencodeConfigArtifact(artifact.content, existingRaw);
@@ -17727,7 +17991,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
17727
17991
  const addedChannels = [...restartDecision.added];
17728
17992
  const writeDmNoticeMarkers = isChannelAddRestart ? () => {
17729
17993
  try {
17730
- const agentAugmentedDir = join42(homedir18(), ".augmented", agent.code_name);
17994
+ const agentAugmentedDir = join42(homedir17(), ".augmented", agent.code_name);
17731
17995
  mkdirSync15(agentAugmentedDir, { recursive: true });
17732
17996
  const markerJson = JSON.stringify({
17733
17997
  version: 1,
@@ -18034,18 +18298,18 @@ async function processAgent(agent, agentStates, managedToolkits) {
18034
18298
  if (agentSessionMode === "persistent" && (agentFrameworkCache.get(agent.code_name) ?? DEFAULT_FRAMEWORK) === "claude-code") {
18035
18299
  try {
18036
18300
  const agentProvisionDir = agentDir;
18037
- const projectDir = join42(homedir18(), ".augmented", agent.code_name, "project");
18301
+ const projectDir = join42(homedir17(), ".augmented", agent.code_name, "project");
18038
18302
  mkdirSync15(agentProvisionDir, { recursive: true });
18039
18303
  mkdirSync15(projectDir, { recursive: true });
18040
18304
  const provisionMcpPath = join42(agentProvisionDir, ".mcp.json");
18041
18305
  const projectMcpPath = join42(projectDir, ".mcp.json");
18042
18306
  let mcpConfig = { mcpServers: {} };
18043
18307
  try {
18044
- mcpConfig = JSON.parse(readFileSync33(provisionMcpPath, "utf-8"));
18308
+ mcpConfig = JSON.parse(readFileSync34(provisionMcpPath, "utf-8"));
18045
18309
  if (!mcpConfig.mcpServers) mcpConfig.mcpServers = {};
18046
18310
  } catch {
18047
18311
  }
18048
- const localDirectChatChannel = join42(homedir18(), ".augmented", "_mcp", "direct-chat-channel.js");
18312
+ const localDirectChatChannel = join42(homedir17(), ".augmented", "_mcp", "direct-chat-channel.js");
18049
18313
  const directChatTeamSettings = refreshData.team?.settings;
18050
18314
  const directChatTz = (() => {
18051
18315
  const tz = directChatTeamSettings?.["timezone"];
@@ -18204,7 +18468,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
18204
18468
  }
18205
18469
  if (hostFlagStore().getBoolean("connectivity-probe")) {
18206
18470
  try {
18207
- const probeProjectDir = join42(homedir18(), ".augmented", agent.code_name, "project");
18471
+ const probeProjectDir = join42(homedir17(), ".augmented", agent.code_name, "project");
18208
18472
  let probeSet = integrations;
18209
18473
  const fetchQuarantined = async () => {
18210
18474
  const quarantined = await api.post("/host/agent-integrations/quarantined", { agent_id: agent.agent_id });
@@ -18264,7 +18528,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
18264
18528
  const forceDue = attemptsLeft > 0;
18265
18529
  let probeRan = false;
18266
18530
  try {
18267
- const probeProjectDir = join42(homedir18(), ".augmented", agent.code_name, "project");
18531
+ const probeProjectDir = join42(homedir17(), ".augmented", agent.code_name, "project");
18268
18532
  probeRan = await runAgentSessionToolBindProbes(agent, integrations, probeProjectDir, { forceDue });
18269
18533
  } catch (err) {
18270
18534
  log(`Session-tool-bind probe failed for '${agent.code_name}': ${err.message}`);
@@ -18341,11 +18605,11 @@ async function processAgent(agent, agentStates, managedToolkits) {
18341
18605
  const intHash = computeIntegrationsHash(integrations);
18342
18606
  const prevIntHash = agentState.knownIntegrationHashes.get(agent.agent_id);
18343
18607
  if (intHash !== prevIntHash) {
18344
- const projectDir = join42(homedir18(), ".augmented", agent.code_name, "project");
18608
+ const projectDir = join42(homedir17(), ".augmented", agent.code_name, "project");
18345
18609
  const envIntPath = join42(projectDir, ".env.integrations");
18346
18610
  let preWriteEnv;
18347
18611
  try {
18348
- preWriteEnv = readFileSync33(envIntPath, "utf-8");
18612
+ preWriteEnv = readFileSync34(envIntPath, "utf-8");
18349
18613
  } catch {
18350
18614
  preWriteEnv = void 0;
18351
18615
  }
@@ -18365,8 +18629,8 @@ async function processAgent(agent, agentStates, managedToolkits) {
18365
18629
  if (fw === "claude-code" && isSessionHealthy(agent.code_name)) {
18366
18630
  try {
18367
18631
  const projectMcpPath = join42(projectDir, ".mcp.json");
18368
- const postWriteEnv = readFileSync33(envIntPath, "utf-8");
18369
- const mcpContent = readFileSync33(projectMcpPath, "utf-8");
18632
+ const postWriteEnv = readFileSync34(envIntPath, "utf-8");
18633
+ const mcpContent = readFileSync34(projectMcpPath, "utf-8");
18370
18634
  const changedVars = diffEnvIntegrations(preWriteEnv, postWriteEnv);
18371
18635
  const mcpJsonForReap = JSON.parse(mcpContent);
18372
18636
  const affectedServerKeys = findMcpServersUsingVars(mcpJsonForReap, changedVars);
@@ -18665,13 +18929,13 @@ async function processAgent(agent, agentStates, managedToolkits) {
18665
18929
  }
18666
18930
  try {
18667
18931
  const { readdirSync: readdirSync13, rmSync: rmSync9 } = await import("fs");
18668
- const { homedir: homedir19 } = await import("os");
18932
+ const { homedir: homedir18 } = await import("os");
18669
18933
  const frameworkId2 = frameworkAdapter.id;
18670
18934
  const candidateSkillDirs = [
18671
18935
  // Claude Code — framework runtime tree
18672
- join42(homedir19(), ".augmented", agent.code_name, "skills"),
18936
+ join42(homedir18(), ".augmented", agent.code_name, "skills"),
18673
18937
  // Claude Code — project tree
18674
- join42(homedir19(), ".augmented", agent.code_name, "project", ".claude", "skills"),
18938
+ join42(homedir18(), ".augmented", agent.code_name, "project", ".claude", "skills"),
18675
18939
  // Defensive: legacy provision-side path, not currently an
18676
18940
  // install target but cheap to sweep.
18677
18941
  join42(agentDir, ".claude", "skills")
@@ -18717,7 +18981,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
18717
18981
  const sharedSkillsPayload = refreshAny.shared_skills;
18718
18982
  const desiredResolved = globalSkillsPayload !== void 0 || sharedSkillsPayload !== void 0;
18719
18983
  const manifestPath = managedSkillManifestPath(
18720
- join42(homedir18(), ".augmented", agent.code_name)
18984
+ join42(homedir17(), ".augmented", agent.code_name)
18721
18985
  );
18722
18986
  const prevIds = /* @__PURE__ */ new Set([
18723
18987
  ...agentState.knownGlobalSkillIds.get(agent.agent_id) ?? /* @__PURE__ */ new Set(),
@@ -18737,8 +19001,8 @@ async function processAgent(agent, agentStates, managedToolkits) {
18737
19001
  }
18738
19002
  if (plan.removes.length) {
18739
19003
  const globalSkillDirs = [
18740
- join42(homedir18(), ".augmented", agent.code_name, "skills"),
18741
- join42(homedir18(), ".augmented", agent.code_name, "project", ".claude", "skills"),
19004
+ join42(homedir17(), ".augmented", agent.code_name, "skills"),
19005
+ join42(homedir17(), ".augmented", agent.code_name, "project", ".claude", "skills"),
18742
19006
  join42(agentDir, ".claude", "skills")
18743
19007
  ];
18744
19008
  for (const id of plan.removes) {
@@ -19002,7 +19266,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
19002
19266
  let mcpJsonParsed = null;
19003
19267
  try {
19004
19268
  const mcpPath = join42(getProjectDir(agent.code_name), ".mcp.json");
19005
- mcpJsonParsed = JSON.parse(readFileSync33(mcpPath, "utf-8"));
19269
+ mcpJsonParsed = JSON.parse(readFileSync34(mcpPath, "utf-8"));
19006
19270
  } catch {
19007
19271
  }
19008
19272
  const computerUseIsolated = isolationMode(agent.code_name) === "docker";
@@ -19509,7 +19773,7 @@ Retried to the limit after repeated stalls \u2014 needs a look.`).catch(() => {
19509
19773
  refreshData.agent.onboarding_state
19510
19774
  );
19511
19775
  const obStep = obState.step;
19512
- const markerPath = join42(homedir18(), ".augmented", agent.code_name, "onboarding-drive.json");
19776
+ const markerPath = join42(homedir17(), ".augmented", agent.code_name, "onboarding-drive.json");
19513
19777
  const marker = readOnboardingDriveMarker(markerPath);
19514
19778
  const obContactRaw = refreshData.agent.manager_last_contacted_at;
19515
19779
  const obContact = typeof obContactRaw === "string" && obContactRaw ? obContactRaw : null;
@@ -20549,7 +20813,7 @@ async function handleRestartDoorbell(agentId, requestedAt, restartReason) {
20549
20813
  try {
20550
20814
  const freshId = rotateSessionForWedge(codeName);
20551
20815
  consecutiveWedgeCycles.delete(codeName);
20552
- const { parkPendingInbound: parkForRestart } = await import("../responsiveness-probe-6NWZAXIZ.js");
20816
+ const { parkPendingInbound: parkForRestart } = await import("../responsiveness-probe-J2DYGC7T.js");
20553
20817
  const { parked, deadLettered } = parkForRestart(codeName, /* @__PURE__ */ new Date());
20554
20818
  const parkNote = parked > 0 ? `, ${parked} inbound parked` : "";
20555
20819
  const deadNote = deadLettered > 0 ? `, ${deadLettered} undeliverable dead-lettered` : "";
@@ -20592,7 +20856,7 @@ async function handleRestartDoorbell(agentId, requestedAt, restartReason) {
20592
20856
  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
20857
  void (async () => {
20594
20858
  try {
20595
- const { collectDiagnostics } = await import("../persistent-session-4PP3ON7H.js");
20859
+ const { collectDiagnostics } = await import("../persistent-session-5KWYODZB.js");
20596
20860
  await api.post("/host/heartbeat", {
20597
20861
  host_id: hostId,
20598
20862
  agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor)
@@ -20643,7 +20907,7 @@ async function respawnAgentAfterMcpStop(codeName, reason) {
20643
20907
  }
20644
20908
  try {
20645
20909
  const hostId = await getHostId();
20646
- const { collectDiagnostics } = await import("../persistent-session-4PP3ON7H.js");
20910
+ const { collectDiagnostics } = await import("../persistent-session-5KWYODZB.js");
20647
20911
  await api.post("/host/heartbeat", {
20648
20912
  host_id: hostId,
20649
20913
  agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor)
@@ -21067,7 +21331,7 @@ async function processDirectChatMessage(agent, msg) {
21067
21331
  const useDoorbell = hostFlagStore().getBoolean("direct-chat-doorbell") || isolationMode(agent.codeName) === "docker";
21068
21332
  if (useDoorbell) {
21069
21333
  try {
21070
- const doorbell = directChatDoorbellPath(agent.agentId, homedir18());
21334
+ const doorbell = directChatDoorbellPath(agent.agentId, homedir17());
21071
21335
  mkdirSync15(dirname11(doorbell), { recursive: true });
21072
21336
  writeFileSync18(doorbell, String(Date.now()));
21073
21337
  log(`[direct-chat] Doorbell rung for '${agent.codeName}' (msg=${msg.id}) \u2014 in-session MCP will pull via the cursor`);
@@ -21196,7 +21460,7 @@ ${formatRunMarker(run_id)}` : KANBAN_CHECK_COMMAND;
21196
21460
  }
21197
21461
  if (run_id) openInjectedRunByCode.set(codeName, run_id);
21198
21462
  try {
21199
- const doorbell = directChatDoorbellPath(agentId, homedir18());
21463
+ const doorbell = directChatDoorbellPath(agentId, homedir17());
21200
21464
  mkdirSync15(dirname11(doorbell), { recursive: true });
21201
21465
  writeFileSync18(doorbell, String(Date.now()));
21202
21466
  } catch (err) {
@@ -21302,8 +21566,19 @@ async function processClaudePairSessions(agents) {
21302
21566
  spawnPairSession,
21303
21567
  killPairSession,
21304
21568
  pairTmuxSession,
21305
- finalizeClaudePairOnboarding
21306
- } = await import("../claude-pair-runtime-DDSYAHQW.js");
21569
+ finalizeClaudePairOnboarding,
21570
+ // ENG-10862: the failure vocabulary lives beside the loop that produces it,
21571
+ // so the code the console stores and the message the operator reads cannot
21572
+ // drift from the reason finalize actually returned.
21573
+ PAIR_FINALIZE_ERROR_CODES,
21574
+ describePairFinalizeFailure,
21575
+ // ENG-10862: the last-chance re-read before a failure is reported.
21576
+ confirmPairFailure,
21577
+ // ENG-10862: the pre-submit mtime baseline. Taken here because finalize
21578
+ // cannot take it for itself — by the time it runs, the write it is looking
21579
+ // for may already have happened.
21580
+ snapshotPairConfig
21581
+ } = await import("../claude-pair-runtime-X27QVAXL.js");
21307
21582
  for (const pairId of pendingResp.cancelled_pair_ids ?? []) {
21308
21583
  log(`[claude-pair] sweeping orphan tmux session for pair ${pairId.slice(0, 8)}`);
21309
21584
  const killed = await killPairSession(pairTmuxSession(pairId));
@@ -21323,7 +21598,8 @@ async function processClaudePairSessions(agents) {
21323
21598
  async function reportAndCleanup(pairId, body) {
21324
21599
  await api.post("/host/claude-pair/result", { pair_id: pairId, ...body });
21325
21600
  if (typeof body.status === "string" && TERMINAL.has(body.status)) {
21326
- if (body.status === "success") {
21601
+ const isOnboardingFailure = typeof body.error_code === "string" && body.error_code.startsWith("onboarding_");
21602
+ if (body.status === "success" || isOnboardingFailure) {
21327
21603
  await new Promise((r) => setTimeout(r, 3e3));
21328
21604
  }
21329
21605
  const killed = await killPairSession(pairTmuxSession(pairId));
@@ -21375,16 +21651,50 @@ async function processClaudePairSessions(agents) {
21375
21651
  }
21376
21652
  } else if (session.status === "code_submitted" && session.code) {
21377
21653
  log(`[claude-pair] submitting code (pair ${session.pair_id.slice(0, 8)})`);
21654
+ const configBaseline = snapshotPairConfig();
21378
21655
  const result = await submitClaudePairCode({
21379
21656
  session: pairSession,
21380
21657
  code: session.code
21381
21658
  });
21382
21659
  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`);
21660
+ const finalize = await finalizeClaudePairOnboarding(pairSession, log, {
21661
+ baseline: configBaseline
21662
+ });
21663
+ const pairShort = session.pair_id.slice(0, 8);
21664
+ const confirmed = finalize.finalized ? "landed-after-all" : await confirmPairFailure({
21665
+ configPath: finalize.configPath,
21666
+ sinceMtimeMs: configBaseline.mtimeMs,
21667
+ log
21668
+ });
21669
+ if (!finalize.finalized && confirmed === "confirmed") {
21670
+ const reason = finalize.reason ?? "not-flushed";
21671
+ const errorCode = PAIR_FINALIZE_ERROR_CODES[reason];
21672
+ log(
21673
+ `[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`
21674
+ );
21675
+ await reportAndCleanup(session.pair_id, {
21676
+ status: "failure",
21677
+ error_code: errorCode,
21678
+ // The path finalize actually watched, returned by it rather than
21679
+ // recomputed here — two copies of that rule is how the operator
21680
+ // ends up reading about a file the flow never looked at.
21681
+ error_message: describePairFinalizeFailure(reason, finalize.configPath),
21682
+ // AC5: the loop's own accounting, so "do real pairings need more
21683
+ // than 10 dismissals?" stops being unanswerable. Counts only —
21684
+ // never pane text, which carries `Logged in as <email>`. These
21685
+ // are NOT stored on the pair row (no column, by decision); the
21686
+ // route forwards them into the alert payload, which is jsonb.
21687
+ finalize_iterations: finalize.iterations,
21688
+ finalize_grace_waits: finalize.graceWaits,
21689
+ finalize_dialog_counts: finalize.counts
21690
+ });
21691
+ } else {
21692
+ const lateness = finalize.finalized ? "" : ` (late: finalize said ${finalize.reason}, config landed during the confirm window)`;
21693
+ log(
21694
+ `[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}`
21695
+ );
21696
+ await reportAndCleanup(session.pair_id, { status: "success" });
21386
21697
  }
21387
- await reportAndCleanup(session.pair_id, { status: "success" });
21388
21698
  } else if (result.kind === "failure") {
21389
21699
  await reportAndCleanup(session.pair_id, {
21390
21700
  status: "failure",
@@ -21545,7 +21855,7 @@ function loadMemoryManifest(agentId, configDir, codeName) {
21545
21855
  if (cached) return cached;
21546
21856
  let manifest = {};
21547
21857
  try {
21548
- const raw = readFileSync33(memoryManifestPath(configDir, codeName), "utf-8");
21858
+ const raw = readFileSync34(memoryManifestPath(configDir, codeName), "utf-8");
21549
21859
  const parsed = JSON.parse(raw);
21550
21860
  if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
21551
21861
  for (const [name, entry] of Object.entries(parsed)) {
@@ -21660,7 +21970,7 @@ function applyMemoryTombstones(opts) {
21660
21970
  continue;
21661
21971
  }
21662
21972
  try {
21663
- const actual = createHash20("sha256").update(readFileSync33(filePath)).digest("hex");
21973
+ const actual = createHash20("sha256").update(readFileSync34(filePath)).digest("hex");
21664
21974
  if (actual !== entry.sha) {
21665
21975
  outcomes.kept_modified++;
21666
21976
  outcomes.unapplied.push({ name: tomb.name, reason: "kept_modified" });
@@ -21760,7 +22070,7 @@ async function syncMemories(agent, configDir, log2) {
21760
22070
  for (const file of readdirSync12(memoryDir)) {
21761
22071
  if (!file.endsWith(".md")) continue;
21762
22072
  try {
21763
- const raw = readFileSync33(join42(memoryDir, file), "utf-8");
22073
+ const raw = readFileSync34(join42(memoryDir, file), "utf-8");
21764
22074
  const fileHash = createHash20("sha256").update(raw).digest("hex").slice(0, 16);
21765
22075
  currentHashes.set(file, fileHash);
21766
22076
  if (prevHashes.get(file) === fileHash) continue;
@@ -21785,7 +22095,7 @@ async function syncMemories(agent, configDir, log2) {
21785
22095
  } catch (err) {
21786
22096
  for (const mem of changedMemories) {
21787
22097
  for (const [file] of currentHashes) {
21788
- const parsed = parseMemoryFile(readFileSync33(join42(memoryDir, file), "utf-8"), file.replace(/\.md$/, ""));
22098
+ const parsed = parseMemoryFile(readFileSync34(join42(memoryDir, file), "utf-8"), file.replace(/\.md$/, ""));
21789
22099
  if (parsed?.name === mem.name) currentHashes.delete(file);
21790
22100
  }
21791
22101
  }
@@ -21924,7 +22234,7 @@ ${mem.content}
21924
22234
  if (existsSync19(filePath)) {
21925
22235
  let existing = "";
21926
22236
  try {
21927
- existing = readFileSync33(filePath, "utf-8");
22237
+ existing = readFileSync34(filePath, "utf-8");
21928
22238
  } catch {
21929
22239
  }
21930
22240
  if (existing === desired) {
@@ -22089,6 +22399,16 @@ function startPolling() {
22089
22399
  livenessTimer.unref();
22090
22400
  startPaneOccupancySampler(() => agentState.persistentSessionAgents);
22091
22401
  startPidPressureSampler(() => agentState.persistentSessionAgents);
22402
+ {
22403
+ const seedOutcome = seedClaudeConfigFromLegacy({ log });
22404
+ const configDirUsable = claudeConfigDirIsReady();
22405
+ if (configDirUsable && !process.env[CLAUDE_CONFIG_DIR_ENV]?.trim()) {
22406
+ process.env[CLAUDE_CONFIG_DIR_ENV] = claudeConfigDirFor();
22407
+ }
22408
+ log(
22409
+ `[claude-config] ${CLAUDE_CONFIG_DIR_ENV}=${process.env[CLAUDE_CONFIG_DIR_ENV] ?? "<not adopted>"} configDirUsable=${configDirUsable} seed=${seedOutcome}`
22410
+ );
22411
+ }
22092
22412
  void startCaffeinate();
22093
22413
  loadChannelHashCache2();
22094
22414
  loadSenderPolicyBaseline2();
@@ -22304,7 +22624,7 @@ function startManager(opts) {
22304
22624
  try {
22305
22625
  const stateFile = getStateFile();
22306
22626
  if (existsSync19(stateFile)) {
22307
- const raw = readFileSync33(stateFile, "utf-8");
22627
+ const raw = readFileSync34(stateFile, "utf-8");
22308
22628
  const parsed = JSON.parse(raw);
22309
22629
  if (Array.isArray(parsed.agents)) {
22310
22630
  state8.agents = parsed.agents;
@@ -22331,7 +22651,7 @@ function startManager(opts) {
22331
22651
  log(`[startup] state rehydration failed (continuing with empty state): ${err.message}`);
22332
22652
  }
22333
22653
  log(
22334
- `[startup] worker pid=${process.pid} ppid=${process.ppid} node=${process.version} log=${join42(homedir18(), ".augmented", "manager.log")}`
22654
+ `[startup] worker pid=${process.pid} ppid=${process.ppid} node=${process.version} log=${join42(homedir17(), ".augmented", "manager.log")}`
22335
22655
  );
22336
22656
  deployMcpAssets();
22337
22657
  reapOrphanChannelMcps({ log });
@@ -22360,7 +22680,7 @@ async function reapOrphanedClaudePids() {
22360
22680
  const looksLikeClaude = (pid) => {
22361
22681
  if (process.platform !== "linux") return true;
22362
22682
  try {
22363
- const comm = readFileSync33(`/proc/${pid}/comm`, "utf-8").trim().toLowerCase();
22683
+ const comm = readFileSync34(`/proc/${pid}/comm`, "utf-8").trim().toLowerCase();
22364
22684
  return comm.includes("claude");
22365
22685
  } catch {
22366
22686
  return false;
@@ -22457,7 +22777,7 @@ function restartRunningChannelMcps(basenames) {
22457
22777
  }
22458
22778
  }
22459
22779
  function deployMcpAssets() {
22460
- const targetDir = join42(homedir18(), ".augmented", "_mcp");
22780
+ const targetDir = join42(homedir17(), ".augmented", "_mcp");
22461
22781
  mkdirSync15(targetDir, { recursive: true });
22462
22782
  const moduleDir = dirname11(fileURLToPath2(import.meta.url));
22463
22783
  let mcpSourceDir = "";
@@ -22482,7 +22802,7 @@ function deployMcpAssets() {
22482
22802
  const fileHash = (p) => {
22483
22803
  try {
22484
22804
  if (!existsSync19(p)) return null;
22485
- return createHash20("sha256").update(readFileSync33(p)).digest("hex");
22805
+ return createHash20("sha256").update(readFileSync34(p)).digest("hex");
22486
22806
  } catch {
22487
22807
  return null;
22488
22808
  }
@@ -22593,14 +22913,14 @@ function deployMcpAssets() {
22593
22913
  }
22594
22914
  const localMcpPath = join42(targetDir, "index.js");
22595
22915
  try {
22596
- const agentsDir = join42(homedir18(), ".augmented", "agents");
22916
+ const agentsDir = join42(homedir17(), ".augmented", "agents");
22597
22917
  if (existsSync19(agentsDir)) {
22598
22918
  for (const entry of readdirSync12(agentsDir, { withFileTypes: true })) {
22599
22919
  if (!entry.isDirectory()) continue;
22600
22920
  for (const subdir of ["provision", "project"]) {
22601
22921
  const mcpJsonPath = join42(agentsDir, entry.name, subdir, ".mcp.json");
22602
22922
  try {
22603
- const raw = readFileSync33(mcpJsonPath, "utf-8");
22923
+ const raw = readFileSync34(mcpJsonPath, "utf-8");
22604
22924
  if (!raw.includes("@integrity-labs/augmented-mcp")) continue;
22605
22925
  const mcpConfig = JSON.parse(raw);
22606
22926
  const augServer = mcpConfig.mcpServers?.["augmented"];