@integrity-labs/agt-cli 0.28.467 → 0.28.468

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-P5NFIZI4.js";
43
+ } from "../chunk-Y2XU2XWM.js";
44
44
  import {
45
45
  AnchorSessionClient,
46
46
  CHANNEL_REGISTRY,
@@ -4830,7 +4830,7 @@ import { execFileSync, execSync } from "child_process";
4830
4830
  import { existsSync as existsSync10, realpathSync as realpathSync2 } from "fs";
4831
4831
  import chalk18 from "chalk";
4832
4832
  import ora16 from "ora";
4833
- var cliVersion = true ? "0.28.467" : "dev";
4833
+ var cliVersion = true ? "0.28.468" : "dev";
4834
4834
  async function fetchLatestVersion() {
4835
4835
  const host2 = getHost();
4836
4836
  if (!host2) return null;
@@ -6002,7 +6002,7 @@ function handleError(err) {
6002
6002
  }
6003
6003
 
6004
6004
  // src/bin/agt.ts
6005
- var cliVersion2 = true ? "0.28.467" : "dev";
6005
+ var cliVersion2 = true ? "0.28.468" : "dev";
6006
6006
  var program = new Command();
6007
6007
  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");
6008
6008
  program.hook("preAction", async (thisCommand, actionCommand) => {
@@ -4910,8 +4910,29 @@ function requireHost() {
4910
4910
  return getHost();
4911
4911
  }
4912
4912
 
4913
+ // src/lib/auth-exchange-error.ts
4914
+ var ApiKeyExchangeError = class extends Error {
4915
+ constructor(message, status, transient) {
4916
+ super(message);
4917
+ this.status = status;
4918
+ this.transient = transient;
4919
+ this.name = "ApiKeyExchangeError";
4920
+ }
4921
+ };
4922
+ function isTransientExchangeStatus(status) {
4923
+ return status >= 500 || status === 429;
4924
+ }
4925
+ function isTransientAuthFailure(err) {
4926
+ return err instanceof ApiKeyExchangeError && err.transient;
4927
+ }
4928
+ function exchangeFailureKind(err) {
4929
+ if (!(err instanceof ApiKeyExchangeError)) return "unclassified";
4930
+ const status = err.status === null ? "transport" : String(err.status);
4931
+ return err.transient ? `transient-${status}` : `verdict-${status}`;
4932
+ }
4933
+
4913
4934
  // src/lib/api-client.ts
4914
- var agtCliVersion = true ? "0.28.467" : "dev";
4935
+ var agtCliVersion = true ? "0.28.468" : "dev";
4915
4936
  var lastConfigHash = null;
4916
4937
  function setConfigHash(hash) {
4917
4938
  lastConfigHash = hash && hash.length > 0 ? hash : null;
@@ -4952,7 +4973,42 @@ async function exchangeApiKey(rawKey, retried = false, opts = {}) {
4952
4973
  exchangeInFlight = null;
4953
4974
  }
4954
4975
  }
4976
+ var DEFAULT_EXCHANGE_RETRY_ATTEMPTS = 2;
4977
+ var DEFAULT_EXCHANGE_RETRY_BASE_MS = 500;
4978
+ function exchangeRetryAttempts() {
4979
+ const raw = process.env["AGT_AUTH_EXCHANGE_RETRY_ATTEMPTS"];
4980
+ const parsed = raw ? parseInt(raw, 10) : NaN;
4981
+ if (Number.isFinite(parsed) && parsed >= 0) return Math.min(parsed, 5);
4982
+ return DEFAULT_EXCHANGE_RETRY_ATTEMPTS;
4983
+ }
4984
+ function exchangeRetryBaseMs() {
4985
+ const raw = process.env["AGT_AUTH_EXCHANGE_RETRY_BASE_MS"];
4986
+ const parsed = raw ? parseInt(raw, 10) : NaN;
4987
+ if (Number.isFinite(parsed) && parsed > 0) return Math.min(parsed, 5e3);
4988
+ return DEFAULT_EXCHANGE_RETRY_BASE_MS;
4989
+ }
4990
+ function asExchangeError(err) {
4991
+ if (err instanceof ApiKeyExchangeError) return err;
4992
+ const message = err instanceof Error ? err.message : String(err);
4993
+ return new ApiKeyExchangeError(message, null, true);
4994
+ }
4955
4995
  async function doExchange(rawKey, retried) {
4996
+ const maxRetries = exchangeRetryAttempts();
4997
+ const baseMs = exchangeRetryBaseMs();
4998
+ let lastErr;
4999
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
5000
+ try {
5001
+ return await attemptExchange(rawKey, retried);
5002
+ } catch (err) {
5003
+ const exchangeErr = asExchangeError(err);
5004
+ if (!exchangeErr.transient || attempt === maxRetries) throw exchangeErr;
5005
+ lastErr = exchangeErr;
5006
+ await new Promise((resolve) => setTimeout(resolve, baseMs * 2 ** attempt));
5007
+ }
5008
+ }
5009
+ throw lastErr ?? new ApiKeyExchangeError("API key exchange failed", null, true);
5010
+ }
5011
+ async function attemptExchange(rawKey, retried) {
4956
5012
  const res = await fetch(`${requireHost()}/host/exchange`, {
4957
5013
  method: "POST",
4958
5014
  headers: { "Content-Type": "application/json" },
@@ -4964,20 +5020,28 @@ async function doExchange(rawKey, retried) {
4964
5020
  const host = requireHost();
4965
5021
  const obfuscated = rawKey.length > 12 ? `${rawKey.slice(0, 8)}${"*".repeat(rawKey.length - 12)}${rawKey.slice(-4)}` : rawKey.slice(0, 4) + "****";
4966
5022
  if (res.status >= 502 && res.status <= 504) {
4967
- throw new Error(`API unreachable (${res.status}): ${host} \u2014 is the API server running?`);
5023
+ throw new ApiKeyExchangeError(
5024
+ `API unreachable (${res.status}): ${host} \u2014 is the API server running?`,
5025
+ res.status,
5026
+ true
5027
+ );
4968
5028
  }
4969
5029
  if (errorMsg.includes("revoked") && !retried) {
4970
5030
  reloadFromShellProfile();
4971
5031
  const freshKey = getApiKey();
4972
5032
  if (freshKey && freshKey !== rawKey) {
4973
- return doExchange(freshKey, true);
5033
+ return attemptExchange(freshKey, true);
4974
5034
  }
4975
5035
  }
4976
- throw new Error(`API key exchange failed: ${errorMsg} (host=${host}, key=${obfuscated})`);
5036
+ throw new ApiKeyExchangeError(
5037
+ `API key exchange failed: ${errorMsg} (host=${host}, key=${obfuscated})`,
5038
+ res.status,
5039
+ isTransientExchangeStatus(res.status)
5040
+ );
4977
5041
  }
4978
5042
  const data = await res.json();
4979
5043
  if (!data.token) {
4980
- throw new Error("API key exchange returned no token");
5044
+ throw new ApiKeyExchangeError("API key exchange returned no token", null, true);
4981
5045
  }
4982
5046
  const claudeAuthMode = data.claude_auth_mode === "api_key" ? "api_key" : data.claude_auth_mode === "openrouter" ? "openrouter" : "subscription";
4983
5047
  cachedExchange = {
@@ -7544,6 +7608,8 @@ export {
7544
7608
  PROD_AGT_HOST,
7545
7609
  getHost,
7546
7610
  requireHost,
7611
+ isTransientAuthFailure,
7612
+ exchangeFailureKind,
7547
7613
  setConfigHash,
7548
7614
  getCachedClaudeAuthMode,
7549
7615
  exchangeApiKey,
@@ -7595,4 +7661,4 @@ export {
7595
7661
  managerInstallSystemUnitCommand,
7596
7662
  managerUninstallSystemUnitCommand
7597
7663
  };
7598
- //# sourceMappingURL=chunk-P5NFIZI4.js.map
7664
+ //# sourceMappingURL=chunk-Y2XU2XWM.js.map