@integrity-labs/agt-cli 0.28.576 → 0.28.578

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-P2LAQMRN.js";
43
+ } from "../chunk-5YFIIWS2.js";
44
44
  import {
45
45
  AnchorSessionClient,
46
46
  CHANNEL_REGISTRY,
@@ -71,7 +71,7 @@ import {
71
71
  requiredMcpWildcard,
72
72
  resolveChannels,
73
73
  serializeManifestForSlackCli
74
- } from "../chunk-E3KBX3UW.js";
74
+ } from "../chunk-L24SX6LH.js";
75
75
  import "../chunk-XWVM4KPK.js";
76
76
 
77
77
  // src/bin/agt.ts
@@ -4853,7 +4853,7 @@ import { execFileSync, execSync } from "child_process";
4853
4853
  import { existsSync as existsSync10, realpathSync as realpathSync2 } from "fs";
4854
4854
  import chalk18 from "chalk";
4855
4855
  import ora16 from "ora";
4856
- var cliVersion = true ? "0.28.576" : "dev";
4856
+ var cliVersion = true ? "0.28.578" : "dev";
4857
4857
  async function fetchLatestVersion() {
4858
4858
  const host2 = getHost();
4859
4859
  if (!host2) return null;
@@ -6031,7 +6031,7 @@ function handleError(err) {
6031
6031
  }
6032
6032
 
6033
6033
  // src/bin/agt.ts
6034
- var cliVersion2 = true ? "0.28.576" : "dev";
6034
+ var cliVersion2 = true ? "0.28.578" : "dev";
6035
6035
  var program = new Command();
6036
6036
  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");
6037
6037
  program.hook("preAction", async (thisCommand, actionCommand) => {
@@ -46,7 +46,7 @@ import {
46
46
  resolveConnectivityProbe,
47
47
  worseConnectivityOutcome,
48
48
  wrapScheduledTaskPrompt
49
- } from "./chunk-E3KBX3UW.js";
49
+ } from "./chunk-L24SX6LH.js";
50
50
  import {
51
51
  parsePsRows
52
52
  } from "./chunk-XWVM4KPK.js";
@@ -617,31 +617,344 @@ function writeXurlStoreForIntegrations(integrations, filePath = getXurlStorePath
617
617
 
618
618
  // ../../packages/core/dist/crypto/secret.js
619
619
  import { createCipheriv, createDecipheriv, randomBytes } from "crypto";
620
- var ALGORITHM = "aes-256-gcm";
621
- var AUTH_TAG_LENGTH = 16;
620
+
621
+ // ../../packages/core/dist/crypto/envelope.js
622
+ import { createHash } from "crypto";
623
+
624
+ // ../../packages/core/dist/crypto/envelope-cbor.js
625
+ var MAJOR_UINT = 0;
626
+ var MAJOR_TSTR = 3;
627
+ var MAJOR_ARRAY = 4;
628
+ var MAJOR_MAP = 5;
629
+ var CborDecodeError = class extends Error {
630
+ };
631
+ function readHead(buf, offset) {
632
+ if (offset >= buf.length)
633
+ throw new CborDecodeError("cbor: truncated (expected head)");
634
+ const first = buf[offset];
635
+ const major = first >> 5;
636
+ const ai = first & 31;
637
+ if (ai < 24)
638
+ return { major, arg: ai, next: offset + 1 };
639
+ if (ai === 24) {
640
+ if (offset + 2 > buf.length)
641
+ throw new CborDecodeError("cbor: truncated uint8 arg");
642
+ const arg = buf[offset + 1];
643
+ if (arg < 24)
644
+ throw new CborDecodeError("cbor: non-canonical (uint8 < 24)");
645
+ return { major, arg, next: offset + 2 };
646
+ }
647
+ if (ai === 25) {
648
+ if (offset + 3 > buf.length)
649
+ throw new CborDecodeError("cbor: truncated uint16 arg");
650
+ const arg = buf.readUInt16BE(offset + 1);
651
+ if (arg < 256)
652
+ throw new CborDecodeError("cbor: non-canonical (uint16 < 256)");
653
+ return { major, arg, next: offset + 3 };
654
+ }
655
+ if (ai === 26) {
656
+ if (offset + 5 > buf.length)
657
+ throw new CborDecodeError("cbor: truncated uint32 arg");
658
+ const arg = buf.readUInt32BE(offset + 1);
659
+ if (arg < 65536)
660
+ throw new CborDecodeError("cbor: non-canonical (uint32 < 65536)");
661
+ return { major, arg, next: offset + 5 };
662
+ }
663
+ throw new CborDecodeError(`cbor: unsupported additional-info ${ai}`);
664
+ }
665
+ function decodeValue(buf, offset) {
666
+ const head = readHead(buf, offset);
667
+ switch (head.major) {
668
+ case MAJOR_UINT:
669
+ return { value: head.arg, next: head.next };
670
+ case MAJOR_TSTR: {
671
+ const end = head.next + head.arg;
672
+ if (end > buf.length)
673
+ throw new CborDecodeError("cbor: truncated text string");
674
+ const bytes = buf.subarray(head.next, end);
675
+ const str = bytes.toString("utf8");
676
+ if (!Buffer.from(str, "utf8").equals(bytes)) {
677
+ throw new CborDecodeError("cbor: invalid UTF-8 in text string");
678
+ }
679
+ return { value: str, next: end };
680
+ }
681
+ case MAJOR_ARRAY: {
682
+ const arr = [];
683
+ let cursor = head.next;
684
+ for (let i = 0; i < head.arg; i++) {
685
+ const decoded = decodeValue(buf, cursor);
686
+ arr.push(decoded.value);
687
+ cursor = decoded.next;
688
+ }
689
+ return { value: arr, next: cursor };
690
+ }
691
+ case MAJOR_MAP: {
692
+ const obj = {};
693
+ let cursor = head.next;
694
+ let prevKeyBytes = null;
695
+ for (let i = 0; i < head.arg; i++) {
696
+ const keyStart = cursor;
697
+ const keyHead = readHead(buf, cursor);
698
+ if (keyHead.major !== MAJOR_TSTR) {
699
+ throw new CborDecodeError("cbor: map keys must be text strings");
700
+ }
701
+ const keyDecoded = decodeValue(buf, cursor);
702
+ const keyBytes = buf.subarray(keyStart, keyDecoded.next);
703
+ if (prevKeyBytes !== null && Buffer.compare(keyBytes, prevKeyBytes) <= 0) {
704
+ throw new CborDecodeError("cbor: map keys not in canonical order or duplicated");
705
+ }
706
+ prevKeyBytes = Buffer.from(keyBytes);
707
+ const valDecoded = decodeValue(buf, keyDecoded.next);
708
+ obj[keyDecoded.value] = valDecoded.value;
709
+ cursor = valDecoded.next;
710
+ }
711
+ return { value: obj, next: cursor };
712
+ }
713
+ default:
714
+ throw new CborDecodeError(`cbor: unsupported major type ${head.major}`);
715
+ }
716
+ }
717
+ function decodeCanonicalCbor(buf) {
718
+ const { value, next } = decodeValue(buf, 0);
719
+ if (next !== buf.length) {
720
+ throw new CborDecodeError(`cbor: ${buf.length - next} trailing byte(s) after top-level item`);
721
+ }
722
+ return value;
723
+ }
724
+
725
+ // ../../packages/core/dist/crypto/secret-errors.js
726
+ var SecretDecryptError = class extends Error {
727
+ constructor(message, options) {
728
+ super(message, options);
729
+ this.name = new.target.name;
730
+ }
731
+ };
732
+ var MalformedEnvelopeError = class extends SecretDecryptError {
733
+ code = "MalformedEnvelope";
734
+ scope = "row";
735
+ };
736
+ var UnknownSchemeError = class extends SecretDecryptError {
737
+ code = "UnknownScheme";
738
+ scope = "row";
739
+ };
740
+ var AppKeyNotInKeyringError = class extends SecretDecryptError {
741
+ code = "AppKeyNotInKeyring";
742
+ scope = "app-key";
743
+ };
744
+ var PlatformKekUnavailableError = class extends SecretDecryptError {
745
+ code = "PlatformKekUnavailable";
746
+ scope = "all-tenants";
747
+ };
748
+ var CustomerKekUnavailableError = class extends SecretDecryptError {
749
+ code = "CustomerKekUnavailable";
750
+ scope = "one-org";
751
+ };
752
+ var AeadAuthFailureError = class extends SecretDecryptError {
753
+ code = "AeadAuthFailure";
754
+ scope = "row";
755
+ };
756
+ var DecryptContextRequiredError = class extends SecretDecryptError {
757
+ code = "DecryptContextRequired";
758
+ scope = "caller";
759
+ };
760
+
761
+ // ../../packages/core/dist/crypto/envelope.js
622
762
  var PREFIX = "enc:";
623
- function getKey() {
624
- const hex = process.env["AUTH_ENCRYPTION_KEY"];
625
- if (!hex || hex.length !== 64) {
626
- throw new Error("AUTH_ENCRYPTION_KEY must be a 64-char hex string (32 bytes)");
763
+ var V2_MARKER = "2";
764
+ var IV_LENGTH = 12;
765
+ var AUTH_TAG_LENGTH = 16;
766
+ var KID_RE = /^[0-9a-f]{8}$/;
767
+ function deriveKid(key) {
768
+ return createHash("sha256").update(key).digest("hex").slice(0, 8);
769
+ }
770
+ function isPlainRecord(v) {
771
+ return typeof v === "object" && v !== null && !Array.isArray(v);
772
+ }
773
+ function decodeWrapList(w) {
774
+ if (!Array.isArray(w) || w.length === 0) {
775
+ throw new MalformedEnvelopeError("envelope: scheme k/c header requires a non-empty wrap list");
776
+ }
777
+ return w.map((entry) => {
778
+ if (!isPlainRecord(entry)) {
779
+ throw new MalformedEnvelopeError("envelope: wrap entry must be a map");
780
+ }
781
+ const keys = Object.keys(entry).sort();
782
+ if (keys.length !== 2 || keys[0] !== "dek" || keys[1] !== "ref") {
783
+ throw new MalformedEnvelopeError("envelope: wrap entry must have exactly {ref, dek}");
784
+ }
785
+ if (typeof entry.ref !== "string" || typeof entry.dek !== "string") {
786
+ throw new MalformedEnvelopeError("envelope: wrap entry ref/dek must be strings");
787
+ }
788
+ return { ref: entry.ref, dek: entry.dek };
789
+ });
790
+ }
791
+ function decodeHeader(bytes) {
792
+ let decoded;
793
+ try {
794
+ decoded = decodeCanonicalCbor(bytes);
795
+ } catch (cause) {
796
+ throw new MalformedEnvelopeError("envelope: header is not canonical CBOR", { cause });
797
+ }
798
+ if (!isPlainRecord(decoded) || typeof decoded.s !== "string") {
799
+ throw new MalformedEnvelopeError("envelope: header must be a map with a string `s`");
627
800
  }
628
- return Buffer.from(hex, "hex");
801
+ const keys = Object.keys(decoded).sort();
802
+ if (decoded.s === "a") {
803
+ if (keys.length !== 2 || keys[0] !== "kid" || keys[1] !== "s") {
804
+ throw new MalformedEnvelopeError("envelope: scheme a header must have exactly {s, kid}");
805
+ }
806
+ if (typeof decoded.kid !== "string" || !KID_RE.test(decoded.kid)) {
807
+ throw new MalformedEnvelopeError("envelope: scheme a kid must be 8 lowercase hex chars");
808
+ }
809
+ return { s: "a", kid: decoded.kid };
810
+ }
811
+ if (decoded.s === "k" || decoded.s === "c") {
812
+ if (keys.length !== 2 || keys[0] !== "s" || keys[1] !== "w") {
813
+ throw new MalformedEnvelopeError("envelope: scheme k/c header must have exactly {s, w}");
814
+ }
815
+ return { s: decoded.s, w: decodeWrapList(decoded.w) };
816
+ }
817
+ throw new UnknownSchemeError(`envelope: unknown scheme ${JSON.stringify(decoded.s)}`);
629
818
  }
630
- function decryptSecret(encoded) {
819
+ function decodeStrict(part, encoding, what) {
820
+ const buf = Buffer.from(part, encoding);
821
+ if (buf.length === 0)
822
+ throw new MalformedEnvelopeError(`envelope: empty ${what}`);
823
+ if (buf.toString(encoding) !== part) {
824
+ throw new MalformedEnvelopeError(`envelope: non-canonical ${encoding} in ${what}`);
825
+ }
826
+ return buf;
827
+ }
828
+ function assertShape(iv, data) {
829
+ if (iv.length !== IV_LENGTH) {
830
+ throw new MalformedEnvelopeError(`envelope: iv must be ${IV_LENGTH} bytes, got ${iv.length}`);
831
+ }
832
+ if (data.length < AUTH_TAG_LENGTH) {
833
+ throw new MalformedEnvelopeError("envelope: ciphertext shorter than the auth tag");
834
+ }
835
+ }
836
+ function parseEnvelope(encoded) {
631
837
  if (!encoded.startsWith(PREFIX)) {
632
- return encoded;
838
+ throw new MalformedEnvelopeError("envelope: missing enc: prefix");
633
839
  }
634
- const key = getKey();
635
840
  const parts = encoded.slice(PREFIX.length).split(":");
636
- if (parts.length !== 2)
637
- throw new Error("Invalid encrypted secret format");
638
- const iv = Buffer.from(parts[0], "base64");
639
- const data = Buffer.from(parts[1], "base64");
640
- const ciphertext = data.subarray(0, data.length - AUTH_TAG_LENGTH);
641
- const tag = data.subarray(data.length - AUTH_TAG_LENGTH);
642
- const decipher = createDecipheriv(ALGORITHM, key, iv, { authTagLength: AUTH_TAG_LENGTH });
841
+ if (parts.length === 2) {
842
+ const iv = decodeStrict(parts[0], "base64", "iv");
843
+ const data = decodeStrict(parts[1], "base64", "ciphertext");
844
+ assertShape(iv, data);
845
+ return { version: 1, iv, data };
846
+ }
847
+ if (parts.length === 4 && parts[0] === V2_MARKER) {
848
+ const headerBytes = decodeStrict(parts[1], "base64url", "header");
849
+ const header = decodeHeader(headerBytes);
850
+ const iv = decodeStrict(parts[2], "base64", "iv");
851
+ const data = decodeStrict(parts[3], "base64", "ciphertext");
852
+ assertShape(iv, data);
853
+ return { version: 2, header, headerBytes, iv, data };
854
+ }
855
+ throw new MalformedEnvelopeError("envelope: unrecognised layout");
856
+ }
857
+ function contextString(ctx) {
858
+ return `org:${ctx.orgId}:${ctx.table}:${ctx.column}:${ctx.field}:${ctx.rowId}`;
859
+ }
860
+ function buildAad(headerBytes, ctx) {
861
+ return Buffer.concat([headerBytes, Buffer.from(contextString(ctx), "utf8")]);
862
+ }
863
+
864
+ // ../../packages/core/dist/crypto/keyring.js
865
+ var ACTIVE_ENV = "AUTH_ENCRYPTION_KEY";
866
+ var PREVIOUS_ENV = "AUTH_ENCRYPTION_KEY_PREVIOUS";
867
+ var HEX_KEY_RE = /^[0-9a-fA-F]{64}$/;
868
+ var derivationCache = /* @__PURE__ */ new Map();
869
+ function deriveEntry(hex) {
870
+ if (!hex || !HEX_KEY_RE.test(hex))
871
+ return null;
872
+ const cached = derivationCache.get(hex);
873
+ if (cached)
874
+ return cached;
875
+ const key = Buffer.from(hex, "hex");
876
+ const entry = { kid: deriveKid(key), key };
877
+ derivationCache.set(hex, entry);
878
+ return entry;
879
+ }
880
+ function getKeyring() {
881
+ const active = deriveEntry(process.env[ACTIVE_ENV]);
882
+ const retiring = deriveEntry(process.env[PREVIOUS_ENV]);
883
+ const byKid = /* @__PURE__ */ new Map();
884
+ const trialOrder = [];
885
+ for (const entry of [active, retiring]) {
886
+ if (!entry)
887
+ continue;
888
+ if (!byKid.has(entry.kid)) {
889
+ byKid.set(entry.kid, entry);
890
+ trialOrder.push(entry);
891
+ }
892
+ }
893
+ return { active, byKid, trialOrder };
894
+ }
895
+ function resolveKeyByKid(kid) {
896
+ return getKeyring().byKid.get(kid);
897
+ }
898
+
899
+ // ../../packages/core/dist/crypto/secret.js
900
+ var ALGORITHM = "aes-256-gcm";
901
+ var AUTH_TAG_LENGTH2 = 16;
902
+ function gcmDecrypt(key, iv, data, aad) {
903
+ const ciphertext = data.subarray(0, data.length - AUTH_TAG_LENGTH2);
904
+ const tag = data.subarray(data.length - AUTH_TAG_LENGTH2);
905
+ const decipher = createDecipheriv(ALGORITHM, key, iv, { authTagLength: AUTH_TAG_LENGTH2 });
906
+ if (aad)
907
+ decipher.setAAD(aad);
643
908
  decipher.setAuthTag(tag);
644
- return decipher.update(ciphertext) + decipher.final("utf8");
909
+ return Buffer.concat([decipher.update(ciphertext), decipher.final()]).toString("utf8");
910
+ }
911
+ function decryptSecret(encoded, context) {
912
+ if (!encoded.startsWith(PREFIX)) {
913
+ return encoded;
914
+ }
915
+ const parsed = parseEnvelope(encoded);
916
+ if (parsed.version === 1) {
917
+ return decryptV1(parsed.iv, parsed.data);
918
+ }
919
+ switch (parsed.header.s) {
920
+ case "a": {
921
+ const entry = resolveKeyByKid(parsed.header.kid);
922
+ if (!entry) {
923
+ throw new AppKeyNotInKeyringError(`no app key with kid ${parsed.header.kid} in the keyring`);
924
+ }
925
+ if (!context) {
926
+ throw new DecryptContextRequiredError("decryptSecret: a v2 envelope requires a DecryptContext to reconstruct its AAD");
927
+ }
928
+ const aad = buildAad(parsed.headerBytes, context);
929
+ try {
930
+ return gcmDecrypt(entry.key, parsed.iv, parsed.data, aad);
931
+ } catch (cause) {
932
+ throw new AeadAuthFailureError(`scheme-a decrypt failed authentication for kid ${parsed.header.kid} (AAD mismatch or tampering)`, { cause });
933
+ }
934
+ }
935
+ // Schemes k/c are grammar this build parses but cannot unwrap — the KEK/DEK
936
+ // path is ADR-0062. A blob under either cannot exist in a 0061-only fleet
937
+ // (the writer never emits them); these throw so dispatch is total and typed.
938
+ case "k":
939
+ throw new PlatformKekUnavailableError("scheme k (platform-CMK DEK) unwrap is not available in this build (ADR-0062)");
940
+ case "c":
941
+ throw new CustomerKekUnavailableError("scheme c (customer-CMK DEK) unwrap is not available in this build (ADR-0062)");
942
+ }
943
+ }
944
+ function decryptV1(iv, data) {
945
+ const { trialOrder } = getKeyring();
946
+ if (trialOrder.length === 0) {
947
+ throw new AppKeyNotInKeyringError("the app-key keyring is empty (AUTH_ENCRYPTION_KEY unset)");
948
+ }
949
+ let lastError;
950
+ for (const entry of trialOrder) {
951
+ try {
952
+ return gcmDecrypt(entry.key, iv, data);
953
+ } catch (err) {
954
+ lastError = err;
955
+ }
956
+ }
957
+ throw new AppKeyNotInKeyringError("no keyring key could decrypt a v1 blob (writing key absent or ciphertext corrupt)", { cause: lastError });
645
958
  }
646
959
  function isEncrypted(value) {
647
960
  return value.startsWith(PREFIX);
@@ -5646,7 +5959,7 @@ function exchangeFailureKind(err) {
5646
5959
  }
5647
5960
 
5648
5961
  // src/lib/api-client.ts
5649
- var agtCliVersion = true ? "0.28.576" : "dev";
5962
+ var agtCliVersion = true ? "0.28.578" : "dev";
5650
5963
  var lastConfigHash = null;
5651
5964
  function setConfigHash(hash) {
5652
5965
  lastConfigHash = hash && hash.length > 0 ? hash : null;
@@ -7957,7 +8270,9 @@ function buildConnectivityProbeDeps(projectDir, probeEnv) {
7957
8270
  message: `MCP '${serverKey}' auth unresolved: ${cfg.unresolved.join(", ")}`
7958
8271
  };
7959
8272
  }
7960
- return probeMcpHttp(cfg);
8273
+ return probeMcpHttp(
8274
+ target.toolName ? { ...cfg, connectivityTest: { tool: target.toolName, ...target.toolArgs ? { args: target.toolArgs } : {} } } : cfg
8275
+ );
7961
8276
  },
7962
8277
  // ENG-7405: local-STDIO MCP probe. Spawns the toolkit's bundled server with
7963
8278
  // the agent's env (the exact command/args/env from `.mcp.json`), handshakes,
@@ -8130,9 +8445,9 @@ async function gatherSessionToolBindProbe(agent, integrations, projectDir, opts)
8130
8445
  }
8131
8446
 
8132
8447
  // ../../packages/core/dist/provisioning/provisioner.js
8133
- import { createHash } from "crypto";
8448
+ import { createHash as createHash2 } from "crypto";
8134
8449
  function sha256(content) {
8135
- return createHash("sha256").update(content, "utf8").digest("hex");
8450
+ return createHash2("sha256").update(content, "utf8").digest("hex");
8136
8451
  }
8137
8452
  function provision(input, frameworkId = "claude-code") {
8138
8453
  const adapter = getFramework(frameworkId);
@@ -8889,9 +9204,14 @@ async function executeConnectivityProbe(target, deps = {}) {
8889
9204
  serverKey: target.mcpServerKey ?? target.definitionId,
8890
9205
  definitionId: target.definitionId,
8891
9206
  inlineServerEntry: target.inlineServerEntry,
8892
- ...rowFacts
9207
+ ...rowFacts,
9208
+ // ENG-7077: the toolkit's prescribed read-only tool, when it declares
9209
+ // one. Mirrors the mcp_stdio branch below — these two legs had drifted,
9210
+ // and only the stdio one could earn `live_call`.
9211
+ toolName: descriptor.probeTool ?? null,
9212
+ toolArgs: descriptor.probeArgs ?? null
8893
9213
  });
8894
- return withEvidence(outcome, "handshake");
9214
+ return withEvidence(outcome, descriptor.probeTool ? "live_call" : "handshake");
8895
9215
  }
8896
9216
  case "mcp_stdio": {
8897
9217
  if (!deps.mcpStdioProbe) return null;
@@ -9015,4 +9335,4 @@ export {
9015
9335
  managerInstallSystemUnitCommand,
9016
9336
  managerUninstallSystemUnitCommand
9017
9337
  };
9018
- //# sourceMappingURL=chunk-P2LAQMRN.js.map
9338
+ //# sourceMappingURL=chunk-5YFIIWS2.js.map