@integrity-labs/agt-cli 0.28.823 → 0.28.825

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.
@@ -16,7 +16,7 @@ import {
16
16
  parseEnvIntegrations,
17
17
  shellQuote,
18
18
  summarizeUnanswerablePane
19
- } from "./chunk-2MB3SP6H.js";
19
+ } from "./chunk-2DT4VGWU.js";
20
20
  import {
21
21
  BIND_FAILURE_QUARANTINE_THRESHOLD,
22
22
  INTEGRATIONS_SECTION_END,
@@ -71,7 +71,7 @@ import {
71
71
  sessionTranscriptDir,
72
72
  worseConnectivityOutcome,
73
73
  wrapScheduledTaskPrompt
74
- } from "./chunk-3QZUOZUZ.js";
74
+ } from "./chunk-PVPLNARY.js";
75
75
  import {
76
76
  parsePsRows
77
77
  } from "./chunk-XWVM4KPK.js";
@@ -6523,7 +6523,7 @@ function exchangeFailureKind(err) {
6523
6523
  }
6524
6524
 
6525
6525
  // src/lib/api-client.ts
6526
- var agtCliVersion = true ? "0.28.823" : "dev";
6526
+ var agtCliVersion = true ? "0.28.825" : "dev";
6527
6527
  var lastConfigHash = null;
6528
6528
  function setConfigHash(hash) {
6529
6529
  lastConfigHash = hash && hash.length > 0 ? hash : null;
@@ -10830,4 +10830,4 @@ export {
10830
10830
  managerInstallSystemUnitCommand,
10831
10831
  managerUninstallSystemUnitCommand
10832
10832
  };
10833
- //# sourceMappingURL=chunk-5PFBPGBO.js.map
10833
+ //# sourceMappingURL=chunk-QICBWFRI.js.map
@@ -0,0 +1,19 @@
1
+ // src/lib/claude-code-brew-result.ts
2
+ var NOT_INSTALLED_RE = /is not installed/i;
3
+ function caskPresenceFromListResult(r) {
4
+ if (r.code === 0) return "present";
5
+ return NOT_INSTALLED_RE.test(`${r.stdout}
6
+ ${r.stderr}`) ? "absent" : "unknown";
7
+ }
8
+ function classifyBrewUpgradeResult(r) {
9
+ const combined = `${r.stdout}
10
+ ${r.stderr}`;
11
+ const noWorkNeeded = combined.includes("already installed") || combined.includes("up-to-date") || combined.includes("not upgraded");
12
+ if (r.code === 0) return noWorkNeeded ? "already-current" : "upgraded";
13
+ return noWorkNeeded ? "already-current" : "failed";
14
+ }
15
+ export {
16
+ caskPresenceFromListResult,
17
+ classifyBrewUpgradeResult
18
+ };
19
+ //# sourceMappingURL=claude-code-brew-result-3A4E7GTC.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lib/claude-code-brew-result.ts"],"sourcesContent":["// ENG-10039: how to read the result of the LEGACY `brew --cask claude-code`\n// path, extracted so it can be tested without importing manager-worker.\n//\n// Same reason `claude-code-upgrade-throttle.ts` was split out under ENG-6418:\n// manager-worker is a 13k-line import graph, evaluating it inside a test's\n// budget flakes under parallel load, so the load-bearing judgement lives here\n// and manager-worker calls it.\n//\n// WHAT WENT WRONG, and it is why this is a module rather than two inline\n// conditionals. On every host provisioned since Claude Code moved to\n// `npm install -g @anthropic-ai/claude-code` (host-bootstrap.ts), there is no\n// Homebrew cask. The manager ran `brew upgrade --cask claude-code` anyway,\n// because its only precondition was \"is there a `claude` on PATH\" — and there\n// is one, at `/usr/bin/claude`, put there by npm. So the upgrade failed with\n// `Error: Cask 'claude-code' is not installed.` every day, on 7 of 10 hosts\n// measured, oldest at least 9 days (the full retained-log window on agt-aws-1:\n// 9 attempts, 9 failures, zero successes).\n//\n// It was invisible because it is only a log line: no alert kind covers it.\n\n/**\n * What `brew list --cask claude-code` actually told us.\n *\n * THREE STATES, NOT TWO, and the third is the one that matters (CodeRabbit on\n * #5616). `runAsync` RESOLVES with a non-zero exit code rather than rejecting,\n * and Homebrew uses non-zero exits for operational errors too — a network\n * failure, a lock, a broken tap. Mapping every non-zero code to `absent` would\n * read a transient brew error as \"this host has no cask\", skip the upgrade, and\n * because the throttle marker is stamped BEFORE the probe, suppress any retry\n * for ~24h. On a genuine cask host that is a silent missed upgrade, which is\n * the same invisible-skip shape this whole ticket exists to remove.\n *\n * So `absent` is claimed ONLY on brew's specific not-installed message.\n * Everything else non-zero is `unknown`: skip this cycle, say so, try again on\n * the next in-window poll.\n */\nexport type CaskPresence = 'present' | 'absent' | 'unknown';\n\n/**\n * Brew's wording for a cask that is not installed, e.g.\n * Error: Cask 'claude-code' is not installed.\n * Matched loosely on the stable half of the sentence rather than the whole\n * line, because the cask name is interpolated and brew has moved the\n * surrounding punctuation before.\n */\nconst NOT_INSTALLED_RE = /is not installed/i;\n\nexport function caskPresenceFromListResult(r: {\n code: number;\n stdout: string;\n stderr: string;\n}): CaskPresence {\n if (r.code === 0) return 'present';\n return NOT_INSTALLED_RE.test(`${r.stdout}\\n${r.stderr}`) ? 'absent' : 'unknown';\n}\n\nexport type BrewUpgradeVerdict = 'upgraded' | 'already-current' | 'failed';\n\n/**\n * Classify a `brew upgrade --cask claude-code` run.\n *\n * THE NON-ZERO-BUT-FINE CASE IS REAL, not defensive padding: brew exits\n * non-zero while printing `already installed` / `up-to-date` / `not upgraded`\n * for a cask that needs no work. Treating that as a failure would have made\n * this monitor cry wolf on exactly the hosts where nothing is wrong, and a\n * version check that cries wolf gets muted — after which it is worth less than\n * nothing, because everyone now believes the case is covered.\n *\n * Both streams are searched because brew is inconsistent about which one\n * carries the notice, and the auto-update banner interleaves them.\n */\nexport function classifyBrewUpgradeResult(r: {\n code: number;\n stdout: string;\n stderr: string;\n}): BrewUpgradeVerdict {\n const combined = `${r.stdout}\\n${r.stderr}`;\n const noWorkNeeded =\n combined.includes('already installed') ||\n combined.includes('up-to-date') ||\n combined.includes('not upgraded');\n\n if (r.code === 0) return noWorkNeeded ? 'already-current' : 'upgraded';\n return noWorkNeeded ? 'already-current' : 'failed';\n}\n"],"mappings":";AA6CA,IAAM,mBAAmB;AAElB,SAAS,2BAA2B,GAI1B;AACf,MAAI,EAAE,SAAS,EAAG,QAAO;AACzB,SAAO,iBAAiB,KAAK,GAAG,EAAE,MAAM;AAAA,EAAK,EAAE,MAAM,EAAE,IAAI,WAAW;AACxE;AAiBO,SAAS,0BAA0B,GAInB;AACrB,QAAM,WAAW,GAAG,EAAE,MAAM;AAAA,EAAK,EAAE,MAAM;AACzC,QAAM,eACJ,SAAS,SAAS,mBAAmB,KACrC,SAAS,SAAS,YAAY,KAC9B,SAAS,SAAS,cAAc;AAElC,MAAI,EAAE,SAAS,EAAG,QAAO,eAAe,oBAAoB;AAC5D,SAAO,eAAe,oBAAoB;AAC5C;","names":[]}
@@ -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-XBCAIURL.js");
103
+ const { resolveClaudeBinary } = await import("./persistent-session-2Y4O3COI.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-CYO2Z5MK.js.map
376
+ //# sourceMappingURL=claude-pair-runtime-5QM5OTAZ.js.map
@@ -59,7 +59,7 @@ import {
59
59
  safeWriteJsonAtomic,
60
60
  setConfigHash,
61
61
  tripClass
62
- } from "../chunk-5PFBPGBO.js";
62
+ } from "../chunk-QICBWFRI.js";
63
63
  import {
64
64
  getProjectDir as getProjectDir2,
65
65
  getReadyTasks,
@@ -124,7 +124,7 @@ import {
124
124
  takeZombieDetection,
125
125
  toOpencodeModel,
126
126
  writeEgressAllowlist
127
- } from "../chunk-2MB3SP6H.js";
127
+ } from "../chunk-2DT4VGWU.js";
128
128
  import {
129
129
  ACCOUNT_ENFORCEMENT_MARKER_FILENAME,
130
130
  AnchorSessionClient,
@@ -216,7 +216,7 @@ import {
216
216
  subagentActivityAgeSeconds,
217
217
  sumTranscriptUsageInWindow,
218
218
  transcriptActivityAgeSeconds
219
- } from "../chunk-3QZUOZUZ.js";
219
+ } from "../chunk-PVPLNARY.js";
220
220
  import {
221
221
  reapOrphanChannelMcps
222
222
  } from "../chunk-XWVM4KPK.js";
@@ -12919,7 +12919,7 @@ var pendingDayRolloverReset = /* @__PURE__ */ new Set();
12919
12919
  var dayRolloverInboundHold = /* @__PURE__ */ new Map();
12920
12920
  var INBOUND_HOLD_EPISODE_GAP_MS = 12e4;
12921
12921
  async function channelInboundActivityAgeSecondsFor(codeName) {
12922
- const { newestPendingInboundActivityMtimeMs } = await import("../responsiveness-probe-R6RPL2OK.js");
12922
+ const { newestPendingInboundActivityMtimeMs } = await import("../responsiveness-probe-OGFPDMFN.js");
12923
12923
  const newest = newestPendingInboundActivityMtimeMs(dirname10(paneLogPath(codeName)));
12924
12924
  if (newest === null) return null;
12925
12925
  return Math.max(0, Math.floor((Date.now() - newest) / 1e3));
@@ -13587,7 +13587,7 @@ var agentRestartTimezoneInputs = /* @__PURE__ */ new Map();
13587
13587
  var lastVersionCheckAt = 0;
13588
13588
  var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
13589
13589
  var lastResponsivenessProbeAt = 0;
13590
- var agtCliVersion = true ? "0.28.823" : "dev";
13590
+ var agtCliVersion = true ? "0.28.825" : "dev";
13591
13591
  function resolveBrewPath(execFileSync2) {
13592
13592
  try {
13593
13593
  const out = execFileSync2("which", ["brew"], { timeout: 5e3 }).toString().trim();
@@ -14073,20 +14073,43 @@ async function maybeUpgradeClaudeCode() {
14073
14073
  }
14074
14074
  return runAsync(brewPath, args, opts);
14075
14075
  };
14076
+ let proceedToUpgrade = false;
14077
+ let brewResult;
14078
+ try {
14079
+ brewResult = await import("../claude-code-brew-result-3A4E7GTC.js");
14080
+ const caskProbe = await runBrew(["list", "--cask", "claude-code"], { timeout: 6e4 });
14081
+ const presence = brewResult.caskPresenceFromListResult(caskProbe);
14082
+ proceedToUpgrade = presence === "present";
14083
+ if (presence === "absent") {
14084
+ log(
14085
+ "Claude Code is not installed as a Homebrew cask on this host, so the legacy brew upgrade path has nothing to upgrade \u2014 skipping it (ENG-10039). This is not an error. Where Claude Code was installed via npm, claude-code-updater (ENG-5672) keeps it current."
14086
+ );
14087
+ } else if (presence === "unknown") {
14088
+ log(
14089
+ `Claude Code cask probe inconclusive (exit ${caskProbe.code}), skipping this cycle (ENG-10039): ${(caskProbe.stderr || caskProbe.stdout).trim().slice(0, 200)}`
14090
+ );
14091
+ }
14092
+ } catch (err) {
14093
+ log(
14094
+ `Claude Code cask probe failed, skipping this cycle (ENG-10039): ${err instanceof Error ? err.message : String(err)}`
14095
+ );
14096
+ } finally {
14097
+ if (!proceedToUpgrade) claudeCodeUpgradeInFlight = false;
14098
+ }
14099
+ if (!proceedToUpgrade || !brewResult) return;
14100
+ const { classifyBrewUpgradeResult } = brewResult;
14076
14101
  log(`Checking for Claude Code updates in background${isRoot ? " (as ec2-user via sudo)" : ""}...`);
14077
14102
  runBrew(["upgrade", "--cask", "claude-code"], { timeout: 12e4 }).then((r) => {
14078
- const combined = `${r.stdout}
14079
- ${r.stderr}`;
14080
- if (r.code === 0) {
14081
- if (combined.includes("already installed") || combined.includes("up-to-date")) {
14103
+ switch (classifyBrewUpgradeResult(r)) {
14104
+ case "already-current":
14082
14105
  log("Claude Code is already up to date");
14083
- } else {
14106
+ break;
14107
+ case "upgraded":
14084
14108
  log("Claude Code upgraded successfully (will apply on next session start)");
14085
- }
14086
- } else if (combined.includes("already installed") || combined.includes("up-to-date") || combined.includes("not upgraded")) {
14087
- log("Claude Code is already up to date");
14088
- } else {
14089
- log(`Claude Code upgrade failed (exit ${r.code}): ${r.stderr.trim() || r.stdout.trim()}`);
14109
+ break;
14110
+ case "failed":
14111
+ log(`Claude Code upgrade failed (exit ${r.code}): ${r.stderr.trim() || r.stdout.trim()}`);
14112
+ break;
14090
14113
  }
14091
14114
  }).catch((err) => log(`Claude Code upgrade failed: ${err.message}`)).finally(() => {
14092
14115
  claudeCodeUpgradeInFlight = false;
@@ -15154,7 +15177,7 @@ function flushRestartedAgentDiagnostics(hostId, codeNames) {
15154
15177
  if (codeNames.length === 0) return;
15155
15178
  void (async () => {
15156
15179
  try {
15157
- const { collectDiagnostics } = await import("../persistent-session-XBCAIURL.js");
15180
+ const { collectDiagnostics } = await import("../persistent-session-2Y4O3COI.js");
15158
15181
  await api.post("/host/heartbeat", {
15159
15182
  host_id: hostId,
15160
15183
  agent_diagnostics: collectDiagnostics(codeNames, quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor)
@@ -15295,7 +15318,7 @@ async function pollCycleInner() {
15295
15318
  }
15296
15319
  try {
15297
15320
  const { detectHostSecurity } = await import("../host-security-6PDFG7F5.js");
15298
- const { collectDiagnostics } = await import("../persistent-session-XBCAIURL.js");
15321
+ const { collectDiagnostics } = await import("../persistent-session-2Y4O3COI.js");
15299
15322
  const diagCodeNames = [...agentState.persistentSessionAgents];
15300
15323
  const agentDiagnostics = diagCodeNames.length > 0 ? collectDiagnostics(diagCodeNames, quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor) : void 0;
15301
15324
  let tailscaleHostname;
@@ -15464,7 +15487,7 @@ async function pollCycleInner() {
15464
15487
  collectPanelessActivityProbes,
15465
15488
  getResponsivenessIntervalMs,
15466
15489
  occupancyQualificationClassifications
15467
- } = await import("../responsiveness-probe-R6RPL2OK.js");
15490
+ } = await import("../responsiveness-probe-OGFPDMFN.js");
15468
15491
  const probeIntervalMs = getResponsivenessIntervalMs();
15469
15492
  if (now - lastResponsivenessProbeAt > probeIntervalMs) {
15470
15493
  const probeCodeNames = [...agentState.persistentSessionAgents];
@@ -15581,7 +15604,7 @@ async function pollCycleInner() {
15581
15604
  collectResponsivenessProbes,
15582
15605
  livePendingInboundOldestAgeSeconds,
15583
15606
  parkPendingInbound
15584
- } = await import("../responsiveness-probe-R6RPL2OK.js");
15607
+ } = await import("../responsiveness-probe-OGFPDMFN.js");
15585
15608
  const { getProjectDir: wedgeProjectDir } = await import("../scheduler-engine-NDP36U7O.js");
15586
15609
  const wedgeNow = /* @__PURE__ */ new Date();
15587
15610
  const liveAgents = agentState.persistentSessionAgents;
@@ -15737,7 +15760,7 @@ async function pollCycleInner() {
15737
15760
  }
15738
15761
  try {
15739
15762
  const { scrapeMcpFailedBannerCount } = await import("../pane-mcp-banner-scraper-JA437JIB.js");
15740
- const { probeSessionAuth } = await import("../session-auth-dead-EMKNS23O.js");
15763
+ const { probeSessionAuth } = await import("../session-auth-dead-UDG6GY3U.js");
15741
15764
  const observations = [];
15742
15765
  const pendingCacheCommits = [];
15743
15766
  const modelApiErrorReportingOn = hostFlagStore().getBoolean("model-api-error-reporting");
@@ -19939,7 +19962,7 @@ async function handleRestartDoorbell(agentId, requestedAt, restartReason) {
19939
19962
  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}`));
19940
19963
  void (async () => {
19941
19964
  try {
19942
- const { collectDiagnostics } = await import("../persistent-session-XBCAIURL.js");
19965
+ const { collectDiagnostics } = await import("../persistent-session-2Y4O3COI.js");
19943
19966
  await api.post("/host/heartbeat", {
19944
19967
  host_id: hostId,
19945
19968
  agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor)
@@ -19985,7 +20008,7 @@ async function respawnAgentAfterMcpStop(codeName, reason) {
19985
20008
  }
19986
20009
  try {
19987
20010
  const hostId = await getHostId();
19988
- const { collectDiagnostics } = await import("../persistent-session-XBCAIURL.js");
20011
+ const { collectDiagnostics } = await import("../persistent-session-2Y4O3COI.js");
19989
20012
  await api.post("/host/heartbeat", {
19990
20013
  host_id: hostId,
19991
20014
  agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor)
@@ -20621,7 +20644,7 @@ async function processClaudePairSessions(agents) {
20621
20644
  killPairSession,
20622
20645
  pairTmuxSession,
20623
20646
  finalizeClaudePairOnboarding
20624
- } = await import("../claude-pair-runtime-CYO2Z5MK.js");
20647
+ } = await import("../claude-pair-runtime-5QM5OTAZ.js");
20625
20648
  for (const pairId of pendingResp.cancelled_pair_ids ?? []) {
20626
20649
  log(`[claude-pair] sweeping orphan tmux session for pair ${pairId.slice(0, 8)}`);
20627
20650
  const killed = await killPairSession(pairTmuxSession(pairId));