@integrity-labs/agt-cli 0.28.640 → 0.28.642

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-4FANS7I6.js";
43
+ } from "../chunk-ND3OFG2Z.js";
44
44
  import {
45
45
  readDirectChatSessionState
46
46
  } from "../chunk-HYLJPTKL.js";
@@ -4909,7 +4909,7 @@ import { execFileSync, execSync } from "child_process";
4909
4909
  import { existsSync as existsSync10, realpathSync as realpathSync2 } from "fs";
4910
4910
  import chalk18 from "chalk";
4911
4911
  import ora16 from "ora";
4912
- var cliVersion = true ? "0.28.640" : "dev";
4912
+ var cliVersion = true ? "0.28.642" : "dev";
4913
4913
  async function fetchLatestVersion() {
4914
4914
  const host2 = getHost();
4915
4915
  if (!host2) return null;
@@ -6089,7 +6089,7 @@ function handleError(err) {
6089
6089
  }
6090
6090
 
6091
6091
  // src/bin/agt.ts
6092
- var cliVersion2 = true ? "0.28.640" : "dev";
6092
+ var cliVersion2 = true ? "0.28.642" : "dev";
6093
6093
  var program = new Command();
6094
6094
  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");
6095
6095
  program.hook("preAction", async (thisCommand, actionCommand) => {
@@ -6073,7 +6073,7 @@ function exchangeFailureKind(err) {
6073
6073
  }
6074
6074
 
6075
6075
  // src/lib/api-client.ts
6076
- var agtCliVersion = true ? "0.28.640" : "dev";
6076
+ var agtCliVersion = true ? "0.28.642" : "dev";
6077
6077
  var lastConfigHash = null;
6078
6078
  function setConfigHash(hash) {
6079
6079
  lastConfigHash = hash && hash.length > 0 ? hash : null;
@@ -9814,4 +9814,4 @@ export {
9814
9814
  managerInstallSystemUnitCommand,
9815
9815
  managerUninstallSystemUnitCommand
9816
9816
  };
9817
- //# sourceMappingURL=chunk-4FANS7I6.js.map
9817
+ //# sourceMappingURL=chunk-ND3OFG2Z.js.map
@@ -55,7 +55,7 @@ import {
55
55
  safeWriteJsonAtomic,
56
56
  setConfigHash,
57
57
  tripClass
58
- } from "../chunk-4FANS7I6.js";
58
+ } from "../chunk-ND3OFG2Z.js";
59
59
  import {
60
60
  getProjectDir as getProjectDir2,
61
61
  getReadyTasks,
@@ -12154,7 +12154,7 @@ var agentRestartTimezoneInputs = /* @__PURE__ */ new Map();
12154
12154
  var lastVersionCheckAt = 0;
12155
12155
  var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
12156
12156
  var lastResponsivenessProbeAt = 0;
12157
- var agtCliVersion = true ? "0.28.640" : "dev";
12157
+ var agtCliVersion = true ? "0.28.642" : "dev";
12158
12158
  function resolveBrewPath(execFileSync3) {
12159
12159
  try {
12160
12160
  const out = execFileSync3("which", ["brew"], { timeout: 5e3 }).toString().trim();
@@ -14121,6 +14121,7 @@ async function pollCycleInner() {
14121
14121
  const fastRespawn = hostFlagStore().getBoolean("fast-mcp-restart-respawn");
14122
14122
  const processOrder = fastRespawn ? reorderRestartedFirst(agents, new Set(restartAcks.keys())) : agents;
14123
14123
  const managedToolkits = createManagedToolkitReader(agents.map((a) => a.agent_id));
14124
+ managedPruneLedger = createManagedPruneLedger();
14124
14125
  for (const agent of processOrder) {
14125
14126
  if (restartInFlight.has(agent.agent_id)) {
14126
14127
  const existing = state7.agents.find((a) => a.agentId === agent.agent_id);
@@ -14160,6 +14161,8 @@ async function pollCycleInner() {
14160
14161
  }
14161
14162
  }
14162
14163
  void maybeReportActivityCache({ api, log });
14164
+ const crossAgentPrune = managedPruneLedger.summarize();
14165
+ if (crossAgentPrune) log(crossAgentPrune);
14163
14166
  const restartAckStateChanged = applyRestartAcks({
14164
14167
  agentStates,
14165
14168
  priorAgents: state7.agents,
@@ -14392,13 +14395,61 @@ async function getOrCacheRegisteredAgents(adapter, profile) {
14392
14395
  }
14393
14396
  return cached;
14394
14397
  }
14398
+ var UntrustworthyToolkitResponseError = class extends Error {
14399
+ constructor(detail) {
14400
+ super(`/host/managed-toolkits returned an untrustworthy body: ${detail}`);
14401
+ this.name = "UntrustworthyToolkitResponseError";
14402
+ }
14403
+ };
14395
14404
  async function fetchManagedToolkits(agentIds) {
14396
14405
  const data = await api.post(
14397
14406
  "/host/managed-toolkits",
14398
14407
  { agent_ids: [...agentIds] }
14399
14408
  );
14400
- return data.toolkits ?? [];
14409
+ const toolkits = data?.toolkits;
14410
+ if (toolkits === void 0 || toolkits === null) {
14411
+ throw new UntrustworthyToolkitResponseError("`toolkits` field is missing");
14412
+ }
14413
+ if (!Array.isArray(toolkits)) {
14414
+ throw new UntrustworthyToolkitResponseError(
14415
+ `\`toolkits\` is ${typeof toolkits}, expected an array`
14416
+ );
14417
+ }
14418
+ const covered = data?.covered_agent_ids;
14419
+ let coveredAgentIds = null;
14420
+ if (covered !== void 0 && covered !== null) {
14421
+ if (!Array.isArray(covered) || covered.some((id) => typeof id !== "string")) {
14422
+ throw new UntrustworthyToolkitResponseError(
14423
+ "`covered_agent_ids` is present but is not an array of strings"
14424
+ );
14425
+ }
14426
+ coveredAgentIds = covered;
14427
+ }
14428
+ return { toolkits, coveredAgentIds };
14401
14429
  }
14430
+ function coverageOf(result, requested) {
14431
+ const covered = new Set(result.coveredAgentIds ?? []);
14432
+ for (const tk of result.toolkits) covered.add(tk.agent_id);
14433
+ const scoped = new Set([...covered].filter((id) => requested.includes(id)));
14434
+ return { covered: scoped, assertedByServer: result.coveredAgentIds !== null };
14435
+ }
14436
+ function createManagedPruneLedger() {
14437
+ const byAgent = /* @__PURE__ */ new Map();
14438
+ return {
14439
+ record(agentCodeName, serverKey) {
14440
+ const list = byAgent.get(agentCodeName);
14441
+ if (list) list.push(serverKey);
14442
+ else byAgent.set(agentCodeName, [serverKey]);
14443
+ },
14444
+ summarize() {
14445
+ if (byAgent.size < 2) return null;
14446
+ const total = [...byAgent.values()].reduce((n, l) => n + l.length, 0);
14447
+ const detail = [...byAgent.entries()].map(([codeName, keys]) => `${codeName}(${keys.join(",")})`).join(" ");
14448
+ return `[managed-toolkit][WARN] cross-agent prune: ${total} MCP server(s) removed across ${byAgent.size} agents in ONE cycle \u2014 agents are configured independently, so a simultaneous revocation is unlikely and this may be an untrustworthy toolkit response rather than a real one (ENG-9140): ${detail}`;
14449
+ }
14450
+ };
14451
+ }
14452
+ var managedPruneLedger = createManagedPruneLedger();
14402
14453
  function createManagedToolkitReader(agentIds, fetchToolkits = fetchManagedToolkits) {
14403
14454
  const requested = [...new Set(agentIds)];
14404
14455
  let batch = null;
@@ -14406,11 +14457,18 @@ function createManagedToolkitReader(agentIds, fetchToolkits = fetchManagedToolki
14406
14457
  batch ??= (async () => {
14407
14458
  if (requested.length === 0) return /* @__PURE__ */ new Map();
14408
14459
  try {
14409
- const toolkits = await fetchToolkits(requested);
14460
+ const result = await fetchToolkits(requested);
14461
+ const { covered, assertedByServer } = coverageOf(result, requested);
14410
14462
  const byAgent = new Map(
14411
- requested.map((id) => [id, []])
14463
+ [...covered].map((id) => [id, []])
14412
14464
  );
14413
- for (const tk of toolkits) byAgent.get(tk.agent_id)?.push(tk);
14465
+ for (const tk of result.toolkits) byAgent.get(tk.agent_id)?.push(tk);
14466
+ const uncovered = requested.length - covered.size;
14467
+ if (uncovered > 0) {
14468
+ log(
14469
+ `[managed-toolkit] batch answered for ${covered.size}/${requested.length} agent(s)${assertedByServer ? "" : " (API build asserts no coverage)"} \u2014 the other ${uncovered} are UNKNOWN, not empty, and will be re-asked per agent rather than pruned (ENG-9140)`
14470
+ );
14471
+ }
14414
14472
  return byAgent;
14415
14473
  } catch (err) {
14416
14474
  log(
@@ -14426,7 +14484,14 @@ function createManagedToolkitReader(agentIds, fetchToolkits = fetchManagedToolki
14426
14484
  const byAgent = await loadBatch();
14427
14485
  const fromBatch = byAgent?.get(agentId);
14428
14486
  if (fromBatch) return fromBatch;
14429
- return (await fetchToolkits([agentId])).filter((tk) => tk.agent_id === agentId);
14487
+ const single = await fetchToolkits([agentId]);
14488
+ const { covered, assertedByServer } = coverageOf(single, [agentId]);
14489
+ if (assertedByServer && !covered.has(agentId)) {
14490
+ throw new UntrustworthyToolkitResponseError(
14491
+ `per-agent fetch for '${agentId}' returned a response that does not cover it`
14492
+ );
14493
+ }
14494
+ return single.toolkits.filter((tk) => tk.agent_id === agentId);
14430
14495
  }
14431
14496
  };
14432
14497
  }
@@ -15760,6 +15825,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
15760
15825
  if (isManagedMcpServerKey(key) && !expectedServerIds.has(key)) {
15761
15826
  frameworkAdapter.removeMcpServer(agent.code_name, key);
15762
15827
  log(`[managed-toolkit] Removed stale MCP server '${key}' for '${agent.code_name}'`);
15828
+ managedPruneLedger.record(agent.code_name, key);
15763
15829
  }
15764
15830
  }
15765
15831
  } catch {
@@ -19133,12 +19199,15 @@ export {
19133
19199
  DAY_ROLLOVER_FORCE_GRACE_MIN,
19134
19200
  DAY_ROLLOVER_INBOUND_DEFER_MAX_MIN,
19135
19201
  DAY_ROLLOVER_INBOUND_GRACE_SEC,
19202
+ UntrustworthyToolkitResponseError,
19136
19203
  applyRestartAcks,
19137
19204
  cancelKanbanNoticeOnDrain,
19138
19205
  classifyLazyDayRolloverReset,
19139
19206
  claudeCodeUpgradeMarkerPath,
19140
19207
  claudeCodeUpgradeThrottled,
19141
19208
  claudeManagedSettingsPath,
19209
+ coverageOf,
19210
+ createManagedPruneLedger,
19142
19211
  createManagedToolkitReader,
19143
19212
  creditInboundHold,
19144
19213
  dashboardRestartBreakerReason,
@@ -19146,6 +19215,7 @@ export {
19146
19215
  ensureClaudeManagedSettings,
19147
19216
  extractCharterSlackPeers,
19148
19217
  extractCharterTelegramPeers,
19218
+ fetchManagedToolkits,
19149
19219
  hasRevokedResiduals,
19150
19220
  inboundHoldMinutes,
19151
19221
  isOlderSemverTuple,