@integrity-labs/agt-cli 0.28.528 → 0.28.529

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-7N55RDMG.js";
56
+ } from "../chunk-MKSL2EQU.js";
57
57
  import {
58
58
  getProjectDir as getProjectDir2,
59
59
  getReadyTasks,
@@ -67,6 +67,7 @@ import {
67
67
  CLAUDE_MD_MAX_CHARS,
68
68
  CONVERSATION_FAILURE_CATEGORIES,
69
69
  DEFAULT_FRAMEWORK,
70
+ DEFAULT_NEIGHBOURHOOD_MS,
70
71
  FLAGS_SCHEMA_VERSION,
71
72
  FLAG_REGISTRY,
72
73
  FORCED_UPDATE_HARD_DEADLINE_MS,
@@ -99,6 +100,7 @@ import {
99
100
  estimateActiveTasksTokens,
100
101
  execFilePromiseLong,
101
102
  extractFrontmatter,
103
+ extractQualifyingTurns,
102
104
  forcedUpdatePendingForMs,
103
105
  formatActorId,
104
106
  formatCursorAdvanceShortfall,
@@ -118,6 +120,7 @@ import {
118
120
  isAgentIdle,
119
121
  isAgentTimezoneOverrideExpired,
120
122
  isBareAck,
123
+ isBucketQualified,
121
124
  isConversationFailureCategory,
122
125
  isEmptyTotals,
123
126
  isForcedUpdatePastDeadline,
@@ -177,16 +180,16 @@ import {
177
180
  toOpencodeModel,
178
181
  transcriptActivityAgeSeconds,
179
182
  writeEgressAllowlist
180
- } from "../chunk-PR3QSOLI.js";
183
+ } from "../chunk-Q4XGKOHZ.js";
181
184
  import {
182
185
  reapOrphanChannelMcps
183
186
  } from "../chunk-XWVM4KPK.js";
184
187
 
185
188
  // src/lib/manager-worker.ts
186
189
  import { createHash as createHash16 } from "crypto";
187
- 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";
190
+ import { readFileSync as readFileSync22, writeFileSync as writeFileSync13, mkdirSync as mkdirSync10, existsSync as existsSync12, rmSync as rmSync5, readdirSync as readdirSync8, statSync as statSync7, copyFileSync } from "fs";
188
191
  import { execFileSync as syncExecFile } from "child_process";
189
- import { join as join28, dirname as dirname8, delimiter as pathDelimiter } from "path";
192
+ import { join as join29, dirname as dirname8, delimiter as pathDelimiter } from "path";
190
193
  import { homedir as homedir12 } from "os";
191
194
  import { fileURLToPath } from "url";
192
195
 
@@ -2427,7 +2430,7 @@ function accountEnforcementMarkerPath(codeName) {
2427
2430
  return join10(homedir6(), ".augmented", codeName, ACCOUNT_ENFORCEMENT_MARKER_FILENAME);
2428
2431
  }
2429
2432
  function syncAccountEnforcementMarker(codeName, level, log2 = (m) => process.stderr.write(`${m}
2430
- `)) {
2433
+ `), text) {
2431
2434
  if (level !== "warn" && level !== "mute") {
2432
2435
  clearAccountEnforcementMarker(codeName, log2);
2433
2436
  return;
@@ -2437,7 +2440,7 @@ function syncAccountEnforcementMarker(codeName, level, log2 = (m) => process.std
2437
2440
  const tempPath = `${path}.${process.pid}.tmp`;
2438
2441
  try {
2439
2442
  mkdirSync4(dir, { recursive: true });
2440
- writeFileSync5(tempPath, serializeAccountEnforcementMarker(level), "utf-8");
2443
+ writeFileSync5(tempPath, serializeAccountEnforcementMarker(level, text), "utf-8");
2441
2444
  renameSync2(tempPath, path);
2442
2445
  } catch (err) {
2443
2446
  try {
@@ -4327,14 +4330,14 @@ import { join as join17 } from "path";
4327
4330
  function integrationSkillHashKey(agentId, skillId) {
4328
4331
  return `plugin-skill:${agentId}:${skillId}`;
4329
4332
  }
4330
- function shouldWriteIntegrationSkill(cache, agentId, skillId, contentHash) {
4331
- return cache.get(integrationSkillHashKey(agentId, skillId)) !== contentHash;
4333
+ function shouldWriteIntegrationSkill(cache2, agentId, skillId, contentHash) {
4334
+ return cache2.get(integrationSkillHashKey(agentId, skillId)) !== contentHash;
4332
4335
  }
4333
- function rememberIntegrationSkill(cache, agentId, skillId, contentHash) {
4334
- cache.set(integrationSkillHashKey(agentId, skillId), contentHash);
4336
+ function rememberIntegrationSkill(cache2, agentId, skillId, contentHash) {
4337
+ cache2.set(integrationSkillHashKey(agentId, skillId), contentHash);
4335
4338
  }
4336
- function forgetIntegrationSkill(cache, agentId, skillId) {
4337
- cache.delete(integrationSkillHashKey(agentId, skillId));
4339
+ function forgetIntegrationSkill(cache2, agentId, skillId) {
4340
+ cache2.delete(integrationSkillHashKey(agentId, skillId));
4338
4341
  }
4339
4342
  function removeIntegrationSkillFolder(opts) {
4340
4343
  forgetIntegrationSkill(opts.cache, opts.agentId, opts.entry);
@@ -6122,15 +6125,174 @@ async function syncAndCheckClaudeScheduler(agent, tasks, boardItems, refreshData
6122
6125
  }
6123
6126
  }
6124
6127
 
6128
+ // src/lib/occupancy-gate.ts
6129
+ import { closeSync, openSync, readdirSync as readdirSync5, readSync, statSync as statSync5 } from "fs";
6130
+ import { join as join25 } from "path";
6131
+ var TAIL_BYTES = 256 * 1024;
6132
+ var MAX_RECORD_ALIGN_BYTES = 8 * 1024 * 1024;
6133
+ var GATE_MAX_BUCKET_AGE_MS = 30 * 6e4;
6134
+ var TRANSCRIPT_MTIME_WINDOW_MS4 = GATE_MAX_BUCKET_AGE_MS + DEFAULT_NEIGHBOURHOOD_MS + 6e4;
6135
+ var cache = /* @__PURE__ */ new Map();
6136
+ function readAlignedTail(path, tailBytes, maxAlignBytes) {
6137
+ let fd = null;
6138
+ try {
6139
+ const size = statSync5(path).size;
6140
+ if (size <= 0) return { content: "", complete: true };
6141
+ fd = openSync(path, "r");
6142
+ let readStart = Math.max(0, size - tailBytes);
6143
+ if (readStart > 0) {
6144
+ const scanFloor = Math.max(0, readStart - maxAlignBytes);
6145
+ const CHUNK = 64 * 1024;
6146
+ let pos = readStart;
6147
+ let boundary = -1;
6148
+ while (pos > scanFloor) {
6149
+ const from = Math.max(scanFloor, pos - CHUNK);
6150
+ const len2 = pos - from;
6151
+ const b = Buffer.allocUnsafe(len2);
6152
+ if (readSync(fd, b, 0, len2, from) !== len2) return null;
6153
+ const idx = b.lastIndexOf(10);
6154
+ if (idx !== -1) {
6155
+ boundary = from + idx + 1;
6156
+ break;
6157
+ }
6158
+ pos = from;
6159
+ }
6160
+ if (boundary !== -1) {
6161
+ readStart = boundary;
6162
+ } else if (scanFloor === 0) {
6163
+ readStart = 0;
6164
+ } else {
6165
+ return { content: "", complete: false };
6166
+ }
6167
+ }
6168
+ const len = size - readStart;
6169
+ const buf = Buffer.allocUnsafe(len);
6170
+ if (readSync(fd, buf, 0, len, readStart) !== len) return null;
6171
+ return { content: buf.toString("utf-8", 0, len), complete: true };
6172
+ } catch {
6173
+ return null;
6174
+ } finally {
6175
+ if (fd != null) {
6176
+ try {
6177
+ closeSync(fd);
6178
+ } catch {
6179
+ }
6180
+ }
6181
+ }
6182
+ }
6183
+ function isAbsentDirError(err) {
6184
+ const code = err.code;
6185
+ return code === "ENOENT" || code === "ENOTDIR";
6186
+ }
6187
+ function candidateTranscriptPaths(dir) {
6188
+ const paths = [];
6189
+ let top;
6190
+ try {
6191
+ top = readdirSync5(dir);
6192
+ } catch {
6193
+ return { paths, complete: false };
6194
+ }
6195
+ let complete = true;
6196
+ for (const name of top) {
6197
+ if (name.endsWith(".jsonl")) {
6198
+ paths.push(join25(dir, name));
6199
+ continue;
6200
+ }
6201
+ const subDir = join25(dir, name, "subagents");
6202
+ let subs;
6203
+ try {
6204
+ subs = readdirSync5(subDir);
6205
+ } catch (err) {
6206
+ if (!isAbsentDirError(err)) complete = false;
6207
+ continue;
6208
+ }
6209
+ for (const sub of subs) {
6210
+ if (sub.endsWith(".jsonl")) paths.push(join25(subDir, sub));
6211
+ }
6212
+ }
6213
+ return { paths, complete };
6214
+ }
6215
+ function collectQualifyingTurns(codeName, nowMs, opts = {}) {
6216
+ const dir = opts.transcriptDir ?? sessionTranscriptDir(getProjectDir(codeName));
6217
+ const tailBytes = opts.tailBytes ?? TAIL_BYTES;
6218
+ const maxAlignBytes = opts.maxAlignBytes ?? MAX_RECORD_ALIGN_BYTES;
6219
+ const sinceMs = nowMs - TRANSCRIPT_MTIME_WINDOW_MS4;
6220
+ const agentCache = cache.get(codeName) ?? /* @__PURE__ */ new Map();
6221
+ const nextCache = /* @__PURE__ */ new Map();
6222
+ const all = /* @__PURE__ */ new Set();
6223
+ let transcriptsRead = 0;
6224
+ const { paths, complete: scanComplete } = candidateTranscriptPaths(dir);
6225
+ let complete = scanComplete;
6226
+ for (const path of paths) {
6227
+ let st;
6228
+ try {
6229
+ st = statSync5(path);
6230
+ } catch (err) {
6231
+ if (!isAbsentDirError(err)) complete = false;
6232
+ continue;
6233
+ }
6234
+ if (!st.isFile()) continue;
6235
+ if (st.mtimeMs < sinceMs) continue;
6236
+ const seen = agentCache.get(path);
6237
+ if (seen && seen.mtimeMs === st.mtimeMs && seen.size === st.size) {
6238
+ transcriptsRead += 1;
6239
+ nextCache.set(path, seen);
6240
+ for (const t of seen.turns) all.add(t);
6241
+ continue;
6242
+ }
6243
+ const aligned = readAlignedTail(path, tailBytes, maxAlignBytes);
6244
+ if (aligned === null) {
6245
+ complete = false;
6246
+ continue;
6247
+ }
6248
+ if (!aligned.complete) {
6249
+ complete = false;
6250
+ continue;
6251
+ }
6252
+ const content = aligned.content;
6253
+ transcriptsRead += 1;
6254
+ const turns = extractQualifyingTurns(content, { startMs: sinceMs });
6255
+ nextCache.set(path, { mtimeMs: st.mtimeMs, size: st.size, turns });
6256
+ for (const t of turns) all.add(t);
6257
+ }
6258
+ cache.set(codeName, nextCache);
6259
+ return { turns: [...all].sort((a, b) => a - b), transcriptsRead, complete };
6260
+ }
6261
+ function qualifyBuckets(buckets, qualifying, mode, nowMs, neighbourhoodMs = DEFAULT_NEIGHBOURHOOD_MS) {
6262
+ const failOpen = !qualifying.complete;
6263
+ const kept = [];
6264
+ let qualified = 0;
6265
+ let unqualifiedDropped = 0;
6266
+ let unreadable = 0;
6267
+ for (const b of buckets) {
6268
+ const startMs = Date.parse(b.bucket);
6269
+ const parsed = Number.isFinite(startMs);
6270
+ const tooOld = parsed && nowMs - startMs > GATE_MAX_BUCKET_AGE_MS;
6271
+ if (failOpen || tooOld || !parsed) {
6272
+ if (failOpen || !parsed) unreadable += 1;
6273
+ kept.push(b);
6274
+ continue;
6275
+ }
6276
+ if (isBucketQualified(startMs, qualifying.turns, neighbourhoodMs)) {
6277
+ qualified += 1;
6278
+ kept.push(b);
6279
+ } else {
6280
+ unqualifiedDropped += 1;
6281
+ if (mode === "shadow") kept.push(b);
6282
+ }
6283
+ }
6284
+ return { kept, qualified, unqualifiedDropped, unreadable };
6285
+ }
6286
+
6125
6287
  // src/lib/pane-occupancy-sampler.ts
6126
- import { statSync as statSync5 } from "fs";
6288
+ import { statSync as statSync6 } from "fs";
6127
6289
  var SAMPLE_INTERVAL_MS = 1e4;
6128
6290
  var IDLE_GAP_MS = 12e4;
6129
6291
  var POST_IDLE_CREDIT_MS = 6e4;
6130
6292
  var lastMtimeMs = /* @__PURE__ */ new Map();
6131
6293
  function paneMtimeMs(codeName) {
6132
6294
  try {
6133
- return statSync5(paneLogPath(codeName)).mtimeMs;
6295
+ return statSync6(paneLogPath(codeName)).mtimeMs;
6134
6296
  } catch {
6135
6297
  return null;
6136
6298
  }
@@ -7293,7 +7455,7 @@ async function fireOpencodeScheduledTask(agent, task) {
7293
7455
  import { createHash as createHash15 } from "crypto";
7294
7456
  import { existsSync as existsSync10, mkdirSync as mkdirSync7, readFileSync as readFileSync19, renameSync as renameSync4, unlinkSync as unlinkSync2, writeFileSync as writeFileSync10 } from "fs";
7295
7457
  import { randomUUID } from "crypto";
7296
- import { join as join25 } from "path";
7458
+ import { join as join26 } from "path";
7297
7459
 
7298
7460
  // src/lib/telegram-ingest.ts
7299
7461
  import https2 from "https";
@@ -7841,7 +8003,7 @@ function createFileOffsetStore(codeName, log2, currentBotId) {
7841
8003
  let filePath;
7842
8004
  try {
7843
8005
  dir = getFramework("opencode").getAgentDir(codeName);
7844
- filePath = join25(dir, "telegram-getupdates-offset-opencode.json");
8006
+ filePath = join26(dir, "telegram-getupdates-offset-opencode.json");
7845
8007
  } catch {
7846
8008
  dir = null;
7847
8009
  filePath = null;
@@ -8120,24 +8282,24 @@ function partitionActionableByPoison(actionable, states, config2) {
8120
8282
  }
8121
8283
 
8122
8284
  // src/lib/restart-flags.ts
8123
- import { existsSync as existsSync11, mkdirSync as mkdirSync8, readdirSync as readdirSync5, readFileSync as readFileSync20, renameSync as renameSync5, rmSync as rmSync4, writeFileSync as writeFileSync11 } from "fs";
8285
+ import { existsSync as existsSync11, mkdirSync as mkdirSync8, readdirSync as readdirSync6, readFileSync as readFileSync20, renameSync as renameSync5, rmSync as rmSync4, writeFileSync as writeFileSync11 } from "fs";
8124
8286
  import { homedir as homedir11 } from "os";
8125
- import { join as join26 } from "path";
8287
+ import { join as join27 } from "path";
8126
8288
  import { randomUUID as randomUUID2 } from "crypto";
8127
8289
  function restartFlagsDir() {
8128
- return join26(homedir11(), ".augmented", "restart-flags");
8290
+ return join27(homedir11(), ".augmented", "restart-flags");
8129
8291
  }
8130
8292
  function flagPath(codeName) {
8131
- return join26(restartFlagsDir(), `${codeName}.flag`);
8293
+ return join27(restartFlagsDir(), `${codeName}.flag`);
8132
8294
  }
8133
8295
  function readRestartFlags() {
8134
8296
  const dir = restartFlagsDir();
8135
8297
  if (!existsSync11(dir)) return [];
8136
8298
  const out = [];
8137
- for (const entry of readdirSync5(dir)) {
8299
+ for (const entry of readdirSync6(dir)) {
8138
8300
  if (!entry.endsWith(".flag")) continue;
8139
8301
  try {
8140
- const raw = readFileSync20(join26(dir, entry), "utf8");
8302
+ const raw = readFileSync20(join27(dir, entry), "utf8");
8141
8303
  const parsed = JSON.parse(raw);
8142
8304
  if (typeof parsed.codeName !== "string" || parsed.codeName.length === 0) {
8143
8305
  parsed.codeName = entry.replace(/\.flag$/, "");
@@ -8255,8 +8417,8 @@ async function sendError(flag, opts, text) {
8255
8417
  }
8256
8418
 
8257
8419
  // src/lib/restart-context.ts
8258
- import { readdirSync as readdirSync6, readFileSync as readFileSync21, writeFileSync as writeFileSync12, mkdirSync as mkdirSync9, unlinkSync as unlinkSync3 } from "fs";
8259
- import { dirname as dirname7, join as join27 } from "path";
8420
+ import { readdirSync as readdirSync7, readFileSync as readFileSync21, writeFileSync as writeFileSync12, mkdirSync as mkdirSync9, unlinkSync as unlinkSync3 } from "fs";
8421
+ import { dirname as dirname7, join as join28 } from "path";
8260
8422
  var SLACK_PENDING_INBOUND_DIRNAME = "slack-pending-inbound";
8261
8423
  var SLACK_RESTART_CONTEXT_DIRNAME = "slack-restart-context";
8262
8424
  var MAX_TOPIC_CHARS = 140;
@@ -8268,10 +8430,10 @@ function augmentedAgentDir(codeName) {
8268
8430
  return dirname7(getProjectDir(codeName));
8269
8431
  }
8270
8432
  function slackPendingInboundDir(codeName) {
8271
- return join27(augmentedAgentDir(codeName), SLACK_PENDING_INBOUND_DIRNAME);
8433
+ return join28(augmentedAgentDir(codeName), SLACK_PENDING_INBOUND_DIRNAME);
8272
8434
  }
8273
8435
  function slackRestartContextDir(codeName) {
8274
- return join27(augmentedAgentDir(codeName), SLACK_RESTART_CONTEXT_DIRNAME);
8436
+ return join28(augmentedAgentDir(codeName), SLACK_RESTART_CONTEXT_DIRNAME);
8275
8437
  }
8276
8438
  function sanitizeTopic(raw) {
8277
8439
  const cleaned = raw.replace(/\s+/g, " ").trim().replace(/[<>]/g, " ").replace(/\s+/g, " ").trim();
@@ -8306,7 +8468,7 @@ function computeRestartContextHints(markers, allTurns, nowMs, reconstruct = reco
8306
8468
  }
8307
8469
  function safeReaddir(dir) {
8308
8470
  try {
8309
- return readdirSync6(dir);
8471
+ return readdirSync7(dir);
8310
8472
  } catch {
8311
8473
  return [];
8312
8474
  }
@@ -8331,7 +8493,7 @@ function pruneHintsExcept(codeName, freshFilenames) {
8331
8493
  if (!filename.endsWith(".json")) continue;
8332
8494
  if (freshFilenames.has(filename)) continue;
8333
8495
  try {
8334
- unlinkSync3(join27(ctxDir, filename));
8496
+ unlinkSync3(join28(ctxDir, filename));
8335
8497
  } catch {
8336
8498
  }
8337
8499
  }
@@ -8352,7 +8514,7 @@ function refreshSlackRestartContextHints(codeNames, opts = {}) {
8352
8514
  }
8353
8515
  const markers = [];
8354
8516
  for (const filename of markerFilenames.slice(0, cap)) {
8355
- const parsed = readStrandedMarker(join27(markerDir, filename));
8517
+ const parsed = readStrandedMarker(join28(markerDir, filename));
8356
8518
  if (parsed) markers.push({ filename, channel: parsed.channel, thread_ts: parsed.thread_ts });
8357
8519
  }
8358
8520
  if (markers.length === 0) {
@@ -8366,7 +8528,7 @@ function refreshSlackRestartContextHints(codeNames, opts = {}) {
8366
8528
  const freshFilenames = /* @__PURE__ */ new Set();
8367
8529
  for (const { filename, hint } of hints) {
8368
8530
  try {
8369
- writeHintFile(join27(ctxDir, filename), ctxDir, hint);
8531
+ writeHintFile(join28(ctxDir, filename), ctxDir, hint);
8370
8532
  freshFilenames.add(filename);
8371
8533
  } catch (err) {
8372
8534
  log2(`[restart-context] ${codeName}: hint write failed for ${filename}: ${err.message}`);
@@ -9646,7 +9808,7 @@ function performLazyDayRolloverReset(codeName, agentTimezone) {
9646
9808
  }
9647
9809
  function paneLogAgeSecondsFor(codeName) {
9648
9810
  try {
9649
- const mtimeMs = statSync6(paneLogPath(codeName)).mtimeMs;
9811
+ const mtimeMs = statSync7(paneLogPath(codeName)).mtimeMs;
9650
9812
  return Math.max(0, Math.floor((Date.now() - mtimeMs) / 1e3));
9651
9813
  } catch (err) {
9652
9814
  if (err?.code === "ENOENT") return null;
@@ -9796,7 +9958,7 @@ var runningChannelSecretHashes = /* @__PURE__ */ new Map();
9796
9958
  var sessionLaunchManagedStructure = /* @__PURE__ */ new Map();
9797
9959
  function projectMcpHash(_codeName, projectDir) {
9798
9960
  try {
9799
- const raw = readFileSync22(join28(projectDir, ".mcp.json"), "utf-8");
9961
+ const raw = readFileSync22(join29(projectDir, ".mcp.json"), "utf-8");
9800
9962
  return createHash16("sha256").update(canonicalJson(JSON.parse(raw))).digest("hex");
9801
9963
  } catch {
9802
9964
  return null;
@@ -9804,7 +9966,7 @@ function projectMcpHash(_codeName, projectDir) {
9804
9966
  }
9805
9967
  function projectMcpKeys(_codeName, projectDir) {
9806
9968
  try {
9807
- const raw = readFileSync22(join28(projectDir, ".mcp.json"), "utf-8");
9969
+ const raw = readFileSync22(join29(projectDir, ".mcp.json"), "utf-8");
9808
9970
  const parsed = JSON.parse(raw);
9809
9971
  const servers = parsed.mcpServers;
9810
9972
  if (!servers || typeof servers !== "object") return /* @__PURE__ */ new Set();
@@ -9822,7 +9984,7 @@ function seedSessionLaunchBaselines(codeName, projectDir) {
9822
9984
  else runningMcpServerKeys.delete(codeName);
9823
9985
  let launchStructure = null;
9824
9986
  try {
9825
- const raw = readFileSync22(join28(projectDir, ".mcp.json"), "utf-8");
9987
+ const raw = readFileSync22(join29(projectDir, ".mcp.json"), "utf-8");
9826
9988
  launchStructure = managedMcpStructureHashFromFile(
9827
9989
  JSON.parse(raw),
9828
9990
  isManagedMcpServerKey
@@ -9932,7 +10094,7 @@ async function runAgentSessionToolBindProbes(agent, integrations, projectDir, op
9932
10094
  if (result && result.rebindCandidates.length > 0 && hostFlagStore().getBoolean("session-tool-rebind")) {
9933
10095
  let mcpJsonForRebind = null;
9934
10096
  try {
9935
- mcpJsonForRebind = JSON.parse(readFileSync22(join28(projectDir, ".mcp.json"), "utf-8"));
10097
+ mcpJsonForRebind = JSON.parse(readFileSync22(join29(projectDir, ".mcp.json"), "utf-8"));
9936
10098
  } catch {
9937
10099
  mcpJsonForRebind = null;
9938
10100
  }
@@ -10076,7 +10238,7 @@ function checkMcpConfigDriftAndScheduleRestart(codeName, projectDir) {
10076
10238
  function projectChannelSecretHash(projectDir) {
10077
10239
  try {
10078
10240
  const entries = parseEnvIntegrations(
10079
- readFileSync22(join28(projectDir, ".env.integrations"), "utf-8")
10241
+ readFileSync22(join29(projectDir, ".env.integrations"), "utf-8")
10080
10242
  );
10081
10243
  return channelSecretValueHash(entries, CHANNEL_SECRET_ENV_KEYS);
10082
10244
  } catch {
@@ -10172,7 +10334,7 @@ var agentRestartTimezoneInputs = /* @__PURE__ */ new Map();
10172
10334
  var lastVersionCheckAt = 0;
10173
10335
  var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
10174
10336
  var lastResponsivenessProbeAt = 0;
10175
- var agtCliVersion = true ? "0.28.528" : "dev";
10337
+ var agtCliVersion = true ? "0.28.529" : "dev";
10176
10338
  function resolveBrewPath(execFileSync2) {
10177
10339
  try {
10178
10340
  const out = execFileSync2("which", ["brew"], { timeout: 5e3 }).toString().trim();
@@ -10560,7 +10722,7 @@ async function ensureOpencodeBinary() {
10560
10722
  try {
10561
10723
  const prefix = execFileSync2("npm", ["prefix", "-g"], { encoding: "utf-8", timeout: 1e4 }).trim();
10562
10724
  if (prefix) {
10563
- const npmBin = join28(prefix, "bin");
10725
+ const npmBin = join29(prefix, "bin");
10564
10726
  const current = (process.env.PATH ?? "").split(pathDelimiter);
10565
10727
  if (!current.includes(npmBin)) {
10566
10728
  process.env.PATH = [npmBin, ...current.filter(Boolean)].join(pathDelimiter);
@@ -10677,7 +10839,7 @@ ${r.stderr}`;
10677
10839
  }
10678
10840
  var UPDATE_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
10679
10841
  function selfUpdateAppliedMarkerPath() {
10680
- return join28(homedir12(), ".augmented", ".last-self-update-applied");
10842
+ return join29(homedir12(), ".augmented", ".last-self-update-applied");
10681
10843
  }
10682
10844
  var selfUpdateUpToDateLogged = false;
10683
10845
  var selfUpdatePinnedLogged = false;
@@ -10706,7 +10868,7 @@ async function checkAndUpdateCli(opts) {
10706
10868
  const isNpmGlobal = !isBrewFormula && resolvedPath.includes("node_modules");
10707
10869
  if (!isBrewFormula && !isNpmGlobal) return "noop";
10708
10870
  const { readFileSync: readF, writeFileSync: writeF } = await import("fs");
10709
- const markerPath = join28(homedir12(), ".augmented", ".last-update-check");
10871
+ const markerPath = join29(homedir12(), ".augmented", ".last-update-check");
10710
10872
  if (!force) {
10711
10873
  try {
10712
10874
  const lastCheck = parseInt(readF(markerPath, "utf-8").trim(), 10);
@@ -11066,12 +11228,12 @@ async function checkClaudeAuth() {
11066
11228
  var evalEmptyMcpConfigPath = null;
11067
11229
  function ensureEvalEmptyMcpConfig() {
11068
11230
  if (evalEmptyMcpConfigPath && existsSync12(evalEmptyMcpConfigPath)) return evalEmptyMcpConfigPath;
11069
- const dir = join28(homedir12(), ".augmented");
11231
+ const dir = join29(homedir12(), ".augmented");
11070
11232
  try {
11071
11233
  mkdirSync10(dir, { recursive: true });
11072
11234
  } catch {
11073
11235
  }
11074
- const p = join28(dir, ".eval-empty-mcp.json");
11236
+ const p = join29(dir, ".eval-empty-mcp.json");
11075
11237
  writeFileSync13(p, JSON.stringify({ mcpServers: {} }));
11076
11238
  evalEmptyMcpConfigPath = p;
11077
11239
  return p;
@@ -11163,10 +11325,10 @@ function resolveConversationEvalBackend() {
11163
11325
  return conversationEvalBackend;
11164
11326
  }
11165
11327
  function getStateFile() {
11166
- return join28(config?.configDir ?? join28(process.env["HOME"] ?? "/tmp", ".augmented"), "manager-state.json");
11328
+ return join29(config?.configDir ?? join29(process.env["HOME"] ?? "/tmp", ".augmented"), "manager-state.json");
11167
11329
  }
11168
11330
  function channelHashCacheDir() {
11169
- return config?.configDir ?? join28(process.env["HOME"] ?? "/tmp", ".augmented");
11331
+ return config?.configDir ?? join29(process.env["HOME"] ?? "/tmp", ".augmented");
11170
11332
  }
11171
11333
  function loadChannelHashCache2() {
11172
11334
  loadChannelHashCache(agentState.knownChannelConfigHashes, channelHashCacheDir());
@@ -11220,7 +11382,7 @@ function removeDeliveryBaselineEntries(agentId) {
11220
11382
  var _channelQuarantineStore = null;
11221
11383
  function channelQuarantineStore() {
11222
11384
  if (!_channelQuarantineStore) {
11223
- const dir = config?.configDir ?? join28(process.env["HOME"] ?? "/tmp", ".augmented");
11385
+ const dir = config?.configDir ?? join29(process.env["HOME"] ?? "/tmp", ".augmented");
11224
11386
  _channelQuarantineStore = new ChannelQuarantineStore(defaultQuarantinePath(dir));
11225
11387
  }
11226
11388
  return _channelQuarantineStore;
@@ -11237,7 +11399,7 @@ function claudeMdSizeFor(codeName) {
11237
11399
  var _hostFlagStore = null;
11238
11400
  function hostFlagStore() {
11239
11401
  if (!_hostFlagStore) {
11240
- const dir = config?.configDir ?? join28(process.env["HOME"] ?? "/tmp", ".augmented");
11402
+ const dir = config?.configDir ?? join29(process.env["HOME"] ?? "/tmp", ".augmented");
11241
11403
  _hostFlagStore = new HostFlagStore({ cachePath: defaultFlagsCachePath(dir), log });
11242
11404
  }
11243
11405
  return _hostFlagStore;
@@ -11264,6 +11426,9 @@ function reportManagerModelCallError(source, err, modelId) {
11264
11426
  function channelQuarantineMode() {
11265
11427
  return hostFlagStore().getString("channel-quarantine-mode");
11266
11428
  }
11429
+ function occupancyQualifierMode() {
11430
+ return hostFlagStore().getString("utilization-occupancy-qualifier") === "enforce" ? "enforce" : "shadow";
11431
+ }
11267
11432
  function channelQuarantineDwellMs() {
11268
11433
  const raw = parseInt(process.env["AGT_CHANNEL_QUARANTINE_DWELL_MS"] ?? "", 10);
11269
11434
  return Number.isFinite(raw) && raw >= 0 ? raw : 18e4;
@@ -11307,13 +11472,13 @@ function parseSkillFrontmatter(content) {
11307
11472
  return out;
11308
11473
  }
11309
11474
  async function refreshSkillsIndexInClaudeMd(configDir, codeName, log2) {
11310
- const { readdirSync: readdirSync8, readFileSync: rfs, existsSync: ex, writeFileSync: writeFileSync14 } = await import("fs");
11311
- const skillsDir = join28(configDir, codeName, "project", ".claude", "skills");
11312
- const claudeMdPath = join28(configDir, codeName, "project", "CLAUDE.md");
11475
+ const { readdirSync: readdirSync9, readFileSync: rfs, existsSync: ex, writeFileSync: writeFileSync14 } = await import("fs");
11476
+ const skillsDir = join29(configDir, codeName, "project", ".claude", "skills");
11477
+ const claudeMdPath = join29(configDir, codeName, "project", "CLAUDE.md");
11313
11478
  if (!ex(skillsDir) || !ex(claudeMdPath)) return;
11314
11479
  const entries = [];
11315
- for (const dir of readdirSync8(skillsDir).sort()) {
11316
- const skillFile = join28(skillsDir, dir, "SKILL.md");
11480
+ for (const dir of readdirSync9(skillsDir).sort()) {
11481
+ const skillFile = join29(skillsDir, dir, "SKILL.md");
11317
11482
  if (!ex(skillFile)) continue;
11318
11483
  try {
11319
11484
  const { name, description } = parseSkillFrontmatter(rfs(skillFile, "utf-8"));
@@ -11380,7 +11545,7 @@ function flushRestartedAgentDiagnostics(hostId, codeNames) {
11380
11545
  if (codeNames.length === 0) return;
11381
11546
  void (async () => {
11382
11547
  try {
11383
- const { collectDiagnostics } = await import("../persistent-session-KAHG73SM.js");
11548
+ const { collectDiagnostics } = await import("../persistent-session-T4IY7AJU.js");
11384
11549
  await api.post("/host/heartbeat", {
11385
11550
  host_id: hostId,
11386
11551
  agent_diagnostics: collectDiagnostics(codeNames, quarantineEntriesFor, claudeMdSizeFor)
@@ -11487,7 +11652,7 @@ async function pollCycle() {
11487
11652
  }
11488
11653
  try {
11489
11654
  const { detectHostSecurity } = await import("../host-security-6PDFG7F5.js");
11490
- const { collectDiagnostics } = await import("../persistent-session-KAHG73SM.js");
11655
+ const { collectDiagnostics } = await import("../persistent-session-T4IY7AJU.js");
11491
11656
  const diagCodeNames = [...agentState.persistentSessionAgents];
11492
11657
  const agentDiagnostics = diagCodeNames.length > 0 ? collectDiagnostics(diagCodeNames, quarantineEntriesFor, claudeMdSizeFor) : void 0;
11493
11658
  let tailscaleHostname;
@@ -11601,8 +11766,9 @@ async function pollCycle() {
11601
11766
  const {
11602
11767
  collectResponsivenessProbes,
11603
11768
  collectPanelessActivityProbes,
11604
- getResponsivenessIntervalMs
11605
- } = await import("../responsiveness-probe-MKUXLX4F.js");
11769
+ getResponsivenessIntervalMs,
11770
+ occupancyQualificationClassifications
11771
+ } = await import("../responsiveness-probe-WYGR4B2F.js");
11606
11772
  const probeIntervalMs = getResponsivenessIntervalMs();
11607
11773
  if (now - lastResponsivenessProbeAt > probeIntervalMs) {
11608
11774
  const probeCodeNames = [...agentState.persistentSessionAgents];
@@ -11617,27 +11783,48 @@ async function pollCycle() {
11617
11783
  });
11618
11784
  const drainedBuckets = /* @__PURE__ */ new Map();
11619
11785
  const drainedCodeNames = /* @__PURE__ */ new Set();
11786
+ const qualifierMode = occupancyQualifierMode();
11620
11787
  const takeBuckets = (codeName) => {
11621
- if (drainedCodeNames.has(codeName)) return [];
11788
+ if (drainedCodeNames.has(codeName)) return { buckets: [], classifications: null };
11622
11789
  drainedCodeNames.add(codeName);
11623
- const buckets = sharedBusyBuckets.drainClosed(codeName, Date.now());
11624
- if (buckets.length > 0) drainedBuckets.set(codeName, buckets);
11625
- return buckets;
11790
+ const nowMs = Date.now();
11791
+ const raw = sharedBusyBuckets.drainClosed(codeName, nowMs);
11792
+ if (raw.length === 0) return { buckets: [], classifications: null };
11793
+ let q;
11794
+ try {
11795
+ q = qualifyBuckets(raw, collectQualifyingTurns(codeName, nowMs), qualifierMode, nowMs);
11796
+ } catch (err) {
11797
+ log(
11798
+ `[occupancy-gate] qualification failed for '${codeName}' \u2014 reporting ${raw.length} bucket(s) ungated: ${err.message}`
11799
+ );
11800
+ q = { kept: raw, qualified: 0, unqualifiedDropped: 0, unreadable: raw.length };
11801
+ }
11802
+ if (q.kept.length > 0) drainedBuckets.set(codeName, q.kept);
11803
+ return {
11804
+ buckets: q.kept,
11805
+ classifications: occupancyQualificationClassifications(q)
11806
+ };
11626
11807
  };
11627
11808
  const probes = [...collectResponsivenessProbes(probeCodeNames), ...paneless].map((p) => {
11628
11809
  const giveUps = takeWatchdogGiveUpCount(p.code_name);
11629
11810
  if (giveUps > 0) drainedGiveUps.set(p.code_name, giveUps);
11630
- const busyBuckets = takeBuckets(p.code_name);
11811
+ const { buckets: busyBuckets, classifications } = takeBuckets(p.code_name);
11631
11812
  return {
11632
11813
  ...p,
11633
11814
  input_stuck_give_ups: giveUps,
11634
- ...busyBuckets.length > 0 ? { busy_buckets: busyBuckets } : {}
11815
+ ...busyBuckets.length > 0 ? { busy_buckets: busyBuckets } : {},
11816
+ ...classifications ? { occupancy_qualification_classifications: classifications } : {}
11635
11817
  };
11636
11818
  });
11637
11819
  for (const codeName of probeCodeNames) {
11638
- const buckets = takeBuckets(codeName);
11639
- if (buckets.length > 0) {
11640
- probes.push({ code_name: codeName, busy_buckets: buckets, input_stuck_give_ups: 0 });
11820
+ const { buckets, classifications } = takeBuckets(codeName);
11821
+ if (buckets.length > 0 || classifications) {
11822
+ probes.push({
11823
+ code_name: codeName,
11824
+ input_stuck_give_ups: 0,
11825
+ ...buckets.length > 0 ? { busy_buckets: buckets } : {},
11826
+ ...classifications ? { occupancy_qualification_classifications: classifications } : {}
11827
+ });
11641
11828
  }
11642
11829
  }
11643
11830
  if (probes.length > 0) {
@@ -11666,7 +11853,7 @@ async function pollCycle() {
11666
11853
  collectResponsivenessProbes,
11667
11854
  livePendingInboundOldestAgeSeconds,
11668
11855
  parkPendingInbound
11669
- } = await import("../responsiveness-probe-MKUXLX4F.js");
11856
+ } = await import("../responsiveness-probe-WYGR4B2F.js");
11670
11857
  const { getProjectDir: wedgeProjectDir } = await import("../scheduler-engine-NDP36U7O.js");
11671
11858
  const wedgeNow = /* @__PURE__ */ new Date();
11672
11859
  const liveAgents = agentState.persistentSessionAgents;
@@ -11758,10 +11945,10 @@ async function pollCycle() {
11758
11945
  const paneTail = readFileSync22(paneLogPath(codeName), "utf8").slice(-65536);
11759
11946
  const transient = detectTransientApiErrorInLog(paneTail);
11760
11947
  if (transient) {
11761
- const wedgeHome = join28(homedir12(), ".augmented", codeName);
11948
+ const wedgeHome = join29(homedir12(), ".augmented", codeName);
11762
11949
  if (existsSync12(wedgeHome)) {
11763
11950
  atomicWriteFileSync(
11764
- join28(wedgeHome, "watchdog-give-up.json"),
11951
+ join29(wedgeHome, "watchdog-give-up.json"),
11765
11952
  JSON.stringify({
11766
11953
  gave_up_at: wedgeNow.toISOString(),
11767
11954
  reason: "transient_overload"
@@ -12032,7 +12219,7 @@ async function pollCycle() {
12032
12219
  const adapter = resolveAgentFramework(prev.codeName);
12033
12220
  stopAgentRuntime2(prev.codeName, "removed-from-host");
12034
12221
  killAgentChannelProcesses(prev.codeName, { log });
12035
- const agentDir = join28(adapter.getAgentDir(prev.codeName), "provision");
12222
+ const agentDir = join29(adapter.getAgentDir(prev.codeName), "provision");
12036
12223
  await cleanupAgentFiles(prev.codeName, agentDir);
12037
12224
  clearAgentCaches(prev.agentId, prev.codeName);
12038
12225
  }
@@ -12119,10 +12306,10 @@ async function pollCycle() {
12119
12306
  // pending-inbound marker. Best-effort: a write failure is logged by
12120
12307
  // the watchdog, never fails the poll cycle.
12121
12308
  signalGiveUp: (codeName) => {
12122
- const dir = join28(homedir12(), ".augmented", codeName);
12309
+ const dir = join29(homedir12(), ".augmented", codeName);
12123
12310
  if (!existsSync12(dir)) return;
12124
12311
  atomicWriteFileSync(
12125
- join28(dir, "watchdog-give-up.json"),
12312
+ join29(dir, "watchdog-give-up.json"),
12126
12313
  JSON.stringify({ gave_up_at: (/* @__PURE__ */ new Date()).toISOString() })
12127
12314
  );
12128
12315
  }
@@ -12207,7 +12394,12 @@ async function getOrCacheRegisteredAgents(adapter, profile) {
12207
12394
  async function processAgent(agent, agentStates) {
12208
12395
  if (!config) return;
12209
12396
  const renderIntegrationsSection = shouldRenderIntegrationsSection();
12210
- syncAccountEnforcementMarker(agent.code_name, agent.enforcement ?? null, log);
12397
+ syncAccountEnforcementMarker(
12398
+ agent.code_name,
12399
+ agent.enforcement ?? null,
12400
+ log,
12401
+ agent.enforcement_text ?? null
12402
+ );
12211
12403
  const previousKnownStatus = agentState.knownStatuses.get(agent.agent_id);
12212
12404
  agentState.agentDisplayNames.set(agent.code_name, agent.display_name);
12213
12405
  agentState.codeNameToAgentId.set(agent.code_name, agent.agent_id);
@@ -12264,7 +12456,7 @@ async function processAgent(agent, agentStates) {
12264
12456
  }
12265
12457
  const now = (/* @__PURE__ */ new Date()).toISOString();
12266
12458
  const adapter = resolveAgentFramework(agent.code_name);
12267
- let agentDir = join28(adapter.getAgentDir(agent.code_name), "provision");
12459
+ let agentDir = join29(adapter.getAgentDir(agent.code_name), "provision");
12268
12460
  if (agent.status === "draft" || agent.status === "paused") {
12269
12461
  if (previousKnownStatus !== agent.status) {
12270
12462
  log(`Agent '${agent.code_name}' is ${agent.status}, skipping provisioning`);
@@ -12438,7 +12630,7 @@ async function processAgent(agent, agentStates) {
12438
12630
  const frameworkId = refreshData.agent.framework ?? DEFAULT_FRAMEWORK;
12439
12631
  agentFrameworkCache.set(agent.code_name, frameworkId);
12440
12632
  const frameworkAdapter = getFramework(frameworkId);
12441
- agentDir = join28(frameworkAdapter.getAgentDir(agent.code_name), "provision");
12633
+ agentDir = join29(frameworkAdapter.getAgentDir(agent.code_name), "provision");
12442
12634
  cacheAgentDeliveryMetadata(agent.code_name, refreshData);
12443
12635
  agentRestartTimezoneInputs.set(agent.code_name, {
12444
12636
  agentTimezone: typeof refreshData.agent.timezone === "string" ? refreshData.agent.timezone : null,
@@ -12487,7 +12679,7 @@ async function processAgent(agent, agentStates) {
12487
12679
  const changedFiles = [];
12488
12680
  mkdirSync10(agentDir, { recursive: true });
12489
12681
  for (const artifact of artifacts) {
12490
- const filePath = join28(agentDir, artifact.relativePath);
12682
+ const filePath = join29(agentDir, artifact.relativePath);
12491
12683
  let existingHash;
12492
12684
  let newHash;
12493
12685
  let writeContent = artifact.content;
@@ -12506,7 +12698,7 @@ async function processAgent(agent, agentStates) {
12506
12698
  };
12507
12699
  newHash = sha256(stripDynamicSections(artifact.content));
12508
12700
  try {
12509
- const projectClaudeMd = join28(config.configDir, agent.code_name, "project", "CLAUDE.md");
12701
+ const projectClaudeMd = join29(config.configDir, agent.code_name, "project", "CLAUDE.md");
12510
12702
  const existing = readFileSync22(projectClaudeMd, "utf-8");
12511
12703
  existingHash = sha256(stripDynamicSections(existing));
12512
12704
  } catch {
@@ -12557,12 +12749,12 @@ async function processAgent(agent, agentStates) {
12557
12749
  }
12558
12750
  }
12559
12751
  if (changedFiles.length > 0) {
12560
- const isFirst = !existsSync12(join28(agentDir, "CHARTER.md"));
12752
+ const isFirst = !existsSync12(join29(agentDir, "CHARTER.md"));
12561
12753
  const verb = isFirst ? "Provisioning" : "Updating";
12562
12754
  const fileNames = changedFiles.map((f) => f.relativePath).join(", ");
12563
12755
  log(`${verb} '${agent.code_name}': ${fileNames}`);
12564
12756
  for (const file of changedFiles) {
12565
- const filePath = join28(agentDir, file.relativePath);
12757
+ const filePath = join29(agentDir, file.relativePath);
12566
12758
  mkdirSync10(dirname8(filePath), { recursive: true });
12567
12759
  if (file.relativePath === ".mcp.json") {
12568
12760
  safeWriteJsonAtomic(filePath, file.content, { mode: 384 });
@@ -12571,12 +12763,12 @@ async function processAgent(agent, agentStates) {
12571
12763
  }
12572
12764
  }
12573
12765
  try {
12574
- const provSkillsDir = join28(agentDir, ".claude", "skills");
12766
+ const provSkillsDir = join29(agentDir, ".claude", "skills");
12575
12767
  if (existsSync12(provSkillsDir)) {
12576
- for (const folder of readdirSync7(provSkillsDir)) {
12768
+ for (const folder of readdirSync8(provSkillsDir)) {
12577
12769
  if (folder.startsWith("knowledge-")) {
12578
12770
  try {
12579
- rmSync5(join28(provSkillsDir, folder), { recursive: true });
12771
+ rmSync5(join29(provSkillsDir, folder), { recursive: true });
12580
12772
  } catch {
12581
12773
  }
12582
12774
  }
@@ -12589,7 +12781,7 @@ async function processAgent(agent, agentStates) {
12589
12781
  const trackedFiles2 = frameworkAdapter.driftTrackedFiles();
12590
12782
  const hashes = /* @__PURE__ */ new Map();
12591
12783
  for (const file of trackedFiles2) {
12592
- const h = hashFile(join28(agentDir, file));
12784
+ const h = hashFile(join29(agentDir, file));
12593
12785
  if (h) hashes.set(file, h);
12594
12786
  }
12595
12787
  agentState.writtenHashes.set(agent.agent_id, hashes);
@@ -12607,14 +12799,14 @@ async function processAgent(agent, agentStates) {
12607
12799
  }
12608
12800
  if (Array.isArray(refreshData.workflows)) {
12609
12801
  try {
12610
- const provWorkflowsDir = join28(agentDir, ".claude", "workflows");
12802
+ const provWorkflowsDir = join29(agentDir, ".claude", "workflows");
12611
12803
  if (existsSync12(provWorkflowsDir)) {
12612
12804
  const expected = new Set(refreshData.workflows.map((w) => `${w.name}.js`));
12613
- for (const file of readdirSync7(provWorkflowsDir)) {
12805
+ for (const file of readdirSync8(provWorkflowsDir)) {
12614
12806
  if (!file.endsWith(".js")) continue;
12615
12807
  if (expected.has(file)) continue;
12616
12808
  try {
12617
- rmSync5(join28(provWorkflowsDir, file));
12809
+ rmSync5(join29(provWorkflowsDir, file));
12618
12810
  } catch {
12619
12811
  }
12620
12812
  }
@@ -12696,7 +12888,7 @@ async function processAgent(agent, agentStates) {
12696
12888
  if (written && existsSync12(agentDir)) {
12697
12889
  const driftedFiles = [];
12698
12890
  for (const [file, expectedHash] of written) {
12699
- const localHash = hashFile(join28(agentDir, file));
12891
+ const localHash = hashFile(join29(agentDir, file));
12700
12892
  if (localHash && localHash !== expectedHash) {
12701
12893
  driftedFiles.push(file);
12702
12894
  }
@@ -12707,7 +12899,7 @@ async function processAgent(agent, agentStates) {
12707
12899
  try {
12708
12900
  const localHashes = {};
12709
12901
  for (const file of driftedFiles) {
12710
- localHashes[file] = hashFile(join28(agentDir, file));
12902
+ localHashes[file] = hashFile(join29(agentDir, file));
12711
12903
  }
12712
12904
  await api.post("/host/drift", {
12713
12905
  agent_id: agent.agent_id,
@@ -12909,7 +13101,7 @@ async function processAgent(agent, agentStates) {
12909
13101
  const addedChannels = [...restartDecision.added];
12910
13102
  const writeDmNoticeMarkers = isChannelAddRestart ? () => {
12911
13103
  try {
12912
- const agentAugmentedDir = join28(homedir12(), ".augmented", agent.code_name);
13104
+ const agentAugmentedDir = join29(homedir12(), ".augmented", agent.code_name);
12913
13105
  mkdirSync10(agentAugmentedDir, { recursive: true });
12914
13106
  const markerJson = JSON.stringify({
12915
13107
  version: 1,
@@ -12917,7 +13109,7 @@ async function processAgent(agent, agentStates) {
12917
13109
  added: addedChannels
12918
13110
  });
12919
13111
  for (const file of ["slack-channel-add-restart.json", "telegram-channel-add-restart.json"]) {
12920
- atomicWriteFileSync(join28(agentAugmentedDir, file), markerJson);
13112
+ atomicWriteFileSync(join29(agentAugmentedDir, file), markerJson);
12921
13113
  }
12922
13114
  } catch (err) {
12923
13115
  log(`[hot-reload] channel-add DM-notice marker write failed for '${agent.code_name}' (non-fatal): ${err.message}`);
@@ -13106,18 +13298,18 @@ async function processAgent(agent, agentStates) {
13106
13298
  if (agentSessionMode === "persistent" && (agentFrameworkCache.get(agent.code_name) ?? DEFAULT_FRAMEWORK) === "claude-code") {
13107
13299
  try {
13108
13300
  const agentProvisionDir = agentDir;
13109
- const projectDir = join28(homedir12(), ".augmented", agent.code_name, "project");
13301
+ const projectDir = join29(homedir12(), ".augmented", agent.code_name, "project");
13110
13302
  mkdirSync10(agentProvisionDir, { recursive: true });
13111
13303
  mkdirSync10(projectDir, { recursive: true });
13112
- const provisionMcpPath = join28(agentProvisionDir, ".mcp.json");
13113
- const projectMcpPath = join28(projectDir, ".mcp.json");
13304
+ const provisionMcpPath = join29(agentProvisionDir, ".mcp.json");
13305
+ const projectMcpPath = join29(projectDir, ".mcp.json");
13114
13306
  let mcpConfig = { mcpServers: {} };
13115
13307
  try {
13116
13308
  mcpConfig = JSON.parse(readFileSync22(provisionMcpPath, "utf-8"));
13117
13309
  if (!mcpConfig.mcpServers) mcpConfig.mcpServers = {};
13118
13310
  } catch {
13119
13311
  }
13120
- const localDirectChatChannel = join28(homedir12(), ".augmented", "_mcp", "direct-chat-channel.js");
13312
+ const localDirectChatChannel = join29(homedir12(), ".augmented", "_mcp", "direct-chat-channel.js");
13121
13313
  const directChatTeamSettings = refreshData.team?.settings;
13122
13314
  const directChatTz = (() => {
13123
13315
  const tz = directChatTeamSettings?.["timezone"];
@@ -13143,7 +13335,7 @@ async function processAgent(agent, agentStates) {
13143
13335
  // ~/.augmented/<codeName>/.current-turn-initiator.json. Note getAgentDir
13144
13336
  // returns the agent root (NOT the /provision subdir `agentDir` points at),
13145
13337
  // so it byte-matches the broker readers' path.
13146
- AGT_TURN_INITIATOR_FILE: join28(
13338
+ AGT_TURN_INITIATOR_FILE: join29(
13147
13339
  frameworkAdapter.getAgentDir(agent.code_name),
13148
13340
  ".current-turn-initiator.json"
13149
13341
  )
@@ -13163,7 +13355,7 @@ async function processAgent(agent, agentStates) {
13163
13355
  log(`Channel credentials written for '${agent.code_name}/direct-chat'`);
13164
13356
  }
13165
13357
  }
13166
- const staleChannelsPath = join28(projectDir, ".mcp-channels.json");
13358
+ const staleChannelsPath = join29(projectDir, ".mcp-channels.json");
13167
13359
  if (existsSync12(staleChannelsPath)) {
13168
13360
  try {
13169
13361
  rmSync5(staleChannelsPath, { force: true });
@@ -13253,7 +13445,7 @@ async function processAgent(agent, agentStates) {
13253
13445
  }
13254
13446
  if (hostFlagStore().getBoolean("connectivity-probe")) {
13255
13447
  try {
13256
- const probeProjectDir = join28(homedir12(), ".augmented", agent.code_name, "project");
13448
+ const probeProjectDir = join29(homedir12(), ".augmented", agent.code_name, "project");
13257
13449
  let probeSet = integrations;
13258
13450
  try {
13259
13451
  const quarantined = await api.post("/host/agent-integrations/quarantined", { agent_id: agent.agent_id });
@@ -13299,7 +13491,7 @@ async function processAgent(agent, agentStates) {
13299
13491
  const forceDue = attemptsLeft > 0;
13300
13492
  let probeRan = false;
13301
13493
  try {
13302
- const probeProjectDir = join28(homedir12(), ".augmented", agent.code_name, "project");
13494
+ const probeProjectDir = join29(homedir12(), ".augmented", agent.code_name, "project");
13303
13495
  probeRan = await runAgentSessionToolBindProbes(agent, integrations, probeProjectDir, { forceDue });
13304
13496
  } catch (err) {
13305
13497
  log(`Session-tool-bind probe failed for '${agent.code_name}': ${err.message}`);
@@ -13376,8 +13568,8 @@ async function processAgent(agent, agentStates) {
13376
13568
  const intHash = computeIntegrationsHash(integrations);
13377
13569
  const prevIntHash = agentState.knownIntegrationHashes.get(agent.agent_id);
13378
13570
  if (intHash !== prevIntHash) {
13379
- const projectDir = join28(homedir12(), ".augmented", agent.code_name, "project");
13380
- const envIntPath = join28(projectDir, ".env.integrations");
13571
+ const projectDir = join29(homedir12(), ".augmented", agent.code_name, "project");
13572
+ const envIntPath = join29(projectDir, ".env.integrations");
13381
13573
  let preWriteEnv;
13382
13574
  try {
13383
13575
  preWriteEnv = readFileSync22(envIntPath, "utf-8");
@@ -13399,7 +13591,7 @@ async function processAgent(agent, agentStates) {
13399
13591
  }
13400
13592
  if (fw === "claude-code" && isSessionHealthy(agent.code_name)) {
13401
13593
  try {
13402
- const projectMcpPath = join28(projectDir, ".mcp.json");
13594
+ const projectMcpPath = join29(projectDir, ".mcp.json");
13403
13595
  const postWriteEnv = readFileSync22(envIntPath, "utf-8");
13404
13596
  const mcpContent = readFileSync22(projectMcpPath, "utf-8");
13405
13597
  const changedVars = diffEnvIntegrations(preWriteEnv, postWriteEnv);
@@ -13664,23 +13856,23 @@ async function processAgent(agent, agentStates) {
13664
13856
  }
13665
13857
  }
13666
13858
  try {
13667
- const { readdirSync: readdirSync8, rmSync: rmSync6 } = await import("fs");
13859
+ const { readdirSync: readdirSync9, rmSync: rmSync6 } = await import("fs");
13668
13860
  const { homedir: homedir13 } = await import("os");
13669
13861
  const frameworkId2 = frameworkAdapter.id;
13670
13862
  const candidateSkillDirs = [
13671
13863
  // Claude Code — framework runtime tree
13672
- join28(homedir13(), ".augmented", agent.code_name, "skills"),
13864
+ join29(homedir13(), ".augmented", agent.code_name, "skills"),
13673
13865
  // Claude Code — project tree
13674
- join28(homedir13(), ".augmented", agent.code_name, "project", ".claude", "skills"),
13866
+ join29(homedir13(), ".augmented", agent.code_name, "project", ".claude", "skills"),
13675
13867
  // Defensive: legacy provision-side path, not currently an
13676
13868
  // install target but cheap to sweep.
13677
- join28(agentDir, ".claude", "skills")
13869
+ join29(agentDir, ".claude", "skills")
13678
13870
  ];
13679
13871
  const existingDirs = candidateSkillDirs.filter((d) => existsSync12(d));
13680
13872
  const discoveredEntries = /* @__PURE__ */ new Set();
13681
13873
  for (const dir of existingDirs) {
13682
13874
  try {
13683
- for (const entry of readdirSync8(dir)) {
13875
+ for (const entry of readdirSync9(dir)) {
13684
13876
  if (entry.startsWith("plugin-") || entry.startsWith("integration-")) {
13685
13877
  discoveredEntries.add(entry);
13686
13878
  }
@@ -13715,7 +13907,7 @@ async function processAgent(agent, agentStates) {
13715
13907
  const sharedSkillsPayload = refreshAny.shared_skills;
13716
13908
  const desiredResolved = globalSkillsPayload !== void 0 || sharedSkillsPayload !== void 0;
13717
13909
  const manifestPath = managedSkillManifestPath(
13718
- join28(homedir12(), ".augmented", agent.code_name)
13910
+ join29(homedir12(), ".augmented", agent.code_name)
13719
13911
  );
13720
13912
  const prevIds = /* @__PURE__ */ new Set([
13721
13913
  ...agentState.knownGlobalSkillIds.get(agent.agent_id) ?? /* @__PURE__ */ new Set(),
@@ -13735,15 +13927,15 @@ async function processAgent(agent, agentStates) {
13735
13927
  }
13736
13928
  if (plan.removes.length) {
13737
13929
  const globalSkillDirs = [
13738
- join28(homedir12(), ".augmented", agent.code_name, "skills"),
13739
- join28(homedir12(), ".augmented", agent.code_name, "project", ".claude", "skills"),
13740
- join28(agentDir, ".claude", "skills")
13930
+ join29(homedir12(), ".augmented", agent.code_name, "skills"),
13931
+ join29(homedir12(), ".augmented", agent.code_name, "project", ".claude", "skills"),
13932
+ join29(agentDir, ".claude", "skills")
13741
13933
  ];
13742
13934
  for (const id of plan.removes) {
13743
13935
  let prunedAny = false;
13744
13936
  for (const dir of globalSkillDirs) {
13745
- const p = join28(dir, id);
13746
- if (existsSync12(p) && existsSync12(join28(p, "SKILL.md"))) {
13937
+ const p = join29(dir, id);
13938
+ if (existsSync12(p) && existsSync12(join29(p, "SKILL.md"))) {
13747
13939
  rmSync5(p, { recursive: true, force: true });
13748
13940
  prunedAny = true;
13749
13941
  }
@@ -13974,7 +14166,7 @@ async function processAgent(agent, agentStates) {
13974
14166
  const sess = getSessionState(agent.code_name);
13975
14167
  let mcpJsonParsed = null;
13976
14168
  try {
13977
- const mcpPath = join28(getProjectDir(agent.code_name), ".mcp.json");
14169
+ const mcpPath = join29(getProjectDir(agent.code_name), ".mcp.json");
13978
14170
  mcpJsonParsed = JSON.parse(readFileSync22(mcpPath, "utf-8"));
13979
14171
  } catch {
13980
14172
  }
@@ -14401,7 +14593,7 @@ Retried to the limit after repeated stalls \u2014 needs a look.`).catch(() => {
14401
14593
  if (trackedFiles.length > 0 && existsSync12(agentDir)) {
14402
14594
  const hashes = /* @__PURE__ */ new Map();
14403
14595
  for (const file of trackedFiles) {
14404
- const h = hashFile(join28(agentDir, file));
14596
+ const h = hashFile(join29(agentDir, file));
14405
14597
  if (h) hashes.set(file, h);
14406
14598
  }
14407
14599
  agentState.writtenHashes.set(agent.agent_id, hashes);
@@ -14416,7 +14608,7 @@ Retried to the limit after repeated stalls \u2014 needs a look.`).catch(() => {
14416
14608
  refreshData.agent.onboarding_state
14417
14609
  );
14418
14610
  const obStep = obState.step;
14419
- const markerPath = join28(homedir12(), ".augmented", agent.code_name, "onboarding-drive.json");
14611
+ const markerPath = join29(homedir12(), ".augmented", agent.code_name, "onboarding-drive.json");
14420
14612
  const marker = readOnboardingDriveMarker(markerPath);
14421
14613
  const decision = decideOnboardingDrive(obStep, marker, Date.now(), obState.generation ?? 0);
14422
14614
  if (decision.clearMarker) {
@@ -14504,7 +14696,7 @@ async function ensureOpencodeRuntime(agent, refreshData, agentTimezone) {
14504
14696
  }
14505
14697
  stopOpencodeSlackIngest(codeName, log);
14506
14698
  stopOpencodeTelegramIngest(codeName, log);
14507
- const opencodeProjectDir = join28(getFramework("opencode").getAgentDir(codeName), "provision");
14699
+ const opencodeProjectDir = join29(getFramework("opencode").getAgentDir(codeName), "provision");
14508
14700
  const serveEnv = {
14509
14701
  AGT_HOST: requireHost(),
14510
14702
  AGT_API_KEY: getApiKey() ?? void 0,
@@ -14554,8 +14746,8 @@ async function ensurePersistentSession(agent, tasks, boardItems, refreshData) {
14554
14746
  });
14555
14747
  }
14556
14748
  const projectDir = getProjectDir(codeName);
14557
- const mcpConfigPath = join28(projectDir, ".mcp.json");
14558
- const claudeMdPath = join28(projectDir, "CLAUDE.md");
14749
+ const mcpConfigPath = join29(projectDir, ".mcp.json");
14750
+ const claudeMdPath = join29(projectDir, "CLAUDE.md");
14559
14751
  if (restartBreaker.isTripped(codeName)) {
14560
14752
  const trip = restartBreaker.getTrip(codeName);
14561
14753
  return {
@@ -15186,7 +15378,7 @@ async function handleRestartDoorbell(agentId, requestedAt, restartReason) {
15186
15378
  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}`));
15187
15379
  void (async () => {
15188
15380
  try {
15189
- const { collectDiagnostics } = await import("../persistent-session-KAHG73SM.js");
15381
+ const { collectDiagnostics } = await import("../persistent-session-T4IY7AJU.js");
15190
15382
  await api.post("/host/heartbeat", {
15191
15383
  host_id: hostId,
15192
15384
  agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor)
@@ -15236,7 +15428,7 @@ async function respawnAgentAfterMcpStop(codeName, reason) {
15236
15428
  }
15237
15429
  try {
15238
15430
  const hostId = await getHostId();
15239
- const { collectDiagnostics } = await import("../persistent-session-KAHG73SM.js");
15431
+ const { collectDiagnostics } = await import("../persistent-session-T4IY7AJU.js");
15240
15432
  await api.post("/host/heartbeat", {
15241
15433
  host_id: hostId,
15242
15434
  agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor)
@@ -15760,7 +15952,7 @@ async function processClaudePairSessions(agents) {
15760
15952
  killPairSession,
15761
15953
  pairTmuxSession,
15762
15954
  finalizeClaudePairOnboarding
15763
- } = await import("../claude-pair-runtime-KQOPJSUJ.js");
15955
+ } = await import("../claude-pair-runtime-TC2TTMIJ.js");
15764
15956
  for (const pairId of pendingResp.cancelled_pair_ids ?? []) {
15765
15957
  log(`[claude-pair] sweeping orphan tmux session for pair ${pairId.slice(0, 8)}`);
15766
15958
  const killed = await killPairSession(pairTmuxSession(pairId));
@@ -16014,8 +16206,8 @@ function parseMemoryFile(raw, fallbackName) {
16014
16206
  };
16015
16207
  }
16016
16208
  async function syncMemories(agent, configDir, log2) {
16017
- const projectDir = join28(configDir, agent.code_name, "project");
16018
- const memoryDir = join28(projectDir, "memory");
16209
+ const projectDir = join29(configDir, agent.code_name, "project");
16210
+ const memoryDir = join29(projectDir, "memory");
16019
16211
  const isFreshSync = pendingFreshMemorySync.has(agent.agent_id);
16020
16212
  if (isFreshSync) {
16021
16213
  log2(`[memory-sync] Fresh-sync requested for '${agent.code_name}' \u2014 pulling DB first`);
@@ -16030,10 +16222,10 @@ async function syncMemories(agent, configDir, log2) {
16030
16222
  const prevHashes = memoryFileHashes.get(agent.agent_id) ?? /* @__PURE__ */ new Map();
16031
16223
  const currentHashes = /* @__PURE__ */ new Map();
16032
16224
  const changedMemories = [];
16033
- for (const file of readdirSync7(memoryDir)) {
16225
+ for (const file of readdirSync8(memoryDir)) {
16034
16226
  if (!file.endsWith(".md")) continue;
16035
16227
  try {
16036
- const raw = readFileSync22(join28(memoryDir, file), "utf-8");
16228
+ const raw = readFileSync22(join29(memoryDir, file), "utf-8");
16037
16229
  const fileHash = createHash16("sha256").update(raw).digest("hex").slice(0, 16);
16038
16230
  currentHashes.set(file, fileHash);
16039
16231
  if (prevHashes.get(file) === fileHash) continue;
@@ -16058,7 +16250,7 @@ async function syncMemories(agent, configDir, log2) {
16058
16250
  } catch (err) {
16059
16251
  for (const mem of changedMemories) {
16060
16252
  for (const [file] of currentHashes) {
16061
- const parsed = parseMemoryFile(readFileSync22(join28(memoryDir, file), "utf-8"), file.replace(/\.md$/, ""));
16253
+ const parsed = parseMemoryFile(readFileSync22(join29(memoryDir, file), "utf-8"), file.replace(/\.md$/, ""));
16062
16254
  if (parsed?.name === mem.name) currentHashes.delete(file);
16063
16255
  }
16064
16256
  }
@@ -16071,7 +16263,7 @@ async function syncMemories(agent, configDir, log2) {
16071
16263
  }
16072
16264
  }
16073
16265
  async function downloadMemories(agent, memoryDir, log2, { force }) {
16074
- const localFiles = existsSync12(memoryDir) ? readdirSync7(memoryDir).filter((f) => f.endsWith(".md")).sort() : [];
16266
+ const localFiles = existsSync12(memoryDir) ? readdirSync8(memoryDir).filter((f) => f.endsWith(".md")).sort() : [];
16075
16267
  const localListHash = createHash16("sha256").update(localFiles.join(",")).digest("hex").slice(0, 16);
16076
16268
  const prevLocalHash = lastLocalFileHash.get(agent.agent_id);
16077
16269
  const prevDownload = lastDownloadHash.get(agent.agent_id);
@@ -16093,7 +16285,7 @@ async function downloadMemories(agent, memoryDir, log2, { force }) {
16093
16285
  const mem = dbMemories.memories[i];
16094
16286
  const rawSlug = mem.name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)/g, "").slice(0, 60);
16095
16287
  const slug = rawSlug || `memory-${i}`;
16096
- const filePath = join28(memoryDir, `${slug}.md`);
16288
+ const filePath = join29(memoryDir, `${slug}.md`);
16097
16289
  const desired = `---
16098
16290
  name: ${JSON.stringify(mem.name)}
16099
16291
  type: ${mem.type}
@@ -16117,7 +16309,7 @@ ${mem.content}
16117
16309
  }
16118
16310
  }
16119
16311
  if (written > 0 || overwritten > 0) {
16120
- const updatedFiles = readdirSync7(memoryDir).filter((f) => f.endsWith(".md")).sort();
16312
+ const updatedFiles = readdirSync8(memoryDir).filter((f) => f.endsWith(".md")).sort();
16121
16313
  lastLocalFileHash.set(agent.agent_id, createHash16("sha256").update(updatedFiles.join(",")).digest("hex").slice(0, 16));
16122
16314
  log2(`Memory download for '${agent.code_name}': wrote ${written} new, overwrote ${overwritten} stale`);
16123
16315
  }
@@ -16396,7 +16588,7 @@ function startManager(opts) {
16396
16588
  log(`[startup] state rehydration failed (continuing with empty state): ${err.message}`);
16397
16589
  }
16398
16590
  log(
16399
- `[startup] worker pid=${process.pid} ppid=${process.ppid} node=${process.version} log=${join28(homedir12(), ".augmented", "manager.log")}`
16591
+ `[startup] worker pid=${process.pid} ppid=${process.ppid} node=${process.version} log=${join29(homedir12(), ".augmented", "manager.log")}`
16400
16592
  );
16401
16593
  deployMcpAssets();
16402
16594
  reapOrphanChannelMcps({ log });
@@ -16522,14 +16714,14 @@ function restartRunningChannelMcps(basenames) {
16522
16714
  }
16523
16715
  }
16524
16716
  function deployMcpAssets() {
16525
- const targetDir = join28(homedir12(), ".augmented", "_mcp");
16717
+ const targetDir = join29(homedir12(), ".augmented", "_mcp");
16526
16718
  mkdirSync10(targetDir, { recursive: true });
16527
16719
  const moduleDir = dirname8(fileURLToPath(import.meta.url));
16528
16720
  let mcpSourceDir = "";
16529
16721
  let dir = moduleDir;
16530
16722
  for (let i = 0; i < 6; i++) {
16531
- const candidate = join28(dir, "dist", "mcp");
16532
- if (existsSync12(join28(candidate, "index.js"))) {
16723
+ const candidate = join29(dir, "dist", "mcp");
16724
+ if (existsSync12(join29(candidate, "index.js"))) {
16533
16725
  mcpSourceDir = candidate;
16534
16726
  break;
16535
16727
  }
@@ -16585,6 +16777,13 @@ function deployMcpAssets() {
16585
16777
  // RESTARTABLE_CHANNEL_FILES; the reaper (re)starts it with the session and a
16586
16778
  // bundle update applies on the next natural session restart.
16587
16779
  "augmented-support.js",
16780
+ // ENG-8332: the help-knowledge-base broker, split out of augmented-support
16781
+ // so the docs can be granted without its ticket-filing and org-state
16782
+ // surface. Bundled with the CLI (never published to npm). Same treatment as
16783
+ // augmented-support - NOT a channel, so not in RESTARTABLE_CHANNEL_FILES;
16784
+ // the reaper (re)starts it with the session and a bundle update applies on
16785
+ // the next natural session restart.
16786
+ "augmented-help-kb.js",
16588
16787
  // ENG-6859: the remote OAuth MCP proxy (brand-ninja, granola). NOT in
16589
16788
  // RESTARTABLE_CHANNEL_FILES - it's not a channel; a bundle update applies on
16590
16789
  // the next natural session restart. It re-reads the token from the secrets
@@ -16609,8 +16808,8 @@ function deployMcpAssets() {
16609
16808
  // needs restarting to pick up a token rotation.
16610
16809
  "xero.js"
16611
16810
  ]) {
16612
- const src = join28(mcpSourceDir, file);
16613
- const dst = join28(targetDir, file);
16811
+ const src = join29(mcpSourceDir, file);
16812
+ const dst = join29(targetDir, file);
16614
16813
  if (!existsSync12(src)) continue;
16615
16814
  const before = fileHash(dst);
16616
16815
  try {
@@ -16628,14 +16827,14 @@ function deployMcpAssets() {
16628
16827
  log(`[manager] Bundle(s) updated: ${changedBasenames.join(", ")} \u2014 signalling running instances to restart`);
16629
16828
  restartRunningChannelMcps(changedBasenames);
16630
16829
  }
16631
- const localMcpPath = join28(targetDir, "index.js");
16830
+ const localMcpPath = join29(targetDir, "index.js");
16632
16831
  try {
16633
- const agentsDir = join28(homedir12(), ".augmented", "agents");
16832
+ const agentsDir = join29(homedir12(), ".augmented", "agents");
16634
16833
  if (existsSync12(agentsDir)) {
16635
- for (const entry of readdirSync7(agentsDir, { withFileTypes: true })) {
16834
+ for (const entry of readdirSync8(agentsDir, { withFileTypes: true })) {
16636
16835
  if (!entry.isDirectory()) continue;
16637
16836
  for (const subdir of ["provision", "project"]) {
16638
- const mcpJsonPath = join28(agentsDir, entry.name, subdir, ".mcp.json");
16837
+ const mcpJsonPath = join29(agentsDir, entry.name, subdir, ".mcp.json");
16639
16838
  try {
16640
16839
  const raw = readFileSync22(mcpJsonPath, "utf-8");
16641
16840
  if (!raw.includes("@integrity-labs/augmented-mcp")) continue;