@integrity-labs/agt-cli 0.28.390 → 0.28.392

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.
@@ -43,7 +43,7 @@ import {
43
43
  resolveEffectivePinRaw,
44
44
  safeWriteJsonAtomic,
45
45
  setConfigHash
46
- } from "../chunk-OIVIZ7Z3.js";
46
+ } from "../chunk-SET6SREA.js";
47
47
  import {
48
48
  getProjectDir as getProjectDir2,
49
49
  getReadyTasks,
@@ -152,9 +152,9 @@ import {
152
152
 
153
153
  // src/lib/manager-worker.ts
154
154
  import { createHash as createHash13 } from "crypto";
155
- import { readFileSync as readFileSync17, writeFileSync as writeFileSync11, mkdirSync as mkdirSync8, existsSync as existsSync11, rmSync as rmSync5, readdirSync as readdirSync5, statSync as statSync4, copyFileSync } from "fs";
155
+ import { readFileSync as readFileSync18, writeFileSync as writeFileSync12, mkdirSync as mkdirSync9, existsSync as existsSync11, rmSync as rmSync5, readdirSync as readdirSync6, statSync as statSync4, copyFileSync } from "fs";
156
156
  import { execFileSync as syncExecFile } from "child_process";
157
- import { join as join21, dirname as dirname5, delimiter as pathDelimiter } from "path";
157
+ import { join as join22, dirname as dirname6, delimiter as pathDelimiter } from "path";
158
158
  import { homedir as homedir10 } from "os";
159
159
  import { fileURLToPath } from "url";
160
160
 
@@ -7622,6 +7622,134 @@ async function sendError(flag, opts, text) {
7622
7622
  await sendAck(flag, opts, text);
7623
7623
  }
7624
7624
 
7625
+ // src/lib/restart-context.ts
7626
+ import { readdirSync as readdirSync5, readFileSync as readFileSync17, writeFileSync as writeFileSync11, mkdirSync as mkdirSync8, unlinkSync as unlinkSync2 } from "fs";
7627
+ import { dirname as dirname5, join as join21 } from "path";
7628
+ var SLACK_PENDING_INBOUND_DIRNAME = "slack-pending-inbound";
7629
+ var SLACK_RESTART_CONTEXT_DIRNAME = "slack-restart-context";
7630
+ var MAX_TOPIC_CHARS = 140;
7631
+ var MIN_TOPIC_CHARS = 3;
7632
+ var RECONSTRUCT_WINDOW_MS = 7 * 24 * 60 * 60 * 1e3;
7633
+ var WINDOW_PAD_MS3 = 5 * 6e4;
7634
+ var DEFAULT_MAX_MARKERS_PER_AGENT = 25;
7635
+ function augmentedAgentDir(codeName) {
7636
+ return dirname5(getProjectDir(codeName));
7637
+ }
7638
+ function slackPendingInboundDir(codeName) {
7639
+ return join21(augmentedAgentDir(codeName), SLACK_PENDING_INBOUND_DIRNAME);
7640
+ }
7641
+ function slackRestartContextDir(codeName) {
7642
+ return join21(augmentedAgentDir(codeName), SLACK_RESTART_CONTEXT_DIRNAME);
7643
+ }
7644
+ function sanitizeTopic(raw) {
7645
+ const cleaned = raw.replace(/\s+/g, " ").trim().replace(/[<>]/g, " ").replace(/\s+/g, " ").trim();
7646
+ if (cleaned.length < MIN_TOPIC_CHARS) return null;
7647
+ if (cleaned.length <= MAX_TOPIC_CHARS) return cleaned;
7648
+ return `${cleaned.slice(0, MAX_TOPIC_CHARS - 1).trimEnd()}\u2026`;
7649
+ }
7650
+ function deriveRestartTopic(turns) {
7651
+ let lastUserText = null;
7652
+ for (const turn of turns) {
7653
+ if (turn.role === "user" && turn.text.trim()) lastUserText = turn.text;
7654
+ }
7655
+ if (lastUserText == null) return null;
7656
+ return sanitizeTopic(lastUserText);
7657
+ }
7658
+ function computeRestartContextHints(markers, allTurns, nowMs, reconstruct = reconstructConversation) {
7659
+ const windowStart = nowMs - RECONSTRUCT_WINDOW_MS;
7660
+ const windowEnd = nowMs + WINDOW_PAD_MS3;
7661
+ const writtenAt = new Date(nowMs).toISOString();
7662
+ const out = [];
7663
+ for (const marker of markers) {
7664
+ const channelRef = `slack:${marker.channel}:${marker.thread_ts}`;
7665
+ const turns = reconstruct(allTurns, channelRef, windowStart, windowEnd);
7666
+ const topic = deriveRestartTopic(turns);
7667
+ if (!topic) continue;
7668
+ out.push({
7669
+ filename: marker.filename,
7670
+ hint: { topic, channel: marker.channel, thread_ts: marker.thread_ts, written_at: writtenAt }
7671
+ });
7672
+ }
7673
+ return out;
7674
+ }
7675
+ function safeReaddir(dir) {
7676
+ try {
7677
+ return readdirSync5(dir);
7678
+ } catch {
7679
+ return [];
7680
+ }
7681
+ }
7682
+ function readStrandedMarker(path) {
7683
+ try {
7684
+ const parsed = JSON.parse(readFileSync17(path, "utf-8"));
7685
+ if (typeof parsed.channel === "string" && typeof parsed.thread_ts === "string") {
7686
+ return { channel: parsed.channel, thread_ts: parsed.thread_ts };
7687
+ }
7688
+ } catch {
7689
+ }
7690
+ return null;
7691
+ }
7692
+ function writeHintFile(path, dir, hint) {
7693
+ mkdirSync8(dir, { recursive: true, mode: 448 });
7694
+ writeFileSync11(path, JSON.stringify(hint), { mode: 384 });
7695
+ }
7696
+ function pruneHintsExcept(codeName, freshFilenames) {
7697
+ const ctxDir = slackRestartContextDir(codeName);
7698
+ for (const filename of safeReaddir(ctxDir)) {
7699
+ if (!filename.endsWith(".json")) continue;
7700
+ if (freshFilenames.has(filename)) continue;
7701
+ try {
7702
+ unlinkSync2(join21(ctxDir, filename));
7703
+ } catch {
7704
+ }
7705
+ }
7706
+ }
7707
+ function refreshSlackRestartContextHints(codeNames, opts = {}) {
7708
+ const nowMs = opts.now ?? Date.now();
7709
+ const log2 = opts.log ?? (() => {
7710
+ });
7711
+ const cap = opts.maxMarkersPerAgent ?? DEFAULT_MAX_MARKERS_PER_AGENT;
7712
+ const readTurns = opts.readTurns ?? readRecentTurns;
7713
+ for (const codeName of codeNames) {
7714
+ try {
7715
+ const markerDir = slackPendingInboundDir(codeName);
7716
+ const markerFilenames = safeReaddir(markerDir).filter((f) => f.endsWith(".json"));
7717
+ if (markerFilenames.length === 0) {
7718
+ pruneHintsExcept(codeName, /* @__PURE__ */ new Set());
7719
+ continue;
7720
+ }
7721
+ const markers = [];
7722
+ for (const filename of markerFilenames.slice(0, cap)) {
7723
+ const parsed = readStrandedMarker(join21(markerDir, filename));
7724
+ if (parsed) markers.push({ filename, channel: parsed.channel, thread_ts: parsed.thread_ts });
7725
+ }
7726
+ if (markers.length === 0) {
7727
+ pruneHintsExcept(codeName, /* @__PURE__ */ new Set());
7728
+ continue;
7729
+ }
7730
+ const transcriptDir = sessionTranscriptDir(getProjectDir(codeName));
7731
+ const allTurns = readTurns(transcriptDir, nowMs);
7732
+ const hints = allTurns.length > 0 ? computeRestartContextHints(markers, allTurns, nowMs) : [];
7733
+ const ctxDir = slackRestartContextDir(codeName);
7734
+ const freshFilenames = /* @__PURE__ */ new Set();
7735
+ for (const { filename, hint } of hints) {
7736
+ try {
7737
+ writeHintFile(join21(ctxDir, filename), ctxDir, hint);
7738
+ freshFilenames.add(filename);
7739
+ } catch (err) {
7740
+ log2(`[restart-context] ${codeName}: hint write failed for ${filename}: ${err.message}`);
7741
+ }
7742
+ }
7743
+ pruneHintsExcept(codeName, freshFilenames);
7744
+ if (hints.length > 0) {
7745
+ log2(`[restart-context] ${codeName}: wrote ${hints.length} topic hint(s) for stranded thread(s)`);
7746
+ }
7747
+ } catch (err) {
7748
+ log2(`[restart-context] ${codeName}: failed (continuing): ${err.message}`);
7749
+ }
7750
+ }
7751
+ }
7752
+
7625
7753
  // src/lib/persistent-session-stuck-tracker.ts
7626
7754
  var DEFAULT_STUCK_WARN_THRESHOLD = 3;
7627
7755
  var PersistentSessionStuckTracker = class {
@@ -8770,7 +8898,7 @@ var runningChannelSecretHashes = /* @__PURE__ */ new Map();
8770
8898
  var sessionLaunchManagedStructure = /* @__PURE__ */ new Map();
8771
8899
  function projectMcpHash(_codeName, projectDir) {
8772
8900
  try {
8773
- const raw = readFileSync17(join21(projectDir, ".mcp.json"), "utf-8");
8901
+ const raw = readFileSync18(join22(projectDir, ".mcp.json"), "utf-8");
8774
8902
  return createHash13("sha256").update(canonicalJson(JSON.parse(raw))).digest("hex");
8775
8903
  } catch {
8776
8904
  return null;
@@ -8778,7 +8906,7 @@ function projectMcpHash(_codeName, projectDir) {
8778
8906
  }
8779
8907
  function projectMcpKeys(_codeName, projectDir) {
8780
8908
  try {
8781
- const raw = readFileSync17(join21(projectDir, ".mcp.json"), "utf-8");
8909
+ const raw = readFileSync18(join22(projectDir, ".mcp.json"), "utf-8");
8782
8910
  const parsed = JSON.parse(raw);
8783
8911
  const servers = parsed.mcpServers;
8784
8912
  if (!servers || typeof servers !== "object") return /* @__PURE__ */ new Set();
@@ -8796,7 +8924,7 @@ function seedSessionLaunchBaselines(codeName, projectDir) {
8796
8924
  else runningMcpServerKeys.delete(codeName);
8797
8925
  let launchStructure = null;
8798
8926
  try {
8799
- const raw = readFileSync17(join21(projectDir, ".mcp.json"), "utf-8");
8927
+ const raw = readFileSync18(join22(projectDir, ".mcp.json"), "utf-8");
8800
8928
  launchStructure = managedMcpStructureHashFromFile(
8801
8929
  JSON.parse(raw),
8802
8930
  isManagedMcpServerKey
@@ -8896,7 +9024,7 @@ async function runAgentSessionToolBindProbes(agent, integrations, projectDir, op
8896
9024
  if (result && result.rebindCandidates.length > 0 && hostFlagStore().getBoolean("session-tool-rebind")) {
8897
9025
  let mcpJsonForRebind = null;
8898
9026
  try {
8899
- mcpJsonForRebind = JSON.parse(readFileSync17(join21(projectDir, ".mcp.json"), "utf-8"));
9027
+ mcpJsonForRebind = JSON.parse(readFileSync18(join22(projectDir, ".mcp.json"), "utf-8"));
8900
9028
  } catch {
8901
9029
  mcpJsonForRebind = null;
8902
9030
  }
@@ -9026,7 +9154,7 @@ function checkMcpConfigDriftAndScheduleRestart(codeName, projectDir) {
9026
9154
  function projectChannelSecretHash(projectDir) {
9027
9155
  try {
9028
9156
  const entries = parseEnvIntegrations(
9029
- readFileSync17(join21(projectDir, ".env.integrations"), "utf-8")
9157
+ readFileSync18(join22(projectDir, ".env.integrations"), "utf-8")
9030
9158
  );
9031
9159
  return channelSecretValueHash(entries, CHANNEL_SECRET_ENV_KEYS);
9032
9160
  } catch {
@@ -9120,7 +9248,7 @@ var agentRestartTimezoneInputs = /* @__PURE__ */ new Map();
9120
9248
  var lastVersionCheckAt = 0;
9121
9249
  var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
9122
9250
  var lastResponsivenessProbeAt = 0;
9123
- var agtCliVersion = true ? "0.28.390" : "dev";
9251
+ var agtCliVersion = true ? "0.28.392" : "dev";
9124
9252
  function resolveBrewPath(execFileSync2) {
9125
9253
  try {
9126
9254
  const out = execFileSync2("which", ["brew"], { timeout: 5e3 }).toString().trim();
@@ -9215,7 +9343,7 @@ async function ensureToolkitCli(toolkitSlug) {
9215
9343
  toolkitCliEnsured.add(toolkitSlug);
9216
9344
  return;
9217
9345
  }
9218
- brewBinDir = dirname5(brewPath);
9346
+ brewBinDir = dirname6(brewPath);
9219
9347
  const isRoot = typeof process.getuid === "function" && process.getuid() === 0;
9220
9348
  log(`[toolkit-install] ${toolkitSlug}: installing via brew (${pkg})\u2026`);
9221
9349
  if (isRoot) {
@@ -9409,7 +9537,7 @@ function ensureClaudeManagedSettings(path = claudeManagedSettingsPath()) {
9409
9537
  try {
9410
9538
  let settings = {};
9411
9539
  if (existsSync11(path)) {
9412
- const raw = readFileSync17(path, "utf-8").trim();
9540
+ const raw = readFileSync18(path, "utf-8").trim();
9413
9541
  if (raw) {
9414
9542
  let parsed;
9415
9543
  try {
@@ -9425,8 +9553,8 @@ function ensureClaudeManagedSettings(path = claudeManagedSettingsPath()) {
9425
9553
  }
9426
9554
  if (settings.channelsEnabled === true) return "ok";
9427
9555
  settings.channelsEnabled = true;
9428
- mkdirSync8(dirname5(path), { recursive: true });
9429
- writeFileSync11(path, `${JSON.stringify(settings, null, 2)}
9556
+ mkdirSync9(dirname6(path), { recursive: true });
9557
+ writeFileSync12(path, `${JSON.stringify(settings, null, 2)}
9430
9558
  `);
9431
9559
  log(`[managed-settings] set channelsEnabled:true in ${path} (ENG-5786 \u2014 unblocks Claude Code channels)`);
9432
9560
  return "ok";
@@ -9464,7 +9592,7 @@ async function ensureOpencodeBinary() {
9464
9592
  try {
9465
9593
  const prefix = execFileSync2("npm", ["prefix", "-g"], { encoding: "utf-8", timeout: 1e4 }).trim();
9466
9594
  if (prefix) {
9467
- const npmBin = join21(prefix, "bin");
9595
+ const npmBin = join22(prefix, "bin");
9468
9596
  const current = (process.env.PATH ?? "").split(pathDelimiter);
9469
9597
  if (!current.includes(npmBin)) {
9470
9598
  process.env.PATH = [npmBin, ...current.filter(Boolean)].join(pathDelimiter);
@@ -9521,7 +9649,7 @@ async function ensureFrameworkBinary(frameworkId) {
9521
9649
  log(`Claude Code install failed: ${err.message}`);
9522
9650
  return;
9523
9651
  }
9524
- const brewBinDir = dirname5(brewPath);
9652
+ const brewBinDir = dirname6(brewPath);
9525
9653
  if (!process.env.PATH?.split(":").includes(brewBinDir)) {
9526
9654
  process.env.PATH = `${brewBinDir}:${process.env.PATH ?? ""}`;
9527
9655
  }
@@ -9581,7 +9709,7 @@ ${r.stderr}`;
9581
9709
  }
9582
9710
  var UPDATE_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
9583
9711
  function selfUpdateAppliedMarkerPath() {
9584
- return join21(homedir10(), ".augmented", ".last-self-update-applied");
9712
+ return join22(homedir10(), ".augmented", ".last-self-update-applied");
9585
9713
  }
9586
9714
  var selfUpdateUpToDateLogged = false;
9587
9715
  var selfUpdatePinnedLogged = false;
@@ -9607,7 +9735,7 @@ async function checkAndUpdateCli(opts) {
9607
9735
  const isNpmGlobal = !isBrewFormula && resolvedPath.includes("node_modules");
9608
9736
  if (!isBrewFormula && !isNpmGlobal) return "noop";
9609
9737
  const { readFileSync: readF, writeFileSync: writeF } = await import("fs");
9610
- const markerPath = join21(homedir10(), ".augmented", ".last-update-check");
9738
+ const markerPath = join22(homedir10(), ".augmented", ".last-update-check");
9611
9739
  if (!force) {
9612
9740
  try {
9613
9741
  const lastCheck = parseInt(readF(markerPath, "utf-8").trim(), 10);
@@ -9953,13 +10081,13 @@ async function checkClaudeAuth() {
9953
10081
  var evalEmptyMcpConfigPath = null;
9954
10082
  function ensureEvalEmptyMcpConfig() {
9955
10083
  if (evalEmptyMcpConfigPath && existsSync11(evalEmptyMcpConfigPath)) return evalEmptyMcpConfigPath;
9956
- const dir = join21(homedir10(), ".augmented");
10084
+ const dir = join22(homedir10(), ".augmented");
9957
10085
  try {
9958
- mkdirSync8(dir, { recursive: true });
10086
+ mkdirSync9(dir, { recursive: true });
9959
10087
  } catch {
9960
10088
  }
9961
- const p = join21(dir, ".eval-empty-mcp.json");
9962
- writeFileSync11(p, JSON.stringify({ mcpServers: {} }));
10089
+ const p = join22(dir, ".eval-empty-mcp.json");
10090
+ writeFileSync12(p, JSON.stringify({ mcpServers: {} }));
9963
10091
  evalEmptyMcpConfigPath = p;
9964
10092
  return p;
9965
10093
  }
@@ -10050,10 +10178,10 @@ function resolveConversationEvalBackend() {
10050
10178
  return conversationEvalBackend;
10051
10179
  }
10052
10180
  function getStateFile() {
10053
- return join21(config?.configDir ?? join21(process.env["HOME"] ?? "/tmp", ".augmented"), "manager-state.json");
10181
+ return join22(config?.configDir ?? join22(process.env["HOME"] ?? "/tmp", ".augmented"), "manager-state.json");
10054
10182
  }
10055
10183
  function channelHashCacheDir() {
10056
- return config?.configDir ?? join21(process.env["HOME"] ?? "/tmp", ".augmented");
10184
+ return config?.configDir ?? join22(process.env["HOME"] ?? "/tmp", ".augmented");
10057
10185
  }
10058
10186
  function loadChannelHashCache2() {
10059
10187
  loadChannelHashCache(agentState.knownChannelConfigHashes, channelHashCacheDir());
@@ -10105,7 +10233,7 @@ function removeDeliveryBaselineEntries(agentId) {
10105
10233
  var _channelQuarantineStore = null;
10106
10234
  function channelQuarantineStore() {
10107
10235
  if (!_channelQuarantineStore) {
10108
- const dir = config?.configDir ?? join21(process.env["HOME"] ?? "/tmp", ".augmented");
10236
+ const dir = config?.configDir ?? join22(process.env["HOME"] ?? "/tmp", ".augmented");
10109
10237
  _channelQuarantineStore = new ChannelQuarantineStore(defaultQuarantinePath(dir));
10110
10238
  }
10111
10239
  return _channelQuarantineStore;
@@ -10116,7 +10244,7 @@ function quarantineEntriesFor(codeName) {
10116
10244
  var _hostFlagStore = null;
10117
10245
  function hostFlagStore() {
10118
10246
  if (!_hostFlagStore) {
10119
- const dir = config?.configDir ?? join21(process.env["HOME"] ?? "/tmp", ".augmented");
10247
+ const dir = config?.configDir ?? join22(process.env["HOME"] ?? "/tmp", ".augmented");
10120
10248
  _hostFlagStore = new HostFlagStore({ cachePath: defaultFlagsCachePath(dir), log });
10121
10249
  }
10122
10250
  return _hostFlagStore;
@@ -10183,13 +10311,13 @@ function parseSkillFrontmatter(content) {
10183
10311
  return out;
10184
10312
  }
10185
10313
  async function refreshSkillsIndexInClaudeMd(configDir, codeName, log2) {
10186
- const { readdirSync: readdirSync6, readFileSync: rfs, existsSync: ex, writeFileSync: writeFileSync12 } = await import("fs");
10187
- const skillsDir = join21(configDir, codeName, "project", ".claude", "skills");
10188
- const claudeMdPath = join21(configDir, codeName, "project", "CLAUDE.md");
10314
+ const { readdirSync: readdirSync7, readFileSync: rfs, existsSync: ex, writeFileSync: writeFileSync13 } = await import("fs");
10315
+ const skillsDir = join22(configDir, codeName, "project", ".claude", "skills");
10316
+ const claudeMdPath = join22(configDir, codeName, "project", "CLAUDE.md");
10189
10317
  if (!ex(skillsDir) || !ex(claudeMdPath)) return;
10190
10318
  const entries = [];
10191
- for (const dir of readdirSync6(skillsDir).sort()) {
10192
- const skillFile = join21(skillsDir, dir, "SKILL.md");
10319
+ for (const dir of readdirSync7(skillsDir).sort()) {
10320
+ const skillFile = join22(skillsDir, dir, "SKILL.md");
10193
10321
  if (!ex(skillFile)) continue;
10194
10322
  try {
10195
10323
  const { name, description } = parseSkillFrontmatter(rfs(skillFile, "utf-8"));
@@ -10231,7 +10359,7 @@ ${SKILLS_INDEX_END}`;
10231
10359
  next = current.trimEnd() + "\n\n" + section + "\n";
10232
10360
  }
10233
10361
  if (next !== current) {
10234
- writeFileSync12(claudeMdPath, next, "utf-8");
10362
+ writeFileSync13(claudeMdPath, next, "utf-8");
10235
10363
  log2(`Refreshed skills index in CLAUDE.md for '${codeName}' (${entries.length} skills)`);
10236
10364
  }
10237
10365
  }
@@ -10627,13 +10755,13 @@ async function pollCycle() {
10627
10755
  );
10628
10756
  if (hostFlagStore().getBoolean("wedge-transient-notice")) {
10629
10757
  try {
10630
- const paneTail = readFileSync17(paneLogPath(codeName), "utf8").slice(-65536);
10758
+ const paneTail = readFileSync18(paneLogPath(codeName), "utf8").slice(-65536);
10631
10759
  const transient = detectTransientApiErrorInLog(paneTail);
10632
10760
  if (transient) {
10633
- const wedgeHome = join21(homedir10(), ".augmented", codeName);
10761
+ const wedgeHome = join22(homedir10(), ".augmented", codeName);
10634
10762
  if (existsSync11(wedgeHome)) {
10635
10763
  atomicWriteFileSync(
10636
- join21(wedgeHome, "watchdog-give-up.json"),
10764
+ join22(wedgeHome, "watchdog-give-up.json"),
10637
10765
  JSON.stringify({
10638
10766
  gave_up_at: wedgeNow.toISOString(),
10639
10767
  reason: "transient_overload"
@@ -10882,7 +11010,7 @@ async function pollCycle() {
10882
11010
  } catch {
10883
11011
  }
10884
11012
  killAgentChannelProcesses(prev.codeName, { log });
10885
- const agentDir = join21(adapter.getAgentDir(prev.codeName), "provision");
11013
+ const agentDir = join22(adapter.getAgentDir(prev.codeName), "provision");
10886
11014
  await cleanupAgentFiles(prev.codeName, agentDir);
10887
11015
  clearAgentCaches(prev.agentId, prev.codeName);
10888
11016
  }
@@ -10969,10 +11097,10 @@ async function pollCycle() {
10969
11097
  // pending-inbound marker. Best-effort: a write failure is logged by
10970
11098
  // the watchdog, never fails the poll cycle.
10971
11099
  signalGiveUp: (codeName) => {
10972
- const dir = join21(homedir10(), ".augmented", codeName);
11100
+ const dir = join22(homedir10(), ".augmented", codeName);
10973
11101
  if (!existsSync11(dir)) return;
10974
11102
  atomicWriteFileSync(
10975
- join21(dir, "watchdog-give-up.json"),
11103
+ join22(dir, "watchdog-give-up.json"),
10976
11104
  JSON.stringify({ gave_up_at: (/* @__PURE__ */ new Date()).toISOString() })
10977
11105
  );
10978
11106
  }
@@ -11111,7 +11239,7 @@ async function processAgent(agent, agentStates) {
11111
11239
  }
11112
11240
  const now = (/* @__PURE__ */ new Date()).toISOString();
11113
11241
  const adapter = resolveAgentFramework(agent.code_name);
11114
- let agentDir = join21(adapter.getAgentDir(agent.code_name), "provision");
11242
+ let agentDir = join22(adapter.getAgentDir(agent.code_name), "provision");
11115
11243
  if (agent.status === "draft" || agent.status === "paused") {
11116
11244
  if (previousKnownStatus !== agent.status) {
11117
11245
  log(`Agent '${agent.code_name}' is ${agent.status}, skipping provisioning`);
@@ -11295,7 +11423,7 @@ async function processAgent(agent, agentStates) {
11295
11423
  const frameworkId = refreshData.agent.framework ?? DEFAULT_FRAMEWORK;
11296
11424
  agentFrameworkCache.set(agent.code_name, frameworkId);
11297
11425
  const frameworkAdapter = getFramework(frameworkId);
11298
- agentDir = join21(frameworkAdapter.getAgentDir(agent.code_name), "provision");
11426
+ agentDir = join22(frameworkAdapter.getAgentDir(agent.code_name), "provision");
11299
11427
  cacheAgentDeliveryMetadata(agent.code_name, refreshData);
11300
11428
  agentRestartTimezoneInputs.set(agent.code_name, {
11301
11429
  agentTimezone: typeof refreshData.agent.timezone === "string" ? refreshData.agent.timezone : null,
@@ -11340,9 +11468,9 @@ async function processAgent(agent, agentStates) {
11340
11468
  try {
11341
11469
  const artifacts = generateArtifacts(agent, refreshData, frameworkAdapter);
11342
11470
  const changedFiles = [];
11343
- mkdirSync8(agentDir, { recursive: true });
11471
+ mkdirSync9(agentDir, { recursive: true });
11344
11472
  for (const artifact of artifacts) {
11345
- const filePath = join21(agentDir, artifact.relativePath);
11473
+ const filePath = join22(agentDir, artifact.relativePath);
11346
11474
  let existingHash;
11347
11475
  let newHash;
11348
11476
  let writeContent = artifact.content;
@@ -11361,8 +11489,8 @@ async function processAgent(agent, agentStates) {
11361
11489
  };
11362
11490
  newHash = sha256(stripDynamicSections(artifact.content));
11363
11491
  try {
11364
- const projectClaudeMd = join21(config.configDir, agent.code_name, "project", "CLAUDE.md");
11365
- const existing = readFileSync17(projectClaudeMd, "utf-8");
11492
+ const projectClaudeMd = join22(config.configDir, agent.code_name, "project", "CLAUDE.md");
11493
+ const existing = readFileSync18(projectClaudeMd, "utf-8");
11366
11494
  existingHash = sha256(stripDynamicSections(existing));
11367
11495
  } catch {
11368
11496
  existingHash = null;
@@ -11380,7 +11508,7 @@ async function processAgent(agent, agentStates) {
11380
11508
  const generatorKeys = Object.keys(generatorServers);
11381
11509
  let existingRaw = "";
11382
11510
  try {
11383
- existingRaw = readFileSync17(filePath, "utf-8");
11511
+ existingRaw = readFileSync18(filePath, "utf-8");
11384
11512
  } catch {
11385
11513
  }
11386
11514
  const existingServers = parseMcp(existingRaw);
@@ -11396,7 +11524,7 @@ async function processAgent(agent, agentStates) {
11396
11524
  } else if (artifact.relativePath === "opencode.json") {
11397
11525
  let existingRaw = null;
11398
11526
  try {
11399
- existingRaw = readFileSync17(filePath, "utf-8");
11527
+ existingRaw = readFileSync18(filePath, "utf-8");
11400
11528
  } catch {
11401
11529
  }
11402
11530
  const mergeResult = mergeOpencodeConfigArtifact(artifact.content, existingRaw);
@@ -11412,26 +11540,26 @@ async function processAgent(agent, agentStates) {
11412
11540
  }
11413
11541
  }
11414
11542
  if (changedFiles.length > 0) {
11415
- const isFirst = !existsSync11(join21(agentDir, "CHARTER.md"));
11543
+ const isFirst = !existsSync11(join22(agentDir, "CHARTER.md"));
11416
11544
  const verb = isFirst ? "Provisioning" : "Updating";
11417
11545
  const fileNames = changedFiles.map((f) => f.relativePath).join(", ");
11418
11546
  log(`${verb} '${agent.code_name}': ${fileNames}`);
11419
11547
  for (const file of changedFiles) {
11420
- const filePath = join21(agentDir, file.relativePath);
11421
- mkdirSync8(dirname5(filePath), { recursive: true });
11548
+ const filePath = join22(agentDir, file.relativePath);
11549
+ mkdirSync9(dirname6(filePath), { recursive: true });
11422
11550
  if (file.relativePath === ".mcp.json") {
11423
11551
  safeWriteJsonAtomic(filePath, file.content, { mode: 384 });
11424
11552
  } else {
11425
- writeFileSync11(filePath, file.content);
11553
+ writeFileSync12(filePath, file.content);
11426
11554
  }
11427
11555
  }
11428
11556
  try {
11429
- const provSkillsDir = join21(agentDir, ".claude", "skills");
11557
+ const provSkillsDir = join22(agentDir, ".claude", "skills");
11430
11558
  if (existsSync11(provSkillsDir)) {
11431
- for (const folder of readdirSync5(provSkillsDir)) {
11559
+ for (const folder of readdirSync6(provSkillsDir)) {
11432
11560
  if (folder.startsWith("knowledge-")) {
11433
11561
  try {
11434
- rmSync5(join21(provSkillsDir, folder), { recursive: true });
11562
+ rmSync5(join22(provSkillsDir, folder), { recursive: true });
11435
11563
  } catch {
11436
11564
  }
11437
11565
  }
@@ -11444,7 +11572,7 @@ async function processAgent(agent, agentStates) {
11444
11572
  const trackedFiles2 = frameworkAdapter.driftTrackedFiles();
11445
11573
  const hashes = /* @__PURE__ */ new Map();
11446
11574
  for (const file of trackedFiles2) {
11447
- const h = hashFile(join21(agentDir, file));
11575
+ const h = hashFile(join22(agentDir, file));
11448
11576
  if (h) hashes.set(file, h);
11449
11577
  }
11450
11578
  agentState.writtenHashes.set(agent.agent_id, hashes);
@@ -11462,14 +11590,14 @@ async function processAgent(agent, agentStates) {
11462
11590
  }
11463
11591
  if (Array.isArray(refreshData.workflows)) {
11464
11592
  try {
11465
- const provWorkflowsDir = join21(agentDir, ".claude", "workflows");
11593
+ const provWorkflowsDir = join22(agentDir, ".claude", "workflows");
11466
11594
  if (existsSync11(provWorkflowsDir)) {
11467
11595
  const expected = new Set(refreshData.workflows.map((w) => `${w.name}.js`));
11468
- for (const file of readdirSync5(provWorkflowsDir)) {
11596
+ for (const file of readdirSync6(provWorkflowsDir)) {
11469
11597
  if (!file.endsWith(".js")) continue;
11470
11598
  if (expected.has(file)) continue;
11471
11599
  try {
11472
- rmSync5(join21(provWorkflowsDir, file));
11600
+ rmSync5(join22(provWorkflowsDir, file));
11473
11601
  } catch {
11474
11602
  }
11475
11603
  }
@@ -11551,7 +11679,7 @@ async function processAgent(agent, agentStates) {
11551
11679
  if (written && existsSync11(agentDir)) {
11552
11680
  const driftedFiles = [];
11553
11681
  for (const [file, expectedHash] of written) {
11554
- const localHash = hashFile(join21(agentDir, file));
11682
+ const localHash = hashFile(join22(agentDir, file));
11555
11683
  if (localHash && localHash !== expectedHash) {
11556
11684
  driftedFiles.push(file);
11557
11685
  }
@@ -11562,7 +11690,7 @@ async function processAgent(agent, agentStates) {
11562
11690
  try {
11563
11691
  const localHashes = {};
11564
11692
  for (const file of driftedFiles) {
11565
- localHashes[file] = hashFile(join21(agentDir, file));
11693
+ localHashes[file] = hashFile(join22(agentDir, file));
11566
11694
  }
11567
11695
  await api.post("/host/drift", {
11568
11696
  agent_id: agent.agent_id,
@@ -11749,15 +11877,15 @@ async function processAgent(agent, agentStates) {
11749
11877
  const addedChannels = [...restartDecision.added];
11750
11878
  const writeDmNoticeMarkers = isChannelAddRestart ? () => {
11751
11879
  try {
11752
- const agentAugmentedDir = join21(homedir10(), ".augmented", agent.code_name);
11753
- mkdirSync8(agentAugmentedDir, { recursive: true });
11880
+ const agentAugmentedDir = join22(homedir10(), ".augmented", agent.code_name);
11881
+ mkdirSync9(agentAugmentedDir, { recursive: true });
11754
11882
  const markerJson = JSON.stringify({
11755
11883
  version: 1,
11756
11884
  at: (/* @__PURE__ */ new Date()).toISOString(),
11757
11885
  added: addedChannels
11758
11886
  });
11759
11887
  for (const file of ["slack-channel-add-restart.json", "telegram-channel-add-restart.json"]) {
11760
- atomicWriteFileSync(join21(agentAugmentedDir, file), markerJson);
11888
+ atomicWriteFileSync(join22(agentAugmentedDir, file), markerJson);
11761
11889
  }
11762
11890
  } catch (err) {
11763
11891
  log(`[hot-reload] channel-add DM-notice marker write failed for '${agent.code_name}' (non-fatal): ${err.message}`);
@@ -11946,18 +12074,18 @@ async function processAgent(agent, agentStates) {
11946
12074
  if (agentSessionMode === "persistent" && (agentFrameworkCache.get(agent.code_name) ?? DEFAULT_FRAMEWORK) === "claude-code") {
11947
12075
  try {
11948
12076
  const agentProvisionDir = agentDir;
11949
- const projectDir = join21(homedir10(), ".augmented", agent.code_name, "project");
11950
- mkdirSync8(agentProvisionDir, { recursive: true });
11951
- mkdirSync8(projectDir, { recursive: true });
11952
- const provisionMcpPath = join21(agentProvisionDir, ".mcp.json");
11953
- const projectMcpPath = join21(projectDir, ".mcp.json");
12077
+ const projectDir = join22(homedir10(), ".augmented", agent.code_name, "project");
12078
+ mkdirSync9(agentProvisionDir, { recursive: true });
12079
+ mkdirSync9(projectDir, { recursive: true });
12080
+ const provisionMcpPath = join22(agentProvisionDir, ".mcp.json");
12081
+ const projectMcpPath = join22(projectDir, ".mcp.json");
11954
12082
  let mcpConfig = { mcpServers: {} };
11955
12083
  try {
11956
- mcpConfig = JSON.parse(readFileSync17(provisionMcpPath, "utf-8"));
12084
+ mcpConfig = JSON.parse(readFileSync18(provisionMcpPath, "utf-8"));
11957
12085
  if (!mcpConfig.mcpServers) mcpConfig.mcpServers = {};
11958
12086
  } catch {
11959
12087
  }
11960
- const localDirectChatChannel = join21(homedir10(), ".augmented", "_mcp", "direct-chat-channel.js");
12088
+ const localDirectChatChannel = join22(homedir10(), ".augmented", "_mcp", "direct-chat-channel.js");
11961
12089
  const directChatTeamSettings = refreshData.team?.settings;
11962
12090
  const directChatTz = (() => {
11963
12091
  const tz = directChatTeamSettings?.["timezone"];
@@ -11983,7 +12111,7 @@ async function processAgent(agent, agentStates) {
11983
12111
  // ~/.augmented/<codeName>/.current-turn-initiator.json. Note getAgentDir
11984
12112
  // returns the agent root (NOT the /provision subdir `agentDir` points at),
11985
12113
  // so it byte-matches the broker readers' path.
11986
- AGT_TURN_INITIATOR_FILE: join21(
12114
+ AGT_TURN_INITIATOR_FILE: join22(
11987
12115
  frameworkAdapter.getAgentDir(agent.code_name),
11988
12116
  ".current-turn-initiator.json"
11989
12117
  )
@@ -12003,7 +12131,7 @@ async function processAgent(agent, agentStates) {
12003
12131
  log(`Channel credentials written for '${agent.code_name}/direct-chat'`);
12004
12132
  }
12005
12133
  }
12006
- const staleChannelsPath = join21(projectDir, ".mcp-channels.json");
12134
+ const staleChannelsPath = join22(projectDir, ".mcp-channels.json");
12007
12135
  if (existsSync11(staleChannelsPath)) {
12008
12136
  try {
12009
12137
  rmSync5(staleChannelsPath, { force: true });
@@ -12093,7 +12221,7 @@ async function processAgent(agent, agentStates) {
12093
12221
  }
12094
12222
  if (hostFlagStore().getBoolean("connectivity-probe")) {
12095
12223
  try {
12096
- const probeProjectDir = join21(homedir10(), ".augmented", agent.code_name, "project");
12224
+ const probeProjectDir = join22(homedir10(), ".augmented", agent.code_name, "project");
12097
12225
  await runAgentConnectivityProbes(agent, integrations, probeProjectDir);
12098
12226
  } catch (err) {
12099
12227
  log(`Connectivity probe failed for '${agent.code_name}': ${err.message}`);
@@ -12104,7 +12232,7 @@ async function processAgent(agent, agentStates) {
12104
12232
  const forceDue = attemptsLeft > 0;
12105
12233
  let probeRan = false;
12106
12234
  try {
12107
- const probeProjectDir = join21(homedir10(), ".augmented", agent.code_name, "project");
12235
+ const probeProjectDir = join22(homedir10(), ".augmented", agent.code_name, "project");
12108
12236
  probeRan = await runAgentSessionToolBindProbes(agent, integrations, probeProjectDir, { forceDue });
12109
12237
  } catch (err) {
12110
12238
  log(`Session-tool-bind probe failed for '${agent.code_name}': ${err.message}`);
@@ -12119,7 +12247,7 @@ async function processAgent(agent, agentStates) {
12119
12247
  const mcpPath = frameworkAdapter.getMcpPath(agent.code_name);
12120
12248
  if (mcpPath && existsSync11(mcpPath)) {
12121
12249
  try {
12122
- const cfg = JSON.parse(readFileSync17(mcpPath, "utf-8"));
12250
+ const cfg = JSON.parse(readFileSync18(mcpPath, "utf-8"));
12123
12251
  const expectedRemoteKeys = new Set(
12124
12252
  integrations.map((i) => i.definition_id)
12125
12253
  );
@@ -12168,11 +12296,11 @@ async function processAgent(agent, agentStates) {
12168
12296
  const intHash = computeIntegrationsHash(integrations);
12169
12297
  const prevIntHash = agentState.knownIntegrationHashes.get(agent.agent_id);
12170
12298
  if (intHash !== prevIntHash) {
12171
- const projectDir = join21(homedir10(), ".augmented", agent.code_name, "project");
12172
- const envIntPath = join21(projectDir, ".env.integrations");
12299
+ const projectDir = join22(homedir10(), ".augmented", agent.code_name, "project");
12300
+ const envIntPath = join22(projectDir, ".env.integrations");
12173
12301
  let preWriteEnv;
12174
12302
  try {
12175
- preWriteEnv = readFileSync17(envIntPath, "utf-8");
12303
+ preWriteEnv = readFileSync18(envIntPath, "utf-8");
12176
12304
  } catch {
12177
12305
  preWriteEnv = void 0;
12178
12306
  }
@@ -12189,9 +12317,9 @@ async function processAgent(agent, agentStates) {
12189
12317
  }
12190
12318
  if (fw === "claude-code" && isSessionHealthy(agent.code_name)) {
12191
12319
  try {
12192
- const projectMcpPath = join21(projectDir, ".mcp.json");
12193
- const postWriteEnv = readFileSync17(envIntPath, "utf-8");
12194
- const mcpContent = readFileSync17(projectMcpPath, "utf-8");
12320
+ const projectMcpPath = join22(projectDir, ".mcp.json");
12321
+ const postWriteEnv = readFileSync18(envIntPath, "utf-8");
12322
+ const mcpContent = readFileSync18(projectMcpPath, "utf-8");
12195
12323
  const changedVars = diffEnvIntegrations(preWriteEnv, postWriteEnv);
12196
12324
  const mcpJsonForReap = JSON.parse(mcpContent);
12197
12325
  const affectedServerKeys = findMcpServersUsingVars(mcpJsonForReap, changedVars);
@@ -12298,8 +12426,8 @@ async function processAgent(agent, agentStates) {
12298
12426
  const mcpPath = frameworkAdapter.getMcpPath(agent.code_name);
12299
12427
  if (mcpPath) {
12300
12428
  try {
12301
- const { readFileSync: readFileSync18 } = await import("fs");
12302
- const mcpConfig = JSON.parse(readFileSync18(mcpPath, "utf-8"));
12429
+ const { readFileSync: readFileSync19 } = await import("fs");
12430
+ const mcpConfig = JSON.parse(readFileSync19(mcpPath, "utf-8"));
12303
12431
  if (mcpConfig.mcpServers) {
12304
12432
  for (const key of Object.keys(mcpConfig.mcpServers)) {
12305
12433
  if (isManagedMcpServerKey(key) && !expectedServerIds.has(key)) {
@@ -12441,23 +12569,23 @@ async function processAgent(agent, agentStates) {
12441
12569
  }
12442
12570
  }
12443
12571
  try {
12444
- const { readdirSync: readdirSync6, rmSync: rmSync6 } = await import("fs");
12572
+ const { readdirSync: readdirSync7, rmSync: rmSync6 } = await import("fs");
12445
12573
  const { homedir: homedir11 } = await import("os");
12446
12574
  const frameworkId2 = frameworkAdapter.id;
12447
12575
  const candidateSkillDirs = [
12448
12576
  // Claude Code — framework runtime tree
12449
- join21(homedir11(), ".augmented", agent.code_name, "skills"),
12577
+ join22(homedir11(), ".augmented", agent.code_name, "skills"),
12450
12578
  // Claude Code — project tree
12451
- join21(homedir11(), ".augmented", agent.code_name, "project", ".claude", "skills"),
12579
+ join22(homedir11(), ".augmented", agent.code_name, "project", ".claude", "skills"),
12452
12580
  // Defensive: legacy provision-side path, not currently an
12453
12581
  // install target but cheap to sweep.
12454
- join21(agentDir, ".claude", "skills")
12582
+ join22(agentDir, ".claude", "skills")
12455
12583
  ];
12456
12584
  const existingDirs = candidateSkillDirs.filter((d) => existsSync11(d));
12457
12585
  const discoveredEntries = /* @__PURE__ */ new Set();
12458
12586
  for (const dir of existingDirs) {
12459
12587
  try {
12460
- for (const entry of readdirSync6(dir)) {
12588
+ for (const entry of readdirSync7(dir)) {
12461
12589
  if (entry.startsWith("plugin-") || entry.startsWith("integration-")) {
12462
12590
  discoveredEntries.add(entry);
12463
12591
  }
@@ -12467,7 +12595,7 @@ async function processAgent(agent, agentStates) {
12467
12595
  }
12468
12596
  const removeSkillFolder = (entry, reason) => {
12469
12597
  for (const dir of existingDirs) {
12470
- const p = join21(dir, entry);
12598
+ const p = join22(dir, entry);
12471
12599
  if (existsSync11(p)) {
12472
12600
  rmSync6(p, { recursive: true, force: true });
12473
12601
  }
@@ -12487,7 +12615,7 @@ async function processAgent(agent, agentStates) {
12487
12615
  const sharedSkillsPayload = refreshAny.shared_skills;
12488
12616
  const desiredResolved = globalSkillsPayload !== void 0 || sharedSkillsPayload !== void 0;
12489
12617
  const manifestPath = managedSkillManifestPath(
12490
- join21(homedir10(), ".augmented", agent.code_name)
12618
+ join22(homedir10(), ".augmented", agent.code_name)
12491
12619
  );
12492
12620
  const prevIds = /* @__PURE__ */ new Set([
12493
12621
  ...agentState.knownGlobalSkillIds.get(agent.agent_id) ?? /* @__PURE__ */ new Set(),
@@ -12507,15 +12635,15 @@ async function processAgent(agent, agentStates) {
12507
12635
  }
12508
12636
  if (plan.removes.length) {
12509
12637
  const globalSkillDirs = [
12510
- join21(homedir10(), ".augmented", agent.code_name, "skills"),
12511
- join21(homedir10(), ".augmented", agent.code_name, "project", ".claude", "skills"),
12512
- join21(agentDir, ".claude", "skills")
12638
+ join22(homedir10(), ".augmented", agent.code_name, "skills"),
12639
+ join22(homedir10(), ".augmented", agent.code_name, "project", ".claude", "skills"),
12640
+ join22(agentDir, ".claude", "skills")
12513
12641
  ];
12514
12642
  for (const id of plan.removes) {
12515
12643
  let prunedAny = false;
12516
12644
  for (const dir of globalSkillDirs) {
12517
- const p = join21(dir, id);
12518
- if (existsSync11(p) && existsSync11(join21(p, "SKILL.md"))) {
12645
+ const p = join22(dir, id);
12646
+ if (existsSync11(p) && existsSync11(join22(p, "SKILL.md"))) {
12519
12647
  rmSync5(p, { recursive: true, force: true });
12520
12648
  prunedAny = true;
12521
12649
  }
@@ -12734,8 +12862,8 @@ async function processAgent(agent, agentStates) {
12734
12862
  const sess = getSessionState(agent.code_name);
12735
12863
  let mcpJsonParsed = null;
12736
12864
  try {
12737
- const mcpPath = join21(getProjectDir(agent.code_name), ".mcp.json");
12738
- mcpJsonParsed = JSON.parse(readFileSync17(mcpPath, "utf-8"));
12865
+ const mcpPath = join22(getProjectDir(agent.code_name), ".mcp.json");
12866
+ mcpJsonParsed = JSON.parse(readFileSync18(mcpPath, "utf-8"));
12739
12867
  } catch {
12740
12868
  }
12741
12869
  reapMissingMcpSessions({
@@ -13094,7 +13222,7 @@ Retried to the limit after repeated stalls \u2014 needs a look.`).catch(() => {
13094
13222
  if (trackedFiles.length > 0 && existsSync11(agentDir)) {
13095
13223
  const hashes = /* @__PURE__ */ new Map();
13096
13224
  for (const file of trackedFiles) {
13097
- const h = hashFile(join21(agentDir, file));
13225
+ const h = hashFile(join22(agentDir, file));
13098
13226
  if (h) hashes.set(file, h);
13099
13227
  }
13100
13228
  agentState.writtenHashes.set(agent.agent_id, hashes);
@@ -13109,7 +13237,7 @@ Retried to the limit after repeated stalls \u2014 needs a look.`).catch(() => {
13109
13237
  refreshData.agent.onboarding_state
13110
13238
  );
13111
13239
  const obStep = obState.step;
13112
- const markerPath = join21(homedir10(), ".augmented", agent.code_name, "onboarding-drive.json");
13240
+ const markerPath = join22(homedir10(), ".augmented", agent.code_name, "onboarding-drive.json");
13113
13241
  const marker = readOnboardingDriveMarker(markerPath);
13114
13242
  const decision = decideOnboardingDrive(obStep, marker, Date.now(), obState.generation ?? 0);
13115
13243
  if (decision.clearMarker) {
@@ -13179,7 +13307,7 @@ async function ensureOpencodeRuntime(agent, refreshData, agentTimezone) {
13179
13307
  }
13180
13308
  stopOpencodeSlackIngest(codeName, log);
13181
13309
  stopOpencodeTelegramIngest(codeName, log);
13182
- const opencodeProjectDir = join21(getFramework("opencode").getAgentDir(codeName), "provision");
13310
+ const opencodeProjectDir = join22(getFramework("opencode").getAgentDir(codeName), "provision");
13183
13311
  const openRouterRaw = refreshData.openrouter ?? null;
13184
13312
  const anthropicRaw = refreshData.anthropic ?? null;
13185
13313
  const serveEnv = {
@@ -13221,8 +13349,8 @@ async function ensureOpencodeRuntime(agent, refreshData, agentTimezone) {
13221
13349
  async function ensurePersistentSession(agent, tasks, boardItems, refreshData) {
13222
13350
  const codeName = agent.code_name;
13223
13351
  const projectDir = getProjectDir(codeName);
13224
- const mcpConfigPath = join21(projectDir, ".mcp.json");
13225
- const claudeMdPath = join21(projectDir, "CLAUDE.md");
13352
+ const mcpConfigPath = join22(projectDir, ".mcp.json");
13353
+ const claudeMdPath = join22(projectDir, "CLAUDE.md");
13226
13354
  if (restartBreaker.isTripped(codeName)) {
13227
13355
  const trip = restartBreaker.getTrip(codeName);
13228
13356
  return {
@@ -14096,8 +14224,8 @@ async function processDirectChatMessage(agent, msg) {
14096
14224
  if (useDoorbell) {
14097
14225
  try {
14098
14226
  const doorbell = directChatDoorbellPath(agent.agentId, homedir10());
14099
- mkdirSync8(dirname5(doorbell), { recursive: true });
14100
- writeFileSync11(doorbell, String(Date.now()));
14227
+ mkdirSync9(dirname6(doorbell), { recursive: true });
14228
+ writeFileSync12(doorbell, String(Date.now()));
14101
14229
  log(`[direct-chat] Doorbell rung for '${agent.codeName}' (msg=${msg.id}) \u2014 in-session MCP will pull via the cursor`);
14102
14230
  return;
14103
14231
  } catch (err) {
@@ -14206,8 +14334,8 @@ ${formatRunMarker(run_id)}` : KANBAN_CHECK_COMMAND;
14206
14334
  if (run_id) openInjectedRunByCode.set(codeName, run_id);
14207
14335
  try {
14208
14336
  const doorbell = directChatDoorbellPath(agentId, homedir10());
14209
- mkdirSync8(dirname5(doorbell), { recursive: true });
14210
- writeFileSync11(doorbell, String(Date.now()));
14337
+ mkdirSync9(dirname6(doorbell), { recursive: true });
14338
+ writeFileSync12(doorbell, String(Date.now()));
14211
14339
  } catch (err) {
14212
14340
  log(`[kanban] doorbell ring failed for '${codeName}': ${err.message} (notice still queued)`);
14213
14341
  }
@@ -14513,8 +14641,8 @@ function parseMemoryFile(raw, fallbackName) {
14513
14641
  };
14514
14642
  }
14515
14643
  async function syncMemories(agent, configDir, log2) {
14516
- const projectDir = join21(configDir, agent.code_name, "project");
14517
- const memoryDir = join21(projectDir, "memory");
14644
+ const projectDir = join22(configDir, agent.code_name, "project");
14645
+ const memoryDir = join22(projectDir, "memory");
14518
14646
  const isFreshSync = pendingFreshMemorySync.has(agent.agent_id);
14519
14647
  if (isFreshSync) {
14520
14648
  log2(`[memory-sync] Fresh-sync requested for '${agent.code_name}' \u2014 pulling DB first`);
@@ -14529,10 +14657,10 @@ async function syncMemories(agent, configDir, log2) {
14529
14657
  const prevHashes = memoryFileHashes.get(agent.agent_id) ?? /* @__PURE__ */ new Map();
14530
14658
  const currentHashes = /* @__PURE__ */ new Map();
14531
14659
  const changedMemories = [];
14532
- for (const file of readdirSync5(memoryDir)) {
14660
+ for (const file of readdirSync6(memoryDir)) {
14533
14661
  if (!file.endsWith(".md")) continue;
14534
14662
  try {
14535
- const raw = readFileSync17(join21(memoryDir, file), "utf-8");
14663
+ const raw = readFileSync18(join22(memoryDir, file), "utf-8");
14536
14664
  const fileHash = createHash13("sha256").update(raw).digest("hex").slice(0, 16);
14537
14665
  currentHashes.set(file, fileHash);
14538
14666
  if (prevHashes.get(file) === fileHash) continue;
@@ -14557,7 +14685,7 @@ async function syncMemories(agent, configDir, log2) {
14557
14685
  } catch (err) {
14558
14686
  for (const mem of changedMemories) {
14559
14687
  for (const [file] of currentHashes) {
14560
- const parsed = parseMemoryFile(readFileSync17(join21(memoryDir, file), "utf-8"), file.replace(/\.md$/, ""));
14688
+ const parsed = parseMemoryFile(readFileSync18(join22(memoryDir, file), "utf-8"), file.replace(/\.md$/, ""));
14561
14689
  if (parsed?.name === mem.name) currentHashes.delete(file);
14562
14690
  }
14563
14691
  }
@@ -14570,7 +14698,7 @@ async function syncMemories(agent, configDir, log2) {
14570
14698
  }
14571
14699
  }
14572
14700
  async function downloadMemories(agent, memoryDir, log2, { force }) {
14573
- const localFiles = existsSync11(memoryDir) ? readdirSync5(memoryDir).filter((f) => f.endsWith(".md")).sort() : [];
14701
+ const localFiles = existsSync11(memoryDir) ? readdirSync6(memoryDir).filter((f) => f.endsWith(".md")).sort() : [];
14574
14702
  const localListHash = createHash13("sha256").update(localFiles.join(",")).digest("hex").slice(0, 16);
14575
14703
  const prevLocalHash = lastLocalFileHash.get(agent.agent_id);
14576
14704
  const prevDownload = lastDownloadHash.get(agent.agent_id);
@@ -14585,14 +14713,14 @@ async function downloadMemories(agent, memoryDir, log2, { force }) {
14585
14713
  lastDownloadHash.set(agent.agent_id, responseHash);
14586
14714
  lastLocalFileHash.set(agent.agent_id, localListHash);
14587
14715
  if (dbMemories.memories?.length) {
14588
- mkdirSync8(memoryDir, { recursive: true });
14716
+ mkdirSync9(memoryDir, { recursive: true });
14589
14717
  let written = 0;
14590
14718
  let overwritten = 0;
14591
14719
  for (let i = 0; i < dbMemories.memories.length; i++) {
14592
14720
  const mem = dbMemories.memories[i];
14593
14721
  const rawSlug = mem.name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)/g, "").slice(0, 60);
14594
14722
  const slug = rawSlug || `memory-${i}`;
14595
- const filePath = join21(memoryDir, `${slug}.md`);
14723
+ const filePath = join22(memoryDir, `${slug}.md`);
14596
14724
  const desired = `---
14597
14725
  name: ${JSON.stringify(mem.name)}
14598
14726
  type: ${mem.type}
@@ -14604,19 +14732,19 @@ ${mem.content}
14604
14732
  if (existsSync11(filePath)) {
14605
14733
  let existing = "";
14606
14734
  try {
14607
- existing = readFileSync17(filePath, "utf-8");
14735
+ existing = readFileSync18(filePath, "utf-8");
14608
14736
  } catch {
14609
14737
  }
14610
14738
  if (existing === desired) continue;
14611
- writeFileSync11(filePath, desired);
14739
+ writeFileSync12(filePath, desired);
14612
14740
  overwritten++;
14613
14741
  } else {
14614
- writeFileSync11(filePath, desired);
14742
+ writeFileSync12(filePath, desired);
14615
14743
  written++;
14616
14744
  }
14617
14745
  }
14618
14746
  if (written > 0 || overwritten > 0) {
14619
- const updatedFiles = readdirSync5(memoryDir).filter((f) => f.endsWith(".md")).sort();
14747
+ const updatedFiles = readdirSync6(memoryDir).filter((f) => f.endsWith(".md")).sort();
14620
14748
  lastLocalFileHash.set(agent.agent_id, createHash13("sha256").update(updatedFiles.join(",")).digest("hex").slice(0, 16));
14621
14749
  log2(`Memory download for '${agent.code_name}': wrote ${written} new, overwrote ${overwritten} stale`);
14622
14750
  }
@@ -14866,7 +14994,7 @@ function startManager(opts) {
14866
14994
  try {
14867
14995
  const stateFile = getStateFile();
14868
14996
  if (existsSync11(stateFile)) {
14869
- const raw = readFileSync17(stateFile, "utf-8");
14997
+ const raw = readFileSync18(stateFile, "utf-8");
14870
14998
  const parsed = JSON.parse(raw);
14871
14999
  if (Array.isArray(parsed.agents)) {
14872
15000
  state6.agents = parsed.agents;
@@ -14893,7 +15021,7 @@ function startManager(opts) {
14893
15021
  log(`[startup] state rehydration failed (continuing with empty state): ${err.message}`);
14894
15022
  }
14895
15023
  log(
14896
- `[startup] worker pid=${process.pid} ppid=${process.ppid} node=${process.version} log=${join21(homedir10(), ".augmented", "manager.log")}`
15024
+ `[startup] worker pid=${process.pid} ppid=${process.ppid} node=${process.version} log=${join22(homedir10(), ".augmented", "manager.log")}`
14897
15025
  );
14898
15026
  deployMcpAssets();
14899
15027
  reapOrphanChannelMcps({ log });
@@ -14903,6 +15031,14 @@ function startManager(opts) {
14903
15031
  } catch (err) {
14904
15032
  log(`[drain] boot reaper failed: ${err.message}`);
14905
15033
  }
15034
+ try {
15035
+ refreshSlackRestartContextHints(
15036
+ state6.agents.map((a) => a.codeName),
15037
+ { log }
15038
+ );
15039
+ } catch (err) {
15040
+ log(`[restart-context] boot refresh failed (continuing): ${err.message}`);
15041
+ }
14906
15042
  void ensureHostFrameworkBinaries();
14907
15043
  startPolling();
14908
15044
  })();
@@ -14914,7 +15050,7 @@ async function reapOrphanedClaudePids() {
14914
15050
  const looksLikeClaude = (pid) => {
14915
15051
  if (process.platform !== "linux") return true;
14916
15052
  try {
14917
- const comm = readFileSync17(`/proc/${pid}/comm`, "utf-8").trim().toLowerCase();
15053
+ const comm = readFileSync18(`/proc/${pid}/comm`, "utf-8").trim().toLowerCase();
14918
15054
  return comm.includes("claude");
14919
15055
  } catch {
14920
15056
  return false;
@@ -15011,18 +15147,18 @@ function restartRunningChannelMcps(basenames) {
15011
15147
  }
15012
15148
  }
15013
15149
  function deployMcpAssets() {
15014
- const targetDir = join21(homedir10(), ".augmented", "_mcp");
15015
- mkdirSync8(targetDir, { recursive: true });
15016
- const moduleDir = dirname5(fileURLToPath(import.meta.url));
15150
+ const targetDir = join22(homedir10(), ".augmented", "_mcp");
15151
+ mkdirSync9(targetDir, { recursive: true });
15152
+ const moduleDir = dirname6(fileURLToPath(import.meta.url));
15017
15153
  let mcpSourceDir = "";
15018
15154
  let dir = moduleDir;
15019
15155
  for (let i = 0; i < 6; i++) {
15020
- const candidate = join21(dir, "dist", "mcp");
15021
- if (existsSync11(join21(candidate, "index.js"))) {
15156
+ const candidate = join22(dir, "dist", "mcp");
15157
+ if (existsSync11(join22(candidate, "index.js"))) {
15022
15158
  mcpSourceDir = candidate;
15023
15159
  break;
15024
15160
  }
15025
- const parent = dirname5(dir);
15161
+ const parent = dirname6(dir);
15026
15162
  if (parent === dir) break;
15027
15163
  dir = parent;
15028
15164
  }
@@ -15034,7 +15170,7 @@ function deployMcpAssets() {
15034
15170
  const fileHash = (p) => {
15035
15171
  try {
15036
15172
  if (!existsSync11(p)) return null;
15037
- return createHash13("sha256").update(readFileSync17(p)).digest("hex");
15173
+ return createHash13("sha256").update(readFileSync18(p)).digest("hex");
15038
15174
  } catch {
15039
15175
  return null;
15040
15176
  }
@@ -15098,8 +15234,8 @@ function deployMcpAssets() {
15098
15234
  // needs restarting to pick up a token rotation.
15099
15235
  "xero.js"
15100
15236
  ]) {
15101
- const src = join21(mcpSourceDir, file);
15102
- const dst = join21(targetDir, file);
15237
+ const src = join22(mcpSourceDir, file);
15238
+ const dst = join22(targetDir, file);
15103
15239
  if (!existsSync11(src)) continue;
15104
15240
  const before = fileHash(dst);
15105
15241
  try {
@@ -15117,23 +15253,23 @@ function deployMcpAssets() {
15117
15253
  log(`[manager] Bundle(s) updated: ${changedBasenames.join(", ")} \u2014 signalling running instances to restart`);
15118
15254
  restartRunningChannelMcps(changedBasenames);
15119
15255
  }
15120
- const localMcpPath = join21(targetDir, "index.js");
15256
+ const localMcpPath = join22(targetDir, "index.js");
15121
15257
  try {
15122
- const agentsDir = join21(homedir10(), ".augmented", "agents");
15258
+ const agentsDir = join22(homedir10(), ".augmented", "agents");
15123
15259
  if (existsSync11(agentsDir)) {
15124
- for (const entry of readdirSync5(agentsDir, { withFileTypes: true })) {
15260
+ for (const entry of readdirSync6(agentsDir, { withFileTypes: true })) {
15125
15261
  if (!entry.isDirectory()) continue;
15126
15262
  for (const subdir of ["provision", "project"]) {
15127
- const mcpJsonPath = join21(agentsDir, entry.name, subdir, ".mcp.json");
15263
+ const mcpJsonPath = join22(agentsDir, entry.name, subdir, ".mcp.json");
15128
15264
  try {
15129
- const raw = readFileSync17(mcpJsonPath, "utf-8");
15265
+ const raw = readFileSync18(mcpJsonPath, "utf-8");
15130
15266
  if (!raw.includes("@integrity-labs/augmented-mcp")) continue;
15131
15267
  const mcpConfig = JSON.parse(raw);
15132
15268
  const augServer = mcpConfig.mcpServers?.["augmented"];
15133
15269
  if (!augServer) continue;
15134
15270
  augServer.command = "node";
15135
15271
  augServer.args = [localMcpPath];
15136
- writeFileSync11(mcpJsonPath, JSON.stringify(mcpConfig, null, 2));
15272
+ writeFileSync12(mcpJsonPath, JSON.stringify(mcpConfig, null, 2));
15137
15273
  log(`[manager] Patched ${entry.name}/${subdir}/.mcp.json: npx \u2192 node`);
15138
15274
  } catch {
15139
15275
  }