@integrity-labs/agt-cli 0.28.627 → 0.28.629

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-DTVTLSID.js";
57
+ } from "../chunk-XQQ6THYK.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,88 @@ 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
+
1615
+ // src/lib/startup-telemetry.ts
1616
+ var SLOW_STARTUP_WARN_MS = 6e4;
1617
+ function shouldWarnSlowStartup(elapsedMs, opts = {}) {
1618
+ if (!Number.isFinite(elapsedMs) || elapsedMs < 0) return false;
1619
+ const threshold = opts.thresholdMs ?? SLOW_STARTUP_WARN_MS;
1620
+ if (!Number.isFinite(threshold) || threshold < 0) return false;
1621
+ return elapsedMs >= threshold;
1622
+ }
1623
+ function formatStartupElapsed(elapsedMs) {
1624
+ if (!Number.isFinite(elapsedMs) || elapsedMs < 0) return "unknown";
1625
+ const seconds = elapsedMs / 1e3;
1626
+ if (seconds < 60) return `${seconds.toFixed(1)}s`;
1627
+ return `${seconds.toFixed(1)}s (${(seconds / 60).toFixed(1)} min)`;
1628
+ }
1629
+ function describeStartupCompletion(elapsedMs, opts = {}) {
1630
+ const elapsed = formatStartupElapsed(elapsedMs);
1631
+ if (!shouldWarnSlowStartup(elapsedMs, opts)) {
1632
+ return { warn: false, message: `[startup] ready in ${elapsed}` };
1633
+ }
1634
+ const threshold = opts.thresholdMs ?? SLOW_STARTUP_WARN_MS;
1635
+ return {
1636
+ warn: true,
1637
+ message: `[startup] SLOW BOOT \u2014 ready in ${elapsed}, over the ${formatStartupElapsed(threshold)} threshold. MCP bundles are deployed during startup, so agents spawning in this window can come up with no MCP tools (ENG-9129). Check for a build/install running on the host.`
1638
+ };
1639
+ }
1640
+
1559
1641
  // src/lib/self-update-coalesce.ts
1560
1642
  import { readFileSync as readFileSync5, writeFileSync as writeFileSync3, mkdirSync as mkdirSync3 } from "fs";
1561
1643
  import { dirname as dirname3 } from "path";
@@ -1925,14 +2007,14 @@ function formatReaperBootLine(opts) {
1925
2007
  }
1926
2008
 
1927
2009
  // src/lib/direct-chat-delivery.ts
1928
- import { join as join4 } from "path";
2010
+ import { join as join5 } from "path";
1929
2011
  var DEFAULT_DIRECT_CHAT_MAX_AGE_MS = 30 * 6e4;
1930
2012
  function directChatMaxAgeMs() {
1931
2013
  const raw = parseInt(process.env["AGT_DIRECT_CHAT_MAX_AGE_MS"] ?? "", 10);
1932
2014
  return Number.isFinite(raw) && raw >= 0 ? raw : DEFAULT_DIRECT_CHAT_MAX_AGE_MS;
1933
2015
  }
1934
2016
  function directChatDoorbellPath(agentId, home) {
1935
- return join4(home, ".augmented", agentId, "direct-chat-doorbell");
2017
+ return join5(home, ".augmented", agentId, "direct-chat-doorbell");
1936
2018
  }
1937
2019
  function isDirectChatMessageExpired(createdAt, nowMs, maxAgeMs) {
1938
2020
  if (!maxAgeMs || maxAgeMs <= 0) return false;
@@ -1944,15 +2026,15 @@ function isDirectChatMessageExpired(createdAt, nowMs, maxAgeMs) {
1944
2026
 
1945
2027
  // src/lib/id-keyed-migration.ts
1946
2028
  import { existsSync as existsSync2, lstatSync, readlinkSync, renameSync } from "fs";
1947
- import { join as join5 } from "path";
1948
- import { homedir as homedir2 } from "os";
2029
+ import { join as join6 } from "path";
2030
+ import { homedir as homedir3 } from "os";
1949
2031
  var ID_KEYED_MIGRATION_FLAG = "id-keyed-layout-migration";
1950
2032
  function agentHasActiveWhatsapp(channelConfigs, codeNameDir) {
1951
2033
  if (channelConfigs && Object.prototype.hasOwnProperty.call(channelConfigs, "whatsapp")) {
1952
2034
  return true;
1953
2035
  }
1954
2036
  try {
1955
- if (existsSync2(join5(codeNameDir, "whatsapp-pending-inbound"))) return true;
2037
+ if (existsSync2(join6(codeNameDir, "whatsapp-pending-inbound"))) return true;
1956
2038
  } catch {
1957
2039
  }
1958
2040
  return false;
@@ -1982,12 +2064,12 @@ function finishTranscriptMove(oldCwd, newCwd, codeName, log2) {
1982
2064
  log2(`[id-keyed-migration] moved transcript store for '${codeName}' to the id-keyed key`);
1983
2065
  }
1984
2066
  function maybeMigrateAgentToIdKeyedLayout(agent, deps) {
1985
- const home = deps.home ?? homedir2();
2067
+ const home = deps.home ?? homedir3();
1986
2068
  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");
2069
+ const codeNamePath = join6(home, ".augmented", codeName);
2070
+ const idPath = join6(home, ".augmented", agentId);
2071
+ const oldCwd = join6(home, ".augmented", codeName, "project");
2072
+ const newCwd = join6(idPath, "project");
1991
2073
  let codeNameKind;
1992
2074
  try {
1993
2075
  codeNameKind = lstatSync(codeNamePath).isSymbolicLink() ? "symlink" : "realdir";
@@ -2115,7 +2197,7 @@ function collectEnvGates(env) {
2115
2197
 
2116
2198
  // ../../packages/core/dist/direct-chat/cursor-advance-telemetry.js
2117
2199
  import { readFileSync as readFileSync7, writeFileSync as writeFileSync4 } from "fs";
2118
- import { join as join6 } from "path";
2200
+ import { join as join7 } from "path";
2119
2201
  var CURSOR_SHORTFALL_COUNTER_SUFFIX = "-cursor-advance-classifications.json";
2120
2202
  function recordCursorAdvanceOutcome(agentDir, source, route, verdict) {
2121
2203
  if (!agentDir)
@@ -2123,7 +2205,7 @@ function recordCursorAdvanceOutcome(agentDir, source, route, verdict) {
2123
2205
  const key = cursorAdvanceCounterKey(route, verdict);
2124
2206
  if (key === null)
2125
2207
  return;
2126
- const path = join6(agentDir, `${source}${CURSOR_SHORTFALL_COUNTER_SUFFIX}`);
2208
+ const path = join7(agentDir, `${source}${CURSOR_SHORTFALL_COUNTER_SUFFIX}`);
2127
2209
  const counts = {};
2128
2210
  try {
2129
2211
  const parsed = JSON.parse(readFileSync7(path, "utf-8"));
@@ -2143,8 +2225,8 @@ function recordCursorAdvanceOutcome(agentDir, source, route, verdict) {
2143
2225
  }
2144
2226
 
2145
2227
  // src/lib/artifact-stream.ts
2146
- import { join as join7 } from "path";
2147
- import { homedir as homedir3 } from "os";
2228
+ import { join as join8 } from "path";
2229
+ import { homedir as homedir4 } from "os";
2148
2230
  import { readdir, stat, readFile } from "fs/promises";
2149
2231
  var ARTEFACT_ENTRY_FILE = "index.html";
2150
2232
  function errMessage(err) {
@@ -2229,7 +2311,7 @@ var ArtifactStreamScanner = class {
2229
2311
  return;
2230
2312
  }
2231
2313
  for (const name of names) {
2232
- const file = join7(this.artifactsDir, name, ARTEFACT_ENTRY_FILE);
2314
+ const file = join8(this.artifactsDir, name, ARTEFACT_ENTRY_FILE);
2233
2315
  const mtime = await this.fsDeps.mtimeMs(file).catch(() => null);
2234
2316
  if (mtime === null) continue;
2235
2317
  if (this.seenMtime.get(name) === mtime) continue;
@@ -2260,7 +2342,7 @@ var ArtifactStreamScanner = class {
2260
2342
  }
2261
2343
  };
2262
2344
  function artifactsDirFor(codeName) {
2263
- return join7(homedir3(), ".augmented", codeName, "artifacts");
2345
+ return join8(homedir4(), ".augmented", codeName, "artifacts");
2264
2346
  }
2265
2347
  var nodeArtifactFs = {
2266
2348
  async listArtefactNames(artifactsDir) {
@@ -2370,13 +2452,13 @@ async function maybeReportUsageBanner(args) {
2370
2452
  // src/lib/claude-account-fingerprint.ts
2371
2453
  import { createHash as createHash6 } from "crypto";
2372
2454
  import { readFile as readFile3, readdir as readdir3 } from "fs/promises";
2373
- import { homedir as homedir5, platform as platform2 } from "os";
2374
- import { dirname as dirname4, join as join9 } from "path";
2455
+ import { homedir as homedir6, platform as platform2 } from "os";
2456
+ import { dirname as dirname4, join as join10 } from "path";
2375
2457
 
2376
2458
  // src/lib/claude-auth-detect.ts
2377
2459
  import { readFile as readFile2, readdir as readdir2 } from "fs/promises";
2378
- import { homedir as homedir4, platform } from "os";
2379
- import { join as join8 } from "path";
2460
+ import { homedir as homedir5, platform } from "os";
2461
+ import { join as join9 } from "path";
2380
2462
  import { execFile } from "child_process";
2381
2463
  import { promisify } from "util";
2382
2464
  var execFileAsync = promisify(execFile);
@@ -2391,16 +2473,16 @@ async function detectClaudeAuth() {
2391
2473
  }
2392
2474
  async function findClaudeCredentialsPaths() {
2393
2475
  const candidates = [
2394
- join8(homedir4(), ".claude", ".credentials.json"),
2395
- join8(homedir4(), ".claude", "credentials.json")
2476
+ join9(homedir5(), ".claude", ".credentials.json"),
2477
+ join9(homedir5(), ".claude", "credentials.json")
2396
2478
  ];
2397
2479
  const isLinuxRoot = platform() === "linux" && typeof process.getuid === "function" && process.getuid() === 0;
2398
2480
  if (isLinuxRoot) {
2399
2481
  try {
2400
2482
  const entries = await readdir2("/home", { withFileTypes: true });
2401
2483
  for (const entry of entries.filter((entry2) => entry2.isDirectory()).sort((a, b) => a.name.localeCompare(b.name))) {
2402
- candidates.push(join8("/home", entry.name, ".claude", ".credentials.json"));
2403
- candidates.push(join8("/home", entry.name, ".claude", "credentials.json"));
2484
+ candidates.push(join9("/home", entry.name, ".claude", ".credentials.json"));
2485
+ candidates.push(join9("/home", entry.name, ".claude", "credentials.json"));
2404
2486
  }
2405
2487
  } catch {
2406
2488
  }
@@ -2478,13 +2560,13 @@ function parseExpiresAt(raw) {
2478
2560
 
2479
2561
  // src/lib/claude-account-fingerprint.ts
2480
2562
  async function candidateHomes() {
2481
- const homes = [homedir5()];
2563
+ const homes = [homedir6()];
2482
2564
  const isLinuxRoot = platform2() === "linux" && typeof process.getuid === "function" && process.getuid() === 0;
2483
2565
  if (isLinuxRoot) {
2484
2566
  try {
2485
2567
  const entries = await readdir3("/home", { withFileTypes: true });
2486
2568
  for (const entry of entries.filter((e) => e.isDirectory()).sort((a, b) => a.name.localeCompare(b.name))) {
2487
- homes.push(join9("/home", entry.name));
2569
+ homes.push(join10("/home", entry.name));
2488
2570
  }
2489
2571
  } catch {
2490
2572
  }
@@ -2504,11 +2586,11 @@ async function homeOfActiveCredentials() {
2504
2586
  async function claudeConfigCandidatePaths() {
2505
2587
  const paths = [];
2506
2588
  const configDir = process.env["CLAUDE_CONFIG_DIR"]?.trim();
2507
- if (configDir) paths.push(join9(configDir, ".claude.json"));
2589
+ if (configDir) paths.push(join10(configDir, ".claude.json"));
2508
2590
  const activeHome = await homeOfActiveCredentials();
2509
- if (activeHome) paths.push(join9(activeHome, ".claude.json"));
2591
+ if (activeHome) paths.push(join10(activeHome, ".claude.json"));
2510
2592
  for (const home of await candidateHomes()) {
2511
- const path = join9(home, ".claude.json");
2593
+ const path = join10(home, ".claude.json");
2512
2594
  if (!paths.includes(path)) paths.push(path);
2513
2595
  }
2514
2596
  return paths;
@@ -2606,10 +2688,10 @@ function diffAuthTuples(recorded, current) {
2606
2688
 
2607
2689
  // src/lib/account-enforcement-marker.ts
2608
2690
  import { mkdirSync as mkdirSync4, renameSync as renameSync2, rmSync as rmSync2, writeFileSync as writeFileSync5 } from "fs";
2609
- import { homedir as homedir6 } from "os";
2610
- import { join as join10 } from "path";
2691
+ import { homedir as homedir7 } from "os";
2692
+ import { join as join11 } from "path";
2611
2693
  function accountEnforcementMarkerPath(codeName) {
2612
- return join10(homedir6(), ".augmented", codeName, ACCOUNT_ENFORCEMENT_MARKER_FILENAME);
2694
+ return join11(homedir7(), ".augmented", codeName, ACCOUNT_ENFORCEMENT_MARKER_FILENAME);
2613
2695
  }
2614
2696
  function syncAccountEnforcementMarker(codeName, level, log2 = (m) => process.stderr.write(`${m}
2615
2697
  `), text) {
@@ -2617,8 +2699,8 @@ function syncAccountEnforcementMarker(codeName, level, log2 = (m) => process.std
2617
2699
  clearAccountEnforcementMarker(codeName, log2);
2618
2700
  return;
2619
2701
  }
2620
- const dir = join10(homedir6(), ".augmented", codeName);
2621
- const path = join10(dir, ACCOUNT_ENFORCEMENT_MARKER_FILENAME);
2702
+ const dir = join11(homedir7(), ".augmented", codeName);
2703
+ const path = join11(dir, ACCOUNT_ENFORCEMENT_MARKER_FILENAME);
2622
2704
  const tempPath = `${path}.${process.pid}.tmp`;
2623
2705
  try {
2624
2706
  mkdirSync4(dir, { recursive: true });
@@ -2644,7 +2726,7 @@ function clearAccountEnforcementMarker(codeName, log2 = (m) => process.stderr.wr
2644
2726
 
2645
2727
  // src/lib/token-usage-monitor.ts
2646
2728
  import { readdirSync, readFileSync as readFileSync8, statSync } from "fs";
2647
- import { join as join11 } from "path";
2729
+ import { join as join12 } from "path";
2648
2730
  var MIN_CHECK_INTERVAL_MS2 = 6e4;
2649
2731
  var TRANSCRIPT_MTIME_WINDOW_MS = 2 * 24 * 60 * 60 * 1e3;
2650
2732
  var MAX_ENTRIES_PER_POST = 200;
@@ -2673,7 +2755,7 @@ async function maybeReportTokenUsage(args) {
2673
2755
  if (!name.endsWith(".jsonl")) continue;
2674
2756
  const sessionId = name.slice(0, -".jsonl".length);
2675
2757
  if (!sessionId) continue;
2676
- const path = join11(dir, name);
2758
+ const path = join12(dir, name);
2677
2759
  let st;
2678
2760
  try {
2679
2761
  st = statSync(path);
@@ -2771,7 +2853,7 @@ async function maybeReportTokenUsage(args) {
2771
2853
 
2772
2854
  // src/lib/workflow-run-reconciler.ts
2773
2855
  import { readdirSync as readdirSync2, readFileSync as readFileSync9, statSync as statSync2 } from "fs";
2774
- import { join as join12 } from "path";
2856
+ import { join as join13 } from "path";
2775
2857
  var MIN_CHECK_INTERVAL_MS3 = 5 * 6e4;
2776
2858
  var SETTLE_MS = 3e4;
2777
2859
  var TRANSCRIPT_MTIME_WINDOW_MS2 = 2 * 24 * 60 * 60 * 1e3;
@@ -2790,7 +2872,7 @@ function collectJsonlRecursive(dir, minMtimeMs, out, depth) {
2790
2872
  return;
2791
2873
  }
2792
2874
  for (const name of entries) {
2793
- const p = join12(dir, name);
2875
+ const p = join13(dir, name);
2794
2876
  let st;
2795
2877
  try {
2796
2878
  st = statSync2(p);
@@ -2813,7 +2895,7 @@ function enumerateTranscriptFiles(transcriptDir, nowMs, minMtimeMs = nowMs - TRA
2813
2895
  return out;
2814
2896
  }
2815
2897
  for (const name of entries) {
2816
- const path = join12(transcriptDir, name);
2898
+ const path = join13(transcriptDir, name);
2817
2899
  let st;
2818
2900
  try {
2819
2901
  st = statSync2(path);
@@ -2825,7 +2907,7 @@ function enumerateTranscriptFiles(transcriptDir, nowMs, minMtimeMs = nowMs - TRA
2825
2907
  continue;
2826
2908
  }
2827
2909
  if (st.isDirectory()) {
2828
- collectJsonlRecursive(join12(path, "subagents"), minMtimeMs, out, 0);
2910
+ collectJsonlRecursive(join13(path, "subagents"), minMtimeMs, out, 0);
2829
2911
  }
2830
2912
  }
2831
2913
  return out;
@@ -2916,7 +2998,7 @@ async function maybeReconcileWorkflowRunTokens(args) {
2916
2998
 
2917
2999
  // src/lib/conversation-evaluator.ts
2918
3000
  import { readdirSync as readdirSync3, readFileSync as readFileSync10, statSync as statSync3 } from "fs";
2919
- import { join as join13 } from "path";
3001
+ import { join as join14 } from "path";
2920
3002
  var MIN_CHECK_INTERVAL_MS4 = 5 * 6e4;
2921
3003
  var TRANSCRIPT_MTIME_WINDOW_MS3 = 7 * 24 * 60 * 60 * 1e3;
2922
3004
  var WINDOW_PAD_MS = 5 * 6e4;
@@ -3352,7 +3434,7 @@ function readRecentTurns(dir, nowMs) {
3352
3434
  return;
3353
3435
  }
3354
3436
  for (const ent of entries) {
3355
- const full = join13(d, ent.name);
3437
+ const full = join14(d, ent.name);
3356
3438
  if (ent.isDirectory()) {
3357
3439
  visit(full);
3358
3440
  continue;
@@ -3657,18 +3739,18 @@ async function reportSkip2(api2, agentId, conversationId, log2, codeName) {
3657
3739
  }
3658
3740
 
3659
3741
  // src/lib/tool-call-audit.ts
3660
- import { homedir as homedir10 } from "os";
3661
- import { join as join18 } from "path";
3742
+ import { homedir as homedir11 } from "os";
3743
+ import { join as join19 } from "path";
3662
3744
 
3663
3745
  // src/lib/agent-logging-mode.ts
3664
3746
  import { readFileSync as readFileSync11 } from "fs";
3665
- import { homedir as homedir7 } from "os";
3666
- import { join as join14 } from "path";
3747
+ import { homedir as homedir8 } from "os";
3748
+ import { join as join15 } from "path";
3667
3749
  var LOGGING_MODES = ["hash-only", "redacted", "full-local"];
3668
3750
  function charterPath(codeName, homeDir) {
3669
- const home = homeDir ?? (process.env["HOME"]?.trim() || homedir7());
3751
+ const home = homeDir ?? (process.env["HOME"]?.trim() || homedir8());
3670
3752
  const key = agentRuntimeKey(codeName, homeDir);
3671
- return join14(home, ".augmented", key, "provision", "CHARTER.md");
3753
+ return join15(home, ".augmented", key, "provision", "CHARTER.md");
3672
3754
  }
3673
3755
  function readAgentLoggingMode(codeName, homeDir) {
3674
3756
  let raw;
@@ -3698,14 +3780,14 @@ function loggingModeWithholdsTargets(reading) {
3698
3780
  // src/lib/tool-call-path-salt.ts
3699
3781
  import { randomBytes } from "crypto";
3700
3782
  import { existsSync as existsSync3, mkdirSync as mkdirSync5, readFileSync as readFileSync12, renameSync as renameSync3, unlinkSync, writeFileSync as writeFileSync6 } from "fs";
3701
- import { homedir as homedir8 } from "os";
3702
- import { dirname as dirname5, join as join15 } from "path";
3783
+ import { homedir as homedir9 } from "os";
3784
+ import { dirname as dirname5, join as join16 } from "path";
3703
3785
  var SALT_BYTES = 32;
3704
3786
  var SALT_RE = /^[0-9a-f]{64}$/;
3705
3787
  function pathSaltPath(codeName, homeDir) {
3706
- const home = homeDir ?? (process.env["HOME"]?.trim() || homedir8());
3788
+ const home = homeDir ?? (process.env["HOME"]?.trim() || homedir9());
3707
3789
  const key = agentRuntimeKey(codeName, homeDir);
3708
- return join15(home, ".augmented", key, "tool-call-path-salt");
3790
+ return join16(home, ".augmented", key, "tool-call-path-salt");
3709
3791
  }
3710
3792
  function readToolCallPathSalt(codeName, homeDir) {
3711
3793
  let file;
@@ -3782,7 +3864,7 @@ function readHostArchiveAddress(path) {
3782
3864
 
3783
3865
  // src/lib/tool-call-extractor.ts
3784
3866
  import { closeSync, fstatSync, openSync, readFileSync as readFileSync14, readSync, readdirSync as readdirSync4 } from "fs";
3785
- import { basename, join as join16, relative } from "path";
3867
+ import { basename, join as join17, relative } from "path";
3786
3868
  import { StringDecoder } from "string_decoder";
3787
3869
 
3788
3870
  // src/lib/tool-call-redaction.ts
@@ -3911,7 +3993,7 @@ function redactToolTargetInner(toolName, input, ctx) {
3911
3993
  var EXTRACTOR_VERSION = "e1";
3912
3994
  function enumerateSessionTranscripts(transcriptDir, sessionId, projectsRoot) {
3913
3995
  const files = [];
3914
- const mainAbs = join16(transcriptDir, `${sessionId}.jsonl`);
3996
+ const mainAbs = join17(transcriptDir, `${sessionId}.jsonl`);
3915
3997
  files.push({
3916
3998
  absPath: mainAbs,
3917
3999
  relPath: relative(projectsRoot, mainAbs),
@@ -3919,7 +4001,7 @@ function enumerateSessionTranscripts(transcriptDir, sessionId, projectsRoot) {
3919
4001
  isSubagent: false,
3920
4002
  subagentId: null
3921
4003
  });
3922
- const subDir = join16(transcriptDir, sessionId, "subagents");
4004
+ const subDir = join17(transcriptDir, sessionId, "subagents");
3923
4005
  let entries;
3924
4006
  try {
3925
4007
  entries = readdirSync4(subDir);
@@ -3928,7 +4010,7 @@ function enumerateSessionTranscripts(transcriptDir, sessionId, projectsRoot) {
3928
4010
  }
3929
4011
  for (const name of entries) {
3930
4012
  if (!name.endsWith(".jsonl")) continue;
3931
- const abs = join16(subDir, name);
4013
+ const abs = join17(subDir, name);
3932
4014
  const stem = basename(name, ".jsonl");
3933
4015
  files.push({
3934
4016
  absPath: abs,
@@ -4127,8 +4209,8 @@ function extractTranscriptWindow(file, opts, from) {
4127
4209
 
4128
4210
  // src/lib/tool-call-cursor.ts
4129
4211
  import { existsSync as existsSync4, readFileSync as readFileSync15 } from "fs";
4130
- import { homedir as homedir9 } from "os";
4131
- import { join as join17 } from "path";
4212
+ import { homedir as homedir10 } from "os";
4213
+ import { join as join18 } from "path";
4132
4214
  var COVERAGE_DISPOSITIONS = [
4133
4215
  "ok",
4134
4216
  "not_entitled",
@@ -4181,9 +4263,9 @@ function parseCursorKey(key) {
4181
4263
  return { sessionId: sessionId.length > 0 ? sessionId : null, transcriptRef: key.slice(i + 1) };
4182
4264
  }
4183
4265
  function cursorStatePath(codeName, homeDir) {
4184
- const home = homeDir ?? (process.env["HOME"]?.trim() || homedir9());
4266
+ const home = homeDir ?? (process.env["HOME"]?.trim() || homedir10());
4185
4267
  const key = agentRuntimeKey(codeName, homeDir);
4186
- return join17(home, ".augmented", key, "tool-call-cursors.json");
4268
+ return join18(home, ".augmented", key, "tool-call-cursors.json");
4187
4269
  }
4188
4270
  function loadCursors(path) {
4189
4271
  const out = /* @__PURE__ */ new Map();
@@ -4595,8 +4677,8 @@ async function maybeScanToolCalls(args) {
4595
4677
  if (!salt && !hashOnly) {
4596
4678
  log2(`[tool-call-audit] ${codeName}: no path-hash salt available \u2014 file targets withheld`);
4597
4679
  }
4598
- const home = args.homeDir ?? (process.env["HOME"]?.trim() || homedir10());
4599
- const projectsRoot = args.projectsRoot ?? join18(home, ".claude", "projects");
4680
+ const home = args.homeDir ?? (process.env["HOME"]?.trim() || homedir11());
4681
+ const projectsRoot = args.projectsRoot ?? join19(home, ".claude", "projects");
4600
4682
  const transcriptDir = args.transcriptDir ?? sessionTranscriptDir(getProjectDir(codeName));
4601
4683
  const current = peekCurrentSession(codeName);
4602
4684
  const sessionIds = current ? [current.sessionId] : [];
@@ -4626,10 +4708,10 @@ async function maybeScanToolCalls(args) {
4626
4708
 
4627
4709
  // src/lib/activity-cache-monitor.ts
4628
4710
  import { existsSync as existsSync5, readFileSync as readFileSync16 } from "fs";
4629
- import { homedir as homedir11 } from "os";
4630
- import { join as join19 } from "path";
4711
+ import { homedir as homedir12 } from "os";
4712
+ import { join as join20 } from "path";
4631
4713
  var MIN_CHECK_INTERVAL_MS7 = 6e4;
4632
- var STATS_CACHE_PATH = join19(homedir11(), ".claude", "stats-cache.json");
4714
+ var STATS_CACHE_PATH = join20(homedir12(), ".claude", "stats-cache.json");
4633
4715
  var ISO_DATE_RE = /^\d{4}-\d{2}-\d{2}$/;
4634
4716
  var state6 = { lastObservedDate: null, lastCheckedAt: 0 };
4635
4717
  function selectNewDailyRows(raw, lastObservedDate) {
@@ -4910,10 +4992,10 @@ function computeChannelConfigHash(input) {
4910
4992
 
4911
4993
  // src/lib/channel-hash-cache.ts
4912
4994
  import { existsSync as existsSync6, readFileSync as readFileSync17, writeFileSync as writeFileSync7 } from "fs";
4913
- import { join as join20 } from "path";
4995
+ import { join as join21 } from "path";
4914
4996
  var CACHE_FILENAME = "channel-hash-cache.json";
4915
4997
  function getChannelHashCacheFile(configDir) {
4916
- return join20(configDir, CACHE_FILENAME);
4998
+ return join21(configDir, CACHE_FILENAME);
4917
4999
  }
4918
5000
  function loadChannelHashCache(target, configDir) {
4919
5001
  const path = getChannelHashCacheFile(configDir);
@@ -4941,7 +5023,7 @@ function saveChannelHashCache(source, configDir) {
4941
5023
 
4942
5024
  // src/lib/sender-policy-baseline.ts
4943
5025
  import { existsSync as existsSync7, readFileSync as readFileSync18 } from "fs";
4944
- import { join as join21 } from "path";
5026
+ import { join as join22 } from "path";
4945
5027
  var BASELINE_FILENAME = "sender-policy-baseline.json";
4946
5028
  var SENDER_POLICY_BASELINE_VERSION = 1;
4947
5029
  var BASELINE_CONCERNS = ["senderPolicy", "slackBehaviour", "msteamsBehaviour"];
@@ -4953,7 +5035,7 @@ function createDeliveryBaselineMaps() {
4953
5035
  };
4954
5036
  }
4955
5037
  function getSenderPolicyBaselineFile(configDir) {
4956
- return join21(configDir, BASELINE_FILENAME);
5038
+ return join22(configDir, BASELINE_FILENAME);
4957
5039
  }
4958
5040
  function loadSenderPolicyBaseline(target, configDir, log2) {
4959
5041
  const path = getSenderPolicyBaselineFile(configDir);
@@ -5483,7 +5565,7 @@ function planGlobalSkillSync(globalSkills, prevIds, hashOf, knownHash, options)
5483
5565
  }
5484
5566
 
5485
5567
  // src/lib/manager/integration-skill-cache.ts
5486
- import { join as join22 } from "path";
5568
+ import { join as join23 } from "path";
5487
5569
  function integrationSkillHashKey(agentId, skillId) {
5488
5570
  return `plugin-skill:${agentId}:${skillId}`;
5489
5571
  }
@@ -5499,16 +5581,16 @@ function forgetIntegrationSkill(cache3, agentId, skillId) {
5499
5581
  function removeIntegrationSkillFolder(opts) {
5500
5582
  forgetIntegrationSkill(opts.cache, opts.agentId, opts.entry);
5501
5583
  for (const dir of opts.dirs) {
5502
- opts.removeDir(join22(dir, opts.entry));
5584
+ opts.removeDir(join23(dir, opts.entry));
5503
5585
  }
5504
5586
  }
5505
5587
 
5506
5588
  // src/lib/manager/managed-skill-manifest.ts
5507
5589
  import { existsSync as existsSync8, mkdirSync as mkdirSync6, readFileSync as readFileSync19, writeFileSync as writeFileSync8 } from "fs";
5508
- import { dirname as dirname6, join as join23 } from "path";
5590
+ import { dirname as dirname6, join as join24 } from "path";
5509
5591
  var MANIFEST_VERSION = 1;
5510
5592
  function managedSkillManifestPath(agentRootDir) {
5511
- return join23(agentRootDir, "managed-skills.json");
5593
+ return join24(agentRootDir, "managed-skills.json");
5512
5594
  }
5513
5595
  function readManagedSkillManifest(path) {
5514
5596
  try {
@@ -5606,7 +5688,7 @@ function resolveModelChain(refreshData) {
5606
5688
  const modelDefaults = refreshData.model_defaults;
5607
5689
  const platform3 = modelDefaults?.platform ?? {};
5608
5690
  const org = modelDefaults?.org ?? {};
5609
- function resolve(tier) {
5691
+ function resolve2(tier) {
5610
5692
  const agentField = `${tier}_model`;
5611
5693
  const platformField = `default_${tier}_model`;
5612
5694
  const agentVal = agent?.[agentField];
@@ -5618,16 +5700,16 @@ function resolveModelChain(refreshData) {
5618
5700
  return void 0;
5619
5701
  }
5620
5702
  return {
5621
- primary: resolve("primary"),
5622
- secondary: resolve("secondary"),
5623
- tertiary: resolve("tertiary")
5703
+ primary: resolve2("primary"),
5704
+ secondary: resolve2("secondary"),
5705
+ tertiary: resolve2("tertiary")
5624
5706
  };
5625
5707
  }
5626
5708
 
5627
5709
  // src/lib/manager/claude-auth.ts
5628
5710
  import { existsSync as existsSync9, rmSync as rmSync3 } from "fs";
5629
- import { join as join24 } from "path";
5630
- import { homedir as homedir12 } from "os";
5711
+ import { join as join25 } from "path";
5712
+ import { homedir as homedir13 } from "os";
5631
5713
  async function applyClaudeAuthToEnv(childEnv, label) {
5632
5714
  const apiKey = getApiKey();
5633
5715
  if (!apiKey) {
@@ -5639,9 +5721,9 @@ async function applyClaudeAuthToEnv(childEnv, label) {
5639
5721
  throw new Error("claude_auth_mode=api_key but /host/exchange returned no decrypted key");
5640
5722
  }
5641
5723
  childEnv.ANTHROPIC_API_KEY = exchange.anthropicApiKey;
5642
- const claudeDir = join24(homedir12(), ".claude");
5724
+ const claudeDir = join25(homedir13(), ".claude");
5643
5725
  for (const filename of [".credentials.json", "credentials.json"]) {
5644
- const p = join24(claudeDir, filename);
5726
+ const p = join25(claudeDir, filename);
5645
5727
  if (existsSync9(p)) {
5646
5728
  try {
5647
5729
  rmSync3(p, { force: true });
@@ -5724,7 +5806,7 @@ function heartbeatRuntimeAuthFields(probeVerdict) {
5724
5806
 
5725
5807
  // src/lib/manager/kanban/parsers.ts
5726
5808
  import { existsSync as existsSync10, readFileSync as readFileSync20 } from "fs";
5727
- import { join as join25 } from "path";
5809
+ import { join as join26 } from "path";
5728
5810
  var STANDUP_TEMPLATES = /* @__PURE__ */ new Set(["daily-standup", "end-of-day-summary"]);
5729
5811
  var TASK_UPDATE_TEMPLATES = /* @__PURE__ */ new Set(["hourly-status", "task-update"]);
5730
5812
  var PLAN_TEMPLATES = /* @__PURE__ */ new Set(["morning-plan"]);
@@ -5876,8 +5958,8 @@ function getBuiltInSkillContent(skillId) {
5876
5958
  if (builtInSkillCache.has(skillId)) return builtInSkillCache.get(skillId);
5877
5959
  try {
5878
5960
  const candidates = [
5879
- join25(process.cwd(), "skills", skillId, "SKILL.md"),
5880
- join25(new URL(".", import.meta.url).pathname, "..", "..", "..", "..", "..", "..", "skills", skillId, "SKILL.md")
5961
+ join26(process.cwd(), "skills", skillId, "SKILL.md"),
5962
+ join26(new URL(".", import.meta.url).pathname, "..", "..", "..", "..", "..", "..", "skills", skillId, "SKILL.md")
5881
5963
  ];
5882
5964
  for (const candidate of candidates) {
5883
5965
  if (existsSync10(candidate)) {
@@ -6023,11 +6105,11 @@ function formatBoardForPrompt(items, template) {
6023
6105
 
6024
6106
  // src/lib/manager/kanban/nudge-state-cache.ts
6025
6107
  import { existsSync as existsSync11, readFileSync as readFileSync21, writeFileSync as writeFileSync9 } from "fs";
6026
- import { join as join26 } from "path";
6108
+ import { join as join27 } from "path";
6027
6109
  var CACHE_FILENAME2 = "kanban-nudge-state.json";
6028
6110
  var KANBAN_NUDGE_STATE_VERSION = 1;
6029
6111
  function getKanbanNudgeStateFile(configDir) {
6030
- return join26(configDir, CACHE_FILENAME2);
6112
+ return join27(configDir, CACHE_FILENAME2);
6031
6113
  }
6032
6114
  function loadKanbanNudgeState(target, configDir) {
6033
6115
  const path = getKanbanNudgeStateFile(configDir);
@@ -6244,7 +6326,7 @@ async function maybePostSlackThreadHint(agentCodeName, channelId, primaryTs) {
6244
6326
  // src/lib/manager/channels/telegram.ts
6245
6327
  import https from "https";
6246
6328
  function telegramApiCall(botToken, method, body) {
6247
- return new Promise((resolve, reject) => {
6329
+ return new Promise((resolve2, reject) => {
6248
6330
  const postData = JSON.stringify(body);
6249
6331
  const req = https.request({
6250
6332
  hostname: "api.telegram.org",
@@ -6261,7 +6343,7 @@ function telegramApiCall(botToken, method, body) {
6261
6343
  });
6262
6344
  res.on("end", () => {
6263
6345
  try {
6264
- resolve(JSON.parse(data));
6346
+ resolve2(JSON.parse(data));
6265
6347
  } catch {
6266
6348
  reject(new Error("Invalid JSON from Telegram API"));
6267
6349
  }
@@ -6568,7 +6650,7 @@ async function finishRun(runId, outcome, options = {}) {
6568
6650
  log(
6569
6651
  `[runs] finish attempt ${attempt + 1}/${maxRetries + 1} failed for run_id=${runId} outcome=${outcome} status=${status} error_id=${errId} \u2014 retrying`
6570
6652
  );
6571
- await new Promise((resolve) => setTimeout(resolve, baseMs * 2 ** attempt));
6653
+ await new Promise((resolve2) => setTimeout(resolve2, baseMs * 2 ** attempt));
6572
6654
  continue;
6573
6655
  }
6574
6656
  log(
@@ -6653,8 +6735,8 @@ function closeSessionRunForCode(codeName, outcome, reason) {
6653
6735
  // src/lib/manager/scheduler/kanban-route.ts
6654
6736
  import { createHash as createHash12 } from "crypto";
6655
6737
  import { writeFileSync as writeFileSync10, renameSync as renameSync4, mkdirSync as mkdirSync7, readFileSync as readFileSync22, unlinkSync as unlinkSync2 } from "fs";
6656
- import { homedir as homedir13 } from "os";
6657
- import { join as join27, dirname as dirname7 } from "path";
6738
+ import { homedir as homedir14 } from "os";
6739
+ import { join as join28, dirname as dirname7 } from "path";
6658
6740
 
6659
6741
  // src/lib/manager/scheduler/notify.ts
6660
6742
  import { createHash as createHash11 } from "crypto";
@@ -7013,7 +7095,7 @@ function resolveScheduledSlackTarget(task) {
7013
7095
  }
7014
7096
  function stampScheduledTurnMarker(codeName, taskId, target) {
7015
7097
  try {
7016
- const file = join27(homedir13(), ".augmented", codeName, SCHEDULED_TURN_MARKER_FILENAME);
7098
+ const file = join28(homedir14(), ".augmented", codeName, SCHEDULED_TURN_MARKER_FILENAME);
7017
7099
  const marker = { ts: Date.now(), task_id: taskId, ...target ? { target } : {} };
7018
7100
  const tmp = `${file}.tmp`;
7019
7101
  writeFileSync10(tmp, JSON.stringify(marker), "utf8");
@@ -7023,7 +7105,7 @@ function stampScheduledTurnMarker(codeName, taskId, target) {
7023
7105
  }
7024
7106
  }
7025
7107
  function clearScheduledTurnMarkerForTask(codeName, taskId) {
7026
- const file = join27(homedir13(), ".augmented", codeName, SCHEDULED_TURN_MARKER_FILENAME);
7108
+ const file = join28(homedir14(), ".augmented", codeName, SCHEDULED_TURN_MARKER_FILENAME);
7027
7109
  try {
7028
7110
  const raw = JSON.parse(readFileSync22(file, "utf8"));
7029
7111
  if (typeof raw?.task_id !== "string" || raw.task_id !== taskId) return;
@@ -7085,7 +7167,7 @@ async function routeScheduledTaskViaKanban(codeName, agentId, task, prompt, dura
7085
7167
  return false;
7086
7168
  }
7087
7169
  try {
7088
- const doorbell = directChatDoorbellPath(agentId, homedir13());
7170
+ const doorbell = directChatDoorbellPath(agentId, homedir14());
7089
7171
  mkdirSync7(dirname7(doorbell), { recursive: true });
7090
7172
  writeFileSync10(doorbell, String(Date.now()));
7091
7173
  } catch (err) {
@@ -7237,12 +7319,12 @@ async function processClaudeTaskResult(codeName, agentId, templateId, rawOutput,
7237
7319
 
7238
7320
  // src/lib/manager/scheduler/execution.ts
7239
7321
  import { createHash as createHash13 } from "crypto";
7240
- import { homedir as homedir14 } from "os";
7241
- import { join as join29 } from "path";
7322
+ import { homedir as homedir15 } from "os";
7323
+ import { join as join30 } from "path";
7242
7324
 
7243
7325
  // src/lib/agent-serving-probe.ts
7244
7326
  import { readFileSync as readFileSync23, readdirSync as readdirSync5, statSync as statSync5 } from "fs";
7245
- import { join as join28 } from "path";
7327
+ import { join as join29 } from "path";
7246
7328
  var RATE_LIMIT_WINDOW_MS = 6 * 60 * 60 * 1e3;
7247
7329
  function probeRateLimit(args) {
7248
7330
  const now = args.now ?? /* @__PURE__ */ new Date();
@@ -7258,7 +7340,7 @@ function probeRateLimit(args) {
7258
7340
  let newest = UNKNOWN_RATE_LIMIT;
7259
7341
  for (const name of entries) {
7260
7342
  if (!name.endsWith(".jsonl")) continue;
7261
- const path = join28(dir, name);
7343
+ const path = join29(dir, name);
7262
7344
  try {
7263
7345
  const st = statSync5(path);
7264
7346
  if (!st.isFile() || st.mtimeMs < startMs) continue;
@@ -7329,7 +7411,7 @@ function shouldLogUsageCapDeferral(site, codeName, limitedUntil) {
7329
7411
 
7330
7412
  // src/lib/manager/scheduler/execution.ts
7331
7413
  function claudePidFilePath() {
7332
- return join29(homedir14(), ".augmented", "manager-claude-pids.json");
7414
+ return join30(homedir15(), ".augmented", "manager-claude-pids.json");
7333
7415
  }
7334
7416
  var inFlightClaudePids = /* @__PURE__ */ new Map();
7335
7417
  function registerClaudeSpawn(record) {
@@ -7400,7 +7482,7 @@ async function syncAndCheckClaudeScheduler(agent, tasks, boardItems, refreshData
7400
7482
 
7401
7483
  // src/lib/occupancy-gate.ts
7402
7484
  import { closeSync as closeSync2, openSync as openSync2, readdirSync as readdirSync6, readSync as readSync2, statSync as statSync6 } from "fs";
7403
- import { join as join30 } from "path";
7485
+ import { join as join31 } from "path";
7404
7486
  function rostersMeasuredZero(mode, attested, runtimeRunning) {
7405
7487
  return mode === "enforce" && attested && runtimeRunning;
7406
7488
  }
@@ -7489,10 +7571,10 @@ function candidateTranscriptPaths(dir) {
7489
7571
  let complete = true;
7490
7572
  for (const name of top) {
7491
7573
  if (name.endsWith(".jsonl")) {
7492
- paths.push(join30(dir, name));
7574
+ paths.push(join31(dir, name));
7493
7575
  continue;
7494
7576
  }
7495
- const subDir = join30(dir, name, "subagents");
7577
+ const subDir = join31(dir, name, "subagents");
7496
7578
  let subs;
7497
7579
  try {
7498
7580
  subs = readdirSync6(subDir);
@@ -7501,7 +7583,7 @@ function candidateTranscriptPaths(dir) {
7501
7583
  continue;
7502
7584
  }
7503
7585
  for (const sub of subs) {
7504
- if (sub.endsWith(".jsonl")) paths.push(join30(subDir, sub));
7586
+ if (sub.endsWith(".jsonl")) paths.push(join31(subDir, sub));
7505
7587
  }
7506
7588
  }
7507
7589
  return { paths, complete };
@@ -8985,7 +9067,7 @@ async function fireOpencodeScheduledTask(agent, task) {
8985
9067
  import { createHash as createHash16 } from "crypto";
8986
9068
  import { existsSync as existsSync13, mkdirSync as mkdirSync8, readFileSync as readFileSync25, renameSync as renameSync5, unlinkSync as unlinkSync3, writeFileSync as writeFileSync11 } from "fs";
8987
9069
  import { randomUUID } from "crypto";
8988
- import { join as join31 } from "path";
9070
+ import { join as join32 } from "path";
8989
9071
 
8990
9072
  // src/lib/telegram-ingest.ts
8991
9073
  import https2 from "https";
@@ -9207,7 +9289,7 @@ function buildTelegramPeerClassifierConfigFromEnv(env, opts) {
9207
9289
  }
9208
9290
 
9209
9291
  // src/lib/telegram-ingest.ts
9210
- var nodeHttpsTelegramFetch = (url, init) => new Promise((resolve, reject) => {
9292
+ var nodeHttpsTelegramFetch = (url, init) => new Promise((resolve2, reject) => {
9211
9293
  const u = new URL(url);
9212
9294
  const body = init?.body;
9213
9295
  const headers = { ...init?.headers ?? {} };
@@ -9233,7 +9315,7 @@ var nodeHttpsTelegramFetch = (url, init) => new Promise((resolve, reject) => {
9233
9315
  });
9234
9316
  res.on("end", () => {
9235
9317
  const status = res.statusCode ?? 0;
9236
- resolve({
9318
+ resolve2({
9237
9319
  ok: status >= 200 && status < 300,
9238
9320
  status,
9239
9321
  json: async () => JSON.parse(data.length > 0 ? data : "{}")
@@ -9422,8 +9504,8 @@ function defaultAddReaction2(botToken, fetchImpl, log2) {
9422
9504
  };
9423
9505
  }
9424
9506
  function sleep(ms) {
9425
- return new Promise((resolve) => {
9426
- setTimeout(resolve, ms).unref?.();
9507
+ return new Promise((resolve2) => {
9508
+ setTimeout(resolve2, ms).unref?.();
9427
9509
  });
9428
9510
  }
9429
9511
  function startTelegramIngest(config2) {
@@ -9533,7 +9615,7 @@ function createFileOffsetStore(codeName, log2, currentBotId) {
9533
9615
  let filePath;
9534
9616
  try {
9535
9617
  dir = getFramework("opencode").getAgentDir(codeName);
9536
- filePath = join31(dir, "telegram-getupdates-offset-opencode.json");
9618
+ filePath = join32(dir, "telegram-getupdates-offset-opencode.json");
9537
9619
  } catch {
9538
9620
  dir = null;
9539
9621
  filePath = null;
@@ -9813,14 +9895,14 @@ function partitionActionableByPoison(actionable, states, config2) {
9813
9895
 
9814
9896
  // src/lib/restart-flags.ts
9815
9897
  import { existsSync as existsSync14, mkdirSync as mkdirSync9, readdirSync as readdirSync7, readFileSync as readFileSync26, renameSync as renameSync6, rmSync as rmSync4, writeFileSync as writeFileSync12 } from "fs";
9816
- import { homedir as homedir15 } from "os";
9817
- import { join as join32 } from "path";
9898
+ import { homedir as homedir16 } from "os";
9899
+ import { join as join33 } from "path";
9818
9900
  import { randomUUID as randomUUID2 } from "crypto";
9819
9901
  function restartFlagsDir() {
9820
- return join32(homedir15(), ".augmented", "restart-flags");
9902
+ return join33(homedir16(), ".augmented", "restart-flags");
9821
9903
  }
9822
9904
  function flagPath(codeName) {
9823
- return join32(restartFlagsDir(), `${codeName}.flag`);
9905
+ return join33(restartFlagsDir(), `${codeName}.flag`);
9824
9906
  }
9825
9907
  function readRestartFlags() {
9826
9908
  const dir = restartFlagsDir();
@@ -9829,7 +9911,7 @@ function readRestartFlags() {
9829
9911
  for (const entry of readdirSync7(dir)) {
9830
9912
  if (!entry.endsWith(".flag")) continue;
9831
9913
  try {
9832
- const raw = readFileSync26(join32(dir, entry), "utf8");
9914
+ const raw = readFileSync26(join33(dir, entry), "utf8");
9833
9915
  const parsed = JSON.parse(raw);
9834
9916
  if (typeof parsed.codeName !== "string" || parsed.codeName.length === 0) {
9835
9917
  parsed.codeName = entry.replace(/\.flag$/, "");
@@ -9948,7 +10030,7 @@ async function sendError(flag, opts, text) {
9948
10030
 
9949
10031
  // src/lib/restart-context.ts
9950
10032
  import { readdirSync as readdirSync8, readFileSync as readFileSync27, writeFileSync as writeFileSync13, mkdirSync as mkdirSync10, unlinkSync as unlinkSync4 } from "fs";
9951
- import { dirname as dirname8, join as join33 } from "path";
10033
+ import { dirname as dirname8, join as join34 } from "path";
9952
10034
  var SLACK_PENDING_INBOUND_DIRNAME = "slack-pending-inbound";
9953
10035
  var SLACK_RESTART_CONTEXT_DIRNAME = "slack-restart-context";
9954
10036
  var MAX_TOPIC_CHARS = 140;
@@ -9960,10 +10042,10 @@ function augmentedAgentDir(codeName) {
9960
10042
  return dirname8(getProjectDir(codeName));
9961
10043
  }
9962
10044
  function slackPendingInboundDir(codeName) {
9963
- return join33(augmentedAgentDir(codeName), SLACK_PENDING_INBOUND_DIRNAME);
10045
+ return join34(augmentedAgentDir(codeName), SLACK_PENDING_INBOUND_DIRNAME);
9964
10046
  }
9965
10047
  function slackRestartContextDir(codeName) {
9966
- return join33(augmentedAgentDir(codeName), SLACK_RESTART_CONTEXT_DIRNAME);
10048
+ return join34(augmentedAgentDir(codeName), SLACK_RESTART_CONTEXT_DIRNAME);
9967
10049
  }
9968
10050
  function sanitizeTopic(raw) {
9969
10051
  const cleaned = raw.replace(/\s+/g, " ").trim().replace(/[<>]/g, " ").replace(/\s+/g, " ").trim();
@@ -10023,7 +10105,7 @@ function pruneHintsExcept(codeName, freshFilenames) {
10023
10105
  if (!filename.endsWith(".json")) continue;
10024
10106
  if (freshFilenames.has(filename)) continue;
10025
10107
  try {
10026
- unlinkSync4(join33(ctxDir, filename));
10108
+ unlinkSync4(join34(ctxDir, filename));
10027
10109
  } catch {
10028
10110
  }
10029
10111
  }
@@ -10044,7 +10126,7 @@ function refreshSlackRestartContextHints(codeNames, opts = {}) {
10044
10126
  }
10045
10127
  const markers = [];
10046
10128
  for (const filename of markerFilenames.slice(0, cap)) {
10047
- const parsed = readStrandedMarker(join33(markerDir, filename));
10129
+ const parsed = readStrandedMarker(join34(markerDir, filename));
10048
10130
  if (parsed) markers.push({ filename, channel: parsed.channel, thread_ts: parsed.thread_ts });
10049
10131
  }
10050
10132
  if (markers.length === 0) {
@@ -10058,7 +10140,7 @@ function refreshSlackRestartContextHints(codeNames, opts = {}) {
10058
10140
  const freshFilenames = /* @__PURE__ */ new Set();
10059
10141
  for (const { filename, hint } of hints) {
10060
10142
  try {
10061
- writeHintFile(join33(ctxDir, filename), ctxDir, hint);
10143
+ writeHintFile(join34(ctxDir, filename), ctxDir, hint);
10062
10144
  freshFilenames.add(filename);
10063
10145
  } catch (err) {
10064
10146
  log2(`[restart-context] ${codeName}: hint write failed for ${filename}: ${err.message}`);
@@ -11660,7 +11742,7 @@ var runningChannelSecretHashes = /* @__PURE__ */ new Map();
11660
11742
  var sessionLaunchManagedStructure = /* @__PURE__ */ new Map();
11661
11743
  function projectMcpHash(_codeName, projectDir) {
11662
11744
  try {
11663
- const raw = readFileSync28(join34(projectDir, ".mcp.json"), "utf-8");
11745
+ const raw = readFileSync28(join35(projectDir, ".mcp.json"), "utf-8");
11664
11746
  return createHash17("sha256").update(canonicalJson(JSON.parse(raw))).digest("hex");
11665
11747
  } catch {
11666
11748
  return null;
@@ -11668,7 +11750,7 @@ function projectMcpHash(_codeName, projectDir) {
11668
11750
  }
11669
11751
  function projectMcpKeys(_codeName, projectDir) {
11670
11752
  try {
11671
- const raw = readFileSync28(join34(projectDir, ".mcp.json"), "utf-8");
11753
+ const raw = readFileSync28(join35(projectDir, ".mcp.json"), "utf-8");
11672
11754
  const parsed = JSON.parse(raw);
11673
11755
  const servers = parsed.mcpServers;
11674
11756
  if (!servers || typeof servers !== "object") return /* @__PURE__ */ new Set();
@@ -11686,7 +11768,7 @@ function seedSessionLaunchBaselines(codeName, projectDir) {
11686
11768
  else runningMcpServerKeys.delete(codeName);
11687
11769
  let launchStructure = null;
11688
11770
  try {
11689
- const raw = readFileSync28(join34(projectDir, ".mcp.json"), "utf-8");
11771
+ const raw = readFileSync28(join35(projectDir, ".mcp.json"), "utf-8");
11690
11772
  launchStructure = managedMcpStructureHashFromFile(
11691
11773
  JSON.parse(raw),
11692
11774
  isManagedMcpServerKey
@@ -11808,7 +11890,7 @@ async function runAgentSessionToolBindProbes(agent, integrations, projectDir, op
11808
11890
  if (result && result.rebindCandidates.length > 0 && hostFlagStore().getBoolean("session-tool-rebind")) {
11809
11891
  let mcpJsonForRebind = null;
11810
11892
  try {
11811
- mcpJsonForRebind = JSON.parse(readFileSync28(join34(projectDir, ".mcp.json"), "utf-8"));
11893
+ mcpJsonForRebind = JSON.parse(readFileSync28(join35(projectDir, ".mcp.json"), "utf-8"));
11812
11894
  } catch {
11813
11895
  mcpJsonForRebind = null;
11814
11896
  }
@@ -11953,7 +12035,7 @@ function checkMcpConfigDriftAndScheduleRestart(codeName, projectDir) {
11953
12035
  function projectChannelSecretHash(projectDir) {
11954
12036
  try {
11955
12037
  const entries = parseEnvIntegrations(
11956
- readFileSync28(join34(projectDir, ".env.integrations"), "utf-8")
12038
+ readFileSync28(join35(projectDir, ".env.integrations"), "utf-8")
11957
12039
  );
11958
12040
  return channelSecretValueHash(entries, CHANNEL_SECRET_ENV_KEYS);
11959
12041
  } catch {
@@ -12049,7 +12131,7 @@ var agentRestartTimezoneInputs = /* @__PURE__ */ new Map();
12049
12131
  var lastVersionCheckAt = 0;
12050
12132
  var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
12051
12133
  var lastResponsivenessProbeAt = 0;
12052
- var agtCliVersion = true ? "0.28.627" : "dev";
12134
+ var agtCliVersion = true ? "0.28.629" : "dev";
12053
12135
  function resolveBrewPath(execFileSync3) {
12054
12136
  try {
12055
12137
  const out = execFileSync3("which", ["brew"], { timeout: 5e3 }).toString().trim();
@@ -12336,7 +12418,7 @@ async function reapSupersededRuntimeImages(imageUri, localTag) {
12336
12418
  }
12337
12419
  }
12338
12420
  function runAsync(cmd, args, opts) {
12339
- return new Promise((resolve, reject) => {
12421
+ return new Promise((resolve2, reject) => {
12340
12422
  import("child_process").then(({ spawn }) => {
12341
12423
  const child = spawn(cmd, args, { stdio: ["ignore", "pipe", "pipe"], cwd: opts.cwd });
12342
12424
  let stdout = "";
@@ -12370,7 +12452,7 @@ function runAsync(cmd, args, opts) {
12370
12452
  if (settled) return;
12371
12453
  settled = true;
12372
12454
  clearTimeout(timer3);
12373
- resolve({ code: code ?? -1, stdout, stderr });
12455
+ resolve2({ code: code ?? -1, stdout, stderr });
12374
12456
  });
12375
12457
  }).catch(reject);
12376
12458
  });
@@ -12437,7 +12519,7 @@ async function ensureOpencodeBinary() {
12437
12519
  try {
12438
12520
  const prefix = execFileSync3("npm", ["prefix", "-g"], { encoding: "utf-8", timeout: 1e4 }).trim();
12439
12521
  if (prefix) {
12440
- const npmBin = join34(prefix, "bin");
12522
+ const npmBin = join35(prefix, "bin");
12441
12523
  const current = (process.env.PATH ?? "").split(pathDelimiter);
12442
12524
  if (!current.includes(npmBin)) {
12443
12525
  process.env.PATH = [npmBin, ...current.filter(Boolean)].join(pathDelimiter);
@@ -12554,7 +12636,7 @@ ${r.stderr}`;
12554
12636
  }
12555
12637
  var UPDATE_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
12556
12638
  function selfUpdateAppliedMarkerPath() {
12557
- return join34(homedir16(), ".augmented", ".last-self-update-applied");
12639
+ return join35(homedir17(), ".augmented", ".last-self-update-applied");
12558
12640
  }
12559
12641
  var selfUpdateUpToDateLogged = false;
12560
12642
  var selfUpdatePinnedLogged = false;
@@ -12583,7 +12665,7 @@ async function checkAndUpdateCli(opts) {
12583
12665
  const isNpmGlobal = !isBrewFormula && resolvedPath.includes("node_modules");
12584
12666
  if (!isBrewFormula && !isNpmGlobal) return "noop";
12585
12667
  const { readFileSync: readF, writeFileSync: writeF } = await import("fs");
12586
- const markerPath = join34(homedir16(), ".augmented", ".last-update-check");
12668
+ const markerPath = join35(homedir17(), ".augmented", ".last-update-check");
12587
12669
  if (!force) {
12588
12670
  try {
12589
12671
  const lastCheck = parseInt(readF(markerPath, "utf-8").trim(), 10);
@@ -12989,7 +13071,7 @@ async function runClaudeRuntimeAuthProbe() {
12989
13071
  ];
12990
13072
  try {
12991
13073
  const { stdout, stderr } = await execFilePromiseLong(resolveClaudeBinary(), args, {
12992
- cwd: homedir16(),
13074
+ cwd: homedir17(),
12993
13075
  timeout: RUNTIME_AUTH_PROBE_TIMEOUT_MS,
12994
13076
  stdin: "ignore",
12995
13077
  env: childEnv,
@@ -13036,12 +13118,12 @@ async function checkClaudeAuth() {
13036
13118
  var evalEmptyMcpConfigPath = null;
13037
13119
  function ensureEvalEmptyMcpConfig() {
13038
13120
  if (evalEmptyMcpConfigPath && existsSync15(evalEmptyMcpConfigPath)) return evalEmptyMcpConfigPath;
13039
- const dir = join34(homedir16(), ".augmented");
13121
+ const dir = join35(homedir17(), ".augmented");
13040
13122
  try {
13041
13123
  mkdirSync11(dir, { recursive: true });
13042
13124
  } catch {
13043
13125
  }
13044
- const p = join34(dir, ".eval-empty-mcp.json");
13126
+ const p = join35(dir, ".eval-empty-mcp.json");
13045
13127
  writeFileSync14(p, JSON.stringify({ mcpServers: {} }));
13046
13128
  evalEmptyMcpConfigPath = p;
13047
13129
  return p;
@@ -13067,7 +13149,7 @@ async function runEvalClaude(prompt, model) {
13067
13149
  ""
13068
13150
  ];
13069
13151
  const { stdout } = await execFilePromiseLong(resolveClaudeBinary(), args, {
13070
- cwd: homedir16(),
13152
+ cwd: homedir17(),
13071
13153
  timeout: 12e4,
13072
13154
  stdin: "ignore",
13073
13155
  env: childEnv,
@@ -13136,10 +13218,10 @@ function resolveConversationEvalBackend() {
13136
13218
  return conversationEvalBackend;
13137
13219
  }
13138
13220
  function getStateFile() {
13139
- return join34(config?.configDir ?? join34(process.env["HOME"] ?? "/tmp", ".augmented"), "manager-state.json");
13221
+ return join35(config?.configDir ?? join35(process.env["HOME"] ?? "/tmp", ".augmented"), "manager-state.json");
13140
13222
  }
13141
13223
  function channelHashCacheDir() {
13142
- return config?.configDir ?? join34(process.env["HOME"] ?? "/tmp", ".augmented");
13224
+ return config?.configDir ?? join35(process.env["HOME"] ?? "/tmp", ".augmented");
13143
13225
  }
13144
13226
  function loadChannelHashCache2() {
13145
13227
  loadChannelHashCache(agentState.knownChannelConfigHashes, channelHashCacheDir());
@@ -13193,7 +13275,7 @@ function removeDeliveryBaselineEntries(agentId) {
13193
13275
  var _channelQuarantineStore = null;
13194
13276
  function channelQuarantineStore() {
13195
13277
  if (!_channelQuarantineStore) {
13196
- const dir = config?.configDir ?? join34(process.env["HOME"] ?? "/tmp", ".augmented");
13278
+ const dir = config?.configDir ?? join35(process.env["HOME"] ?? "/tmp", ".augmented");
13197
13279
  _channelQuarantineStore = new ChannelQuarantineStore(defaultQuarantinePath(dir));
13198
13280
  }
13199
13281
  return _channelQuarantineStore;
@@ -13210,7 +13292,7 @@ function claudeMdSizeFor(codeName) {
13210
13292
  var _hostFlagStore = null;
13211
13293
  function hostFlagStore() {
13212
13294
  if (!_hostFlagStore) {
13213
- const dir = config?.configDir ?? join34(process.env["HOME"] ?? "/tmp", ".augmented");
13295
+ const dir = config?.configDir ?? join35(process.env["HOME"] ?? "/tmp", ".augmented");
13214
13296
  _hostFlagStore = new HostFlagStore({ cachePath: defaultFlagsCachePath(dir), log });
13215
13297
  }
13216
13298
  return _hostFlagStore;
@@ -13284,12 +13366,12 @@ function parseSkillFrontmatter(content) {
13284
13366
  }
13285
13367
  async function refreshSkillsIndexInClaudeMd(configDir, codeName, log2) {
13286
13368
  const { readdirSync: readdirSync10, readFileSync: rfs, existsSync: ex, writeFileSync: writeFileSync15 } = await import("fs");
13287
- const skillsDir = join34(configDir, codeName, "project", ".claude", "skills");
13288
- const claudeMdPath = join34(configDir, codeName, "project", "CLAUDE.md");
13369
+ const skillsDir = join35(configDir, codeName, "project", ".claude", "skills");
13370
+ const claudeMdPath = join35(configDir, codeName, "project", "CLAUDE.md");
13289
13371
  if (!ex(skillsDir) || !ex(claudeMdPath)) return;
13290
13372
  const entries = [];
13291
13373
  for (const dir of readdirSync10(skillsDir).sort()) {
13292
- const skillFile = join34(skillsDir, dir, "SKILL.md");
13374
+ const skillFile = join35(skillsDir, dir, "SKILL.md");
13293
13375
  if (!ex(skillFile)) continue;
13294
13376
  try {
13295
13377
  const { name, description } = parseSkillFrontmatter(rfs(skillFile, "utf-8"));
@@ -13793,10 +13875,10 @@ async function pollCycleInner() {
13793
13875
  const paneTail = readFileSync28(paneLogPath(codeName), "utf8").slice(-65536);
13794
13876
  const transient = detectTransientApiErrorInLog(paneTail);
13795
13877
  if (transient) {
13796
- const wedgeHome = join34(homedir16(), ".augmented", codeName);
13878
+ const wedgeHome = join35(homedir17(), ".augmented", codeName);
13797
13879
  if (existsSync15(wedgeHome)) {
13798
13880
  atomicWriteFileSync(
13799
- join34(wedgeHome, "watchdog-give-up.json"),
13881
+ join35(wedgeHome, "watchdog-give-up.json"),
13800
13882
  JSON.stringify({
13801
13883
  gave_up_at: wedgeNow.toISOString(),
13802
13884
  reason: "transient_overload"
@@ -14090,7 +14172,7 @@ async function pollCycleInner() {
14090
14172
  const adapter = resolveAgentFramework(prev.codeName);
14091
14173
  stopAgentRuntime2(prev.codeName, "removed-from-host");
14092
14174
  killAgentChannelProcesses(prev.codeName, { log });
14093
- const agentDir = join34(adapter.getAgentDir(prev.codeName), "provision");
14175
+ const agentDir = join35(adapter.getAgentDir(prev.codeName), "provision");
14094
14176
  await cleanupAgentFiles(prev.codeName, agentDir);
14095
14177
  clearAgentCaches(prev.agentId, prev.codeName);
14096
14178
  }
@@ -14177,10 +14259,10 @@ async function pollCycleInner() {
14177
14259
  // pending-inbound marker. Best-effort: a write failure is logged by
14178
14260
  // the watchdog, never fails the poll cycle.
14179
14261
  signalGiveUp: (codeName) => {
14180
- const dir = join34(homedir16(), ".augmented", codeName);
14262
+ const dir = join35(homedir17(), ".augmented", codeName);
14181
14263
  if (!existsSync15(dir)) return;
14182
14264
  atomicWriteFileSync(
14183
- join34(dir, "watchdog-give-up.json"),
14265
+ join35(dir, "watchdog-give-up.json"),
14184
14266
  JSON.stringify({ gave_up_at: (/* @__PURE__ */ new Date()).toISOString() })
14185
14267
  );
14186
14268
  }
@@ -14376,7 +14458,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
14376
14458
  }
14377
14459
  const now = (/* @__PURE__ */ new Date()).toISOString();
14378
14460
  const adapter = resolveAgentFramework(agent.code_name);
14379
- let agentDir = join34(adapter.getAgentDir(agent.code_name), "provision");
14461
+ let agentDir = join35(adapter.getAgentDir(agent.code_name), "provision");
14380
14462
  if (agent.status === "draft" || agent.status === "paused") {
14381
14463
  if (previousKnownStatus !== agent.status) {
14382
14464
  log(`Agent '${agent.code_name}' is ${agent.status}, skipping provisioning`);
@@ -14550,7 +14632,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
14550
14632
  const frameworkId = refreshData.agent.framework ?? DEFAULT_FRAMEWORK;
14551
14633
  agentFrameworkCache.set(agent.code_name, frameworkId);
14552
14634
  const frameworkAdapter = getFramework(frameworkId);
14553
- agentDir = join34(frameworkAdapter.getAgentDir(agent.code_name), "provision");
14635
+ agentDir = join35(frameworkAdapter.getAgentDir(agent.code_name), "provision");
14554
14636
  cacheAgentDeliveryMetadata(agent.code_name, refreshData);
14555
14637
  agentRestartTimezoneInputs.set(agent.code_name, {
14556
14638
  agentTimezone: typeof refreshData.agent.timezone === "string" ? refreshData.agent.timezone : null,
@@ -14599,7 +14681,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
14599
14681
  const changedFiles = [];
14600
14682
  mkdirSync11(agentDir, { recursive: true });
14601
14683
  for (const artifact of artifacts) {
14602
- const filePath = join34(agentDir, artifact.relativePath);
14684
+ const filePath = join35(agentDir, artifact.relativePath);
14603
14685
  let existingHash;
14604
14686
  let newHash;
14605
14687
  let writeContent = artifact.content;
@@ -14618,7 +14700,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
14618
14700
  };
14619
14701
  newHash = sha256(stripDynamicSections(artifact.content));
14620
14702
  try {
14621
- const projectClaudeMd = join34(config.configDir, agent.code_name, "project", "CLAUDE.md");
14703
+ const projectClaudeMd = join35(config.configDir, agent.code_name, "project", "CLAUDE.md");
14622
14704
  const existing = readFileSync28(projectClaudeMd, "utf-8");
14623
14705
  existingHash = sha256(stripDynamicSections(existing));
14624
14706
  } catch {
@@ -14669,12 +14751,12 @@ async function processAgent(agent, agentStates, managedToolkits) {
14669
14751
  }
14670
14752
  }
14671
14753
  if (changedFiles.length > 0) {
14672
- const isFirst = !existsSync15(join34(agentDir, "CHARTER.md"));
14754
+ const isFirst = !existsSync15(join35(agentDir, "CHARTER.md"));
14673
14755
  const verb = isFirst ? "Provisioning" : "Updating";
14674
14756
  const fileNames = changedFiles.map((f) => f.relativePath).join(", ");
14675
14757
  log(`${verb} '${agent.code_name}': ${fileNames}`);
14676
14758
  for (const file of changedFiles) {
14677
- const filePath = join34(agentDir, file.relativePath);
14759
+ const filePath = join35(agentDir, file.relativePath);
14678
14760
  mkdirSync11(dirname9(filePath), { recursive: true });
14679
14761
  if (file.relativePath === ".mcp.json") {
14680
14762
  safeWriteJsonAtomic(filePath, file.content, { mode: 384 });
@@ -14683,12 +14765,12 @@ async function processAgent(agent, agentStates, managedToolkits) {
14683
14765
  }
14684
14766
  }
14685
14767
  try {
14686
- const provSkillsDir = join34(agentDir, ".claude", "skills");
14768
+ const provSkillsDir = join35(agentDir, ".claude", "skills");
14687
14769
  if (existsSync15(provSkillsDir)) {
14688
14770
  for (const folder of readdirSync9(provSkillsDir)) {
14689
14771
  if (folder.startsWith("knowledge-")) {
14690
14772
  try {
14691
- rmSync5(join34(provSkillsDir, folder), { recursive: true });
14773
+ rmSync5(join35(provSkillsDir, folder), { recursive: true });
14692
14774
  } catch {
14693
14775
  }
14694
14776
  }
@@ -14701,7 +14783,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
14701
14783
  const trackedFiles2 = frameworkAdapter.driftTrackedFiles();
14702
14784
  const hashes = /* @__PURE__ */ new Map();
14703
14785
  for (const file of trackedFiles2) {
14704
- const h = hashFile(join34(agentDir, file));
14786
+ const h = hashFile(join35(agentDir, file));
14705
14787
  if (h) hashes.set(file, h);
14706
14788
  }
14707
14789
  agentState.writtenHashes.set(agent.agent_id, hashes);
@@ -14719,14 +14801,14 @@ async function processAgent(agent, agentStates, managedToolkits) {
14719
14801
  }
14720
14802
  if (Array.isArray(refreshData.workflows)) {
14721
14803
  try {
14722
- const provWorkflowsDir = join34(agentDir, ".claude", "workflows");
14804
+ const provWorkflowsDir = join35(agentDir, ".claude", "workflows");
14723
14805
  if (existsSync15(provWorkflowsDir)) {
14724
14806
  const expected = new Set(refreshData.workflows.map((w) => `${w.name}.js`));
14725
14807
  for (const file of readdirSync9(provWorkflowsDir)) {
14726
14808
  if (!file.endsWith(".js")) continue;
14727
14809
  if (expected.has(file)) continue;
14728
14810
  try {
14729
- rmSync5(join34(provWorkflowsDir, file));
14811
+ rmSync5(join35(provWorkflowsDir, file));
14730
14812
  } catch {
14731
14813
  }
14732
14814
  }
@@ -14808,7 +14890,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
14808
14890
  if (written && existsSync15(agentDir)) {
14809
14891
  const driftedFiles = [];
14810
14892
  for (const [file, expectedHash] of written) {
14811
- const localHash = hashFile(join34(agentDir, file));
14893
+ const localHash = hashFile(join35(agentDir, file));
14812
14894
  if (localHash && localHash !== expectedHash) {
14813
14895
  driftedFiles.push(file);
14814
14896
  }
@@ -14819,7 +14901,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
14819
14901
  try {
14820
14902
  const localHashes = {};
14821
14903
  for (const file of driftedFiles) {
14822
- localHashes[file] = hashFile(join34(agentDir, file));
14904
+ localHashes[file] = hashFile(join35(agentDir, file));
14823
14905
  }
14824
14906
  await api.post("/host/drift", {
14825
14907
  agent_id: agent.agent_id,
@@ -15021,7 +15103,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
15021
15103
  const addedChannels = [...restartDecision.added];
15022
15104
  const writeDmNoticeMarkers = isChannelAddRestart ? () => {
15023
15105
  try {
15024
- const agentAugmentedDir = join34(homedir16(), ".augmented", agent.code_name);
15106
+ const agentAugmentedDir = join35(homedir17(), ".augmented", agent.code_name);
15025
15107
  mkdirSync11(agentAugmentedDir, { recursive: true });
15026
15108
  const markerJson = JSON.stringify({
15027
15109
  version: 1,
@@ -15029,7 +15111,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
15029
15111
  added: addedChannels
15030
15112
  });
15031
15113
  for (const file of ["slack-channel-add-restart.json", "telegram-channel-add-restart.json"]) {
15032
- atomicWriteFileSync(join34(agentAugmentedDir, file), markerJson);
15114
+ atomicWriteFileSync(join35(agentAugmentedDir, file), markerJson);
15033
15115
  }
15034
15116
  } catch (err) {
15035
15117
  log(`[hot-reload] channel-add DM-notice marker write failed for '${agent.code_name}' (non-fatal): ${err.message}`);
@@ -15218,18 +15300,18 @@ async function processAgent(agent, agentStates, managedToolkits) {
15218
15300
  if (agentSessionMode === "persistent" && (agentFrameworkCache.get(agent.code_name) ?? DEFAULT_FRAMEWORK) === "claude-code") {
15219
15301
  try {
15220
15302
  const agentProvisionDir = agentDir;
15221
- const projectDir = join34(homedir16(), ".augmented", agent.code_name, "project");
15303
+ const projectDir = join35(homedir17(), ".augmented", agent.code_name, "project");
15222
15304
  mkdirSync11(agentProvisionDir, { recursive: true });
15223
15305
  mkdirSync11(projectDir, { recursive: true });
15224
- const provisionMcpPath = join34(agentProvisionDir, ".mcp.json");
15225
- const projectMcpPath = join34(projectDir, ".mcp.json");
15306
+ const provisionMcpPath = join35(agentProvisionDir, ".mcp.json");
15307
+ const projectMcpPath = join35(projectDir, ".mcp.json");
15226
15308
  let mcpConfig = { mcpServers: {} };
15227
15309
  try {
15228
15310
  mcpConfig = JSON.parse(readFileSync28(provisionMcpPath, "utf-8"));
15229
15311
  if (!mcpConfig.mcpServers) mcpConfig.mcpServers = {};
15230
15312
  } catch {
15231
15313
  }
15232
- const localDirectChatChannel = join34(homedir16(), ".augmented", "_mcp", "direct-chat-channel.js");
15314
+ const localDirectChatChannel = join35(homedir17(), ".augmented", "_mcp", "direct-chat-channel.js");
15233
15315
  const directChatTeamSettings = refreshData.team?.settings;
15234
15316
  const directChatTz = (() => {
15235
15317
  const tz = directChatTeamSettings?.["timezone"];
@@ -15255,7 +15337,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
15255
15337
  // ~/.augmented/<codeName>/.current-turn-initiator.json. Note getAgentDir
15256
15338
  // returns the agent root (NOT the /provision subdir `agentDir` points at),
15257
15339
  // so it byte-matches the broker readers' path.
15258
- AGT_TURN_INITIATOR_FILE: join34(
15340
+ AGT_TURN_INITIATOR_FILE: join35(
15259
15341
  frameworkAdapter.getAgentDir(agent.code_name),
15260
15342
  ".current-turn-initiator.json"
15261
15343
  )
@@ -15275,7 +15357,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
15275
15357
  log(`Channel credentials written for '${agent.code_name}/direct-chat'`);
15276
15358
  }
15277
15359
  }
15278
- const staleChannelsPath = join34(projectDir, ".mcp-channels.json");
15360
+ const staleChannelsPath = join35(projectDir, ".mcp-channels.json");
15279
15361
  if (existsSync15(staleChannelsPath)) {
15280
15362
  try {
15281
15363
  rmSync5(staleChannelsPath, { force: true });
@@ -15365,7 +15447,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
15365
15447
  }
15366
15448
  if (hostFlagStore().getBoolean("connectivity-probe")) {
15367
15449
  try {
15368
- const probeProjectDir = join34(homedir16(), ".augmented", agent.code_name, "project");
15450
+ const probeProjectDir = join35(homedir17(), ".augmented", agent.code_name, "project");
15369
15451
  let probeSet = integrations;
15370
15452
  try {
15371
15453
  const quarantined = await api.post("/host/agent-integrations/quarantined", { agent_id: agent.agent_id });
@@ -15411,7 +15493,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
15411
15493
  const forceDue = attemptsLeft > 0;
15412
15494
  let probeRan = false;
15413
15495
  try {
15414
- const probeProjectDir = join34(homedir16(), ".augmented", agent.code_name, "project");
15496
+ const probeProjectDir = join35(homedir17(), ".augmented", agent.code_name, "project");
15415
15497
  probeRan = await runAgentSessionToolBindProbes(agent, integrations, probeProjectDir, { forceDue });
15416
15498
  } catch (err) {
15417
15499
  log(`Session-tool-bind probe failed for '${agent.code_name}': ${err.message}`);
@@ -15488,8 +15570,8 @@ async function processAgent(agent, agentStates, managedToolkits) {
15488
15570
  const intHash = computeIntegrationsHash(integrations);
15489
15571
  const prevIntHash = agentState.knownIntegrationHashes.get(agent.agent_id);
15490
15572
  if (intHash !== prevIntHash) {
15491
- const projectDir = join34(homedir16(), ".augmented", agent.code_name, "project");
15492
- const envIntPath = join34(projectDir, ".env.integrations");
15573
+ const projectDir = join35(homedir17(), ".augmented", agent.code_name, "project");
15574
+ const envIntPath = join35(projectDir, ".env.integrations");
15493
15575
  let preWriteEnv;
15494
15576
  try {
15495
15577
  preWriteEnv = readFileSync28(envIntPath, "utf-8");
@@ -15511,7 +15593,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
15511
15593
  }
15512
15594
  if (fw === "claude-code" && isSessionHealthy(agent.code_name)) {
15513
15595
  try {
15514
- const projectMcpPath = join34(projectDir, ".mcp.json");
15596
+ const projectMcpPath = join35(projectDir, ".mcp.json");
15515
15597
  const postWriteEnv = readFileSync28(envIntPath, "utf-8");
15516
15598
  const mcpContent = readFileSync28(projectMcpPath, "utf-8");
15517
15599
  const changedVars = diffEnvIntegrations(preWriteEnv, postWriteEnv);
@@ -15776,16 +15858,16 @@ async function processAgent(agent, agentStates, managedToolkits) {
15776
15858
  }
15777
15859
  try {
15778
15860
  const { readdirSync: readdirSync10, rmSync: rmSync6 } = await import("fs");
15779
- const { homedir: homedir17 } = await import("os");
15861
+ const { homedir: homedir18 } = await import("os");
15780
15862
  const frameworkId2 = frameworkAdapter.id;
15781
15863
  const candidateSkillDirs = [
15782
15864
  // Claude Code — framework runtime tree
15783
- join34(homedir17(), ".augmented", agent.code_name, "skills"),
15865
+ join35(homedir18(), ".augmented", agent.code_name, "skills"),
15784
15866
  // Claude Code — project tree
15785
- join34(homedir17(), ".augmented", agent.code_name, "project", ".claude", "skills"),
15867
+ join35(homedir18(), ".augmented", agent.code_name, "project", ".claude", "skills"),
15786
15868
  // Defensive: legacy provision-side path, not currently an
15787
15869
  // install target but cheap to sweep.
15788
- join34(agentDir, ".claude", "skills")
15870
+ join35(agentDir, ".claude", "skills")
15789
15871
  ];
15790
15872
  const existingDirs = candidateSkillDirs.filter((d) => existsSync15(d));
15791
15873
  const discoveredEntries = /* @__PURE__ */ new Set();
@@ -15826,7 +15908,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
15826
15908
  const sharedSkillsPayload = refreshAny.shared_skills;
15827
15909
  const desiredResolved = globalSkillsPayload !== void 0 || sharedSkillsPayload !== void 0;
15828
15910
  const manifestPath = managedSkillManifestPath(
15829
- join34(homedir16(), ".augmented", agent.code_name)
15911
+ join35(homedir17(), ".augmented", agent.code_name)
15830
15912
  );
15831
15913
  const prevIds = /* @__PURE__ */ new Set([
15832
15914
  ...agentState.knownGlobalSkillIds.get(agent.agent_id) ?? /* @__PURE__ */ new Set(),
@@ -15846,15 +15928,15 @@ async function processAgent(agent, agentStates, managedToolkits) {
15846
15928
  }
15847
15929
  if (plan.removes.length) {
15848
15930
  const globalSkillDirs = [
15849
- join34(homedir16(), ".augmented", agent.code_name, "skills"),
15850
- join34(homedir16(), ".augmented", agent.code_name, "project", ".claude", "skills"),
15851
- join34(agentDir, ".claude", "skills")
15931
+ join35(homedir17(), ".augmented", agent.code_name, "skills"),
15932
+ join35(homedir17(), ".augmented", agent.code_name, "project", ".claude", "skills"),
15933
+ join35(agentDir, ".claude", "skills")
15852
15934
  ];
15853
15935
  for (const id of plan.removes) {
15854
15936
  let prunedAny = false;
15855
15937
  for (const dir of globalSkillDirs) {
15856
- const p = join34(dir, id);
15857
- if (existsSync15(p) && existsSync15(join34(p, "SKILL.md"))) {
15938
+ const p = join35(dir, id);
15939
+ if (existsSync15(p) && existsSync15(join35(p, "SKILL.md"))) {
15858
15940
  rmSync5(p, { recursive: true, force: true });
15859
15941
  prunedAny = true;
15860
15942
  }
@@ -16086,7 +16168,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
16086
16168
  const sess = getSessionState(agent.code_name);
16087
16169
  let mcpJsonParsed = null;
16088
16170
  try {
16089
- const mcpPath = join34(getProjectDir(agent.code_name), ".mcp.json");
16171
+ const mcpPath = join35(getProjectDir(agent.code_name), ".mcp.json");
16090
16172
  mcpJsonParsed = JSON.parse(readFileSync28(mcpPath, "utf-8"));
16091
16173
  } catch {
16092
16174
  }
@@ -16521,7 +16603,7 @@ Retried to the limit after repeated stalls \u2014 needs a look.`).catch(() => {
16521
16603
  if (trackedFiles.length > 0 && existsSync15(agentDir)) {
16522
16604
  const hashes = /* @__PURE__ */ new Map();
16523
16605
  for (const file of trackedFiles) {
16524
- const h = hashFile(join34(agentDir, file));
16606
+ const h = hashFile(join35(agentDir, file));
16525
16607
  if (h) hashes.set(file, h);
16526
16608
  }
16527
16609
  agentState.writtenHashes.set(agent.agent_id, hashes);
@@ -16536,7 +16618,7 @@ Retried to the limit after repeated stalls \u2014 needs a look.`).catch(() => {
16536
16618
  refreshData.agent.onboarding_state
16537
16619
  );
16538
16620
  const obStep = obState.step;
16539
- const markerPath = join34(homedir16(), ".augmented", agent.code_name, "onboarding-drive.json");
16621
+ const markerPath = join35(homedir17(), ".augmented", agent.code_name, "onboarding-drive.json");
16540
16622
  const marker = readOnboardingDriveMarker(markerPath);
16541
16623
  const obContactRaw = refreshData.agent.manager_last_contacted_at;
16542
16624
  const obContact = typeof obContactRaw === "string" && obContactRaw ? obContactRaw : null;
@@ -16638,7 +16720,7 @@ async function ensureOpencodeRuntime(agent, refreshData, agentTimezone) {
16638
16720
  }
16639
16721
  stopOpencodeSlackIngest(codeName, log);
16640
16722
  stopOpencodeTelegramIngest(codeName, log);
16641
- const opencodeProjectDir = join34(getFramework("opencode").getAgentDir(codeName), "provision");
16723
+ const opencodeProjectDir = join35(getFramework("opencode").getAgentDir(codeName), "provision");
16642
16724
  const serveEnv = {
16643
16725
  AGT_HOST: requireHost(),
16644
16726
  AGT_API_KEY: getApiKey() ?? void 0,
@@ -16693,8 +16775,8 @@ async function ensurePersistentSession(agent, tasks, boardItems, refreshData) {
16693
16775
  });
16694
16776
  }
16695
16777
  const projectDir = getProjectDir(codeName);
16696
- const mcpConfigPath = join34(projectDir, ".mcp.json");
16697
- const claudeMdPath = join34(projectDir, "CLAUDE.md");
16778
+ const mcpConfigPath = join35(projectDir, ".mcp.json");
16779
+ const claudeMdPath = join35(projectDir, "CLAUDE.md");
16698
16780
  if (restartBreaker.isTripped(codeName)) {
16699
16781
  const trip = restartBreaker.getTrip(codeName);
16700
16782
  return {
@@ -16704,6 +16786,21 @@ async function ensurePersistentSession(agent, tasks, boardItems, refreshData) {
16704
16786
  detail: trip.statusMessage
16705
16787
  };
16706
16788
  }
16789
+ if ((agentFrameworkCache.get(codeName) ?? DEFAULT_FRAMEWORK) === "claude-code" && !isSessionHealthy(codeName)) {
16790
+ const missingMcpBundles = findMissingMcpBundles(mcpConfigPath);
16791
+ if (missingMcpBundles.length > 0) {
16792
+ const detail = formatMissingMcpBundles(missingMcpBundles);
16793
+ log(
16794
+ `[persistent-session] '${codeName}': deferring spawn \u2014 ${detail}. Not counted as a restart; will spawn once the host deploys them.`
16795
+ );
16796
+ return {
16797
+ decision: "skipped-mcp-assets-not-ready",
16798
+ spawnAttempted: false,
16799
+ sessionHealthyAfter: false,
16800
+ detail
16801
+ };
16802
+ }
16803
+ }
16707
16804
  const teamSettingsForTz = refreshData.team?.settings;
16708
16805
  const agentTimezone = (() => {
16709
16806
  const ownTzRaw = refreshData.agent?.timezone;
@@ -17796,7 +17893,7 @@ async function processDirectChatMessage(agent, msg) {
17796
17893
  const useDoorbell = hostFlagStore().getBoolean("direct-chat-doorbell") || isolationMode(agent.codeName) === "docker";
17797
17894
  if (useDoorbell) {
17798
17895
  try {
17799
- const doorbell = directChatDoorbellPath(agent.agentId, homedir16());
17896
+ const doorbell = directChatDoorbellPath(agent.agentId, homedir17());
17800
17897
  mkdirSync11(dirname9(doorbell), { recursive: true });
17801
17898
  writeFileSync14(doorbell, String(Date.now()));
17802
17899
  log(`[direct-chat] Doorbell rung for '${agent.codeName}' (msg=${msg.id}) \u2014 in-session MCP will pull via the cursor`);
@@ -17925,7 +18022,7 @@ ${formatRunMarker(run_id)}` : KANBAN_CHECK_COMMAND;
17925
18022
  }
17926
18023
  if (run_id) openInjectedRunByCode.set(codeName, run_id);
17927
18024
  try {
17928
- const doorbell = directChatDoorbellPath(agentId, homedir16());
18025
+ const doorbell = directChatDoorbellPath(agentId, homedir17());
17929
18026
  mkdirSync11(dirname9(doorbell), { recursive: true });
17930
18027
  writeFileSync14(doorbell, String(Date.now()));
17931
18028
  } catch (err) {
@@ -18285,8 +18382,8 @@ function parseMemoryFile(raw, fallbackName) {
18285
18382
  };
18286
18383
  }
18287
18384
  async function syncMemories(agent, configDir, log2) {
18288
- const projectDir = join34(configDir, agent.code_name, "project");
18289
- const memoryDir = join34(projectDir, "memory");
18385
+ const projectDir = join35(configDir, agent.code_name, "project");
18386
+ const memoryDir = join35(projectDir, "memory");
18290
18387
  const isFreshSync = pendingFreshMemorySync.has(agent.agent_id);
18291
18388
  if (isFreshSync) {
18292
18389
  log2(`[memory-sync] Fresh-sync requested for '${agent.code_name}' \u2014 pulling DB first`);
@@ -18304,7 +18401,7 @@ async function syncMemories(agent, configDir, log2) {
18304
18401
  for (const file of readdirSync9(memoryDir)) {
18305
18402
  if (!file.endsWith(".md")) continue;
18306
18403
  try {
18307
- const raw = readFileSync28(join34(memoryDir, file), "utf-8");
18404
+ const raw = readFileSync28(join35(memoryDir, file), "utf-8");
18308
18405
  const fileHash = createHash17("sha256").update(raw).digest("hex").slice(0, 16);
18309
18406
  currentHashes.set(file, fileHash);
18310
18407
  if (prevHashes.get(file) === fileHash) continue;
@@ -18329,7 +18426,7 @@ async function syncMemories(agent, configDir, log2) {
18329
18426
  } catch (err) {
18330
18427
  for (const mem of changedMemories) {
18331
18428
  for (const [file] of currentHashes) {
18332
- const parsed = parseMemoryFile(readFileSync28(join34(memoryDir, file), "utf-8"), file.replace(/\.md$/, ""));
18429
+ const parsed = parseMemoryFile(readFileSync28(join35(memoryDir, file), "utf-8"), file.replace(/\.md$/, ""));
18333
18430
  if (parsed?.name === mem.name) currentHashes.delete(file);
18334
18431
  }
18335
18432
  }
@@ -18364,7 +18461,7 @@ async function downloadMemories(agent, memoryDir, log2, { force }) {
18364
18461
  const mem = dbMemories.memories[i];
18365
18462
  const rawSlug = mem.name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)/g, "").slice(0, 60);
18366
18463
  const slug = rawSlug || `memory-${i}`;
18367
- const filePath = join34(memoryDir, `${slug}.md`);
18464
+ const filePath = join35(memoryDir, `${slug}.md`);
18368
18465
  const desired = `---
18369
18466
  name: ${JSON.stringify(mem.name)}
18370
18467
  type: ${mem.type}
@@ -18515,6 +18612,10 @@ function startPolling() {
18515
18612
  loadKanbanNudgeStateFromDisk();
18516
18613
  hostFlagStore().init();
18517
18614
  log(`Starting poll loop (interval=${config.intervalMs}ms, configDir=${config.configDir})`);
18615
+ {
18616
+ const startupOutcome = describeStartupCompletion(process.uptime() * 1e3);
18617
+ log(startupOutcome.message);
18618
+ }
18518
18619
  void killAllAgtTmuxSessions().catch(() => {
18519
18620
  }).then(() => {
18520
18621
  return pollCycle();
@@ -18538,7 +18639,7 @@ async function reportSelfUpdateRestarts() {
18538
18639
  });
18539
18640
  })
18540
18641
  ).then(() => void 0);
18541
- const deadline = new Promise((resolve) => setTimeout(resolve, 3e3));
18642
+ const deadline = new Promise((resolve2) => setTimeout(resolve2, 3e3));
18542
18643
  await Promise.race([posts, deadline]);
18543
18644
  }
18544
18645
  function scheduleNext() {
@@ -18641,6 +18742,7 @@ async function stopPolling(opts = {}) {
18641
18742
  clearTimeout(shutdownTimer);
18642
18743
  }
18643
18744
  function startManager(opts) {
18745
+ log(`[startup] begin (pid=${process.pid}, node=${process.version}, interval=${opts.intervalMs}ms)`);
18644
18746
  config = opts;
18645
18747
  try {
18646
18748
  const stateFile = getStateFile();
@@ -18672,7 +18774,7 @@ function startManager(opts) {
18672
18774
  log(`[startup] state rehydration failed (continuing with empty state): ${err.message}`);
18673
18775
  }
18674
18776
  log(
18675
- `[startup] worker pid=${process.pid} ppid=${process.ppid} node=${process.version} log=${join34(homedir16(), ".augmented", "manager.log")}`
18777
+ `[startup] worker pid=${process.pid} ppid=${process.ppid} node=${process.version} log=${join35(homedir17(), ".augmented", "manager.log")}`
18676
18778
  );
18677
18779
  deployMcpAssets();
18678
18780
  reapOrphanChannelMcps({ log });
@@ -18798,14 +18900,14 @@ function restartRunningChannelMcps(basenames) {
18798
18900
  }
18799
18901
  }
18800
18902
  function deployMcpAssets() {
18801
- const targetDir = join34(homedir16(), ".augmented", "_mcp");
18903
+ const targetDir = join35(homedir17(), ".augmented", "_mcp");
18802
18904
  mkdirSync11(targetDir, { recursive: true });
18803
18905
  const moduleDir = dirname9(fileURLToPath(import.meta.url));
18804
18906
  let mcpSourceDir = "";
18805
18907
  let dir = moduleDir;
18806
18908
  for (let i = 0; i < 6; i++) {
18807
- const candidate = join34(dir, "dist", "mcp");
18808
- if (existsSync15(join34(candidate, "index.js"))) {
18909
+ const candidate = join35(dir, "dist", "mcp");
18910
+ if (existsSync15(join35(candidate, "index.js"))) {
18809
18911
  mcpSourceDir = candidate;
18810
18912
  break;
18811
18913
  }
@@ -18818,6 +18920,8 @@ function deployMcpAssets() {
18818
18920
  return;
18819
18921
  }
18820
18922
  const changedBasenames = [];
18923
+ const attemptedFiles = [];
18924
+ const failedFiles = [];
18821
18925
  const fileHash = (p) => {
18822
18926
  try {
18823
18927
  if (!existsSync15(p)) return null;
@@ -18892,9 +18996,10 @@ function deployMcpAssets() {
18892
18996
  // needs restarting to pick up a token rotation.
18893
18997
  "xero.js"
18894
18998
  ]) {
18895
- const src = join34(mcpSourceDir, file);
18896
- const dst = join34(targetDir, file);
18999
+ const src = join35(mcpSourceDir, file);
19000
+ const dst = join35(targetDir, file);
18897
19001
  if (!existsSync15(src)) continue;
19002
+ attemptedFiles.push(file);
18898
19003
  const before = fileHash(dst);
18899
19004
  try {
18900
19005
  copyFileSync(src, dst);
@@ -18903,22 +19008,29 @@ function deployMcpAssets() {
18903
19008
  changedBasenames.push(file.replace(/\.js$/, ""));
18904
19009
  }
18905
19010
  } catch (err) {
19011
+ failedFiles.push(file);
18906
19012
  log(`[manager] Failed to deploy ${file}: ${err.message}`);
18907
19013
  }
18908
19014
  }
18909
- log(`[manager] MCP assets deployed to ${targetDir}`);
19015
+ if (failedFiles.length > 0) {
19016
+ log(
19017
+ `[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.`
19018
+ );
19019
+ } else {
19020
+ log(`[manager] MCP assets deployed to ${targetDir} (${attemptedFiles.length} bundle(s))`);
19021
+ }
18910
19022
  if (changedBasenames.length > 0) {
18911
19023
  log(`[manager] Bundle(s) updated: ${changedBasenames.join(", ")} \u2014 signalling running instances to restart`);
18912
19024
  restartRunningChannelMcps(changedBasenames);
18913
19025
  }
18914
- const localMcpPath = join34(targetDir, "index.js");
19026
+ const localMcpPath = join35(targetDir, "index.js");
18915
19027
  try {
18916
- const agentsDir = join34(homedir16(), ".augmented", "agents");
19028
+ const agentsDir = join35(homedir17(), ".augmented", "agents");
18917
19029
  if (existsSync15(agentsDir)) {
18918
19030
  for (const entry of readdirSync9(agentsDir, { withFileTypes: true })) {
18919
19031
  if (!entry.isDirectory()) continue;
18920
19032
  for (const subdir of ["provision", "project"]) {
18921
- const mcpJsonPath = join34(agentsDir, entry.name, subdir, ".mcp.json");
19033
+ const mcpJsonPath = join35(agentsDir, entry.name, subdir, ".mcp.json");
18922
19034
  try {
18923
19035
  const raw = readFileSync28(mcpJsonPath, "utf-8");
18924
19036
  if (!raw.includes("@integrity-labs/augmented-mcp")) continue;