@integrity-labs/agt-cli 0.28.897 → 0.28.899

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.
package/dist/bin/agt.js CHANGED
@@ -40,7 +40,7 @@ import {
40
40
  success,
41
41
  table,
42
42
  warn
43
- } from "../chunk-SYTV34UM.js";
43
+ } from "../chunk-FZBIHBDG.js";
44
44
  import {
45
45
  getProjectDir,
46
46
  isSessionResumeDisabled,
@@ -5467,7 +5467,7 @@ import { execFileSync, execSync } from "child_process";
5467
5467
  import { existsSync as existsSync11, realpathSync as realpathSync2 } from "fs";
5468
5468
  import chalk18 from "chalk";
5469
5469
  import ora16 from "ora";
5470
- var cliVersion = true ? "0.28.897" : "dev";
5470
+ var cliVersion = true ? "0.28.899" : "dev";
5471
5471
  async function fetchLatestVersion() {
5472
5472
  const host2 = getHost();
5473
5473
  if (!host2) return null;
@@ -6658,7 +6658,7 @@ function handleError(err) {
6658
6658
  }
6659
6659
 
6660
6660
  // src/bin/agt.ts
6661
- var cliVersion2 = true ? "0.28.897" : "dev";
6661
+ var cliVersion2 = true ? "0.28.899" : "dev";
6662
6662
  var program = new Command();
6663
6663
  program.name("agt").description("Augmented CLI \u2014 agent provisioning and management").version(cliVersion2).option("--json", "Emit machine-readable JSON output (suppress spinners and colors)").option("--skip-update-check", "Skip the automatic update check on startup");
6664
6664
  program.hook("preAction", async (thisCommand, actionCommand) => {
@@ -6841,7 +6841,7 @@ function exchangeFailureKind(err) {
6841
6841
  }
6842
6842
 
6843
6843
  // src/lib/api-client.ts
6844
- var agtCliVersion = true ? "0.28.897" : "dev";
6844
+ var agtCliVersion = true ? "0.28.899" : "dev";
6845
6845
  var lastConfigHash = null;
6846
6846
  function setConfigHash(hash) {
6847
6847
  lastConfigHash = hash && hash.length > 0 ? hash : null;
@@ -11451,4 +11451,4 @@ export {
11451
11451
  managerInstallSystemUnitCommand,
11452
11452
  managerUninstallSystemUnitCommand
11453
11453
  };
11454
- //# sourceMappingURL=chunk-SYTV34UM.js.map
11454
+ //# sourceMappingURL=chunk-FZBIHBDG.js.map
@@ -63,7 +63,7 @@ import {
63
63
  safeWriteJsonAtomic,
64
64
  setConfigHash,
65
65
  tripClass
66
- } from "../chunk-SYTV34UM.js";
66
+ } from "../chunk-FZBIHBDG.js";
67
67
  import {
68
68
  getProjectDir as getProjectDir2,
69
69
  getReadyTasks,
@@ -2261,13 +2261,63 @@ function decideReaperActions(file, isAlive, looksLikeClaude = () => true) {
2261
2261
  }
2262
2262
  function formatDrainShutdownLine(opts) {
2263
2263
  const killed = opts.killedPids && opts.killedPids.length > 0 ? ` killed_pids=${opts.killedPids.join(",")}` : "";
2264
+ const scanned = opts.scanned === void 0 ? "" : ` scanned=${opts.scanned}`;
2265
+ const acted = opts.acted === void 0 ? "" : ` acted=${opts.acted}`;
2264
2266
  const note = opts.note ? ` note="${opts.note.replace(/"/g, '\\"')}"` : "";
2265
- return `[drain] step=${opts.step} elapsed_ms=${opts.elapsedMs}${killed}${note}`;
2267
+ return `[drain] step=${opts.step} elapsed_ms=${opts.elapsedMs}${killed}${scanned}${acted}${note}`;
2266
2268
  }
2267
2269
  function formatReaperBootLine(opts) {
2268
2270
  return `[drain] step=boot-reaper total=${opts.totalRecorded} killed=${opts.killed} already_dead=${opts.alreadyDead} pid_reused_skipped=${opts.pidReusedSkipped}`;
2269
2271
  }
2270
2272
 
2273
+ // src/lib/drain-card-release.ts
2274
+ function decideDrainReleaseTargets(liveAgents, resolveAgentId) {
2275
+ const targets = [];
2276
+ const unresolved = [];
2277
+ for (const codeName of liveAgents) {
2278
+ const agentId = resolveAgentId(codeName);
2279
+ if (agentId) targets.push({ codeName, agentId });
2280
+ else unresolved.push(codeName);
2281
+ }
2282
+ return { targets, unresolved };
2283
+ }
2284
+ function drainReleaseScanned(enumerated, liveAgentCount) {
2285
+ return enumerated ? liveAgentCount : "not-scanned";
2286
+ }
2287
+ function tallyDrainReleases(results) {
2288
+ let released = 0;
2289
+ let failed = 0;
2290
+ for (const r of results) {
2291
+ if (r.status !== "fulfilled") {
2292
+ failed += 1;
2293
+ continue;
2294
+ }
2295
+ if (r.value && r.value.error !== void 0 && r.value.error !== null) {
2296
+ failed += 1;
2297
+ continue;
2298
+ }
2299
+ const n = r.value?.released;
2300
+ if (typeof n === "number" && Number.isFinite(n) && n > 0) released += n;
2301
+ const f = r.value?.failed;
2302
+ if (typeof f === "number" && Number.isFinite(f) && f > 0) failed += f;
2303
+ }
2304
+ return { released, failed };
2305
+ }
2306
+
2307
+ // src/lib/drain-session-kill.ts
2308
+ async function killSessionsConcurrently(sessions, killOne) {
2309
+ const killed = [];
2310
+ const failed = [];
2311
+ if (sessions.length === 0) return { killed, failed };
2312
+ const settled = await Promise.allSettled(sessions.map((s) => killOne(s)));
2313
+ settled.forEach((r, i) => {
2314
+ const session = sessions[i];
2315
+ if (r.status === "fulfilled") killed.push(session);
2316
+ else failed.push(session);
2317
+ });
2318
+ return { killed, failed };
2319
+ }
2320
+
2271
2321
  // src/lib/direct-chat-delivery.ts
2272
2322
  import { join as join7 } from "path";
2273
2323
  var DEFAULT_DIRECT_CHAT_MAX_AGE_MS = 30 * 6e4;
@@ -13671,7 +13721,7 @@ var agentRestartTimezoneInputs = /* @__PURE__ */ new Map();
13671
13721
  var lastVersionCheckAt = 0;
13672
13722
  var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
13673
13723
  var lastResponsivenessProbeAt = 0;
13674
- var agtCliVersion = true ? "0.28.897" : "dev";
13724
+ var agtCliVersion = true ? "0.28.899" : "dev";
13675
13725
  function resolveBrewPath(execFileSync2) {
13676
13726
  try {
13677
13727
  const out = execFileSync2("which", ["brew"], { timeout: 5e3 }).toString().trim();
@@ -21688,22 +21738,70 @@ async function killAllAgtTmuxSessions() {
21688
21738
  { timeout: 2e3, stdin: "ignore" }
21689
21739
  );
21690
21740
  const sessions = output.trim().split("\n").filter((s) => s.startsWith("agt-"));
21691
- for (const session of sessions) {
21692
- try {
21693
- await execFilePromiseLong("tmux", ["kill-session", "-t", session], {
21694
- timeout: 2e3,
21695
- stdin: "ignore"
21696
- });
21697
- log(`Killed tmux session '${session}'`);
21698
- } catch {
21699
- }
21700
- }
21741
+ const { killed, failed } = await killSessionsConcurrently(sessions, async (session) => {
21742
+ await execFilePromiseLong("tmux", ["kill-session", "-t", session], {
21743
+ timeout: 2e3,
21744
+ stdin: "ignore"
21745
+ });
21746
+ });
21747
+ for (const session of killed) log(`Killed tmux session '${session}'`);
21701
21748
  if (sessions.length > 0) {
21702
- log(`Cleaned up ${sessions.length} agt-* tmux session(s)`);
21749
+ log(
21750
+ `Cleaned up ${killed.length} agt-* tmux session(s)` + (failed.length > 0 ? ` (${failed.length} already gone or unkillable)` : "")
21751
+ );
21703
21752
  }
21704
21753
  } catch {
21705
21754
  }
21706
21755
  }
21756
+ function snapshotDrainReleaseTargets() {
21757
+ try {
21758
+ return { enumerated: true, liveAgents: [...agentState.persistentSessionAgents] };
21759
+ } catch {
21760
+ return { enumerated: false, liveAgents: [] };
21761
+ }
21762
+ }
21763
+ async function releaseInterruptedCardsOnDrain(snapshot) {
21764
+ const startedAt = Date.now();
21765
+ const { enumerated, liveAgents } = snapshot;
21766
+ const { targets, unresolved } = decideDrainReleaseTargets(
21767
+ liveAgents,
21768
+ (codeName) => agentState.codeNameToAgentId.get(codeName)
21769
+ );
21770
+ let released = 0;
21771
+ let failed = 0;
21772
+ if (targets.length > 0) {
21773
+ const reason = restartAfterUpgrade ? `manager drain: CLI self-update${pendingUpgradeVersion ? ` to ${pendingUpgradeVersion}` : ""}` : "manager drain: manager shutdown";
21774
+ const posts = Promise.allSettled(
21775
+ targets.map(
21776
+ (t) => api.post("/host/kanban/release-interrupted", {
21777
+ agent_id: t.agentId,
21778
+ reason
21779
+ })
21780
+ )
21781
+ );
21782
+ const deadline = new Promise((resolve2) => setTimeout(() => resolve2([]), 3e3));
21783
+ const settled = await Promise.race([posts, deadline]);
21784
+ if (settled.length === 0 && targets.length > 0) {
21785
+ failed = targets.length;
21786
+ } else {
21787
+ const tally = tallyDrainReleases(settled);
21788
+ released = tally.released;
21789
+ failed = tally.failed;
21790
+ }
21791
+ }
21792
+ const noteParts = [];
21793
+ if (unresolved.length > 0) noteParts.push(`unresolved_agent_ids=${unresolved.length}`);
21794
+ if (failed > 0) noteParts.push(`post_failures=${failed}`);
21795
+ log(
21796
+ formatDrainShutdownLine({
21797
+ step: "release-interrupted-cards",
21798
+ elapsedMs: Date.now() - startedAt,
21799
+ scanned: drainReleaseScanned(enumerated, liveAgents.length),
21800
+ acted: released,
21801
+ note: noteParts.length > 0 ? noteParts.join(" ") : void 0
21802
+ })
21803
+ );
21804
+ }
21707
21805
  async function stopPolling(opts = {}) {
21708
21806
  running = false;
21709
21807
  if (pollTimer) {
@@ -21730,9 +21828,21 @@ async function stopPolling(opts = {}) {
21730
21828
  } catch {
21731
21829
  }
21732
21830
  }
21733
- log(formatDrainShutdownLine({ step: "sigterm-claude-pids", elapsedMs: Date.now() - drainStartedAt, killedPids: livePids }));
21831
+ log(formatDrainShutdownLine({
21832
+ step: "sigterm-claude-pids",
21833
+ elapsedMs: Date.now() - drainStartedAt,
21834
+ killedPids: livePids,
21835
+ scanned: livePids.length,
21836
+ acted: livePids.length
21837
+ }));
21734
21838
  } else {
21735
- log(formatDrainShutdownLine({ step: "sigterm-claude-pids", elapsedMs: 0, note: "no in-flight claude -p children" }));
21839
+ log(formatDrainShutdownLine({
21840
+ step: "sigterm-claude-pids",
21841
+ elapsedMs: 0,
21842
+ scanned: 0,
21843
+ acted: 0,
21844
+ note: "no in-flight claude -p children (this step scans claude -p children only)"
21845
+ }));
21736
21846
  }
21737
21847
  const subsysStartedAt = Date.now();
21738
21848
  stopCaffeinate();
@@ -21746,8 +21856,13 @@ async function stopPolling(opts = {}) {
21746
21856
  for (const codeName of [...sessionRunsByCode.keys()]) {
21747
21857
  closeSessionRunForCode(codeName, "completed", "manager shutdown");
21748
21858
  }
21859
+ const drainReleaseSnapshot = snapshotDrainReleaseTargets();
21749
21860
  log("Killing tmux sessions...");
21750
- await killAllAgtTmuxSessions();
21861
+ try {
21862
+ await killAllAgtTmuxSessions();
21863
+ } finally {
21864
+ await releaseInterruptedCardsOnDrain(drainReleaseSnapshot);
21865
+ }
21751
21866
  log("Stopping persistent sessions...");
21752
21867
  await stopAllSessionsAndWait(log, { timeoutMs: 4e3 });
21753
21868
  clearTimeout(shutdownTimer);