@integrity-labs/agt-cli 0.28.723 → 0.28.725

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
@@ -41,7 +41,7 @@ import {
41
41
  success,
42
42
  table,
43
43
  warn
44
- } from "../chunk-ABM45AFN.js";
44
+ } from "../chunk-MHB3SEYC.js";
45
45
  import {
46
46
  getProjectDir,
47
47
  isSessionResumeDisabled,
@@ -5467,7 +5467,7 @@ import { execFileSync, execSync } from "child_process";
5467
5467
  import { existsSync as existsSync11, realpathSync as realpathSync2 } from "fs";
5468
5468
  import chalk18 from "chalk";
5469
5469
  import ora16 from "ora";
5470
- var cliVersion = true ? "0.28.723" : "dev";
5470
+ var cliVersion = true ? "0.28.725" : "dev";
5471
5471
  async function fetchLatestVersion() {
5472
5472
  const host2 = getHost();
5473
5473
  if (!host2) return null;
@@ -6654,7 +6654,7 @@ function handleError(err) {
6654
6654
  }
6655
6655
 
6656
6656
  // src/bin/agt.ts
6657
- var cliVersion2 = true ? "0.28.723" : "dev";
6657
+ var cliVersion2 = true ? "0.28.725" : "dev";
6658
6658
  var program = new Command();
6659
6659
  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");
6660
6660
  program.hook("preAction", async (thisCommand, actionCommand) => {
@@ -6428,7 +6428,7 @@ function exchangeFailureKind(err) {
6428
6428
  }
6429
6429
 
6430
6430
  // src/lib/api-client.ts
6431
- var agtCliVersion = true ? "0.28.723" : "dev";
6431
+ var agtCliVersion = true ? "0.28.725" : "dev";
6432
6432
  var lastConfigHash = null;
6433
6433
  function setConfigHash(hash) {
6434
6434
  lastConfigHash = hash && hash.length > 0 ? hash : null;
@@ -10474,4 +10474,4 @@ export {
10474
10474
  managerInstallSystemUnitCommand,
10475
10475
  managerUninstallSystemUnitCommand
10476
10476
  };
10477
- //# sourceMappingURL=chunk-ABM45AFN.js.map
10477
+ //# sourceMappingURL=chunk-MHB3SEYC.js.map
@@ -57,7 +57,7 @@ import {
57
57
  safeWriteJsonAtomic,
58
58
  setConfigHash,
59
59
  tripClass
60
- } from "../chunk-ABM45AFN.js";
60
+ } from "../chunk-MHB3SEYC.js";
61
61
  import {
62
62
  getProjectDir as getProjectDir2,
63
63
  getReadyTasks,
@@ -5138,6 +5138,16 @@ function slugToTitle(slug) {
5138
5138
  function escapeYamlDouble(value) {
5139
5139
  return value.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
5140
5140
  }
5141
+ function resolveIntegrationSkillLane(payload) {
5142
+ if (payload.integration_skills_manifest !== void 0 && payload.integration_skills === void 0) {
5143
+ return null;
5144
+ }
5145
+ return payload.integration_skills ?? payload.plugin_skills ?? [];
5146
+ }
5147
+ function planIntegrationSkillSweep(discovered, currentIds, desiredResolved) {
5148
+ if (!desiredResolved) return [];
5149
+ return [...discovered].filter((entry) => !currentIds.has(entry));
5150
+ }
5141
5151
  function groupSkillsByIntegration(skills) {
5142
5152
  const map = /* @__PURE__ */ new Map();
5143
5153
  for (const s of skills) {
@@ -5365,19 +5375,14 @@ function sweepSkillCache(cacheDir, now = Date.now()) {
5365
5375
  } catch {
5366
5376
  }
5367
5377
  }
5368
- async function resolveSkillsFromManifest(args) {
5369
- const { globals, shared, cacheDir, fetchContents, log: log2 } = args;
5378
+ async function collectBodies(hashes, cacheDir, fetchContents, lane, log2) {
5370
5379
  const bodies = /* @__PURE__ */ new Map();
5371
5380
  const missing = [];
5372
- for (const entry of [...globals, ...shared]) {
5373
- if (!entry.hash) {
5374
- log2?.(`[skills] manifest entry '${entry.code_name}' has no hash \u2014 skipping skill sync`);
5375
- return null;
5376
- }
5377
- if (bodies.has(entry.hash) || missing.includes(entry.hash)) continue;
5378
- const cached = readCachedSkill(cacheDir, entry.hash);
5379
- if (cached !== null) bodies.set(entry.hash, cached);
5380
- else missing.push(entry.hash);
5381
+ for (const hash of hashes) {
5382
+ if (bodies.has(hash) || missing.includes(hash)) continue;
5383
+ const cached = readCachedSkill(cacheDir, hash);
5384
+ if (cached !== null) bodies.set(hash, cached);
5385
+ else missing.push(hash);
5381
5386
  }
5382
5387
  for (let i = 0; i < missing.length; i += SKILL_FETCH_CHUNK) {
5383
5388
  const chunk2 = missing.slice(i, i + SKILL_FETCH_CHUNK);
@@ -5385,19 +5390,32 @@ async function resolveSkillsFromManifest(args) {
5385
5390
  for (const { hash, content } of await fetchContents(chunk2)) {
5386
5391
  const written = writeCachedSkill(cacheDir, hash, content);
5387
5392
  if (written === "mismatch") {
5388
- log2?.(`[skills] hash mismatch for ${hash} \u2014 skipping skill sync this poll`);
5393
+ log2?.(`[${lane}] hash mismatch for ${hash} \u2014 skipping skill sync this poll`);
5389
5394
  continue;
5390
5395
  }
5391
5396
  if (written === "write-failed") {
5392
- log2?.(`[skills] cache write failed for ${hash} \u2014 serving it uncached this poll`);
5397
+ log2?.(`[${lane}] cache write failed for ${hash} \u2014 serving it uncached this poll`);
5393
5398
  }
5394
5399
  bodies.set(hash, content);
5395
5400
  }
5396
5401
  } catch (err) {
5397
- log2?.(`[skills] fetch failed for ${chunk2.length} entries: ${err.message}`);
5402
+ log2?.(`[${lane}] fetch failed for ${chunk2.length} entries: ${err.message}`);
5398
5403
  }
5399
5404
  }
5400
5405
  sweepSkillCache(cacheDir);
5406
+ return bodies;
5407
+ }
5408
+ async function resolveSkillsFromManifest(args) {
5409
+ const { globals, shared, cacheDir, fetchContents, log: log2 } = args;
5410
+ const hashes = [];
5411
+ for (const entry of [...globals, ...shared]) {
5412
+ if (!entry.hash) {
5413
+ log2?.(`[skills] manifest entry '${entry.code_name}' has no hash \u2014 skipping skill sync`);
5414
+ return null;
5415
+ }
5416
+ hashes.push(entry.hash);
5417
+ }
5418
+ const bodies = await collectBodies(hashes, cacheDir, fetchContents, "skills", log2);
5401
5419
  const resolve2 = (entries) => {
5402
5420
  const out = [];
5403
5421
  for (const e of entries) {
@@ -5420,6 +5438,47 @@ async function resolveSkillsFromManifest(args) {
5420
5438
  }
5421
5439
  return { globals: resolvedGlobals, shared: resolvedShared };
5422
5440
  }
5441
+ async function resolveIntegrationSkillsFromManifest(args) {
5442
+ const { manifest, cacheDir, fetchContents, log: log2 } = args;
5443
+ const hashes = [];
5444
+ for (const entry of manifest) {
5445
+ if (entry.hash) {
5446
+ hashes.push(entry.hash);
5447
+ continue;
5448
+ }
5449
+ if (typeof entry.content !== "string") {
5450
+ log2?.(
5451
+ `[integration-skills] manifest entry '${entry.plugin_slug}/${entry.skill_id}' has neither hash nor content \u2014 skipping integration skill sync`
5452
+ );
5453
+ return null;
5454
+ }
5455
+ }
5456
+ const bodies = await collectBodies(
5457
+ hashes,
5458
+ cacheDir,
5459
+ fetchContents,
5460
+ "integration-skills",
5461
+ log2
5462
+ );
5463
+ const out = [];
5464
+ for (const e of manifest) {
5465
+ const content = e.hash ? bodies.get(e.hash) : e.content;
5466
+ if (content === void 0) {
5467
+ log2?.(
5468
+ "[integration-skills] one or more bodies unresolved \u2014 leaving on-disk integration skills untouched this poll"
5469
+ );
5470
+ return null;
5471
+ }
5472
+ out.push({
5473
+ plugin_slug: e.plugin_slug,
5474
+ ...e.integration_slug !== void 0 ? { integration_slug: e.integration_slug } : {},
5475
+ skill_id: e.skill_id,
5476
+ skill_name: e.skill_name,
5477
+ content
5478
+ });
5479
+ }
5480
+ return out;
5481
+ }
5423
5482
 
5424
5483
  // src/lib/channel-hash-cache.ts
5425
5484
  import { existsSync as existsSync8, readFileSync as readFileSync19, writeFileSync as writeFileSync10 } from "fs";
@@ -12832,7 +12891,7 @@ var agentRestartTimezoneInputs = /* @__PURE__ */ new Map();
12832
12891
  var lastVersionCheckAt = 0;
12833
12892
  var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
12834
12893
  var lastResponsivenessProbeAt = 0;
12835
- var agtCliVersion = true ? "0.28.723" : "dev";
12894
+ var agtCliVersion = true ? "0.28.725" : "dev";
12836
12895
  function resolveBrewPath(execFileSync3) {
12837
12896
  try {
12838
12897
  const out = execFileSync3("which", ["brew"], { timeout: 5e3 }).toString().trim();
@@ -15677,7 +15736,13 @@ async function processAgent(agent, agentStates, managedToolkits) {
15677
15736
  // ENG-9585: the same for the two root-skill lanes. A separate flag
15678
15737
  // because the two shipped in different CLI versions — an API that
15679
15738
  // understands one and not the other must still be able to answer.
15680
- skills_manifest: true
15739
+ skills_manifest: true,
15740
+ // ENG-9585: and the integration lane, a third flag for the same reason
15741
+ // one level sharper. A manager that sent `skills_manifest` but could not
15742
+ // decode THIS manifest would read the lane as empty and sweep every
15743
+ // integration skill folder off disk, so the flag has to name the exact
15744
+ // capability rather than the family.
15745
+ integration_skills_manifest: true
15681
15746
  });
15682
15747
  if (refreshData.knowledge_manifest) {
15683
15748
  const resolved = await resolveKnowledgeFromManifest({
@@ -15714,6 +15779,23 @@ async function processAgent(agent, agentStates, managedToolkits) {
15714
15779
  refreshData.shared_skills = resolvedSkills.shared;
15715
15780
  }
15716
15781
  }
15782
+ if (refreshData.integration_skills_manifest) {
15783
+ const resolvedIntegrationSkills = await resolveIntegrationSkillsFromManifest({
15784
+ manifest: refreshData.integration_skills_manifest,
15785
+ cacheDir: join40(config.configDir, "_skills"),
15786
+ fetchContents: async (hashes) => {
15787
+ const res = await api.post(
15788
+ "/host/skills/contents",
15789
+ { agent_id: agent.agent_id, hashes }
15790
+ );
15791
+ return res.contents ?? [];
15792
+ },
15793
+ log
15794
+ });
15795
+ if (resolvedIntegrationSkills) {
15796
+ refreshData.integration_skills = resolvedIntegrationSkills;
15797
+ }
15798
+ }
15717
15799
  } catch (err) {
15718
15800
  log(`Refresh failed for '${agent.code_name}': ${err.message}`);
15719
15801
  const existing = state8.agents.find((a) => a.agentId === agent.agent_id);
@@ -16988,9 +17070,10 @@ async function processAgent(agent, agentStates, managedToolkits) {
16988
17070
  agent_id: agent.agent_id,
16989
17071
  knowledge_manifest: true,
16990
17072
  // Only `scheduled_tasks` is read here, so ask for the manifest shape on
16991
- // both lanes — nothing in this branch consumes a skill body, and the
17073
+ // every lane — nothing in this branch consumes a skill body, and the
16992
17074
  // skill lanes are the largest part of the payload being discarded.
16993
- skills_manifest: true
17075
+ skills_manifest: true,
17076
+ integration_skills_manifest: true
16994
17077
  });
16995
17078
  tasks = freshData.scheduled_tasks ?? tasks;
16996
17079
  }
@@ -17023,9 +17106,17 @@ async function processAgent(agent, agentStates, managedToolkits) {
17023
17106
  if (!slug) continue;
17024
17107
  contextBySlug.set(slug, { values: ctx.values ?? {}, overrides: (ctx.overrides ?? "").trim() });
17025
17108
  }
17026
- const integrationGroups = groupSkillsByIntegration(
17027
- refreshAny.integration_skills ?? refreshAny.plugin_skills ?? []
17028
- );
17109
+ const integrationSkillsInput = resolveIntegrationSkillLane({
17110
+ integration_skills: refreshAny.integration_skills,
17111
+ plugin_skills: refreshAny.plugin_skills,
17112
+ integration_skills_manifest: refreshAny.integration_skills_manifest
17113
+ });
17114
+ if (integrationSkillsInput === null) {
17115
+ log(
17116
+ `Integration skill manifest unresolved for '${agent.code_name}' \u2014 leaving integration skill folders untouched this poll`
17117
+ );
17118
+ }
17119
+ const integrationGroups = groupSkillsByIntegration(integrationSkillsInput ?? []);
17029
17120
  for (const [integrationSlug, scopes] of integrationGroups) {
17030
17121
  try {
17031
17122
  const integrationSkillId = `integration-${integrationSlug}`.replace(/[^a-z0-9-]/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
@@ -17104,10 +17195,12 @@ async function processAgent(agent, agentStates, managedToolkits) {
17104
17195
  });
17105
17196
  log(`Removed ${reason} '${entry}' for '${agent.code_name}' (framework=${frameworkId2})`);
17106
17197
  };
17107
- for (const entry of discoveredEntries) {
17108
- if (!currentIntegrationSkillIds.has(entry)) {
17109
- removeSkillFolder(entry, "orphaned skill folder");
17110
- }
17198
+ for (const entry of planIntegrationSkillSweep(
17199
+ discoveredEntries,
17200
+ currentIntegrationSkillIds,
17201
+ integrationSkillsInput !== null
17202
+ )) {
17203
+ removeSkillFolder(entry, "orphaned skill folder");
17111
17204
  }
17112
17205
  } catch (err) {
17113
17206
  log(`Integration skill cleanup failed for '${agent.code_name}': ${err.message}`);