@integrity-labs/agt-cli 0.28.57 → 0.28.58

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
@@ -37,7 +37,7 @@ import {
37
37
  success,
38
38
  table,
39
39
  warn
40
- } from "../chunk-F45T5XPH.js";
40
+ } from "../chunk-ZKHETP7Y.js";
41
41
  import {
42
42
  CHANNEL_REGISTRY,
43
43
  DEPLOYMENT_TEMPLATES,
@@ -4777,7 +4777,7 @@ import { execFileSync, execSync } from "child_process";
4777
4777
  import { existsSync as existsSync10, realpathSync as realpathSync2 } from "fs";
4778
4778
  import chalk18 from "chalk";
4779
4779
  import ora16 from "ora";
4780
- var cliVersion = true ? "0.28.57" : "dev";
4780
+ var cliVersion = true ? "0.28.58" : "dev";
4781
4781
  async function fetchLatestVersion() {
4782
4782
  const host2 = getHost();
4783
4783
  if (!host2) return null;
@@ -5791,7 +5791,7 @@ function handleError(err) {
5791
5791
  }
5792
5792
 
5793
5793
  // src/bin/agt.ts
5794
- var cliVersion2 = true ? "0.28.57" : "dev";
5794
+ var cliVersion2 = true ? "0.28.58" : "dev";
5795
5795
  var program = new Command();
5796
5796
  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");
5797
5797
  program.hook("preAction", async (thisCommand, actionCommand) => {
@@ -7355,7 +7355,7 @@ function requireHost() {
7355
7355
  }
7356
7356
 
7357
7357
  // src/lib/api-client.ts
7358
- var agtCliVersion = true ? "0.28.57" : "dev";
7358
+ var agtCliVersion = true ? "0.28.58" : "dev";
7359
7359
  var lastConfigHash = null;
7360
7360
  function setConfigHash(hash) {
7361
7361
  lastConfigHash = hash && hash.length > 0 ? hash : null;
@@ -8651,4 +8651,4 @@ export {
8651
8651
  managerInstallSystemUnitCommand,
8652
8652
  managerUninstallSystemUnitCommand
8653
8653
  };
8654
- //# sourceMappingURL=chunk-F45T5XPH.js.map
8654
+ //# sourceMappingURL=chunk-ZKHETP7Y.js.map
@@ -27,7 +27,7 @@ import {
27
27
  requireHost,
28
28
  safeWriteJsonAtomic,
29
29
  setConfigHash
30
- } from "../chunk-F45T5XPH.js";
30
+ } from "../chunk-ZKHETP7Y.js";
31
31
  import {
32
32
  getProjectDir as getProjectDir2,
33
33
  getReadyTasks,
@@ -1512,9 +1512,13 @@ var GATEABLE_RESTART_REASONS = /* @__PURE__ */ new Set([
1512
1512
  function isGateableRestartReason(reason) {
1513
1513
  return reason != null && GATEABLE_RESTART_REASONS.has(reason);
1514
1514
  }
1515
+ var WINDOW_EXEMPT_RESTART_REASONS = /* @__PURE__ */ new Set(["channel-set-change"]);
1516
+ function isWindowExemptRestartReason(reason) {
1517
+ return reason != null && WINDOW_EXEMPT_RESTART_REASONS.has(reason);
1518
+ }
1515
1519
  function decideRestartGate(opts) {
1516
1520
  if (isMaintenanceWindowDisabled(opts.env)) return "proceed";
1517
- if (opts.window && !isWithinMaintenanceWindow(opts.window, opts.now)) {
1521
+ if (!opts.windowExempt && opts.window && !isWithinMaintenanceWindow(opts.window, opts.now)) {
1518
1522
  return "defer-window";
1519
1523
  }
1520
1524
  const paneThreshold = opts.idleThresholdSeconds ?? RESTART_IDLE_THRESHOLD_SECONDS;
@@ -6281,10 +6285,17 @@ async function maybeResumeReconcile(agent) {
6281
6285
  autoResumeInFlight.delete(codeName);
6282
6286
  }
6283
6287
  }
6284
- function scheduleSessionRestart(codeName, delayMs, reason, breakerReason = "hot-reload-mcp") {
6288
+ function scheduleSessionRestart(codeName, delayMs, reason, breakerReason = "hot-reload-mcp", beforeStop) {
6285
6289
  const existing = pendingSessionRestarts.get(codeName);
6286
6290
  if (existing) {
6287
- clearTimeout(existing);
6291
+ const keepExistingWindowExempt = isWindowExemptRestartReason(existing.breakerReason) && !isWindowExemptRestartReason(breakerReason);
6292
+ if (keepExistingWindowExempt) {
6293
+ log(
6294
+ `[hot-reload] Coalesced restart for '${codeName}': keeping the already-scheduled window-exempt '${existing.reason}' (${existing.breakerReason}); ignoring lower-priority '${reason}' (${breakerReason}) (ENG-6491)`
6295
+ );
6296
+ return;
6297
+ }
6298
+ clearTimeout(existing.timer);
6288
6299
  log(`[hot-reload] Coalesced restart for '${codeName}': replacing pending timer with ${reason}`);
6289
6300
  }
6290
6301
  const timer = setTimeout(() => {
@@ -6298,7 +6309,7 @@ function scheduleSessionRestart(codeName, delayMs, reason, breakerReason = "hot-
6298
6309
  );
6299
6310
  deferLogThrottle.set(codeName, Date.now());
6300
6311
  }
6301
- scheduleSessionRestart(codeName, RESTART_DEFER_RECHECK_MS, reason, breakerReason);
6312
+ scheduleSessionRestart(codeName, RESTART_DEFER_RECHECK_MS, reason, breakerReason, beforeStop);
6302
6313
  return;
6303
6314
  }
6304
6315
  deferLogThrottle.delete(codeName);
@@ -6308,11 +6319,18 @@ function scheduleSessionRestart(codeName, delayMs, reason, breakerReason = "hot-
6308
6319
  );
6309
6320
  return;
6310
6321
  }
6322
+ if (beforeStop) {
6323
+ try {
6324
+ beforeStop();
6325
+ } catch (err) {
6326
+ log(`[hot-reload] beforeStop hook threw for '${codeName}' (non-fatal): ${err.message}`);
6327
+ }
6328
+ }
6311
6329
  stopPersistentSession(codeName, log);
6312
6330
  runningMcpHashes.delete(codeName);
6313
6331
  recordRestartForBreaker(codeName, breakerReason);
6314
6332
  log(`[hot-reload] Session stopped for '${codeName}' \u2014 will respawn with ${reason}`);
6315
- if (breakerReason === "hot-reload-mcp" || breakerReason === "bind-remediation") {
6333
+ if (breakerReason === "hot-reload-mcp" || breakerReason === "bind-remediation" || breakerReason === "channel-set-change") {
6316
6334
  const prior = pendingRestartVerifications.get(codeName);
6317
6335
  pendingRestartVerifications.set(codeName, {
6318
6336
  firedAt: Date.now(),
@@ -6321,13 +6339,13 @@ function scheduleSessionRestart(codeName, delayMs, reason, breakerReason = "hot-
6321
6339
  }
6322
6340
  }, delayMs);
6323
6341
  timer.unref?.();
6324
- pendingSessionRestarts.set(codeName, timer);
6342
+ pendingSessionRestarts.set(codeName, { timer, reason, breakerReason, beforeStop });
6325
6343
  }
6326
6344
  function cancelPendingSessionRestart(codeName) {
6327
6345
  pendingRestartVerifications.delete(codeName);
6328
6346
  const existing = pendingSessionRestarts.get(codeName);
6329
6347
  if (!existing) return;
6330
- clearTimeout(existing);
6348
+ clearTimeout(existing.timer);
6331
6349
  pendingSessionRestarts.delete(codeName);
6332
6350
  deferLogThrottle.delete(codeName);
6333
6351
  log(`[hot-reload] Cancelled pending restart timer for '${codeName}' (another teardown path is handling it)`);
@@ -6415,6 +6433,9 @@ function restartGateFor(codeName, reason) {
6415
6433
  if (!isGateableRestartReason(reason)) return "bypass";
6416
6434
  return decideRestartGate({
6417
6435
  window: cachedMaintenanceWindow,
6436
+ // ENG-6491: channel adds (channel-set-change) skip the off-peak window but
6437
+ // still defer-until-idle — they come online as soon as the agent is quiet.
6438
+ windowExempt: isWindowExemptRestartReason(reason),
6418
6439
  paneLogAgeSeconds: paneLogAgeSecondsFor(codeName),
6419
6440
  transcriptAgeSeconds: transcriptAgeSecondsFor(codeName),
6420
6441
  inboundAgeSeconds: inboundAgeSecondsFor(codeName),
@@ -6680,7 +6701,7 @@ var cachedMaintenanceWindow = null;
6680
6701
  var lastVersionCheckAt = 0;
6681
6702
  var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
6682
6703
  var lastResponsivenessProbeAt = 0;
6683
- var agtCliVersion = true ? "0.28.57" : "dev";
6704
+ var agtCliVersion = true ? "0.28.58" : "dev";
6684
6705
  function resolveBrewPath(execFileSync4) {
6685
6706
  try {
6686
6707
  const out = execFileSync4("which", ["brew"], { timeout: 5e3 }).toString().trim();
@@ -9012,7 +9033,31 @@ async function processAgent(agent, agentStates) {
9012
9033
  if (!delivered) {
9013
9034
  log(`[hot-reload] Inject notification unconfirmed for '${agent.code_name}' \u2014 proceeding with shorter delay`);
9014
9035
  }
9015
- scheduleSessionRestart(agent.code_name, delay, "new channel set");
9036
+ const isChannelAddRestart = restartDecision.added.length > 0;
9037
+ const addedChannels = [...restartDecision.added];
9038
+ const writeDmNoticeMarkers = isChannelAddRestart ? () => {
9039
+ try {
9040
+ const agentAugmentedDir = join16(homedir9(), ".augmented", agent.code_name);
9041
+ mkdirSync5(agentAugmentedDir, { recursive: true });
9042
+ const markerJson = JSON.stringify({
9043
+ version: 1,
9044
+ at: (/* @__PURE__ */ new Date()).toISOString(),
9045
+ added: addedChannels
9046
+ });
9047
+ for (const file of ["slack-channel-add-restart.json", "telegram-channel-add-restart.json"]) {
9048
+ atomicWriteFileSync(join16(agentAugmentedDir, file), markerJson);
9049
+ }
9050
+ } catch (err) {
9051
+ log(`[hot-reload] channel-add DM-notice marker write failed for '${agent.code_name}' (non-fatal): ${err.message}`);
9052
+ }
9053
+ } : void 0;
9054
+ scheduleSessionRestart(
9055
+ agent.code_name,
9056
+ delay,
9057
+ "new channel set",
9058
+ isChannelAddRestart ? "channel-set-change" : "hot-reload-mcp",
9059
+ writeDmNoticeMarkers
9060
+ );
9016
9061
  }
9017
9062
  if (channelConfigConverged) {
9018
9063
  const hasSenderPolicyChannel = currentChannelIds.has("slack") || currentChannelIds.has("msteams");