@integrity-labs/agt-cli 0.28.1139 → 0.28.1141
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-6WHFJSXT.js";
|
|
44
44
|
import {
|
|
45
45
|
getProjectDir,
|
|
46
46
|
isSessionResumeDisabled,
|
|
@@ -5474,7 +5474,7 @@ import { execFileSync, execSync } from "child_process";
|
|
|
5474
5474
|
import { existsSync as existsSync11, realpathSync as realpathSync2 } from "fs";
|
|
5475
5475
|
import chalk18 from "chalk";
|
|
5476
5476
|
import ora16 from "ora";
|
|
5477
|
-
var cliVersion = true ? "0.28.
|
|
5477
|
+
var cliVersion = true ? "0.28.1141" : "dev";
|
|
5478
5478
|
async function fetchLatestVersion() {
|
|
5479
5479
|
const host2 = getHost();
|
|
5480
5480
|
if (!host2) return null;
|
|
@@ -6734,7 +6734,7 @@ function handleError(err) {
|
|
|
6734
6734
|
}
|
|
6735
6735
|
|
|
6736
6736
|
// src/bin/agt.ts
|
|
6737
|
-
var cliVersion2 = true ? "0.28.
|
|
6737
|
+
var cliVersion2 = true ? "0.28.1141" : "dev";
|
|
6738
6738
|
var program = new Command();
|
|
6739
6739
|
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");
|
|
6740
6740
|
program.hook("preAction", async (thisCommand, actionCommand) => {
|
|
@@ -8076,7 +8076,7 @@ function exchangeFailureKind(err) {
|
|
|
8076
8076
|
}
|
|
8077
8077
|
|
|
8078
8078
|
// src/lib/api-client.ts
|
|
8079
|
-
var agtCliVersion = true ? "0.28.
|
|
8079
|
+
var agtCliVersion = true ? "0.28.1141" : "dev";
|
|
8080
8080
|
var lastConfigHash = null;
|
|
8081
8081
|
function setConfigHash(hash) {
|
|
8082
8082
|
lastConfigHash = hash && hash.length > 0 ? hash : null;
|
|
@@ -13227,4 +13227,4 @@ export {
|
|
|
13227
13227
|
managerInstallSystemUnitCommand,
|
|
13228
13228
|
managerUninstallSystemUnitCommand
|
|
13229
13229
|
};
|
|
13230
|
-
//# sourceMappingURL=chunk-
|
|
13230
|
+
//# sourceMappingURL=chunk-6WHFJSXT.js.map
|
|
@@ -76,7 +76,7 @@ import {
|
|
|
76
76
|
setConfigHash,
|
|
77
77
|
shellGuard,
|
|
78
78
|
tripClass
|
|
79
|
-
} from "../chunk-
|
|
79
|
+
} from "../chunk-6WHFJSXT.js";
|
|
80
80
|
import {
|
|
81
81
|
getProjectDir as getProjectDir2,
|
|
82
82
|
getReadyTasks,
|
|
@@ -343,6 +343,8 @@ var HostNodeConvergence = class {
|
|
|
343
343
|
}
|
|
344
344
|
converged = /* @__PURE__ */ new Set();
|
|
345
345
|
abandoned = /* @__PURE__ */ new Set();
|
|
346
|
+
/** Pins this platform cannot install at all; see {@link recordUnsupported}. */
|
|
347
|
+
unsupported = /* @__PURE__ */ new Set();
|
|
346
348
|
failures = /* @__PURE__ */ new Map();
|
|
347
349
|
retryAfter = /* @__PURE__ */ new Map();
|
|
348
350
|
/**
|
|
@@ -383,6 +385,7 @@ var HostNodeConvergence = class {
|
|
|
383
385
|
this.lastDesired = pin;
|
|
384
386
|
this.converged.clear();
|
|
385
387
|
this.abandoned.clear();
|
|
388
|
+
this.unsupported.clear();
|
|
386
389
|
this.failures.clear();
|
|
387
390
|
this.retryAfter.clear();
|
|
388
391
|
}
|
|
@@ -393,6 +396,7 @@ var HostNodeConvergence = class {
|
|
|
393
396
|
stateOf(pin, now = Date.now()) {
|
|
394
397
|
if (this.converged.has(pin)) return "converged";
|
|
395
398
|
if (this.abandoned.has(pin)) return "abandoned";
|
|
399
|
+
if (this.unsupported.has(pin)) return "unsupported";
|
|
396
400
|
if ((this.retryAfter.get(pin) ?? 0) > now) return "cooling";
|
|
397
401
|
return "ready";
|
|
398
402
|
}
|
|
@@ -447,6 +451,20 @@ var HostNodeConvergence = class {
|
|
|
447
451
|
this.failures.delete(pin);
|
|
448
452
|
this.retryAfter.delete(pin);
|
|
449
453
|
}
|
|
454
|
+
/**
|
|
455
|
+
* The pin cannot be installed on this platform (no `dnf`). Terminal, so it
|
|
456
|
+
* stops further attempts exactly as success does — hammering an impossible
|
|
457
|
+
* install every poll is worse than stopping — but it reports as itself.
|
|
458
|
+
*
|
|
459
|
+
* Carries the same staleness guard as {@link recordSuccess}: a late call for
|
|
460
|
+
* a superseded pin must not write a conclusion about the pin now wanted.
|
|
461
|
+
*/
|
|
462
|
+
recordUnsupported(pin) {
|
|
463
|
+
if (this.lastDesired !== null && pin !== this.lastDesired) return;
|
|
464
|
+
this.unsupported.add(pin);
|
|
465
|
+
this.failures.delete(pin);
|
|
466
|
+
this.retryAfter.delete(pin);
|
|
467
|
+
}
|
|
450
468
|
/**
|
|
451
469
|
* An attempt failed. Returns the resulting state so the caller can log the
|
|
452
470
|
* right thing: 'cooling' means it will retry, 'abandoned' means it will not.
|
|
@@ -488,6 +506,58 @@ var HostNodeConvergence = class {
|
|
|
488
506
|
}
|
|
489
507
|
};
|
|
490
508
|
|
|
509
|
+
// src/lib/host-node-report.ts
|
|
510
|
+
var HOST_NODE_PROBE_INTERVAL_MS = 15 * 60 * 1e3;
|
|
511
|
+
function shouldReprobeHostNode(lastObservedAt, now) {
|
|
512
|
+
if (lastObservedAt === 0) return true;
|
|
513
|
+
return now - lastObservedAt >= HOST_NODE_PROBE_INTERVAL_MS;
|
|
514
|
+
}
|
|
515
|
+
function normalizeReportedNodeVersion(raw) {
|
|
516
|
+
if (raw == null) return null;
|
|
517
|
+
const v = raw.trim().replace(/^v/, "");
|
|
518
|
+
return HOST_NODE_PIN_VERSION_RE.test(v) ? v : null;
|
|
519
|
+
}
|
|
520
|
+
function parsePathNodeVersion(stdout) {
|
|
521
|
+
const m = /^v?(\d+\.\d+\.\d+)$/.exec(stdout.trim());
|
|
522
|
+
return m ? normalizeReportedNodeVersion(m[1]) : null;
|
|
523
|
+
}
|
|
524
|
+
function parseRpmNodeVersion(stdout) {
|
|
525
|
+
return normalizeReportedNodeVersion(stdout.trim());
|
|
526
|
+
}
|
|
527
|
+
var RPM_NODE_QUERY_ARGV = ["-q", "--qf", "%{VERSION}", "nodejs"];
|
|
528
|
+
var PATH_NODE_QUERY_ARGV = ["--version"];
|
|
529
|
+
async function probeOrNull(probe) {
|
|
530
|
+
try {
|
|
531
|
+
return await probe();
|
|
532
|
+
} catch {
|
|
533
|
+
return null;
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
async function probeHostNode(run) {
|
|
537
|
+
const pathVersion = await probeOrNull(async () => {
|
|
538
|
+
const probe = await run("node", [...PATH_NODE_QUERY_ARGV]);
|
|
539
|
+
return probe.code === 0 ? parsePathNodeVersion(probe.stdout) : null;
|
|
540
|
+
});
|
|
541
|
+
const rpmVersion = await probeOrNull(async () => {
|
|
542
|
+
const rpm = await run("rpm", [...RPM_NODE_QUERY_ARGV]);
|
|
543
|
+
return rpm.code === 0 ? parseRpmNodeVersion(rpm.stdout) : null;
|
|
544
|
+
});
|
|
545
|
+
return { pathVersion, rpmVersion };
|
|
546
|
+
}
|
|
547
|
+
function heartbeatHostNodeFields(observation, pin, pinState) {
|
|
548
|
+
if (!observation) return {};
|
|
549
|
+
return {
|
|
550
|
+
host_node_version: normalizeReportedNodeVersion(observation.pathVersion),
|
|
551
|
+
host_node_rpm_version: normalizeReportedNodeVersion(observation.rpmVersion),
|
|
552
|
+
// A state without a pin would be meaningless, so the two are resolved
|
|
553
|
+
// together: no pin in force means no state, whatever the converger's
|
|
554
|
+
// internal maps happen to still hold for an older pin.
|
|
555
|
+
host_node_pin: pin,
|
|
556
|
+
host_node_pin_state: pin ? pinState : null,
|
|
557
|
+
host_node_observed: true
|
|
558
|
+
};
|
|
559
|
+
}
|
|
560
|
+
|
|
491
561
|
// src/lib/manager-worker.ts
|
|
492
562
|
import { execFileSync as syncExecFile } from "child_process";
|
|
493
563
|
import { join as join43, dirname as dirname11, delimiter as pathDelimiter } from "path";
|
|
@@ -15416,7 +15486,7 @@ var agentRestartTimezoneInputs = /* @__PURE__ */ new Map();
|
|
|
15416
15486
|
var lastVersionCheckAt = 0;
|
|
15417
15487
|
var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
|
|
15418
15488
|
var lastResponsivenessProbeAt = 0;
|
|
15419
|
-
var agtCliVersion = true ? "0.28.
|
|
15489
|
+
var agtCliVersion = true ? "0.28.1141" : "dev";
|
|
15420
15490
|
function resolveBrewPath(execFileSync3) {
|
|
15421
15491
|
try {
|
|
15422
15492
|
const out = execFileSync3("which", ["brew"], { timeout: 5e3 }).toString().trim();
|
|
@@ -15597,8 +15667,22 @@ function recordHostNodeFailure(pin, reason) {
|
|
|
15597
15667
|
async function diskNodeVersion() {
|
|
15598
15668
|
const probe = await runAsync("node", ["--version"], { timeout: 15e3 });
|
|
15599
15669
|
if (probe.code !== 0) return null;
|
|
15600
|
-
|
|
15601
|
-
|
|
15670
|
+
return parsePathNodeVersion(probe.stdout);
|
|
15671
|
+
}
|
|
15672
|
+
var hostNodeObservation = null;
|
|
15673
|
+
var hostNodeObservedAt = 0;
|
|
15674
|
+
function invalidateHostNodeObservation(pathVersion) {
|
|
15675
|
+
hostNodeObservedAt = 0;
|
|
15676
|
+
if (pathVersion !== void 0 && hostNodeObservation) {
|
|
15677
|
+
hostNodeObservation = { ...hostNodeObservation, pathVersion };
|
|
15678
|
+
}
|
|
15679
|
+
}
|
|
15680
|
+
async function refreshHostNodeObservation(now = Date.now()) {
|
|
15681
|
+
if (!shouldReprobeHostNode(hostNodeObservedAt, now)) return;
|
|
15682
|
+
hostNodeObservedAt = now;
|
|
15683
|
+
hostNodeObservation = await probeHostNode(
|
|
15684
|
+
(cmd, args) => runAsync(cmd, args, { timeout: 15e3 })
|
|
15685
|
+
);
|
|
15602
15686
|
}
|
|
15603
15687
|
async function ensureHostNodeVersion(rawPin) {
|
|
15604
15688
|
const pin = normalizeHostNodePinVersion(rawPin);
|
|
@@ -15628,7 +15712,7 @@ async function ensureHostNodeVersion(rawPin) {
|
|
|
15628
15712
|
hostNodeNoDnfLogged = true;
|
|
15629
15713
|
log(`[host-node] 'dnf' not found - cannot converge host Node onto ${pin} on this platform (leaving ${current ?? "unknown"} in place)`);
|
|
15630
15714
|
}
|
|
15631
|
-
hostNodeConvergence.
|
|
15715
|
+
hostNodeConvergence.recordUnsupported(pin);
|
|
15632
15716
|
return;
|
|
15633
15717
|
}
|
|
15634
15718
|
const asRoot = typeof process.getuid === "function" && process.getuid() === 0;
|
|
@@ -15649,6 +15733,7 @@ async function ensureHostNodeVersion(rawPin) {
|
|
|
15649
15733
|
}
|
|
15650
15734
|
log(`[host-node] host Node is now ${pin} on disk. Running processes keep the previous binary until they restart - this does NOT restart the manager (ENG-11617).`);
|
|
15651
15735
|
hostNodeConvergence.recordSuccess(pin);
|
|
15736
|
+
invalidateHostNodeObservation(after);
|
|
15652
15737
|
} catch (err) {
|
|
15653
15738
|
recordHostNodeFailure(pin, `install attempt threw: ${isolationImageErrDetail(err)}`);
|
|
15654
15739
|
} finally {
|
|
@@ -17317,6 +17402,8 @@ async function pollCycleInner() {
|
|
|
17317
17402
|
} else {
|
|
17318
17403
|
lastManagedSettingsStatus = null;
|
|
17319
17404
|
}
|
|
17405
|
+
await refreshHostNodeObservation();
|
|
17406
|
+
const hostNodePin = hostNodeConvergence.desiredPin();
|
|
17320
17407
|
const hbResp = await api.post("/host/heartbeat", {
|
|
17321
17408
|
host_id: hostId,
|
|
17322
17409
|
framework_version: cachedFrameworkVersion ?? void 0,
|
|
@@ -17330,6 +17417,17 @@ async function pollCycleInner() {
|
|
|
17330
17417
|
// rather than as two fields a future edit could separate. See
|
|
17331
17418
|
// `heartbeatRuntimeAuthFields`.
|
|
17332
17419
|
...heartbeatRuntimeAuthFields(runtimeAuthProbeVerdict),
|
|
17420
|
+
// ENG-11639: host Node, and how the pin stands with this host. Spread as
|
|
17421
|
+
// ONE unit for the same reason as the line above — the API stamps a
|
|
17422
|
+
// freshness timestamp on receipt, so the values and their
|
|
17423
|
+
// `host_node_observed` marker must never be editable apart. Omitted
|
|
17424
|
+
// entirely until the first measurement, because ABSENCE MEANS NO SIGNAL
|
|
17425
|
+
// here and must not be readable as either patched or unpatched.
|
|
17426
|
+
...heartbeatHostNodeFields(
|
|
17427
|
+
hostNodeObservation,
|
|
17428
|
+
hostNodePin,
|
|
17429
|
+
hostNodePin ? hostNodeConvergence.stateOf(hostNodePin) : null
|
|
17430
|
+
),
|
|
17333
17431
|
agent_diagnostics: agentDiagnostics,
|
|
17334
17432
|
hostname: tailscaleHostname,
|
|
17335
17433
|
os_username: osUsername,
|