@integrity-labs/agt-cli 0.28.236 → 0.28.237

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
@@ -38,7 +38,7 @@ import {
38
38
  success,
39
39
  table,
40
40
  warn
41
- } from "../chunk-ND3HG32M.js";
41
+ } from "../chunk-DN4HSL6M.js";
42
42
  import {
43
43
  CHANNEL_REGISTRY,
44
44
  DEFAULT_FRAMEWORK,
@@ -4826,7 +4826,7 @@ import { execFileSync, execSync } from "child_process";
4826
4826
  import { existsSync as existsSync10, realpathSync as realpathSync2 } from "fs";
4827
4827
  import chalk18 from "chalk";
4828
4828
  import ora16 from "ora";
4829
- var cliVersion = true ? "0.28.236" : "dev";
4829
+ var cliVersion = true ? "0.28.237" : "dev";
4830
4830
  async function fetchLatestVersion() {
4831
4831
  const host2 = getHost();
4832
4832
  if (!host2) return null;
@@ -5840,7 +5840,7 @@ function handleError(err) {
5840
5840
  }
5841
5841
 
5842
5842
  // src/bin/agt.ts
5843
- var cliVersion2 = true ? "0.28.236" : "dev";
5843
+ var cliVersion2 = true ? "0.28.237" : "dev";
5844
5844
  var program = new Command();
5845
5845
  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");
5846
5846
  program.hook("preAction", async (thisCommand, actionCommand) => {
@@ -5720,7 +5720,7 @@ function requireHost() {
5720
5720
  }
5721
5721
 
5722
5722
  // src/lib/api-client.ts
5723
- var agtCliVersion = true ? "0.28.236" : "dev";
5723
+ var agtCliVersion = true ? "0.28.237" : "dev";
5724
5724
  var lastConfigHash = null;
5725
5725
  function setConfigHash(hash) {
5726
5726
  lastConfigHash = hash && hash.length > 0 ? hash : null;
@@ -7813,4 +7813,4 @@ export {
7813
7813
  managerInstallSystemUnitCommand,
7814
7814
  managerUninstallSystemUnitCommand
7815
7815
  };
7816
- //# sourceMappingURL=chunk-ND3HG32M.js.map
7816
+ //# sourceMappingURL=chunk-DN4HSL6M.js.map
@@ -37,7 +37,7 @@ import {
37
37
  requireHost,
38
38
  safeWriteJsonAtomic,
39
39
  setConfigHash
40
- } from "../chunk-ND3HG32M.js";
40
+ } from "../chunk-DN4HSL6M.js";
41
41
  import {
42
42
  getProjectDir as getProjectDir2,
43
43
  getReadyTasks,
@@ -3416,6 +3416,74 @@ async function execFilePromiseLong(cmd, args, opts) {
3416
3416
  });
3417
3417
  }
3418
3418
 
3419
+ // src/lib/manager/restart-timing.ts
3420
+ var pendingRequested = /* @__PURE__ */ new Map();
3421
+ var tracks = /* @__PURE__ */ new Map();
3422
+ var REQUESTED_TTL_MS = 5 * 6e4;
3423
+ function fmtMs(ms) {
3424
+ return `${Math.round(ms)}ms`;
3425
+ }
3426
+ function noteRestartRequested(codeName, requestedAtIso, now = Date.now()) {
3427
+ const requestedAtMs = Date.parse(requestedAtIso);
3428
+ if (Number.isNaN(requestedAtMs)) return;
3429
+ pendingRequested.set(codeName, { requestedAtMs, notedAtMs: now });
3430
+ }
3431
+ function beginRestartTiming(codeName, opts, log2, now = Date.now()) {
3432
+ const pending = pendingRequested.get(codeName);
3433
+ pendingRequested.delete(codeName);
3434
+ const requestedAtMs = pending && now - pending.notedAtMs <= REQUESTED_TTL_MS ? pending.requestedAtMs : null;
3435
+ tracks.set(codeName, {
3436
+ reason: opts.reason,
3437
+ requestedAtMs,
3438
+ startedAtMs: now,
3439
+ injectDelayMs: opts.injectDelayMs,
3440
+ delivered: opts.delivered,
3441
+ stopAtMs: null
3442
+ });
3443
+ const parts = [
3444
+ `reason="${opts.reason}"`,
3445
+ `delivered=${opts.delivered === null ? "unknown" : opts.delivered}`,
3446
+ `injectDelayMs=${opts.injectDelayMs ?? "n/a"}`
3447
+ ];
3448
+ if (requestedAtMs !== null) {
3449
+ parts.push(`pickup=${fmtMs(now - requestedAtMs)} (request->render)`);
3450
+ }
3451
+ log2(`[restart-timing] '${codeName}' begin ${parts.join(" ")}`);
3452
+ }
3453
+ function markRestartStopped(codeName, log2, now = Date.now()) {
3454
+ const track = tracks.get(codeName);
3455
+ if (!track) return;
3456
+ track.stopAtMs = now;
3457
+ log2(
3458
+ `[restart-timing] '${codeName}' stop +${fmtMs(now - track.startedAtMs)} (schedule->stop; inject/gate delay)`
3459
+ );
3460
+ }
3461
+ function finishRestartTiming(codeName, outcome, detail, log2, now = Date.now()) {
3462
+ const track = tracks.get(codeName);
3463
+ if (!track) return;
3464
+ tracks.delete(codeName);
3465
+ const originMs = track.requestedAtMs ?? track.startedAtMs;
3466
+ const originLabel = track.requestedAtMs !== null ? "request->tools-live" : "schedule->tools-live";
3467
+ const totalMs = now - originMs;
3468
+ const stopToBound = track.stopAtMs !== null ? now - track.stopAtMs : null;
3469
+ const suffix = detail ? ` (${detail})` : "";
3470
+ if (outcome === "tools-bound") {
3471
+ const boundPart = stopToBound !== null ? `+${fmtMs(stopToBound)} (stop->bound: respawn + MCP bind)` : `(no stop observed)`;
3472
+ log2(
3473
+ `[restart-timing] '${codeName}' tools-bound ${boundPart} \u2014 total ${fmtMs(totalMs)} (${originLabel})${suffix}`
3474
+ );
3475
+ } else {
3476
+ const boundPart = stopToBound !== null ? `+${fmtMs(stopToBound)} since stop` : `(no stop observed)`;
3477
+ log2(
3478
+ `[restart-timing] '${codeName}' FAILED to bind ${boundPart} \u2014 total ${fmtMs(totalMs)} (${track.requestedAtMs !== null ? "request" : "schedule"}->give-up)${suffix}`
3479
+ );
3480
+ }
3481
+ }
3482
+ function clearRestartTiming(codeName) {
3483
+ tracks.delete(codeName);
3484
+ pendingRequested.delete(codeName);
3485
+ }
3486
+
3419
3487
  // src/lib/manager/model.ts
3420
3488
  function resolveModelChain(refreshData) {
3421
3489
  const agent = refreshData.agent;
@@ -5975,6 +6043,7 @@ function scheduleSessionRestart(codeName, delayMs, reason, breakerReason = "hot-
5975
6043
  }
5976
6044
  }
5977
6045
  stopPersistentSession(codeName, log);
6046
+ markRestartStopped(codeName, log);
5978
6047
  runningMcpHashes.delete(codeName);
5979
6048
  recordRestartForBreaker(codeName, breakerReason);
5980
6049
  log(`[hot-reload] Session stopped for '${codeName}' \u2014 will respawn with ${reason}`);
@@ -5991,6 +6060,7 @@ function scheduleSessionRestart(codeName, delayMs, reason, breakerReason = "hot-
5991
6060
  }
5992
6061
  function cancelPendingSessionRestart(codeName) {
5993
6062
  pendingRestartVerifications.delete(codeName);
6063
+ clearRestartTiming(codeName);
5994
6064
  const existing = pendingSessionRestarts.get(codeName);
5995
6065
  if (!existing) return;
5996
6066
  clearTimeout(existing.timer);
@@ -6015,6 +6085,7 @@ function verifyPendingRestarts(now) {
6015
6085
  case "verified":
6016
6086
  pendingRestartVerifications.delete(codeName);
6017
6087
  log(`[restart-verify] '${codeName}' respawned healthy after MCP change \u2014 tools bound (ENG-6174)`);
6088
+ finishRestartTiming(codeName, "tools-bound", void 0, log, now);
6018
6089
  break;
6019
6090
  case "waiting":
6020
6091
  break;
@@ -6024,6 +6095,7 @@ function verifyPendingRestarts(now) {
6024
6095
  log(
6025
6096
  `[restart-verify] ERROR '${codeName}' did NOT respawn healthy after ${outcome.attempt} attempts following an MCP change \u2014 the live session may be stuck on its pre-restart tools. Check session health / manager.log; a manual session restart may be required (ENG-6174)`
6026
6097
  );
6098
+ finishRestartTiming(codeName, "failed", `${outcome.attempt} verify attempts`, log, now);
6027
6099
  if (shouldRemediateUnverifiedRestart(outcome, {
6028
6100
  enabled: bindRemediationEnabled(),
6029
6101
  breakerTripped: restartBreaker.isTripped(codeName)
@@ -6426,7 +6498,7 @@ var agentRestartTimezoneInputs = /* @__PURE__ */ new Map();
6426
6498
  var lastVersionCheckAt = 0;
6427
6499
  var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
6428
6500
  var lastResponsivenessProbeAt = 0;
6429
- var agtCliVersion = true ? "0.28.236" : "dev";
6501
+ var agtCliVersion = true ? "0.28.237" : "dev";
6430
6502
  function resolveBrewPath(execFileSync2) {
6431
6503
  try {
6432
6504
  const out = execFileSync2("which", ["brew"], { timeout: 5e3 }).toString().trim();
@@ -9154,6 +9226,11 @@ async function processAgent(agent, agentStates) {
9154
9226
  if (!delivered) {
9155
9227
  log(`[hot-reload] Inject notification unconfirmed for '${agent.code_name}' \u2014 proceeding with shorter delay`);
9156
9228
  }
9229
+ beginRestartTiming(
9230
+ agent.code_name,
9231
+ { reason: "new MCP servers", delivered, injectDelayMs: delay },
9232
+ log
9233
+ );
9157
9234
  scheduleSessionRestart(agent.code_name, delay, "new MCP servers");
9158
9235
  }
9159
9236
  }
@@ -10292,6 +10369,9 @@ var restartInFlight = /* @__PURE__ */ new Set();
10292
10369
  function restartReasonNeedsRender(reason) {
10293
10370
  return reason != null && reason !== "manual";
10294
10371
  }
10372
+ function restartReasonStampsTiming(reason) {
10373
+ return reason === "integration-change";
10374
+ }
10295
10375
  async function handleRestartDoorbell(agentId, requestedAt, restartReason) {
10296
10376
  const prev = state6.agents.find((a) => a.agentId === agentId);
10297
10377
  const codeName = prev?.codeName;
@@ -10299,6 +10379,9 @@ async function handleRestartDoorbell(agentId, requestedAt, restartReason) {
10299
10379
  const lastProcessed = prev?.lastRestartProcessedAt ?? null;
10300
10380
  if (lastProcessed != null && Date.parse(lastProcessed) >= Date.parse(requestedAt)) return;
10301
10381
  if (restartReasonNeedsRender(restartReason)) {
10382
+ if (restartReasonStampsTiming(restartReason)) {
10383
+ noteRestartRequested(codeName, requestedAt);
10384
+ }
10302
10385
  triggerEarlyPoll(`config-change reload for '${codeName}' (reason=${restartReason})`);
10303
10386
  return;
10304
10387
  }