@integrity-labs/agt-cli 0.28.131 → 0.28.132

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-N5N3CA6W.js";
40
+ } from "../chunk-GF2KBUVY.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.131" : "dev";
4780
+ var cliVersion = true ? "0.28.132" : "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.131" : "dev";
5794
+ var cliVersion2 = true ? "0.28.132" : "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) => {
@@ -7692,7 +7692,7 @@ function requireHost() {
7692
7692
  }
7693
7693
 
7694
7694
  // src/lib/api-client.ts
7695
- var agtCliVersion = true ? "0.28.131" : "dev";
7695
+ var agtCliVersion = true ? "0.28.132" : "dev";
7696
7696
  var lastConfigHash = null;
7697
7697
  function setConfigHash(hash) {
7698
7698
  lastConfigHash = hash && hash.length > 0 ? hash : null;
@@ -8989,4 +8989,4 @@ export {
8989
8989
  managerInstallSystemUnitCommand,
8990
8990
  managerUninstallSystemUnitCommand
8991
8991
  };
8992
- //# sourceMappingURL=chunk-N5N3CA6W.js.map
8992
+ //# sourceMappingURL=chunk-GF2KBUVY.js.map
@@ -28,7 +28,7 @@ import {
28
28
  requireHost,
29
29
  safeWriteJsonAtomic,
30
30
  setConfigHash
31
- } from "../chunk-N5N3CA6W.js";
31
+ } from "../chunk-GF2KBUVY.js";
32
32
  import {
33
33
  getProjectDir as getProjectDir2,
34
34
  getReadyTasks,
@@ -1676,6 +1676,18 @@ function decideMaintenanceWindowGate(opts) {
1676
1676
  if (!opts.window) return "proceed";
1677
1677
  return isWithinMaintenanceWindow(opts.window, opts.now) ? "proceed" : "defer";
1678
1678
  }
1679
+ function decideForcedUpdate(opts) {
1680
+ const { requestedAt, lastProcessedAt, hostBusy } = opts;
1681
+ if (!requestedAt) return "none";
1682
+ const requestedMs = Date.parse(requestedAt);
1683
+ if (Number.isNaN(requestedMs)) return "none";
1684
+ if (lastProcessedAt) {
1685
+ const processedMs = Date.parse(lastProcessedAt);
1686
+ if (!Number.isNaN(processedMs) && processedMs >= requestedMs) return "already-handled";
1687
+ }
1688
+ if (hostBusy) return "defer-idle";
1689
+ return "consume";
1690
+ }
1679
1691
  function isUrgentUpgrade(opts) {
1680
1692
  if (!opts.urgentTarget) return false;
1681
1693
  if (opts.installed === "dev") return false;
@@ -6780,6 +6792,21 @@ function restartGateFor(codeName, reason) {
6780
6792
  now: /* @__PURE__ */ new Date()
6781
6793
  });
6782
6794
  }
6795
+ function isHostBusyForForcedUpdate() {
6796
+ const now = /* @__PURE__ */ new Date();
6797
+ for (const agent of state6.agents) {
6798
+ const decision = decideRestartGate({
6799
+ window: null,
6800
+ paneLogAgeSeconds: paneLogAgeSecondsFor(agent.codeName),
6801
+ transcriptAgeSeconds: transcriptAgeSecondsFor(agent.codeName),
6802
+ inboundAgeSeconds: inboundAgeSecondsFor(agent.codeName),
6803
+ now,
6804
+ env: {}
6805
+ });
6806
+ if (decision === "defer-idle") return true;
6807
+ }
6808
+ return false;
6809
+ }
6783
6810
  var runningMcpHashes = /* @__PURE__ */ new Map();
6784
6811
  var runningMcpServerKeys = /* @__PURE__ */ new Map();
6785
6812
  var runningChannelSecretHashes = /* @__PURE__ */ new Map();
@@ -7040,7 +7067,7 @@ var agentRestartTimezoneInputs = /* @__PURE__ */ new Map();
7040
7067
  var lastVersionCheckAt = 0;
7041
7068
  var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
7042
7069
  var lastResponsivenessProbeAt = 0;
7043
- var agtCliVersion = true ? "0.28.131" : "dev";
7070
+ var agtCliVersion = true ? "0.28.132" : "dev";
7044
7071
  function resolveBrewPath(execFileSync4) {
7045
7072
  try {
7046
7073
  const out = execFileSync4("which", ["brew"], { timeout: 5e3 }).toString().trim();
@@ -7341,7 +7368,8 @@ var selfUpdateUpToDateLogged = false;
7341
7368
  var restartAfterUpgrade = false;
7342
7369
  var pendingUpgradeVersion = null;
7343
7370
  var selfUpdateInFlight = false;
7344
- async function checkAndUpdateCli() {
7371
+ async function checkAndUpdateCli(opts) {
7372
+ const force = opts?.force ?? false;
7345
7373
  if (selfUpdateInFlight) return;
7346
7374
  selfUpdateInFlight = true;
7347
7375
  try {
@@ -7359,19 +7387,21 @@ async function checkAndUpdateCli() {
7359
7387
  if (!isBrewFormula && !isNpmGlobal) return;
7360
7388
  const { readFileSync: readF, writeFileSync: writeF } = await import("fs");
7361
7389
  const markerPath = join16(homedir9(), ".augmented", ".last-update-check");
7362
- try {
7363
- const lastCheck = parseInt(readF(markerPath, "utf-8").trim(), 10);
7364
- if (Date.now() - lastCheck < UPDATE_CHECK_INTERVAL_MS) return;
7365
- } catch {
7390
+ if (!force) {
7391
+ try {
7392
+ const lastCheck = parseInt(readF(markerPath, "utf-8").trim(), 10);
7393
+ if (Date.now() - lastCheck < UPDATE_CHECK_INTERVAL_MS) return;
7394
+ } catch {
7395
+ }
7366
7396
  }
7367
7397
  try {
7368
7398
  writeF(markerPath, String(Date.now()));
7369
7399
  } catch {
7370
7400
  }
7371
7401
  if (isBrewFormula) {
7372
- await checkAndUpdateCliViaBrew();
7402
+ await checkAndUpdateCliViaBrew(force);
7373
7403
  } else {
7374
- await checkAndUpdateCliViaNpm();
7404
+ await checkAndUpdateCliViaNpm(force);
7375
7405
  }
7376
7406
  try {
7377
7407
  writeF(markerPath, String(Date.now()));
@@ -7381,7 +7411,7 @@ async function checkAndUpdateCli() {
7381
7411
  selfUpdateInFlight = false;
7382
7412
  }
7383
7413
  }
7384
- async function checkAndUpdateCliViaBrew() {
7414
+ async function checkAndUpdateCliViaBrew(force = false) {
7385
7415
  const { execFileSync: execFileSync4 } = await import("child_process");
7386
7416
  const brewPath = resolveBrewPath(execFileSync4);
7387
7417
  if (!brewPath) return;
@@ -7400,7 +7430,7 @@ async function checkAndUpdateCliViaBrew() {
7400
7430
  if (agtOutdated) {
7401
7431
  const installed = agtOutdated.installed_versions?.[0] ?? "unknown";
7402
7432
  const latest = agtOutdated.current_version ?? "unknown";
7403
- if (decideMaintenanceWindowGate({ window: cachedMaintenanceWindow, now: /* @__PURE__ */ new Date() }) === "defer") {
7433
+ if (!force && decideMaintenanceWindowGate({ window: cachedMaintenanceWindow, now: /* @__PURE__ */ new Date() }) === "defer") {
7404
7434
  log(
7405
7435
  `[self-update] agt CLI ${installed} \u2192 ${latest} (brew) deferred \u2014 ` + formatWindowDeferLogLine(cachedMaintenanceWindow ?? {}, /* @__PURE__ */ new Date())
7406
7436
  );
@@ -7412,7 +7442,7 @@ async function checkAndUpdateCliViaBrew() {
7412
7442
  lastAppliedMs: readLastSelfUpdateAppliedMs(selfUpdateAppliedMarkerPath()),
7413
7443
  now: Date.now()
7414
7444
  });
7415
- if (!coalesce.proceed) {
7445
+ if (!force && !coalesce.proceed) {
7416
7446
  log(formatCoalesceDeferLogLine({
7417
7447
  installed,
7418
7448
  latest,
@@ -7422,7 +7452,7 @@ async function checkAndUpdateCliViaBrew() {
7422
7452
  }));
7423
7453
  return;
7424
7454
  }
7425
- log(`[self-update] agt CLI update available: ${installed} \u2192 ${latest}. Upgrading via brew...`);
7455
+ log(`[self-update] agt CLI update available: ${installed} \u2192 ${latest}. Upgrading via brew${force ? " (forced \u2014 Update CLI now)" : ""}...`);
7426
7456
  try {
7427
7457
  execFileSync4(brewPath, ["upgrade", "integrity-labs/tap/agt"], {
7428
7458
  timeout: 12e4,
@@ -7443,7 +7473,7 @@ async function checkAndUpdateCliViaBrew() {
7443
7473
  log(`[self-update] brew outdated failed: ${err.message}`);
7444
7474
  }
7445
7475
  }
7446
- async function checkAndUpdateCliViaNpm() {
7476
+ async function checkAndUpdateCliViaNpm(force = false) {
7447
7477
  if (agtCliVersion === "dev") return;
7448
7478
  const channel = process.env.AGT_CLI_RELEASE_CHANNEL || "latest";
7449
7479
  let latest;
@@ -7501,7 +7531,7 @@ async function checkAndUpdateCliViaNpm() {
7501
7531
  }
7502
7532
  return;
7503
7533
  }
7504
- if (decideMaintenanceWindowGate({ window: cachedMaintenanceWindow, now: /* @__PURE__ */ new Date() }) === "defer") {
7534
+ if (!force && decideMaintenanceWindowGate({ window: cachedMaintenanceWindow, now: /* @__PURE__ */ new Date() }) === "defer") {
7505
7535
  log(
7506
7536
  `[self-update] agt CLI ${agtCliVersion} \u2192 ${latest} (channel=${channel}) deferred \u2014 ` + formatWindowDeferLogLine(cachedMaintenanceWindow ?? {}, /* @__PURE__ */ new Date())
7507
7537
  );
@@ -7513,7 +7543,7 @@ async function checkAndUpdateCliViaNpm() {
7513
7543
  lastAppliedMs: readLastSelfUpdateAppliedMs(selfUpdateAppliedMarkerPath()),
7514
7544
  now: Date.now()
7515
7545
  });
7516
- if (!coalesce.proceed) {
7546
+ if (!force && !coalesce.proceed) {
7517
7547
  log(formatCoalesceDeferLogLine({
7518
7548
  installed: agtCliVersion,
7519
7549
  latest,
@@ -8239,11 +8269,53 @@ async function pollCycle() {
8239
8269
  // combines these with the org's server-resolved flags + versions into a
8240
8270
  // host_config_snapshots row (on change) so bugs correlate with config.
8241
8271
  // Allowlist-only by construction — no raw env / secrets ever sent.
8242
- env_gates: collectEnvGates(process.env)
8272
+ env_gates: collectEnvGates(process.env),
8273
+ // ENG-6692: ack the last consumed "Update CLI now" timestamp so the API
8274
+ // clears hosts.update_requested_at. Echoes our persisted dedup marker;
8275
+ // null until we've ever consumed one.
8276
+ update_request_processed_at: state6.lastUpdateRequestProcessedAt ?? null
8243
8277
  });
8244
8278
  if (hbResp?.maintenance_window) {
8245
8279
  cachedMaintenanceWindow = hbResp.maintenance_window;
8246
8280
  }
8281
+ const requestedUpdateAt = hbResp?.update_requested_at ?? null;
8282
+ const forcedUpdate = decideForcedUpdate({
8283
+ requestedAt: requestedUpdateAt,
8284
+ lastProcessedAt: state6.lastUpdateRequestProcessedAt ?? null,
8285
+ hostBusy: isHostBusyForForcedUpdate()
8286
+ });
8287
+ if (forcedUpdate === "defer-idle") {
8288
+ log(
8289
+ `[self-update] "Update CLI now" requested at ${requestedUpdateAt} \u2014 deferring: an agent is mid-turn / recently active. Retrying next poll.`
8290
+ );
8291
+ } else if (forcedUpdate === "consume") {
8292
+ if (selfUpdateInFlight) {
8293
+ log(
8294
+ `[self-update] "Update CLI now" requested at ${requestedUpdateAt} \u2014 deferring: a self-update is already in flight. Retrying next poll.`
8295
+ );
8296
+ } else {
8297
+ const prevProcessedAt = state6.lastUpdateRequestProcessedAt ?? null;
8298
+ state6.lastUpdateRequestProcessedAt = requestedUpdateAt;
8299
+ let persisted = true;
8300
+ try {
8301
+ atomicWriteFileSync(getStateFile(), JSON.stringify(state6, null, 2));
8302
+ } catch (err) {
8303
+ persisted = false;
8304
+ state6.lastUpdateRequestProcessedAt = prevProcessedAt;
8305
+ log(
8306
+ `[self-update] failed to persist update-request ack; retrying next heartbeat: ${err.message}`
8307
+ );
8308
+ }
8309
+ if (persisted) {
8310
+ log(
8311
+ `[self-update] "Update CLI now" requested at ${requestedUpdateAt} \u2014 running window-bypassing self-update now (host idle).`
8312
+ );
8313
+ void checkAndUpdateCli({ force: true }).catch(
8314
+ (err) => log(`[self-update] forced check failed: ${err.message}`)
8315
+ );
8316
+ }
8317
+ }
8318
+ }
8247
8319
  if (hbResp?.feature_flags) {
8248
8320
  hostFlagStore().applyHeartbeat(hbResp.feature_flags, hbResp.flags_schema_version);
8249
8321
  }
@@ -12475,6 +12547,12 @@ function startManager(opts) {
12475
12547
  const n = autoResumeMarkers.size;
12476
12548
  if (n > 0) log(`[startup] rehydrated ${n} auto-resume marker(s) (ENG-6088)`);
12477
12549
  }
12550
+ if (typeof parsed.lastUpdateRequestProcessedAt === "string" || parsed.lastUpdateRequestProcessedAt === null) {
12551
+ state6.lastUpdateRequestProcessedAt = parsed.lastUpdateRequestProcessedAt;
12552
+ if (state6.lastUpdateRequestProcessedAt) {
12553
+ log(`[startup] rehydrated update-request ack at ${state6.lastUpdateRequestProcessedAt} (ENG-6692)`);
12554
+ }
12555
+ }
12478
12556
  }
12479
12557
  } catch (err) {
12480
12558
  log(`[startup] state rehydration failed (continuing with empty state): ${err.message}`);