@integrity-labs/agt-cli 0.28.626 → 0.28.628

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.
@@ -54,7 +54,7 @@ import {
54
54
  safeWriteJsonAtomic,
55
55
  setConfigHash,
56
56
  tripClass
57
- } from "../chunk-4NCEO44Q.js";
57
+ } from "../chunk-G3FPZ4KK.js";
58
58
  import {
59
59
  getProjectDir as getProjectDir2,
60
60
  getReadyTasks,
@@ -196,8 +196,8 @@ import {
196
196
  import { createHash as createHash17 } from "crypto";
197
197
  import { readFileSync as readFileSync28, writeFileSync as writeFileSync14, mkdirSync as mkdirSync11, existsSync as existsSync15, rmSync as rmSync5, readdirSync as readdirSync9, statSync as statSync8, copyFileSync } from "fs";
198
198
  import { execFileSync as syncExecFile } from "child_process";
199
- import { join as join34, dirname as dirname9, delimiter as pathDelimiter } from "path";
200
- import { homedir as homedir16 } from "os";
199
+ import { join as join35, dirname as dirname9, delimiter as pathDelimiter } from "path";
200
+ import { homedir as homedir17 } from "os";
201
201
  import { fileURLToPath } from "url";
202
202
 
203
203
  // src/lib/single-flight.ts
@@ -215,8 +215,8 @@ function createSingleFlight(task, opts = {}) {
215
215
  }
216
216
  running2 = true;
217
217
  let markSettled;
218
- settled = new Promise((resolve) => {
219
- markSettled = resolve;
218
+ settled = new Promise((resolve2) => {
219
+ markSettled = resolve2;
220
220
  });
221
221
  const primary = (async () => {
222
222
  try {
@@ -1556,6 +1556,62 @@ var DependencyRecoveryLedger = class {
1556
1556
  }
1557
1557
  };
1558
1558
 
1559
+ // src/lib/mcp-assets-ready.ts
1560
+ import { existsSync as nodeExistsSync, readFileSync as nodeReadFileSync } from "fs";
1561
+ import { homedir as homedir2 } from "os";
1562
+ import { join as join4, resolve, sep } from "path";
1563
+ function getSharedMcpDir(homeDir = homedir2()) {
1564
+ return join4(homeDir, ".augmented", "_mcp");
1565
+ }
1566
+ function isPathInsideDir(candidate, dir) {
1567
+ const resolvedDir = resolve(dir);
1568
+ const resolvedCandidate = resolve(candidate);
1569
+ if (resolvedCandidate === resolvedDir) return false;
1570
+ return resolvedCandidate.startsWith(resolvedDir.endsWith(sep) ? resolvedDir : resolvedDir + sep);
1571
+ }
1572
+ function findMissingMcpBundles(mcpConfigPath, deps = {}) {
1573
+ const existsSync16 = deps.existsSync ?? nodeExistsSync;
1574
+ const readFileSync29 = deps.readFileSync ?? nodeReadFileSync;
1575
+ const mcpDir = deps.mcpDir ?? getSharedMcpDir();
1576
+ let parsed;
1577
+ try {
1578
+ parsed = JSON.parse(readFileSync29(mcpConfigPath, "utf-8"));
1579
+ } catch {
1580
+ return [];
1581
+ }
1582
+ const servers = parsed?.mcpServers;
1583
+ if (!servers || typeof servers !== "object" || Array.isArray(servers)) return [];
1584
+ const missing = [];
1585
+ const seenPaths = /* @__PURE__ */ new Set();
1586
+ for (const [key, rawEntry] of Object.entries(servers)) {
1587
+ if (!rawEntry || typeof rawEntry !== "object" || Array.isArray(rawEntry)) continue;
1588
+ const entry = rawEntry;
1589
+ if (entry.command !== "node") continue;
1590
+ if (!Array.isArray(entry.args) || entry.args.length === 0) continue;
1591
+ const bundlePath = entry.args[0];
1592
+ if (typeof bundlePath !== "string" || bundlePath.length === 0) continue;
1593
+ if (!isPathInsideDir(bundlePath, mcpDir)) continue;
1594
+ const resolvedBundlePath = resolve(bundlePath);
1595
+ if (seenPaths.has(resolvedBundlePath)) continue;
1596
+ let present;
1597
+ try {
1598
+ present = existsSync16(bundlePath);
1599
+ } catch {
1600
+ continue;
1601
+ }
1602
+ if (!present) {
1603
+ seenPaths.add(resolvedBundlePath);
1604
+ missing.push({ key, path: bundlePath });
1605
+ }
1606
+ }
1607
+ return missing.sort((a, b) => a.key.localeCompare(b.key));
1608
+ }
1609
+ function formatMissingMcpBundles(missing) {
1610
+ if (missing.length === 0) return "all declared MCP bundles present";
1611
+ const detail = missing.map((m) => `${m.key} (${m.path})`).join(", ");
1612
+ return `MCP bundle(s) not yet on disk in the host-shared _mcp mount: ${detail}`;
1613
+ }
1614
+
1559
1615
  // src/lib/self-update-coalesce.ts
1560
1616
  import { readFileSync as readFileSync5, writeFileSync as writeFileSync3, mkdirSync as mkdirSync3 } from "fs";
1561
1617
  import { dirname as dirname3 } from "path";
@@ -1925,14 +1981,14 @@ function formatReaperBootLine(opts) {
1925
1981
  }
1926
1982
 
1927
1983
  // src/lib/direct-chat-delivery.ts
1928
- import { join as join4 } from "path";
1984
+ import { join as join5 } from "path";
1929
1985
  var DEFAULT_DIRECT_CHAT_MAX_AGE_MS = 30 * 6e4;
1930
1986
  function directChatMaxAgeMs() {
1931
1987
  const raw = parseInt(process.env["AGT_DIRECT_CHAT_MAX_AGE_MS"] ?? "", 10);
1932
1988
  return Number.isFinite(raw) && raw >= 0 ? raw : DEFAULT_DIRECT_CHAT_MAX_AGE_MS;
1933
1989
  }
1934
1990
  function directChatDoorbellPath(agentId, home) {
1935
- return join4(home, ".augmented", agentId, "direct-chat-doorbell");
1991
+ return join5(home, ".augmented", agentId, "direct-chat-doorbell");
1936
1992
  }
1937
1993
  function isDirectChatMessageExpired(createdAt, nowMs, maxAgeMs) {
1938
1994
  if (!maxAgeMs || maxAgeMs <= 0) return false;
@@ -1944,15 +2000,15 @@ function isDirectChatMessageExpired(createdAt, nowMs, maxAgeMs) {
1944
2000
 
1945
2001
  // src/lib/id-keyed-migration.ts
1946
2002
  import { existsSync as existsSync2, lstatSync, readlinkSync, renameSync } from "fs";
1947
- import { join as join5 } from "path";
1948
- import { homedir as homedir2 } from "os";
2003
+ import { join as join6 } from "path";
2004
+ import { homedir as homedir3 } from "os";
1949
2005
  var ID_KEYED_MIGRATION_FLAG = "id-keyed-layout-migration";
1950
2006
  function agentHasActiveWhatsapp(channelConfigs, codeNameDir) {
1951
2007
  if (channelConfigs && Object.prototype.hasOwnProperty.call(channelConfigs, "whatsapp")) {
1952
2008
  return true;
1953
2009
  }
1954
2010
  try {
1955
- if (existsSync2(join5(codeNameDir, "whatsapp-pending-inbound"))) return true;
2011
+ if (existsSync2(join6(codeNameDir, "whatsapp-pending-inbound"))) return true;
1956
2012
  } catch {
1957
2013
  }
1958
2014
  return false;
@@ -1982,12 +2038,12 @@ function finishTranscriptMove(oldCwd, newCwd, codeName, log2) {
1982
2038
  log2(`[id-keyed-migration] moved transcript store for '${codeName}' to the id-keyed key`);
1983
2039
  }
1984
2040
  function maybeMigrateAgentToIdKeyedLayout(agent, deps) {
1985
- const home = deps.home ?? homedir2();
2041
+ const home = deps.home ?? homedir3();
1986
2042
  const { code_name: codeName, agent_id: agentId } = agent;
1987
- const codeNamePath = join5(home, ".augmented", codeName);
1988
- const idPath = join5(home, ".augmented", agentId);
1989
- const oldCwd = join5(home, ".augmented", codeName, "project");
1990
- const newCwd = join5(idPath, "project");
2043
+ const codeNamePath = join6(home, ".augmented", codeName);
2044
+ const idPath = join6(home, ".augmented", agentId);
2045
+ const oldCwd = join6(home, ".augmented", codeName, "project");
2046
+ const newCwd = join6(idPath, "project");
1991
2047
  let codeNameKind;
1992
2048
  try {
1993
2049
  codeNameKind = lstatSync(codeNamePath).isSymbolicLink() ? "symlink" : "realdir";
@@ -2115,7 +2171,7 @@ function collectEnvGates(env) {
2115
2171
 
2116
2172
  // ../../packages/core/dist/direct-chat/cursor-advance-telemetry.js
2117
2173
  import { readFileSync as readFileSync7, writeFileSync as writeFileSync4 } from "fs";
2118
- import { join as join6 } from "path";
2174
+ import { join as join7 } from "path";
2119
2175
  var CURSOR_SHORTFALL_COUNTER_SUFFIX = "-cursor-advance-classifications.json";
2120
2176
  function recordCursorAdvanceOutcome(agentDir, source, route, verdict) {
2121
2177
  if (!agentDir)
@@ -2123,7 +2179,7 @@ function recordCursorAdvanceOutcome(agentDir, source, route, verdict) {
2123
2179
  const key = cursorAdvanceCounterKey(route, verdict);
2124
2180
  if (key === null)
2125
2181
  return;
2126
- const path = join6(agentDir, `${source}${CURSOR_SHORTFALL_COUNTER_SUFFIX}`);
2182
+ const path = join7(agentDir, `${source}${CURSOR_SHORTFALL_COUNTER_SUFFIX}`);
2127
2183
  const counts = {};
2128
2184
  try {
2129
2185
  const parsed = JSON.parse(readFileSync7(path, "utf-8"));
@@ -2143,8 +2199,8 @@ function recordCursorAdvanceOutcome(agentDir, source, route, verdict) {
2143
2199
  }
2144
2200
 
2145
2201
  // src/lib/artifact-stream.ts
2146
- import { join as join7 } from "path";
2147
- import { homedir as homedir3 } from "os";
2202
+ import { join as join8 } from "path";
2203
+ import { homedir as homedir4 } from "os";
2148
2204
  import { readdir, stat, readFile } from "fs/promises";
2149
2205
  var ARTEFACT_ENTRY_FILE = "index.html";
2150
2206
  function errMessage(err) {
@@ -2229,7 +2285,7 @@ var ArtifactStreamScanner = class {
2229
2285
  return;
2230
2286
  }
2231
2287
  for (const name of names) {
2232
- const file = join7(this.artifactsDir, name, ARTEFACT_ENTRY_FILE);
2288
+ const file = join8(this.artifactsDir, name, ARTEFACT_ENTRY_FILE);
2233
2289
  const mtime = await this.fsDeps.mtimeMs(file).catch(() => null);
2234
2290
  if (mtime === null) continue;
2235
2291
  if (this.seenMtime.get(name) === mtime) continue;
@@ -2260,7 +2316,7 @@ var ArtifactStreamScanner = class {
2260
2316
  }
2261
2317
  };
2262
2318
  function artifactsDirFor(codeName) {
2263
- return join7(homedir3(), ".augmented", codeName, "artifacts");
2319
+ return join8(homedir4(), ".augmented", codeName, "artifacts");
2264
2320
  }
2265
2321
  var nodeArtifactFs = {
2266
2322
  async listArtefactNames(artifactsDir) {
@@ -2312,6 +2368,7 @@ async function maybeReportUsageBanner(args) {
2312
2368
  const next = {
2313
2369
  lastPct: existing?.lastPct ?? null,
2314
2370
  lastWeekResetsAt: existing?.lastWeekResetsAt ?? null,
2371
+ lastLimitScope: existing?.lastLimitScope ?? null,
2315
2372
  lastCheckedAt: nowMs
2316
2373
  };
2317
2374
  if (!tail) {
@@ -2326,7 +2383,7 @@ async function maybeReportUsageBanner(args) {
2326
2383
  }
2327
2384
  const observedAtIso = next.lastWeekResetsAt;
2328
2385
  const weekResetsAtIso = observation.weekResetsAt.toISOString();
2329
- if (existing && existing.lastPct === observation.pct && observedAtIso === weekResetsAtIso) {
2386
+ if (existing && existing.lastPct === observation.pct && observedAtIso === weekResetsAtIso && existing.lastLimitScope === observation.limitScope) {
2330
2387
  state.set(codeName, next);
2331
2388
  return;
2332
2389
  }
@@ -2340,10 +2397,25 @@ async function maybeReportUsageBanner(args) {
2340
2397
  // server cannot tell a measurement from a guess, which is how a reset
2341
2398
  // three days early reached an operator as a precise timestamp.
2342
2399
  reset_precision: observation.resetPrecision,
2400
+ // ENG-9007 wired the producer end. `classifyLimitScope` had been reading
2401
+ // the banner's qualifier and `parseUsageBanner` had been returning it on
2402
+ // every observation, but this POST never carried it — so the API's
2403
+ // validate-or-'unknown' contract (host-runtime.ts: an older host that
2404
+ // does not send it is not an error) resolved EVERY observation on the
2405
+ // fleet to `limit_scope: 'unknown'`, and every usage alert rendered
2406
+ // "banner qualifier not recognised, treated as weekly".
2407
+ //
2408
+ // That sentence was false on its face for the commonest banner of all —
2409
+ // "You've used 93% of your weekly limit", whose qualifier the parser
2410
+ // hard-codes to 'weekly'. Nothing was unrecognised; nobody had asked.
2411
+ // Sending the field is the whole fix: a session cap can now be told from
2412
+ // a weekly one, which is what ENG-9007 exists to do.
2413
+ limit_scope: observation.limitScope,
2343
2414
  source: "pane_log"
2344
2415
  });
2345
2416
  next.lastPct = observation.pct;
2346
2417
  next.lastWeekResetsAt = weekResetsAtIso;
2418
+ next.lastLimitScope = observation.limitScope;
2347
2419
  state.set(codeName, next);
2348
2420
  } catch (err) {
2349
2421
  log2(`[usage-banner] POST /host/usage-observations failed for '${codeName}': ${err.message}`);
@@ -2354,13 +2426,13 @@ async function maybeReportUsageBanner(args) {
2354
2426
  // src/lib/claude-account-fingerprint.ts
2355
2427
  import { createHash as createHash6 } from "crypto";
2356
2428
  import { readFile as readFile3, readdir as readdir3 } from "fs/promises";
2357
- import { homedir as homedir5, platform as platform2 } from "os";
2358
- import { dirname as dirname4, join as join9 } from "path";
2429
+ import { homedir as homedir6, platform as platform2 } from "os";
2430
+ import { dirname as dirname4, join as join10 } from "path";
2359
2431
 
2360
2432
  // src/lib/claude-auth-detect.ts
2361
2433
  import { readFile as readFile2, readdir as readdir2 } from "fs/promises";
2362
- import { homedir as homedir4, platform } from "os";
2363
- import { join as join8 } from "path";
2434
+ import { homedir as homedir5, platform } from "os";
2435
+ import { join as join9 } from "path";
2364
2436
  import { execFile } from "child_process";
2365
2437
  import { promisify } from "util";
2366
2438
  var execFileAsync = promisify(execFile);
@@ -2375,16 +2447,16 @@ async function detectClaudeAuth() {
2375
2447
  }
2376
2448
  async function findClaudeCredentialsPaths() {
2377
2449
  const candidates = [
2378
- join8(homedir4(), ".claude", ".credentials.json"),
2379
- join8(homedir4(), ".claude", "credentials.json")
2450
+ join9(homedir5(), ".claude", ".credentials.json"),
2451
+ join9(homedir5(), ".claude", "credentials.json")
2380
2452
  ];
2381
2453
  const isLinuxRoot = platform() === "linux" && typeof process.getuid === "function" && process.getuid() === 0;
2382
2454
  if (isLinuxRoot) {
2383
2455
  try {
2384
2456
  const entries = await readdir2("/home", { withFileTypes: true });
2385
2457
  for (const entry of entries.filter((entry2) => entry2.isDirectory()).sort((a, b) => a.name.localeCompare(b.name))) {
2386
- candidates.push(join8("/home", entry.name, ".claude", ".credentials.json"));
2387
- candidates.push(join8("/home", entry.name, ".claude", "credentials.json"));
2458
+ candidates.push(join9("/home", entry.name, ".claude", ".credentials.json"));
2459
+ candidates.push(join9("/home", entry.name, ".claude", "credentials.json"));
2388
2460
  }
2389
2461
  } catch {
2390
2462
  }
@@ -2462,13 +2534,13 @@ function parseExpiresAt(raw) {
2462
2534
 
2463
2535
  // src/lib/claude-account-fingerprint.ts
2464
2536
  async function candidateHomes() {
2465
- const homes = [homedir5()];
2537
+ const homes = [homedir6()];
2466
2538
  const isLinuxRoot = platform2() === "linux" && typeof process.getuid === "function" && process.getuid() === 0;
2467
2539
  if (isLinuxRoot) {
2468
2540
  try {
2469
2541
  const entries = await readdir3("/home", { withFileTypes: true });
2470
2542
  for (const entry of entries.filter((e) => e.isDirectory()).sort((a, b) => a.name.localeCompare(b.name))) {
2471
- homes.push(join9("/home", entry.name));
2543
+ homes.push(join10("/home", entry.name));
2472
2544
  }
2473
2545
  } catch {
2474
2546
  }
@@ -2488,11 +2560,11 @@ async function homeOfActiveCredentials() {
2488
2560
  async function claudeConfigCandidatePaths() {
2489
2561
  const paths = [];
2490
2562
  const configDir = process.env["CLAUDE_CONFIG_DIR"]?.trim();
2491
- if (configDir) paths.push(join9(configDir, ".claude.json"));
2563
+ if (configDir) paths.push(join10(configDir, ".claude.json"));
2492
2564
  const activeHome = await homeOfActiveCredentials();
2493
- if (activeHome) paths.push(join9(activeHome, ".claude.json"));
2565
+ if (activeHome) paths.push(join10(activeHome, ".claude.json"));
2494
2566
  for (const home of await candidateHomes()) {
2495
- const path = join9(home, ".claude.json");
2567
+ const path = join10(home, ".claude.json");
2496
2568
  if (!paths.includes(path)) paths.push(path);
2497
2569
  }
2498
2570
  return paths;
@@ -2590,10 +2662,10 @@ function diffAuthTuples(recorded, current) {
2590
2662
 
2591
2663
  // src/lib/account-enforcement-marker.ts
2592
2664
  import { mkdirSync as mkdirSync4, renameSync as renameSync2, rmSync as rmSync2, writeFileSync as writeFileSync5 } from "fs";
2593
- import { homedir as homedir6 } from "os";
2594
- import { join as join10 } from "path";
2665
+ import { homedir as homedir7 } from "os";
2666
+ import { join as join11 } from "path";
2595
2667
  function accountEnforcementMarkerPath(codeName) {
2596
- return join10(homedir6(), ".augmented", codeName, ACCOUNT_ENFORCEMENT_MARKER_FILENAME);
2668
+ return join11(homedir7(), ".augmented", codeName, ACCOUNT_ENFORCEMENT_MARKER_FILENAME);
2597
2669
  }
2598
2670
  function syncAccountEnforcementMarker(codeName, level, log2 = (m) => process.stderr.write(`${m}
2599
2671
  `), text) {
@@ -2601,8 +2673,8 @@ function syncAccountEnforcementMarker(codeName, level, log2 = (m) => process.std
2601
2673
  clearAccountEnforcementMarker(codeName, log2);
2602
2674
  return;
2603
2675
  }
2604
- const dir = join10(homedir6(), ".augmented", codeName);
2605
- const path = join10(dir, ACCOUNT_ENFORCEMENT_MARKER_FILENAME);
2676
+ const dir = join11(homedir7(), ".augmented", codeName);
2677
+ const path = join11(dir, ACCOUNT_ENFORCEMENT_MARKER_FILENAME);
2606
2678
  const tempPath = `${path}.${process.pid}.tmp`;
2607
2679
  try {
2608
2680
  mkdirSync4(dir, { recursive: true });
@@ -2628,7 +2700,7 @@ function clearAccountEnforcementMarker(codeName, log2 = (m) => process.stderr.wr
2628
2700
 
2629
2701
  // src/lib/token-usage-monitor.ts
2630
2702
  import { readdirSync, readFileSync as readFileSync8, statSync } from "fs";
2631
- import { join as join11 } from "path";
2703
+ import { join as join12 } from "path";
2632
2704
  var MIN_CHECK_INTERVAL_MS2 = 6e4;
2633
2705
  var TRANSCRIPT_MTIME_WINDOW_MS = 2 * 24 * 60 * 60 * 1e3;
2634
2706
  var MAX_ENTRIES_PER_POST = 200;
@@ -2657,7 +2729,7 @@ async function maybeReportTokenUsage(args) {
2657
2729
  if (!name.endsWith(".jsonl")) continue;
2658
2730
  const sessionId = name.slice(0, -".jsonl".length);
2659
2731
  if (!sessionId) continue;
2660
- const path = join11(dir, name);
2732
+ const path = join12(dir, name);
2661
2733
  let st;
2662
2734
  try {
2663
2735
  st = statSync(path);
@@ -2755,7 +2827,7 @@ async function maybeReportTokenUsage(args) {
2755
2827
 
2756
2828
  // src/lib/workflow-run-reconciler.ts
2757
2829
  import { readdirSync as readdirSync2, readFileSync as readFileSync9, statSync as statSync2 } from "fs";
2758
- import { join as join12 } from "path";
2830
+ import { join as join13 } from "path";
2759
2831
  var MIN_CHECK_INTERVAL_MS3 = 5 * 6e4;
2760
2832
  var SETTLE_MS = 3e4;
2761
2833
  var TRANSCRIPT_MTIME_WINDOW_MS2 = 2 * 24 * 60 * 60 * 1e3;
@@ -2774,7 +2846,7 @@ function collectJsonlRecursive(dir, minMtimeMs, out, depth) {
2774
2846
  return;
2775
2847
  }
2776
2848
  for (const name of entries) {
2777
- const p = join12(dir, name);
2849
+ const p = join13(dir, name);
2778
2850
  let st;
2779
2851
  try {
2780
2852
  st = statSync2(p);
@@ -2797,7 +2869,7 @@ function enumerateTranscriptFiles(transcriptDir, nowMs, minMtimeMs = nowMs - TRA
2797
2869
  return out;
2798
2870
  }
2799
2871
  for (const name of entries) {
2800
- const path = join12(transcriptDir, name);
2872
+ const path = join13(transcriptDir, name);
2801
2873
  let st;
2802
2874
  try {
2803
2875
  st = statSync2(path);
@@ -2809,7 +2881,7 @@ function enumerateTranscriptFiles(transcriptDir, nowMs, minMtimeMs = nowMs - TRA
2809
2881
  continue;
2810
2882
  }
2811
2883
  if (st.isDirectory()) {
2812
- collectJsonlRecursive(join12(path, "subagents"), minMtimeMs, out, 0);
2884
+ collectJsonlRecursive(join13(path, "subagents"), minMtimeMs, out, 0);
2813
2885
  }
2814
2886
  }
2815
2887
  return out;
@@ -2900,7 +2972,7 @@ async function maybeReconcileWorkflowRunTokens(args) {
2900
2972
 
2901
2973
  // src/lib/conversation-evaluator.ts
2902
2974
  import { readdirSync as readdirSync3, readFileSync as readFileSync10, statSync as statSync3 } from "fs";
2903
- import { join as join13 } from "path";
2975
+ import { join as join14 } from "path";
2904
2976
  var MIN_CHECK_INTERVAL_MS4 = 5 * 6e4;
2905
2977
  var TRANSCRIPT_MTIME_WINDOW_MS3 = 7 * 24 * 60 * 60 * 1e3;
2906
2978
  var WINDOW_PAD_MS = 5 * 6e4;
@@ -3336,7 +3408,7 @@ function readRecentTurns(dir, nowMs) {
3336
3408
  return;
3337
3409
  }
3338
3410
  for (const ent of entries) {
3339
- const full = join13(d, ent.name);
3411
+ const full = join14(d, ent.name);
3340
3412
  if (ent.isDirectory()) {
3341
3413
  visit(full);
3342
3414
  continue;
@@ -3641,18 +3713,18 @@ async function reportSkip2(api2, agentId, conversationId, log2, codeName) {
3641
3713
  }
3642
3714
 
3643
3715
  // src/lib/tool-call-audit.ts
3644
- import { homedir as homedir10 } from "os";
3645
- import { join as join18 } from "path";
3716
+ import { homedir as homedir11 } from "os";
3717
+ import { join as join19 } from "path";
3646
3718
 
3647
3719
  // src/lib/agent-logging-mode.ts
3648
3720
  import { readFileSync as readFileSync11 } from "fs";
3649
- import { homedir as homedir7 } from "os";
3650
- import { join as join14 } from "path";
3721
+ import { homedir as homedir8 } from "os";
3722
+ import { join as join15 } from "path";
3651
3723
  var LOGGING_MODES = ["hash-only", "redacted", "full-local"];
3652
3724
  function charterPath(codeName, homeDir) {
3653
- const home = homeDir ?? (process.env["HOME"]?.trim() || homedir7());
3725
+ const home = homeDir ?? (process.env["HOME"]?.trim() || homedir8());
3654
3726
  const key = agentRuntimeKey(codeName, homeDir);
3655
- return join14(home, ".augmented", key, "provision", "CHARTER.md");
3727
+ return join15(home, ".augmented", key, "provision", "CHARTER.md");
3656
3728
  }
3657
3729
  function readAgentLoggingMode(codeName, homeDir) {
3658
3730
  let raw;
@@ -3682,14 +3754,14 @@ function loggingModeWithholdsTargets(reading) {
3682
3754
  // src/lib/tool-call-path-salt.ts
3683
3755
  import { randomBytes } from "crypto";
3684
3756
  import { existsSync as existsSync3, mkdirSync as mkdirSync5, readFileSync as readFileSync12, renameSync as renameSync3, unlinkSync, writeFileSync as writeFileSync6 } from "fs";
3685
- import { homedir as homedir8 } from "os";
3686
- import { dirname as dirname5, join as join15 } from "path";
3757
+ import { homedir as homedir9 } from "os";
3758
+ import { dirname as dirname5, join as join16 } from "path";
3687
3759
  var SALT_BYTES = 32;
3688
3760
  var SALT_RE = /^[0-9a-f]{64}$/;
3689
3761
  function pathSaltPath(codeName, homeDir) {
3690
- const home = homeDir ?? (process.env["HOME"]?.trim() || homedir8());
3762
+ const home = homeDir ?? (process.env["HOME"]?.trim() || homedir9());
3691
3763
  const key = agentRuntimeKey(codeName, homeDir);
3692
- return join15(home, ".augmented", key, "tool-call-path-salt");
3764
+ return join16(home, ".augmented", key, "tool-call-path-salt");
3693
3765
  }
3694
3766
  function readToolCallPathSalt(codeName, homeDir) {
3695
3767
  let file;
@@ -3766,7 +3838,7 @@ function readHostArchiveAddress(path) {
3766
3838
 
3767
3839
  // src/lib/tool-call-extractor.ts
3768
3840
  import { closeSync, fstatSync, openSync, readFileSync as readFileSync14, readSync, readdirSync as readdirSync4 } from "fs";
3769
- import { basename, join as join16, relative } from "path";
3841
+ import { basename, join as join17, relative } from "path";
3770
3842
  import { StringDecoder } from "string_decoder";
3771
3843
 
3772
3844
  // src/lib/tool-call-redaction.ts
@@ -3895,7 +3967,7 @@ function redactToolTargetInner(toolName, input, ctx) {
3895
3967
  var EXTRACTOR_VERSION = "e1";
3896
3968
  function enumerateSessionTranscripts(transcriptDir, sessionId, projectsRoot) {
3897
3969
  const files = [];
3898
- const mainAbs = join16(transcriptDir, `${sessionId}.jsonl`);
3970
+ const mainAbs = join17(transcriptDir, `${sessionId}.jsonl`);
3899
3971
  files.push({
3900
3972
  absPath: mainAbs,
3901
3973
  relPath: relative(projectsRoot, mainAbs),
@@ -3903,7 +3975,7 @@ function enumerateSessionTranscripts(transcriptDir, sessionId, projectsRoot) {
3903
3975
  isSubagent: false,
3904
3976
  subagentId: null
3905
3977
  });
3906
- const subDir = join16(transcriptDir, sessionId, "subagents");
3978
+ const subDir = join17(transcriptDir, sessionId, "subagents");
3907
3979
  let entries;
3908
3980
  try {
3909
3981
  entries = readdirSync4(subDir);
@@ -3912,7 +3984,7 @@ function enumerateSessionTranscripts(transcriptDir, sessionId, projectsRoot) {
3912
3984
  }
3913
3985
  for (const name of entries) {
3914
3986
  if (!name.endsWith(".jsonl")) continue;
3915
- const abs = join16(subDir, name);
3987
+ const abs = join17(subDir, name);
3916
3988
  const stem = basename(name, ".jsonl");
3917
3989
  files.push({
3918
3990
  absPath: abs,
@@ -4111,8 +4183,8 @@ function extractTranscriptWindow(file, opts, from) {
4111
4183
 
4112
4184
  // src/lib/tool-call-cursor.ts
4113
4185
  import { existsSync as existsSync4, readFileSync as readFileSync15 } from "fs";
4114
- import { homedir as homedir9 } from "os";
4115
- import { join as join17 } from "path";
4186
+ import { homedir as homedir10 } from "os";
4187
+ import { join as join18 } from "path";
4116
4188
  var COVERAGE_DISPOSITIONS = [
4117
4189
  "ok",
4118
4190
  "not_entitled",
@@ -4165,9 +4237,9 @@ function parseCursorKey(key) {
4165
4237
  return { sessionId: sessionId.length > 0 ? sessionId : null, transcriptRef: key.slice(i + 1) };
4166
4238
  }
4167
4239
  function cursorStatePath(codeName, homeDir) {
4168
- const home = homeDir ?? (process.env["HOME"]?.trim() || homedir9());
4240
+ const home = homeDir ?? (process.env["HOME"]?.trim() || homedir10());
4169
4241
  const key = agentRuntimeKey(codeName, homeDir);
4170
- return join17(home, ".augmented", key, "tool-call-cursors.json");
4242
+ return join18(home, ".augmented", key, "tool-call-cursors.json");
4171
4243
  }
4172
4244
  function loadCursors(path) {
4173
4245
  const out = /* @__PURE__ */ new Map();
@@ -4579,8 +4651,8 @@ async function maybeScanToolCalls(args) {
4579
4651
  if (!salt && !hashOnly) {
4580
4652
  log2(`[tool-call-audit] ${codeName}: no path-hash salt available \u2014 file targets withheld`);
4581
4653
  }
4582
- const home = args.homeDir ?? (process.env["HOME"]?.trim() || homedir10());
4583
- const projectsRoot = args.projectsRoot ?? join18(home, ".claude", "projects");
4654
+ const home = args.homeDir ?? (process.env["HOME"]?.trim() || homedir11());
4655
+ const projectsRoot = args.projectsRoot ?? join19(home, ".claude", "projects");
4584
4656
  const transcriptDir = args.transcriptDir ?? sessionTranscriptDir(getProjectDir(codeName));
4585
4657
  const current = peekCurrentSession(codeName);
4586
4658
  const sessionIds = current ? [current.sessionId] : [];
@@ -4610,10 +4682,10 @@ async function maybeScanToolCalls(args) {
4610
4682
 
4611
4683
  // src/lib/activity-cache-monitor.ts
4612
4684
  import { existsSync as existsSync5, readFileSync as readFileSync16 } from "fs";
4613
- import { homedir as homedir11 } from "os";
4614
- import { join as join19 } from "path";
4685
+ import { homedir as homedir12 } from "os";
4686
+ import { join as join20 } from "path";
4615
4687
  var MIN_CHECK_INTERVAL_MS7 = 6e4;
4616
- var STATS_CACHE_PATH = join19(homedir11(), ".claude", "stats-cache.json");
4688
+ var STATS_CACHE_PATH = join20(homedir12(), ".claude", "stats-cache.json");
4617
4689
  var ISO_DATE_RE = /^\d{4}-\d{2}-\d{2}$/;
4618
4690
  var state6 = { lastObservedDate: null, lastCheckedAt: 0 };
4619
4691
  function selectNewDailyRows(raw, lastObservedDate) {
@@ -4894,10 +4966,10 @@ function computeChannelConfigHash(input) {
4894
4966
 
4895
4967
  // src/lib/channel-hash-cache.ts
4896
4968
  import { existsSync as existsSync6, readFileSync as readFileSync17, writeFileSync as writeFileSync7 } from "fs";
4897
- import { join as join20 } from "path";
4969
+ import { join as join21 } from "path";
4898
4970
  var CACHE_FILENAME = "channel-hash-cache.json";
4899
4971
  function getChannelHashCacheFile(configDir) {
4900
- return join20(configDir, CACHE_FILENAME);
4972
+ return join21(configDir, CACHE_FILENAME);
4901
4973
  }
4902
4974
  function loadChannelHashCache(target, configDir) {
4903
4975
  const path = getChannelHashCacheFile(configDir);
@@ -4925,7 +4997,7 @@ function saveChannelHashCache(source, configDir) {
4925
4997
 
4926
4998
  // src/lib/sender-policy-baseline.ts
4927
4999
  import { existsSync as existsSync7, readFileSync as readFileSync18 } from "fs";
4928
- import { join as join21 } from "path";
5000
+ import { join as join22 } from "path";
4929
5001
  var BASELINE_FILENAME = "sender-policy-baseline.json";
4930
5002
  var SENDER_POLICY_BASELINE_VERSION = 1;
4931
5003
  var BASELINE_CONCERNS = ["senderPolicy", "slackBehaviour", "msteamsBehaviour"];
@@ -4937,7 +5009,7 @@ function createDeliveryBaselineMaps() {
4937
5009
  };
4938
5010
  }
4939
5011
  function getSenderPolicyBaselineFile(configDir) {
4940
- return join21(configDir, BASELINE_FILENAME);
5012
+ return join22(configDir, BASELINE_FILENAME);
4941
5013
  }
4942
5014
  function loadSenderPolicyBaseline(target, configDir, log2) {
4943
5015
  const path = getSenderPolicyBaselineFile(configDir);
@@ -5467,7 +5539,7 @@ function planGlobalSkillSync(globalSkills, prevIds, hashOf, knownHash, options)
5467
5539
  }
5468
5540
 
5469
5541
  // src/lib/manager/integration-skill-cache.ts
5470
- import { join as join22 } from "path";
5542
+ import { join as join23 } from "path";
5471
5543
  function integrationSkillHashKey(agentId, skillId) {
5472
5544
  return `plugin-skill:${agentId}:${skillId}`;
5473
5545
  }
@@ -5483,16 +5555,16 @@ function forgetIntegrationSkill(cache3, agentId, skillId) {
5483
5555
  function removeIntegrationSkillFolder(opts) {
5484
5556
  forgetIntegrationSkill(opts.cache, opts.agentId, opts.entry);
5485
5557
  for (const dir of opts.dirs) {
5486
- opts.removeDir(join22(dir, opts.entry));
5558
+ opts.removeDir(join23(dir, opts.entry));
5487
5559
  }
5488
5560
  }
5489
5561
 
5490
5562
  // src/lib/manager/managed-skill-manifest.ts
5491
5563
  import { existsSync as existsSync8, mkdirSync as mkdirSync6, readFileSync as readFileSync19, writeFileSync as writeFileSync8 } from "fs";
5492
- import { dirname as dirname6, join as join23 } from "path";
5564
+ import { dirname as dirname6, join as join24 } from "path";
5493
5565
  var MANIFEST_VERSION = 1;
5494
5566
  function managedSkillManifestPath(agentRootDir) {
5495
- return join23(agentRootDir, "managed-skills.json");
5567
+ return join24(agentRootDir, "managed-skills.json");
5496
5568
  }
5497
5569
  function readManagedSkillManifest(path) {
5498
5570
  try {
@@ -5590,7 +5662,7 @@ function resolveModelChain(refreshData) {
5590
5662
  const modelDefaults = refreshData.model_defaults;
5591
5663
  const platform3 = modelDefaults?.platform ?? {};
5592
5664
  const org = modelDefaults?.org ?? {};
5593
- function resolve(tier) {
5665
+ function resolve2(tier) {
5594
5666
  const agentField = `${tier}_model`;
5595
5667
  const platformField = `default_${tier}_model`;
5596
5668
  const agentVal = agent?.[agentField];
@@ -5602,16 +5674,16 @@ function resolveModelChain(refreshData) {
5602
5674
  return void 0;
5603
5675
  }
5604
5676
  return {
5605
- primary: resolve("primary"),
5606
- secondary: resolve("secondary"),
5607
- tertiary: resolve("tertiary")
5677
+ primary: resolve2("primary"),
5678
+ secondary: resolve2("secondary"),
5679
+ tertiary: resolve2("tertiary")
5608
5680
  };
5609
5681
  }
5610
5682
 
5611
5683
  // src/lib/manager/claude-auth.ts
5612
5684
  import { existsSync as existsSync9, rmSync as rmSync3 } from "fs";
5613
- import { join as join24 } from "path";
5614
- import { homedir as homedir12 } from "os";
5685
+ import { join as join25 } from "path";
5686
+ import { homedir as homedir13 } from "os";
5615
5687
  async function applyClaudeAuthToEnv(childEnv, label) {
5616
5688
  const apiKey = getApiKey();
5617
5689
  if (!apiKey) {
@@ -5623,9 +5695,9 @@ async function applyClaudeAuthToEnv(childEnv, label) {
5623
5695
  throw new Error("claude_auth_mode=api_key but /host/exchange returned no decrypted key");
5624
5696
  }
5625
5697
  childEnv.ANTHROPIC_API_KEY = exchange.anthropicApiKey;
5626
- const claudeDir = join24(homedir12(), ".claude");
5698
+ const claudeDir = join25(homedir13(), ".claude");
5627
5699
  for (const filename of [".credentials.json", "credentials.json"]) {
5628
- const p = join24(claudeDir, filename);
5700
+ const p = join25(claudeDir, filename);
5629
5701
  if (existsSync9(p)) {
5630
5702
  try {
5631
5703
  rmSync3(p, { force: true });
@@ -5708,7 +5780,7 @@ function heartbeatRuntimeAuthFields(probeVerdict) {
5708
5780
 
5709
5781
  // src/lib/manager/kanban/parsers.ts
5710
5782
  import { existsSync as existsSync10, readFileSync as readFileSync20 } from "fs";
5711
- import { join as join25 } from "path";
5783
+ import { join as join26 } from "path";
5712
5784
  var STANDUP_TEMPLATES = /* @__PURE__ */ new Set(["daily-standup", "end-of-day-summary"]);
5713
5785
  var TASK_UPDATE_TEMPLATES = /* @__PURE__ */ new Set(["hourly-status", "task-update"]);
5714
5786
  var PLAN_TEMPLATES = /* @__PURE__ */ new Set(["morning-plan"]);
@@ -5860,8 +5932,8 @@ function getBuiltInSkillContent(skillId) {
5860
5932
  if (builtInSkillCache.has(skillId)) return builtInSkillCache.get(skillId);
5861
5933
  try {
5862
5934
  const candidates = [
5863
- join25(process.cwd(), "skills", skillId, "SKILL.md"),
5864
- join25(new URL(".", import.meta.url).pathname, "..", "..", "..", "..", "..", "..", "skills", skillId, "SKILL.md")
5935
+ join26(process.cwd(), "skills", skillId, "SKILL.md"),
5936
+ join26(new URL(".", import.meta.url).pathname, "..", "..", "..", "..", "..", "..", "skills", skillId, "SKILL.md")
5865
5937
  ];
5866
5938
  for (const candidate of candidates) {
5867
5939
  if (existsSync10(candidate)) {
@@ -6007,11 +6079,11 @@ function formatBoardForPrompt(items, template) {
6007
6079
 
6008
6080
  // src/lib/manager/kanban/nudge-state-cache.ts
6009
6081
  import { existsSync as existsSync11, readFileSync as readFileSync21, writeFileSync as writeFileSync9 } from "fs";
6010
- import { join as join26 } from "path";
6082
+ import { join as join27 } from "path";
6011
6083
  var CACHE_FILENAME2 = "kanban-nudge-state.json";
6012
6084
  var KANBAN_NUDGE_STATE_VERSION = 1;
6013
6085
  function getKanbanNudgeStateFile(configDir) {
6014
- return join26(configDir, CACHE_FILENAME2);
6086
+ return join27(configDir, CACHE_FILENAME2);
6015
6087
  }
6016
6088
  function loadKanbanNudgeState(target, configDir) {
6017
6089
  const path = getKanbanNudgeStateFile(configDir);
@@ -6228,7 +6300,7 @@ async function maybePostSlackThreadHint(agentCodeName, channelId, primaryTs) {
6228
6300
  // src/lib/manager/channels/telegram.ts
6229
6301
  import https from "https";
6230
6302
  function telegramApiCall(botToken, method, body) {
6231
- return new Promise((resolve, reject) => {
6303
+ return new Promise((resolve2, reject) => {
6232
6304
  const postData = JSON.stringify(body);
6233
6305
  const req = https.request({
6234
6306
  hostname: "api.telegram.org",
@@ -6245,7 +6317,7 @@ function telegramApiCall(botToken, method, body) {
6245
6317
  });
6246
6318
  res.on("end", () => {
6247
6319
  try {
6248
- resolve(JSON.parse(data));
6320
+ resolve2(JSON.parse(data));
6249
6321
  } catch {
6250
6322
  reject(new Error("Invalid JSON from Telegram API"));
6251
6323
  }
@@ -6552,7 +6624,7 @@ async function finishRun(runId, outcome, options = {}) {
6552
6624
  log(
6553
6625
  `[runs] finish attempt ${attempt + 1}/${maxRetries + 1} failed for run_id=${runId} outcome=${outcome} status=${status} error_id=${errId} \u2014 retrying`
6554
6626
  );
6555
- await new Promise((resolve) => setTimeout(resolve, baseMs * 2 ** attempt));
6627
+ await new Promise((resolve2) => setTimeout(resolve2, baseMs * 2 ** attempt));
6556
6628
  continue;
6557
6629
  }
6558
6630
  log(
@@ -6637,8 +6709,8 @@ function closeSessionRunForCode(codeName, outcome, reason) {
6637
6709
  // src/lib/manager/scheduler/kanban-route.ts
6638
6710
  import { createHash as createHash12 } from "crypto";
6639
6711
  import { writeFileSync as writeFileSync10, renameSync as renameSync4, mkdirSync as mkdirSync7, readFileSync as readFileSync22, unlinkSync as unlinkSync2 } from "fs";
6640
- import { homedir as homedir13 } from "os";
6641
- import { join as join27, dirname as dirname7 } from "path";
6712
+ import { homedir as homedir14 } from "os";
6713
+ import { join as join28, dirname as dirname7 } from "path";
6642
6714
 
6643
6715
  // src/lib/manager/scheduler/notify.ts
6644
6716
  import { createHash as createHash11 } from "crypto";
@@ -6997,7 +7069,7 @@ function resolveScheduledSlackTarget(task) {
6997
7069
  }
6998
7070
  function stampScheduledTurnMarker(codeName, taskId, target) {
6999
7071
  try {
7000
- const file = join27(homedir13(), ".augmented", codeName, SCHEDULED_TURN_MARKER_FILENAME);
7072
+ const file = join28(homedir14(), ".augmented", codeName, SCHEDULED_TURN_MARKER_FILENAME);
7001
7073
  const marker = { ts: Date.now(), task_id: taskId, ...target ? { target } : {} };
7002
7074
  const tmp = `${file}.tmp`;
7003
7075
  writeFileSync10(tmp, JSON.stringify(marker), "utf8");
@@ -7007,7 +7079,7 @@ function stampScheduledTurnMarker(codeName, taskId, target) {
7007
7079
  }
7008
7080
  }
7009
7081
  function clearScheduledTurnMarkerForTask(codeName, taskId) {
7010
- const file = join27(homedir13(), ".augmented", codeName, SCHEDULED_TURN_MARKER_FILENAME);
7082
+ const file = join28(homedir14(), ".augmented", codeName, SCHEDULED_TURN_MARKER_FILENAME);
7011
7083
  try {
7012
7084
  const raw = JSON.parse(readFileSync22(file, "utf8"));
7013
7085
  if (typeof raw?.task_id !== "string" || raw.task_id !== taskId) return;
@@ -7069,7 +7141,7 @@ async function routeScheduledTaskViaKanban(codeName, agentId, task, prompt, dura
7069
7141
  return false;
7070
7142
  }
7071
7143
  try {
7072
- const doorbell = directChatDoorbellPath(agentId, homedir13());
7144
+ const doorbell = directChatDoorbellPath(agentId, homedir14());
7073
7145
  mkdirSync7(dirname7(doorbell), { recursive: true });
7074
7146
  writeFileSync10(doorbell, String(Date.now()));
7075
7147
  } catch (err) {
@@ -7221,12 +7293,12 @@ async function processClaudeTaskResult(codeName, agentId, templateId, rawOutput,
7221
7293
 
7222
7294
  // src/lib/manager/scheduler/execution.ts
7223
7295
  import { createHash as createHash13 } from "crypto";
7224
- import { homedir as homedir14 } from "os";
7225
- import { join as join29 } from "path";
7296
+ import { homedir as homedir15 } from "os";
7297
+ import { join as join30 } from "path";
7226
7298
 
7227
7299
  // src/lib/agent-serving-probe.ts
7228
7300
  import { readFileSync as readFileSync23, readdirSync as readdirSync5, statSync as statSync5 } from "fs";
7229
- import { join as join28 } from "path";
7301
+ import { join as join29 } from "path";
7230
7302
  var RATE_LIMIT_WINDOW_MS = 6 * 60 * 60 * 1e3;
7231
7303
  function probeRateLimit(args) {
7232
7304
  const now = args.now ?? /* @__PURE__ */ new Date();
@@ -7242,7 +7314,7 @@ function probeRateLimit(args) {
7242
7314
  let newest = UNKNOWN_RATE_LIMIT;
7243
7315
  for (const name of entries) {
7244
7316
  if (!name.endsWith(".jsonl")) continue;
7245
- const path = join28(dir, name);
7317
+ const path = join29(dir, name);
7246
7318
  try {
7247
7319
  const st = statSync5(path);
7248
7320
  if (!st.isFile() || st.mtimeMs < startMs) continue;
@@ -7313,7 +7385,7 @@ function shouldLogUsageCapDeferral(site, codeName, limitedUntil) {
7313
7385
 
7314
7386
  // src/lib/manager/scheduler/execution.ts
7315
7387
  function claudePidFilePath() {
7316
- return join29(homedir14(), ".augmented", "manager-claude-pids.json");
7388
+ return join30(homedir15(), ".augmented", "manager-claude-pids.json");
7317
7389
  }
7318
7390
  var inFlightClaudePids = /* @__PURE__ */ new Map();
7319
7391
  function registerClaudeSpawn(record) {
@@ -7384,7 +7456,7 @@ async function syncAndCheckClaudeScheduler(agent, tasks, boardItems, refreshData
7384
7456
 
7385
7457
  // src/lib/occupancy-gate.ts
7386
7458
  import { closeSync as closeSync2, openSync as openSync2, readdirSync as readdirSync6, readSync as readSync2, statSync as statSync6 } from "fs";
7387
- import { join as join30 } from "path";
7459
+ import { join as join31 } from "path";
7388
7460
  function rostersMeasuredZero(mode, attested, runtimeRunning) {
7389
7461
  return mode === "enforce" && attested && runtimeRunning;
7390
7462
  }
@@ -7473,10 +7545,10 @@ function candidateTranscriptPaths(dir) {
7473
7545
  let complete = true;
7474
7546
  for (const name of top) {
7475
7547
  if (name.endsWith(".jsonl")) {
7476
- paths.push(join30(dir, name));
7548
+ paths.push(join31(dir, name));
7477
7549
  continue;
7478
7550
  }
7479
- const subDir = join30(dir, name, "subagents");
7551
+ const subDir = join31(dir, name, "subagents");
7480
7552
  let subs;
7481
7553
  try {
7482
7554
  subs = readdirSync6(subDir);
@@ -7485,7 +7557,7 @@ function candidateTranscriptPaths(dir) {
7485
7557
  continue;
7486
7558
  }
7487
7559
  for (const sub of subs) {
7488
- if (sub.endsWith(".jsonl")) paths.push(join30(subDir, sub));
7560
+ if (sub.endsWith(".jsonl")) paths.push(join31(subDir, sub));
7489
7561
  }
7490
7562
  }
7491
7563
  return { paths, complete };
@@ -8969,7 +9041,7 @@ async function fireOpencodeScheduledTask(agent, task) {
8969
9041
  import { createHash as createHash16 } from "crypto";
8970
9042
  import { existsSync as existsSync13, mkdirSync as mkdirSync8, readFileSync as readFileSync25, renameSync as renameSync5, unlinkSync as unlinkSync3, writeFileSync as writeFileSync11 } from "fs";
8971
9043
  import { randomUUID } from "crypto";
8972
- import { join as join31 } from "path";
9044
+ import { join as join32 } from "path";
8973
9045
 
8974
9046
  // src/lib/telegram-ingest.ts
8975
9047
  import https2 from "https";
@@ -9191,7 +9263,7 @@ function buildTelegramPeerClassifierConfigFromEnv(env, opts) {
9191
9263
  }
9192
9264
 
9193
9265
  // src/lib/telegram-ingest.ts
9194
- var nodeHttpsTelegramFetch = (url, init) => new Promise((resolve, reject) => {
9266
+ var nodeHttpsTelegramFetch = (url, init) => new Promise((resolve2, reject) => {
9195
9267
  const u = new URL(url);
9196
9268
  const body = init?.body;
9197
9269
  const headers = { ...init?.headers ?? {} };
@@ -9217,7 +9289,7 @@ var nodeHttpsTelegramFetch = (url, init) => new Promise((resolve, reject) => {
9217
9289
  });
9218
9290
  res.on("end", () => {
9219
9291
  const status = res.statusCode ?? 0;
9220
- resolve({
9292
+ resolve2({
9221
9293
  ok: status >= 200 && status < 300,
9222
9294
  status,
9223
9295
  json: async () => JSON.parse(data.length > 0 ? data : "{}")
@@ -9406,8 +9478,8 @@ function defaultAddReaction2(botToken, fetchImpl, log2) {
9406
9478
  };
9407
9479
  }
9408
9480
  function sleep(ms) {
9409
- return new Promise((resolve) => {
9410
- setTimeout(resolve, ms).unref?.();
9481
+ return new Promise((resolve2) => {
9482
+ setTimeout(resolve2, ms).unref?.();
9411
9483
  });
9412
9484
  }
9413
9485
  function startTelegramIngest(config2) {
@@ -9517,7 +9589,7 @@ function createFileOffsetStore(codeName, log2, currentBotId) {
9517
9589
  let filePath;
9518
9590
  try {
9519
9591
  dir = getFramework("opencode").getAgentDir(codeName);
9520
- filePath = join31(dir, "telegram-getupdates-offset-opencode.json");
9592
+ filePath = join32(dir, "telegram-getupdates-offset-opencode.json");
9521
9593
  } catch {
9522
9594
  dir = null;
9523
9595
  filePath = null;
@@ -9797,14 +9869,14 @@ function partitionActionableByPoison(actionable, states, config2) {
9797
9869
 
9798
9870
  // src/lib/restart-flags.ts
9799
9871
  import { existsSync as existsSync14, mkdirSync as mkdirSync9, readdirSync as readdirSync7, readFileSync as readFileSync26, renameSync as renameSync6, rmSync as rmSync4, writeFileSync as writeFileSync12 } from "fs";
9800
- import { homedir as homedir15 } from "os";
9801
- import { join as join32 } from "path";
9872
+ import { homedir as homedir16 } from "os";
9873
+ import { join as join33 } from "path";
9802
9874
  import { randomUUID as randomUUID2 } from "crypto";
9803
9875
  function restartFlagsDir() {
9804
- return join32(homedir15(), ".augmented", "restart-flags");
9876
+ return join33(homedir16(), ".augmented", "restart-flags");
9805
9877
  }
9806
9878
  function flagPath(codeName) {
9807
- return join32(restartFlagsDir(), `${codeName}.flag`);
9879
+ return join33(restartFlagsDir(), `${codeName}.flag`);
9808
9880
  }
9809
9881
  function readRestartFlags() {
9810
9882
  const dir = restartFlagsDir();
@@ -9813,7 +9885,7 @@ function readRestartFlags() {
9813
9885
  for (const entry of readdirSync7(dir)) {
9814
9886
  if (!entry.endsWith(".flag")) continue;
9815
9887
  try {
9816
- const raw = readFileSync26(join32(dir, entry), "utf8");
9888
+ const raw = readFileSync26(join33(dir, entry), "utf8");
9817
9889
  const parsed = JSON.parse(raw);
9818
9890
  if (typeof parsed.codeName !== "string" || parsed.codeName.length === 0) {
9819
9891
  parsed.codeName = entry.replace(/\.flag$/, "");
@@ -9932,7 +10004,7 @@ async function sendError(flag, opts, text) {
9932
10004
 
9933
10005
  // src/lib/restart-context.ts
9934
10006
  import { readdirSync as readdirSync8, readFileSync as readFileSync27, writeFileSync as writeFileSync13, mkdirSync as mkdirSync10, unlinkSync as unlinkSync4 } from "fs";
9935
- import { dirname as dirname8, join as join33 } from "path";
10007
+ import { dirname as dirname8, join as join34 } from "path";
9936
10008
  var SLACK_PENDING_INBOUND_DIRNAME = "slack-pending-inbound";
9937
10009
  var SLACK_RESTART_CONTEXT_DIRNAME = "slack-restart-context";
9938
10010
  var MAX_TOPIC_CHARS = 140;
@@ -9944,10 +10016,10 @@ function augmentedAgentDir(codeName) {
9944
10016
  return dirname8(getProjectDir(codeName));
9945
10017
  }
9946
10018
  function slackPendingInboundDir(codeName) {
9947
- return join33(augmentedAgentDir(codeName), SLACK_PENDING_INBOUND_DIRNAME);
10019
+ return join34(augmentedAgentDir(codeName), SLACK_PENDING_INBOUND_DIRNAME);
9948
10020
  }
9949
10021
  function slackRestartContextDir(codeName) {
9950
- return join33(augmentedAgentDir(codeName), SLACK_RESTART_CONTEXT_DIRNAME);
10022
+ return join34(augmentedAgentDir(codeName), SLACK_RESTART_CONTEXT_DIRNAME);
9951
10023
  }
9952
10024
  function sanitizeTopic(raw) {
9953
10025
  const cleaned = raw.replace(/\s+/g, " ").trim().replace(/[<>]/g, " ").replace(/\s+/g, " ").trim();
@@ -10007,7 +10079,7 @@ function pruneHintsExcept(codeName, freshFilenames) {
10007
10079
  if (!filename.endsWith(".json")) continue;
10008
10080
  if (freshFilenames.has(filename)) continue;
10009
10081
  try {
10010
- unlinkSync4(join33(ctxDir, filename));
10082
+ unlinkSync4(join34(ctxDir, filename));
10011
10083
  } catch {
10012
10084
  }
10013
10085
  }
@@ -10028,7 +10100,7 @@ function refreshSlackRestartContextHints(codeNames, opts = {}) {
10028
10100
  }
10029
10101
  const markers = [];
10030
10102
  for (const filename of markerFilenames.slice(0, cap)) {
10031
- const parsed = readStrandedMarker(join33(markerDir, filename));
10103
+ const parsed = readStrandedMarker(join34(markerDir, filename));
10032
10104
  if (parsed) markers.push({ filename, channel: parsed.channel, thread_ts: parsed.thread_ts });
10033
10105
  }
10034
10106
  if (markers.length === 0) {
@@ -10042,7 +10114,7 @@ function refreshSlackRestartContextHints(codeNames, opts = {}) {
10042
10114
  const freshFilenames = /* @__PURE__ */ new Set();
10043
10115
  for (const { filename, hint } of hints) {
10044
10116
  try {
10045
- writeHintFile(join33(ctxDir, filename), ctxDir, hint);
10117
+ writeHintFile(join34(ctxDir, filename), ctxDir, hint);
10046
10118
  freshFilenames.add(filename);
10047
10119
  } catch (err) {
10048
10120
  log2(`[restart-context] ${codeName}: hint write failed for ${filename}: ${err.message}`);
@@ -11644,7 +11716,7 @@ var runningChannelSecretHashes = /* @__PURE__ */ new Map();
11644
11716
  var sessionLaunchManagedStructure = /* @__PURE__ */ new Map();
11645
11717
  function projectMcpHash(_codeName, projectDir) {
11646
11718
  try {
11647
- const raw = readFileSync28(join34(projectDir, ".mcp.json"), "utf-8");
11719
+ const raw = readFileSync28(join35(projectDir, ".mcp.json"), "utf-8");
11648
11720
  return createHash17("sha256").update(canonicalJson(JSON.parse(raw))).digest("hex");
11649
11721
  } catch {
11650
11722
  return null;
@@ -11652,7 +11724,7 @@ function projectMcpHash(_codeName, projectDir) {
11652
11724
  }
11653
11725
  function projectMcpKeys(_codeName, projectDir) {
11654
11726
  try {
11655
- const raw = readFileSync28(join34(projectDir, ".mcp.json"), "utf-8");
11727
+ const raw = readFileSync28(join35(projectDir, ".mcp.json"), "utf-8");
11656
11728
  const parsed = JSON.parse(raw);
11657
11729
  const servers = parsed.mcpServers;
11658
11730
  if (!servers || typeof servers !== "object") return /* @__PURE__ */ new Set();
@@ -11670,7 +11742,7 @@ function seedSessionLaunchBaselines(codeName, projectDir) {
11670
11742
  else runningMcpServerKeys.delete(codeName);
11671
11743
  let launchStructure = null;
11672
11744
  try {
11673
- const raw = readFileSync28(join34(projectDir, ".mcp.json"), "utf-8");
11745
+ const raw = readFileSync28(join35(projectDir, ".mcp.json"), "utf-8");
11674
11746
  launchStructure = managedMcpStructureHashFromFile(
11675
11747
  JSON.parse(raw),
11676
11748
  isManagedMcpServerKey
@@ -11792,7 +11864,7 @@ async function runAgentSessionToolBindProbes(agent, integrations, projectDir, op
11792
11864
  if (result && result.rebindCandidates.length > 0 && hostFlagStore().getBoolean("session-tool-rebind")) {
11793
11865
  let mcpJsonForRebind = null;
11794
11866
  try {
11795
- mcpJsonForRebind = JSON.parse(readFileSync28(join34(projectDir, ".mcp.json"), "utf-8"));
11867
+ mcpJsonForRebind = JSON.parse(readFileSync28(join35(projectDir, ".mcp.json"), "utf-8"));
11796
11868
  } catch {
11797
11869
  mcpJsonForRebind = null;
11798
11870
  }
@@ -11937,7 +12009,7 @@ function checkMcpConfigDriftAndScheduleRestart(codeName, projectDir) {
11937
12009
  function projectChannelSecretHash(projectDir) {
11938
12010
  try {
11939
12011
  const entries = parseEnvIntegrations(
11940
- readFileSync28(join34(projectDir, ".env.integrations"), "utf-8")
12012
+ readFileSync28(join35(projectDir, ".env.integrations"), "utf-8")
11941
12013
  );
11942
12014
  return channelSecretValueHash(entries, CHANNEL_SECRET_ENV_KEYS);
11943
12015
  } catch {
@@ -12033,7 +12105,7 @@ var agentRestartTimezoneInputs = /* @__PURE__ */ new Map();
12033
12105
  var lastVersionCheckAt = 0;
12034
12106
  var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
12035
12107
  var lastResponsivenessProbeAt = 0;
12036
- var agtCliVersion = true ? "0.28.626" : "dev";
12108
+ var agtCliVersion = true ? "0.28.628" : "dev";
12037
12109
  function resolveBrewPath(execFileSync3) {
12038
12110
  try {
12039
12111
  const out = execFileSync3("which", ["brew"], { timeout: 5e3 }).toString().trim();
@@ -12320,7 +12392,7 @@ async function reapSupersededRuntimeImages(imageUri, localTag) {
12320
12392
  }
12321
12393
  }
12322
12394
  function runAsync(cmd, args, opts) {
12323
- return new Promise((resolve, reject) => {
12395
+ return new Promise((resolve2, reject) => {
12324
12396
  import("child_process").then(({ spawn }) => {
12325
12397
  const child = spawn(cmd, args, { stdio: ["ignore", "pipe", "pipe"], cwd: opts.cwd });
12326
12398
  let stdout = "";
@@ -12354,7 +12426,7 @@ function runAsync(cmd, args, opts) {
12354
12426
  if (settled) return;
12355
12427
  settled = true;
12356
12428
  clearTimeout(timer3);
12357
- resolve({ code: code ?? -1, stdout, stderr });
12429
+ resolve2({ code: code ?? -1, stdout, stderr });
12358
12430
  });
12359
12431
  }).catch(reject);
12360
12432
  });
@@ -12421,7 +12493,7 @@ async function ensureOpencodeBinary() {
12421
12493
  try {
12422
12494
  const prefix = execFileSync3("npm", ["prefix", "-g"], { encoding: "utf-8", timeout: 1e4 }).trim();
12423
12495
  if (prefix) {
12424
- const npmBin = join34(prefix, "bin");
12496
+ const npmBin = join35(prefix, "bin");
12425
12497
  const current = (process.env.PATH ?? "").split(pathDelimiter);
12426
12498
  if (!current.includes(npmBin)) {
12427
12499
  process.env.PATH = [npmBin, ...current.filter(Boolean)].join(pathDelimiter);
@@ -12538,7 +12610,7 @@ ${r.stderr}`;
12538
12610
  }
12539
12611
  var UPDATE_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
12540
12612
  function selfUpdateAppliedMarkerPath() {
12541
- return join34(homedir16(), ".augmented", ".last-self-update-applied");
12613
+ return join35(homedir17(), ".augmented", ".last-self-update-applied");
12542
12614
  }
12543
12615
  var selfUpdateUpToDateLogged = false;
12544
12616
  var selfUpdatePinnedLogged = false;
@@ -12567,7 +12639,7 @@ async function checkAndUpdateCli(opts) {
12567
12639
  const isNpmGlobal = !isBrewFormula && resolvedPath.includes("node_modules");
12568
12640
  if (!isBrewFormula && !isNpmGlobal) return "noop";
12569
12641
  const { readFileSync: readF, writeFileSync: writeF } = await import("fs");
12570
- const markerPath = join34(homedir16(), ".augmented", ".last-update-check");
12642
+ const markerPath = join35(homedir17(), ".augmented", ".last-update-check");
12571
12643
  if (!force) {
12572
12644
  try {
12573
12645
  const lastCheck = parseInt(readF(markerPath, "utf-8").trim(), 10);
@@ -12973,7 +13045,7 @@ async function runClaudeRuntimeAuthProbe() {
12973
13045
  ];
12974
13046
  try {
12975
13047
  const { stdout, stderr } = await execFilePromiseLong(resolveClaudeBinary(), args, {
12976
- cwd: homedir16(),
13048
+ cwd: homedir17(),
12977
13049
  timeout: RUNTIME_AUTH_PROBE_TIMEOUT_MS,
12978
13050
  stdin: "ignore",
12979
13051
  env: childEnv,
@@ -13020,12 +13092,12 @@ async function checkClaudeAuth() {
13020
13092
  var evalEmptyMcpConfigPath = null;
13021
13093
  function ensureEvalEmptyMcpConfig() {
13022
13094
  if (evalEmptyMcpConfigPath && existsSync15(evalEmptyMcpConfigPath)) return evalEmptyMcpConfigPath;
13023
- const dir = join34(homedir16(), ".augmented");
13095
+ const dir = join35(homedir17(), ".augmented");
13024
13096
  try {
13025
13097
  mkdirSync11(dir, { recursive: true });
13026
13098
  } catch {
13027
13099
  }
13028
- const p = join34(dir, ".eval-empty-mcp.json");
13100
+ const p = join35(dir, ".eval-empty-mcp.json");
13029
13101
  writeFileSync14(p, JSON.stringify({ mcpServers: {} }));
13030
13102
  evalEmptyMcpConfigPath = p;
13031
13103
  return p;
@@ -13051,7 +13123,7 @@ async function runEvalClaude(prompt, model) {
13051
13123
  ""
13052
13124
  ];
13053
13125
  const { stdout } = await execFilePromiseLong(resolveClaudeBinary(), args, {
13054
- cwd: homedir16(),
13126
+ cwd: homedir17(),
13055
13127
  timeout: 12e4,
13056
13128
  stdin: "ignore",
13057
13129
  env: childEnv,
@@ -13120,10 +13192,10 @@ function resolveConversationEvalBackend() {
13120
13192
  return conversationEvalBackend;
13121
13193
  }
13122
13194
  function getStateFile() {
13123
- return join34(config?.configDir ?? join34(process.env["HOME"] ?? "/tmp", ".augmented"), "manager-state.json");
13195
+ return join35(config?.configDir ?? join35(process.env["HOME"] ?? "/tmp", ".augmented"), "manager-state.json");
13124
13196
  }
13125
13197
  function channelHashCacheDir() {
13126
- return config?.configDir ?? join34(process.env["HOME"] ?? "/tmp", ".augmented");
13198
+ return config?.configDir ?? join35(process.env["HOME"] ?? "/tmp", ".augmented");
13127
13199
  }
13128
13200
  function loadChannelHashCache2() {
13129
13201
  loadChannelHashCache(agentState.knownChannelConfigHashes, channelHashCacheDir());
@@ -13177,7 +13249,7 @@ function removeDeliveryBaselineEntries(agentId) {
13177
13249
  var _channelQuarantineStore = null;
13178
13250
  function channelQuarantineStore() {
13179
13251
  if (!_channelQuarantineStore) {
13180
- const dir = config?.configDir ?? join34(process.env["HOME"] ?? "/tmp", ".augmented");
13252
+ const dir = config?.configDir ?? join35(process.env["HOME"] ?? "/tmp", ".augmented");
13181
13253
  _channelQuarantineStore = new ChannelQuarantineStore(defaultQuarantinePath(dir));
13182
13254
  }
13183
13255
  return _channelQuarantineStore;
@@ -13194,7 +13266,7 @@ function claudeMdSizeFor(codeName) {
13194
13266
  var _hostFlagStore = null;
13195
13267
  function hostFlagStore() {
13196
13268
  if (!_hostFlagStore) {
13197
- const dir = config?.configDir ?? join34(process.env["HOME"] ?? "/tmp", ".augmented");
13269
+ const dir = config?.configDir ?? join35(process.env["HOME"] ?? "/tmp", ".augmented");
13198
13270
  _hostFlagStore = new HostFlagStore({ cachePath: defaultFlagsCachePath(dir), log });
13199
13271
  }
13200
13272
  return _hostFlagStore;
@@ -13268,12 +13340,12 @@ function parseSkillFrontmatter(content) {
13268
13340
  }
13269
13341
  async function refreshSkillsIndexInClaudeMd(configDir, codeName, log2) {
13270
13342
  const { readdirSync: readdirSync10, readFileSync: rfs, existsSync: ex, writeFileSync: writeFileSync15 } = await import("fs");
13271
- const skillsDir = join34(configDir, codeName, "project", ".claude", "skills");
13272
- const claudeMdPath = join34(configDir, codeName, "project", "CLAUDE.md");
13343
+ const skillsDir = join35(configDir, codeName, "project", ".claude", "skills");
13344
+ const claudeMdPath = join35(configDir, codeName, "project", "CLAUDE.md");
13273
13345
  if (!ex(skillsDir) || !ex(claudeMdPath)) return;
13274
13346
  const entries = [];
13275
13347
  for (const dir of readdirSync10(skillsDir).sort()) {
13276
- const skillFile = join34(skillsDir, dir, "SKILL.md");
13348
+ const skillFile = join35(skillsDir, dir, "SKILL.md");
13277
13349
  if (!ex(skillFile)) continue;
13278
13350
  try {
13279
13351
  const { name, description } = parseSkillFrontmatter(rfs(skillFile, "utf-8"));
@@ -13777,10 +13849,10 @@ async function pollCycleInner() {
13777
13849
  const paneTail = readFileSync28(paneLogPath(codeName), "utf8").slice(-65536);
13778
13850
  const transient = detectTransientApiErrorInLog(paneTail);
13779
13851
  if (transient) {
13780
- const wedgeHome = join34(homedir16(), ".augmented", codeName);
13852
+ const wedgeHome = join35(homedir17(), ".augmented", codeName);
13781
13853
  if (existsSync15(wedgeHome)) {
13782
13854
  atomicWriteFileSync(
13783
- join34(wedgeHome, "watchdog-give-up.json"),
13855
+ join35(wedgeHome, "watchdog-give-up.json"),
13784
13856
  JSON.stringify({
13785
13857
  gave_up_at: wedgeNow.toISOString(),
13786
13858
  reason: "transient_overload"
@@ -14074,7 +14146,7 @@ async function pollCycleInner() {
14074
14146
  const adapter = resolveAgentFramework(prev.codeName);
14075
14147
  stopAgentRuntime2(prev.codeName, "removed-from-host");
14076
14148
  killAgentChannelProcesses(prev.codeName, { log });
14077
- const agentDir = join34(adapter.getAgentDir(prev.codeName), "provision");
14149
+ const agentDir = join35(adapter.getAgentDir(prev.codeName), "provision");
14078
14150
  await cleanupAgentFiles(prev.codeName, agentDir);
14079
14151
  clearAgentCaches(prev.agentId, prev.codeName);
14080
14152
  }
@@ -14161,10 +14233,10 @@ async function pollCycleInner() {
14161
14233
  // pending-inbound marker. Best-effort: a write failure is logged by
14162
14234
  // the watchdog, never fails the poll cycle.
14163
14235
  signalGiveUp: (codeName) => {
14164
- const dir = join34(homedir16(), ".augmented", codeName);
14236
+ const dir = join35(homedir17(), ".augmented", codeName);
14165
14237
  if (!existsSync15(dir)) return;
14166
14238
  atomicWriteFileSync(
14167
- join34(dir, "watchdog-give-up.json"),
14239
+ join35(dir, "watchdog-give-up.json"),
14168
14240
  JSON.stringify({ gave_up_at: (/* @__PURE__ */ new Date()).toISOString() })
14169
14241
  );
14170
14242
  }
@@ -14360,7 +14432,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
14360
14432
  }
14361
14433
  const now = (/* @__PURE__ */ new Date()).toISOString();
14362
14434
  const adapter = resolveAgentFramework(agent.code_name);
14363
- let agentDir = join34(adapter.getAgentDir(agent.code_name), "provision");
14435
+ let agentDir = join35(adapter.getAgentDir(agent.code_name), "provision");
14364
14436
  if (agent.status === "draft" || agent.status === "paused") {
14365
14437
  if (previousKnownStatus !== agent.status) {
14366
14438
  log(`Agent '${agent.code_name}' is ${agent.status}, skipping provisioning`);
@@ -14534,7 +14606,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
14534
14606
  const frameworkId = refreshData.agent.framework ?? DEFAULT_FRAMEWORK;
14535
14607
  agentFrameworkCache.set(agent.code_name, frameworkId);
14536
14608
  const frameworkAdapter = getFramework(frameworkId);
14537
- agentDir = join34(frameworkAdapter.getAgentDir(agent.code_name), "provision");
14609
+ agentDir = join35(frameworkAdapter.getAgentDir(agent.code_name), "provision");
14538
14610
  cacheAgentDeliveryMetadata(agent.code_name, refreshData);
14539
14611
  agentRestartTimezoneInputs.set(agent.code_name, {
14540
14612
  agentTimezone: typeof refreshData.agent.timezone === "string" ? refreshData.agent.timezone : null,
@@ -14583,7 +14655,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
14583
14655
  const changedFiles = [];
14584
14656
  mkdirSync11(agentDir, { recursive: true });
14585
14657
  for (const artifact of artifacts) {
14586
- const filePath = join34(agentDir, artifact.relativePath);
14658
+ const filePath = join35(agentDir, artifact.relativePath);
14587
14659
  let existingHash;
14588
14660
  let newHash;
14589
14661
  let writeContent = artifact.content;
@@ -14602,7 +14674,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
14602
14674
  };
14603
14675
  newHash = sha256(stripDynamicSections(artifact.content));
14604
14676
  try {
14605
- const projectClaudeMd = join34(config.configDir, agent.code_name, "project", "CLAUDE.md");
14677
+ const projectClaudeMd = join35(config.configDir, agent.code_name, "project", "CLAUDE.md");
14606
14678
  const existing = readFileSync28(projectClaudeMd, "utf-8");
14607
14679
  existingHash = sha256(stripDynamicSections(existing));
14608
14680
  } catch {
@@ -14653,12 +14725,12 @@ async function processAgent(agent, agentStates, managedToolkits) {
14653
14725
  }
14654
14726
  }
14655
14727
  if (changedFiles.length > 0) {
14656
- const isFirst = !existsSync15(join34(agentDir, "CHARTER.md"));
14728
+ const isFirst = !existsSync15(join35(agentDir, "CHARTER.md"));
14657
14729
  const verb = isFirst ? "Provisioning" : "Updating";
14658
14730
  const fileNames = changedFiles.map((f) => f.relativePath).join(", ");
14659
14731
  log(`${verb} '${agent.code_name}': ${fileNames}`);
14660
14732
  for (const file of changedFiles) {
14661
- const filePath = join34(agentDir, file.relativePath);
14733
+ const filePath = join35(agentDir, file.relativePath);
14662
14734
  mkdirSync11(dirname9(filePath), { recursive: true });
14663
14735
  if (file.relativePath === ".mcp.json") {
14664
14736
  safeWriteJsonAtomic(filePath, file.content, { mode: 384 });
@@ -14667,12 +14739,12 @@ async function processAgent(agent, agentStates, managedToolkits) {
14667
14739
  }
14668
14740
  }
14669
14741
  try {
14670
- const provSkillsDir = join34(agentDir, ".claude", "skills");
14742
+ const provSkillsDir = join35(agentDir, ".claude", "skills");
14671
14743
  if (existsSync15(provSkillsDir)) {
14672
14744
  for (const folder of readdirSync9(provSkillsDir)) {
14673
14745
  if (folder.startsWith("knowledge-")) {
14674
14746
  try {
14675
- rmSync5(join34(provSkillsDir, folder), { recursive: true });
14747
+ rmSync5(join35(provSkillsDir, folder), { recursive: true });
14676
14748
  } catch {
14677
14749
  }
14678
14750
  }
@@ -14685,7 +14757,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
14685
14757
  const trackedFiles2 = frameworkAdapter.driftTrackedFiles();
14686
14758
  const hashes = /* @__PURE__ */ new Map();
14687
14759
  for (const file of trackedFiles2) {
14688
- const h = hashFile(join34(agentDir, file));
14760
+ const h = hashFile(join35(agentDir, file));
14689
14761
  if (h) hashes.set(file, h);
14690
14762
  }
14691
14763
  agentState.writtenHashes.set(agent.agent_id, hashes);
@@ -14703,14 +14775,14 @@ async function processAgent(agent, agentStates, managedToolkits) {
14703
14775
  }
14704
14776
  if (Array.isArray(refreshData.workflows)) {
14705
14777
  try {
14706
- const provWorkflowsDir = join34(agentDir, ".claude", "workflows");
14778
+ const provWorkflowsDir = join35(agentDir, ".claude", "workflows");
14707
14779
  if (existsSync15(provWorkflowsDir)) {
14708
14780
  const expected = new Set(refreshData.workflows.map((w) => `${w.name}.js`));
14709
14781
  for (const file of readdirSync9(provWorkflowsDir)) {
14710
14782
  if (!file.endsWith(".js")) continue;
14711
14783
  if (expected.has(file)) continue;
14712
14784
  try {
14713
- rmSync5(join34(provWorkflowsDir, file));
14785
+ rmSync5(join35(provWorkflowsDir, file));
14714
14786
  } catch {
14715
14787
  }
14716
14788
  }
@@ -14792,7 +14864,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
14792
14864
  if (written && existsSync15(agentDir)) {
14793
14865
  const driftedFiles = [];
14794
14866
  for (const [file, expectedHash] of written) {
14795
- const localHash = hashFile(join34(agentDir, file));
14867
+ const localHash = hashFile(join35(agentDir, file));
14796
14868
  if (localHash && localHash !== expectedHash) {
14797
14869
  driftedFiles.push(file);
14798
14870
  }
@@ -14803,7 +14875,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
14803
14875
  try {
14804
14876
  const localHashes = {};
14805
14877
  for (const file of driftedFiles) {
14806
- localHashes[file] = hashFile(join34(agentDir, file));
14878
+ localHashes[file] = hashFile(join35(agentDir, file));
14807
14879
  }
14808
14880
  await api.post("/host/drift", {
14809
14881
  agent_id: agent.agent_id,
@@ -15005,7 +15077,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
15005
15077
  const addedChannels = [...restartDecision.added];
15006
15078
  const writeDmNoticeMarkers = isChannelAddRestart ? () => {
15007
15079
  try {
15008
- const agentAugmentedDir = join34(homedir16(), ".augmented", agent.code_name);
15080
+ const agentAugmentedDir = join35(homedir17(), ".augmented", agent.code_name);
15009
15081
  mkdirSync11(agentAugmentedDir, { recursive: true });
15010
15082
  const markerJson = JSON.stringify({
15011
15083
  version: 1,
@@ -15013,7 +15085,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
15013
15085
  added: addedChannels
15014
15086
  });
15015
15087
  for (const file of ["slack-channel-add-restart.json", "telegram-channel-add-restart.json"]) {
15016
- atomicWriteFileSync(join34(agentAugmentedDir, file), markerJson);
15088
+ atomicWriteFileSync(join35(agentAugmentedDir, file), markerJson);
15017
15089
  }
15018
15090
  } catch (err) {
15019
15091
  log(`[hot-reload] channel-add DM-notice marker write failed for '${agent.code_name}' (non-fatal): ${err.message}`);
@@ -15202,18 +15274,18 @@ async function processAgent(agent, agentStates, managedToolkits) {
15202
15274
  if (agentSessionMode === "persistent" && (agentFrameworkCache.get(agent.code_name) ?? DEFAULT_FRAMEWORK) === "claude-code") {
15203
15275
  try {
15204
15276
  const agentProvisionDir = agentDir;
15205
- const projectDir = join34(homedir16(), ".augmented", agent.code_name, "project");
15277
+ const projectDir = join35(homedir17(), ".augmented", agent.code_name, "project");
15206
15278
  mkdirSync11(agentProvisionDir, { recursive: true });
15207
15279
  mkdirSync11(projectDir, { recursive: true });
15208
- const provisionMcpPath = join34(agentProvisionDir, ".mcp.json");
15209
- const projectMcpPath = join34(projectDir, ".mcp.json");
15280
+ const provisionMcpPath = join35(agentProvisionDir, ".mcp.json");
15281
+ const projectMcpPath = join35(projectDir, ".mcp.json");
15210
15282
  let mcpConfig = { mcpServers: {} };
15211
15283
  try {
15212
15284
  mcpConfig = JSON.parse(readFileSync28(provisionMcpPath, "utf-8"));
15213
15285
  if (!mcpConfig.mcpServers) mcpConfig.mcpServers = {};
15214
15286
  } catch {
15215
15287
  }
15216
- const localDirectChatChannel = join34(homedir16(), ".augmented", "_mcp", "direct-chat-channel.js");
15288
+ const localDirectChatChannel = join35(homedir17(), ".augmented", "_mcp", "direct-chat-channel.js");
15217
15289
  const directChatTeamSettings = refreshData.team?.settings;
15218
15290
  const directChatTz = (() => {
15219
15291
  const tz = directChatTeamSettings?.["timezone"];
@@ -15239,7 +15311,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
15239
15311
  // ~/.augmented/<codeName>/.current-turn-initiator.json. Note getAgentDir
15240
15312
  // returns the agent root (NOT the /provision subdir `agentDir` points at),
15241
15313
  // so it byte-matches the broker readers' path.
15242
- AGT_TURN_INITIATOR_FILE: join34(
15314
+ AGT_TURN_INITIATOR_FILE: join35(
15243
15315
  frameworkAdapter.getAgentDir(agent.code_name),
15244
15316
  ".current-turn-initiator.json"
15245
15317
  )
@@ -15259,7 +15331,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
15259
15331
  log(`Channel credentials written for '${agent.code_name}/direct-chat'`);
15260
15332
  }
15261
15333
  }
15262
- const staleChannelsPath = join34(projectDir, ".mcp-channels.json");
15334
+ const staleChannelsPath = join35(projectDir, ".mcp-channels.json");
15263
15335
  if (existsSync15(staleChannelsPath)) {
15264
15336
  try {
15265
15337
  rmSync5(staleChannelsPath, { force: true });
@@ -15349,7 +15421,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
15349
15421
  }
15350
15422
  if (hostFlagStore().getBoolean("connectivity-probe")) {
15351
15423
  try {
15352
- const probeProjectDir = join34(homedir16(), ".augmented", agent.code_name, "project");
15424
+ const probeProjectDir = join35(homedir17(), ".augmented", agent.code_name, "project");
15353
15425
  let probeSet = integrations;
15354
15426
  try {
15355
15427
  const quarantined = await api.post("/host/agent-integrations/quarantined", { agent_id: agent.agent_id });
@@ -15395,7 +15467,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
15395
15467
  const forceDue = attemptsLeft > 0;
15396
15468
  let probeRan = false;
15397
15469
  try {
15398
- const probeProjectDir = join34(homedir16(), ".augmented", agent.code_name, "project");
15470
+ const probeProjectDir = join35(homedir17(), ".augmented", agent.code_name, "project");
15399
15471
  probeRan = await runAgentSessionToolBindProbes(agent, integrations, probeProjectDir, { forceDue });
15400
15472
  } catch (err) {
15401
15473
  log(`Session-tool-bind probe failed for '${agent.code_name}': ${err.message}`);
@@ -15472,8 +15544,8 @@ async function processAgent(agent, agentStates, managedToolkits) {
15472
15544
  const intHash = computeIntegrationsHash(integrations);
15473
15545
  const prevIntHash = agentState.knownIntegrationHashes.get(agent.agent_id);
15474
15546
  if (intHash !== prevIntHash) {
15475
- const projectDir = join34(homedir16(), ".augmented", agent.code_name, "project");
15476
- const envIntPath = join34(projectDir, ".env.integrations");
15547
+ const projectDir = join35(homedir17(), ".augmented", agent.code_name, "project");
15548
+ const envIntPath = join35(projectDir, ".env.integrations");
15477
15549
  let preWriteEnv;
15478
15550
  try {
15479
15551
  preWriteEnv = readFileSync28(envIntPath, "utf-8");
@@ -15495,7 +15567,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
15495
15567
  }
15496
15568
  if (fw === "claude-code" && isSessionHealthy(agent.code_name)) {
15497
15569
  try {
15498
- const projectMcpPath = join34(projectDir, ".mcp.json");
15570
+ const projectMcpPath = join35(projectDir, ".mcp.json");
15499
15571
  const postWriteEnv = readFileSync28(envIntPath, "utf-8");
15500
15572
  const mcpContent = readFileSync28(projectMcpPath, "utf-8");
15501
15573
  const changedVars = diffEnvIntegrations(preWriteEnv, postWriteEnv);
@@ -15760,16 +15832,16 @@ async function processAgent(agent, agentStates, managedToolkits) {
15760
15832
  }
15761
15833
  try {
15762
15834
  const { readdirSync: readdirSync10, rmSync: rmSync6 } = await import("fs");
15763
- const { homedir: homedir17 } = await import("os");
15835
+ const { homedir: homedir18 } = await import("os");
15764
15836
  const frameworkId2 = frameworkAdapter.id;
15765
15837
  const candidateSkillDirs = [
15766
15838
  // Claude Code — framework runtime tree
15767
- join34(homedir17(), ".augmented", agent.code_name, "skills"),
15839
+ join35(homedir18(), ".augmented", agent.code_name, "skills"),
15768
15840
  // Claude Code — project tree
15769
- join34(homedir17(), ".augmented", agent.code_name, "project", ".claude", "skills"),
15841
+ join35(homedir18(), ".augmented", agent.code_name, "project", ".claude", "skills"),
15770
15842
  // Defensive: legacy provision-side path, not currently an
15771
15843
  // install target but cheap to sweep.
15772
- join34(agentDir, ".claude", "skills")
15844
+ join35(agentDir, ".claude", "skills")
15773
15845
  ];
15774
15846
  const existingDirs = candidateSkillDirs.filter((d) => existsSync15(d));
15775
15847
  const discoveredEntries = /* @__PURE__ */ new Set();
@@ -15810,7 +15882,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
15810
15882
  const sharedSkillsPayload = refreshAny.shared_skills;
15811
15883
  const desiredResolved = globalSkillsPayload !== void 0 || sharedSkillsPayload !== void 0;
15812
15884
  const manifestPath = managedSkillManifestPath(
15813
- join34(homedir16(), ".augmented", agent.code_name)
15885
+ join35(homedir17(), ".augmented", agent.code_name)
15814
15886
  );
15815
15887
  const prevIds = /* @__PURE__ */ new Set([
15816
15888
  ...agentState.knownGlobalSkillIds.get(agent.agent_id) ?? /* @__PURE__ */ new Set(),
@@ -15830,15 +15902,15 @@ async function processAgent(agent, agentStates, managedToolkits) {
15830
15902
  }
15831
15903
  if (plan.removes.length) {
15832
15904
  const globalSkillDirs = [
15833
- join34(homedir16(), ".augmented", agent.code_name, "skills"),
15834
- join34(homedir16(), ".augmented", agent.code_name, "project", ".claude", "skills"),
15835
- join34(agentDir, ".claude", "skills")
15905
+ join35(homedir17(), ".augmented", agent.code_name, "skills"),
15906
+ join35(homedir17(), ".augmented", agent.code_name, "project", ".claude", "skills"),
15907
+ join35(agentDir, ".claude", "skills")
15836
15908
  ];
15837
15909
  for (const id of plan.removes) {
15838
15910
  let prunedAny = false;
15839
15911
  for (const dir of globalSkillDirs) {
15840
- const p = join34(dir, id);
15841
- if (existsSync15(p) && existsSync15(join34(p, "SKILL.md"))) {
15912
+ const p = join35(dir, id);
15913
+ if (existsSync15(p) && existsSync15(join35(p, "SKILL.md"))) {
15842
15914
  rmSync5(p, { recursive: true, force: true });
15843
15915
  prunedAny = true;
15844
15916
  }
@@ -16070,7 +16142,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
16070
16142
  const sess = getSessionState(agent.code_name);
16071
16143
  let mcpJsonParsed = null;
16072
16144
  try {
16073
- const mcpPath = join34(getProjectDir(agent.code_name), ".mcp.json");
16145
+ const mcpPath = join35(getProjectDir(agent.code_name), ".mcp.json");
16074
16146
  mcpJsonParsed = JSON.parse(readFileSync28(mcpPath, "utf-8"));
16075
16147
  } catch {
16076
16148
  }
@@ -16505,7 +16577,7 @@ Retried to the limit after repeated stalls \u2014 needs a look.`).catch(() => {
16505
16577
  if (trackedFiles.length > 0 && existsSync15(agentDir)) {
16506
16578
  const hashes = /* @__PURE__ */ new Map();
16507
16579
  for (const file of trackedFiles) {
16508
- const h = hashFile(join34(agentDir, file));
16580
+ const h = hashFile(join35(agentDir, file));
16509
16581
  if (h) hashes.set(file, h);
16510
16582
  }
16511
16583
  agentState.writtenHashes.set(agent.agent_id, hashes);
@@ -16520,7 +16592,7 @@ Retried to the limit after repeated stalls \u2014 needs a look.`).catch(() => {
16520
16592
  refreshData.agent.onboarding_state
16521
16593
  );
16522
16594
  const obStep = obState.step;
16523
- const markerPath = join34(homedir16(), ".augmented", agent.code_name, "onboarding-drive.json");
16595
+ const markerPath = join35(homedir17(), ".augmented", agent.code_name, "onboarding-drive.json");
16524
16596
  const marker = readOnboardingDriveMarker(markerPath);
16525
16597
  const obContactRaw = refreshData.agent.manager_last_contacted_at;
16526
16598
  const obContact = typeof obContactRaw === "string" && obContactRaw ? obContactRaw : null;
@@ -16622,7 +16694,7 @@ async function ensureOpencodeRuntime(agent, refreshData, agentTimezone) {
16622
16694
  }
16623
16695
  stopOpencodeSlackIngest(codeName, log);
16624
16696
  stopOpencodeTelegramIngest(codeName, log);
16625
- const opencodeProjectDir = join34(getFramework("opencode").getAgentDir(codeName), "provision");
16697
+ const opencodeProjectDir = join35(getFramework("opencode").getAgentDir(codeName), "provision");
16626
16698
  const serveEnv = {
16627
16699
  AGT_HOST: requireHost(),
16628
16700
  AGT_API_KEY: getApiKey() ?? void 0,
@@ -16677,8 +16749,8 @@ async function ensurePersistentSession(agent, tasks, boardItems, refreshData) {
16677
16749
  });
16678
16750
  }
16679
16751
  const projectDir = getProjectDir(codeName);
16680
- const mcpConfigPath = join34(projectDir, ".mcp.json");
16681
- const claudeMdPath = join34(projectDir, "CLAUDE.md");
16752
+ const mcpConfigPath = join35(projectDir, ".mcp.json");
16753
+ const claudeMdPath = join35(projectDir, "CLAUDE.md");
16682
16754
  if (restartBreaker.isTripped(codeName)) {
16683
16755
  const trip = restartBreaker.getTrip(codeName);
16684
16756
  return {
@@ -16688,6 +16760,21 @@ async function ensurePersistentSession(agent, tasks, boardItems, refreshData) {
16688
16760
  detail: trip.statusMessage
16689
16761
  };
16690
16762
  }
16763
+ if ((agentFrameworkCache.get(codeName) ?? DEFAULT_FRAMEWORK) === "claude-code" && !isSessionHealthy(codeName)) {
16764
+ const missingMcpBundles = findMissingMcpBundles(mcpConfigPath);
16765
+ if (missingMcpBundles.length > 0) {
16766
+ const detail = formatMissingMcpBundles(missingMcpBundles);
16767
+ log(
16768
+ `[persistent-session] '${codeName}': deferring spawn \u2014 ${detail}. Not counted as a restart; will spawn once the host deploys them.`
16769
+ );
16770
+ return {
16771
+ decision: "skipped-mcp-assets-not-ready",
16772
+ spawnAttempted: false,
16773
+ sessionHealthyAfter: false,
16774
+ detail
16775
+ };
16776
+ }
16777
+ }
16691
16778
  const teamSettingsForTz = refreshData.team?.settings;
16692
16779
  const agentTimezone = (() => {
16693
16780
  const ownTzRaw = refreshData.agent?.timezone;
@@ -17780,7 +17867,7 @@ async function processDirectChatMessage(agent, msg) {
17780
17867
  const useDoorbell = hostFlagStore().getBoolean("direct-chat-doorbell") || isolationMode(agent.codeName) === "docker";
17781
17868
  if (useDoorbell) {
17782
17869
  try {
17783
- const doorbell = directChatDoorbellPath(agent.agentId, homedir16());
17870
+ const doorbell = directChatDoorbellPath(agent.agentId, homedir17());
17784
17871
  mkdirSync11(dirname9(doorbell), { recursive: true });
17785
17872
  writeFileSync14(doorbell, String(Date.now()));
17786
17873
  log(`[direct-chat] Doorbell rung for '${agent.codeName}' (msg=${msg.id}) \u2014 in-session MCP will pull via the cursor`);
@@ -17909,7 +17996,7 @@ ${formatRunMarker(run_id)}` : KANBAN_CHECK_COMMAND;
17909
17996
  }
17910
17997
  if (run_id) openInjectedRunByCode.set(codeName, run_id);
17911
17998
  try {
17912
- const doorbell = directChatDoorbellPath(agentId, homedir16());
17999
+ const doorbell = directChatDoorbellPath(agentId, homedir17());
17913
18000
  mkdirSync11(dirname9(doorbell), { recursive: true });
17914
18001
  writeFileSync14(doorbell, String(Date.now()));
17915
18002
  } catch (err) {
@@ -18269,8 +18356,8 @@ function parseMemoryFile(raw, fallbackName) {
18269
18356
  };
18270
18357
  }
18271
18358
  async function syncMemories(agent, configDir, log2) {
18272
- const projectDir = join34(configDir, agent.code_name, "project");
18273
- const memoryDir = join34(projectDir, "memory");
18359
+ const projectDir = join35(configDir, agent.code_name, "project");
18360
+ const memoryDir = join35(projectDir, "memory");
18274
18361
  const isFreshSync = pendingFreshMemorySync.has(agent.agent_id);
18275
18362
  if (isFreshSync) {
18276
18363
  log2(`[memory-sync] Fresh-sync requested for '${agent.code_name}' \u2014 pulling DB first`);
@@ -18288,7 +18375,7 @@ async function syncMemories(agent, configDir, log2) {
18288
18375
  for (const file of readdirSync9(memoryDir)) {
18289
18376
  if (!file.endsWith(".md")) continue;
18290
18377
  try {
18291
- const raw = readFileSync28(join34(memoryDir, file), "utf-8");
18378
+ const raw = readFileSync28(join35(memoryDir, file), "utf-8");
18292
18379
  const fileHash = createHash17("sha256").update(raw).digest("hex").slice(0, 16);
18293
18380
  currentHashes.set(file, fileHash);
18294
18381
  if (prevHashes.get(file) === fileHash) continue;
@@ -18313,7 +18400,7 @@ async function syncMemories(agent, configDir, log2) {
18313
18400
  } catch (err) {
18314
18401
  for (const mem of changedMemories) {
18315
18402
  for (const [file] of currentHashes) {
18316
- const parsed = parseMemoryFile(readFileSync28(join34(memoryDir, file), "utf-8"), file.replace(/\.md$/, ""));
18403
+ const parsed = parseMemoryFile(readFileSync28(join35(memoryDir, file), "utf-8"), file.replace(/\.md$/, ""));
18317
18404
  if (parsed?.name === mem.name) currentHashes.delete(file);
18318
18405
  }
18319
18406
  }
@@ -18348,7 +18435,7 @@ async function downloadMemories(agent, memoryDir, log2, { force }) {
18348
18435
  const mem = dbMemories.memories[i];
18349
18436
  const rawSlug = mem.name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)/g, "").slice(0, 60);
18350
18437
  const slug = rawSlug || `memory-${i}`;
18351
- const filePath = join34(memoryDir, `${slug}.md`);
18438
+ const filePath = join35(memoryDir, `${slug}.md`);
18352
18439
  const desired = `---
18353
18440
  name: ${JSON.stringify(mem.name)}
18354
18441
  type: ${mem.type}
@@ -18522,7 +18609,7 @@ async function reportSelfUpdateRestarts() {
18522
18609
  });
18523
18610
  })
18524
18611
  ).then(() => void 0);
18525
- const deadline = new Promise((resolve) => setTimeout(resolve, 3e3));
18612
+ const deadline = new Promise((resolve2) => setTimeout(resolve2, 3e3));
18526
18613
  await Promise.race([posts, deadline]);
18527
18614
  }
18528
18615
  function scheduleNext() {
@@ -18656,7 +18743,7 @@ function startManager(opts) {
18656
18743
  log(`[startup] state rehydration failed (continuing with empty state): ${err.message}`);
18657
18744
  }
18658
18745
  log(
18659
- `[startup] worker pid=${process.pid} ppid=${process.ppid} node=${process.version} log=${join34(homedir16(), ".augmented", "manager.log")}`
18746
+ `[startup] worker pid=${process.pid} ppid=${process.ppid} node=${process.version} log=${join35(homedir17(), ".augmented", "manager.log")}`
18660
18747
  );
18661
18748
  deployMcpAssets();
18662
18749
  reapOrphanChannelMcps({ log });
@@ -18782,14 +18869,14 @@ function restartRunningChannelMcps(basenames) {
18782
18869
  }
18783
18870
  }
18784
18871
  function deployMcpAssets() {
18785
- const targetDir = join34(homedir16(), ".augmented", "_mcp");
18872
+ const targetDir = join35(homedir17(), ".augmented", "_mcp");
18786
18873
  mkdirSync11(targetDir, { recursive: true });
18787
18874
  const moduleDir = dirname9(fileURLToPath(import.meta.url));
18788
18875
  let mcpSourceDir = "";
18789
18876
  let dir = moduleDir;
18790
18877
  for (let i = 0; i < 6; i++) {
18791
- const candidate = join34(dir, "dist", "mcp");
18792
- if (existsSync15(join34(candidate, "index.js"))) {
18878
+ const candidate = join35(dir, "dist", "mcp");
18879
+ if (existsSync15(join35(candidate, "index.js"))) {
18793
18880
  mcpSourceDir = candidate;
18794
18881
  break;
18795
18882
  }
@@ -18802,6 +18889,8 @@ function deployMcpAssets() {
18802
18889
  return;
18803
18890
  }
18804
18891
  const changedBasenames = [];
18892
+ const attemptedFiles = [];
18893
+ const failedFiles = [];
18805
18894
  const fileHash = (p) => {
18806
18895
  try {
18807
18896
  if (!existsSync15(p)) return null;
@@ -18876,9 +18965,10 @@ function deployMcpAssets() {
18876
18965
  // needs restarting to pick up a token rotation.
18877
18966
  "xero.js"
18878
18967
  ]) {
18879
- const src = join34(mcpSourceDir, file);
18880
- const dst = join34(targetDir, file);
18968
+ const src = join35(mcpSourceDir, file);
18969
+ const dst = join35(targetDir, file);
18881
18970
  if (!existsSync15(src)) continue;
18971
+ attemptedFiles.push(file);
18882
18972
  const before = fileHash(dst);
18883
18973
  try {
18884
18974
  copyFileSync(src, dst);
@@ -18887,22 +18977,29 @@ function deployMcpAssets() {
18887
18977
  changedBasenames.push(file.replace(/\.js$/, ""));
18888
18978
  }
18889
18979
  } catch (err) {
18980
+ failedFiles.push(file);
18890
18981
  log(`[manager] Failed to deploy ${file}: ${err.message}`);
18891
18982
  }
18892
18983
  }
18893
- log(`[manager] MCP assets deployed to ${targetDir}`);
18984
+ if (failedFiles.length > 0) {
18985
+ log(
18986
+ `[manager] MCP asset deployment INCOMPLETE for ${targetDir} \u2014 ${failedFiles.length}/${attemptedFiles.length} bundle(s) failed to copy: ${failedFiles.join(", ")}. Agents declaring these bundles will be held out of spawn (ENG-9125) until this succeeds. A read-only target directory is the usual cause.`
18987
+ );
18988
+ } else {
18989
+ log(`[manager] MCP assets deployed to ${targetDir} (${attemptedFiles.length} bundle(s))`);
18990
+ }
18894
18991
  if (changedBasenames.length > 0) {
18895
18992
  log(`[manager] Bundle(s) updated: ${changedBasenames.join(", ")} \u2014 signalling running instances to restart`);
18896
18993
  restartRunningChannelMcps(changedBasenames);
18897
18994
  }
18898
- const localMcpPath = join34(targetDir, "index.js");
18995
+ const localMcpPath = join35(targetDir, "index.js");
18899
18996
  try {
18900
- const agentsDir = join34(homedir16(), ".augmented", "agents");
18997
+ const agentsDir = join35(homedir17(), ".augmented", "agents");
18901
18998
  if (existsSync15(agentsDir)) {
18902
18999
  for (const entry of readdirSync9(agentsDir, { withFileTypes: true })) {
18903
19000
  if (!entry.isDirectory()) continue;
18904
19001
  for (const subdir of ["provision", "project"]) {
18905
- const mcpJsonPath = join34(agentsDir, entry.name, subdir, ".mcp.json");
19002
+ const mcpJsonPath = join35(agentsDir, entry.name, subdir, ".mcp.json");
18906
19003
  try {
18907
19004
  const raw = readFileSync28(mcpJsonPath, "utf-8");
18908
19005
  if (!raw.includes("@integrity-labs/augmented-mcp")) continue;