@integrity-labs/agt-cli 0.28.492 → 0.28.493

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.
@@ -28,6 +28,7 @@ import {
28
28
  isTransientAuthFailure,
29
29
  liveProxyExtraHeaderVars,
30
30
  liveProxyTokenVars,
31
+ migrateAgentDirToIdKeyed,
31
32
  pinAllowsUrgent,
32
33
  provision,
33
34
  provisionAutoKanbanProgressHook,
@@ -44,7 +45,7 @@ import {
44
45
  resolveEffectivePinRaw,
45
46
  safeWriteJsonAtomic,
46
47
  setConfigHash
47
- } from "../chunk-KB5KVAWJ.js";
48
+ } from "../chunk-3XLUSG32.js";
48
49
  import {
49
50
  getProjectDir as getProjectDir2,
50
51
  getReadyTasks,
@@ -162,17 +163,17 @@ import {
162
163
  toOpencodeModel,
163
164
  transcriptActivityAgeSeconds,
164
165
  writeEgressAllowlist
165
- } from "../chunk-34E3FHOS.js";
166
+ } from "../chunk-SRO2IQ4R.js";
166
167
  import {
167
168
  reapOrphanChannelMcps
168
169
  } from "../chunk-XWVM4KPK.js";
169
170
 
170
171
  // src/lib/manager-worker.ts
171
172
  import { createHash as createHash16 } from "crypto";
172
- import { readFileSync as readFileSync21, writeFileSync as writeFileSync12, mkdirSync as mkdirSync10, existsSync as existsSync11, rmSync as rmSync5, readdirSync as readdirSync7, statSync as statSync6, copyFileSync } from "fs";
173
+ import { readFileSync as readFileSync21, writeFileSync as writeFileSync12, mkdirSync as mkdirSync10, existsSync as existsSync12, rmSync as rmSync5, readdirSync as readdirSync7, statSync as statSync6, copyFileSync } from "fs";
173
174
  import { execFileSync as syncExecFile } from "child_process";
174
- import { join as join25, dirname as dirname8, delimiter as pathDelimiter } from "path";
175
- import { homedir as homedir11 } from "os";
175
+ import { join as join26, dirname as dirname8, delimiter as pathDelimiter } from "path";
176
+ import { homedir as homedir12 } from "os";
176
177
  import { fileURLToPath } from "url";
177
178
 
178
179
  // src/lib/claude-code-upgrade-throttle.ts
@@ -2035,6 +2036,115 @@ function isDirectChatMessageExpired(createdAt, nowMs, maxAgeMs) {
2035
2036
  return nowMs - created > maxAgeMs;
2036
2037
  }
2037
2038
 
2039
+ // src/lib/id-keyed-migration.ts
2040
+ import { existsSync as existsSync2, lstatSync, readlinkSync, renameSync } from "fs";
2041
+ import { join as join5 } from "path";
2042
+ import { homedir as homedir2 } from "os";
2043
+ var ID_KEYED_MIGRATION_FLAG = "id-keyed-layout-migration";
2044
+ function agentHasActiveWhatsapp(channelConfigs, codeNameDir) {
2045
+ if (channelConfigs && Object.prototype.hasOwnProperty.call(channelConfigs, "whatsapp")) {
2046
+ return true;
2047
+ }
2048
+ try {
2049
+ if (existsSync2(join5(codeNameDir, "whatsapp-pending-inbound"))) return true;
2050
+ } catch {
2051
+ }
2052
+ return false;
2053
+ }
2054
+ function finishTranscriptMove(oldCwd, newCwd, codeName, log2) {
2055
+ const from = sessionTranscriptDir(oldCwd);
2056
+ const to = sessionTranscriptDir(newCwd);
2057
+ if (from === to) return;
2058
+ let fromExists = false;
2059
+ let toExists = false;
2060
+ try {
2061
+ fromExists = existsSync2(from);
2062
+ } catch {
2063
+ }
2064
+ if (!fromExists) return;
2065
+ try {
2066
+ toExists = existsSync2(to);
2067
+ } catch {
2068
+ }
2069
+ if (toExists) {
2070
+ log2(
2071
+ `[id-keyed-migration] transcript store for '${codeName}' already present at the id-keyed key; leaving the legacy dir in place for an operator to reconcile`
2072
+ );
2073
+ return;
2074
+ }
2075
+ renameSync(from, to);
2076
+ log2(`[id-keyed-migration] moved transcript store for '${codeName}' to the id-keyed key`);
2077
+ }
2078
+ function maybeMigrateAgentToIdKeyedLayout(agent, deps) {
2079
+ const home = deps.home ?? homedir2();
2080
+ const { code_name: codeName, agent_id: agentId } = agent;
2081
+ const codeNamePath = join5(home, ".augmented", codeName);
2082
+ const idPath = join5(home, ".augmented", agentId);
2083
+ const oldCwd = join5(home, ".augmented", codeName, "project");
2084
+ const newCwd = join5(idPath, "project");
2085
+ let codeNameKind;
2086
+ try {
2087
+ codeNameKind = lstatSync(codeNamePath).isSymbolicLink() ? "symlink" : "realdir";
2088
+ } catch {
2089
+ codeNameKind = "absent";
2090
+ }
2091
+ const idExists = existsSync2(idPath);
2092
+ try {
2093
+ if (codeNameKind === "symlink") {
2094
+ const target = readlinkSync(codeNamePath);
2095
+ if (target !== agentId) {
2096
+ deps.log(
2097
+ `[id-keyed-migration] CONFLICT for '${codeName}': codename symlink points at "${target}", expected "${agentId}"; refusing to touch the transcript store (operator reconciliation required)`
2098
+ );
2099
+ return "conflict";
2100
+ }
2101
+ finishTranscriptMove(oldCwd, newCwd, codeName, deps.log);
2102
+ return "already-id-keyed";
2103
+ }
2104
+ if (codeNameKind === "absent" && idExists) {
2105
+ migrateAgentDirToIdKeyed(codeName, agentId, { home });
2106
+ finishTranscriptMove(oldCwd, newCwd, codeName, deps.log);
2107
+ deps.log(
2108
+ `[id-keyed-migration] recovered an interrupted migration for '${codeName}' -> ${agentId}`
2109
+ );
2110
+ return "recovered";
2111
+ }
2112
+ if (codeNameKind === "absent") return "no-agent";
2113
+ if (!deps.flagStore.getBooleanForAgent(ID_KEYED_MIGRATION_FLAG, agentId)) {
2114
+ return "skipped-flag-off";
2115
+ }
2116
+ if (idExists) {
2117
+ deps.log(
2118
+ `[id-keyed-migration] CONFLICT for '${codeName}': a real codename dir AND a real ${agentId} dir both exist; refusing to migrate (operator reconciliation required)`
2119
+ );
2120
+ return "conflict";
2121
+ }
2122
+ if (agentHasActiveWhatsapp(deps.channelConfigs, codeNamePath)) {
2123
+ deps.log(
2124
+ `[id-keyed-migration] deferred '${codeName}': active WhatsApp channel \u2014 the host-resident inbound writer cannot be quiesced from the manager; use the manual rename runbook`
2125
+ );
2126
+ return "skipped-external-writer";
2127
+ }
2128
+ const status = migrateAgentDirToIdKeyed(codeName, agentId, { home });
2129
+ if (status === "conflict") {
2130
+ deps.log(
2131
+ `[id-keyed-migration] CONFLICT for '${codeName}': ${agentId} dir appeared mid-migration; refusing to migrate (operator reconciliation required)`
2132
+ );
2133
+ return "conflict";
2134
+ }
2135
+ finishTranscriptMove(oldCwd, newCwd, codeName, deps.log);
2136
+ deps.log(
2137
+ `[id-keyed-migration] migrated '${codeName}' to the id-keyed layout (~/.augmented/${agentId}); codename is now a compatibility symlink`
2138
+ );
2139
+ return "migrated";
2140
+ } catch (err) {
2141
+ deps.log(
2142
+ `[id-keyed-migration] FAILED for '${codeName}': ${err.message}; leaving the current layout in place, will retry next tick`
2143
+ );
2144
+ return "failed";
2145
+ }
2146
+ }
2147
+
2038
2148
  // src/lib/manager/auth-resolve-decision.ts
2039
2149
  function decideAuthResolveFailureAction(args) {
2040
2150
  const transient = isTransientAuthFailure(args.error);
@@ -2086,8 +2196,8 @@ function collectEnvGates(env) {
2086
2196
  }
2087
2197
 
2088
2198
  // src/lib/artifact-stream.ts
2089
- import { join as join5 } from "path";
2090
- import { homedir as homedir2 } from "os";
2199
+ import { join as join6 } from "path";
2200
+ import { homedir as homedir3 } from "os";
2091
2201
  import { readdir, stat, readFile } from "fs/promises";
2092
2202
  var ARTEFACT_ENTRY_FILE = "index.html";
2093
2203
  function errMessage(err) {
@@ -2172,7 +2282,7 @@ var ArtifactStreamScanner = class {
2172
2282
  return;
2173
2283
  }
2174
2284
  for (const name of names) {
2175
- const file = join5(this.artifactsDir, name, ARTEFACT_ENTRY_FILE);
2285
+ const file = join6(this.artifactsDir, name, ARTEFACT_ENTRY_FILE);
2176
2286
  const mtime = await this.fsDeps.mtimeMs(file).catch(() => null);
2177
2287
  if (mtime === null) continue;
2178
2288
  if (this.seenMtime.get(name) === mtime) continue;
@@ -2203,7 +2313,7 @@ var ArtifactStreamScanner = class {
2203
2313
  }
2204
2314
  };
2205
2315
  function artifactsDirFor(codeName) {
2206
- return join5(homedir2(), ".augmented", codeName, "artifacts");
2316
+ return join6(homedir3(), ".augmented", codeName, "artifacts");
2207
2317
  }
2208
2318
  var nodeArtifactFs = {
2209
2319
  async listArtefactNames(artifactsDir) {
@@ -2292,13 +2402,13 @@ async function maybeReportUsageBanner(args) {
2292
2402
  // src/lib/claude-account-fingerprint.ts
2293
2403
  import { createHash as createHash6 } from "crypto";
2294
2404
  import { readFile as readFile3, readdir as readdir3 } from "fs/promises";
2295
- import { homedir as homedir4, platform as platform2 } from "os";
2296
- import { dirname as dirname4, join as join7 } from "path";
2405
+ import { homedir as homedir5, platform as platform2 } from "os";
2406
+ import { dirname as dirname4, join as join8 } from "path";
2297
2407
 
2298
2408
  // src/lib/claude-auth-detect.ts
2299
2409
  import { readFile as readFile2, readdir as readdir2 } from "fs/promises";
2300
- import { homedir as homedir3, platform } from "os";
2301
- import { join as join6 } from "path";
2410
+ import { homedir as homedir4, platform } from "os";
2411
+ import { join as join7 } from "path";
2302
2412
  import { execFile } from "child_process";
2303
2413
  import { promisify } from "util";
2304
2414
  var execFileAsync = promisify(execFile);
@@ -2313,16 +2423,16 @@ async function detectClaudeAuth() {
2313
2423
  }
2314
2424
  async function findClaudeCredentialsPaths() {
2315
2425
  const candidates = [
2316
- join6(homedir3(), ".claude", ".credentials.json"),
2317
- join6(homedir3(), ".claude", "credentials.json")
2426
+ join7(homedir4(), ".claude", ".credentials.json"),
2427
+ join7(homedir4(), ".claude", "credentials.json")
2318
2428
  ];
2319
2429
  const isLinuxRoot = platform() === "linux" && typeof process.getuid === "function" && process.getuid() === 0;
2320
2430
  if (isLinuxRoot) {
2321
2431
  try {
2322
2432
  const entries = await readdir2("/home", { withFileTypes: true });
2323
2433
  for (const entry of entries.filter((entry2) => entry2.isDirectory()).sort((a, b) => a.name.localeCompare(b.name))) {
2324
- candidates.push(join6("/home", entry.name, ".claude", ".credentials.json"));
2325
- candidates.push(join6("/home", entry.name, ".claude", "credentials.json"));
2434
+ candidates.push(join7("/home", entry.name, ".claude", ".credentials.json"));
2435
+ candidates.push(join7("/home", entry.name, ".claude", "credentials.json"));
2326
2436
  }
2327
2437
  } catch {
2328
2438
  }
@@ -2400,13 +2510,13 @@ function parseExpiresAt(raw) {
2400
2510
 
2401
2511
  // src/lib/claude-account-fingerprint.ts
2402
2512
  async function candidateHomes() {
2403
- const homes = [homedir4()];
2513
+ const homes = [homedir5()];
2404
2514
  const isLinuxRoot = platform2() === "linux" && typeof process.getuid === "function" && process.getuid() === 0;
2405
2515
  if (isLinuxRoot) {
2406
2516
  try {
2407
2517
  const entries = await readdir3("/home", { withFileTypes: true });
2408
2518
  for (const entry of entries.filter((e) => e.isDirectory()).sort((a, b) => a.name.localeCompare(b.name))) {
2409
- homes.push(join7("/home", entry.name));
2519
+ homes.push(join8("/home", entry.name));
2410
2520
  }
2411
2521
  } catch {
2412
2522
  }
@@ -2426,11 +2536,11 @@ async function homeOfActiveCredentials() {
2426
2536
  async function claudeConfigCandidatePaths() {
2427
2537
  const paths = [];
2428
2538
  const configDir = process.env["CLAUDE_CONFIG_DIR"]?.trim();
2429
- if (configDir) paths.push(join7(configDir, ".claude.json"));
2539
+ if (configDir) paths.push(join8(configDir, ".claude.json"));
2430
2540
  const activeHome = await homeOfActiveCredentials();
2431
- if (activeHome) paths.push(join7(activeHome, ".claude.json"));
2541
+ if (activeHome) paths.push(join8(activeHome, ".claude.json"));
2432
2542
  for (const home of await candidateHomes()) {
2433
- const path = join7(home, ".claude.json");
2543
+ const path = join8(home, ".claude.json");
2434
2544
  if (!paths.includes(path)) paths.push(path);
2435
2545
  }
2436
2546
  return paths;
@@ -2527,11 +2637,11 @@ function diffAuthTuples(recorded, current) {
2527
2637
  }
2528
2638
 
2529
2639
  // src/lib/account-enforcement-marker.ts
2530
- import { mkdirSync as mkdirSync4, renameSync, rmSync as rmSync2, writeFileSync as writeFileSync4 } from "fs";
2531
- import { homedir as homedir5 } from "os";
2532
- import { join as join8 } from "path";
2640
+ import { mkdirSync as mkdirSync4, renameSync as renameSync2, rmSync as rmSync2, writeFileSync as writeFileSync4 } from "fs";
2641
+ import { homedir as homedir6 } from "os";
2642
+ import { join as join9 } from "path";
2533
2643
  function accountEnforcementMarkerPath(codeName) {
2534
- return join8(homedir5(), ".augmented", codeName, ACCOUNT_ENFORCEMENT_MARKER_FILENAME);
2644
+ return join9(homedir6(), ".augmented", codeName, ACCOUNT_ENFORCEMENT_MARKER_FILENAME);
2535
2645
  }
2536
2646
  function syncAccountEnforcementMarker(codeName, level, log2 = (m) => process.stderr.write(`${m}
2537
2647
  `)) {
@@ -2539,13 +2649,13 @@ function syncAccountEnforcementMarker(codeName, level, log2 = (m) => process.std
2539
2649
  clearAccountEnforcementMarker(codeName, log2);
2540
2650
  return;
2541
2651
  }
2542
- const dir = join8(homedir5(), ".augmented", codeName);
2543
- const path = join8(dir, ACCOUNT_ENFORCEMENT_MARKER_FILENAME);
2652
+ const dir = join9(homedir6(), ".augmented", codeName);
2653
+ const path = join9(dir, ACCOUNT_ENFORCEMENT_MARKER_FILENAME);
2544
2654
  const tempPath = `${path}.${process.pid}.tmp`;
2545
2655
  try {
2546
2656
  mkdirSync4(dir, { recursive: true });
2547
2657
  writeFileSync4(tempPath, serializeAccountEnforcementMarker(level), "utf-8");
2548
- renameSync(tempPath, path);
2658
+ renameSync2(tempPath, path);
2549
2659
  } catch (err) {
2550
2660
  try {
2551
2661
  rmSync2(tempPath, { force: true });
@@ -2566,7 +2676,7 @@ function clearAccountEnforcementMarker(codeName, log2 = (m) => process.stderr.wr
2566
2676
 
2567
2677
  // src/lib/token-usage-monitor.ts
2568
2678
  import { readdirSync, readFileSync as readFileSync7, statSync } from "fs";
2569
- import { join as join9 } from "path";
2679
+ import { join as join10 } from "path";
2570
2680
  var MIN_CHECK_INTERVAL_MS2 = 6e4;
2571
2681
  var TRANSCRIPT_MTIME_WINDOW_MS = 2 * 24 * 60 * 60 * 1e3;
2572
2682
  var MAX_ENTRIES_PER_POST = 200;
@@ -2595,7 +2705,7 @@ async function maybeReportTokenUsage(args) {
2595
2705
  if (!name.endsWith(".jsonl")) continue;
2596
2706
  const sessionId = name.slice(0, -".jsonl".length);
2597
2707
  if (!sessionId) continue;
2598
- const path = join9(dir, name);
2708
+ const path = join10(dir, name);
2599
2709
  let st;
2600
2710
  try {
2601
2711
  st = statSync(path);
@@ -2693,7 +2803,7 @@ async function maybeReportTokenUsage(args) {
2693
2803
 
2694
2804
  // src/lib/workflow-run-reconciler.ts
2695
2805
  import { readdirSync as readdirSync2, readFileSync as readFileSync8, statSync as statSync2 } from "fs";
2696
- import { join as join10 } from "path";
2806
+ import { join as join11 } from "path";
2697
2807
  var MIN_CHECK_INTERVAL_MS3 = 5 * 6e4;
2698
2808
  var SETTLE_MS = 3e4;
2699
2809
  var TRANSCRIPT_MTIME_WINDOW_MS2 = 2 * 24 * 60 * 60 * 1e3;
@@ -2712,7 +2822,7 @@ function collectJsonlRecursive(dir, minMtimeMs, out, depth) {
2712
2822
  return;
2713
2823
  }
2714
2824
  for (const name of entries) {
2715
- const p = join10(dir, name);
2825
+ const p = join11(dir, name);
2716
2826
  let st;
2717
2827
  try {
2718
2828
  st = statSync2(p);
@@ -2735,7 +2845,7 @@ function enumerateTranscriptFiles(transcriptDir, nowMs, minMtimeMs = nowMs - TRA
2735
2845
  return out;
2736
2846
  }
2737
2847
  for (const name of entries) {
2738
- const path = join10(transcriptDir, name);
2848
+ const path = join11(transcriptDir, name);
2739
2849
  let st;
2740
2850
  try {
2741
2851
  st = statSync2(path);
@@ -2747,7 +2857,7 @@ function enumerateTranscriptFiles(transcriptDir, nowMs, minMtimeMs = nowMs - TRA
2747
2857
  continue;
2748
2858
  }
2749
2859
  if (st.isDirectory()) {
2750
- collectJsonlRecursive(join10(path, "subagents"), minMtimeMs, out, 0);
2860
+ collectJsonlRecursive(join11(path, "subagents"), minMtimeMs, out, 0);
2751
2861
  }
2752
2862
  }
2753
2863
  return out;
@@ -2838,7 +2948,7 @@ async function maybeReconcileWorkflowRunTokens(args) {
2838
2948
 
2839
2949
  // src/lib/conversation-evaluator.ts
2840
2950
  import { readdirSync as readdirSync3, readFileSync as readFileSync9, statSync as statSync3 } from "fs";
2841
- import { join as join11 } from "path";
2951
+ import { join as join12 } from "path";
2842
2952
  var MIN_CHECK_INTERVAL_MS4 = 5 * 6e4;
2843
2953
  var TRANSCRIPT_MTIME_WINDOW_MS3 = 7 * 24 * 60 * 60 * 1e3;
2844
2954
  var WINDOW_PAD_MS = 5 * 6e4;
@@ -3274,7 +3384,7 @@ function readRecentTurns(dir, nowMs) {
3274
3384
  return;
3275
3385
  }
3276
3386
  for (const ent of entries) {
3277
- const full = join11(d, ent.name);
3387
+ const full = join12(d, ent.name);
3278
3388
  if (ent.isDirectory()) {
3279
3389
  visit(full);
3280
3390
  continue;
@@ -3579,11 +3689,11 @@ async function reportSkip2(api2, agentId, conversationId, log2, codeName) {
3579
3689
  }
3580
3690
 
3581
3691
  // src/lib/activity-cache-monitor.ts
3582
- import { existsSync as existsSync2, readFileSync as readFileSync10 } from "fs";
3583
- import { homedir as homedir6 } from "os";
3584
- import { join as join12 } from "path";
3692
+ import { existsSync as existsSync3, readFileSync as readFileSync10 } from "fs";
3693
+ import { homedir as homedir7 } from "os";
3694
+ import { join as join13 } from "path";
3585
3695
  var MIN_CHECK_INTERVAL_MS6 = 6e4;
3586
- var STATS_CACHE_PATH = join12(homedir6(), ".claude", "stats-cache.json");
3696
+ var STATS_CACHE_PATH = join13(homedir7(), ".claude", "stats-cache.json");
3587
3697
  var ISO_DATE_RE = /^\d{4}-\d{2}-\d{2}$/;
3588
3698
  var state5 = { lastObservedDate: null, lastCheckedAt: 0 };
3589
3699
  function selectNewDailyRows(raw, lastObservedDate) {
@@ -3626,7 +3736,7 @@ async function maybeReportActivityCache(args) {
3626
3736
  const nowMs = now.getTime();
3627
3737
  if (nowMs - state5.lastCheckedAt < MIN_CHECK_INTERVAL_MS6) return;
3628
3738
  state5.lastCheckedAt = nowMs;
3629
- if (!existsSync2(STATS_CACHE_PATH)) {
3739
+ if (!existsSync3(STATS_CACHE_PATH)) {
3630
3740
  return;
3631
3741
  }
3632
3742
  let raw;
@@ -3835,15 +3945,15 @@ function computeChannelConfigHash(input) {
3835
3945
  }
3836
3946
 
3837
3947
  // src/lib/channel-hash-cache.ts
3838
- import { existsSync as existsSync3, readFileSync as readFileSync11, writeFileSync as writeFileSync5 } from "fs";
3839
- import { join as join13 } from "path";
3948
+ import { existsSync as existsSync4, readFileSync as readFileSync11, writeFileSync as writeFileSync5 } from "fs";
3949
+ import { join as join14 } from "path";
3840
3950
  var CACHE_FILENAME = "channel-hash-cache.json";
3841
3951
  function getChannelHashCacheFile(configDir) {
3842
- return join13(configDir, CACHE_FILENAME);
3952
+ return join14(configDir, CACHE_FILENAME);
3843
3953
  }
3844
3954
  function loadChannelHashCache(target, configDir) {
3845
3955
  const path = getChannelHashCacheFile(configDir);
3846
- if (!existsSync3(path)) return;
3956
+ if (!existsSync4(path)) return;
3847
3957
  let parsed;
3848
3958
  try {
3849
3959
  parsed = JSON.parse(readFileSync11(path, "utf-8"));
@@ -3866,8 +3976,8 @@ function saveChannelHashCache(source, configDir) {
3866
3976
  }
3867
3977
 
3868
3978
  // src/lib/sender-policy-baseline.ts
3869
- import { existsSync as existsSync4, readFileSync as readFileSync12 } from "fs";
3870
- import { join as join14 } from "path";
3979
+ import { existsSync as existsSync5, readFileSync as readFileSync12 } from "fs";
3980
+ import { join as join15 } from "path";
3871
3981
  var BASELINE_FILENAME = "sender-policy-baseline.json";
3872
3982
  var SENDER_POLICY_BASELINE_VERSION = 1;
3873
3983
  var BASELINE_CONCERNS = ["senderPolicy", "slackBehaviour", "msteamsBehaviour"];
@@ -3879,11 +3989,11 @@ function createDeliveryBaselineMaps() {
3879
3989
  };
3880
3990
  }
3881
3991
  function getSenderPolicyBaselineFile(configDir) {
3882
- return join14(configDir, BASELINE_FILENAME);
3992
+ return join15(configDir, BASELINE_FILENAME);
3883
3993
  }
3884
3994
  function loadSenderPolicyBaseline(target, configDir, log2) {
3885
3995
  const path = getSenderPolicyBaselineFile(configDir);
3886
- if (!existsSync4(path)) return;
3996
+ if (!existsSync5(path)) return;
3887
3997
  let parsed;
3888
3998
  try {
3889
3999
  parsed = JSON.parse(readFileSync12(path, "utf-8"));
@@ -4409,15 +4519,15 @@ function planGlobalSkillSync(globalSkills, prevIds, hashOf, knownHash, options)
4409
4519
  }
4410
4520
 
4411
4521
  // src/lib/manager/managed-skill-manifest.ts
4412
- import { existsSync as existsSync5, mkdirSync as mkdirSync5, readFileSync as readFileSync13, writeFileSync as writeFileSync6 } from "fs";
4413
- import { dirname as dirname5, join as join15 } from "path";
4522
+ import { existsSync as existsSync6, mkdirSync as mkdirSync5, readFileSync as readFileSync13, writeFileSync as writeFileSync6 } from "fs";
4523
+ import { dirname as dirname5, join as join16 } from "path";
4414
4524
  var MANIFEST_VERSION = 1;
4415
4525
  function managedSkillManifestPath(agentRootDir) {
4416
- return join15(agentRootDir, "managed-skills.json");
4526
+ return join16(agentRootDir, "managed-skills.json");
4417
4527
  }
4418
4528
  function readManagedSkillManifest(path) {
4419
4529
  try {
4420
- if (!existsSync5(path)) return /* @__PURE__ */ new Set();
4530
+ if (!existsSync6(path)) return /* @__PURE__ */ new Set();
4421
4531
  const parsed = JSON.parse(readFileSync13(path, "utf-8"));
4422
4532
  const ids = Array.isArray(parsed?.globalSkillIds) ? parsed.globalSkillIds : [];
4423
4533
  return new Set(ids.filter((id) => typeof id === "string" && id.length > 0));
@@ -4530,9 +4640,9 @@ function resolveModelChain(refreshData) {
4530
4640
  }
4531
4641
 
4532
4642
  // src/lib/manager/claude-auth.ts
4533
- import { existsSync as existsSync6, rmSync as rmSync3 } from "fs";
4534
- import { join as join16 } from "path";
4535
- import { homedir as homedir7 } from "os";
4643
+ import { existsSync as existsSync7, rmSync as rmSync3 } from "fs";
4644
+ import { join as join17 } from "path";
4645
+ import { homedir as homedir8 } from "os";
4536
4646
  async function applyClaudeAuthToEnv(childEnv, label) {
4537
4647
  const apiKey = getApiKey();
4538
4648
  if (!apiKey) {
@@ -4544,10 +4654,10 @@ async function applyClaudeAuthToEnv(childEnv, label) {
4544
4654
  throw new Error("claude_auth_mode=api_key but /host/exchange returned no decrypted key");
4545
4655
  }
4546
4656
  childEnv.ANTHROPIC_API_KEY = exchange.anthropicApiKey;
4547
- const claudeDir = join16(homedir7(), ".claude");
4657
+ const claudeDir = join17(homedir8(), ".claude");
4548
4658
  for (const filename of [".credentials.json", "credentials.json"]) {
4549
- const p = join16(claudeDir, filename);
4550
- if (existsSync6(p)) {
4659
+ const p = join17(claudeDir, filename);
4660
+ if (existsSync7(p)) {
4551
4661
  try {
4552
4662
  rmSync3(p, { force: true });
4553
4663
  log(`[${label}] Removed ${p} (api_key mode \u2014 preventing OAuth fallback)`);
@@ -4561,8 +4671,8 @@ async function applyClaudeAuthToEnv(childEnv, label) {
4561
4671
  }
4562
4672
 
4563
4673
  // src/lib/manager/kanban/parsers.ts
4564
- import { existsSync as existsSync7, readFileSync as readFileSync14 } from "fs";
4565
- import { join as join17 } from "path";
4674
+ import { existsSync as existsSync8, readFileSync as readFileSync14 } from "fs";
4675
+ import { join as join18 } from "path";
4566
4676
  var STANDUP_TEMPLATES = /* @__PURE__ */ new Set(["daily-standup", "end-of-day-summary"]);
4567
4677
  var TASK_UPDATE_TEMPLATES = /* @__PURE__ */ new Set(["hourly-status", "task-update"]);
4568
4678
  var PLAN_TEMPLATES = /* @__PURE__ */ new Set(["morning-plan"]);
@@ -4701,11 +4811,11 @@ function getBuiltInSkillContent(skillId) {
4701
4811
  if (builtInSkillCache.has(skillId)) return builtInSkillCache.get(skillId);
4702
4812
  try {
4703
4813
  const candidates = [
4704
- join17(process.cwd(), "skills", skillId, "SKILL.md"),
4705
- join17(new URL(".", import.meta.url).pathname, "..", "..", "..", "..", "..", "..", "skills", skillId, "SKILL.md")
4814
+ join18(process.cwd(), "skills", skillId, "SKILL.md"),
4815
+ join18(new URL(".", import.meta.url).pathname, "..", "..", "..", "..", "..", "..", "skills", skillId, "SKILL.md")
4706
4816
  ];
4707
4817
  for (const candidate of candidates) {
4708
- if (existsSync7(candidate)) {
4818
+ if (existsSync8(candidate)) {
4709
4819
  const content = readFileSync14(candidate, "utf-8");
4710
4820
  const files = [{ relativePath: "SKILL.md", content }];
4711
4821
  builtInSkillCache.set(skillId, files);
@@ -4847,16 +4957,16 @@ function formatBoardForPrompt(items, template) {
4847
4957
  }
4848
4958
 
4849
4959
  // src/lib/manager/kanban/nudge-state-cache.ts
4850
- import { existsSync as existsSync8, readFileSync as readFileSync15, writeFileSync as writeFileSync7 } from "fs";
4851
- import { join as join18 } from "path";
4960
+ import { existsSync as existsSync9, readFileSync as readFileSync15, writeFileSync as writeFileSync7 } from "fs";
4961
+ import { join as join19 } from "path";
4852
4962
  var CACHE_FILENAME2 = "kanban-nudge-state.json";
4853
4963
  var KANBAN_NUDGE_STATE_VERSION = 1;
4854
4964
  function getKanbanNudgeStateFile(configDir) {
4855
- return join18(configDir, CACHE_FILENAME2);
4965
+ return join19(configDir, CACHE_FILENAME2);
4856
4966
  }
4857
4967
  function loadKanbanNudgeState(target, configDir) {
4858
4968
  const path = getKanbanNudgeStateFile(configDir);
4859
- if (!existsSync8(path)) return;
4969
+ if (!existsSync9(path)) return;
4860
4970
  let parsed;
4861
4971
  try {
4862
4972
  parsed = JSON.parse(readFileSync15(path, "utf-8"));
@@ -5459,9 +5569,9 @@ function closeScheduledRunsForCode(codeName, outcome, reason) {
5459
5569
 
5460
5570
  // src/lib/manager/scheduler/kanban-route.ts
5461
5571
  import { createHash as createHash11 } from "crypto";
5462
- import { writeFileSync as writeFileSync8, renameSync as renameSync2, mkdirSync as mkdirSync6, readFileSync as readFileSync16, unlinkSync } from "fs";
5463
- import { homedir as homedir8 } from "os";
5464
- import { join as join19, dirname as dirname6 } from "path";
5572
+ import { writeFileSync as writeFileSync8, renameSync as renameSync3, mkdirSync as mkdirSync6, readFileSync as readFileSync16, unlinkSync } from "fs";
5573
+ import { homedir as homedir9 } from "os";
5574
+ import { join as join20, dirname as dirname6 } from "path";
5465
5575
 
5466
5576
  // src/lib/manager/scheduler/notify.ts
5467
5577
  import { createHash as createHash10 } from "crypto";
@@ -5802,17 +5912,17 @@ function resolveScheduledSlackTarget(task) {
5802
5912
  }
5803
5913
  function stampScheduledTurnMarker(codeName, taskId, target) {
5804
5914
  try {
5805
- const file = join19(homedir8(), ".augmented", codeName, SCHEDULED_TURN_MARKER_FILENAME);
5915
+ const file = join20(homedir9(), ".augmented", codeName, SCHEDULED_TURN_MARKER_FILENAME);
5806
5916
  const marker = { ts: Date.now(), task_id: taskId, ...target ? { target } : {} };
5807
5917
  const tmp = `${file}.tmp`;
5808
5918
  writeFileSync8(tmp, JSON.stringify(marker), "utf8");
5809
- renameSync2(tmp, file);
5919
+ renameSync3(tmp, file);
5810
5920
  } catch (err) {
5811
5921
  log(`[scheduled-kanban] scheduled-turn marker write failed for '${codeName}': ${err.message}`);
5812
5922
  }
5813
5923
  }
5814
5924
  function clearScheduledTurnMarkerForTask(codeName, taskId) {
5815
- const file = join19(homedir8(), ".augmented", codeName, SCHEDULED_TURN_MARKER_FILENAME);
5925
+ const file = join20(homedir9(), ".augmented", codeName, SCHEDULED_TURN_MARKER_FILENAME);
5816
5926
  try {
5817
5927
  const raw = JSON.parse(readFileSync16(file, "utf8"));
5818
5928
  if (typeof raw?.task_id !== "string" || raw.task_id !== taskId) return;
@@ -5874,7 +5984,7 @@ async function routeScheduledTaskViaKanban(codeName, agentId, task, prompt, dura
5874
5984
  return false;
5875
5985
  }
5876
5986
  try {
5877
- const doorbell = directChatDoorbellPath(agentId, homedir8());
5987
+ const doorbell = directChatDoorbellPath(agentId, homedir9());
5878
5988
  mkdirSync6(dirname6(doorbell), { recursive: true });
5879
5989
  writeFileSync8(doorbell, String(Date.now()));
5880
5990
  } catch (err) {
@@ -6026,12 +6136,12 @@ async function processClaudeTaskResult(codeName, agentId, templateId, rawOutput,
6026
6136
 
6027
6137
  // src/lib/manager/scheduler/execution.ts
6028
6138
  import { createHash as createHash12 } from "crypto";
6029
- import { homedir as homedir9 } from "os";
6030
- import { join as join21 } from "path";
6139
+ import { homedir as homedir10 } from "os";
6140
+ import { join as join22 } from "path";
6031
6141
 
6032
6142
  // src/lib/agent-serving-probe.ts
6033
6143
  import { readFileSync as readFileSync17, readdirSync as readdirSync4, statSync as statSync4 } from "fs";
6034
- import { join as join20 } from "path";
6144
+ import { join as join21 } from "path";
6035
6145
  var RATE_LIMIT_WINDOW_MS = 6 * 60 * 60 * 1e3;
6036
6146
  function probeRateLimit(args) {
6037
6147
  const now = args.now ?? /* @__PURE__ */ new Date();
@@ -6047,7 +6157,7 @@ function probeRateLimit(args) {
6047
6157
  let newest = UNKNOWN_RATE_LIMIT;
6048
6158
  for (const name of entries) {
6049
6159
  if (!name.endsWith(".jsonl")) continue;
6050
- const path = join20(dir, name);
6160
+ const path = join21(dir, name);
6051
6161
  try {
6052
6162
  const st = statSync4(path);
6053
6163
  if (!st.isFile() || st.mtimeMs < startMs) continue;
@@ -6118,7 +6228,7 @@ function shouldLogUsageCapDeferral(site, codeName, limitedUntil) {
6118
6228
 
6119
6229
  // src/lib/manager/scheduler/execution.ts
6120
6230
  function claudePidFilePath() {
6121
- return join21(homedir9(), ".augmented", "manager-claude-pids.json");
6231
+ return join22(homedir10(), ".augmented", "manager-claude-pids.json");
6122
6232
  }
6123
6233
  var inFlightClaudePids = /* @__PURE__ */ new Map();
6124
6234
  function registerClaudeSpawn(record) {
@@ -7351,9 +7461,9 @@ async function fireOpencodeScheduledTask(agent, task) {
7351
7461
 
7352
7462
  // src/lib/opencode-telegram-ingest.ts
7353
7463
  import { createHash as createHash15 } from "crypto";
7354
- import { existsSync as existsSync9, mkdirSync as mkdirSync7, readFileSync as readFileSync18, renameSync as renameSync3, unlinkSync as unlinkSync2, writeFileSync as writeFileSync9 } from "fs";
7464
+ import { existsSync as existsSync10, mkdirSync as mkdirSync7, readFileSync as readFileSync18, renameSync as renameSync4, unlinkSync as unlinkSync2, writeFileSync as writeFileSync9 } from "fs";
7355
7465
  import { randomUUID } from "crypto";
7356
- import { join as join22 } from "path";
7466
+ import { join as join23 } from "path";
7357
7467
 
7358
7468
  // src/lib/telegram-ingest.ts
7359
7469
  import https2 from "https";
@@ -7901,7 +8011,7 @@ function createFileOffsetStore(codeName, log2, currentBotId) {
7901
8011
  let filePath;
7902
8012
  try {
7903
8013
  dir = getFramework("opencode").getAgentDir(codeName);
7904
- filePath = join22(dir, "telegram-getupdates-offset-opencode.json");
8014
+ filePath = join23(dir, "telegram-getupdates-offset-opencode.json");
7905
8015
  } catch {
7906
8016
  dir = null;
7907
8017
  filePath = null;
@@ -7939,11 +8049,11 @@ function createFileOffsetStore(codeName, log2, currentBotId) {
7939
8049
  }),
7940
8050
  { mode: 384 }
7941
8051
  );
7942
- renameSync3(tmpPath, filePath);
8052
+ renameSync4(tmpPath, filePath);
7943
8053
  } catch (err) {
7944
8054
  log2(`[telegram-ingest:${codeName}] offset persist failed: ${err instanceof Error ? err.message : String(err)}`);
7945
8055
  try {
7946
- if (existsSync9(tmpPath)) unlinkSync2(tmpPath);
8056
+ if (existsSync10(tmpPath)) unlinkSync2(tmpPath);
7947
8057
  } catch {
7948
8058
  }
7949
8059
  }
@@ -8180,24 +8290,24 @@ function partitionActionableByPoison(actionable, states, config2) {
8180
8290
  }
8181
8291
 
8182
8292
  // src/lib/restart-flags.ts
8183
- import { existsSync as existsSync10, mkdirSync as mkdirSync8, readdirSync as readdirSync5, readFileSync as readFileSync19, renameSync as renameSync4, rmSync as rmSync4, writeFileSync as writeFileSync10 } from "fs";
8184
- import { homedir as homedir10 } from "os";
8185
- import { join as join23 } from "path";
8293
+ import { existsSync as existsSync11, mkdirSync as mkdirSync8, readdirSync as readdirSync5, readFileSync as readFileSync19, renameSync as renameSync5, rmSync as rmSync4, writeFileSync as writeFileSync10 } from "fs";
8294
+ import { homedir as homedir11 } from "os";
8295
+ import { join as join24 } from "path";
8186
8296
  import { randomUUID as randomUUID2 } from "crypto";
8187
8297
  function restartFlagsDir() {
8188
- return join23(homedir10(), ".augmented", "restart-flags");
8298
+ return join24(homedir11(), ".augmented", "restart-flags");
8189
8299
  }
8190
8300
  function flagPath(codeName) {
8191
- return join23(restartFlagsDir(), `${codeName}.flag`);
8301
+ return join24(restartFlagsDir(), `${codeName}.flag`);
8192
8302
  }
8193
8303
  function readRestartFlags() {
8194
8304
  const dir = restartFlagsDir();
8195
- if (!existsSync10(dir)) return [];
8305
+ if (!existsSync11(dir)) return [];
8196
8306
  const out = [];
8197
8307
  for (const entry of readdirSync5(dir)) {
8198
8308
  if (!entry.endsWith(".flag")) continue;
8199
8309
  try {
8200
- const raw = readFileSync19(join23(dir, entry), "utf8");
8310
+ const raw = readFileSync19(join24(dir, entry), "utf8");
8201
8311
  const parsed = JSON.parse(raw);
8202
8312
  if (typeof parsed.codeName !== "string" || parsed.codeName.length === 0) {
8203
8313
  parsed.codeName = entry.replace(/\.flag$/, "");
@@ -8215,7 +8325,7 @@ function readRestartFlags() {
8215
8325
  }
8216
8326
  function deleteRestartFlag(codeName) {
8217
8327
  const path = flagPath(codeName);
8218
- if (existsSync10(path)) {
8328
+ if (existsSync11(path)) {
8219
8329
  rmSync4(path, { force: true });
8220
8330
  }
8221
8331
  }
@@ -8316,7 +8426,7 @@ async function sendError(flag, opts, text) {
8316
8426
 
8317
8427
  // src/lib/restart-context.ts
8318
8428
  import { readdirSync as readdirSync6, readFileSync as readFileSync20, writeFileSync as writeFileSync11, mkdirSync as mkdirSync9, unlinkSync as unlinkSync3 } from "fs";
8319
- import { dirname as dirname7, join as join24 } from "path";
8429
+ import { dirname as dirname7, join as join25 } from "path";
8320
8430
  var SLACK_PENDING_INBOUND_DIRNAME = "slack-pending-inbound";
8321
8431
  var SLACK_RESTART_CONTEXT_DIRNAME = "slack-restart-context";
8322
8432
  var MAX_TOPIC_CHARS = 140;
@@ -8328,10 +8438,10 @@ function augmentedAgentDir(codeName) {
8328
8438
  return dirname7(getProjectDir(codeName));
8329
8439
  }
8330
8440
  function slackPendingInboundDir(codeName) {
8331
- return join24(augmentedAgentDir(codeName), SLACK_PENDING_INBOUND_DIRNAME);
8441
+ return join25(augmentedAgentDir(codeName), SLACK_PENDING_INBOUND_DIRNAME);
8332
8442
  }
8333
8443
  function slackRestartContextDir(codeName) {
8334
- return join24(augmentedAgentDir(codeName), SLACK_RESTART_CONTEXT_DIRNAME);
8444
+ return join25(augmentedAgentDir(codeName), SLACK_RESTART_CONTEXT_DIRNAME);
8335
8445
  }
8336
8446
  function sanitizeTopic(raw) {
8337
8447
  const cleaned = raw.replace(/\s+/g, " ").trim().replace(/[<>]/g, " ").replace(/\s+/g, " ").trim();
@@ -8391,7 +8501,7 @@ function pruneHintsExcept(codeName, freshFilenames) {
8391
8501
  if (!filename.endsWith(".json")) continue;
8392
8502
  if (freshFilenames.has(filename)) continue;
8393
8503
  try {
8394
- unlinkSync3(join24(ctxDir, filename));
8504
+ unlinkSync3(join25(ctxDir, filename));
8395
8505
  } catch {
8396
8506
  }
8397
8507
  }
@@ -8412,7 +8522,7 @@ function refreshSlackRestartContextHints(codeNames, opts = {}) {
8412
8522
  }
8413
8523
  const markers = [];
8414
8524
  for (const filename of markerFilenames.slice(0, cap)) {
8415
- const parsed = readStrandedMarker(join24(markerDir, filename));
8525
+ const parsed = readStrandedMarker(join25(markerDir, filename));
8416
8526
  if (parsed) markers.push({ filename, channel: parsed.channel, thread_ts: parsed.thread_ts });
8417
8527
  }
8418
8528
  if (markers.length === 0) {
@@ -8426,7 +8536,7 @@ function refreshSlackRestartContextHints(codeNames, opts = {}) {
8426
8536
  const freshFilenames = /* @__PURE__ */ new Set();
8427
8537
  for (const { filename, hint } of hints) {
8428
8538
  try {
8429
- writeHintFile(join24(ctxDir, filename), ctxDir, hint);
8539
+ writeHintFile(join25(ctxDir, filename), ctxDir, hint);
8430
8540
  freshFilenames.add(filename);
8431
8541
  } catch (err) {
8432
8542
  log2(`[restart-context] ${codeName}: hint write failed for ${filename}: ${err.message}`);
@@ -9736,7 +9846,7 @@ var runningChannelSecretHashes = /* @__PURE__ */ new Map();
9736
9846
  var sessionLaunchManagedStructure = /* @__PURE__ */ new Map();
9737
9847
  function projectMcpHash(_codeName, projectDir) {
9738
9848
  try {
9739
- const raw = readFileSync21(join25(projectDir, ".mcp.json"), "utf-8");
9849
+ const raw = readFileSync21(join26(projectDir, ".mcp.json"), "utf-8");
9740
9850
  return createHash16("sha256").update(canonicalJson(JSON.parse(raw))).digest("hex");
9741
9851
  } catch {
9742
9852
  return null;
@@ -9744,7 +9854,7 @@ function projectMcpHash(_codeName, projectDir) {
9744
9854
  }
9745
9855
  function projectMcpKeys(_codeName, projectDir) {
9746
9856
  try {
9747
- const raw = readFileSync21(join25(projectDir, ".mcp.json"), "utf-8");
9857
+ const raw = readFileSync21(join26(projectDir, ".mcp.json"), "utf-8");
9748
9858
  const parsed = JSON.parse(raw);
9749
9859
  const servers = parsed.mcpServers;
9750
9860
  if (!servers || typeof servers !== "object") return /* @__PURE__ */ new Set();
@@ -9762,7 +9872,7 @@ function seedSessionLaunchBaselines(codeName, projectDir) {
9762
9872
  else runningMcpServerKeys.delete(codeName);
9763
9873
  let launchStructure = null;
9764
9874
  try {
9765
- const raw = readFileSync21(join25(projectDir, ".mcp.json"), "utf-8");
9875
+ const raw = readFileSync21(join26(projectDir, ".mcp.json"), "utf-8");
9766
9876
  launchStructure = managedMcpStructureHashFromFile(
9767
9877
  JSON.parse(raw),
9768
9878
  isManagedMcpServerKey
@@ -9866,7 +9976,7 @@ async function runAgentSessionToolBindProbes(agent, integrations, projectDir, op
9866
9976
  if (result && result.rebindCandidates.length > 0 && hostFlagStore().getBoolean("session-tool-rebind")) {
9867
9977
  let mcpJsonForRebind = null;
9868
9978
  try {
9869
- mcpJsonForRebind = JSON.parse(readFileSync21(join25(projectDir, ".mcp.json"), "utf-8"));
9979
+ mcpJsonForRebind = JSON.parse(readFileSync21(join26(projectDir, ".mcp.json"), "utf-8"));
9870
9980
  } catch {
9871
9981
  mcpJsonForRebind = null;
9872
9982
  }
@@ -10010,7 +10120,7 @@ function checkMcpConfigDriftAndScheduleRestart(codeName, projectDir) {
10010
10120
  function projectChannelSecretHash(projectDir) {
10011
10121
  try {
10012
10122
  const entries = parseEnvIntegrations(
10013
- readFileSync21(join25(projectDir, ".env.integrations"), "utf-8")
10123
+ readFileSync21(join26(projectDir, ".env.integrations"), "utf-8")
10014
10124
  );
10015
10125
  return channelSecretValueHash(entries, CHANNEL_SECRET_ENV_KEYS);
10016
10126
  } catch {
@@ -10106,7 +10216,7 @@ var agentRestartTimezoneInputs = /* @__PURE__ */ new Map();
10106
10216
  var lastVersionCheckAt = 0;
10107
10217
  var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
10108
10218
  var lastResponsivenessProbeAt = 0;
10109
- var agtCliVersion = true ? "0.28.492" : "dev";
10219
+ var agtCliVersion = true ? "0.28.493" : "dev";
10110
10220
  function resolveBrewPath(execFileSync2) {
10111
10221
  try {
10112
10222
  const out = execFileSync2("which", ["brew"], { timeout: 5e3 }).toString().trim();
@@ -10119,7 +10229,7 @@ function resolveBrewPath(execFileSync2) {
10119
10229
  "/usr/local/bin/brew"
10120
10230
  ];
10121
10231
  for (const path of fallbacks) {
10122
- if (existsSync11(path)) return path;
10232
+ if (existsSync12(path)) return path;
10123
10233
  }
10124
10234
  return null;
10125
10235
  }
@@ -10129,7 +10239,7 @@ function claudeBinaryInstalled(execFileSync2) {
10129
10239
  "/opt/homebrew/bin/claude",
10130
10240
  "/usr/local/bin/claude"
10131
10241
  ];
10132
- if (canonical.some((path) => existsSync11(path))) return true;
10242
+ if (canonical.some((path) => existsSync12(path))) return true;
10133
10243
  try {
10134
10244
  execFileSync2("which", ["claude"], { timeout: 5e3 });
10135
10245
  return true;
@@ -10394,7 +10504,7 @@ function claudeManagedSettingsPath() {
10394
10504
  function ensureClaudeManagedSettings(path = claudeManagedSettingsPath()) {
10395
10505
  try {
10396
10506
  let settings = {};
10397
- if (existsSync11(path)) {
10507
+ if (existsSync12(path)) {
10398
10508
  const raw = readFileSync21(path, "utf-8").trim();
10399
10509
  if (raw) {
10400
10510
  let parsed;
@@ -10450,7 +10560,7 @@ async function ensureOpencodeBinary() {
10450
10560
  try {
10451
10561
  const prefix = execFileSync2("npm", ["prefix", "-g"], { encoding: "utf-8", timeout: 1e4 }).trim();
10452
10562
  if (prefix) {
10453
- const npmBin = join25(prefix, "bin");
10563
+ const npmBin = join26(prefix, "bin");
10454
10564
  const current = (process.env.PATH ?? "").split(pathDelimiter);
10455
10565
  if (!current.includes(npmBin)) {
10456
10566
  process.env.PATH = [npmBin, ...current.filter(Boolean)].join(pathDelimiter);
@@ -10511,7 +10621,7 @@ async function ensureFrameworkBinary(frameworkId) {
10511
10621
  if (!process.env.PATH?.split(":").includes(brewBinDir)) {
10512
10622
  process.env.PATH = `${brewBinDir}:${process.env.PATH ?? ""}`;
10513
10623
  }
10514
- if (existsSync11("/home/linuxbrew/.linuxbrew/bin/claude")) {
10624
+ if (existsSync12("/home/linuxbrew/.linuxbrew/bin/claude")) {
10515
10625
  log("Claude Code installed successfully");
10516
10626
  } else {
10517
10627
  log("Claude Code install completed but binary not found at expected path \u2014 check brew logs");
@@ -10567,7 +10677,7 @@ ${r.stderr}`;
10567
10677
  }
10568
10678
  var UPDATE_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
10569
10679
  function selfUpdateAppliedMarkerPath() {
10570
- return join25(homedir11(), ".augmented", ".last-self-update-applied");
10680
+ return join26(homedir12(), ".augmented", ".last-self-update-applied");
10571
10681
  }
10572
10682
  var selfUpdateUpToDateLogged = false;
10573
10683
  var selfUpdatePinnedLogged = false;
@@ -10595,7 +10705,7 @@ async function checkAndUpdateCli(opts) {
10595
10705
  const isNpmGlobal = !isBrewFormula && resolvedPath.includes("node_modules");
10596
10706
  if (!isBrewFormula && !isNpmGlobal) return "noop";
10597
10707
  const { readFileSync: readF, writeFileSync: writeF } = await import("fs");
10598
- const markerPath = join25(homedir11(), ".augmented", ".last-update-check");
10708
+ const markerPath = join26(homedir12(), ".augmented", ".last-update-check");
10599
10709
  if (!force) {
10600
10710
  try {
10601
10711
  const lastCheck = parseInt(readF(markerPath, "utf-8").trim(), 10);
@@ -10954,13 +11064,13 @@ async function checkClaudeAuth() {
10954
11064
  }
10955
11065
  var evalEmptyMcpConfigPath = null;
10956
11066
  function ensureEvalEmptyMcpConfig() {
10957
- if (evalEmptyMcpConfigPath && existsSync11(evalEmptyMcpConfigPath)) return evalEmptyMcpConfigPath;
10958
- const dir = join25(homedir11(), ".augmented");
11067
+ if (evalEmptyMcpConfigPath && existsSync12(evalEmptyMcpConfigPath)) return evalEmptyMcpConfigPath;
11068
+ const dir = join26(homedir12(), ".augmented");
10959
11069
  try {
10960
11070
  mkdirSync10(dir, { recursive: true });
10961
11071
  } catch {
10962
11072
  }
10963
- const p = join25(dir, ".eval-empty-mcp.json");
11073
+ const p = join26(dir, ".eval-empty-mcp.json");
10964
11074
  writeFileSync12(p, JSON.stringify({ mcpServers: {} }));
10965
11075
  evalEmptyMcpConfigPath = p;
10966
11076
  return p;
@@ -10986,7 +11096,7 @@ async function runEvalClaude(prompt, model) {
10986
11096
  ""
10987
11097
  ];
10988
11098
  const { stdout } = await execFilePromiseLong(resolveClaudeBinary(), args, {
10989
- cwd: homedir11(),
11099
+ cwd: homedir12(),
10990
11100
  timeout: 12e4,
10991
11101
  stdin: "ignore",
10992
11102
  env: childEnv,
@@ -11052,10 +11162,10 @@ function resolveConversationEvalBackend() {
11052
11162
  return conversationEvalBackend;
11053
11163
  }
11054
11164
  function getStateFile() {
11055
- return join25(config?.configDir ?? join25(process.env["HOME"] ?? "/tmp", ".augmented"), "manager-state.json");
11165
+ return join26(config?.configDir ?? join26(process.env["HOME"] ?? "/tmp", ".augmented"), "manager-state.json");
11056
11166
  }
11057
11167
  function channelHashCacheDir() {
11058
- return config?.configDir ?? join25(process.env["HOME"] ?? "/tmp", ".augmented");
11168
+ return config?.configDir ?? join26(process.env["HOME"] ?? "/tmp", ".augmented");
11059
11169
  }
11060
11170
  function loadChannelHashCache2() {
11061
11171
  loadChannelHashCache(agentState.knownChannelConfigHashes, channelHashCacheDir());
@@ -11109,7 +11219,7 @@ function removeDeliveryBaselineEntries(agentId) {
11109
11219
  var _channelQuarantineStore = null;
11110
11220
  function channelQuarantineStore() {
11111
11221
  if (!_channelQuarantineStore) {
11112
- const dir = config?.configDir ?? join25(process.env["HOME"] ?? "/tmp", ".augmented");
11222
+ const dir = config?.configDir ?? join26(process.env["HOME"] ?? "/tmp", ".augmented");
11113
11223
  _channelQuarantineStore = new ChannelQuarantineStore(defaultQuarantinePath(dir));
11114
11224
  }
11115
11225
  return _channelQuarantineStore;
@@ -11126,7 +11236,7 @@ function claudeMdSizeFor(codeName) {
11126
11236
  var _hostFlagStore = null;
11127
11237
  function hostFlagStore() {
11128
11238
  if (!_hostFlagStore) {
11129
- const dir = config?.configDir ?? join25(process.env["HOME"] ?? "/tmp", ".augmented");
11239
+ const dir = config?.configDir ?? join26(process.env["HOME"] ?? "/tmp", ".augmented");
11130
11240
  _hostFlagStore = new HostFlagStore({ cachePath: defaultFlagsCachePath(dir), log });
11131
11241
  }
11132
11242
  return _hostFlagStore;
@@ -11197,12 +11307,12 @@ function parseSkillFrontmatter(content) {
11197
11307
  }
11198
11308
  async function refreshSkillsIndexInClaudeMd(configDir, codeName, log2) {
11199
11309
  const { readdirSync: readdirSync8, readFileSync: rfs, existsSync: ex, writeFileSync: writeFileSync13 } = await import("fs");
11200
- const skillsDir = join25(configDir, codeName, "project", ".claude", "skills");
11201
- const claudeMdPath = join25(configDir, codeName, "project", "CLAUDE.md");
11310
+ const skillsDir = join26(configDir, codeName, "project", ".claude", "skills");
11311
+ const claudeMdPath = join26(configDir, codeName, "project", "CLAUDE.md");
11202
11312
  if (!ex(skillsDir) || !ex(claudeMdPath)) return;
11203
11313
  const entries = [];
11204
11314
  for (const dir of readdirSync8(skillsDir).sort()) {
11205
- const skillFile = join25(skillsDir, dir, "SKILL.md");
11315
+ const skillFile = join26(skillsDir, dir, "SKILL.md");
11206
11316
  if (!ex(skillFile)) continue;
11207
11317
  try {
11208
11318
  const { name, description } = parseSkillFrontmatter(rfs(skillFile, "utf-8"));
@@ -11269,7 +11379,7 @@ function flushRestartedAgentDiagnostics(hostId, codeNames) {
11269
11379
  if (codeNames.length === 0) return;
11270
11380
  void (async () => {
11271
11381
  try {
11272
- const { collectDiagnostics } = await import("../persistent-session-Y3WIXJPW.js");
11382
+ const { collectDiagnostics } = await import("../persistent-session-MVAEGE6J.js");
11273
11383
  await api.post("/host/heartbeat", {
11274
11384
  host_id: hostId,
11275
11385
  agent_diagnostics: collectDiagnostics(codeNames, quarantineEntriesFor, claudeMdSizeFor)
@@ -11376,7 +11486,7 @@ async function pollCycle() {
11376
11486
  }
11377
11487
  try {
11378
11488
  const { detectHostSecurity } = await import("../host-security-6PDFG7F5.js");
11379
- const { collectDiagnostics } = await import("../persistent-session-Y3WIXJPW.js");
11489
+ const { collectDiagnostics } = await import("../persistent-session-MVAEGE6J.js");
11380
11490
  const diagCodeNames = [...agentState.persistentSessionAgents];
11381
11491
  const agentDiagnostics = diagCodeNames.length > 0 ? collectDiagnostics(diagCodeNames, quarantineEntriesFor, claudeMdSizeFor) : void 0;
11382
11492
  let tailscaleHostname;
@@ -11468,6 +11578,7 @@ async function pollCycle() {
11468
11578
  hostFlagStore().applyHeartbeat(hbResp.feature_flags, hbResp.flags_schema_version);
11469
11579
  }
11470
11580
  hostFlagStore().applyNotifyDispatchByAgent(hbResp?.notify_dispatch_by_agent);
11581
+ hostFlagStore().applyBooleanFlagsByAgent(hbResp?.feature_flags_by_agent);
11471
11582
  setConfigHash(hbResp?.config_hash ?? null);
11472
11583
  try {
11473
11584
  if (decideMaintenanceWindowGate({ window: cachedMaintenanceWindow, now: /* @__PURE__ */ new Date() }) === "proceed") {
@@ -11490,7 +11601,7 @@ async function pollCycle() {
11490
11601
  collectResponsivenessProbes,
11491
11602
  collectPanelessActivityProbes,
11492
11603
  getResponsivenessIntervalMs
11493
- } = await import("../responsiveness-probe-AEFEFKOQ.js");
11604
+ } = await import("../responsiveness-probe-6YXN4G6V.js");
11494
11605
  const probeIntervalMs = getResponsivenessIntervalMs();
11495
11606
  if (now - lastResponsivenessProbeAt > probeIntervalMs) {
11496
11607
  const probeCodeNames = [...agentState.persistentSessionAgents];
@@ -11554,7 +11665,7 @@ async function pollCycle() {
11554
11665
  collectResponsivenessProbes,
11555
11666
  livePendingInboundOldestAgeSeconds,
11556
11667
  parkPendingInbound
11557
- } = await import("../responsiveness-probe-AEFEFKOQ.js");
11668
+ } = await import("../responsiveness-probe-6YXN4G6V.js");
11558
11669
  const { getProjectDir: wedgeProjectDir } = await import("../scheduler-engine-NDP36U7O.js");
11559
11670
  const wedgeNow = /* @__PURE__ */ new Date();
11560
11671
  const liveAgents = agentState.persistentSessionAgents;
@@ -11646,10 +11757,10 @@ async function pollCycle() {
11646
11757
  const paneTail = readFileSync21(paneLogPath(codeName), "utf8").slice(-65536);
11647
11758
  const transient = detectTransientApiErrorInLog(paneTail);
11648
11759
  if (transient) {
11649
- const wedgeHome = join25(homedir11(), ".augmented", codeName);
11650
- if (existsSync11(wedgeHome)) {
11760
+ const wedgeHome = join26(homedir12(), ".augmented", codeName);
11761
+ if (existsSync12(wedgeHome)) {
11651
11762
  atomicWriteFileSync(
11652
- join25(wedgeHome, "watchdog-give-up.json"),
11763
+ join26(wedgeHome, "watchdog-give-up.json"),
11653
11764
  JSON.stringify({
11654
11765
  gave_up_at: wedgeNow.toISOString(),
11655
11766
  reason: "transient_overload"
@@ -11920,7 +12031,7 @@ async function pollCycle() {
11920
12031
  const adapter = resolveAgentFramework(prev.codeName);
11921
12032
  stopAgentRuntime2(prev.codeName, "removed-from-host");
11922
12033
  killAgentChannelProcesses(prev.codeName, { log });
11923
- const agentDir = join25(adapter.getAgentDir(prev.codeName), "provision");
12034
+ const agentDir = join26(adapter.getAgentDir(prev.codeName), "provision");
11924
12035
  await cleanupAgentFiles(prev.codeName, agentDir);
11925
12036
  clearAgentCaches(prev.agentId, prev.codeName);
11926
12037
  }
@@ -12007,10 +12118,10 @@ async function pollCycle() {
12007
12118
  // pending-inbound marker. Best-effort: a write failure is logged by
12008
12119
  // the watchdog, never fails the poll cycle.
12009
12120
  signalGiveUp: (codeName) => {
12010
- const dir = join25(homedir11(), ".augmented", codeName);
12011
- if (!existsSync11(dir)) return;
12121
+ const dir = join26(homedir12(), ".augmented", codeName);
12122
+ if (!existsSync12(dir)) return;
12012
12123
  atomicWriteFileSync(
12013
- join25(dir, "watchdog-give-up.json"),
12124
+ join26(dir, "watchdog-give-up.json"),
12014
12125
  JSON.stringify({ gave_up_at: (/* @__PURE__ */ new Date()).toISOString() })
12015
12126
  );
12016
12127
  }
@@ -12152,7 +12263,7 @@ async function processAgent(agent, agentStates) {
12152
12263
  }
12153
12264
  const now = (/* @__PURE__ */ new Date()).toISOString();
12154
12265
  const adapter = resolveAgentFramework(agent.code_name);
12155
- let agentDir = join25(adapter.getAgentDir(agent.code_name), "provision");
12266
+ let agentDir = join26(adapter.getAgentDir(agent.code_name), "provision");
12156
12267
  if (agent.status === "draft" || agent.status === "paused") {
12157
12268
  if (previousKnownStatus !== agent.status) {
12158
12269
  log(`Agent '${agent.code_name}' is ${agent.status}, skipping provisioning`);
@@ -12192,7 +12303,7 @@ async function processAgent(agent, agentStates) {
12192
12303
  const residuals = {
12193
12304
  gatewayRunning: false,
12194
12305
  portAllocated: false,
12195
- provisionDirExists: existsSync11(agentDir)
12306
+ provisionDirExists: existsSync12(agentDir)
12196
12307
  };
12197
12308
  if (!hasRevokedResiduals(residuals)) {
12198
12309
  agentStates.push({
@@ -12326,7 +12437,7 @@ async function processAgent(agent, agentStates) {
12326
12437
  const frameworkId = refreshData.agent.framework ?? DEFAULT_FRAMEWORK;
12327
12438
  agentFrameworkCache.set(agent.code_name, frameworkId);
12328
12439
  const frameworkAdapter = getFramework(frameworkId);
12329
- agentDir = join25(frameworkAdapter.getAgentDir(agent.code_name), "provision");
12440
+ agentDir = join26(frameworkAdapter.getAgentDir(agent.code_name), "provision");
12330
12441
  cacheAgentDeliveryMetadata(agent.code_name, refreshData);
12331
12442
  agentRestartTimezoneInputs.set(agent.code_name, {
12332
12443
  agentTimezone: typeof refreshData.agent.timezone === "string" ? refreshData.agent.timezone : null,
@@ -12375,7 +12486,7 @@ async function processAgent(agent, agentStates) {
12375
12486
  const changedFiles = [];
12376
12487
  mkdirSync10(agentDir, { recursive: true });
12377
12488
  for (const artifact of artifacts) {
12378
- const filePath = join25(agentDir, artifact.relativePath);
12489
+ const filePath = join26(agentDir, artifact.relativePath);
12379
12490
  let existingHash;
12380
12491
  let newHash;
12381
12492
  let writeContent = artifact.content;
@@ -12394,7 +12505,7 @@ async function processAgent(agent, agentStates) {
12394
12505
  };
12395
12506
  newHash = sha256(stripDynamicSections(artifact.content));
12396
12507
  try {
12397
- const projectClaudeMd = join25(config.configDir, agent.code_name, "project", "CLAUDE.md");
12508
+ const projectClaudeMd = join26(config.configDir, agent.code_name, "project", "CLAUDE.md");
12398
12509
  const existing = readFileSync21(projectClaudeMd, "utf-8");
12399
12510
  existingHash = sha256(stripDynamicSections(existing));
12400
12511
  } catch {
@@ -12445,12 +12556,12 @@ async function processAgent(agent, agentStates) {
12445
12556
  }
12446
12557
  }
12447
12558
  if (changedFiles.length > 0) {
12448
- const isFirst = !existsSync11(join25(agentDir, "CHARTER.md"));
12559
+ const isFirst = !existsSync12(join26(agentDir, "CHARTER.md"));
12449
12560
  const verb = isFirst ? "Provisioning" : "Updating";
12450
12561
  const fileNames = changedFiles.map((f) => f.relativePath).join(", ");
12451
12562
  log(`${verb} '${agent.code_name}': ${fileNames}`);
12452
12563
  for (const file of changedFiles) {
12453
- const filePath = join25(agentDir, file.relativePath);
12564
+ const filePath = join26(agentDir, file.relativePath);
12454
12565
  mkdirSync10(dirname8(filePath), { recursive: true });
12455
12566
  if (file.relativePath === ".mcp.json") {
12456
12567
  safeWriteJsonAtomic(filePath, file.content, { mode: 384 });
@@ -12459,12 +12570,12 @@ async function processAgent(agent, agentStates) {
12459
12570
  }
12460
12571
  }
12461
12572
  try {
12462
- const provSkillsDir = join25(agentDir, ".claude", "skills");
12463
- if (existsSync11(provSkillsDir)) {
12573
+ const provSkillsDir = join26(agentDir, ".claude", "skills");
12574
+ if (existsSync12(provSkillsDir)) {
12464
12575
  for (const folder of readdirSync7(provSkillsDir)) {
12465
12576
  if (folder.startsWith("knowledge-")) {
12466
12577
  try {
12467
- rmSync5(join25(provSkillsDir, folder), { recursive: true });
12578
+ rmSync5(join26(provSkillsDir, folder), { recursive: true });
12468
12579
  } catch {
12469
12580
  }
12470
12581
  }
@@ -12477,7 +12588,7 @@ async function processAgent(agent, agentStates) {
12477
12588
  const trackedFiles2 = frameworkAdapter.driftTrackedFiles();
12478
12589
  const hashes = /* @__PURE__ */ new Map();
12479
12590
  for (const file of trackedFiles2) {
12480
- const h = hashFile(join25(agentDir, file));
12591
+ const h = hashFile(join26(agentDir, file));
12481
12592
  if (h) hashes.set(file, h);
12482
12593
  }
12483
12594
  agentState.writtenHashes.set(agent.agent_id, hashes);
@@ -12495,14 +12606,14 @@ async function processAgent(agent, agentStates) {
12495
12606
  }
12496
12607
  if (Array.isArray(refreshData.workflows)) {
12497
12608
  try {
12498
- const provWorkflowsDir = join25(agentDir, ".claude", "workflows");
12499
- if (existsSync11(provWorkflowsDir)) {
12609
+ const provWorkflowsDir = join26(agentDir, ".claude", "workflows");
12610
+ if (existsSync12(provWorkflowsDir)) {
12500
12611
  const expected = new Set(refreshData.workflows.map((w) => `${w.name}.js`));
12501
12612
  for (const file of readdirSync7(provWorkflowsDir)) {
12502
12613
  if (!file.endsWith(".js")) continue;
12503
12614
  if (expected.has(file)) continue;
12504
12615
  try {
12505
- rmSync5(join25(provWorkflowsDir, file));
12616
+ rmSync5(join26(provWorkflowsDir, file));
12506
12617
  } catch {
12507
12618
  }
12508
12619
  }
@@ -12581,10 +12692,10 @@ async function processAgent(agent, agentStates) {
12581
12692
  }
12582
12693
  let lastDriftCheckAt = now;
12583
12694
  const written = agentState.writtenHashes.get(agent.agent_id);
12584
- if (written && existsSync11(agentDir)) {
12695
+ if (written && existsSync12(agentDir)) {
12585
12696
  const driftedFiles = [];
12586
12697
  for (const [file, expectedHash] of written) {
12587
- const localHash = hashFile(join25(agentDir, file));
12698
+ const localHash = hashFile(join26(agentDir, file));
12588
12699
  if (localHash && localHash !== expectedHash) {
12589
12700
  driftedFiles.push(file);
12590
12701
  }
@@ -12595,7 +12706,7 @@ async function processAgent(agent, agentStates) {
12595
12706
  try {
12596
12707
  const localHashes = {};
12597
12708
  for (const file of driftedFiles) {
12598
- localHashes[file] = hashFile(join25(agentDir, file));
12709
+ localHashes[file] = hashFile(join26(agentDir, file));
12599
12710
  }
12600
12711
  await api.post("/host/drift", {
12601
12712
  agent_id: agent.agent_id,
@@ -12797,7 +12908,7 @@ async function processAgent(agent, agentStates) {
12797
12908
  const addedChannels = [...restartDecision.added];
12798
12909
  const writeDmNoticeMarkers = isChannelAddRestart ? () => {
12799
12910
  try {
12800
- const agentAugmentedDir = join25(homedir11(), ".augmented", agent.code_name);
12911
+ const agentAugmentedDir = join26(homedir12(), ".augmented", agent.code_name);
12801
12912
  mkdirSync10(agentAugmentedDir, { recursive: true });
12802
12913
  const markerJson = JSON.stringify({
12803
12914
  version: 1,
@@ -12805,7 +12916,7 @@ async function processAgent(agent, agentStates) {
12805
12916
  added: addedChannels
12806
12917
  });
12807
12918
  for (const file of ["slack-channel-add-restart.json", "telegram-channel-add-restart.json"]) {
12808
- atomicWriteFileSync(join25(agentAugmentedDir, file), markerJson);
12919
+ atomicWriteFileSync(join26(agentAugmentedDir, file), markerJson);
12809
12920
  }
12810
12921
  } catch (err) {
12811
12922
  log(`[hot-reload] channel-add DM-notice marker write failed for '${agent.code_name}' (non-fatal): ${err.message}`);
@@ -12994,24 +13105,24 @@ async function processAgent(agent, agentStates) {
12994
13105
  if (agentSessionMode === "persistent" && (agentFrameworkCache.get(agent.code_name) ?? DEFAULT_FRAMEWORK) === "claude-code") {
12995
13106
  try {
12996
13107
  const agentProvisionDir = agentDir;
12997
- const projectDir = join25(homedir11(), ".augmented", agent.code_name, "project");
13108
+ const projectDir = join26(homedir12(), ".augmented", agent.code_name, "project");
12998
13109
  mkdirSync10(agentProvisionDir, { recursive: true });
12999
13110
  mkdirSync10(projectDir, { recursive: true });
13000
- const provisionMcpPath = join25(agentProvisionDir, ".mcp.json");
13001
- const projectMcpPath = join25(projectDir, ".mcp.json");
13111
+ const provisionMcpPath = join26(agentProvisionDir, ".mcp.json");
13112
+ const projectMcpPath = join26(projectDir, ".mcp.json");
13002
13113
  let mcpConfig = { mcpServers: {} };
13003
13114
  try {
13004
13115
  mcpConfig = JSON.parse(readFileSync21(provisionMcpPath, "utf-8"));
13005
13116
  if (!mcpConfig.mcpServers) mcpConfig.mcpServers = {};
13006
13117
  } catch {
13007
13118
  }
13008
- const localDirectChatChannel = join25(homedir11(), ".augmented", "_mcp", "direct-chat-channel.js");
13119
+ const localDirectChatChannel = join26(homedir12(), ".augmented", "_mcp", "direct-chat-channel.js");
13009
13120
  const directChatTeamSettings = refreshData.team?.settings;
13010
13121
  const directChatTz = (() => {
13011
13122
  const tz = directChatTeamSettings?.["timezone"];
13012
13123
  return typeof tz === "string" && tz.trim() !== "" ? tz.trim() : void 0;
13013
13124
  })();
13014
- if (existsSync11(localDirectChatChannel)) {
13125
+ if (existsSync12(localDirectChatChannel)) {
13015
13126
  const directChatEnv = {
13016
13127
  AGT_HOST: requireHost(),
13017
13128
  // ENG-5901 Track D: templated — the manager exports the real
@@ -13031,7 +13142,7 @@ async function processAgent(agent, agentStates) {
13031
13142
  // ~/.augmented/<codeName>/.current-turn-initiator.json. Note getAgentDir
13032
13143
  // returns the agent root (NOT the /provision subdir `agentDir` points at),
13033
13144
  // so it byte-matches the broker readers' path.
13034
- AGT_TURN_INITIATOR_FILE: join25(
13145
+ AGT_TURN_INITIATOR_FILE: join26(
13035
13146
  frameworkAdapter.getAgentDir(agent.code_name),
13036
13147
  ".current-turn-initiator.json"
13037
13148
  )
@@ -13051,8 +13162,8 @@ async function processAgent(agent, agentStates) {
13051
13162
  log(`Channel credentials written for '${agent.code_name}/direct-chat'`);
13052
13163
  }
13053
13164
  }
13054
- const staleChannelsPath = join25(projectDir, ".mcp-channels.json");
13055
- if (existsSync11(staleChannelsPath)) {
13165
+ const staleChannelsPath = join26(projectDir, ".mcp-channels.json");
13166
+ if (existsSync12(staleChannelsPath)) {
13056
13167
  try {
13057
13168
  rmSync5(staleChannelsPath, { force: true });
13058
13169
  } catch {
@@ -13141,7 +13252,7 @@ async function processAgent(agent, agentStates) {
13141
13252
  }
13142
13253
  if (hostFlagStore().getBoolean("connectivity-probe")) {
13143
13254
  try {
13144
- const probeProjectDir = join25(homedir11(), ".augmented", agent.code_name, "project");
13255
+ const probeProjectDir = join26(homedir12(), ".augmented", agent.code_name, "project");
13145
13256
  let probeSet = integrations;
13146
13257
  try {
13147
13258
  const quarantined = await api.post("/host/agent-integrations/quarantined", { agent_id: agent.agent_id });
@@ -13187,7 +13298,7 @@ async function processAgent(agent, agentStates) {
13187
13298
  const forceDue = attemptsLeft > 0;
13188
13299
  let probeRan = false;
13189
13300
  try {
13190
- const probeProjectDir = join25(homedir11(), ".augmented", agent.code_name, "project");
13301
+ const probeProjectDir = join26(homedir12(), ".augmented", agent.code_name, "project");
13191
13302
  probeRan = await runAgentSessionToolBindProbes(agent, integrations, probeProjectDir, { forceDue });
13192
13303
  } catch (err) {
13193
13304
  log(`Session-tool-bind probe failed for '${agent.code_name}': ${err.message}`);
@@ -13264,8 +13375,8 @@ async function processAgent(agent, agentStates) {
13264
13375
  const intHash = computeIntegrationsHash(integrations);
13265
13376
  const prevIntHash = agentState.knownIntegrationHashes.get(agent.agent_id);
13266
13377
  if (intHash !== prevIntHash) {
13267
- const projectDir = join25(homedir11(), ".augmented", agent.code_name, "project");
13268
- const envIntPath = join25(projectDir, ".env.integrations");
13378
+ const projectDir = join26(homedir12(), ".augmented", agent.code_name, "project");
13379
+ const envIntPath = join26(projectDir, ".env.integrations");
13269
13380
  let preWriteEnv;
13270
13381
  try {
13271
13382
  preWriteEnv = readFileSync21(envIntPath, "utf-8");
@@ -13287,7 +13398,7 @@ async function processAgent(agent, agentStates) {
13287
13398
  }
13288
13399
  if (fw === "claude-code" && isSessionHealthy(agent.code_name)) {
13289
13400
  try {
13290
- const projectMcpPath = join25(projectDir, ".mcp.json");
13401
+ const projectMcpPath = join26(projectDir, ".mcp.json");
13291
13402
  const postWriteEnv = readFileSync21(envIntPath, "utf-8");
13292
13403
  const mcpContent = readFileSync21(projectMcpPath, "utf-8");
13293
13404
  const changedVars = diffEnvIntegrations(preWriteEnv, postWriteEnv);
@@ -13542,18 +13653,18 @@ async function processAgent(agent, agentStates) {
13542
13653
  }
13543
13654
  try {
13544
13655
  const { readdirSync: readdirSync8, rmSync: rmSync6 } = await import("fs");
13545
- const { homedir: homedir12 } = await import("os");
13656
+ const { homedir: homedir13 } = await import("os");
13546
13657
  const frameworkId2 = frameworkAdapter.id;
13547
13658
  const candidateSkillDirs = [
13548
13659
  // Claude Code — framework runtime tree
13549
- join25(homedir12(), ".augmented", agent.code_name, "skills"),
13660
+ join26(homedir13(), ".augmented", agent.code_name, "skills"),
13550
13661
  // Claude Code — project tree
13551
- join25(homedir12(), ".augmented", agent.code_name, "project", ".claude", "skills"),
13662
+ join26(homedir13(), ".augmented", agent.code_name, "project", ".claude", "skills"),
13552
13663
  // Defensive: legacy provision-side path, not currently an
13553
13664
  // install target but cheap to sweep.
13554
- join25(agentDir, ".claude", "skills")
13665
+ join26(agentDir, ".claude", "skills")
13555
13666
  ];
13556
- const existingDirs = candidateSkillDirs.filter((d) => existsSync11(d));
13667
+ const existingDirs = candidateSkillDirs.filter((d) => existsSync12(d));
13557
13668
  const discoveredEntries = /* @__PURE__ */ new Set();
13558
13669
  for (const dir of existingDirs) {
13559
13670
  try {
@@ -13567,8 +13678,8 @@ async function processAgent(agent, agentStates) {
13567
13678
  }
13568
13679
  const removeSkillFolder = (entry, reason) => {
13569
13680
  for (const dir of existingDirs) {
13570
- const p = join25(dir, entry);
13571
- if (existsSync11(p)) {
13681
+ const p = join26(dir, entry);
13682
+ if (existsSync12(p)) {
13572
13683
  rmSync6(p, { recursive: true, force: true });
13573
13684
  }
13574
13685
  }
@@ -13587,7 +13698,7 @@ async function processAgent(agent, agentStates) {
13587
13698
  const sharedSkillsPayload = refreshAny.shared_skills;
13588
13699
  const desiredResolved = globalSkillsPayload !== void 0 || sharedSkillsPayload !== void 0;
13589
13700
  const manifestPath = managedSkillManifestPath(
13590
- join25(homedir11(), ".augmented", agent.code_name)
13701
+ join26(homedir12(), ".augmented", agent.code_name)
13591
13702
  );
13592
13703
  const prevIds = /* @__PURE__ */ new Set([
13593
13704
  ...agentState.knownGlobalSkillIds.get(agent.agent_id) ?? /* @__PURE__ */ new Set(),
@@ -13607,15 +13718,15 @@ async function processAgent(agent, agentStates) {
13607
13718
  }
13608
13719
  if (plan.removes.length) {
13609
13720
  const globalSkillDirs = [
13610
- join25(homedir11(), ".augmented", agent.code_name, "skills"),
13611
- join25(homedir11(), ".augmented", agent.code_name, "project", ".claude", "skills"),
13612
- join25(agentDir, ".claude", "skills")
13721
+ join26(homedir12(), ".augmented", agent.code_name, "skills"),
13722
+ join26(homedir12(), ".augmented", agent.code_name, "project", ".claude", "skills"),
13723
+ join26(agentDir, ".claude", "skills")
13613
13724
  ];
13614
13725
  for (const id of plan.removes) {
13615
13726
  let prunedAny = false;
13616
13727
  for (const dir of globalSkillDirs) {
13617
- const p = join25(dir, id);
13618
- if (existsSync11(p) && existsSync11(join25(p, "SKILL.md"))) {
13728
+ const p = join26(dir, id);
13729
+ if (existsSync12(p) && existsSync12(join26(p, "SKILL.md"))) {
13619
13730
  rmSync5(p, { recursive: true, force: true });
13620
13731
  prunedAny = true;
13621
13732
  }
@@ -13846,7 +13957,7 @@ async function processAgent(agent, agentStates) {
13846
13957
  const sess = getSessionState(agent.code_name);
13847
13958
  let mcpJsonParsed = null;
13848
13959
  try {
13849
- const mcpPath = join25(getProjectDir(agent.code_name), ".mcp.json");
13960
+ const mcpPath = join26(getProjectDir(agent.code_name), ".mcp.json");
13850
13961
  mcpJsonParsed = JSON.parse(readFileSync21(mcpPath, "utf-8"));
13851
13962
  } catch {
13852
13963
  }
@@ -14270,10 +14381,10 @@ Retried to the limit after repeated stalls \u2014 needs a look.`).catch(() => {
14270
14381
  }
14271
14382
  }
14272
14383
  const trackedFiles = frameworkAdapter.driftTrackedFiles();
14273
- if (trackedFiles.length > 0 && existsSync11(agentDir)) {
14384
+ if (trackedFiles.length > 0 && existsSync12(agentDir)) {
14274
14385
  const hashes = /* @__PURE__ */ new Map();
14275
14386
  for (const file of trackedFiles) {
14276
- const h = hashFile(join25(agentDir, file));
14387
+ const h = hashFile(join26(agentDir, file));
14277
14388
  if (h) hashes.set(file, h);
14278
14389
  }
14279
14390
  agentState.writtenHashes.set(agent.agent_id, hashes);
@@ -14288,7 +14399,7 @@ Retried to the limit after repeated stalls \u2014 needs a look.`).catch(() => {
14288
14399
  refreshData.agent.onboarding_state
14289
14400
  );
14290
14401
  const obStep = obState.step;
14291
- const markerPath = join25(homedir11(), ".augmented", agent.code_name, "onboarding-drive.json");
14402
+ const markerPath = join26(homedir12(), ".augmented", agent.code_name, "onboarding-drive.json");
14292
14403
  const marker = readOnboardingDriveMarker(markerPath);
14293
14404
  const decision = decideOnboardingDrive(obStep, marker, Date.now(), obState.generation ?? 0);
14294
14405
  if (decision.clearMarker) {
@@ -14376,7 +14487,7 @@ async function ensureOpencodeRuntime(agent, refreshData, agentTimezone) {
14376
14487
  }
14377
14488
  stopOpencodeSlackIngest(codeName, log);
14378
14489
  stopOpencodeTelegramIngest(codeName, log);
14379
- const opencodeProjectDir = join25(getFramework("opencode").getAgentDir(codeName), "provision");
14490
+ const opencodeProjectDir = join26(getFramework("opencode").getAgentDir(codeName), "provision");
14380
14491
  const serveEnv = {
14381
14492
  AGT_HOST: requireHost(),
14382
14493
  AGT_API_KEY: getApiKey() ?? void 0,
@@ -14418,9 +14529,16 @@ async function ensureOpencodeRuntime(agent, refreshData, agentTimezone) {
14418
14529
  }
14419
14530
  async function ensurePersistentSession(agent, tasks, boardItems, refreshData) {
14420
14531
  const codeName = agent.code_name;
14532
+ if ((agentFrameworkCache.get(codeName) ?? DEFAULT_FRAMEWORK) === "claude-code" && !isSessionHealthy(codeName)) {
14533
+ maybeMigrateAgentToIdKeyedLayout(agent, {
14534
+ flagStore: hostFlagStore(),
14535
+ channelConfigs: refreshData["channel_configs"] ?? null,
14536
+ log
14537
+ });
14538
+ }
14421
14539
  const projectDir = getProjectDir(codeName);
14422
- const mcpConfigPath = join25(projectDir, ".mcp.json");
14423
- const claudeMdPath = join25(projectDir, "CLAUDE.md");
14540
+ const mcpConfigPath = join26(projectDir, ".mcp.json");
14541
+ const claudeMdPath = join26(projectDir, "CLAUDE.md");
14424
14542
  if (restartBreaker.isTripped(codeName)) {
14425
14543
  const trip = restartBreaker.getTrip(codeName);
14426
14544
  return {
@@ -15036,7 +15154,7 @@ async function handleRestartDoorbell(agentId, requestedAt, restartReason) {
15036
15154
  void api.post("/host/restart-ack", { host_id: hostId, agent_id: agentId, restart_requested_at: requestedAt }).catch((err) => log(`[restart-lane] ack failed for '${codeName}': ${err.message}`));
15037
15155
  void (async () => {
15038
15156
  try {
15039
- const { collectDiagnostics } = await import("../persistent-session-Y3WIXJPW.js");
15157
+ const { collectDiagnostics } = await import("../persistent-session-MVAEGE6J.js");
15040
15158
  await api.post("/host/heartbeat", {
15041
15159
  host_id: hostId,
15042
15160
  agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor)
@@ -15086,7 +15204,7 @@ async function respawnAgentAfterMcpStop(codeName, reason) {
15086
15204
  }
15087
15205
  try {
15088
15206
  const hostId = await getHostId();
15089
- const { collectDiagnostics } = await import("../persistent-session-Y3WIXJPW.js");
15207
+ const { collectDiagnostics } = await import("../persistent-session-MVAEGE6J.js");
15090
15208
  await api.post("/host/heartbeat", {
15091
15209
  host_id: hostId,
15092
15210
  agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor)
@@ -15376,7 +15494,7 @@ async function processDirectChatMessage(agent, msg) {
15376
15494
  const useDoorbell = hostFlagStore().getBoolean("direct-chat-doorbell") || isolationMode(agent.codeName) === "docker";
15377
15495
  if (useDoorbell) {
15378
15496
  try {
15379
- const doorbell = directChatDoorbellPath(agent.agentId, homedir11());
15497
+ const doorbell = directChatDoorbellPath(agent.agentId, homedir12());
15380
15498
  mkdirSync10(dirname8(doorbell), { recursive: true });
15381
15499
  writeFileSync12(doorbell, String(Date.now()));
15382
15500
  log(`[direct-chat] Doorbell rung for '${agent.codeName}' (msg=${msg.id}) \u2014 in-session MCP will pull via the cursor`);
@@ -15486,7 +15604,7 @@ ${formatRunMarker(run_id)}` : KANBAN_CHECK_COMMAND;
15486
15604
  }
15487
15605
  if (run_id) openInjectedRunByCode.set(codeName, run_id);
15488
15606
  try {
15489
- const doorbell = directChatDoorbellPath(agentId, homedir11());
15607
+ const doorbell = directChatDoorbellPath(agentId, homedir12());
15490
15608
  mkdirSync10(dirname8(doorbell), { recursive: true });
15491
15609
  writeFileSync12(doorbell, String(Date.now()));
15492
15610
  } catch (err) {
@@ -15544,7 +15662,7 @@ async function processClaudePairSessions(agents) {
15544
15662
  killPairSession,
15545
15663
  pairTmuxSession,
15546
15664
  finalizeClaudePairOnboarding
15547
- } = await import("../claude-pair-runtime-GJF64TMZ.js");
15665
+ } = await import("../claude-pair-runtime-7TSEIWGA.js");
15548
15666
  for (const pairId of pendingResp.cancelled_pair_ids ?? []) {
15549
15667
  log(`[claude-pair] sweeping orphan tmux session for pair ${pairId.slice(0, 8)}`);
15550
15668
  const killed = await killPairSession(pairTmuxSession(pairId));
@@ -15798,8 +15916,8 @@ function parseMemoryFile(raw, fallbackName) {
15798
15916
  };
15799
15917
  }
15800
15918
  async function syncMemories(agent, configDir, log2) {
15801
- const projectDir = join25(configDir, agent.code_name, "project");
15802
- const memoryDir = join25(projectDir, "memory");
15919
+ const projectDir = join26(configDir, agent.code_name, "project");
15920
+ const memoryDir = join26(projectDir, "memory");
15803
15921
  const isFreshSync = pendingFreshMemorySync.has(agent.agent_id);
15804
15922
  if (isFreshSync) {
15805
15923
  log2(`[memory-sync] Fresh-sync requested for '${agent.code_name}' \u2014 pulling DB first`);
@@ -15810,14 +15928,14 @@ async function syncMemories(agent, configDir, log2) {
15810
15928
  }
15811
15929
  pendingFreshMemorySync.delete(agent.agent_id);
15812
15930
  }
15813
- if (existsSync11(memoryDir)) {
15931
+ if (existsSync12(memoryDir)) {
15814
15932
  const prevHashes = memoryFileHashes.get(agent.agent_id) ?? /* @__PURE__ */ new Map();
15815
15933
  const currentHashes = /* @__PURE__ */ new Map();
15816
15934
  const changedMemories = [];
15817
15935
  for (const file of readdirSync7(memoryDir)) {
15818
15936
  if (!file.endsWith(".md")) continue;
15819
15937
  try {
15820
- const raw = readFileSync21(join25(memoryDir, file), "utf-8");
15938
+ const raw = readFileSync21(join26(memoryDir, file), "utf-8");
15821
15939
  const fileHash = createHash16("sha256").update(raw).digest("hex").slice(0, 16);
15822
15940
  currentHashes.set(file, fileHash);
15823
15941
  if (prevHashes.get(file) === fileHash) continue;
@@ -15842,7 +15960,7 @@ async function syncMemories(agent, configDir, log2) {
15842
15960
  } catch (err) {
15843
15961
  for (const mem of changedMemories) {
15844
15962
  for (const [file] of currentHashes) {
15845
- const parsed = parseMemoryFile(readFileSync21(join25(memoryDir, file), "utf-8"), file.replace(/\.md$/, ""));
15963
+ const parsed = parseMemoryFile(readFileSync21(join26(memoryDir, file), "utf-8"), file.replace(/\.md$/, ""));
15846
15964
  if (parsed?.name === mem.name) currentHashes.delete(file);
15847
15965
  }
15848
15966
  }
@@ -15855,7 +15973,7 @@ async function syncMemories(agent, configDir, log2) {
15855
15973
  }
15856
15974
  }
15857
15975
  async function downloadMemories(agent, memoryDir, log2, { force }) {
15858
- const localFiles = existsSync11(memoryDir) ? readdirSync7(memoryDir).filter((f) => f.endsWith(".md")).sort() : [];
15976
+ const localFiles = existsSync12(memoryDir) ? readdirSync7(memoryDir).filter((f) => f.endsWith(".md")).sort() : [];
15859
15977
  const localListHash = createHash16("sha256").update(localFiles.join(",")).digest("hex").slice(0, 16);
15860
15978
  const prevLocalHash = lastLocalFileHash.get(agent.agent_id);
15861
15979
  const prevDownload = lastDownloadHash.get(agent.agent_id);
@@ -15877,7 +15995,7 @@ async function downloadMemories(agent, memoryDir, log2, { force }) {
15877
15995
  const mem = dbMemories.memories[i];
15878
15996
  const rawSlug = mem.name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)/g, "").slice(0, 60);
15879
15997
  const slug = rawSlug || `memory-${i}`;
15880
- const filePath = join25(memoryDir, `${slug}.md`);
15998
+ const filePath = join26(memoryDir, `${slug}.md`);
15881
15999
  const desired = `---
15882
16000
  name: ${JSON.stringify(mem.name)}
15883
16001
  type: ${mem.type}
@@ -15886,7 +16004,7 @@ description: ${JSON.stringify(mem.content.slice(0, 200))}
15886
16004
 
15887
16005
  ${mem.content}
15888
16006
  `;
15889
- if (existsSync11(filePath)) {
16007
+ if (existsSync12(filePath)) {
15890
16008
  let existing = "";
15891
16009
  try {
15892
16010
  existing = readFileSync21(filePath, "utf-8");
@@ -15913,7 +16031,7 @@ ${mem.content}
15913
16031
  }
15914
16032
  }
15915
16033
  async function cleanupAgentFiles(codeName, agentDir) {
15916
- if (existsSync11(agentDir)) {
16034
+ if (existsSync12(agentDir)) {
15917
16035
  try {
15918
16036
  rmSync5(agentDir, { recursive: true, force: true });
15919
16037
  log(`Removed provision directory for '${codeName}'`);
@@ -16152,7 +16270,7 @@ function startManager(opts) {
16152
16270
  config = opts;
16153
16271
  try {
16154
16272
  const stateFile = getStateFile();
16155
- if (existsSync11(stateFile)) {
16273
+ if (existsSync12(stateFile)) {
16156
16274
  const raw = readFileSync21(stateFile, "utf-8");
16157
16275
  const parsed = JSON.parse(raw);
16158
16276
  if (Array.isArray(parsed.agents)) {
@@ -16180,7 +16298,7 @@ function startManager(opts) {
16180
16298
  log(`[startup] state rehydration failed (continuing with empty state): ${err.message}`);
16181
16299
  }
16182
16300
  log(
16183
- `[startup] worker pid=${process.pid} ppid=${process.ppid} node=${process.version} log=${join25(homedir11(), ".augmented", "manager.log")}`
16301
+ `[startup] worker pid=${process.pid} ppid=${process.ppid} node=${process.version} log=${join26(homedir12(), ".augmented", "manager.log")}`
16184
16302
  );
16185
16303
  deployMcpAssets();
16186
16304
  reapOrphanChannelMcps({ log });
@@ -16306,14 +16424,14 @@ function restartRunningChannelMcps(basenames) {
16306
16424
  }
16307
16425
  }
16308
16426
  function deployMcpAssets() {
16309
- const targetDir = join25(homedir11(), ".augmented", "_mcp");
16427
+ const targetDir = join26(homedir12(), ".augmented", "_mcp");
16310
16428
  mkdirSync10(targetDir, { recursive: true });
16311
16429
  const moduleDir = dirname8(fileURLToPath(import.meta.url));
16312
16430
  let mcpSourceDir = "";
16313
16431
  let dir = moduleDir;
16314
16432
  for (let i = 0; i < 6; i++) {
16315
- const candidate = join25(dir, "dist", "mcp");
16316
- if (existsSync11(join25(candidate, "index.js"))) {
16433
+ const candidate = join26(dir, "dist", "mcp");
16434
+ if (existsSync12(join26(candidate, "index.js"))) {
16317
16435
  mcpSourceDir = candidate;
16318
16436
  break;
16319
16437
  }
@@ -16328,7 +16446,7 @@ function deployMcpAssets() {
16328
16446
  const changedBasenames = [];
16329
16447
  const fileHash = (p) => {
16330
16448
  try {
16331
- if (!existsSync11(p)) return null;
16449
+ if (!existsSync12(p)) return null;
16332
16450
  return createHash16("sha256").update(readFileSync21(p)).digest("hex");
16333
16451
  } catch {
16334
16452
  return null;
@@ -16393,9 +16511,9 @@ function deployMcpAssets() {
16393
16511
  // needs restarting to pick up a token rotation.
16394
16512
  "xero.js"
16395
16513
  ]) {
16396
- const src = join25(mcpSourceDir, file);
16397
- const dst = join25(targetDir, file);
16398
- if (!existsSync11(src)) continue;
16514
+ const src = join26(mcpSourceDir, file);
16515
+ const dst = join26(targetDir, file);
16516
+ if (!existsSync12(src)) continue;
16399
16517
  const before = fileHash(dst);
16400
16518
  try {
16401
16519
  copyFileSync(src, dst);
@@ -16412,14 +16530,14 @@ function deployMcpAssets() {
16412
16530
  log(`[manager] Bundle(s) updated: ${changedBasenames.join(", ")} \u2014 signalling running instances to restart`);
16413
16531
  restartRunningChannelMcps(changedBasenames);
16414
16532
  }
16415
- const localMcpPath = join25(targetDir, "index.js");
16533
+ const localMcpPath = join26(targetDir, "index.js");
16416
16534
  try {
16417
- const agentsDir = join25(homedir11(), ".augmented", "agents");
16418
- if (existsSync11(agentsDir)) {
16535
+ const agentsDir = join26(homedir12(), ".augmented", "agents");
16536
+ if (existsSync12(agentsDir)) {
16419
16537
  for (const entry of readdirSync7(agentsDir, { withFileTypes: true })) {
16420
16538
  if (!entry.isDirectory()) continue;
16421
16539
  for (const subdir of ["provision", "project"]) {
16422
- const mcpJsonPath = join25(agentsDir, entry.name, subdir, ".mcp.json");
16540
+ const mcpJsonPath = join26(agentsDir, entry.name, subdir, ".mcp.json");
16423
16541
  try {
16424
16542
  const raw = readFileSync21(mcpJsonPath, "utf-8");
16425
16543
  if (!raw.includes("@integrity-labs/augmented-mcp")) continue;