@integrity-labs/agt-cli 0.28.425 → 0.28.427

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.
@@ -25,7 +25,7 @@ import {
25
25
  resolveConnectivityProbe,
26
26
  worseConnectivityOutcome,
27
27
  wrapScheduledTaskPrompt
28
- } from "./chunk-PR3IJAMV.js";
28
+ } from "./chunk-NSG3PTR6.js";
29
29
  import {
30
30
  parsePsRows
31
31
  } from "./chunk-XWVM4KPK.js";
@@ -6027,7 +6027,7 @@ function requireHost() {
6027
6027
  }
6028
6028
 
6029
6029
  // src/lib/api-client.ts
6030
- var agtCliVersion = true ? "0.28.425" : "dev";
6030
+ var agtCliVersion = true ? "0.28.427" : "dev";
6031
6031
  var lastConfigHash = null;
6032
6032
  function setConfigHash(hash) {
6033
6033
  lastConfigHash = hash && hash.length > 0 ? hash : null;
@@ -8531,4 +8531,4 @@ export {
8531
8531
  managerInstallSystemUnitCommand,
8532
8532
  managerUninstallSystemUnitCommand
8533
8533
  };
8534
- //# sourceMappingURL=chunk-M3L6HOYG.js.map
8534
+ //# sourceMappingURL=chunk-QXEUCIOC.js.map
@@ -100,7 +100,7 @@ async function spawnPairSession(session) {
100
100
  return { ok: true };
101
101
  } catch {
102
102
  }
103
- const { resolveClaudeBinary } = await import("./persistent-session-37WNPBRA.js");
103
+ const { resolveClaudeBinary } = await import("./persistent-session-2ZXAKOO4.js");
104
104
  const claudeBin = resolveClaudeBinary();
105
105
  const pairEnv = {
106
106
  ...process.env,
@@ -373,4 +373,4 @@ export {
373
373
  startClaudePair,
374
374
  submitClaudePairCode
375
375
  };
376
- //# sourceMappingURL=claude-pair-runtime-XN4JLRAB.js.map
376
+ //# sourceMappingURL=claude-pair-runtime-ITWM6RWY.js.map
@@ -45,7 +45,7 @@ import {
45
45
  resolveEffectivePinRaw,
46
46
  safeWriteJsonAtomic,
47
47
  setConfigHash
48
- } from "../chunk-M3L6HOYG.js";
48
+ } from "../chunk-QXEUCIOC.js";
49
49
  import {
50
50
  getProjectDir as getProjectDir2,
51
51
  getReadyTasks,
@@ -138,6 +138,7 @@ import {
138
138
  serializeUsageLimitMarker,
139
139
  sessionTranscriptDir,
140
140
  sha256,
141
+ sharedBusyBuckets,
141
142
  startOpencodeSession,
142
143
  startPersistentSession,
143
144
  stopAllSessionsAndWait,
@@ -150,14 +151,14 @@ import {
150
151
  toOpencodeModel,
151
152
  transcriptActivityAgeSeconds,
152
153
  writeEgressAllowlist
153
- } from "../chunk-PR3IJAMV.js";
154
+ } from "../chunk-NSG3PTR6.js";
154
155
  import {
155
156
  reapOrphanChannelMcps
156
157
  } from "../chunk-XWVM4KPK.js";
157
158
 
158
159
  // src/lib/manager-worker.ts
159
160
  import { createHash as createHash15 } from "crypto";
160
- import { readFileSync as readFileSync19, writeFileSync as writeFileSync12, mkdirSync as mkdirSync10, existsSync as existsSync11, rmSync as rmSync5, readdirSync as readdirSync6, statSync as statSync4, copyFileSync } from "fs";
161
+ import { readFileSync as readFileSync19, writeFileSync as writeFileSync12, mkdirSync as mkdirSync10, existsSync as existsSync11, rmSync as rmSync5, readdirSync as readdirSync6, statSync as statSync5, copyFileSync } from "fs";
161
162
  import { execFileSync as syncExecFile } from "child_process";
162
163
  import { join as join22, dirname as dirname7, delimiter as pathDelimiter } from "path";
163
164
  import { homedir as homedir10 } from "os";
@@ -5707,6 +5708,59 @@ async function syncAndCheckClaudeScheduler(agent, tasks, boardItems, refreshData
5707
5708
  }
5708
5709
  }
5709
5710
 
5711
+ // src/lib/pane-occupancy-sampler.ts
5712
+ import { statSync as statSync4 } from "fs";
5713
+ var SAMPLE_INTERVAL_MS = 1e4;
5714
+ var IDLE_GAP_MS = 12e4;
5715
+ var POST_IDLE_CREDIT_MS = 6e4;
5716
+ var lastMtimeMs = /* @__PURE__ */ new Map();
5717
+ function paneMtimeMs(codeName) {
5718
+ try {
5719
+ return statSync4(paneLogPath(codeName)).mtimeMs;
5720
+ } catch {
5721
+ return null;
5722
+ }
5723
+ }
5724
+ function samplePaneOccupancyOnce(codeNames, opts = {}) {
5725
+ const ledger = opts.ledger ?? sharedBusyBuckets;
5726
+ const readMtime = opts.readMtime ?? paneMtimeMs;
5727
+ const seen = /* @__PURE__ */ new Set();
5728
+ for (const codeName of codeNames) {
5729
+ seen.add(codeName);
5730
+ const mtime = readMtime(codeName);
5731
+ if (mtime == null) continue;
5732
+ const prev = lastMtimeMs.get(codeName);
5733
+ lastMtimeMs.set(codeName, mtime);
5734
+ if (prev == null) continue;
5735
+ if (mtime <= prev) continue;
5736
+ const gap = mtime - prev;
5737
+ if (gap <= IDLE_GAP_MS) {
5738
+ ledger.accrueSpan(codeName, prev, mtime);
5739
+ } else {
5740
+ ledger.accrueSpan(codeName, mtime - POST_IDLE_CREDIT_MS, mtime);
5741
+ }
5742
+ }
5743
+ for (const codeName of [...lastMtimeMs.keys()]) {
5744
+ if (!seen.has(codeName)) lastMtimeMs.delete(codeName);
5745
+ }
5746
+ }
5747
+ var timer = null;
5748
+ function startPaneOccupancySampler(liveAgents) {
5749
+ if (timer) return;
5750
+ timer = setInterval(() => {
5751
+ try {
5752
+ samplePaneOccupancyOnce(liveAgents());
5753
+ } catch {
5754
+ }
5755
+ }, SAMPLE_INTERVAL_MS);
5756
+ timer.unref?.();
5757
+ }
5758
+ function stopPaneOccupancySampler() {
5759
+ if (!timer) return;
5760
+ clearInterval(timer);
5761
+ timer = null;
5762
+ }
5763
+
5710
5764
  // src/lib/opencode-slack-ingest.ts
5711
5765
  import { createHash as createHash12 } from "crypto";
5712
5766
 
@@ -8803,7 +8857,7 @@ function scheduleSessionRestart(codeName, delayMs, reason, breakerReason = "hot-
8803
8857
  clearTimeout(existing.timer);
8804
8858
  log(`[hot-reload] Coalesced restart for '${codeName}': replacing pending timer with ${reason}`);
8805
8859
  }
8806
- const timer = setTimeout(() => {
8860
+ const timer2 = setTimeout(() => {
8807
8861
  pendingSessionRestarts.delete(codeName);
8808
8862
  const gate = restartGateFor(codeName, breakerReason);
8809
8863
  if (gate !== "bypass" && gate !== "proceed") {
@@ -8869,8 +8923,8 @@ function scheduleSessionRestart(codeName, delayMs, reason, breakerReason = "hot-
8869
8923
  void respawnAgentAfterMcpStop(codeName, reason);
8870
8924
  }
8871
8925
  }, delayMs);
8872
- timer.unref?.();
8873
- pendingSessionRestarts.set(codeName, { timer, reason, breakerReason, beforeStop });
8926
+ timer2.unref?.();
8927
+ pendingSessionRestarts.set(codeName, { timer: timer2, reason, breakerReason, beforeStop });
8874
8928
  }
8875
8929
  function cancelPendingSessionRestart(codeName) {
8876
8930
  pendingRestartVerifications.delete(codeName);
@@ -8982,7 +9036,7 @@ function inboundAgeSecondsFor(codeName) {
8982
9036
  }
8983
9037
  function paneLogAgeSecondsFor(codeName) {
8984
9038
  try {
8985
- const mtimeMs = statSync4(paneLogPath(codeName)).mtimeMs;
9039
+ const mtimeMs = statSync5(paneLogPath(codeName)).mtimeMs;
8986
9040
  return Math.max(0, Math.floor((Date.now() - mtimeMs) / 1e3));
8987
9041
  } catch (err) {
8988
9042
  if (err?.code === "ENOENT") return null;
@@ -9447,6 +9501,7 @@ function resolveAgentFramework(codeName) {
9447
9501
  function clearAgentCaches(agentId, codeName) {
9448
9502
  const channelCacheMutated = clearAgentState(agentId, codeName);
9449
9503
  agentChannelTokens.delete(codeName);
9504
+ sharedBusyBuckets.reset(codeName);
9450
9505
  stopOpencodeSlackIngest(codeName, log);
9451
9506
  stopOpencodeTelegramIngest(codeName, log);
9452
9507
  agentFrameworkCache.delete(codeName);
@@ -9479,7 +9534,7 @@ var agentRestartTimezoneInputs = /* @__PURE__ */ new Map();
9479
9534
  var lastVersionCheckAt = 0;
9480
9535
  var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
9481
9536
  var lastResponsivenessProbeAt = 0;
9482
- var agtCliVersion = true ? "0.28.425" : "dev";
9537
+ var agtCliVersion = true ? "0.28.427" : "dev";
9483
9538
  function resolveBrewPath(execFileSync2) {
9484
9539
  try {
9485
9540
  const out = execFileSync2("which", ["brew"], { timeout: 5e3 }).toString().trim();
@@ -9728,7 +9783,7 @@ function runAsync(cmd, args, opts) {
9728
9783
  let stdout = "";
9729
9784
  let stderr = "";
9730
9785
  let settled = false;
9731
- const timer = setTimeout(() => {
9786
+ const timer2 = setTimeout(() => {
9732
9787
  child.kill("SIGTERM");
9733
9788
  if (settled) return;
9734
9789
  settled = true;
@@ -9749,13 +9804,13 @@ function runAsync(cmd, args, opts) {
9749
9804
  child.on("error", (err) => {
9750
9805
  if (settled) return;
9751
9806
  settled = true;
9752
- clearTimeout(timer);
9807
+ clearTimeout(timer2);
9753
9808
  reject(err);
9754
9809
  });
9755
9810
  child.on("close", (code) => {
9756
9811
  if (settled) return;
9757
9812
  settled = true;
9758
- clearTimeout(timer);
9813
+ clearTimeout(timer2);
9759
9814
  resolve({ code: code ?? -1, stdout, stderr });
9760
9815
  });
9761
9816
  }).catch(reject);
@@ -10577,14 +10632,16 @@ async function refreshSkillsIndexInClaudeMd(configDir, codeName, log2) {
10577
10632
  }
10578
10633
  }
10579
10634
  const body = entries.length ? entries.map((e) => `- **${e.name}** \u2014 ${e.description}`).join("\n") : "_(no skills installed)_";
10580
- const section = `${SKILLS_INDEX_START}
10581
- ## Available Skills
10635
+ const injectSkillList = hostFlagStore().getBoolean("claude-md-skills-index");
10636
+ const skillList = injectSkillList ? `## Available Skills
10582
10637
 
10583
10638
  The following skills are installed in \`.claude/skills/\`. Claude Code auto-activates them when relevant \u2014 you don't need to read them manually, but you should know they exist.
10584
10639
 
10585
10640
  ${body}
10586
10641
 
10587
- ## Updating Integrations (ENG-4341)
10642
+ ` : "";
10643
+ const section = `${SKILLS_INDEX_START}
10644
+ ${skillList}## Updating Integrations (ENG-4341)
10588
10645
 
10589
10646
  Integration skills under \`.claude/skills/integration-*/SKILL.md\` are **read-only** and managed by the platform. They are derived from the integration's database row plus any per-agent context overrides, and are re-rendered every time the manager polls or a context change is broadcast over Supabase Realtime.
10590
10647
 
@@ -10607,7 +10664,9 @@ ${SKILLS_INDEX_END}`;
10607
10664
  }
10608
10665
  if (next !== current) {
10609
10666
  writeFileSync13(claudeMdPath, next, "utf-8");
10610
- log2(`Refreshed skills index in CLAUDE.md for '${codeName}' (${entries.length} skills)`);
10667
+ log2(
10668
+ injectSkillList ? `Refreshed skills index in CLAUDE.md for '${codeName}' (${entries.length} skills)` : `Refreshed CLAUDE.md managed block for '${codeName}' (skill list suppressed by claude-md-skills-index=false; ${entries.length} skills on disk)`
10669
+ );
10611
10670
  }
10612
10671
  }
10613
10672
  var consecutivePollFailures = 0;
@@ -10627,7 +10686,7 @@ function flushRestartedAgentDiagnostics(hostId, codeNames) {
10627
10686
  if (codeNames.length === 0) return;
10628
10687
  void (async () => {
10629
10688
  try {
10630
- const { collectDiagnostics } = await import("../persistent-session-37WNPBRA.js");
10689
+ const { collectDiagnostics } = await import("../persistent-session-2ZXAKOO4.js");
10631
10690
  await api.post("/host/heartbeat", {
10632
10691
  host_id: hostId,
10633
10692
  agent_diagnostics: collectDiagnostics(codeNames, quarantineEntriesFor)
@@ -10660,7 +10719,7 @@ async function pollCycle() {
10660
10719
  getSlackToken: (codeName) => agentChannelTokens.get(codeName)?.slack ?? null,
10661
10720
  sendSlack: async (botToken, body) => {
10662
10721
  const controller = new AbortController();
10663
- const timer = setTimeout(() => controller.abort(), 5e3);
10722
+ const timer2 = setTimeout(() => controller.abort(), 5e3);
10664
10723
  try {
10665
10724
  const res = await fetch("https://slack.com/api/chat.postMessage", {
10666
10725
  method: "POST",
@@ -10677,7 +10736,7 @@ async function pollCycle() {
10677
10736
  const isAbort = err.name === "AbortError";
10678
10737
  return { ok: false, error: isAbort ? "timeout" : err.message };
10679
10738
  } finally {
10680
- clearTimeout(timer);
10739
+ clearTimeout(timer2);
10681
10740
  }
10682
10741
  },
10683
10742
  // ENG-6399: report the restart to audit_log via POST /host/restart-event.
@@ -10734,7 +10793,7 @@ async function pollCycle() {
10734
10793
  }
10735
10794
  try {
10736
10795
  const { detectHostSecurity } = await import("../host-security-6PDFG7F5.js");
10737
- const { collectDiagnostics } = await import("../persistent-session-37WNPBRA.js");
10796
+ const { collectDiagnostics } = await import("../persistent-session-2ZXAKOO4.js");
10738
10797
  const diagCodeNames = [...agentState.persistentSessionAgents];
10739
10798
  const agentDiagnostics = diagCodeNames.length > 0 ? collectDiagnostics(diagCodeNames, quarantineEntriesFor) : void 0;
10740
10799
  let tailscaleHostname;
@@ -10848,7 +10907,7 @@ async function pollCycle() {
10848
10907
  collectResponsivenessProbes,
10849
10908
  collectPanelessActivityProbes,
10850
10909
  getResponsivenessIntervalMs
10851
- } = await import("../responsiveness-probe-GMIXR3TR.js");
10910
+ } = await import("../responsiveness-probe-ILEPBUI7.js");
10852
10911
  const probeIntervalMs = getResponsivenessIntervalMs();
10853
10912
  if (now - lastResponsivenessProbeAt > probeIntervalMs) {
10854
10913
  const probeCodeNames = [...agentState.persistentSessionAgents];
@@ -10861,17 +10920,42 @@ async function pollCycle() {
10861
10920
  return lastRepliedAt == null ? null : Math.max(0, Math.floor((Date.now() - lastRepliedAt) / 1e3));
10862
10921
  }
10863
10922
  });
10923
+ const drainedBuckets = /* @__PURE__ */ new Map();
10924
+ const drainedCodeNames = /* @__PURE__ */ new Set();
10925
+ const takeBuckets = (codeName) => {
10926
+ if (drainedCodeNames.has(codeName)) return [];
10927
+ drainedCodeNames.add(codeName);
10928
+ const buckets = sharedBusyBuckets.drainClosed(codeName, Date.now());
10929
+ if (buckets.length > 0) drainedBuckets.set(codeName, buckets);
10930
+ return buckets;
10931
+ };
10864
10932
  const probes = [...collectResponsivenessProbes(probeCodeNames), ...paneless].map((p) => {
10865
10933
  const giveUps = takeWatchdogGiveUpCount(p.code_name);
10866
10934
  if (giveUps > 0) drainedGiveUps.set(p.code_name, giveUps);
10867
- return { ...p, input_stuck_give_ups: giveUps };
10935
+ const busyBuckets = takeBuckets(p.code_name);
10936
+ return {
10937
+ ...p,
10938
+ input_stuck_give_ups: giveUps,
10939
+ ...busyBuckets.length > 0 ? { busy_buckets: busyBuckets } : {}
10940
+ };
10868
10941
  });
10942
+ for (const codeName of probeCodeNames) {
10943
+ const buckets = takeBuckets(codeName);
10944
+ if (buckets.length > 0) {
10945
+ probes.push({ code_name: codeName, busy_buckets: buckets, input_stuck_give_ups: 0 });
10946
+ }
10947
+ }
10869
10948
  if (probes.length > 0) {
10870
10949
  void api.post("/host/responsiveness-probe", { host_id: hostId, probes }).catch((err) => {
10871
10950
  for (const [codeName, count] of drainedGiveUps) {
10872
10951
  creditWatchdogGiveUpCount(codeName, count);
10873
10952
  }
10874
- log(`[responsiveness-probe] post failed (give-up counts re-credited): ${err.message}`);
10953
+ for (const [codeName, buckets] of drainedBuckets) {
10954
+ sharedBusyBuckets.credit(codeName, buckets);
10955
+ }
10956
+ log(
10957
+ `[responsiveness-probe] post failed (give-up counts + ${drainedBuckets.size} busy-bucket set(s) re-credited): ${err.message}`
10958
+ );
10875
10959
  });
10876
10960
  }
10877
10961
  }
@@ -10887,7 +10971,7 @@ async function pollCycle() {
10887
10971
  collectResponsivenessProbes,
10888
10972
  livePendingInboundOldestAgeSeconds,
10889
10973
  parkPendingInbound
10890
- } = await import("../responsiveness-probe-GMIXR3TR.js");
10974
+ } = await import("../responsiveness-probe-ILEPBUI7.js");
10891
10975
  const { getProjectDir: wedgeProjectDir } = await import("../scheduler-engine-NDP36U7O.js");
10892
10976
  const wedgeNow = /* @__PURE__ */ new Date();
10893
10977
  const liveAgents = agentState.persistentSessionAgents;
@@ -14198,7 +14282,7 @@ async function handleRestartDoorbell(agentId, requestedAt, restartReason) {
14198
14282
  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}`));
14199
14283
  void (async () => {
14200
14284
  try {
14201
- const { collectDiagnostics } = await import("../persistent-session-37WNPBRA.js");
14285
+ const { collectDiagnostics } = await import("../persistent-session-2ZXAKOO4.js");
14202
14286
  await api.post("/host/heartbeat", {
14203
14287
  host_id: hostId,
14204
14288
  agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor)
@@ -14248,7 +14332,7 @@ async function respawnAgentAfterMcpStop(codeName, reason) {
14248
14332
  }
14249
14333
  try {
14250
14334
  const hostId = await getHostId();
14251
- const { collectDiagnostics } = await import("../persistent-session-37WNPBRA.js");
14335
+ const { collectDiagnostics } = await import("../persistent-session-2ZXAKOO4.js");
14252
14336
  await api.post("/host/heartbeat", {
14253
14337
  host_id: hostId,
14254
14338
  agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor)
@@ -14701,7 +14785,7 @@ async function processClaudePairSessions(agents) {
14701
14785
  killPairSession,
14702
14786
  pairTmuxSession,
14703
14787
  finalizeClaudePairOnboarding
14704
- } = await import("../claude-pair-runtime-XN4JLRAB.js");
14788
+ } = await import("../claude-pair-runtime-ITWM6RWY.js");
14705
14789
  for (const pairId of pendingResp.cancelled_pair_ids ?? []) {
14706
14790
  log(`[claude-pair] sweeping orphan tmux session for pair ${pairId.slice(0, 8)}`);
14707
14791
  const killed = await killPairSession(pairTmuxSession(pairId));
@@ -15173,6 +15257,7 @@ function startPolling() {
15173
15257
  void postLivenessHeartbeat();
15174
15258
  }, LIVENESS_HEARTBEAT_INTERVAL_MS);
15175
15259
  livenessTimer.unref();
15260
+ startPaneOccupancySampler(() => agentState.persistentSessionAgents);
15176
15261
  void startCaffeinate();
15177
15262
  loadChannelHashCache2();
15178
15263
  loadSenderPolicyBaseline2();
@@ -15266,6 +15351,7 @@ async function stopPolling(opts = {}) {
15266
15351
  clearInterval(livenessTimer);
15267
15352
  livenessTimer = null;
15268
15353
  }
15354
+ stopPaneOccupancySampler();
15269
15355
  const shutdownTimer = setTimeout(() => {
15270
15356
  log("Shutdown timeout exceeded (15s), forcing exit");
15271
15357
  process.exit(opts.forcedExitCode ?? 1);
@@ -15631,6 +15717,7 @@ export {
15631
15717
  markAgentForFreshMemorySync,
15632
15718
  maybeInjectKanbanCheck,
15633
15719
  maybeUpgradeClaudeCode,
15720
+ refreshSkillsIndexInClaudeMd,
15634
15721
  reorderRestartedFirst,
15635
15722
  resolveManagedMcpServerId,
15636
15723
  restartReasonBindsNewMcp,