@integrity-labs/agt-cli 0.28.981 → 0.28.982
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-
|
|
43
|
+
} from "../chunk-CD42ZALM.js";
|
|
44
44
|
import {
|
|
45
45
|
getProjectDir,
|
|
46
46
|
isSessionResumeDisabled,
|
|
@@ -5472,7 +5472,7 @@ import { execFileSync, execSync } from "child_process";
|
|
|
5472
5472
|
import { existsSync as existsSync11, realpathSync as realpathSync2 } from "fs";
|
|
5473
5473
|
import chalk18 from "chalk";
|
|
5474
5474
|
import ora16 from "ora";
|
|
5475
|
-
var cliVersion = true ? "0.28.
|
|
5475
|
+
var cliVersion = true ? "0.28.982" : "dev";
|
|
5476
5476
|
async function fetchLatestVersion() {
|
|
5477
5477
|
const host2 = getHost();
|
|
5478
5478
|
if (!host2) return null;
|
|
@@ -6732,7 +6732,7 @@ function handleError(err) {
|
|
|
6732
6732
|
}
|
|
6733
6733
|
|
|
6734
6734
|
// src/bin/agt.ts
|
|
6735
|
-
var cliVersion2 = true ? "0.28.
|
|
6735
|
+
var cliVersion2 = true ? "0.28.982" : "dev";
|
|
6736
6736
|
var program = new Command();
|
|
6737
6737
|
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");
|
|
6738
6738
|
program.hook("preAction", async (thisCommand, actionCommand) => {
|
|
@@ -6967,7 +6967,7 @@ function exchangeFailureKind(err) {
|
|
|
6967
6967
|
}
|
|
6968
6968
|
|
|
6969
6969
|
// src/lib/api-client.ts
|
|
6970
|
-
var agtCliVersion = true ? "0.28.
|
|
6970
|
+
var agtCliVersion = true ? "0.28.982" : "dev";
|
|
6971
6971
|
var lastConfigHash = null;
|
|
6972
6972
|
function setConfigHash(hash) {
|
|
6973
6973
|
lastConfigHash = hash && hash.length > 0 ? hash : null;
|
|
@@ -11709,4 +11709,4 @@ export {
|
|
|
11709
11709
|
managerInstallSystemUnitCommand,
|
|
11710
11710
|
managerUninstallSystemUnitCommand
|
|
11711
11711
|
};
|
|
11712
|
-
//# sourceMappingURL=chunk-
|
|
11712
|
+
//# sourceMappingURL=chunk-CD42ZALM.js.map
|
|
@@ -63,7 +63,7 @@ import {
|
|
|
63
63
|
safeWriteJsonAtomic,
|
|
64
64
|
setConfigHash,
|
|
65
65
|
tripClass
|
|
66
|
-
} from "../chunk-
|
|
66
|
+
} from "../chunk-CD42ZALM.js";
|
|
67
67
|
import {
|
|
68
68
|
getProjectDir as getProjectDir2,
|
|
69
69
|
getReadyTasks,
|
|
@@ -6461,6 +6461,16 @@ import { join as join30 } from "path";
|
|
|
6461
6461
|
function claudeDeviceStatePath(env = process.env) {
|
|
6462
6462
|
return join30(env.HOME?.trim() || homedir13(), ".claude.json");
|
|
6463
6463
|
}
|
|
6464
|
+
function probeClaudeDeviceStatePresence(path = claudeDeviceStatePath()) {
|
|
6465
|
+
try {
|
|
6466
|
+
return statSync9(path).isFile() ? { present: true } : { present: false, reason: "not-a-file" };
|
|
6467
|
+
} catch (err) {
|
|
6468
|
+
return {
|
|
6469
|
+
present: false,
|
|
6470
|
+
reason: err?.code === "ENOENT" ? "missing" : "unreadable"
|
|
6471
|
+
};
|
|
6472
|
+
}
|
|
6473
|
+
}
|
|
6464
6474
|
function checkClaudeDeviceState(path = claudeDeviceStatePath()) {
|
|
6465
6475
|
try {
|
|
6466
6476
|
if (!statSync9(path).isFile()) return { usable: false, reason: "not-a-file" };
|
|
@@ -6489,10 +6499,18 @@ function checkClaudeDeviceState(path = claudeDeviceStatePath()) {
|
|
|
6489
6499
|
return { usable: true };
|
|
6490
6500
|
}
|
|
6491
6501
|
var DeviceStateRotationGate = class {
|
|
6492
|
-
constructor(check = () => checkClaudeDeviceState()) {
|
|
6502
|
+
constructor(check = () => checkClaudeDeviceState(), probe = () => probeClaudeDeviceStatePresence()) {
|
|
6493
6503
|
this.check = check;
|
|
6504
|
+
this.probe = probe;
|
|
6494
6505
|
}
|
|
6495
6506
|
held = /* @__PURE__ */ new Map();
|
|
6507
|
+
/**
|
|
6508
|
+
* ENG-10730: when the CHEAP probe first saw the file gone with nothing held.
|
|
6509
|
+
* Separate from `held`, which records when each agent's rotation was stopped -
|
|
6510
|
+
* in this state no rotation has been stopped at all. Cleared whenever the file
|
|
6511
|
+
* is seen present again, so a later episode gets its own clock.
|
|
6512
|
+
*/
|
|
6513
|
+
unusableSinceMs = null;
|
|
6496
6514
|
/**
|
|
6497
6515
|
* Ask before tearing `codeName`'s session down for a planned rotation.
|
|
6498
6516
|
* Returns `ready: true` when the respawn can start; otherwise the rotation must
|
|
@@ -6510,22 +6528,62 @@ var DeviceStateRotationGate = class {
|
|
|
6510
6528
|
return { ready: false, reason: verdict.reason, firstHold };
|
|
6511
6529
|
}
|
|
6512
6530
|
/**
|
|
6513
|
-
* The value for the heartbeat.
|
|
6514
|
-
*
|
|
6515
|
-
*
|
|
6516
|
-
*
|
|
6531
|
+
* The value for the heartbeat.
|
|
6532
|
+
*
|
|
6533
|
+
* ENG-10730. This used to open with `if (this.held.size === 0) return null;` -
|
|
6534
|
+
* it returned the affirmative all-clear WITHOUT LOOKING, and the docblock
|
|
6535
|
+
* defended that as "a healthy host pays no file read per heartbeat". The
|
|
6536
|
+
* saving was real and so was the hole: a host whose `~/.claude.json` had been
|
|
6537
|
+
* unlinked, and which had not happened to attempt a rotation since, reported
|
|
6538
|
+
* `null` every 30 seconds while already doomed. Nothing asked until some
|
|
6539
|
+
* agent's rollover did, which on ENG-10724 was the maintenance window - i.e.
|
|
6540
|
+
* the moment the agents were lost. The host was discovered one whole host at a
|
|
6541
|
+
* time, at whatever hour its window fell.
|
|
6542
|
+
*
|
|
6543
|
+
* So the heartbeat now always looks, and pays for it with ONE `statSync` -
|
|
6544
|
+
* `probeClaudeDeviceStatePresence`, no read, no parse. The original perf
|
|
6545
|
+
* objection is answered rather than overridden: what was rejected in PR #6250
|
|
6546
|
+
* was a multi-MB synchronous `JSON.parse` on every healthy host's event loop,
|
|
6547
|
+
* and that is still not happening here.
|
|
6548
|
+
*
|
|
6549
|
+
* THE TWO PATHS ARE NOT SYMMETRIC, AND THAT IS DELIBERATE.
|
|
6550
|
+
* - Something held: the FULL check, exactly as before. A hold must only clear
|
|
6551
|
+
* on a genuinely usable file, so a present-but-corrupt one cannot read as a
|
|
6552
|
+
* recovery and release a rotation onto a host that still cannot respawn.
|
|
6553
|
+
* - Nothing held: the CHEAP probe. It can only report that the file has GONE,
|
|
6554
|
+
* never that one is well - so it can raise this warning and it can clear
|
|
6555
|
+
* this warning, but it is never allowed to clear a hold.
|
|
6556
|
+
*
|
|
6557
|
+
* `deferred_agents: []` with a reason is therefore a THIRD state, distinct
|
|
6558
|
+
* from both `null` and a hold: the file is unusable and nothing has been
|
|
6559
|
+
* stopped yet. The API must not describe that as a hold - see
|
|
6560
|
+
* `summariseDeviceStateBlock`, which separates the two so the alert does not
|
|
6561
|
+
* claim the manager is holding work it is not.
|
|
6517
6562
|
*/
|
|
6518
|
-
heartbeatField() {
|
|
6519
|
-
if (this.held.size
|
|
6520
|
-
|
|
6521
|
-
|
|
6522
|
-
|
|
6563
|
+
heartbeatField(nowMs = Date.now()) {
|
|
6564
|
+
if (this.held.size > 0) {
|
|
6565
|
+
const verdict = this.check();
|
|
6566
|
+
if (verdict.usable) {
|
|
6567
|
+
this.held.clear();
|
|
6568
|
+
this.unusableSinceMs = null;
|
|
6569
|
+
return null;
|
|
6570
|
+
}
|
|
6571
|
+
return {
|
|
6572
|
+
reason: verdict.reason,
|
|
6573
|
+
deferred_agents: [...this.held.keys()].sort(),
|
|
6574
|
+
blocked_since: new Date(Math.min(...this.held.values())).toISOString()
|
|
6575
|
+
};
|
|
6576
|
+
}
|
|
6577
|
+
const presence = this.probe();
|
|
6578
|
+
if (presence.present) {
|
|
6579
|
+
this.unusableSinceMs = null;
|
|
6523
6580
|
return null;
|
|
6524
6581
|
}
|
|
6582
|
+
if (this.unusableSinceMs === null) this.unusableSinceMs = nowMs;
|
|
6525
6583
|
return {
|
|
6526
|
-
reason:
|
|
6527
|
-
deferred_agents: [
|
|
6528
|
-
blocked_since: new Date(
|
|
6584
|
+
reason: presence.reason,
|
|
6585
|
+
deferred_agents: [],
|
|
6586
|
+
blocked_since: new Date(this.unusableSinceMs).toISOString()
|
|
6529
6587
|
};
|
|
6530
6588
|
}
|
|
6531
6589
|
/** For tests and logs. */
|
|
@@ -13955,7 +14013,7 @@ var agentRestartTimezoneInputs = /* @__PURE__ */ new Map();
|
|
|
13955
14013
|
var lastVersionCheckAt = 0;
|
|
13956
14014
|
var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
|
|
13957
14015
|
var lastResponsivenessProbeAt = 0;
|
|
13958
|
-
var agtCliVersion = true ? "0.28.
|
|
14016
|
+
var agtCliVersion = true ? "0.28.982" : "dev";
|
|
13959
14017
|
function resolveBrewPath(execFileSync2) {
|
|
13960
14018
|
try {
|
|
13961
14019
|
const out = execFileSync2("which", ["brew"], { timeout: 5e3 }).toString().trim();
|