@integrity-labs/agt-cli 0.28.509 → 0.28.511

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.
@@ -53,7 +53,7 @@ import {
53
53
  safeWriteJsonAtomic,
54
54
  setConfigHash,
55
55
  tripClass
56
- } from "../chunk-S5X4XFAC.js";
56
+ } from "../chunk-I3DZ3LI5.js";
57
57
  import {
58
58
  getProjectDir as getProjectDir2,
59
59
  getReadyTasks,
@@ -173,7 +173,7 @@ import {
173
173
  toOpencodeModel,
174
174
  transcriptActivityAgeSeconds,
175
175
  writeEgressAllowlist
176
- } from "../chunk-7U63M5R6.js";
176
+ } from "../chunk-OQBHTDWK.js";
177
177
  import {
178
178
  reapOrphanChannelMcps
179
179
  } from "../chunk-XWVM4KPK.js";
@@ -182,7 +182,7 @@ import {
182
182
  import { createHash as createHash16 } from "crypto";
183
183
  import { readFileSync as readFileSync22, writeFileSync as writeFileSync13, mkdirSync as mkdirSync10, existsSync as existsSync12, rmSync as rmSync5, readdirSync as readdirSync7, statSync as statSync6, copyFileSync } from "fs";
184
184
  import { execFileSync as syncExecFile } from "child_process";
185
- import { join as join27, dirname as dirname8, delimiter as pathDelimiter } from "path";
185
+ import { join as join28, dirname as dirname8, delimiter as pathDelimiter } from "path";
186
186
  import { homedir as homedir12 } from "os";
187
187
  import { fileURLToPath } from "url";
188
188
 
@@ -1899,7 +1899,19 @@ var NON_SECRET_ENV_GATES = [
1899
1899
  "AGT_DISABLE_MSTEAMS_HOST_ROUTES",
1900
1900
  "AGT_DEPLOY_CRONS",
1901
1901
  "AGT_CONV_EVAL_BACKEND",
1902
- "AGT_CLI_RELEASE_CHANNEL"
1902
+ "AGT_CLI_RELEASE_CHANNEL",
1903
+ // ENG-8341: the host-local self-update pin. It OUTRANKS
1904
+ // hosts.desired_agt_cli_version in resolveEffectivePinRaw, so without it the
1905
+ // control plane cannot resolve a host's true target: a host env-pinned to X
1906
+ // while the DB says NULL is CORRECT to sit behind `latest`, and a drift
1907
+ // monitor that cannot see the env pin would page on exactly the hosts an
1908
+ // operator deliberately held back. A version string, not a secret (and
1909
+ // SECRET_NAME_PATTERN would drop it if it were shaped like one).
1910
+ "AGT_CLI_PIN_VERSION",
1911
+ // ENG-8341: the paired escape hatch. A host allowing urgent upgrades can
1912
+ // legitimately be AHEAD of its pin, which is the other direction of the same
1913
+ // false positive.
1914
+ "AGT_CLI_PIN_ALLOW_URGENT"
1903
1915
  ];
1904
1916
  var SECRET_NAME_PATTERN = /(KEY|SECRET|TOKEN|PASSWORD|PASSWD|CREDENTIAL|PRIVATE|SIGNING|WEBHOOK)/i;
1905
1917
  function listCapturableEnvGateNames() {
@@ -4290,12 +4302,33 @@ function planGlobalSkillSync(globalSkills, prevIds, hashOf, knownHash, options)
4290
4302
  return { installs, removes, currentIds };
4291
4303
  }
4292
4304
 
4305
+ // src/lib/manager/integration-skill-cache.ts
4306
+ import { join as join17 } from "path";
4307
+ function integrationSkillHashKey(agentId, skillId) {
4308
+ return `plugin-skill:${agentId}:${skillId}`;
4309
+ }
4310
+ function shouldWriteIntegrationSkill(cache, agentId, skillId, contentHash) {
4311
+ return cache.get(integrationSkillHashKey(agentId, skillId)) !== contentHash;
4312
+ }
4313
+ function rememberIntegrationSkill(cache, agentId, skillId, contentHash) {
4314
+ cache.set(integrationSkillHashKey(agentId, skillId), contentHash);
4315
+ }
4316
+ function forgetIntegrationSkill(cache, agentId, skillId) {
4317
+ cache.delete(integrationSkillHashKey(agentId, skillId));
4318
+ }
4319
+ function removeIntegrationSkillFolder(opts) {
4320
+ forgetIntegrationSkill(opts.cache, opts.agentId, opts.entry);
4321
+ for (const dir of opts.dirs) {
4322
+ opts.removeDir(join17(dir, opts.entry));
4323
+ }
4324
+ }
4325
+
4293
4326
  // src/lib/manager/managed-skill-manifest.ts
4294
4327
  import { existsSync as existsSync6, mkdirSync as mkdirSync5, readFileSync as readFileSync14, writeFileSync as writeFileSync7 } from "fs";
4295
- import { dirname as dirname5, join as join17 } from "path";
4328
+ import { dirname as dirname5, join as join18 } from "path";
4296
4329
  var MANIFEST_VERSION = 1;
4297
4330
  function managedSkillManifestPath(agentRootDir) {
4298
- return join17(agentRootDir, "managed-skills.json");
4331
+ return join18(agentRootDir, "managed-skills.json");
4299
4332
  }
4300
4333
  function readManagedSkillManifest(path) {
4301
4334
  try {
@@ -4413,7 +4446,7 @@ function resolveModelChain(refreshData) {
4413
4446
 
4414
4447
  // src/lib/manager/claude-auth.ts
4415
4448
  import { existsSync as existsSync7, rmSync as rmSync3 } from "fs";
4416
- import { join as join18 } from "path";
4449
+ import { join as join19 } from "path";
4417
4450
  import { homedir as homedir8 } from "os";
4418
4451
  async function applyClaudeAuthToEnv(childEnv, label) {
4419
4452
  const apiKey = getApiKey();
@@ -4426,9 +4459,9 @@ async function applyClaudeAuthToEnv(childEnv, label) {
4426
4459
  throw new Error("claude_auth_mode=api_key but /host/exchange returned no decrypted key");
4427
4460
  }
4428
4461
  childEnv.ANTHROPIC_API_KEY = exchange.anthropicApiKey;
4429
- const claudeDir = join18(homedir8(), ".claude");
4462
+ const claudeDir = join19(homedir8(), ".claude");
4430
4463
  for (const filename of [".credentials.json", "credentials.json"]) {
4431
- const p = join18(claudeDir, filename);
4464
+ const p = join19(claudeDir, filename);
4432
4465
  if (existsSync7(p)) {
4433
4466
  try {
4434
4467
  rmSync3(p, { force: true });
@@ -4444,7 +4477,7 @@ async function applyClaudeAuthToEnv(childEnv, label) {
4444
4477
 
4445
4478
  // src/lib/manager/kanban/parsers.ts
4446
4479
  import { existsSync as existsSync8, readFileSync as readFileSync15 } from "fs";
4447
- import { join as join19 } from "path";
4480
+ import { join as join20 } from "path";
4448
4481
  var STANDUP_TEMPLATES = /* @__PURE__ */ new Set(["daily-standup", "end-of-day-summary"]);
4449
4482
  var TASK_UPDATE_TEMPLATES = /* @__PURE__ */ new Set(["hourly-status", "task-update"]);
4450
4483
  var PLAN_TEMPLATES = /* @__PURE__ */ new Set(["morning-plan"]);
@@ -4583,8 +4616,8 @@ function getBuiltInSkillContent(skillId) {
4583
4616
  if (builtInSkillCache.has(skillId)) return builtInSkillCache.get(skillId);
4584
4617
  try {
4585
4618
  const candidates = [
4586
- join19(process.cwd(), "skills", skillId, "SKILL.md"),
4587
- join19(new URL(".", import.meta.url).pathname, "..", "..", "..", "..", "..", "..", "skills", skillId, "SKILL.md")
4619
+ join20(process.cwd(), "skills", skillId, "SKILL.md"),
4620
+ join20(new URL(".", import.meta.url).pathname, "..", "..", "..", "..", "..", "..", "skills", skillId, "SKILL.md")
4588
4621
  ];
4589
4622
  for (const candidate of candidates) {
4590
4623
  if (existsSync8(candidate)) {
@@ -4730,11 +4763,11 @@ function formatBoardForPrompt(items, template) {
4730
4763
 
4731
4764
  // src/lib/manager/kanban/nudge-state-cache.ts
4732
4765
  import { existsSync as existsSync9, readFileSync as readFileSync16, writeFileSync as writeFileSync8 } from "fs";
4733
- import { join as join20 } from "path";
4766
+ import { join as join21 } from "path";
4734
4767
  var CACHE_FILENAME2 = "kanban-nudge-state.json";
4735
4768
  var KANBAN_NUDGE_STATE_VERSION = 1;
4736
4769
  function getKanbanNudgeStateFile(configDir) {
4737
- return join20(configDir, CACHE_FILENAME2);
4770
+ return join21(configDir, CACHE_FILENAME2);
4738
4771
  }
4739
4772
  function loadKanbanNudgeState(target, configDir) {
4740
4773
  const path = getKanbanNudgeStateFile(configDir);
@@ -5343,7 +5376,7 @@ function closeScheduledRunsForCode(codeName, outcome, reason) {
5343
5376
  import { createHash as createHash11 } from "crypto";
5344
5377
  import { writeFileSync as writeFileSync9, renameSync as renameSync3, mkdirSync as mkdirSync6, readFileSync as readFileSync17, unlinkSync } from "fs";
5345
5378
  import { homedir as homedir9 } from "os";
5346
- import { join as join21, dirname as dirname6 } from "path";
5379
+ import { join as join22, dirname as dirname6 } from "path";
5347
5380
 
5348
5381
  // src/lib/manager/scheduler/notify.ts
5349
5382
  import { createHash as createHash10 } from "crypto";
@@ -5684,7 +5717,7 @@ function resolveScheduledSlackTarget(task) {
5684
5717
  }
5685
5718
  function stampScheduledTurnMarker(codeName, taskId, target) {
5686
5719
  try {
5687
- const file = join21(homedir9(), ".augmented", codeName, SCHEDULED_TURN_MARKER_FILENAME);
5720
+ const file = join22(homedir9(), ".augmented", codeName, SCHEDULED_TURN_MARKER_FILENAME);
5688
5721
  const marker = { ts: Date.now(), task_id: taskId, ...target ? { target } : {} };
5689
5722
  const tmp = `${file}.tmp`;
5690
5723
  writeFileSync9(tmp, JSON.stringify(marker), "utf8");
@@ -5694,7 +5727,7 @@ function stampScheduledTurnMarker(codeName, taskId, target) {
5694
5727
  }
5695
5728
  }
5696
5729
  function clearScheduledTurnMarkerForTask(codeName, taskId) {
5697
- const file = join21(homedir9(), ".augmented", codeName, SCHEDULED_TURN_MARKER_FILENAME);
5730
+ const file = join22(homedir9(), ".augmented", codeName, SCHEDULED_TURN_MARKER_FILENAME);
5698
5731
  try {
5699
5732
  const raw = JSON.parse(readFileSync17(file, "utf8"));
5700
5733
  if (typeof raw?.task_id !== "string" || raw.task_id !== taskId) return;
@@ -5909,11 +5942,11 @@ async function processClaudeTaskResult(codeName, agentId, templateId, rawOutput,
5909
5942
  // src/lib/manager/scheduler/execution.ts
5910
5943
  import { createHash as createHash12 } from "crypto";
5911
5944
  import { homedir as homedir10 } from "os";
5912
- import { join as join23 } from "path";
5945
+ import { join as join24 } from "path";
5913
5946
 
5914
5947
  // src/lib/agent-serving-probe.ts
5915
5948
  import { readFileSync as readFileSync18, readdirSync as readdirSync4, statSync as statSync4 } from "fs";
5916
- import { join as join22 } from "path";
5949
+ import { join as join23 } from "path";
5917
5950
  var RATE_LIMIT_WINDOW_MS = 6 * 60 * 60 * 1e3;
5918
5951
  function probeRateLimit(args) {
5919
5952
  const now = args.now ?? /* @__PURE__ */ new Date();
@@ -5929,7 +5962,7 @@ function probeRateLimit(args) {
5929
5962
  let newest = UNKNOWN_RATE_LIMIT;
5930
5963
  for (const name of entries) {
5931
5964
  if (!name.endsWith(".jsonl")) continue;
5932
- const path = join22(dir, name);
5965
+ const path = join23(dir, name);
5933
5966
  try {
5934
5967
  const st = statSync4(path);
5935
5968
  if (!st.isFile() || st.mtimeMs < startMs) continue;
@@ -6000,7 +6033,7 @@ function shouldLogUsageCapDeferral(site, codeName, limitedUntil) {
6000
6033
 
6001
6034
  // src/lib/manager/scheduler/execution.ts
6002
6035
  function claudePidFilePath() {
6003
- return join23(homedir10(), ".augmented", "manager-claude-pids.json");
6036
+ return join24(homedir10(), ".augmented", "manager-claude-pids.json");
6004
6037
  }
6005
6038
  var inFlightClaudePids = /* @__PURE__ */ new Map();
6006
6039
  function registerClaudeSpawn(record) {
@@ -7235,7 +7268,7 @@ async function fireOpencodeScheduledTask(agent, task) {
7235
7268
  import { createHash as createHash15 } from "crypto";
7236
7269
  import { existsSync as existsSync10, mkdirSync as mkdirSync7, readFileSync as readFileSync19, renameSync as renameSync4, unlinkSync as unlinkSync2, writeFileSync as writeFileSync10 } from "fs";
7237
7270
  import { randomUUID } from "crypto";
7238
- import { join as join24 } from "path";
7271
+ import { join as join25 } from "path";
7239
7272
 
7240
7273
  // src/lib/telegram-ingest.ts
7241
7274
  import https2 from "https";
@@ -7783,7 +7816,7 @@ function createFileOffsetStore(codeName, log2, currentBotId) {
7783
7816
  let filePath;
7784
7817
  try {
7785
7818
  dir = getFramework("opencode").getAgentDir(codeName);
7786
- filePath = join24(dir, "telegram-getupdates-offset-opencode.json");
7819
+ filePath = join25(dir, "telegram-getupdates-offset-opencode.json");
7787
7820
  } catch {
7788
7821
  dir = null;
7789
7822
  filePath = null;
@@ -8064,13 +8097,13 @@ function partitionActionableByPoison(actionable, states, config2) {
8064
8097
  // src/lib/restart-flags.ts
8065
8098
  import { existsSync as existsSync11, mkdirSync as mkdirSync8, readdirSync as readdirSync5, readFileSync as readFileSync20, renameSync as renameSync5, rmSync as rmSync4, writeFileSync as writeFileSync11 } from "fs";
8066
8099
  import { homedir as homedir11 } from "os";
8067
- import { join as join25 } from "path";
8100
+ import { join as join26 } from "path";
8068
8101
  import { randomUUID as randomUUID2 } from "crypto";
8069
8102
  function restartFlagsDir() {
8070
- return join25(homedir11(), ".augmented", "restart-flags");
8103
+ return join26(homedir11(), ".augmented", "restart-flags");
8071
8104
  }
8072
8105
  function flagPath(codeName) {
8073
- return join25(restartFlagsDir(), `${codeName}.flag`);
8106
+ return join26(restartFlagsDir(), `${codeName}.flag`);
8074
8107
  }
8075
8108
  function readRestartFlags() {
8076
8109
  const dir = restartFlagsDir();
@@ -8079,7 +8112,7 @@ function readRestartFlags() {
8079
8112
  for (const entry of readdirSync5(dir)) {
8080
8113
  if (!entry.endsWith(".flag")) continue;
8081
8114
  try {
8082
- const raw = readFileSync20(join25(dir, entry), "utf8");
8115
+ const raw = readFileSync20(join26(dir, entry), "utf8");
8083
8116
  const parsed = JSON.parse(raw);
8084
8117
  if (typeof parsed.codeName !== "string" || parsed.codeName.length === 0) {
8085
8118
  parsed.codeName = entry.replace(/\.flag$/, "");
@@ -8198,7 +8231,7 @@ async function sendError(flag, opts, text) {
8198
8231
 
8199
8232
  // src/lib/restart-context.ts
8200
8233
  import { readdirSync as readdirSync6, readFileSync as readFileSync21, writeFileSync as writeFileSync12, mkdirSync as mkdirSync9, unlinkSync as unlinkSync3 } from "fs";
8201
- import { dirname as dirname7, join as join26 } from "path";
8234
+ import { dirname as dirname7, join as join27 } from "path";
8202
8235
  var SLACK_PENDING_INBOUND_DIRNAME = "slack-pending-inbound";
8203
8236
  var SLACK_RESTART_CONTEXT_DIRNAME = "slack-restart-context";
8204
8237
  var MAX_TOPIC_CHARS = 140;
@@ -8210,10 +8243,10 @@ function augmentedAgentDir(codeName) {
8210
8243
  return dirname7(getProjectDir(codeName));
8211
8244
  }
8212
8245
  function slackPendingInboundDir(codeName) {
8213
- return join26(augmentedAgentDir(codeName), SLACK_PENDING_INBOUND_DIRNAME);
8246
+ return join27(augmentedAgentDir(codeName), SLACK_PENDING_INBOUND_DIRNAME);
8214
8247
  }
8215
8248
  function slackRestartContextDir(codeName) {
8216
- return join26(augmentedAgentDir(codeName), SLACK_RESTART_CONTEXT_DIRNAME);
8249
+ return join27(augmentedAgentDir(codeName), SLACK_RESTART_CONTEXT_DIRNAME);
8217
8250
  }
8218
8251
  function sanitizeTopic(raw) {
8219
8252
  const cleaned = raw.replace(/\s+/g, " ").trim().replace(/[<>]/g, " ").replace(/\s+/g, " ").trim();
@@ -8273,7 +8306,7 @@ function pruneHintsExcept(codeName, freshFilenames) {
8273
8306
  if (!filename.endsWith(".json")) continue;
8274
8307
  if (freshFilenames.has(filename)) continue;
8275
8308
  try {
8276
- unlinkSync3(join26(ctxDir, filename));
8309
+ unlinkSync3(join27(ctxDir, filename));
8277
8310
  } catch {
8278
8311
  }
8279
8312
  }
@@ -8294,7 +8327,7 @@ function refreshSlackRestartContextHints(codeNames, opts = {}) {
8294
8327
  }
8295
8328
  const markers = [];
8296
8329
  for (const filename of markerFilenames.slice(0, cap)) {
8297
- const parsed = readStrandedMarker(join26(markerDir, filename));
8330
+ const parsed = readStrandedMarker(join27(markerDir, filename));
8298
8331
  if (parsed) markers.push({ filename, channel: parsed.channel, thread_ts: parsed.thread_ts });
8299
8332
  }
8300
8333
  if (markers.length === 0) {
@@ -8308,7 +8341,7 @@ function refreshSlackRestartContextHints(codeNames, opts = {}) {
8308
8341
  const freshFilenames = /* @__PURE__ */ new Set();
8309
8342
  for (const { filename, hint } of hints) {
8310
8343
  try {
8311
- writeHintFile(join26(ctxDir, filename), ctxDir, hint);
8344
+ writeHintFile(join27(ctxDir, filename), ctxDir, hint);
8312
8345
  freshFilenames.add(filename);
8313
8346
  } catch (err) {
8314
8347
  log2(`[restart-context] ${codeName}: hint write failed for ${filename}: ${err.message}`);
@@ -9662,7 +9695,7 @@ var runningChannelSecretHashes = /* @__PURE__ */ new Map();
9662
9695
  var sessionLaunchManagedStructure = /* @__PURE__ */ new Map();
9663
9696
  function projectMcpHash(_codeName, projectDir) {
9664
9697
  try {
9665
- const raw = readFileSync22(join27(projectDir, ".mcp.json"), "utf-8");
9698
+ const raw = readFileSync22(join28(projectDir, ".mcp.json"), "utf-8");
9666
9699
  return createHash16("sha256").update(canonicalJson(JSON.parse(raw))).digest("hex");
9667
9700
  } catch {
9668
9701
  return null;
@@ -9670,7 +9703,7 @@ function projectMcpHash(_codeName, projectDir) {
9670
9703
  }
9671
9704
  function projectMcpKeys(_codeName, projectDir) {
9672
9705
  try {
9673
- const raw = readFileSync22(join27(projectDir, ".mcp.json"), "utf-8");
9706
+ const raw = readFileSync22(join28(projectDir, ".mcp.json"), "utf-8");
9674
9707
  const parsed = JSON.parse(raw);
9675
9708
  const servers = parsed.mcpServers;
9676
9709
  if (!servers || typeof servers !== "object") return /* @__PURE__ */ new Set();
@@ -9688,7 +9721,7 @@ function seedSessionLaunchBaselines(codeName, projectDir) {
9688
9721
  else runningMcpServerKeys.delete(codeName);
9689
9722
  let launchStructure = null;
9690
9723
  try {
9691
- const raw = readFileSync22(join27(projectDir, ".mcp.json"), "utf-8");
9724
+ const raw = readFileSync22(join28(projectDir, ".mcp.json"), "utf-8");
9692
9725
  launchStructure = managedMcpStructureHashFromFile(
9693
9726
  JSON.parse(raw),
9694
9727
  isManagedMcpServerKey
@@ -9798,7 +9831,7 @@ async function runAgentSessionToolBindProbes(agent, integrations, projectDir, op
9798
9831
  if (result && result.rebindCandidates.length > 0 && hostFlagStore().getBoolean("session-tool-rebind")) {
9799
9832
  let mcpJsonForRebind = null;
9800
9833
  try {
9801
- mcpJsonForRebind = JSON.parse(readFileSync22(join27(projectDir, ".mcp.json"), "utf-8"));
9834
+ mcpJsonForRebind = JSON.parse(readFileSync22(join28(projectDir, ".mcp.json"), "utf-8"));
9802
9835
  } catch {
9803
9836
  mcpJsonForRebind = null;
9804
9837
  }
@@ -9942,7 +9975,7 @@ function checkMcpConfigDriftAndScheduleRestart(codeName, projectDir) {
9942
9975
  function projectChannelSecretHash(projectDir) {
9943
9976
  try {
9944
9977
  const entries = parseEnvIntegrations(
9945
- readFileSync22(join27(projectDir, ".env.integrations"), "utf-8")
9978
+ readFileSync22(join28(projectDir, ".env.integrations"), "utf-8")
9946
9979
  );
9947
9980
  return channelSecretValueHash(entries, CHANNEL_SECRET_ENV_KEYS);
9948
9981
  } catch {
@@ -10038,7 +10071,7 @@ var agentRestartTimezoneInputs = /* @__PURE__ */ new Map();
10038
10071
  var lastVersionCheckAt = 0;
10039
10072
  var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
10040
10073
  var lastResponsivenessProbeAt = 0;
10041
- var agtCliVersion = true ? "0.28.509" : "dev";
10074
+ var agtCliVersion = true ? "0.28.511" : "dev";
10042
10075
  function resolveBrewPath(execFileSync2) {
10043
10076
  try {
10044
10077
  const out = execFileSync2("which", ["brew"], { timeout: 5e3 }).toString().trim();
@@ -10426,7 +10459,7 @@ async function ensureOpencodeBinary() {
10426
10459
  try {
10427
10460
  const prefix = execFileSync2("npm", ["prefix", "-g"], { encoding: "utf-8", timeout: 1e4 }).trim();
10428
10461
  if (prefix) {
10429
- const npmBin = join27(prefix, "bin");
10462
+ const npmBin = join28(prefix, "bin");
10430
10463
  const current = (process.env.PATH ?? "").split(pathDelimiter);
10431
10464
  if (!current.includes(npmBin)) {
10432
10465
  process.env.PATH = [npmBin, ...current.filter(Boolean)].join(pathDelimiter);
@@ -10543,7 +10576,7 @@ ${r.stderr}`;
10543
10576
  }
10544
10577
  var UPDATE_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
10545
10578
  function selfUpdateAppliedMarkerPath() {
10546
- return join27(homedir12(), ".augmented", ".last-self-update-applied");
10579
+ return join28(homedir12(), ".augmented", ".last-self-update-applied");
10547
10580
  }
10548
10581
  var selfUpdateUpToDateLogged = false;
10549
10582
  var selfUpdatePinnedLogged = false;
@@ -10571,7 +10604,7 @@ async function checkAndUpdateCli(opts) {
10571
10604
  const isNpmGlobal = !isBrewFormula && resolvedPath.includes("node_modules");
10572
10605
  if (!isBrewFormula && !isNpmGlobal) return "noop";
10573
10606
  const { readFileSync: readF, writeFileSync: writeF } = await import("fs");
10574
- const markerPath = join27(homedir12(), ".augmented", ".last-update-check");
10607
+ const markerPath = join28(homedir12(), ".augmented", ".last-update-check");
10575
10608
  if (!force) {
10576
10609
  try {
10577
10610
  const lastCheck = parseInt(readF(markerPath, "utf-8").trim(), 10);
@@ -10931,12 +10964,12 @@ async function checkClaudeAuth() {
10931
10964
  var evalEmptyMcpConfigPath = null;
10932
10965
  function ensureEvalEmptyMcpConfig() {
10933
10966
  if (evalEmptyMcpConfigPath && existsSync12(evalEmptyMcpConfigPath)) return evalEmptyMcpConfigPath;
10934
- const dir = join27(homedir12(), ".augmented");
10967
+ const dir = join28(homedir12(), ".augmented");
10935
10968
  try {
10936
10969
  mkdirSync10(dir, { recursive: true });
10937
10970
  } catch {
10938
10971
  }
10939
- const p = join27(dir, ".eval-empty-mcp.json");
10972
+ const p = join28(dir, ".eval-empty-mcp.json");
10940
10973
  writeFileSync13(p, JSON.stringify({ mcpServers: {} }));
10941
10974
  evalEmptyMcpConfigPath = p;
10942
10975
  return p;
@@ -11028,10 +11061,10 @@ function resolveConversationEvalBackend() {
11028
11061
  return conversationEvalBackend;
11029
11062
  }
11030
11063
  function getStateFile() {
11031
- return join27(config?.configDir ?? join27(process.env["HOME"] ?? "/tmp", ".augmented"), "manager-state.json");
11064
+ return join28(config?.configDir ?? join28(process.env["HOME"] ?? "/tmp", ".augmented"), "manager-state.json");
11032
11065
  }
11033
11066
  function channelHashCacheDir() {
11034
- return config?.configDir ?? join27(process.env["HOME"] ?? "/tmp", ".augmented");
11067
+ return config?.configDir ?? join28(process.env["HOME"] ?? "/tmp", ".augmented");
11035
11068
  }
11036
11069
  function loadChannelHashCache2() {
11037
11070
  loadChannelHashCache(agentState.knownChannelConfigHashes, channelHashCacheDir());
@@ -11085,7 +11118,7 @@ function removeDeliveryBaselineEntries(agentId) {
11085
11118
  var _channelQuarantineStore = null;
11086
11119
  function channelQuarantineStore() {
11087
11120
  if (!_channelQuarantineStore) {
11088
- const dir = config?.configDir ?? join27(process.env["HOME"] ?? "/tmp", ".augmented");
11121
+ const dir = config?.configDir ?? join28(process.env["HOME"] ?? "/tmp", ".augmented");
11089
11122
  _channelQuarantineStore = new ChannelQuarantineStore(defaultQuarantinePath(dir));
11090
11123
  }
11091
11124
  return _channelQuarantineStore;
@@ -11102,7 +11135,7 @@ function claudeMdSizeFor(codeName) {
11102
11135
  var _hostFlagStore = null;
11103
11136
  function hostFlagStore() {
11104
11137
  if (!_hostFlagStore) {
11105
- const dir = config?.configDir ?? join27(process.env["HOME"] ?? "/tmp", ".augmented");
11138
+ const dir = config?.configDir ?? join28(process.env["HOME"] ?? "/tmp", ".augmented");
11106
11139
  _hostFlagStore = new HostFlagStore({ cachePath: defaultFlagsCachePath(dir), log });
11107
11140
  }
11108
11141
  return _hostFlagStore;
@@ -11173,12 +11206,12 @@ function parseSkillFrontmatter(content) {
11173
11206
  }
11174
11207
  async function refreshSkillsIndexInClaudeMd(configDir, codeName, log2) {
11175
11208
  const { readdirSync: readdirSync8, readFileSync: rfs, existsSync: ex, writeFileSync: writeFileSync14 } = await import("fs");
11176
- const skillsDir = join27(configDir, codeName, "project", ".claude", "skills");
11177
- const claudeMdPath = join27(configDir, codeName, "project", "CLAUDE.md");
11209
+ const skillsDir = join28(configDir, codeName, "project", ".claude", "skills");
11210
+ const claudeMdPath = join28(configDir, codeName, "project", "CLAUDE.md");
11178
11211
  if (!ex(skillsDir) || !ex(claudeMdPath)) return;
11179
11212
  const entries = [];
11180
11213
  for (const dir of readdirSync8(skillsDir).sort()) {
11181
- const skillFile = join27(skillsDir, dir, "SKILL.md");
11214
+ const skillFile = join28(skillsDir, dir, "SKILL.md");
11182
11215
  if (!ex(skillFile)) continue;
11183
11216
  try {
11184
11217
  const { name, description } = parseSkillFrontmatter(rfs(skillFile, "utf-8"));
@@ -11245,7 +11278,7 @@ function flushRestartedAgentDiagnostics(hostId, codeNames) {
11245
11278
  if (codeNames.length === 0) return;
11246
11279
  void (async () => {
11247
11280
  try {
11248
- const { collectDiagnostics } = await import("../persistent-session-BDNW4K6M.js");
11281
+ const { collectDiagnostics } = await import("../persistent-session-CMG4VWT6.js");
11249
11282
  await api.post("/host/heartbeat", {
11250
11283
  host_id: hostId,
11251
11284
  agent_diagnostics: collectDiagnostics(codeNames, quarantineEntriesFor, claudeMdSizeFor)
@@ -11352,7 +11385,7 @@ async function pollCycle() {
11352
11385
  }
11353
11386
  try {
11354
11387
  const { detectHostSecurity } = await import("../host-security-6PDFG7F5.js");
11355
- const { collectDiagnostics } = await import("../persistent-session-BDNW4K6M.js");
11388
+ const { collectDiagnostics } = await import("../persistent-session-CMG4VWT6.js");
11356
11389
  const diagCodeNames = [...agentState.persistentSessionAgents];
11357
11390
  const agentDiagnostics = diagCodeNames.length > 0 ? collectDiagnostics(diagCodeNames, quarantineEntriesFor, claudeMdSizeFor) : void 0;
11358
11391
  let tailscaleHostname;
@@ -11467,7 +11500,7 @@ async function pollCycle() {
11467
11500
  collectResponsivenessProbes,
11468
11501
  collectPanelessActivityProbes,
11469
11502
  getResponsivenessIntervalMs
11470
- } = await import("../responsiveness-probe-KR73VA2S.js");
11503
+ } = await import("../responsiveness-probe-COMUJVPF.js");
11471
11504
  const probeIntervalMs = getResponsivenessIntervalMs();
11472
11505
  if (now - lastResponsivenessProbeAt > probeIntervalMs) {
11473
11506
  const probeCodeNames = [...agentState.persistentSessionAgents];
@@ -11531,7 +11564,7 @@ async function pollCycle() {
11531
11564
  collectResponsivenessProbes,
11532
11565
  livePendingInboundOldestAgeSeconds,
11533
11566
  parkPendingInbound
11534
- } = await import("../responsiveness-probe-KR73VA2S.js");
11567
+ } = await import("../responsiveness-probe-COMUJVPF.js");
11535
11568
  const { getProjectDir: wedgeProjectDir } = await import("../scheduler-engine-NDP36U7O.js");
11536
11569
  const wedgeNow = /* @__PURE__ */ new Date();
11537
11570
  const liveAgents = agentState.persistentSessionAgents;
@@ -11623,10 +11656,10 @@ async function pollCycle() {
11623
11656
  const paneTail = readFileSync22(paneLogPath(codeName), "utf8").slice(-65536);
11624
11657
  const transient = detectTransientApiErrorInLog(paneTail);
11625
11658
  if (transient) {
11626
- const wedgeHome = join27(homedir12(), ".augmented", codeName);
11659
+ const wedgeHome = join28(homedir12(), ".augmented", codeName);
11627
11660
  if (existsSync12(wedgeHome)) {
11628
11661
  atomicWriteFileSync(
11629
- join27(wedgeHome, "watchdog-give-up.json"),
11662
+ join28(wedgeHome, "watchdog-give-up.json"),
11630
11663
  JSON.stringify({
11631
11664
  gave_up_at: wedgeNow.toISOString(),
11632
11665
  reason: "transient_overload"
@@ -11897,7 +11930,7 @@ async function pollCycle() {
11897
11930
  const adapter = resolveAgentFramework(prev.codeName);
11898
11931
  stopAgentRuntime2(prev.codeName, "removed-from-host");
11899
11932
  killAgentChannelProcesses(prev.codeName, { log });
11900
- const agentDir = join27(adapter.getAgentDir(prev.codeName), "provision");
11933
+ const agentDir = join28(adapter.getAgentDir(prev.codeName), "provision");
11901
11934
  await cleanupAgentFiles(prev.codeName, agentDir);
11902
11935
  clearAgentCaches(prev.agentId, prev.codeName);
11903
11936
  }
@@ -11984,10 +12017,10 @@ async function pollCycle() {
11984
12017
  // pending-inbound marker. Best-effort: a write failure is logged by
11985
12018
  // the watchdog, never fails the poll cycle.
11986
12019
  signalGiveUp: (codeName) => {
11987
- const dir = join27(homedir12(), ".augmented", codeName);
12020
+ const dir = join28(homedir12(), ".augmented", codeName);
11988
12021
  if (!existsSync12(dir)) return;
11989
12022
  atomicWriteFileSync(
11990
- join27(dir, "watchdog-give-up.json"),
12023
+ join28(dir, "watchdog-give-up.json"),
11991
12024
  JSON.stringify({ gave_up_at: (/* @__PURE__ */ new Date()).toISOString() })
11992
12025
  );
11993
12026
  }
@@ -12129,7 +12162,7 @@ async function processAgent(agent, agentStates) {
12129
12162
  }
12130
12163
  const now = (/* @__PURE__ */ new Date()).toISOString();
12131
12164
  const adapter = resolveAgentFramework(agent.code_name);
12132
- let agentDir = join27(adapter.getAgentDir(agent.code_name), "provision");
12165
+ let agentDir = join28(adapter.getAgentDir(agent.code_name), "provision");
12133
12166
  if (agent.status === "draft" || agent.status === "paused") {
12134
12167
  if (previousKnownStatus !== agent.status) {
12135
12168
  log(`Agent '${agent.code_name}' is ${agent.status}, skipping provisioning`);
@@ -12303,7 +12336,7 @@ async function processAgent(agent, agentStates) {
12303
12336
  const frameworkId = refreshData.agent.framework ?? DEFAULT_FRAMEWORK;
12304
12337
  agentFrameworkCache.set(agent.code_name, frameworkId);
12305
12338
  const frameworkAdapter = getFramework(frameworkId);
12306
- agentDir = join27(frameworkAdapter.getAgentDir(agent.code_name), "provision");
12339
+ agentDir = join28(frameworkAdapter.getAgentDir(agent.code_name), "provision");
12307
12340
  cacheAgentDeliveryMetadata(agent.code_name, refreshData);
12308
12341
  agentRestartTimezoneInputs.set(agent.code_name, {
12309
12342
  agentTimezone: typeof refreshData.agent.timezone === "string" ? refreshData.agent.timezone : null,
@@ -12352,7 +12385,7 @@ async function processAgent(agent, agentStates) {
12352
12385
  const changedFiles = [];
12353
12386
  mkdirSync10(agentDir, { recursive: true });
12354
12387
  for (const artifact of artifacts) {
12355
- const filePath = join27(agentDir, artifact.relativePath);
12388
+ const filePath = join28(agentDir, artifact.relativePath);
12356
12389
  let existingHash;
12357
12390
  let newHash;
12358
12391
  let writeContent = artifact.content;
@@ -12371,7 +12404,7 @@ async function processAgent(agent, agentStates) {
12371
12404
  };
12372
12405
  newHash = sha256(stripDynamicSections(artifact.content));
12373
12406
  try {
12374
- const projectClaudeMd = join27(config.configDir, agent.code_name, "project", "CLAUDE.md");
12407
+ const projectClaudeMd = join28(config.configDir, agent.code_name, "project", "CLAUDE.md");
12375
12408
  const existing = readFileSync22(projectClaudeMd, "utf-8");
12376
12409
  existingHash = sha256(stripDynamicSections(existing));
12377
12410
  } catch {
@@ -12422,12 +12455,12 @@ async function processAgent(agent, agentStates) {
12422
12455
  }
12423
12456
  }
12424
12457
  if (changedFiles.length > 0) {
12425
- const isFirst = !existsSync12(join27(agentDir, "CHARTER.md"));
12458
+ const isFirst = !existsSync12(join28(agentDir, "CHARTER.md"));
12426
12459
  const verb = isFirst ? "Provisioning" : "Updating";
12427
12460
  const fileNames = changedFiles.map((f) => f.relativePath).join(", ");
12428
12461
  log(`${verb} '${agent.code_name}': ${fileNames}`);
12429
12462
  for (const file of changedFiles) {
12430
- const filePath = join27(agentDir, file.relativePath);
12463
+ const filePath = join28(agentDir, file.relativePath);
12431
12464
  mkdirSync10(dirname8(filePath), { recursive: true });
12432
12465
  if (file.relativePath === ".mcp.json") {
12433
12466
  safeWriteJsonAtomic(filePath, file.content, { mode: 384 });
@@ -12436,12 +12469,12 @@ async function processAgent(agent, agentStates) {
12436
12469
  }
12437
12470
  }
12438
12471
  try {
12439
- const provSkillsDir = join27(agentDir, ".claude", "skills");
12472
+ const provSkillsDir = join28(agentDir, ".claude", "skills");
12440
12473
  if (existsSync12(provSkillsDir)) {
12441
12474
  for (const folder of readdirSync7(provSkillsDir)) {
12442
12475
  if (folder.startsWith("knowledge-")) {
12443
12476
  try {
12444
- rmSync5(join27(provSkillsDir, folder), { recursive: true });
12477
+ rmSync5(join28(provSkillsDir, folder), { recursive: true });
12445
12478
  } catch {
12446
12479
  }
12447
12480
  }
@@ -12454,7 +12487,7 @@ async function processAgent(agent, agentStates) {
12454
12487
  const trackedFiles2 = frameworkAdapter.driftTrackedFiles();
12455
12488
  const hashes = /* @__PURE__ */ new Map();
12456
12489
  for (const file of trackedFiles2) {
12457
- const h = hashFile(join27(agentDir, file));
12490
+ const h = hashFile(join28(agentDir, file));
12458
12491
  if (h) hashes.set(file, h);
12459
12492
  }
12460
12493
  agentState.writtenHashes.set(agent.agent_id, hashes);
@@ -12472,14 +12505,14 @@ async function processAgent(agent, agentStates) {
12472
12505
  }
12473
12506
  if (Array.isArray(refreshData.workflows)) {
12474
12507
  try {
12475
- const provWorkflowsDir = join27(agentDir, ".claude", "workflows");
12508
+ const provWorkflowsDir = join28(agentDir, ".claude", "workflows");
12476
12509
  if (existsSync12(provWorkflowsDir)) {
12477
12510
  const expected = new Set(refreshData.workflows.map((w) => `${w.name}.js`));
12478
12511
  for (const file of readdirSync7(provWorkflowsDir)) {
12479
12512
  if (!file.endsWith(".js")) continue;
12480
12513
  if (expected.has(file)) continue;
12481
12514
  try {
12482
- rmSync5(join27(provWorkflowsDir, file));
12515
+ rmSync5(join28(provWorkflowsDir, file));
12483
12516
  } catch {
12484
12517
  }
12485
12518
  }
@@ -12561,7 +12594,7 @@ async function processAgent(agent, agentStates) {
12561
12594
  if (written && existsSync12(agentDir)) {
12562
12595
  const driftedFiles = [];
12563
12596
  for (const [file, expectedHash] of written) {
12564
- const localHash = hashFile(join27(agentDir, file));
12597
+ const localHash = hashFile(join28(agentDir, file));
12565
12598
  if (localHash && localHash !== expectedHash) {
12566
12599
  driftedFiles.push(file);
12567
12600
  }
@@ -12572,7 +12605,7 @@ async function processAgent(agent, agentStates) {
12572
12605
  try {
12573
12606
  const localHashes = {};
12574
12607
  for (const file of driftedFiles) {
12575
- localHashes[file] = hashFile(join27(agentDir, file));
12608
+ localHashes[file] = hashFile(join28(agentDir, file));
12576
12609
  }
12577
12610
  await api.post("/host/drift", {
12578
12611
  agent_id: agent.agent_id,
@@ -12774,7 +12807,7 @@ async function processAgent(agent, agentStates) {
12774
12807
  const addedChannels = [...restartDecision.added];
12775
12808
  const writeDmNoticeMarkers = isChannelAddRestart ? () => {
12776
12809
  try {
12777
- const agentAugmentedDir = join27(homedir12(), ".augmented", agent.code_name);
12810
+ const agentAugmentedDir = join28(homedir12(), ".augmented", agent.code_name);
12778
12811
  mkdirSync10(agentAugmentedDir, { recursive: true });
12779
12812
  const markerJson = JSON.stringify({
12780
12813
  version: 1,
@@ -12782,7 +12815,7 @@ async function processAgent(agent, agentStates) {
12782
12815
  added: addedChannels
12783
12816
  });
12784
12817
  for (const file of ["slack-channel-add-restart.json", "telegram-channel-add-restart.json"]) {
12785
- atomicWriteFileSync(join27(agentAugmentedDir, file), markerJson);
12818
+ atomicWriteFileSync(join28(agentAugmentedDir, file), markerJson);
12786
12819
  }
12787
12820
  } catch (err) {
12788
12821
  log(`[hot-reload] channel-add DM-notice marker write failed for '${agent.code_name}' (non-fatal): ${err.message}`);
@@ -12971,18 +13004,18 @@ async function processAgent(agent, agentStates) {
12971
13004
  if (agentSessionMode === "persistent" && (agentFrameworkCache.get(agent.code_name) ?? DEFAULT_FRAMEWORK) === "claude-code") {
12972
13005
  try {
12973
13006
  const agentProvisionDir = agentDir;
12974
- const projectDir = join27(homedir12(), ".augmented", agent.code_name, "project");
13007
+ const projectDir = join28(homedir12(), ".augmented", agent.code_name, "project");
12975
13008
  mkdirSync10(agentProvisionDir, { recursive: true });
12976
13009
  mkdirSync10(projectDir, { recursive: true });
12977
- const provisionMcpPath = join27(agentProvisionDir, ".mcp.json");
12978
- const projectMcpPath = join27(projectDir, ".mcp.json");
13010
+ const provisionMcpPath = join28(agentProvisionDir, ".mcp.json");
13011
+ const projectMcpPath = join28(projectDir, ".mcp.json");
12979
13012
  let mcpConfig = { mcpServers: {} };
12980
13013
  try {
12981
13014
  mcpConfig = JSON.parse(readFileSync22(provisionMcpPath, "utf-8"));
12982
13015
  if (!mcpConfig.mcpServers) mcpConfig.mcpServers = {};
12983
13016
  } catch {
12984
13017
  }
12985
- const localDirectChatChannel = join27(homedir12(), ".augmented", "_mcp", "direct-chat-channel.js");
13018
+ const localDirectChatChannel = join28(homedir12(), ".augmented", "_mcp", "direct-chat-channel.js");
12986
13019
  const directChatTeamSettings = refreshData.team?.settings;
12987
13020
  const directChatTz = (() => {
12988
13021
  const tz = directChatTeamSettings?.["timezone"];
@@ -13008,7 +13041,7 @@ async function processAgent(agent, agentStates) {
13008
13041
  // ~/.augmented/<codeName>/.current-turn-initiator.json. Note getAgentDir
13009
13042
  // returns the agent root (NOT the /provision subdir `agentDir` points at),
13010
13043
  // so it byte-matches the broker readers' path.
13011
- AGT_TURN_INITIATOR_FILE: join27(
13044
+ AGT_TURN_INITIATOR_FILE: join28(
13012
13045
  frameworkAdapter.getAgentDir(agent.code_name),
13013
13046
  ".current-turn-initiator.json"
13014
13047
  )
@@ -13028,7 +13061,7 @@ async function processAgent(agent, agentStates) {
13028
13061
  log(`Channel credentials written for '${agent.code_name}/direct-chat'`);
13029
13062
  }
13030
13063
  }
13031
- const staleChannelsPath = join27(projectDir, ".mcp-channels.json");
13064
+ const staleChannelsPath = join28(projectDir, ".mcp-channels.json");
13032
13065
  if (existsSync12(staleChannelsPath)) {
13033
13066
  try {
13034
13067
  rmSync5(staleChannelsPath, { force: true });
@@ -13118,7 +13151,7 @@ async function processAgent(agent, agentStates) {
13118
13151
  }
13119
13152
  if (hostFlagStore().getBoolean("connectivity-probe")) {
13120
13153
  try {
13121
- const probeProjectDir = join27(homedir12(), ".augmented", agent.code_name, "project");
13154
+ const probeProjectDir = join28(homedir12(), ".augmented", agent.code_name, "project");
13122
13155
  let probeSet = integrations;
13123
13156
  try {
13124
13157
  const quarantined = await api.post("/host/agent-integrations/quarantined", { agent_id: agent.agent_id });
@@ -13164,7 +13197,7 @@ async function processAgent(agent, agentStates) {
13164
13197
  const forceDue = attemptsLeft > 0;
13165
13198
  let probeRan = false;
13166
13199
  try {
13167
- const probeProjectDir = join27(homedir12(), ".augmented", agent.code_name, "project");
13200
+ const probeProjectDir = join28(homedir12(), ".augmented", agent.code_name, "project");
13168
13201
  probeRan = await runAgentSessionToolBindProbes(agent, integrations, probeProjectDir, { forceDue });
13169
13202
  } catch (err) {
13170
13203
  log(`Session-tool-bind probe failed for '${agent.code_name}': ${err.message}`);
@@ -13241,8 +13274,8 @@ async function processAgent(agent, agentStates) {
13241
13274
  const intHash = computeIntegrationsHash(integrations);
13242
13275
  const prevIntHash = agentState.knownIntegrationHashes.get(agent.agent_id);
13243
13276
  if (intHash !== prevIntHash) {
13244
- const projectDir = join27(homedir12(), ".augmented", agent.code_name, "project");
13245
- const envIntPath = join27(projectDir, ".env.integrations");
13277
+ const projectDir = join28(homedir12(), ".augmented", agent.code_name, "project");
13278
+ const envIntPath = join28(projectDir, ".env.integrations");
13246
13279
  let preWriteEnv;
13247
13280
  try {
13248
13281
  preWriteEnv = readFileSync22(envIntPath, "utf-8");
@@ -13264,7 +13297,7 @@ async function processAgent(agent, agentStates) {
13264
13297
  }
13265
13298
  if (fw === "claude-code" && isSessionHealthy(agent.code_name)) {
13266
13299
  try {
13267
- const projectMcpPath = join27(projectDir, ".mcp.json");
13300
+ const projectMcpPath = join28(projectDir, ".mcp.json");
13268
13301
  const postWriteEnv = readFileSync22(envIntPath, "utf-8");
13269
13302
  const mcpContent = readFileSync22(projectMcpPath, "utf-8");
13270
13303
  const changedVars = diffEnvIntegrations(preWriteEnv, postWriteEnv);
@@ -13507,10 +13540,21 @@ async function processAgent(agent, agentStates) {
13507
13540
  }));
13508
13541
  const bundle = buildIntegrationBundle(renderedScopes);
13509
13542
  const contentHash = createHash17("sha256").update(bundleFingerprint(bundle.files)).digest("hex").slice(0, 12);
13510
- const hashKey = `plugin-skill:${agent.agent_id}:${integrationSkillId}`;
13511
- if (agentState.knownSkillHashes.get(hashKey) === contentHash) continue;
13543
+ if (!shouldWriteIntegrationSkill(
13544
+ agentState.knownSkillHashes,
13545
+ agent.agent_id,
13546
+ integrationSkillId,
13547
+ contentHash
13548
+ )) {
13549
+ continue;
13550
+ }
13512
13551
  frameworkAdapter.installSkillFiles(agent.code_name, integrationSkillId, bundle.files);
13513
- agentState.knownSkillHashes.set(hashKey, contentHash);
13552
+ rememberIntegrationSkill(
13553
+ agentState.knownSkillHashes,
13554
+ agent.agent_id,
13555
+ integrationSkillId,
13556
+ contentHash
13557
+ );
13514
13558
  for (const s of scopes) installedIntegrationSkills.push(s.skill_name);
13515
13559
  log(`Installed integration skill bundle '${integrationSkillId}' for '${agent.code_name}' (${scopes.length} scope(s))`);
13516
13560
  } catch (err) {
@@ -13523,12 +13567,12 @@ async function processAgent(agent, agentStates) {
13523
13567
  const frameworkId2 = frameworkAdapter.id;
13524
13568
  const candidateSkillDirs = [
13525
13569
  // Claude Code — framework runtime tree
13526
- join27(homedir13(), ".augmented", agent.code_name, "skills"),
13570
+ join28(homedir13(), ".augmented", agent.code_name, "skills"),
13527
13571
  // Claude Code — project tree
13528
- join27(homedir13(), ".augmented", agent.code_name, "project", ".claude", "skills"),
13572
+ join28(homedir13(), ".augmented", agent.code_name, "project", ".claude", "skills"),
13529
13573
  // Defensive: legacy provision-side path, not currently an
13530
13574
  // install target but cheap to sweep.
13531
- join27(agentDir, ".claude", "skills")
13575
+ join28(agentDir, ".claude", "skills")
13532
13576
  ];
13533
13577
  const existingDirs = candidateSkillDirs.filter((d) => existsSync12(d));
13534
13578
  const discoveredEntries = /* @__PURE__ */ new Set();
@@ -13543,12 +13587,17 @@ async function processAgent(agent, agentStates) {
13543
13587
  }
13544
13588
  }
13545
13589
  const removeSkillFolder = (entry, reason) => {
13546
- for (const dir of existingDirs) {
13547
- const p = join27(dir, entry);
13548
- if (existsSync12(p)) {
13549
- rmSync6(p, { recursive: true, force: true });
13590
+ removeIntegrationSkillFolder({
13591
+ cache: agentState.knownSkillHashes,
13592
+ agentId: agent.agent_id,
13593
+ entry,
13594
+ dirs: existingDirs,
13595
+ removeDir: (p) => {
13596
+ if (existsSync12(p)) {
13597
+ rmSync6(p, { recursive: true, force: true });
13598
+ }
13550
13599
  }
13551
- }
13600
+ });
13552
13601
  log(`Removed ${reason} '${entry}' for '${agent.code_name}' (framework=${frameworkId2})`);
13553
13602
  };
13554
13603
  for (const entry of discoveredEntries) {
@@ -13564,7 +13613,7 @@ async function processAgent(agent, agentStates) {
13564
13613
  const sharedSkillsPayload = refreshAny.shared_skills;
13565
13614
  const desiredResolved = globalSkillsPayload !== void 0 || sharedSkillsPayload !== void 0;
13566
13615
  const manifestPath = managedSkillManifestPath(
13567
- join27(homedir12(), ".augmented", agent.code_name)
13616
+ join28(homedir12(), ".augmented", agent.code_name)
13568
13617
  );
13569
13618
  const prevIds = /* @__PURE__ */ new Set([
13570
13619
  ...agentState.knownGlobalSkillIds.get(agent.agent_id) ?? /* @__PURE__ */ new Set(),
@@ -13584,15 +13633,15 @@ async function processAgent(agent, agentStates) {
13584
13633
  }
13585
13634
  if (plan.removes.length) {
13586
13635
  const globalSkillDirs = [
13587
- join27(homedir12(), ".augmented", agent.code_name, "skills"),
13588
- join27(homedir12(), ".augmented", agent.code_name, "project", ".claude", "skills"),
13589
- join27(agentDir, ".claude", "skills")
13636
+ join28(homedir12(), ".augmented", agent.code_name, "skills"),
13637
+ join28(homedir12(), ".augmented", agent.code_name, "project", ".claude", "skills"),
13638
+ join28(agentDir, ".claude", "skills")
13590
13639
  ];
13591
13640
  for (const id of plan.removes) {
13592
13641
  let prunedAny = false;
13593
13642
  for (const dir of globalSkillDirs) {
13594
- const p = join27(dir, id);
13595
- if (existsSync12(p) && existsSync12(join27(p, "SKILL.md"))) {
13643
+ const p = join28(dir, id);
13644
+ if (existsSync12(p) && existsSync12(join28(p, "SKILL.md"))) {
13596
13645
  rmSync5(p, { recursive: true, force: true });
13597
13646
  prunedAny = true;
13598
13647
  }
@@ -13823,7 +13872,7 @@ async function processAgent(agent, agentStates) {
13823
13872
  const sess = getSessionState(agent.code_name);
13824
13873
  let mcpJsonParsed = null;
13825
13874
  try {
13826
- const mcpPath = join27(getProjectDir(agent.code_name), ".mcp.json");
13875
+ const mcpPath = join28(getProjectDir(agent.code_name), ".mcp.json");
13827
13876
  mcpJsonParsed = JSON.parse(readFileSync22(mcpPath, "utf-8"));
13828
13877
  } catch {
13829
13878
  }
@@ -14250,7 +14299,7 @@ Retried to the limit after repeated stalls \u2014 needs a look.`).catch(() => {
14250
14299
  if (trackedFiles.length > 0 && existsSync12(agentDir)) {
14251
14300
  const hashes = /* @__PURE__ */ new Map();
14252
14301
  for (const file of trackedFiles) {
14253
- const h = hashFile(join27(agentDir, file));
14302
+ const h = hashFile(join28(agentDir, file));
14254
14303
  if (h) hashes.set(file, h);
14255
14304
  }
14256
14305
  agentState.writtenHashes.set(agent.agent_id, hashes);
@@ -14265,7 +14314,7 @@ Retried to the limit after repeated stalls \u2014 needs a look.`).catch(() => {
14265
14314
  refreshData.agent.onboarding_state
14266
14315
  );
14267
14316
  const obStep = obState.step;
14268
- const markerPath = join27(homedir12(), ".augmented", agent.code_name, "onboarding-drive.json");
14317
+ const markerPath = join28(homedir12(), ".augmented", agent.code_name, "onboarding-drive.json");
14269
14318
  const marker = readOnboardingDriveMarker(markerPath);
14270
14319
  const decision = decideOnboardingDrive(obStep, marker, Date.now(), obState.generation ?? 0);
14271
14320
  if (decision.clearMarker) {
@@ -14353,7 +14402,7 @@ async function ensureOpencodeRuntime(agent, refreshData, agentTimezone) {
14353
14402
  }
14354
14403
  stopOpencodeSlackIngest(codeName, log);
14355
14404
  stopOpencodeTelegramIngest(codeName, log);
14356
- const opencodeProjectDir = join27(getFramework("opencode").getAgentDir(codeName), "provision");
14405
+ const opencodeProjectDir = join28(getFramework("opencode").getAgentDir(codeName), "provision");
14357
14406
  const serveEnv = {
14358
14407
  AGT_HOST: requireHost(),
14359
14408
  AGT_API_KEY: getApiKey() ?? void 0,
@@ -14403,8 +14452,8 @@ async function ensurePersistentSession(agent, tasks, boardItems, refreshData) {
14403
14452
  });
14404
14453
  }
14405
14454
  const projectDir = getProjectDir(codeName);
14406
- const mcpConfigPath = join27(projectDir, ".mcp.json");
14407
- const claudeMdPath = join27(projectDir, "CLAUDE.md");
14455
+ const mcpConfigPath = join28(projectDir, ".mcp.json");
14456
+ const claudeMdPath = join28(projectDir, "CLAUDE.md");
14408
14457
  if (restartBreaker.isTripped(codeName)) {
14409
14458
  const trip = restartBreaker.getTrip(codeName);
14410
14459
  return {
@@ -15023,7 +15072,7 @@ async function handleRestartDoorbell(agentId, requestedAt, restartReason) {
15023
15072
  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}`));
15024
15073
  void (async () => {
15025
15074
  try {
15026
- const { collectDiagnostics } = await import("../persistent-session-BDNW4K6M.js");
15075
+ const { collectDiagnostics } = await import("../persistent-session-CMG4VWT6.js");
15027
15076
  await api.post("/host/heartbeat", {
15028
15077
  host_id: hostId,
15029
15078
  agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor)
@@ -15073,7 +15122,7 @@ async function respawnAgentAfterMcpStop(codeName, reason) {
15073
15122
  }
15074
15123
  try {
15075
15124
  const hostId = await getHostId();
15076
- const { collectDiagnostics } = await import("../persistent-session-BDNW4K6M.js");
15125
+ const { collectDiagnostics } = await import("../persistent-session-CMG4VWT6.js");
15077
15126
  await api.post("/host/heartbeat", {
15078
15127
  host_id: hostId,
15079
15128
  agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor)
@@ -15591,7 +15640,7 @@ async function processClaudePairSessions(agents) {
15591
15640
  killPairSession,
15592
15641
  pairTmuxSession,
15593
15642
  finalizeClaudePairOnboarding
15594
- } = await import("../claude-pair-runtime-5CDR4XPI.js");
15643
+ } = await import("../claude-pair-runtime-AK6RLKSR.js");
15595
15644
  for (const pairId of pendingResp.cancelled_pair_ids ?? []) {
15596
15645
  log(`[claude-pair] sweeping orphan tmux session for pair ${pairId.slice(0, 8)}`);
15597
15646
  const killed = await killPairSession(pairTmuxSession(pairId));
@@ -15845,8 +15894,8 @@ function parseMemoryFile(raw, fallbackName) {
15845
15894
  };
15846
15895
  }
15847
15896
  async function syncMemories(agent, configDir, log2) {
15848
- const projectDir = join27(configDir, agent.code_name, "project");
15849
- const memoryDir = join27(projectDir, "memory");
15897
+ const projectDir = join28(configDir, agent.code_name, "project");
15898
+ const memoryDir = join28(projectDir, "memory");
15850
15899
  const isFreshSync = pendingFreshMemorySync.has(agent.agent_id);
15851
15900
  if (isFreshSync) {
15852
15901
  log2(`[memory-sync] Fresh-sync requested for '${agent.code_name}' \u2014 pulling DB first`);
@@ -15864,7 +15913,7 @@ async function syncMemories(agent, configDir, log2) {
15864
15913
  for (const file of readdirSync7(memoryDir)) {
15865
15914
  if (!file.endsWith(".md")) continue;
15866
15915
  try {
15867
- const raw = readFileSync22(join27(memoryDir, file), "utf-8");
15916
+ const raw = readFileSync22(join28(memoryDir, file), "utf-8");
15868
15917
  const fileHash = createHash16("sha256").update(raw).digest("hex").slice(0, 16);
15869
15918
  currentHashes.set(file, fileHash);
15870
15919
  if (prevHashes.get(file) === fileHash) continue;
@@ -15889,7 +15938,7 @@ async function syncMemories(agent, configDir, log2) {
15889
15938
  } catch (err) {
15890
15939
  for (const mem of changedMemories) {
15891
15940
  for (const [file] of currentHashes) {
15892
- const parsed = parseMemoryFile(readFileSync22(join27(memoryDir, file), "utf-8"), file.replace(/\.md$/, ""));
15941
+ const parsed = parseMemoryFile(readFileSync22(join28(memoryDir, file), "utf-8"), file.replace(/\.md$/, ""));
15893
15942
  if (parsed?.name === mem.name) currentHashes.delete(file);
15894
15943
  }
15895
15944
  }
@@ -15924,7 +15973,7 @@ async function downloadMemories(agent, memoryDir, log2, { force }) {
15924
15973
  const mem = dbMemories.memories[i];
15925
15974
  const rawSlug = mem.name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)/g, "").slice(0, 60);
15926
15975
  const slug = rawSlug || `memory-${i}`;
15927
- const filePath = join27(memoryDir, `${slug}.md`);
15976
+ const filePath = join28(memoryDir, `${slug}.md`);
15928
15977
  const desired = `---
15929
15978
  name: ${JSON.stringify(mem.name)}
15930
15979
  type: ${mem.type}
@@ -16227,7 +16276,7 @@ function startManager(opts) {
16227
16276
  log(`[startup] state rehydration failed (continuing with empty state): ${err.message}`);
16228
16277
  }
16229
16278
  log(
16230
- `[startup] worker pid=${process.pid} ppid=${process.ppid} node=${process.version} log=${join27(homedir12(), ".augmented", "manager.log")}`
16279
+ `[startup] worker pid=${process.pid} ppid=${process.ppid} node=${process.version} log=${join28(homedir12(), ".augmented", "manager.log")}`
16231
16280
  );
16232
16281
  deployMcpAssets();
16233
16282
  reapOrphanChannelMcps({ log });
@@ -16353,14 +16402,14 @@ function restartRunningChannelMcps(basenames) {
16353
16402
  }
16354
16403
  }
16355
16404
  function deployMcpAssets() {
16356
- const targetDir = join27(homedir12(), ".augmented", "_mcp");
16405
+ const targetDir = join28(homedir12(), ".augmented", "_mcp");
16357
16406
  mkdirSync10(targetDir, { recursive: true });
16358
16407
  const moduleDir = dirname8(fileURLToPath(import.meta.url));
16359
16408
  let mcpSourceDir = "";
16360
16409
  let dir = moduleDir;
16361
16410
  for (let i = 0; i < 6; i++) {
16362
- const candidate = join27(dir, "dist", "mcp");
16363
- if (existsSync12(join27(candidate, "index.js"))) {
16411
+ const candidate = join28(dir, "dist", "mcp");
16412
+ if (existsSync12(join28(candidate, "index.js"))) {
16364
16413
  mcpSourceDir = candidate;
16365
16414
  break;
16366
16415
  }
@@ -16440,8 +16489,8 @@ function deployMcpAssets() {
16440
16489
  // needs restarting to pick up a token rotation.
16441
16490
  "xero.js"
16442
16491
  ]) {
16443
- const src = join27(mcpSourceDir, file);
16444
- const dst = join27(targetDir, file);
16492
+ const src = join28(mcpSourceDir, file);
16493
+ const dst = join28(targetDir, file);
16445
16494
  if (!existsSync12(src)) continue;
16446
16495
  const before = fileHash(dst);
16447
16496
  try {
@@ -16459,14 +16508,14 @@ function deployMcpAssets() {
16459
16508
  log(`[manager] Bundle(s) updated: ${changedBasenames.join(", ")} \u2014 signalling running instances to restart`);
16460
16509
  restartRunningChannelMcps(changedBasenames);
16461
16510
  }
16462
- const localMcpPath = join27(targetDir, "index.js");
16511
+ const localMcpPath = join28(targetDir, "index.js");
16463
16512
  try {
16464
- const agentsDir = join27(homedir12(), ".augmented", "agents");
16513
+ const agentsDir = join28(homedir12(), ".augmented", "agents");
16465
16514
  if (existsSync12(agentsDir)) {
16466
16515
  for (const entry of readdirSync7(agentsDir, { withFileTypes: true })) {
16467
16516
  if (!entry.isDirectory()) continue;
16468
16517
  for (const subdir of ["provision", "project"]) {
16469
- const mcpJsonPath = join27(agentsDir, entry.name, subdir, ".mcp.json");
16518
+ const mcpJsonPath = join28(agentsDir, entry.name, subdir, ".mcp.json");
16470
16519
  try {
16471
16520
  const raw = readFileSync22(mcpJsonPath, "utf-8");
16472
16521
  if (!raw.includes("@integrity-labs/augmented-mcp")) continue;