@integrity-labs/agt-cli 0.28.675 → 0.28.677

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (25) hide show
  1. package/dist/bin/agt.js +5 -5
  2. package/dist/{chunk-7Y54PSMR.js → chunk-F6CUSDJ6.js} +2 -2
  3. package/dist/{chunk-AJNES24H.js → chunk-GYYEUNTD.js} +26 -1
  4. package/dist/chunk-GYYEUNTD.js.map +1 -0
  5. package/dist/{chunk-ZKP6UYPJ.js → chunk-HTLUHAKN.js} +4 -4
  6. package/dist/{claude-pair-runtime-VAU7UXE4.js → claude-pair-runtime-MY5LMJVT.js} +2 -2
  7. package/dist/lib/manager-worker.js +382 -210
  8. package/dist/lib/manager-worker.js.map +1 -1
  9. package/dist/mcp/augmented-admin.js +34 -1
  10. package/dist/mcp/direct-chat-channel.js +25 -0
  11. package/dist/mcp/index.js +25 -0
  12. package/dist/mcp/origami.js +25 -0
  13. package/dist/mcp/slack-channel.js +25 -0
  14. package/dist/mcp/telegram-channel.js +25 -0
  15. package/dist/{persistent-session-F7JEOWHQ.js → persistent-session-TMOTEVV6.js} +3 -3
  16. package/dist/{responsiveness-probe-7465YNMN.js → responsiveness-probe-ZHE7S6G4.js} +3 -3
  17. package/dist/{session-auth-dead-GBC5QPH3.js → session-auth-dead-JCKENEY5.js} +2 -2
  18. package/package.json +1 -1
  19. package/dist/chunk-AJNES24H.js.map +0 -1
  20. /package/dist/{chunk-7Y54PSMR.js.map → chunk-F6CUSDJ6.js.map} +0 -0
  21. /package/dist/{chunk-ZKP6UYPJ.js.map → chunk-HTLUHAKN.js.map} +0 -0
  22. /package/dist/{claude-pair-runtime-VAU7UXE4.js.map → claude-pair-runtime-MY5LMJVT.js.map} +0 -0
  23. /package/dist/{persistent-session-F7JEOWHQ.js.map → persistent-session-TMOTEVV6.js.map} +0 -0
  24. /package/dist/{responsiveness-probe-7465YNMN.js.map → responsiveness-probe-ZHE7S6G4.js.map} +0 -0
  25. /package/dist/{session-auth-dead-GBC5QPH3.js.map → session-auth-dead-JCKENEY5.js.map} +0 -0
@@ -54,7 +54,7 @@ import {
54
54
  safeWriteJsonAtomic,
55
55
  setConfigHash,
56
56
  tripClass
57
- } from "../chunk-ZKP6UYPJ.js";
57
+ } from "../chunk-HTLUHAKN.js";
58
58
  import {
59
59
  getProjectDir as getProjectDir2,
60
60
  getReadyTasks,
@@ -112,7 +112,7 @@ import {
112
112
  takeZombieDetection,
113
113
  toOpencodeModel,
114
114
  writeEgressAllowlist
115
- } from "../chunk-7Y54PSMR.js";
115
+ } from "../chunk-F6CUSDJ6.js";
116
116
  import {
117
117
  ACCOUNT_ENFORCEMENT_MARKER_FILENAME,
118
118
  AnchorSessionClient,
@@ -193,14 +193,14 @@ import {
193
193
  subagentActivityAgeSeconds,
194
194
  sumTranscriptUsageInWindow,
195
195
  transcriptActivityAgeSeconds
196
- } from "../chunk-AJNES24H.js";
196
+ } from "../chunk-GYYEUNTD.js";
197
197
  import {
198
198
  reapOrphanChannelMcps
199
199
  } from "../chunk-XWVM4KPK.js";
200
200
 
201
201
  // src/lib/manager-worker.ts
202
202
  import { createHash as createHash17 } from "crypto";
203
- import { readFileSync as readFileSync28, writeFileSync as writeFileSync14, mkdirSync as mkdirSync11, existsSync as existsSync15, rmSync as rmSync5, readdirSync as readdirSync9, statSync as statSync8, unlinkSync as unlinkSync6, renameSync as renameSync8, utimesSync } from "fs";
203
+ import { readFileSync as readFileSync29, writeFileSync as writeFileSync14, mkdirSync as mkdirSync11, existsSync as existsSync16, rmSync as rmSync5, readdirSync as readdirSync9, statSync as statSync8, unlinkSync as unlinkSync6, renameSync as renameSync8, utimesSync } from "fs";
204
204
 
205
205
  // src/lib/atomic-file-replace.ts
206
206
  import { copyFileSync, renameSync, unlinkSync } from "fs";
@@ -226,7 +226,7 @@ function defaultUnique() {
226
226
 
227
227
  // src/lib/manager-worker.ts
228
228
  import { execFileSync as syncExecFile } from "child_process";
229
- import { join as join36, dirname as dirname10, delimiter as pathDelimiter } from "path";
229
+ import { join as join37, dirname as dirname10, delimiter as pathDelimiter } from "path";
230
230
  import { homedir as homedir17 } from "os";
231
231
  import { fileURLToPath } from "url";
232
232
 
@@ -1608,12 +1608,12 @@ function isPathInsideDir(candidate, dir) {
1608
1608
  return resolvedCandidate.startsWith(resolvedDir.endsWith(sep) ? resolvedDir : resolvedDir + sep);
1609
1609
  }
1610
1610
  function findMissingMcpBundles(mcpConfigPath, deps = {}) {
1611
- const existsSync16 = deps.existsSync ?? nodeExistsSync;
1612
- const readFileSync29 = deps.readFileSync ?? nodeReadFileSync;
1611
+ const existsSync17 = deps.existsSync ?? nodeExistsSync;
1612
+ const readFileSync30 = deps.readFileSync ?? nodeReadFileSync;
1613
1613
  const mcpDir = deps.mcpDir ?? getSharedMcpDir();
1614
1614
  let parsed;
1615
1615
  try {
1616
- parsed = JSON.parse(readFileSync29(mcpConfigPath, "utf-8"));
1616
+ parsed = JSON.parse(readFileSync30(mcpConfigPath, "utf-8"));
1617
1617
  } catch {
1618
1618
  return [];
1619
1619
  }
@@ -1633,7 +1633,7 @@ function findMissingMcpBundles(mcpConfigPath, deps = {}) {
1633
1633
  if (seenPaths.has(resolvedBundlePath)) continue;
1634
1634
  let present;
1635
1635
  try {
1636
- present = existsSync16(bundlePath);
1636
+ present = existsSync17(bundlePath);
1637
1637
  } catch {
1638
1638
  continue;
1639
1639
  }
@@ -5107,6 +5107,100 @@ function saveSenderPolicyBaseline(source, configDir, log2) {
5107
5107
  }
5108
5108
  }
5109
5109
 
5110
+ // src/lib/stuck-streak-store.ts
5111
+ import { existsSync as existsSync8, readFileSync as readFileSync19 } from "fs";
5112
+ import { join as join24 } from "path";
5113
+ var STORE_FILENAME = "stuck-streaks.json";
5114
+ var STUCK_STREAK_STORE_VERSION = 1;
5115
+ var STUCK_STREAK_CONCERNS = ["channelSync", "realtimeRebind"];
5116
+ function createStuckStreakMaps() {
5117
+ return { channelSync: /* @__PURE__ */ new Map(), realtimeRebind: /* @__PURE__ */ new Map() };
5118
+ }
5119
+ function getStuckStreakStoreFile(configDir) {
5120
+ return join24(configDir, STORE_FILENAME);
5121
+ }
5122
+ function isValidPersistedStreak(value) {
5123
+ if (!value || typeof value !== "object" || Array.isArray(value)) return false;
5124
+ const v = value;
5125
+ if (typeof v.attempts !== "number" || !Number.isFinite(v.attempts) || v.attempts < 1) return false;
5126
+ if (typeof v.since !== "number" || !Number.isFinite(v.since) || v.since <= 0) return false;
5127
+ if (typeof v.nextAttemptAt !== "number" || !Number.isFinite(v.nextAttemptAt)) return false;
5128
+ if (typeof v.loggedAtAttempt !== "number" || !Number.isFinite(v.loggedAtAttempt) || v.loggedAtAttempt < 0) return false;
5129
+ if (typeof v.detail !== "string") return false;
5130
+ return true;
5131
+ }
5132
+ function parseStuckStreakPayload(parsed) {
5133
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return null;
5134
+ const obj = parsed;
5135
+ if (obj.version !== STUCK_STREAK_STORE_VERSION) return null;
5136
+ const maps = createStuckStreakMaps();
5137
+ for (const concern of STUCK_STREAK_CONCERNS) {
5138
+ const entries = obj[concern];
5139
+ if (!entries || typeof entries !== "object" || Array.isArray(entries)) continue;
5140
+ for (const [agentId, entry] of Object.entries(entries)) {
5141
+ if (!agentId) continue;
5142
+ if (!isValidPersistedStreak(entry)) continue;
5143
+ maps[concern].set(agentId, entry);
5144
+ }
5145
+ }
5146
+ return maps;
5147
+ }
5148
+ function buildStuckStreakPayload(source) {
5149
+ const payload = { version: STUCK_STREAK_STORE_VERSION };
5150
+ for (const concern of STUCK_STREAK_CONCERNS) {
5151
+ const entries = {};
5152
+ for (const [agentId, streak] of source[concern]) entries[agentId] = streak;
5153
+ payload[concern] = entries;
5154
+ }
5155
+ return payload;
5156
+ }
5157
+ function loadStuckStreaks(target, configDir, log2) {
5158
+ const path = getStuckStreakStoreFile(configDir);
5159
+ if (!existsSync8(path)) return;
5160
+ let parsed;
5161
+ try {
5162
+ parsed = JSON.parse(readFileSync19(path, "utf-8"));
5163
+ } catch (err) {
5164
+ log2?.(
5165
+ `[stuck-streaks] discarding corrupt ${STORE_FILENAME} (${err.message}) \u2014 stuck-streak ages restart from zero and one spurious "recovered" close may follow`
5166
+ );
5167
+ return;
5168
+ }
5169
+ const maps = parseStuckStreakPayload(parsed);
5170
+ if (!maps) {
5171
+ log2?.(
5172
+ `[stuck-streaks] discarding unusable ${STORE_FILENAME} (bad shape or version, expected ${STUCK_STREAK_STORE_VERSION}) \u2014 stuck-streak ages restart from zero and one spurious "recovered" close may follow`
5173
+ );
5174
+ return;
5175
+ }
5176
+ for (const concern of STUCK_STREAK_CONCERNS) {
5177
+ for (const [agentId, streak] of maps[concern]) target[concern].set(agentId, streak);
5178
+ }
5179
+ }
5180
+ function saveStuckStreaks(source, configDir, log2) {
5181
+ const path = getStuckStreakStoreFile(configDir);
5182
+ try {
5183
+ atomicWriteFileSync(path, JSON.stringify(buildStuckStreakPayload(source), null, 2));
5184
+ return true;
5185
+ } catch (err) {
5186
+ log2?.(
5187
+ `[stuck-streaks] failed to persist ${STORE_FILENAME} (non-fatal): ${err.message}`
5188
+ );
5189
+ return false;
5190
+ }
5191
+ }
5192
+ function pruneStuckStreaksToAgents(maps, activeAgentIds) {
5193
+ const dropped = [];
5194
+ for (const concern of STUCK_STREAK_CONCERNS) {
5195
+ for (const agentId of [...maps[concern].keys()]) {
5196
+ if (activeAgentIds.has(agentId)) continue;
5197
+ maps[concern].delete(agentId);
5198
+ if (!dropped.includes(agentId)) dropped.push(agentId);
5199
+ }
5200
+ }
5201
+ return dropped;
5202
+ }
5203
+
5110
5204
  // src/lib/channel-sweep.ts
5111
5205
  import { execFileSync } from "child_process";
5112
5206
  var CHANNEL_BASENAMES = [
@@ -5582,7 +5676,7 @@ function planGlobalSkillSync(globalSkills, prevIds, hashOf, knownHash, options)
5582
5676
  }
5583
5677
 
5584
5678
  // src/lib/manager/integration-skill-cache.ts
5585
- import { join as join24 } from "path";
5679
+ import { join as join25 } from "path";
5586
5680
  function integrationSkillHashKey(agentId, skillId) {
5587
5681
  return `plugin-skill:${agentId}:${skillId}`;
5588
5682
  }
@@ -5598,21 +5692,21 @@ function forgetIntegrationSkill(cache3, agentId, skillId) {
5598
5692
  function removeIntegrationSkillFolder(opts) {
5599
5693
  forgetIntegrationSkill(opts.cache, opts.agentId, opts.entry);
5600
5694
  for (const dir of opts.dirs) {
5601
- opts.removeDir(join24(dir, opts.entry));
5695
+ opts.removeDir(join25(dir, opts.entry));
5602
5696
  }
5603
5697
  }
5604
5698
 
5605
5699
  // src/lib/manager/managed-skill-manifest.ts
5606
- import { existsSync as existsSync8, mkdirSync as mkdirSync6, readFileSync as readFileSync19, writeFileSync as writeFileSync8 } from "fs";
5607
- import { dirname as dirname7, join as join25 } from "path";
5700
+ import { existsSync as existsSync9, mkdirSync as mkdirSync6, readFileSync as readFileSync20, writeFileSync as writeFileSync8 } from "fs";
5701
+ import { dirname as dirname7, join as join26 } from "path";
5608
5702
  var MANIFEST_VERSION = 1;
5609
5703
  function managedSkillManifestPath(agentRootDir) {
5610
- return join25(agentRootDir, "managed-skills.json");
5704
+ return join26(agentRootDir, "managed-skills.json");
5611
5705
  }
5612
5706
  function readManagedSkillManifest(path) {
5613
5707
  try {
5614
- if (!existsSync8(path)) return /* @__PURE__ */ new Set();
5615
- const parsed = JSON.parse(readFileSync19(path, "utf-8"));
5708
+ if (!existsSync9(path)) return /* @__PURE__ */ new Set();
5709
+ const parsed = JSON.parse(readFileSync20(path, "utf-8"));
5616
5710
  const ids = Array.isArray(parsed?.globalSkillIds) ? parsed.globalSkillIds : [];
5617
5711
  return new Set(ids.filter((id) => typeof id === "string" && id.length > 0));
5618
5712
  } catch {
@@ -5738,8 +5832,8 @@ function resolveModelChain(refreshData) {
5738
5832
  }
5739
5833
 
5740
5834
  // src/lib/manager/claude-auth.ts
5741
- import { existsSync as existsSync9, rmSync as rmSync3 } from "fs";
5742
- import { join as join26 } from "path";
5835
+ import { existsSync as existsSync10, rmSync as rmSync3 } from "fs";
5836
+ import { join as join27 } from "path";
5743
5837
  import { homedir as homedir13 } from "os";
5744
5838
  async function applyClaudeAuthToEnv(childEnv, label) {
5745
5839
  const apiKey = getApiKey();
@@ -5752,10 +5846,10 @@ async function applyClaudeAuthToEnv(childEnv, label) {
5752
5846
  throw new Error("claude_auth_mode=api_key but /host/exchange returned no decrypted key");
5753
5847
  }
5754
5848
  childEnv.ANTHROPIC_API_KEY = exchange.anthropicApiKey;
5755
- const claudeDir = join26(homedir13(), ".claude");
5849
+ const claudeDir = join27(homedir13(), ".claude");
5756
5850
  for (const filename of [".credentials.json", "credentials.json"]) {
5757
- const p = join26(claudeDir, filename);
5758
- if (existsSync9(p)) {
5851
+ const p = join27(claudeDir, filename);
5852
+ if (existsSync10(p)) {
5759
5853
  try {
5760
5854
  rmSync3(p, { force: true });
5761
5855
  log(`[${label}] Removed ${p} (api_key mode \u2014 preventing OAuth fallback)`);
@@ -5836,8 +5930,8 @@ function heartbeatRuntimeAuthFields(probeVerdict) {
5836
5930
  }
5837
5931
 
5838
5932
  // src/lib/manager/kanban/parsers.ts
5839
- import { existsSync as existsSync10, readFileSync as readFileSync20 } from "fs";
5840
- import { join as join27 } from "path";
5933
+ import { existsSync as existsSync11, readFileSync as readFileSync21 } from "fs";
5934
+ import { join as join28 } from "path";
5841
5935
  var STANDUP_TEMPLATES = /* @__PURE__ */ new Set(["daily-standup", "end-of-day-summary"]);
5842
5936
  var TASK_UPDATE_TEMPLATES = /* @__PURE__ */ new Set(["hourly-status", "task-update"]);
5843
5937
  var PLAN_TEMPLATES = /* @__PURE__ */ new Set(["morning-plan"]);
@@ -5989,12 +6083,12 @@ function getBuiltInSkillContent(skillId) {
5989
6083
  if (builtInSkillCache.has(skillId)) return builtInSkillCache.get(skillId);
5990
6084
  try {
5991
6085
  const candidates = [
5992
- join27(process.cwd(), "skills", skillId, "SKILL.md"),
5993
- join27(new URL(".", import.meta.url).pathname, "..", "..", "..", "..", "..", "..", "skills", skillId, "SKILL.md")
6086
+ join28(process.cwd(), "skills", skillId, "SKILL.md"),
6087
+ join28(new URL(".", import.meta.url).pathname, "..", "..", "..", "..", "..", "..", "skills", skillId, "SKILL.md")
5994
6088
  ];
5995
6089
  for (const candidate of candidates) {
5996
- if (existsSync10(candidate)) {
5997
- const content = readFileSync20(candidate, "utf-8");
6090
+ if (existsSync11(candidate)) {
6091
+ const content = readFileSync21(candidate, "utf-8");
5998
6092
  const files = [{ relativePath: "SKILL.md", content }];
5999
6093
  builtInSkillCache.set(skillId, files);
6000
6094
  return files;
@@ -6135,19 +6229,19 @@ function formatBoardForPrompt(items, template) {
6135
6229
  }
6136
6230
 
6137
6231
  // src/lib/manager/kanban/nudge-state-cache.ts
6138
- import { existsSync as existsSync11, readFileSync as readFileSync21, writeFileSync as writeFileSync9 } from "fs";
6139
- import { join as join28 } from "path";
6232
+ import { existsSync as existsSync12, readFileSync as readFileSync22, writeFileSync as writeFileSync9 } from "fs";
6233
+ import { join as join29 } from "path";
6140
6234
  var CACHE_FILENAME2 = "kanban-nudge-state.json";
6141
6235
  var KANBAN_NUDGE_STATE_VERSION = 1;
6142
6236
  function getKanbanNudgeStateFile(configDir) {
6143
- return join28(configDir, CACHE_FILENAME2);
6237
+ return join29(configDir, CACHE_FILENAME2);
6144
6238
  }
6145
6239
  function loadKanbanNudgeState(target, configDir) {
6146
6240
  const path = getKanbanNudgeStateFile(configDir);
6147
- if (!existsSync11(path)) return;
6241
+ if (!existsSync12(path)) return;
6148
6242
  let parsed;
6149
6243
  try {
6150
- parsed = JSON.parse(readFileSync21(path, "utf-8"));
6244
+ parsed = JSON.parse(readFileSync22(path, "utf-8"));
6151
6245
  } catch {
6152
6246
  return;
6153
6247
  }
@@ -6765,9 +6859,9 @@ function closeSessionRunForCode(codeName, outcome, reason) {
6765
6859
 
6766
6860
  // src/lib/manager/scheduler/kanban-route.ts
6767
6861
  import { createHash as createHash12 } from "crypto";
6768
- import { writeFileSync as writeFileSync10, renameSync as renameSync5, mkdirSync as mkdirSync7, readFileSync as readFileSync22, unlinkSync as unlinkSync3 } from "fs";
6862
+ import { writeFileSync as writeFileSync10, renameSync as renameSync5, mkdirSync as mkdirSync7, readFileSync as readFileSync23, unlinkSync as unlinkSync3 } from "fs";
6769
6863
  import { homedir as homedir14 } from "os";
6770
- import { join as join29, dirname as dirname8 } from "path";
6864
+ import { join as join30, dirname as dirname8 } from "path";
6771
6865
 
6772
6866
  // src/lib/manager/scheduler/notify.ts
6773
6867
  import { createHash as createHash11 } from "crypto";
@@ -7126,7 +7220,7 @@ function resolveScheduledSlackTarget(task) {
7126
7220
  }
7127
7221
  function stampScheduledTurnMarker(codeName, taskId, target) {
7128
7222
  try {
7129
- const file = join29(homedir14(), ".augmented", codeName, SCHEDULED_TURN_MARKER_FILENAME);
7223
+ const file = join30(homedir14(), ".augmented", codeName, SCHEDULED_TURN_MARKER_FILENAME);
7130
7224
  const marker = { ts: Date.now(), task_id: taskId, ...target ? { target } : {} };
7131
7225
  const tmp = `${file}.tmp`;
7132
7226
  writeFileSync10(tmp, JSON.stringify(marker), "utf8");
@@ -7136,9 +7230,9 @@ function stampScheduledTurnMarker(codeName, taskId, target) {
7136
7230
  }
7137
7231
  }
7138
7232
  function clearScheduledTurnMarkerForTask(codeName, taskId) {
7139
- const file = join29(homedir14(), ".augmented", codeName, SCHEDULED_TURN_MARKER_FILENAME);
7233
+ const file = join30(homedir14(), ".augmented", codeName, SCHEDULED_TURN_MARKER_FILENAME);
7140
7234
  try {
7141
- const raw = JSON.parse(readFileSync22(file, "utf8"));
7235
+ const raw = JSON.parse(readFileSync23(file, "utf8"));
7142
7236
  if (typeof raw?.task_id !== "string" || raw.task_id !== taskId) return;
7143
7237
  unlinkSync3(file);
7144
7238
  log(`[scheduled-kanban] scheduled-turn marker cleared for '${codeName}' (task ${taskId} complete)`);
@@ -7351,11 +7445,11 @@ async function processClaudeTaskResult(codeName, agentId, templateId, rawOutput,
7351
7445
  // src/lib/manager/scheduler/execution.ts
7352
7446
  import { createHash as createHash13 } from "crypto";
7353
7447
  import { homedir as homedir15 } from "os";
7354
- import { join as join31 } from "path";
7448
+ import { join as join32 } from "path";
7355
7449
 
7356
7450
  // src/lib/agent-serving-probe.ts
7357
- import { readFileSync as readFileSync23, readdirSync as readdirSync5, statSync as statSync5 } from "fs";
7358
- import { join as join30 } from "path";
7451
+ import { readFileSync as readFileSync24, readdirSync as readdirSync5, statSync as statSync5 } from "fs";
7452
+ import { join as join31 } from "path";
7359
7453
  var RATE_LIMIT_WINDOW_MS = 6 * 60 * 60 * 1e3;
7360
7454
  function probeRateLimit(args) {
7361
7455
  const now = args.now ?? /* @__PURE__ */ new Date();
@@ -7371,7 +7465,7 @@ function probeRateLimit(args) {
7371
7465
  let newest = UNKNOWN_RATE_LIMIT;
7372
7466
  for (const name of entries) {
7373
7467
  if (!name.endsWith(".jsonl")) continue;
7374
- const path = join30(dir, name);
7468
+ const path = join31(dir, name);
7375
7469
  try {
7376
7470
  const st = statSync5(path);
7377
7471
  if (!st.isFile() || st.mtimeMs < startMs) continue;
@@ -7380,7 +7474,7 @@ function probeRateLimit(args) {
7380
7474
  }
7381
7475
  let content;
7382
7476
  try {
7383
- content = readFileSync23(path, "utf-8");
7477
+ content = readFileSync24(path, "utf-8");
7384
7478
  } catch {
7385
7479
  continue;
7386
7480
  }
@@ -7442,7 +7536,7 @@ function shouldLogUsageCapDeferral(site, codeName, limitedUntil) {
7442
7536
 
7443
7537
  // src/lib/manager/scheduler/execution.ts
7444
7538
  function claudePidFilePath() {
7445
- return join31(homedir15(), ".augmented", "manager-claude-pids.json");
7539
+ return join32(homedir15(), ".augmented", "manager-claude-pids.json");
7446
7540
  }
7447
7541
  var inFlightClaudePids = /* @__PURE__ */ new Map();
7448
7542
  function registerClaudeSpawn(record) {
@@ -7513,7 +7607,7 @@ async function syncAndCheckClaudeScheduler(agent, tasks, boardItems, refreshData
7513
7607
 
7514
7608
  // src/lib/occupancy-gate.ts
7515
7609
  import { closeSync as closeSync2, openSync as openSync2, readdirSync as readdirSync6, readSync as readSync2, statSync as statSync6 } from "fs";
7516
- import { join as join32 } from "path";
7610
+ import { join as join33 } from "path";
7517
7611
  function rostersMeasuredZero(mode, attested, runtimeRunning) {
7518
7612
  return mode === "enforce" && attested && runtimeRunning;
7519
7613
  }
@@ -7604,10 +7698,10 @@ function candidateTranscriptPaths(dir) {
7604
7698
  let complete = true;
7605
7699
  for (const name of top) {
7606
7700
  if (name.endsWith(".jsonl")) {
7607
- paths.push(join32(dir, name));
7701
+ paths.push(join33(dir, name));
7608
7702
  continue;
7609
7703
  }
7610
- const subDir = join32(dir, name, "subagents");
7704
+ const subDir = join33(dir, name, "subagents");
7611
7705
  let subs;
7612
7706
  try {
7613
7707
  subs = readdirSync6(subDir);
@@ -7616,7 +7710,7 @@ function candidateTranscriptPaths(dir) {
7616
7710
  continue;
7617
7711
  }
7618
7712
  for (const sub of subs) {
7619
- if (sub.endsWith(".jsonl")) paths.push(join32(subDir, sub));
7713
+ if (sub.endsWith(".jsonl")) paths.push(join33(subDir, sub));
7620
7714
  }
7621
7715
  }
7622
7716
  return { paths, complete };
@@ -7843,7 +7937,7 @@ function stopPaneOccupancySampler() {
7843
7937
 
7844
7938
  // src/lib/pid-pressure-sampler.ts
7845
7939
  import { execFileSync as execFileSync2 } from "child_process";
7846
- import { existsSync as existsSync12, readFileSync as readFileSync24 } from "fs";
7940
+ import { existsSync as existsSync13, readFileSync as readFileSync25 } from "fs";
7847
7941
  var SAMPLE_INTERVAL_MS2 = 3e4;
7848
7942
  function warnFraction() {
7849
7943
  const raw = Number(process.env.AGT_PID_PRESSURE_WARN_FRACTION);
@@ -7856,7 +7950,7 @@ function configuredCeiling() {
7856
7950
  }
7857
7951
  function readTextReal(path) {
7858
7952
  try {
7859
- return readFileSync24(path, "utf-8");
7953
+ return readFileSync25(path, "utf-8");
7860
7954
  } catch {
7861
7955
  return null;
7862
7956
  }
@@ -7865,7 +7959,7 @@ var cgroupDirCache = /* @__PURE__ */ new Map();
7865
7959
  var resolveRetryAfter = /* @__PURE__ */ new Map();
7866
7960
  var RESOLVE_RETRY_BACKOFF_MS = 5 * 6e4;
7867
7961
  function resolveCgroupDirReal(codeName, deps = {}) {
7868
- const exists = deps.exists ?? existsSync12;
7962
+ const exists = deps.exists ?? existsSync13;
7869
7963
  const inspectId = deps.inspectId ?? inspectContainerId;
7870
7964
  const now = deps.now ?? Date.now;
7871
7965
  const cached = cgroupDirCache.get(codeName);
@@ -9164,9 +9258,9 @@ async function fireOpencodeScheduledTask(agent, task) {
9164
9258
 
9165
9259
  // src/lib/opencode-telegram-ingest.ts
9166
9260
  import { createHash as createHash16 } from "crypto";
9167
- import { existsSync as existsSync13, mkdirSync as mkdirSync8, readFileSync as readFileSync25, renameSync as renameSync6, unlinkSync as unlinkSync4, writeFileSync as writeFileSync11 } from "fs";
9261
+ import { existsSync as existsSync14, mkdirSync as mkdirSync8, readFileSync as readFileSync26, renameSync as renameSync6, unlinkSync as unlinkSync4, writeFileSync as writeFileSync11 } from "fs";
9168
9262
  import { randomUUID } from "crypto";
9169
- import { join as join33 } from "path";
9263
+ import { join as join34 } from "path";
9170
9264
 
9171
9265
  // src/lib/telegram-ingest.ts
9172
9266
  import https2 from "https";
@@ -9714,7 +9808,7 @@ function createFileOffsetStore(codeName, log2, currentBotId) {
9714
9808
  let filePath;
9715
9809
  try {
9716
9810
  dir = getFramework("opencode").getAgentDir(codeName);
9717
- filePath = join33(dir, "telegram-getupdates-offset-opencode.json");
9811
+ filePath = join34(dir, "telegram-getupdates-offset-opencode.json");
9718
9812
  } catch {
9719
9813
  dir = null;
9720
9814
  filePath = null;
@@ -9723,7 +9817,7 @@ function createFileOffsetStore(codeName, log2, currentBotId) {
9723
9817
  load() {
9724
9818
  if (!filePath) return 0;
9725
9819
  try {
9726
- const parsed = JSON.parse(readFileSync25(filePath, "utf-8"));
9820
+ const parsed = JSON.parse(readFileSync26(filePath, "utf-8"));
9727
9821
  if (currentBotId != null && typeof parsed?.bot_id === "number" && parsed.bot_id !== currentBotId) {
9728
9822
  log2(`[telegram-ingest:${codeName}] offset cursor belongs to a different bot; ignoring (bot swap)`);
9729
9823
  return 0;
@@ -9756,7 +9850,7 @@ function createFileOffsetStore(codeName, log2, currentBotId) {
9756
9850
  } catch (err) {
9757
9851
  log2(`[telegram-ingest:${codeName}] offset persist failed: ${err instanceof Error ? err.message : String(err)}`);
9758
9852
  try {
9759
- if (existsSync13(tmpPath)) unlinkSync4(tmpPath);
9853
+ if (existsSync14(tmpPath)) unlinkSync4(tmpPath);
9760
9854
  } catch {
9761
9855
  }
9762
9856
  }
@@ -9993,24 +10087,24 @@ function partitionActionableByPoison(actionable, states, config2) {
9993
10087
  }
9994
10088
 
9995
10089
  // src/lib/restart-flags.ts
9996
- import { existsSync as existsSync14, mkdirSync as mkdirSync9, readdirSync as readdirSync7, readFileSync as readFileSync26, renameSync as renameSync7, rmSync as rmSync4, writeFileSync as writeFileSync12 } from "fs";
10090
+ import { existsSync as existsSync15, mkdirSync as mkdirSync9, readdirSync as readdirSync7, readFileSync as readFileSync27, renameSync as renameSync7, rmSync as rmSync4, writeFileSync as writeFileSync12 } from "fs";
9997
10091
  import { homedir as homedir16 } from "os";
9998
- import { join as join34 } from "path";
10092
+ import { join as join35 } from "path";
9999
10093
  import { randomUUID as randomUUID2 } from "crypto";
10000
10094
  function restartFlagsDir() {
10001
- return join34(homedir16(), ".augmented", "restart-flags");
10095
+ return join35(homedir16(), ".augmented", "restart-flags");
10002
10096
  }
10003
10097
  function flagPath(codeName) {
10004
- return join34(restartFlagsDir(), `${codeName}.flag`);
10098
+ return join35(restartFlagsDir(), `${codeName}.flag`);
10005
10099
  }
10006
10100
  function readRestartFlags() {
10007
10101
  const dir = restartFlagsDir();
10008
- if (!existsSync14(dir)) return [];
10102
+ if (!existsSync15(dir)) return [];
10009
10103
  const out = [];
10010
10104
  for (const entry of readdirSync7(dir)) {
10011
10105
  if (!entry.endsWith(".flag")) continue;
10012
10106
  try {
10013
- const raw = readFileSync26(join34(dir, entry), "utf8");
10107
+ const raw = readFileSync27(join35(dir, entry), "utf8");
10014
10108
  const parsed = JSON.parse(raw);
10015
10109
  if (typeof parsed.codeName !== "string" || parsed.codeName.length === 0) {
10016
10110
  parsed.codeName = entry.replace(/\.flag$/, "");
@@ -10028,7 +10122,7 @@ function readRestartFlags() {
10028
10122
  }
10029
10123
  function deleteRestartFlag(codeName) {
10030
10124
  const path = flagPath(codeName);
10031
- if (existsSync14(path)) {
10125
+ if (existsSync15(path)) {
10032
10126
  rmSync4(path, { force: true });
10033
10127
  }
10034
10128
  }
@@ -10128,8 +10222,8 @@ async function sendError(flag, opts, text) {
10128
10222
  }
10129
10223
 
10130
10224
  // src/lib/restart-context.ts
10131
- import { readdirSync as readdirSync8, readFileSync as readFileSync27, writeFileSync as writeFileSync13, mkdirSync as mkdirSync10, unlinkSync as unlinkSync5 } from "fs";
10132
- import { dirname as dirname9, join as join35 } from "path";
10225
+ import { readdirSync as readdirSync8, readFileSync as readFileSync28, writeFileSync as writeFileSync13, mkdirSync as mkdirSync10, unlinkSync as unlinkSync5 } from "fs";
10226
+ import { dirname as dirname9, join as join36 } from "path";
10133
10227
  var SLACK_PENDING_INBOUND_DIRNAME = "slack-pending-inbound";
10134
10228
  var SLACK_RESTART_CONTEXT_DIRNAME = "slack-restart-context";
10135
10229
  var MAX_TOPIC_CHARS = 140;
@@ -10141,10 +10235,10 @@ function augmentedAgentDir(codeName) {
10141
10235
  return dirname9(getProjectDir(codeName));
10142
10236
  }
10143
10237
  function slackPendingInboundDir(codeName) {
10144
- return join35(augmentedAgentDir(codeName), SLACK_PENDING_INBOUND_DIRNAME);
10238
+ return join36(augmentedAgentDir(codeName), SLACK_PENDING_INBOUND_DIRNAME);
10145
10239
  }
10146
10240
  function slackRestartContextDir(codeName) {
10147
- return join35(augmentedAgentDir(codeName), SLACK_RESTART_CONTEXT_DIRNAME);
10241
+ return join36(augmentedAgentDir(codeName), SLACK_RESTART_CONTEXT_DIRNAME);
10148
10242
  }
10149
10243
  function sanitizeTopic(raw) {
10150
10244
  const cleaned = raw.replace(/\s+/g, " ").trim().replace(/[<>]/g, " ").replace(/\s+/g, " ").trim();
@@ -10186,7 +10280,7 @@ function safeReaddir(dir) {
10186
10280
  }
10187
10281
  function readStrandedMarker(path) {
10188
10282
  try {
10189
- const parsed = JSON.parse(readFileSync27(path, "utf-8"));
10283
+ const parsed = JSON.parse(readFileSync28(path, "utf-8"));
10190
10284
  if (typeof parsed.channel === "string" && typeof parsed.thread_ts === "string") {
10191
10285
  return { channel: parsed.channel, thread_ts: parsed.thread_ts };
10192
10286
  }
@@ -10204,7 +10298,7 @@ function pruneHintsExcept(codeName, freshFilenames) {
10204
10298
  if (!filename.endsWith(".json")) continue;
10205
10299
  if (freshFilenames.has(filename)) continue;
10206
10300
  try {
10207
- unlinkSync5(join35(ctxDir, filename));
10301
+ unlinkSync5(join36(ctxDir, filename));
10208
10302
  } catch {
10209
10303
  }
10210
10304
  }
@@ -10225,7 +10319,7 @@ function refreshSlackRestartContextHints(codeNames, opts = {}) {
10225
10319
  }
10226
10320
  const markers = [];
10227
10321
  for (const filename of markerFilenames.slice(0, cap)) {
10228
- const parsed = readStrandedMarker(join35(markerDir, filename));
10322
+ const parsed = readStrandedMarker(join36(markerDir, filename));
10229
10323
  if (parsed) markers.push({ filename, channel: parsed.channel, thread_ts: parsed.thread_ts });
10230
10324
  }
10231
10325
  if (markers.length === 0) {
@@ -10239,7 +10333,7 @@ function refreshSlackRestartContextHints(codeNames, opts = {}) {
10239
10333
  const freshFilenames = /* @__PURE__ */ new Set();
10240
10334
  for (const { filename, hint } of hints) {
10241
10335
  try {
10242
- writeHintFile(join35(ctxDir, filename), ctxDir, hint);
10336
+ writeHintFile(join36(ctxDir, filename), ctxDir, hint);
10243
10337
  freshFilenames.add(filename);
10244
10338
  } catch (err) {
10245
10339
  log2(`[restart-context] ${codeName}: hint write failed for ${filename}: ${err.message}`);
@@ -11617,7 +11711,7 @@ var pendingDayRolloverReset = /* @__PURE__ */ new Set();
11617
11711
  var dayRolloverInboundHold = /* @__PURE__ */ new Map();
11618
11712
  var INBOUND_HOLD_EPISODE_GAP_MS = 12e4;
11619
11713
  async function channelInboundActivityAgeSecondsFor(codeName) {
11620
- const { newestPendingInboundActivityMtimeMs } = await import("../responsiveness-probe-7465YNMN.js");
11714
+ const { newestPendingInboundActivityMtimeMs } = await import("../responsiveness-probe-ZHE7S6G4.js");
11621
11715
  const newest = newestPendingInboundActivityMtimeMs(dirname10(paneLogPath(codeName)));
11622
11716
  if (newest === null) return null;
11623
11717
  return Math.max(0, Math.floor((Date.now() - newest) / 1e3));
@@ -11867,7 +11961,7 @@ var runningChannelSecretHashes = /* @__PURE__ */ new Map();
11867
11961
  var sessionLaunchManagedStructure = /* @__PURE__ */ new Map();
11868
11962
  function projectMcpHash(_codeName, projectDir) {
11869
11963
  try {
11870
- const raw = readFileSync28(join36(projectDir, ".mcp.json"), "utf-8");
11964
+ const raw = readFileSync29(join37(projectDir, ".mcp.json"), "utf-8");
11871
11965
  return createHash17("sha256").update(canonicalJson(JSON.parse(raw))).digest("hex");
11872
11966
  } catch {
11873
11967
  return null;
@@ -11875,7 +11969,7 @@ function projectMcpHash(_codeName, projectDir) {
11875
11969
  }
11876
11970
  function projectMcpKeys(_codeName, projectDir) {
11877
11971
  try {
11878
- const raw = readFileSync28(join36(projectDir, ".mcp.json"), "utf-8");
11972
+ const raw = readFileSync29(join37(projectDir, ".mcp.json"), "utf-8");
11879
11973
  const parsed = JSON.parse(raw);
11880
11974
  const servers = parsed.mcpServers;
11881
11975
  if (!servers || typeof servers !== "object") return /* @__PURE__ */ new Set();
@@ -11893,7 +11987,7 @@ function seedSessionLaunchBaselines(codeName, projectDir) {
11893
11987
  else runningMcpServerKeys.delete(codeName);
11894
11988
  let launchStructure = null;
11895
11989
  try {
11896
- const raw = readFileSync28(join36(projectDir, ".mcp.json"), "utf-8");
11990
+ const raw = readFileSync29(join37(projectDir, ".mcp.json"), "utf-8");
11897
11991
  launchStructure = managedMcpStructureHashFromFile(
11898
11992
  JSON.parse(raw),
11899
11993
  isManagedMcpServerKey
@@ -12019,7 +12113,7 @@ async function runAgentSessionToolBindProbes(agent, integrations, projectDir, op
12019
12113
  if (result && result.rebindCandidates.length > 0 && hostFlagStore().getBoolean("session-tool-rebind")) {
12020
12114
  let mcpJsonForRebind = null;
12021
12115
  try {
12022
- mcpJsonForRebind = JSON.parse(readFileSync28(join36(projectDir, ".mcp.json"), "utf-8"));
12116
+ mcpJsonForRebind = JSON.parse(readFileSync29(join37(projectDir, ".mcp.json"), "utf-8"));
12023
12117
  } catch {
12024
12118
  mcpJsonForRebind = null;
12025
12119
  }
@@ -12167,7 +12261,7 @@ function shouldInjectChannelSecrets(agentId) {
12167
12261
  function projectChannelSecretHash(projectDir) {
12168
12262
  try {
12169
12263
  const entries = parseEnvIntegrations(
12170
- readFileSync28(join36(projectDir, ".env.integrations"), "utf-8")
12264
+ readFileSync29(join37(projectDir, ".env.integrations"), "utf-8")
12171
12265
  );
12172
12266
  return channelSecretValueHash(entries, CHANNEL_SECRET_ENV_KEYS);
12173
12267
  } catch {
@@ -12265,7 +12359,7 @@ var agentRestartTimezoneInputs = /* @__PURE__ */ new Map();
12265
12359
  var lastVersionCheckAt = 0;
12266
12360
  var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
12267
12361
  var lastResponsivenessProbeAt = 0;
12268
- var agtCliVersion = true ? "0.28.675" : "dev";
12362
+ var agtCliVersion = true ? "0.28.677" : "dev";
12269
12363
  function resolveBrewPath(execFileSync3) {
12270
12364
  try {
12271
12365
  const out = execFileSync3("which", ["brew"], { timeout: 5e3 }).toString().trim();
@@ -12278,7 +12372,7 @@ function resolveBrewPath(execFileSync3) {
12278
12372
  "/usr/local/bin/brew"
12279
12373
  ];
12280
12374
  for (const path of fallbacks) {
12281
- if (existsSync15(path)) return path;
12375
+ if (existsSync16(path)) return path;
12282
12376
  }
12283
12377
  return null;
12284
12378
  }
@@ -12288,7 +12382,7 @@ function claudeBinaryInstalled(execFileSync3) {
12288
12382
  "/opt/homebrew/bin/claude",
12289
12383
  "/usr/local/bin/claude"
12290
12384
  ];
12291
- if (canonical.some((path) => existsSync15(path))) return true;
12385
+ if (canonical.some((path) => existsSync16(path))) return true;
12292
12386
  try {
12293
12387
  execFileSync3("which", ["claude"], { timeout: 5e3 });
12294
12388
  return true;
@@ -12598,8 +12692,8 @@ var MANAGED_SETTINGS_KEYS = ["channelsEnabled", "enableAllProjectMcpServers"];
12598
12692
  function ensureClaudeManagedSettings(path = claudeManagedSettingsPath()) {
12599
12693
  try {
12600
12694
  let settings = {};
12601
- if (existsSync15(path)) {
12602
- const raw = readFileSync28(path, "utf-8").trim();
12695
+ if (existsSync16(path)) {
12696
+ const raw = readFileSync29(path, "utf-8").trim();
12603
12697
  if (raw) {
12604
12698
  let parsed;
12605
12699
  try {
@@ -12655,7 +12749,7 @@ async function ensureOpencodeBinary() {
12655
12749
  try {
12656
12750
  const prefix = execFileSync3("npm", ["prefix", "-g"], { encoding: "utf-8", timeout: 1e4 }).trim();
12657
12751
  if (prefix) {
12658
- const npmBin = join36(prefix, "bin");
12752
+ const npmBin = join37(prefix, "bin");
12659
12753
  const current = (process.env.PATH ?? "").split(pathDelimiter);
12660
12754
  if (!current.includes(npmBin)) {
12661
12755
  process.env.PATH = [npmBin, ...current.filter(Boolean)].join(pathDelimiter);
@@ -12716,7 +12810,7 @@ async function ensureFrameworkBinary(frameworkId) {
12716
12810
  if (!process.env.PATH?.split(":").includes(brewBinDir)) {
12717
12811
  process.env.PATH = `${brewBinDir}:${process.env.PATH ?? ""}`;
12718
12812
  }
12719
- if (existsSync15("/home/linuxbrew/.linuxbrew/bin/claude")) {
12813
+ if (existsSync16("/home/linuxbrew/.linuxbrew/bin/claude")) {
12720
12814
  log("Claude Code installed successfully");
12721
12815
  } else {
12722
12816
  log("Claude Code install completed but binary not found at expected path \u2014 check brew logs");
@@ -12772,7 +12866,7 @@ ${r.stderr}`;
12772
12866
  }
12773
12867
  var UPDATE_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
12774
12868
  function selfUpdateAppliedMarkerPath() {
12775
- return join36(homedir17(), ".augmented", ".last-self-update-applied");
12869
+ return join37(homedir17(), ".augmented", ".last-self-update-applied");
12776
12870
  }
12777
12871
  var selfUpdateUpToDateLogged = false;
12778
12872
  var selfUpdatePinnedLogged = false;
@@ -12823,7 +12917,7 @@ async function checkAndUpdateCli(opts) {
12823
12917
  const isNpmGlobal = !isBrewFormula && resolvedPath.includes("node_modules");
12824
12918
  if (!isBrewFormula && !isNpmGlobal) return "noop";
12825
12919
  const { readFileSync: readF, writeFileSync: writeF } = await import("fs");
12826
- const markerPath = join36(homedir17(), ".augmented", ".last-update-check");
12920
+ const markerPath = join37(homedir17(), ".augmented", ".last-update-check");
12827
12921
  if (!force) {
12828
12922
  try {
12829
12923
  const lastCheck = parseInt(readF(markerPath, "utf-8").trim(), 10);
@@ -13276,13 +13370,13 @@ async function checkClaudeAuth() {
13276
13370
  }
13277
13371
  var evalEmptyMcpConfigPath = null;
13278
13372
  function ensureEvalEmptyMcpConfig() {
13279
- if (evalEmptyMcpConfigPath && existsSync15(evalEmptyMcpConfigPath)) return evalEmptyMcpConfigPath;
13280
- const dir = join36(homedir17(), ".augmented");
13373
+ if (evalEmptyMcpConfigPath && existsSync16(evalEmptyMcpConfigPath)) return evalEmptyMcpConfigPath;
13374
+ const dir = join37(homedir17(), ".augmented");
13281
13375
  try {
13282
13376
  mkdirSync11(dir, { recursive: true });
13283
13377
  } catch {
13284
13378
  }
13285
- const p = join36(dir, ".eval-empty-mcp.json");
13379
+ const p = join37(dir, ".eval-empty-mcp.json");
13286
13380
  writeFileSync14(p, JSON.stringify({ mcpServers: {} }));
13287
13381
  evalEmptyMcpConfigPath = p;
13288
13382
  return p;
@@ -13377,10 +13471,10 @@ function resolveConversationEvalBackend() {
13377
13471
  return conversationEvalBackend;
13378
13472
  }
13379
13473
  function getStateFile() {
13380
- return join36(config?.configDir ?? join36(process.env["HOME"] ?? "/tmp", ".augmented"), "manager-state.json");
13474
+ return join37(config?.configDir ?? join37(process.env["HOME"] ?? "/tmp", ".augmented"), "manager-state.json");
13381
13475
  }
13382
13476
  function channelHashCacheDir() {
13383
- return config?.configDir ?? join36(process.env["HOME"] ?? "/tmp", ".augmented");
13477
+ return config?.configDir ?? join37(process.env["HOME"] ?? "/tmp", ".augmented");
13384
13478
  }
13385
13479
  function loadChannelHashCache2() {
13386
13480
  loadChannelHashCache(agentState.knownChannelConfigHashes, channelHashCacheDir());
@@ -13468,6 +13562,81 @@ function saveDeliveryBaseline() {
13468
13562
  function flushDeliveryBaselineIfDirty() {
13469
13563
  if (deliveryBaselineDirty) saveDeliveryBaseline();
13470
13564
  }
13565
+ var stuckStreakSidecarDirty = false;
13566
+ var lastStuckStreakSignature = "";
13567
+ function snapshotStuckStreaks() {
13568
+ const maps = createStuckStreakMaps();
13569
+ for (const [agentId, s] of channelSyncFailures) {
13570
+ maps.channelSync.set(agentId, {
13571
+ attempts: s.attempts,
13572
+ since: s.since,
13573
+ nextAttemptAt: s.nextAttemptAt,
13574
+ loggedAtAttempt: s.loggedAtAttempt,
13575
+ detail: s.lastReason
13576
+ });
13577
+ }
13578
+ for (const [agentId, s] of realtimeRebindFailures) {
13579
+ maps.realtimeRebind.set(agentId, {
13580
+ attempts: s.attempts,
13581
+ since: s.since,
13582
+ nextAttemptAt: s.nextAttemptAt,
13583
+ loggedAtAttempt: s.loggedAtAttempt,
13584
+ detail: s.lastStatus
13585
+ });
13586
+ }
13587
+ return maps;
13588
+ }
13589
+ function flushStuckStreaksIfChanged() {
13590
+ const maps = snapshotStuckStreaks();
13591
+ const signature = JSON.stringify([
13592
+ [...maps.channelSync].map(([id, s]) => [id, s.since, s.attempts, s.detail]),
13593
+ [...maps.realtimeRebind].map(([id, s]) => [id, s.since, s.attempts, s.detail])
13594
+ ]);
13595
+ if (signature === lastStuckStreakSignature && !stuckStreakSidecarDirty) return;
13596
+ const wrote = saveStuckStreaks(maps, channelHashCacheDir(), log);
13597
+ stuckStreakSidecarDirty = !wrote;
13598
+ if (wrote) lastStuckStreakSignature = signature;
13599
+ }
13600
+ function loadStuckStreaks2() {
13601
+ const maps = createStuckStreakMaps();
13602
+ loadStuckStreaks(maps, channelHashCacheDir(), log);
13603
+ for (const [agentId, s] of maps.channelSync) {
13604
+ channelSyncFailures.set(agentId, {
13605
+ attempts: s.attempts,
13606
+ since: s.since,
13607
+ lastReason: s.detail,
13608
+ loggedAtAttempt: s.loggedAtAttempt,
13609
+ nextAttemptAt: s.nextAttemptAt
13610
+ });
13611
+ }
13612
+ for (const [agentId, s] of maps.realtimeRebind) {
13613
+ realtimeRebindFailures.set(agentId, {
13614
+ attempts: s.attempts,
13615
+ since: s.since,
13616
+ lastStatus: s.detail,
13617
+ loggedAtAttempt: s.loggedAtAttempt,
13618
+ nextAttemptAt: s.nextAttemptAt
13619
+ });
13620
+ }
13621
+ const restored = channelSyncFailures.size + realtimeRebindFailures.size;
13622
+ if (restored > 0) {
13623
+ log(
13624
+ `[stuck-streaks] restored ${channelSyncFailures.size} channel-sync and ${realtimeRebindFailures.size} rebind streak(s) across the manager restart \u2014 their ages continue rather than restarting (ENG-9346)`
13625
+ );
13626
+ }
13627
+ }
13628
+ function pruneStuckStreaksToActiveAgents(activeAgentIds) {
13629
+ if (activeAgentIds.length === 0) return;
13630
+ const dropped = pruneStuckStreaksToAgents(snapshotStuckStreaks(), new Set(activeAgentIds));
13631
+ if (dropped.length === 0) return;
13632
+ for (const agentId of dropped) {
13633
+ channelSyncFailures.delete(agentId);
13634
+ realtimeRebindFailures.delete(agentId);
13635
+ }
13636
+ log(
13637
+ `[stuck-streaks] dropped ${dropped.length} persisted streak(s) for agent(s) no longer on this host (ENG-9346)`
13638
+ );
13639
+ }
13471
13640
  function persistDeliveryBaselineEntry(concern, agentId, hash) {
13472
13641
  if (hash === void 0) return;
13473
13642
  if (persistedDeliveryBaseline[concern].get(agentId) === hash && !deliveryBaselineDirty) return;
@@ -13488,7 +13657,7 @@ function removeDeliveryBaselineEntries(agentId) {
13488
13657
  var _channelQuarantineStore = null;
13489
13658
  function channelQuarantineStore() {
13490
13659
  if (!_channelQuarantineStore) {
13491
- const dir = config?.configDir ?? join36(process.env["HOME"] ?? "/tmp", ".augmented");
13660
+ const dir = config?.configDir ?? join37(process.env["HOME"] ?? "/tmp", ".augmented");
13492
13661
  _channelQuarantineStore = new ChannelQuarantineStore(defaultQuarantinePath(dir));
13493
13662
  }
13494
13663
  return _channelQuarantineStore;
@@ -13505,7 +13674,7 @@ function claudeMdSizeFor(codeName) {
13505
13674
  var _hostFlagStore = null;
13506
13675
  function hostFlagStore() {
13507
13676
  if (!_hostFlagStore) {
13508
- const dir = config?.configDir ?? join36(process.env["HOME"] ?? "/tmp", ".augmented");
13677
+ const dir = config?.configDir ?? join37(process.env["HOME"] ?? "/tmp", ".augmented");
13509
13678
  _hostFlagStore = new HostFlagStore({ cachePath: defaultFlagsCachePath(dir), log });
13510
13679
  }
13511
13680
  return _hostFlagStore;
@@ -13579,12 +13748,12 @@ function parseSkillFrontmatter(content) {
13579
13748
  }
13580
13749
  async function refreshSkillsIndexInClaudeMd(configDir, codeName, log2) {
13581
13750
  const { readdirSync: readdirSync10, readFileSync: rfs, existsSync: ex, writeFileSync: writeFileSync15 } = await import("fs");
13582
- const skillsDir = join36(configDir, codeName, "project", ".claude", "skills");
13583
- const claudeMdPath = join36(configDir, codeName, "project", "CLAUDE.md");
13751
+ const skillsDir = join37(configDir, codeName, "project", ".claude", "skills");
13752
+ const claudeMdPath = join37(configDir, codeName, "project", "CLAUDE.md");
13584
13753
  if (!ex(skillsDir) || !ex(claudeMdPath)) return;
13585
13754
  const entries = [];
13586
13755
  for (const dir of readdirSync10(skillsDir).sort()) {
13587
- const skillFile = join36(skillsDir, dir, "SKILL.md");
13756
+ const skillFile = join37(skillsDir, dir, "SKILL.md");
13588
13757
  if (!ex(skillFile)) continue;
13589
13758
  try {
13590
13759
  const { name, description } = parseSkillFrontmatter(rfs(skillFile, "utf-8"));
@@ -13651,7 +13820,7 @@ function flushRestartedAgentDiagnostics(hostId, codeNames) {
13651
13820
  if (codeNames.length === 0) return;
13652
13821
  void (async () => {
13653
13822
  try {
13654
- const { collectDiagnostics } = await import("../persistent-session-F7JEOWHQ.js");
13823
+ const { collectDiagnostics } = await import("../persistent-session-TMOTEVV6.js");
13655
13824
  await api.post("/host/heartbeat", {
13656
13825
  host_id: hostId,
13657
13826
  agent_diagnostics: collectDiagnostics(codeNames, quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor)
@@ -13673,6 +13842,7 @@ async function pollCycleInner() {
13673
13842
  if (!config) return;
13674
13843
  if (restartAfterUpgrade) return;
13675
13844
  flushDeliveryBaselineIfDirty();
13845
+ flushStuckStreaksIfChanged();
13676
13846
  try {
13677
13847
  await processRestartFlags({
13678
13848
  log,
@@ -13767,7 +13937,7 @@ async function pollCycleInner() {
13767
13937
  }
13768
13938
  try {
13769
13939
  const { detectHostSecurity } = await import("../host-security-6PDFG7F5.js");
13770
- const { collectDiagnostics } = await import("../persistent-session-F7JEOWHQ.js");
13940
+ const { collectDiagnostics } = await import("../persistent-session-TMOTEVV6.js");
13771
13941
  const diagCodeNames = [...agentState.persistentSessionAgents];
13772
13942
  const agentDiagnostics = diagCodeNames.length > 0 ? collectDiagnostics(diagCodeNames, quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor) : void 0;
13773
13943
  let tailscaleHostname;
@@ -13919,7 +14089,7 @@ async function pollCycleInner() {
13919
14089
  collectPanelessActivityProbes,
13920
14090
  getResponsivenessIntervalMs,
13921
14091
  occupancyQualificationClassifications
13922
- } = await import("../responsiveness-probe-7465YNMN.js");
14092
+ } = await import("../responsiveness-probe-ZHE7S6G4.js");
13923
14093
  const probeIntervalMs = getResponsivenessIntervalMs();
13924
14094
  if (now - lastResponsivenessProbeAt > probeIntervalMs) {
13925
14095
  const probeCodeNames = [...agentState.persistentSessionAgents];
@@ -14029,7 +14199,7 @@ async function pollCycleInner() {
14029
14199
  collectResponsivenessProbes,
14030
14200
  livePendingInboundOldestAgeSeconds,
14031
14201
  parkPendingInbound
14032
- } = await import("../responsiveness-probe-7465YNMN.js");
14202
+ } = await import("../responsiveness-probe-ZHE7S6G4.js");
14033
14203
  const { getProjectDir: wedgeProjectDir } = await import("../scheduler-engine-NDP36U7O.js");
14034
14204
  const wedgeNow = /* @__PURE__ */ new Date();
14035
14205
  const liveAgents = agentState.persistentSessionAgents;
@@ -14118,13 +14288,13 @@ async function pollCycleInner() {
14118
14288
  );
14119
14289
  if (hostFlagStore().getBoolean("wedge-transient-notice")) {
14120
14290
  try {
14121
- const paneTail = readFileSync28(paneLogPath(codeName), "utf8").slice(-65536);
14291
+ const paneTail = readFileSync29(paneLogPath(codeName), "utf8").slice(-65536);
14122
14292
  const transient = detectTransientApiErrorInLog(paneTail);
14123
14293
  if (transient) {
14124
- const wedgeHome = join36(homedir17(), ".augmented", codeName);
14125
- if (existsSync15(wedgeHome)) {
14294
+ const wedgeHome = join37(homedir17(), ".augmented", codeName);
14295
+ if (existsSync16(wedgeHome)) {
14126
14296
  atomicWriteFileSync(
14127
- join36(wedgeHome, "watchdog-give-up.json"),
14297
+ join37(wedgeHome, "watchdog-give-up.json"),
14128
14298
  JSON.stringify({
14129
14299
  gave_up_at: wedgeNow.toISOString(),
14130
14300
  reason: "transient_overload"
@@ -14185,7 +14355,7 @@ async function pollCycleInner() {
14185
14355
  }
14186
14356
  try {
14187
14357
  const { scrapeMcpFailedBannerCount } = await import("../pane-mcp-banner-scraper-JA437JIB.js");
14188
- const { probeSessionAuth } = await import("../session-auth-dead-GBC5QPH3.js");
14358
+ const { probeSessionAuth } = await import("../session-auth-dead-JCKENEY5.js");
14189
14359
  const observations = [];
14190
14360
  const pendingCacheCommits = [];
14191
14361
  const modelApiErrorReportingOn = hostFlagStore().getBoolean("model-api-error-reporting");
@@ -14421,7 +14591,7 @@ async function pollCycleInner() {
14421
14591
  const adapter = resolveAgentFramework(prev.codeName);
14422
14592
  stopAgentRuntime2(prev.codeName, "removed-from-host");
14423
14593
  killAgentChannelProcesses(prev.codeName, { log });
14424
- const agentDir = join36(adapter.getAgentDir(prev.codeName), "provision");
14594
+ const agentDir = join37(adapter.getAgentDir(prev.codeName), "provision");
14425
14595
  await cleanupAgentFiles(prev.codeName, agentDir);
14426
14596
  clearAgentCaches(prev.agentId, prev.codeName);
14427
14597
  }
@@ -14508,10 +14678,10 @@ async function pollCycleInner() {
14508
14678
  // pending-inbound marker. Best-effort: a write failure is logged by
14509
14679
  // the watchdog, never fails the poll cycle.
14510
14680
  signalGiveUp: (codeName) => {
14511
- const dir = join36(homedir17(), ".augmented", codeName);
14512
- if (!existsSync15(dir)) return;
14681
+ const dir = join37(homedir17(), ".augmented", codeName);
14682
+ if (!existsSync16(dir)) return;
14513
14683
  atomicWriteFileSync(
14514
- join36(dir, "watchdog-give-up.json"),
14684
+ join37(dir, "watchdog-give-up.json"),
14515
14685
  JSON.stringify({ gave_up_at: (/* @__PURE__ */ new Date()).toISOString() })
14516
14686
  );
14517
14687
  },
@@ -14530,9 +14700,9 @@ async function pollCycleInner() {
14530
14700
  // parser elsewhere can only reconstruct an hour (ENG-8901).
14531
14701
  signalUsageLimit: (codeName, resetsHint) => {
14532
14702
  const dir = getFramework("claude-code").getAgentDir(codeName);
14533
- if (!existsSync15(dir)) return;
14703
+ if (!existsSync16(dir)) return;
14534
14704
  atomicWriteFileSync(
14535
- join36(dir, "watchdog-give-up.json"),
14705
+ join37(dir, "watchdog-give-up.json"),
14536
14706
  JSON.stringify({
14537
14707
  gave_up_at: (/* @__PURE__ */ new Date()).toISOString(),
14538
14708
  reason: "usage_limit",
@@ -14794,7 +14964,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
14794
14964
  }
14795
14965
  const now = (/* @__PURE__ */ new Date()).toISOString();
14796
14966
  const adapter = resolveAgentFramework(agent.code_name);
14797
- let agentDir = join36(adapter.getAgentDir(agent.code_name), "provision");
14967
+ let agentDir = join37(adapter.getAgentDir(agent.code_name), "provision");
14798
14968
  if (agent.status === "draft" || agent.status === "paused") {
14799
14969
  forgetChannelSyncState(agent.agent_id);
14800
14970
  if (previousKnownStatus !== agent.status) {
@@ -14835,7 +15005,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
14835
15005
  const residuals = {
14836
15006
  gatewayRunning: false,
14837
15007
  portAllocated: false,
14838
- provisionDirExists: existsSync15(agentDir)
15008
+ provisionDirExists: existsSync16(agentDir)
14839
15009
  };
14840
15010
  if (!hasRevokedResiduals(residuals)) {
14841
15011
  agentStates.push({
@@ -14969,7 +15139,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
14969
15139
  const frameworkId = refreshData.agent.framework ?? DEFAULT_FRAMEWORK;
14970
15140
  agentFrameworkCache.set(agent.code_name, frameworkId);
14971
15141
  const frameworkAdapter = getFramework(frameworkId);
14972
- agentDir = join36(frameworkAdapter.getAgentDir(agent.code_name), "provision");
15142
+ agentDir = join37(frameworkAdapter.getAgentDir(agent.code_name), "provision");
14973
15143
  cacheAgentDeliveryMetadata(agent.code_name, refreshData);
14974
15144
  agentRestartTimezoneInputs.set(agent.code_name, {
14975
15145
  agentTimezone: typeof refreshData.agent.timezone === "string" ? refreshData.agent.timezone : null,
@@ -15027,7 +15197,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
15027
15197
  const changedFiles = [];
15028
15198
  mkdirSync11(agentDir, { recursive: true });
15029
15199
  for (const artifact of artifacts) {
15030
- const filePath = join36(agentDir, artifact.relativePath);
15200
+ const filePath = join37(agentDir, artifact.relativePath);
15031
15201
  let existingHash;
15032
15202
  let newHash;
15033
15203
  let writeContent = artifact.content;
@@ -15046,8 +15216,8 @@ async function processAgent(agent, agentStates, managedToolkits) {
15046
15216
  };
15047
15217
  newHash = sha256(stripDynamicSections(artifact.content));
15048
15218
  try {
15049
- const projectClaudeMd = join36(config.configDir, agent.code_name, "project", "CLAUDE.md");
15050
- const existing = readFileSync28(projectClaudeMd, "utf-8");
15219
+ const projectClaudeMd = join37(config.configDir, agent.code_name, "project", "CLAUDE.md");
15220
+ const existing = readFileSync29(projectClaudeMd, "utf-8");
15051
15221
  existingHash = sha256(stripDynamicSections(existing));
15052
15222
  } catch {
15053
15223
  existingHash = null;
@@ -15065,7 +15235,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
15065
15235
  const generatorKeys = Object.keys(generatorServers);
15066
15236
  let existingRaw = "";
15067
15237
  try {
15068
- existingRaw = readFileSync28(filePath, "utf-8");
15238
+ existingRaw = readFileSync29(filePath, "utf-8");
15069
15239
  } catch {
15070
15240
  }
15071
15241
  const existingServers = parseMcp(existingRaw);
@@ -15081,7 +15251,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
15081
15251
  } else if (artifact.relativePath === "opencode.json") {
15082
15252
  let existingRaw = null;
15083
15253
  try {
15084
- existingRaw = readFileSync28(filePath, "utf-8");
15254
+ existingRaw = readFileSync29(filePath, "utf-8");
15085
15255
  } catch {
15086
15256
  }
15087
15257
  const mergeResult = mergeOpencodeConfigArtifact(artifact.content, existingRaw);
@@ -15097,12 +15267,12 @@ async function processAgent(agent, agentStates, managedToolkits) {
15097
15267
  }
15098
15268
  }
15099
15269
  if (changedFiles.length > 0) {
15100
- const isFirst = !existsSync15(join36(agentDir, "CHARTER.md"));
15270
+ const isFirst = !existsSync16(join37(agentDir, "CHARTER.md"));
15101
15271
  const verb = isFirst ? "Provisioning" : "Updating";
15102
15272
  const fileNames = changedFiles.map((f) => f.relativePath).join(", ");
15103
15273
  log(`${verb} '${agent.code_name}': ${fileNames}`);
15104
15274
  for (const file of changedFiles) {
15105
- const filePath = join36(agentDir, file.relativePath);
15275
+ const filePath = join37(agentDir, file.relativePath);
15106
15276
  mkdirSync11(dirname10(filePath), { recursive: true });
15107
15277
  if (file.relativePath === ".mcp.json") {
15108
15278
  safeWriteJsonAtomic(filePath, file.content, { mode: 384 });
@@ -15111,12 +15281,12 @@ async function processAgent(agent, agentStates, managedToolkits) {
15111
15281
  }
15112
15282
  }
15113
15283
  try {
15114
- const provSkillsDir = join36(agentDir, ".claude", "skills");
15115
- if (existsSync15(provSkillsDir)) {
15284
+ const provSkillsDir = join37(agentDir, ".claude", "skills");
15285
+ if (existsSync16(provSkillsDir)) {
15116
15286
  for (const folder of readdirSync9(provSkillsDir)) {
15117
15287
  if (folder.startsWith("knowledge-")) {
15118
15288
  try {
15119
- rmSync5(join36(provSkillsDir, folder), { recursive: true });
15289
+ rmSync5(join37(provSkillsDir, folder), { recursive: true });
15120
15290
  } catch {
15121
15291
  }
15122
15292
  }
@@ -15129,7 +15299,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
15129
15299
  const trackedFiles2 = frameworkAdapter.driftTrackedFiles();
15130
15300
  const hashes = /* @__PURE__ */ new Map();
15131
15301
  for (const file of trackedFiles2) {
15132
- const h = hashFile(join36(agentDir, file));
15302
+ const h = hashFile(join37(agentDir, file));
15133
15303
  if (h) hashes.set(file, h);
15134
15304
  }
15135
15305
  agentState.writtenHashes.set(agent.agent_id, hashes);
@@ -15147,14 +15317,14 @@ async function processAgent(agent, agentStates, managedToolkits) {
15147
15317
  }
15148
15318
  if (Array.isArray(refreshData.workflows)) {
15149
15319
  try {
15150
- const provWorkflowsDir = join36(agentDir, ".claude", "workflows");
15151
- if (existsSync15(provWorkflowsDir)) {
15320
+ const provWorkflowsDir = join37(agentDir, ".claude", "workflows");
15321
+ if (existsSync16(provWorkflowsDir)) {
15152
15322
  const expected = new Set(refreshData.workflows.map((w) => `${w.name}.js`));
15153
15323
  for (const file of readdirSync9(provWorkflowsDir)) {
15154
15324
  if (!file.endsWith(".js")) continue;
15155
15325
  if (expected.has(file)) continue;
15156
15326
  try {
15157
- rmSync5(join36(provWorkflowsDir, file));
15327
+ rmSync5(join37(provWorkflowsDir, file));
15158
15328
  } catch {
15159
15329
  }
15160
15330
  }
@@ -15233,10 +15403,10 @@ async function processAgent(agent, agentStates, managedToolkits) {
15233
15403
  }
15234
15404
  let lastDriftCheckAt = now;
15235
15405
  const written = agentState.writtenHashes.get(agent.agent_id);
15236
- if (written && existsSync15(agentDir)) {
15406
+ if (written && existsSync16(agentDir)) {
15237
15407
  const driftedFiles = [];
15238
15408
  for (const [file, expectedHash] of written) {
15239
- const localHash = hashFile(join36(agentDir, file));
15409
+ const localHash = hashFile(join37(agentDir, file));
15240
15410
  if (localHash && localHash !== expectedHash) {
15241
15411
  driftedFiles.push(file);
15242
15412
  }
@@ -15247,7 +15417,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
15247
15417
  try {
15248
15418
  const localHashes = {};
15249
15419
  for (const file of driftedFiles) {
15250
- localHashes[file] = hashFile(join36(agentDir, file));
15420
+ localHashes[file] = hashFile(join37(agentDir, file));
15251
15421
  }
15252
15422
  await api.post("/host/drift", {
15253
15423
  agent_id: agent.agent_id,
@@ -15492,7 +15662,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
15492
15662
  const addedChannels = [...restartDecision.added];
15493
15663
  const writeDmNoticeMarkers = isChannelAddRestart ? () => {
15494
15664
  try {
15495
- const agentAugmentedDir = join36(homedir17(), ".augmented", agent.code_name);
15665
+ const agentAugmentedDir = join37(homedir17(), ".augmented", agent.code_name);
15496
15666
  mkdirSync11(agentAugmentedDir, { recursive: true });
15497
15667
  const markerJson = JSON.stringify({
15498
15668
  version: 1,
@@ -15500,7 +15670,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
15500
15670
  added: addedChannels
15501
15671
  });
15502
15672
  for (const file of ["slack-channel-add-restart.json", "telegram-channel-add-restart.json"]) {
15503
- atomicWriteFileSync(join36(agentAugmentedDir, file), markerJson);
15673
+ atomicWriteFileSync(join37(agentAugmentedDir, file), markerJson);
15504
15674
  }
15505
15675
  } catch (err) {
15506
15676
  log(`[hot-reload] channel-add DM-notice marker write failed for '${agent.code_name}' (non-fatal): ${err.message}`);
@@ -15689,24 +15859,24 @@ async function processAgent(agent, agentStates, managedToolkits) {
15689
15859
  if (agentSessionMode === "persistent" && (agentFrameworkCache.get(agent.code_name) ?? DEFAULT_FRAMEWORK) === "claude-code") {
15690
15860
  try {
15691
15861
  const agentProvisionDir = agentDir;
15692
- const projectDir = join36(homedir17(), ".augmented", agent.code_name, "project");
15862
+ const projectDir = join37(homedir17(), ".augmented", agent.code_name, "project");
15693
15863
  mkdirSync11(agentProvisionDir, { recursive: true });
15694
15864
  mkdirSync11(projectDir, { recursive: true });
15695
- const provisionMcpPath = join36(agentProvisionDir, ".mcp.json");
15696
- const projectMcpPath = join36(projectDir, ".mcp.json");
15865
+ const provisionMcpPath = join37(agentProvisionDir, ".mcp.json");
15866
+ const projectMcpPath = join37(projectDir, ".mcp.json");
15697
15867
  let mcpConfig = { mcpServers: {} };
15698
15868
  try {
15699
- mcpConfig = JSON.parse(readFileSync28(provisionMcpPath, "utf-8"));
15869
+ mcpConfig = JSON.parse(readFileSync29(provisionMcpPath, "utf-8"));
15700
15870
  if (!mcpConfig.mcpServers) mcpConfig.mcpServers = {};
15701
15871
  } catch {
15702
15872
  }
15703
- const localDirectChatChannel = join36(homedir17(), ".augmented", "_mcp", "direct-chat-channel.js");
15873
+ const localDirectChatChannel = join37(homedir17(), ".augmented", "_mcp", "direct-chat-channel.js");
15704
15874
  const directChatTeamSettings = refreshData.team?.settings;
15705
15875
  const directChatTz = (() => {
15706
15876
  const tz = directChatTeamSettings?.["timezone"];
15707
15877
  return typeof tz === "string" && tz.trim() !== "" ? tz.trim() : void 0;
15708
15878
  })();
15709
- if (existsSync15(localDirectChatChannel)) {
15879
+ if (existsSync16(localDirectChatChannel)) {
15710
15880
  const directChatEnv = {
15711
15881
  AGT_HOST: requireHost(),
15712
15882
  // ENG-5901 Track D: templated — the manager exports the real
@@ -15726,7 +15896,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
15726
15896
  // ~/.augmented/<codeName>/.current-turn-initiator.json. Note getAgentDir
15727
15897
  // returns the agent root (NOT the /provision subdir `agentDir` points at),
15728
15898
  // so it byte-matches the broker readers' path.
15729
- AGT_TURN_INITIATOR_FILE: join36(
15899
+ AGT_TURN_INITIATOR_FILE: join37(
15730
15900
  frameworkAdapter.getAgentDir(agent.code_name),
15731
15901
  ".current-turn-initiator.json"
15732
15902
  )
@@ -15746,8 +15916,8 @@ async function processAgent(agent, agentStates, managedToolkits) {
15746
15916
  log(`Channel credentials written for '${agent.code_name}/direct-chat'`);
15747
15917
  }
15748
15918
  }
15749
- const staleChannelsPath = join36(projectDir, ".mcp-channels.json");
15750
- if (existsSync15(staleChannelsPath)) {
15919
+ const staleChannelsPath = join37(projectDir, ".mcp-channels.json");
15920
+ if (existsSync16(staleChannelsPath)) {
15751
15921
  try {
15752
15922
  rmSync5(staleChannelsPath, { force: true });
15753
15923
  } catch {
@@ -15836,7 +16006,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
15836
16006
  }
15837
16007
  if (hostFlagStore().getBoolean("connectivity-probe")) {
15838
16008
  try {
15839
- const probeProjectDir = join36(homedir17(), ".augmented", agent.code_name, "project");
16009
+ const probeProjectDir = join37(homedir17(), ".augmented", agent.code_name, "project");
15840
16010
  let probeSet = integrations;
15841
16011
  try {
15842
16012
  const quarantined = await api.post("/host/agent-integrations/quarantined", { agent_id: agent.agent_id });
@@ -15882,7 +16052,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
15882
16052
  const forceDue = attemptsLeft > 0;
15883
16053
  let probeRan = false;
15884
16054
  try {
15885
- const probeProjectDir = join36(homedir17(), ".augmented", agent.code_name, "project");
16055
+ const probeProjectDir = join37(homedir17(), ".augmented", agent.code_name, "project");
15886
16056
  probeRan = await runAgentSessionToolBindProbes(agent, integrations, probeProjectDir, { forceDue });
15887
16057
  } catch (err) {
15888
16058
  log(`Session-tool-bind probe failed for '${agent.code_name}': ${err.message}`);
@@ -15959,11 +16129,11 @@ async function processAgent(agent, agentStates, managedToolkits) {
15959
16129
  const intHash = computeIntegrationsHash(integrations);
15960
16130
  const prevIntHash = agentState.knownIntegrationHashes.get(agent.agent_id);
15961
16131
  if (intHash !== prevIntHash) {
15962
- const projectDir = join36(homedir17(), ".augmented", agent.code_name, "project");
15963
- const envIntPath = join36(projectDir, ".env.integrations");
16132
+ const projectDir = join37(homedir17(), ".augmented", agent.code_name, "project");
16133
+ const envIntPath = join37(projectDir, ".env.integrations");
15964
16134
  let preWriteEnv;
15965
16135
  try {
15966
- preWriteEnv = readFileSync28(envIntPath, "utf-8");
16136
+ preWriteEnv = readFileSync29(envIntPath, "utf-8");
15967
16137
  } catch {
15968
16138
  preWriteEnv = void 0;
15969
16139
  }
@@ -15982,9 +16152,9 @@ async function processAgent(agent, agentStates, managedToolkits) {
15982
16152
  }
15983
16153
  if (fw === "claude-code" && isSessionHealthy(agent.code_name)) {
15984
16154
  try {
15985
- const projectMcpPath = join36(projectDir, ".mcp.json");
15986
- const postWriteEnv = readFileSync28(envIntPath, "utf-8");
15987
- const mcpContent = readFileSync28(projectMcpPath, "utf-8");
16155
+ const projectMcpPath = join37(projectDir, ".mcp.json");
16156
+ const postWriteEnv = readFileSync29(envIntPath, "utf-8");
16157
+ const mcpContent = readFileSync29(projectMcpPath, "utf-8");
15988
16158
  const changedVars = diffEnvIntegrations(preWriteEnv, postWriteEnv);
15989
16159
  const mcpJsonForReap = JSON.parse(mcpContent);
15990
16160
  const affectedServerKeys = findMcpServersUsingVars(mcpJsonForReap, changedVars);
@@ -16252,14 +16422,14 @@ async function processAgent(agent, agentStates, managedToolkits) {
16252
16422
  const frameworkId2 = frameworkAdapter.id;
16253
16423
  const candidateSkillDirs = [
16254
16424
  // Claude Code — framework runtime tree
16255
- join36(homedir18(), ".augmented", agent.code_name, "skills"),
16425
+ join37(homedir18(), ".augmented", agent.code_name, "skills"),
16256
16426
  // Claude Code — project tree
16257
- join36(homedir18(), ".augmented", agent.code_name, "project", ".claude", "skills"),
16427
+ join37(homedir18(), ".augmented", agent.code_name, "project", ".claude", "skills"),
16258
16428
  // Defensive: legacy provision-side path, not currently an
16259
16429
  // install target but cheap to sweep.
16260
- join36(agentDir, ".claude", "skills")
16430
+ join37(agentDir, ".claude", "skills")
16261
16431
  ];
16262
- const existingDirs = candidateSkillDirs.filter((d) => existsSync15(d));
16432
+ const existingDirs = candidateSkillDirs.filter((d) => existsSync16(d));
16263
16433
  const discoveredEntries = /* @__PURE__ */ new Set();
16264
16434
  for (const dir of existingDirs) {
16265
16435
  try {
@@ -16278,7 +16448,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
16278
16448
  entry,
16279
16449
  dirs: existingDirs,
16280
16450
  removeDir: (p) => {
16281
- if (existsSync15(p)) {
16451
+ if (existsSync16(p)) {
16282
16452
  rmSync6(p, { recursive: true, force: true });
16283
16453
  }
16284
16454
  }
@@ -16298,7 +16468,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
16298
16468
  const sharedSkillsPayload = refreshAny.shared_skills;
16299
16469
  const desiredResolved = globalSkillsPayload !== void 0 || sharedSkillsPayload !== void 0;
16300
16470
  const manifestPath = managedSkillManifestPath(
16301
- join36(homedir17(), ".augmented", agent.code_name)
16471
+ join37(homedir17(), ".augmented", agent.code_name)
16302
16472
  );
16303
16473
  const prevIds = /* @__PURE__ */ new Set([
16304
16474
  ...agentState.knownGlobalSkillIds.get(agent.agent_id) ?? /* @__PURE__ */ new Set(),
@@ -16318,15 +16488,15 @@ async function processAgent(agent, agentStates, managedToolkits) {
16318
16488
  }
16319
16489
  if (plan.removes.length) {
16320
16490
  const globalSkillDirs = [
16321
- join36(homedir17(), ".augmented", agent.code_name, "skills"),
16322
- join36(homedir17(), ".augmented", agent.code_name, "project", ".claude", "skills"),
16323
- join36(agentDir, ".claude", "skills")
16491
+ join37(homedir17(), ".augmented", agent.code_name, "skills"),
16492
+ join37(homedir17(), ".augmented", agent.code_name, "project", ".claude", "skills"),
16493
+ join37(agentDir, ".claude", "skills")
16324
16494
  ];
16325
16495
  for (const id of plan.removes) {
16326
16496
  let prunedAny = false;
16327
16497
  for (const dir of globalSkillDirs) {
16328
- const p = join36(dir, id);
16329
- if (existsSync15(p) && existsSync15(join36(p, "SKILL.md"))) {
16498
+ const p = join37(dir, id);
16499
+ if (existsSync16(p) && existsSync16(join37(p, "SKILL.md"))) {
16330
16500
  rmSync5(p, { recursive: true, force: true });
16331
16501
  prunedAny = true;
16332
16502
  }
@@ -16562,8 +16732,8 @@ async function processAgent(agent, agentStates, managedToolkits) {
16562
16732
  const sess = getSessionState(agent.code_name);
16563
16733
  let mcpJsonParsed = null;
16564
16734
  try {
16565
- const mcpPath = join36(getProjectDir(agent.code_name), ".mcp.json");
16566
- mcpJsonParsed = JSON.parse(readFileSync28(mcpPath, "utf-8"));
16735
+ const mcpPath = join37(getProjectDir(agent.code_name), ".mcp.json");
16736
+ mcpJsonParsed = JSON.parse(readFileSync29(mcpPath, "utf-8"));
16567
16737
  } catch {
16568
16738
  }
16569
16739
  reapMissingMcpSessions({
@@ -16994,10 +17164,10 @@ Retried to the limit after repeated stalls \u2014 needs a look.`).catch(() => {
16994
17164
  }
16995
17165
  }
16996
17166
  const trackedFiles = frameworkAdapter.driftTrackedFiles();
16997
- if (trackedFiles.length > 0 && existsSync15(agentDir)) {
17167
+ if (trackedFiles.length > 0 && existsSync16(agentDir)) {
16998
17168
  const hashes = /* @__PURE__ */ new Map();
16999
17169
  for (const file of trackedFiles) {
17000
- const h = hashFile(join36(agentDir, file));
17170
+ const h = hashFile(join37(agentDir, file));
17001
17171
  if (h) hashes.set(file, h);
17002
17172
  }
17003
17173
  agentState.writtenHashes.set(agent.agent_id, hashes);
@@ -17012,7 +17182,7 @@ Retried to the limit after repeated stalls \u2014 needs a look.`).catch(() => {
17012
17182
  refreshData.agent.onboarding_state
17013
17183
  );
17014
17184
  const obStep = obState.step;
17015
- const markerPath = join36(homedir17(), ".augmented", agent.code_name, "onboarding-drive.json");
17185
+ const markerPath = join37(homedir17(), ".augmented", agent.code_name, "onboarding-drive.json");
17016
17186
  const marker = readOnboardingDriveMarker(markerPath);
17017
17187
  const obContactRaw = refreshData.agent.manager_last_contacted_at;
17018
17188
  const obContact = typeof obContactRaw === "string" && obContactRaw ? obContactRaw : null;
@@ -17114,7 +17284,7 @@ async function ensureOpencodeRuntime(agent, refreshData, agentTimezone) {
17114
17284
  }
17115
17285
  stopOpencodeSlackIngest(codeName, log);
17116
17286
  stopOpencodeTelegramIngest(codeName, log);
17117
- const opencodeProjectDir = join36(getFramework("opencode").getAgentDir(codeName), "provision");
17287
+ const opencodeProjectDir = join37(getFramework("opencode").getAgentDir(codeName), "provision");
17118
17288
  const serveEnv = {
17119
17289
  AGT_HOST: requireHost(),
17120
17290
  AGT_API_KEY: getApiKey() ?? void 0,
@@ -17169,8 +17339,8 @@ async function ensurePersistentSession(agent, tasks, boardItems, refreshData) {
17169
17339
  });
17170
17340
  }
17171
17341
  const projectDir = getProjectDir(codeName);
17172
- const mcpConfigPath = join36(projectDir, ".mcp.json");
17173
- const claudeMdPath = join36(projectDir, "CLAUDE.md");
17342
+ const mcpConfigPath = join37(projectDir, ".mcp.json");
17343
+ const claudeMdPath = join37(projectDir, "CLAUDE.md");
17174
17344
  if (restartBreaker.isTripped(codeName)) {
17175
17345
  const trip = restartBreaker.getTrip(codeName);
17176
17346
  return {
@@ -17945,7 +18115,7 @@ async function handleRestartDoorbell(agentId, requestedAt, restartReason) {
17945
18115
  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}`));
17946
18116
  void (async () => {
17947
18117
  try {
17948
- const { collectDiagnostics } = await import("../persistent-session-F7JEOWHQ.js");
18118
+ const { collectDiagnostics } = await import("../persistent-session-TMOTEVV6.js");
17949
18119
  await api.post("/host/heartbeat", {
17950
18120
  host_id: hostId,
17951
18121
  agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor)
@@ -17996,7 +18166,7 @@ async function respawnAgentAfterMcpStop(codeName, reason) {
17996
18166
  }
17997
18167
  try {
17998
18168
  const hostId = await getHostId();
17999
- const { collectDiagnostics } = await import("../persistent-session-F7JEOWHQ.js");
18169
+ const { collectDiagnostics } = await import("../persistent-session-TMOTEVV6.js");
18000
18170
  await api.post("/host/heartbeat", {
18001
18171
  host_id: hostId,
18002
18172
  agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor)
@@ -18147,6 +18317,7 @@ function ensureRealtimeIntegrationContextStarted(agentStates) {
18147
18317
  log(`[realtime] Dropped ${dropped} token-rotation rebind streak(s) for no-longer-active agent(s) (ENG-9265)`);
18148
18318
  }
18149
18319
  }
18320
+ pruneStuckStreaksToActiveAgents(activeAgentIds);
18150
18321
  if (activeAgentIds.length === 0) {
18151
18322
  if (subscribedIntegrationContextAgentIds.size > 0) {
18152
18323
  stopRealtimeIntegrationContext();
@@ -18627,7 +18798,7 @@ async function processClaudePairSessions(agents) {
18627
18798
  killPairSession,
18628
18799
  pairTmuxSession,
18629
18800
  finalizeClaudePairOnboarding
18630
- } = await import("../claude-pair-runtime-VAU7UXE4.js");
18801
+ } = await import("../claude-pair-runtime-MY5LMJVT.js");
18631
18802
  for (const pairId of pendingResp.cancelled_pair_ids ?? []) {
18632
18803
  log(`[claude-pair] sweeping orphan tmux session for pair ${pairId.slice(0, 8)}`);
18633
18804
  const killed = await killPairSession(pairTmuxSession(pairId));
@@ -18852,17 +19023,17 @@ var lastDownloadHash = /* @__PURE__ */ new Map();
18852
19023
  var lastLocalFileHash = /* @__PURE__ */ new Map();
18853
19024
  var memoryManifests = /* @__PURE__ */ new Map();
18854
19025
  function memoryRetirementDir(configDir, codeName) {
18855
- return join36(configDir, "_memory-retirement", codeName);
19026
+ return join37(configDir, "_memory-retirement", codeName);
18856
19027
  }
18857
19028
  function memoryManifestPath(configDir, codeName) {
18858
- return join36(memoryRetirementDir(configDir, codeName), "manifest.json");
19029
+ return join37(memoryRetirementDir(configDir, codeName), "manifest.json");
18859
19030
  }
18860
19031
  function loadMemoryManifest(agentId, configDir, codeName) {
18861
19032
  const cached = memoryManifests.get(agentId);
18862
19033
  if (cached) return cached;
18863
19034
  let manifest = {};
18864
19035
  try {
18865
- const raw = readFileSync28(memoryManifestPath(configDir, codeName), "utf-8");
19036
+ const raw = readFileSync29(memoryManifestPath(configDir, codeName), "utf-8");
18866
19037
  const parsed = JSON.parse(raw);
18867
19038
  if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
18868
19039
  for (const [name, entry] of Object.entries(parsed)) {
@@ -18890,7 +19061,7 @@ function saveMemoryManifest(agentId, configDir, codeName) {
18890
19061
  }
18891
19062
  }
18892
19063
  function retiredMemoryDir(configDir, codeName) {
18893
- return join36(memoryRetirementDir(configDir, codeName), "retired");
19064
+ return join37(memoryRetirementDir(configDir, codeName), "retired");
18894
19065
  }
18895
19066
  var RETIRED_MEMORY_TTL_MS = 30 * 24 * 60 * 60 * 1e3;
18896
19067
  var lastRetirementReport = /* @__PURE__ */ new Map();
@@ -18968,15 +19139,15 @@ function applyMemoryTombstones(opts) {
18968
19139
  log2(`[memory-retire] ${agent.code_name}: KEPT '${tomb.name}' \u2014 no write record, not ours to remove`);
18969
19140
  continue;
18970
19141
  }
18971
- const filePath = join36(memoryDir, entry.file);
18972
- if (!existsSync15(filePath)) {
19142
+ const filePath = join37(memoryDir, entry.file);
19143
+ if (!existsSync16(filePath)) {
18973
19144
  outcomes.already_gone++;
18974
19145
  delete manifest[tomb.name];
18975
19146
  manifestDirty = true;
18976
19147
  continue;
18977
19148
  }
18978
19149
  try {
18979
- const actual = createHash17("sha256").update(readFileSync28(filePath)).digest("hex");
19150
+ const actual = createHash17("sha256").update(readFileSync29(filePath)).digest("hex");
18980
19151
  if (actual !== entry.sha) {
18981
19152
  outcomes.kept_modified++;
18982
19153
  outcomes.unapplied.push({ name: tomb.name, reason: "kept_modified" });
@@ -18988,9 +19159,9 @@ function applyMemoryTombstones(opts) {
18988
19159
  const destDir = retiredMemoryDir(configDir, agent.code_name);
18989
19160
  mkdirSync11(destDir, { recursive: true });
18990
19161
  const stamp = Date.now();
18991
- let dest = join36(destDir, `${entry.file}.${stamp}.retired`);
18992
- for (let n = 1; existsSync15(dest); n++) {
18993
- dest = join36(destDir, `${entry.file}.${stamp}-${n}.retired`);
19162
+ let dest = join37(destDir, `${entry.file}.${stamp}.retired`);
19163
+ for (let n = 1; existsSync16(dest); n++) {
19164
+ dest = join37(destDir, `${entry.file}.${stamp}-${n}.retired`);
18994
19165
  }
18995
19166
  renameSync8(filePath, dest);
18996
19167
  try {
@@ -19023,13 +19194,13 @@ function applyMemoryTombstones(opts) {
19023
19194
  }
19024
19195
  function reapRetiredMemories(configDir, codeName, log2) {
19025
19196
  const dir = retiredMemoryDir(configDir, codeName);
19026
- if (!existsSync15(dir)) return;
19197
+ if (!existsSync16(dir)) return;
19027
19198
  const cutoff = Date.now() - RETIRED_MEMORY_TTL_MS;
19028
19199
  let reaped = 0;
19029
19200
  try {
19030
19201
  for (const file of readdirSync9(dir)) {
19031
19202
  if (!file.endsWith(".retired")) continue;
19032
- const path = join36(dir, file);
19203
+ const path = join37(dir, file);
19033
19204
  try {
19034
19205
  if (statSync8(path).mtimeMs < cutoff) {
19035
19206
  unlinkSync6(path);
@@ -19044,8 +19215,8 @@ function reapRetiredMemories(configDir, codeName, log2) {
19044
19215
  if (reaped > 0) log2(`[memory-retire] ${codeName}: reaped ${reaped} retired memory file(s) past TTL`);
19045
19216
  }
19046
19217
  async function syncMemories(agent, configDir, log2) {
19047
- const projectDir = join36(configDir, agent.code_name, "project");
19048
- const memoryDir = join36(projectDir, "memory");
19218
+ const projectDir = join37(configDir, agent.code_name, "project");
19219
+ const memoryDir = join37(projectDir, "memory");
19049
19220
  const isFreshSync = pendingFreshMemorySync.has(agent.agent_id);
19050
19221
  if (isFreshSync) {
19051
19222
  log2(`[memory-sync] Fresh-sync requested for '${agent.code_name}' \u2014 pulling DB first`);
@@ -19069,14 +19240,14 @@ async function syncMemories(agent, configDir, log2) {
19069
19240
  }
19070
19241
  pendingFreshMemorySync.delete(agent.agent_id);
19071
19242
  }
19072
- if (existsSync15(memoryDir)) {
19243
+ if (existsSync16(memoryDir)) {
19073
19244
  const prevHashes = memoryFileHashes.get(agent.agent_id) ?? /* @__PURE__ */ new Map();
19074
19245
  const currentHashes = /* @__PURE__ */ new Map();
19075
19246
  const changedMemories = [];
19076
19247
  for (const file of readdirSync9(memoryDir)) {
19077
19248
  if (!file.endsWith(".md")) continue;
19078
19249
  try {
19079
- const raw = readFileSync28(join36(memoryDir, file), "utf-8");
19250
+ const raw = readFileSync29(join37(memoryDir, file), "utf-8");
19080
19251
  const fileHash = createHash17("sha256").update(raw).digest("hex").slice(0, 16);
19081
19252
  currentHashes.set(file, fileHash);
19082
19253
  if (prevHashes.get(file) === fileHash) continue;
@@ -19101,7 +19272,7 @@ async function syncMemories(agent, configDir, log2) {
19101
19272
  } catch (err) {
19102
19273
  for (const mem of changedMemories) {
19103
19274
  for (const [file] of currentHashes) {
19104
- const parsed = parseMemoryFile(readFileSync28(join36(memoryDir, file), "utf-8"), file.replace(/\.md$/, ""));
19275
+ const parsed = parseMemoryFile(readFileSync29(join37(memoryDir, file), "utf-8"), file.replace(/\.md$/, ""));
19105
19276
  if (parsed?.name === mem.name) currentHashes.delete(file);
19106
19277
  }
19107
19278
  }
@@ -19127,7 +19298,7 @@ async function syncMemories(agent, configDir, log2) {
19127
19298
  }
19128
19299
  }
19129
19300
  async function downloadMemories(agent, memoryDir, log2, { force, configDir }) {
19130
- const localFiles = existsSync15(memoryDir) ? readdirSync9(memoryDir).filter((f) => f.endsWith(".md")).sort() : [];
19301
+ const localFiles = existsSync16(memoryDir) ? readdirSync9(memoryDir).filter((f) => f.endsWith(".md")).sort() : [];
19131
19302
  const localListHash = createHash17("sha256").update(localFiles.join(",")).digest("hex").slice(0, 16);
19132
19303
  const prevLocalHash = lastLocalFileHash.get(agent.agent_id);
19133
19304
  const prevDownload = lastDownloadHash.get(agent.agent_id);
@@ -19152,7 +19323,7 @@ async function downloadMemories(agent, memoryDir, log2, { force, configDir }) {
19152
19323
  const rawSlug = mem.name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)/g, "").slice(0, 60);
19153
19324
  const slug = rawSlug || `memory-${i}`;
19154
19325
  const fileName = `${slug}.md`;
19155
- const filePath = join36(memoryDir, fileName);
19326
+ const filePath = join37(memoryDir, fileName);
19156
19327
  const desired = `---
19157
19328
  name: ${JSON.stringify(mem.name)}
19158
19329
  type: ${mem.type}
@@ -19169,10 +19340,10 @@ ${mem.content}
19169
19340
  return true;
19170
19341
  };
19171
19342
  let manifestDirty = false;
19172
- if (existsSync15(filePath)) {
19343
+ if (existsSync16(filePath)) {
19173
19344
  let existing = "";
19174
19345
  try {
19175
- existing = readFileSync28(filePath, "utf-8");
19346
+ existing = readFileSync29(filePath, "utf-8");
19176
19347
  } catch {
19177
19348
  }
19178
19349
  if (existing === desired) {
@@ -19202,7 +19373,7 @@ ${mem.content}
19202
19373
  }
19203
19374
  }
19204
19375
  async function cleanupAgentFiles(codeName, agentDir) {
19205
- if (existsSync15(agentDir)) {
19376
+ if (existsSync16(agentDir)) {
19206
19377
  try {
19207
19378
  rmSync5(agentDir, { recursive: true, force: true });
19208
19379
  log(`Removed provision directory for '${codeName}'`);
@@ -19325,6 +19496,7 @@ function startPolling() {
19325
19496
  void startCaffeinate();
19326
19497
  loadChannelHashCache2();
19327
19498
  loadSenderPolicyBaseline2();
19499
+ loadStuckStreaks2();
19328
19500
  loadKanbanNudgeStateFromDisk();
19329
19501
  hostFlagStore().init();
19330
19502
  log(`Starting poll loop (interval=${config.intervalMs}ms, configDir=${config.configDir})`);
@@ -19470,8 +19642,8 @@ function startManager(opts) {
19470
19642
  config = opts;
19471
19643
  try {
19472
19644
  const stateFile = getStateFile();
19473
- if (existsSync15(stateFile)) {
19474
- const raw = readFileSync28(stateFile, "utf-8");
19645
+ if (existsSync16(stateFile)) {
19646
+ const raw = readFileSync29(stateFile, "utf-8");
19475
19647
  const parsed = JSON.parse(raw);
19476
19648
  if (Array.isArray(parsed.agents)) {
19477
19649
  state7.agents = parsed.agents;
@@ -19498,7 +19670,7 @@ function startManager(opts) {
19498
19670
  log(`[startup] state rehydration failed (continuing with empty state): ${err.message}`);
19499
19671
  }
19500
19672
  log(
19501
- `[startup] worker pid=${process.pid} ppid=${process.ppid} node=${process.version} log=${join36(homedir17(), ".augmented", "manager.log")}`
19673
+ `[startup] worker pid=${process.pid} ppid=${process.ppid} node=${process.version} log=${join37(homedir17(), ".augmented", "manager.log")}`
19502
19674
  );
19503
19675
  deployMcpAssets();
19504
19676
  reapOrphanChannelMcps({ log });
@@ -19527,7 +19699,7 @@ async function reapOrphanedClaudePids() {
19527
19699
  const looksLikeClaude = (pid) => {
19528
19700
  if (process.platform !== "linux") return true;
19529
19701
  try {
19530
- const comm = readFileSync28(`/proc/${pid}/comm`, "utf-8").trim().toLowerCase();
19702
+ const comm = readFileSync29(`/proc/${pid}/comm`, "utf-8").trim().toLowerCase();
19531
19703
  return comm.includes("claude");
19532
19704
  } catch {
19533
19705
  return false;
@@ -19624,14 +19796,14 @@ function restartRunningChannelMcps(basenames) {
19624
19796
  }
19625
19797
  }
19626
19798
  function deployMcpAssets() {
19627
- const targetDir = join36(homedir17(), ".augmented", "_mcp");
19799
+ const targetDir = join37(homedir17(), ".augmented", "_mcp");
19628
19800
  mkdirSync11(targetDir, { recursive: true });
19629
19801
  const moduleDir = dirname10(fileURLToPath(import.meta.url));
19630
19802
  let mcpSourceDir = "";
19631
19803
  let dir = moduleDir;
19632
19804
  for (let i = 0; i < 6; i++) {
19633
- const candidate = join36(dir, "dist", "mcp");
19634
- if (existsSync15(join36(candidate, "index.js"))) {
19805
+ const candidate = join37(dir, "dist", "mcp");
19806
+ if (existsSync16(join37(candidate, "index.js"))) {
19635
19807
  mcpSourceDir = candidate;
19636
19808
  break;
19637
19809
  }
@@ -19648,8 +19820,8 @@ function deployMcpAssets() {
19648
19820
  const failedFiles = [];
19649
19821
  const fileHash = (p) => {
19650
19822
  try {
19651
- if (!existsSync15(p)) return null;
19652
- return createHash17("sha256").update(readFileSync28(p)).digest("hex");
19823
+ if (!existsSync16(p)) return null;
19824
+ return createHash17("sha256").update(readFileSync29(p)).digest("hex");
19653
19825
  } catch {
19654
19826
  return null;
19655
19827
  }
@@ -19720,9 +19892,9 @@ function deployMcpAssets() {
19720
19892
  // needs restarting to pick up a token rotation.
19721
19893
  "xero.js"
19722
19894
  ]) {
19723
- const src = join36(mcpSourceDir, file);
19724
- const dst = join36(targetDir, file);
19725
- if (!existsSync15(src)) continue;
19895
+ const src = join37(mcpSourceDir, file);
19896
+ const dst = join37(targetDir, file);
19897
+ if (!existsSync16(src)) continue;
19726
19898
  attemptedFiles.push(file);
19727
19899
  const before = fileHash(dst);
19728
19900
  try {
@@ -19747,16 +19919,16 @@ function deployMcpAssets() {
19747
19919
  log(`[manager] Bundle(s) updated: ${changedBasenames.join(", ")} \u2014 signalling running instances to restart`);
19748
19920
  restartRunningChannelMcps(changedBasenames);
19749
19921
  }
19750
- const localMcpPath = join36(targetDir, "index.js");
19922
+ const localMcpPath = join37(targetDir, "index.js");
19751
19923
  try {
19752
- const agentsDir = join36(homedir17(), ".augmented", "agents");
19753
- if (existsSync15(agentsDir)) {
19924
+ const agentsDir = join37(homedir17(), ".augmented", "agents");
19925
+ if (existsSync16(agentsDir)) {
19754
19926
  for (const entry of readdirSync9(agentsDir, { withFileTypes: true })) {
19755
19927
  if (!entry.isDirectory()) continue;
19756
19928
  for (const subdir of ["provision", "project"]) {
19757
- const mcpJsonPath = join36(agentsDir, entry.name, subdir, ".mcp.json");
19929
+ const mcpJsonPath = join37(agentsDir, entry.name, subdir, ".mcp.json");
19758
19930
  try {
19759
- const raw = readFileSync28(mcpJsonPath, "utf-8");
19931
+ const raw = readFileSync29(mcpJsonPath, "utf-8");
19760
19932
  if (!raw.includes("@integrity-labs/augmented-mcp")) continue;
19761
19933
  const mcpConfig = JSON.parse(raw);
19762
19934
  const augServer = mcpConfig.mcpServers?.["augmented"];