@integrity-labs/agt-cli 0.27.120 → 0.27.121
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
|
@@ -28,7 +28,7 @@ import {
|
|
|
28
28
|
success,
|
|
29
29
|
table,
|
|
30
30
|
warn
|
|
31
|
-
} from "../chunk-
|
|
31
|
+
} from "../chunk-PMBWORBQ.js";
|
|
32
32
|
import {
|
|
33
33
|
CHANNEL_REGISTRY,
|
|
34
34
|
DEPLOYMENT_TEMPLATES,
|
|
@@ -4934,7 +4934,7 @@ import { execFileSync, execSync } from "child_process";
|
|
|
4934
4934
|
import { existsSync as existsSync10, realpathSync as realpathSync2 } from "fs";
|
|
4935
4935
|
import chalk18 from "chalk";
|
|
4936
4936
|
import ora16 from "ora";
|
|
4937
|
-
var cliVersion = true ? "0.27.
|
|
4937
|
+
var cliVersion = true ? "0.27.121" : "dev";
|
|
4938
4938
|
async function fetchLatestVersion() {
|
|
4939
4939
|
const host2 = getHost();
|
|
4940
4940
|
if (!host2) return null;
|
|
@@ -5857,7 +5857,7 @@ function handleError(err) {
|
|
|
5857
5857
|
}
|
|
5858
5858
|
|
|
5859
5859
|
// src/bin/agt.ts
|
|
5860
|
-
var cliVersion2 = true ? "0.27.
|
|
5860
|
+
var cliVersion2 = true ? "0.27.121" : "dev";
|
|
5861
5861
|
var program = new Command();
|
|
5862
5862
|
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");
|
|
5863
5863
|
program.hook("preAction", async (thisCommand, actionCommand) => {
|
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
provisionStopHook,
|
|
18
18
|
requireHost,
|
|
19
19
|
safeWriteJsonAtomic
|
|
20
|
-
} from "../chunk-
|
|
20
|
+
} from "../chunk-PMBWORBQ.js";
|
|
21
21
|
import {
|
|
22
22
|
getProjectDir as getProjectDir2,
|
|
23
23
|
getReadyTasks,
|
|
@@ -3225,6 +3225,63 @@ function decideWedgeRestart(input, config2) {
|
|
|
3225
3225
|
return input.consecutiveWedgeCycles >= config2.minCycles ? "wedged" : "none";
|
|
3226
3226
|
}
|
|
3227
3227
|
|
|
3228
|
+
// src/lib/wedge-poison-card.ts
|
|
3229
|
+
var DEFAULTS2 = {
|
|
3230
|
+
threshold: 3,
|
|
3231
|
+
cooldownSeconds: 1800
|
|
3232
|
+
// 30 min — matches the kanban stale-auto-fail window
|
|
3233
|
+
};
|
|
3234
|
+
function parsePositiveInt2(raw, fallback, floor) {
|
|
3235
|
+
const n = raw ? Number.parseInt(raw, 10) : NaN;
|
|
3236
|
+
return Number.isInteger(n) && n >= floor ? n : fallback;
|
|
3237
|
+
}
|
|
3238
|
+
function resolvePoisonCardConfig(env = process.env) {
|
|
3239
|
+
return {
|
|
3240
|
+
threshold: parsePositiveInt2(env.AGT_WEDGE_POISON_CARD_THRESHOLD, DEFAULTS2.threshold, 2),
|
|
3241
|
+
cooldownMs: parsePositiveInt2(
|
|
3242
|
+
env.AGT_WEDGE_POISON_CARD_COOLDOWN_SECONDS,
|
|
3243
|
+
DEFAULTS2.cooldownSeconds,
|
|
3244
|
+
300
|
|
3245
|
+
) * 1e3
|
|
3246
|
+
};
|
|
3247
|
+
}
|
|
3248
|
+
function recordWedgeForCards(states, inProgressCardIds, nowMs, config2) {
|
|
3249
|
+
if (inProgressCardIds.length === 0) {
|
|
3250
|
+
return { next: new Map(states), newlyPoisoned: [] };
|
|
3251
|
+
}
|
|
3252
|
+
const next = /* @__PURE__ */ new Map();
|
|
3253
|
+
const newlyPoisoned = [];
|
|
3254
|
+
for (const id of inProgressCardIds) {
|
|
3255
|
+
if (next.has(id)) continue;
|
|
3256
|
+
const count = (states.get(id)?.count ?? 0) + 1;
|
|
3257
|
+
next.set(id, { count, lastWedgeAtMs: nowMs });
|
|
3258
|
+
if (count === config2.threshold) newlyPoisoned.push(id);
|
|
3259
|
+
}
|
|
3260
|
+
return { next, newlyPoisoned };
|
|
3261
|
+
}
|
|
3262
|
+
function pruneCardStates(states, liveInProgressCardIds, nowMs, config2) {
|
|
3263
|
+
const live = liveInProgressCardIds instanceof Set ? liveInProgressCardIds : new Set(liveInProgressCardIds);
|
|
3264
|
+
const next = /* @__PURE__ */ new Map();
|
|
3265
|
+
for (const [id, state6] of states) {
|
|
3266
|
+
if (!live.has(id)) continue;
|
|
3267
|
+
if (nowMs - state6.lastWedgeAtMs > config2.cooldownMs) continue;
|
|
3268
|
+
next.set(id, state6);
|
|
3269
|
+
}
|
|
3270
|
+
return next;
|
|
3271
|
+
}
|
|
3272
|
+
function isCardPoisoned(states, cardId, config2) {
|
|
3273
|
+
return (states.get(cardId)?.count ?? 0) >= config2.threshold;
|
|
3274
|
+
}
|
|
3275
|
+
function partitionActionableByPoison(actionable, states, config2) {
|
|
3276
|
+
const allowed = [];
|
|
3277
|
+
const suppressed = [];
|
|
3278
|
+
for (const item of actionable) {
|
|
3279
|
+
if (isCardPoisoned(states, item.id, config2)) suppressed.push(item);
|
|
3280
|
+
else allowed.push(item);
|
|
3281
|
+
}
|
|
3282
|
+
return { allowed, suppressed };
|
|
3283
|
+
}
|
|
3284
|
+
|
|
3228
3285
|
// src/lib/restart-flags.ts
|
|
3229
3286
|
import { existsSync as existsSync4, mkdirSync as mkdirSync3, readdirSync as readdirSync3, readFileSync as readFileSync8, renameSync as renameSync2, rmSync, writeFileSync as writeFileSync3 } from "fs";
|
|
3230
3287
|
import { homedir as homedir3 } from "os";
|
|
@@ -4047,6 +4104,7 @@ var DEFER_LOG_THROTTLE_MS = 6e5;
|
|
|
4047
4104
|
var deferLogThrottle = /* @__PURE__ */ new Map();
|
|
4048
4105
|
var lastInboundMs = /* @__PURE__ */ new Map();
|
|
4049
4106
|
var consecutiveWedgeCycles = /* @__PURE__ */ new Map();
|
|
4107
|
+
var wedgeRestartsByCard = /* @__PURE__ */ new Map();
|
|
4050
4108
|
function noteInbound(codeName) {
|
|
4051
4109
|
lastInboundMs.set(codeName, Date.now());
|
|
4052
4110
|
}
|
|
@@ -4366,7 +4424,7 @@ var cachedMaintenanceWindow = null;
|
|
|
4366
4424
|
var lastVersionCheckAt = 0;
|
|
4367
4425
|
var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
|
|
4368
4426
|
var lastResponsivenessProbeAt = 0;
|
|
4369
|
-
var agtCliVersion = true ? "0.27.
|
|
4427
|
+
var agtCliVersion = true ? "0.27.121" : "dev";
|
|
4370
4428
|
function resolveBrewPath(execFileSync4) {
|
|
4371
4429
|
try {
|
|
4372
4430
|
const out = execFileSync4("which", ["brew"], { timeout: 5e3 }).toString().trim();
|
|
@@ -5691,6 +5749,10 @@ async function pollCycle() {
|
|
|
5691
5749
|
for (const tracked of consecutiveWedgeCycles.keys()) {
|
|
5692
5750
|
if (!liveAgents.has(tracked)) consecutiveWedgeCycles.delete(tracked);
|
|
5693
5751
|
}
|
|
5752
|
+
for (const tracked of wedgeRestartsByCard.keys()) {
|
|
5753
|
+
if (!liveAgents.has(tracked)) wedgeRestartsByCard.delete(tracked);
|
|
5754
|
+
}
|
|
5755
|
+
const poisonConfig = resolvePoisonCardConfig();
|
|
5694
5756
|
for (const probe of collectResponsivenessProbes([...liveAgents])) {
|
|
5695
5757
|
const codeName = probe.code_name;
|
|
5696
5758
|
if (!isSessionHealthy(codeName)) {
|
|
@@ -5736,6 +5798,20 @@ async function pollCycle() {
|
|
|
5736
5798
|
log(
|
|
5737
5799
|
`[wedge] forced fresh respawn ${detail} \u2192 new session ${newId} (transcript preserved${deadNote})`
|
|
5738
5800
|
);
|
|
5801
|
+
const inProgressCardIds = (kanbanBoardCache.get(codeName) ?? []).filter((item) => item.status === "in_progress" && isHybridActionable(item)).map((item) => item.id);
|
|
5802
|
+
const cardStates = wedgeRestartsByCard.get(codeName) ?? /* @__PURE__ */ new Map();
|
|
5803
|
+
const { next, newlyPoisoned } = recordWedgeForCards(
|
|
5804
|
+
cardStates,
|
|
5805
|
+
inProgressCardIds,
|
|
5806
|
+
wedgeNow.getTime(),
|
|
5807
|
+
poisonConfig
|
|
5808
|
+
);
|
|
5809
|
+
wedgeRestartsByCard.set(codeName, next);
|
|
5810
|
+
for (const cardId of newlyPoisoned) {
|
|
5811
|
+
log(
|
|
5812
|
+
`[wedge] poison-card suspected agent=${codeName} card=${cardId} consecutiveWedgeRespawns=${poisonConfig.threshold} \u2014 suppressing re-nudge (falls to stale-auto-fail). See ENG-6171.`
|
|
5813
|
+
);
|
|
5814
|
+
}
|
|
5739
5815
|
} catch (err) {
|
|
5740
5816
|
log(`[wedge] force-fresh respawn failed for ${codeName}: ${err.message}`);
|
|
5741
5817
|
}
|
|
@@ -7335,11 +7411,22 @@ async function processAgent(agent, agentStates) {
|
|
|
7335
7411
|
}
|
|
7336
7412
|
void reconcileScheduledRuns(agent.code_name, agent.agent_id, hybridBoard);
|
|
7337
7413
|
if (wantsHybridInject) {
|
|
7338
|
-
|
|
7339
|
-
|
|
7340
|
-
|
|
7414
|
+
const poisonCfg = resolvePoisonCardConfig();
|
|
7415
|
+
const existingStates = wedgeRestartsByCard.get(agent.code_name);
|
|
7416
|
+
if (existingStates && existingStates.size > 0) {
|
|
7417
|
+
const liveInProgress = hybridBoard.filter((item) => item.status === "in_progress" && isHybridActionable(item)).map((item) => item.id);
|
|
7418
|
+
const pruned = pruneCardStates(existingStates, liveInProgress, Date.now(), poisonCfg);
|
|
7419
|
+
if (pruned.size > 0) wedgeRestartsByCard.set(agent.code_name, pruned);
|
|
7420
|
+
else wedgeRestartsByCard.delete(agent.code_name);
|
|
7421
|
+
}
|
|
7422
|
+
const cardStates = wedgeRestartsByCard.get(agent.code_name);
|
|
7423
|
+
const actionable = hybridBoard.filter(isHybridActionable);
|
|
7424
|
+
const { allowed, suppressed } = cardStates ? partitionActionableByPoison(actionable, cardStates, poisonCfg) : { allowed: actionable, suppressed: [] };
|
|
7425
|
+
if (allowed.length > 0) {
|
|
7426
|
+
void maybeInjectKanbanCheck(agent.code_name, agent.agent_id, allowed.length);
|
|
7341
7427
|
} else {
|
|
7342
|
-
|
|
7428
|
+
const reason = suppressed.length > 0 ? "kanban inject suppressed \u2014 suspected poison card(s) (ENG-6171)" : "kanban board drained";
|
|
7429
|
+
closeInjectedRunIfOpen(agent.code_name, "completed", reason);
|
|
7343
7430
|
}
|
|
7344
7431
|
}
|
|
7345
7432
|
}
|