@uipath/audit-tool 1.1.0 → 1.195.0

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.
Files changed (3) hide show
  1. package/dist/index.js +660 -154
  2. package/dist/tool.js +660 -154
  3. package/package.json +28 -37
package/dist/index.js CHANGED
@@ -2800,6 +2800,7 @@ var init_open = __esm(() => {
2800
2800
  });
2801
2801
 
2802
2802
  // ../../filesystem/src/node.ts
2803
+ import { randomUUID } from "node:crypto";
2803
2804
  import { existsSync } from "node:fs";
2804
2805
  import * as fs6 from "node:fs/promises";
2805
2806
  import * as os2 from "node:os";
@@ -2881,6 +2882,90 @@ class NodeFileSystem {
2881
2882
  async mkdir(dirPath) {
2882
2883
  await fs6.mkdir(dirPath, { recursive: true });
2883
2884
  }
2885
+ async acquireLock(lockPath) {
2886
+ const canonicalPath = await this.canonicalizeLockTarget(lockPath);
2887
+ const lockFile = `${canonicalPath}.lock`;
2888
+ const ownerId = randomUUID();
2889
+ const start = Date.now();
2890
+ while (true) {
2891
+ try {
2892
+ await fs6.writeFile(lockFile, ownerId, { flag: "wx" });
2893
+ return this.createLockRelease(lockFile, ownerId);
2894
+ } catch (error) {
2895
+ if (!this.hasErrnoCode(error, "EEXIST")) {
2896
+ throw error;
2897
+ }
2898
+ const stats = await fs6.stat(lockFile).catch(() => null);
2899
+ if (stats && Date.now() - stats.mtimeMs > LOCK_STALE_MS) {
2900
+ const reclaimed = await fs6.rm(lockFile, { force: true }).then(() => true).catch(() => false);
2901
+ if (reclaimed)
2902
+ continue;
2903
+ }
2904
+ if (Date.now() - start > LOCK_MAX_WAIT_MS) {
2905
+ throw new Error(`ELOCKED: timed out waiting for lock on ${canonicalPath}`);
2906
+ }
2907
+ await new Promise((resolve2) => setTimeout(resolve2, LOCK_RETRY_MIN_MS + Math.random() * LOCK_RETRY_JITTER_MS));
2908
+ }
2909
+ }
2910
+ }
2911
+ async canonicalizeLockTarget(lockPath) {
2912
+ const absolute = path2.resolve(lockPath);
2913
+ const fullReal = await fs6.realpath(absolute).catch(() => null);
2914
+ if (fullReal)
2915
+ return fullReal;
2916
+ const parent = path2.dirname(absolute);
2917
+ const base = path2.basename(absolute);
2918
+ const canonicalParent = await fs6.realpath(parent).catch(() => parent);
2919
+ return path2.join(canonicalParent, base);
2920
+ }
2921
+ createLockRelease(lockFile, ownerId) {
2922
+ const heartbeatStart = Date.now();
2923
+ let heartbeatTimer;
2924
+ let stopped = false;
2925
+ const stopHeartbeat = () => {
2926
+ stopped = true;
2927
+ if (heartbeatTimer)
2928
+ clearTimeout(heartbeatTimer);
2929
+ };
2930
+ const scheduleNextHeartbeat = () => {
2931
+ if (stopped)
2932
+ return;
2933
+ if (Date.now() - heartbeatStart >= LOCK_MAX_HOLD_MS) {
2934
+ stopped = true;
2935
+ return;
2936
+ }
2937
+ heartbeatTimer = setTimeout(() => {
2938
+ runHeartbeat();
2939
+ }, LOCK_HEARTBEAT_MS);
2940
+ heartbeatTimer.unref?.();
2941
+ };
2942
+ const runHeartbeat = async () => {
2943
+ if (stopped)
2944
+ return;
2945
+ const current = await fs6.readFile(lockFile, "utf-8").catch(() => null);
2946
+ if (stopped)
2947
+ return;
2948
+ if (current !== ownerId) {
2949
+ stopped = true;
2950
+ return;
2951
+ }
2952
+ const now = Date.now() / 1000;
2953
+ await fs6.utimes(lockFile, now, now).catch(() => {});
2954
+ scheduleNextHeartbeat();
2955
+ };
2956
+ scheduleNextHeartbeat();
2957
+ let released = false;
2958
+ return async () => {
2959
+ if (released)
2960
+ return;
2961
+ released = true;
2962
+ stopHeartbeat();
2963
+ const current = await fs6.readFile(lockFile, "utf-8").catch(() => null);
2964
+ if (current === ownerId) {
2965
+ await fs6.rm(lockFile, { force: true });
2966
+ }
2967
+ };
2968
+ }
2884
2969
  async rm(filePath) {
2885
2970
  await fs6.rm(filePath, { recursive: true, force: true });
2886
2971
  }
@@ -2926,9 +3011,13 @@ class NodeFileSystem {
2926
3011
  }
2927
3012
  }
2928
3013
  isEnoent(error) {
2929
- return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
3014
+ return this.hasErrnoCode(error, "ENOENT");
3015
+ }
3016
+ hasErrnoCode(error, code) {
3017
+ return typeof error === "object" && error !== null && "code" in error && error.code === code;
2930
3018
  }
2931
3019
  }
3020
+ var LOCK_HEARTBEAT_MS = 5000, LOCK_STALE_MS = 15000, LOCK_MAX_WAIT_MS = 20000, LOCK_MAX_HOLD_MS = 60000, LOCK_RETRY_MIN_MS = 100, LOCK_RETRY_JITTER_MS = 200;
2932
3021
  var init_node = __esm(() => {
2933
3022
  init_open();
2934
3023
  });
@@ -2942,7 +3031,7 @@ var init_src = __esm(() => {
2942
3031
 
2943
3032
  // ../../../node_modules/@uipath/coreipc/index.js
2944
3033
  var require_coreipc = __commonJS((exports, module) => {
2945
- var __dirname = "/Users/alexandru.oltean/github/cli/node_modules/@uipath/coreipc";
3034
+ var __dirname = "/home/runner/work/cli/cli/node_modules/@uipath/coreipc";
2946
3035
  /*! For license information please see index.js.LICENSE.txt */
2947
3036
  (function(e, t) {
2948
3037
  typeof exports == "object" && typeof module == "object" ? module.exports = t() : typeof define == "function" && define.amd ? define([], t) : typeof exports == "object" ? exports.ipc = t() : e.ipc = t();
@@ -21134,6 +21223,10 @@ var require_dist = __commonJS((exports) => {
21134
21223
  exports.RobotProxyConstructor = RobotProxyConstructor;
21135
21224
  __exportStar(require_agent(), exports);
21136
21225
  });
21226
+ // ../../auth/src/server.ts
21227
+ var init_server = __esm(() => {
21228
+ init_constants();
21229
+ });
21137
21230
 
21138
21231
  // ../../../node_modules/adm-zip/util/constants.js
21139
21232
  var require_constants = __commonJS((exports, module) => {
@@ -23451,7 +23544,8 @@ var {
23451
23544
  // package.json
23452
23545
  var package_default = {
23453
23546
  name: "@uipath/audit-tool",
23454
- version: "1.1.0",
23547
+ license: "MIT",
23548
+ version: "1.195.0",
23455
23549
  description: "CLI plugin for the UiPath Audit Service — query event sources, paginate events, and export ZIPs from the long-term store.",
23456
23550
  private: false,
23457
23551
  repository: {
@@ -23462,7 +23556,9 @@ var package_default = {
23462
23556
  publishConfig: {
23463
23557
  registry: "https://npm.pkg.github.com/@uipath"
23464
23558
  },
23465
- keywords: ["cli-tool"],
23559
+ keywords: [
23560
+ "cli-tool"
23561
+ ],
23466
23562
  type: "module",
23467
23563
  main: "./dist/tool.js",
23468
23564
  exports: {
@@ -23471,7 +23567,9 @@ var package_default = {
23471
23567
  bin: {
23472
23568
  "audit-tool": "./dist/index.js"
23473
23569
  },
23474
- files: ["dist"],
23570
+ files: [
23571
+ "dist"
23572
+ ],
23475
23573
  scripts: {
23476
23574
  build: "bun build ./src/tool.ts --outdir dist --format esm --target node --external commander && bun build ./src/index.ts --outdir dist --format esm --target node",
23477
23575
  package: "bun run build && bun pm pack",
@@ -23492,6 +23590,136 @@ var package_default = {
23492
23590
  }
23493
23591
  };
23494
23592
 
23593
+ // ../../common/src/singleton.ts
23594
+ var PREFIX = "@uipath/common/";
23595
+ var _g = globalThis;
23596
+ function singleton(ctorOrName) {
23597
+ const name = typeof ctorOrName === "string" ? ctorOrName : ctorOrName.name;
23598
+ const key = Symbol.for(PREFIX + name);
23599
+ return {
23600
+ get(fallback) {
23601
+ return _g[key] ?? fallback;
23602
+ },
23603
+ set(value) {
23604
+ _g[key] = value;
23605
+ },
23606
+ clear() {
23607
+ delete _g[key];
23608
+ },
23609
+ getOrInit(factory, guard) {
23610
+ const existing = _g[key];
23611
+ if (existing != null && typeof existing === "object") {
23612
+ if (!guard || guard(existing)) {
23613
+ return existing;
23614
+ }
23615
+ }
23616
+ const instance = factory();
23617
+ _g[key] = instance;
23618
+ return instance;
23619
+ }
23620
+ };
23621
+ }
23622
+
23623
+ // ../../common/src/sdk-user-agent.ts
23624
+ var USER_AGENT_HEADER = "User-Agent";
23625
+ var sdkUserAgentHostToken = singleton("SdkUserAgentHostToken");
23626
+ function userAgentPatchKey(userAgent) {
23627
+ return Symbol.for(`@uipath/common/sdk-user-agent/${userAgent}`);
23628
+ }
23629
+ function splitUserAgentTokens(value) {
23630
+ return value?.trim().split(/\s+/).filter(Boolean) ?? [];
23631
+ }
23632
+ function appendUserAgentToken(value, userAgent) {
23633
+ const tokens = splitUserAgentTokens(value);
23634
+ const seen = new Set(tokens);
23635
+ for (const token of splitUserAgentTokens(userAgent)) {
23636
+ if (!seen.has(token)) {
23637
+ tokens.push(token);
23638
+ seen.add(token);
23639
+ }
23640
+ }
23641
+ return tokens.join(" ");
23642
+ }
23643
+ function getEffectiveUserAgent(userAgent) {
23644
+ return appendUserAgentToken(sdkUserAgentHostToken.get(), userAgent);
23645
+ }
23646
+ function isHeadersLike(headers) {
23647
+ return typeof headers === "object" && headers !== null && "get" in headers && typeof headers.get === "function" && "set" in headers && typeof headers.set === "function";
23648
+ }
23649
+ function getSdkUserAgentToken(pkg) {
23650
+ const packageName = pkg.name.replace(/^@uipath\//, "");
23651
+ return getEffectiveUserAgent(`${packageName}/${pkg.version}`);
23652
+ }
23653
+ function addSdkUserAgentHeader(headers, userAgent) {
23654
+ const result = { ...headers ?? {} };
23655
+ const effectiveUserAgent = getEffectiveUserAgent(userAgent);
23656
+ const headerName = Object.keys(result).find((key) => key.toLowerCase() === USER_AGENT_HEADER.toLowerCase());
23657
+ if (headerName) {
23658
+ result[headerName] = appendUserAgentToken(result[headerName], effectiveUserAgent);
23659
+ } else {
23660
+ result[USER_AGENT_HEADER] = effectiveUserAgent;
23661
+ }
23662
+ return result;
23663
+ }
23664
+ function withSdkUserAgentHeader(headers, userAgent) {
23665
+ const effectiveUserAgent = getEffectiveUserAgent(userAgent);
23666
+ if (isHeadersLike(headers)) {
23667
+ headers.set(USER_AGENT_HEADER, appendUserAgentToken(headers.get(USER_AGENT_HEADER), effectiveUserAgent));
23668
+ return headers;
23669
+ }
23670
+ if (Array.isArray(headers)) {
23671
+ const result = headers.map((entry) => {
23672
+ const [key, value] = entry;
23673
+ return [key, value];
23674
+ });
23675
+ const headerIndex = result.findIndex(([key]) => key.toLowerCase() === USER_AGENT_HEADER.toLowerCase());
23676
+ if (headerIndex >= 0) {
23677
+ const [key, value] = result[headerIndex];
23678
+ result[headerIndex] = [
23679
+ key,
23680
+ appendUserAgentToken(value, effectiveUserAgent)
23681
+ ];
23682
+ } else {
23683
+ result.push([USER_AGENT_HEADER, effectiveUserAgent]);
23684
+ }
23685
+ return result;
23686
+ }
23687
+ return addSdkUserAgentHeader(typeof headers === "object" && headers !== null ? { ...headers } : {}, effectiveUserAgent);
23688
+ }
23689
+ function withUserAgentInitOverride(initOverrides, userAgent) {
23690
+ return async (requestContext) => {
23691
+ const initWithUserAgent = {
23692
+ ...requestContext.init,
23693
+ headers: withSdkUserAgentHeader(requestContext.init.headers, userAgent)
23694
+ };
23695
+ const override = typeof initOverrides === "function" ? await initOverrides({
23696
+ ...requestContext,
23697
+ init: initWithUserAgent
23698
+ }) : initOverrides;
23699
+ return {
23700
+ ...override ?? {},
23701
+ headers: withSdkUserAgentHeader(override?.headers ?? initWithUserAgent.headers, userAgent)
23702
+ };
23703
+ };
23704
+ }
23705
+ function installSdkUserAgentHeader(BaseApiClass, userAgent) {
23706
+ const prototype = BaseApiClass.prototype;
23707
+ const patchKey = userAgentPatchKey(userAgent);
23708
+ if (prototype[patchKey]) {
23709
+ return;
23710
+ }
23711
+ if (typeof prototype.request !== "function") {
23712
+ throw new Error("Generated BaseAPI request function not found.");
23713
+ }
23714
+ const originalRequest = prototype.request;
23715
+ prototype.request = function requestWithUserAgent(context, initOverrides) {
23716
+ return originalRequest.call(this, context, withUserAgentInitOverride(initOverrides, userAgent));
23717
+ };
23718
+ Object.defineProperty(prototype, patchKey, {
23719
+ value: true
23720
+ });
23721
+ }
23722
+
23495
23723
  // ../audit-sdk/generated/src/runtime.ts
23496
23724
  var BASE_PATH = "https://localhost:7008".replace(/\/+$/, "");
23497
23725
 
@@ -23740,6 +23968,55 @@ class VoidApiResponse {
23740
23968
  return;
23741
23969
  }
23742
23970
  }
23971
+ // ../audit-sdk/package.json
23972
+ var package_default2 = {
23973
+ name: "@uipath/audit-sdk",
23974
+ license: "MIT",
23975
+ version: "1.195.0",
23976
+ description: "SDK for the UiPath Audit Service — query audit event sources, list events, and download long-term-store exports.",
23977
+ repository: {
23978
+ type: "git",
23979
+ url: "https://github.com/UiPath/cli.git",
23980
+ directory: "packages/admin/audit-sdk"
23981
+ },
23982
+ publishConfig: {
23983
+ registry: "https://npm.pkg.github.com/@uipath"
23984
+ },
23985
+ keywords: [
23986
+ "uipath",
23987
+ "audit",
23988
+ "sdk"
23989
+ ],
23990
+ type: "module",
23991
+ main: "./dist/index.js",
23992
+ types: "./dist/src/index.d.ts",
23993
+ exports: {
23994
+ ".": {
23995
+ types: "./dist/src/index.d.ts",
23996
+ default: "./dist/index.js"
23997
+ }
23998
+ },
23999
+ files: [
24000
+ "dist"
24001
+ ],
24002
+ private: true,
24003
+ scripts: {
24004
+ build: "bun build ./src/index.ts --outdir dist --format esm --target node && tsc -p tsconfig.build.json --noCheck",
24005
+ generate: "bun run src/scripts/generate-sdk.ts",
24006
+ lint: "biome check ."
24007
+ },
24008
+ devDependencies: {
24009
+ "@openapitools/openapi-generator-cli": "^2.31.1",
24010
+ "@types/node": "^25.5.0",
24011
+ "@uipath/auth": "workspace:*",
24012
+ "@uipath/common": "workspace:*",
24013
+ typescript: "^6.0.2"
24014
+ }
24015
+ };
24016
+
24017
+ // ../audit-sdk/src/user-agent.ts
24018
+ var SDK_USER_AGENT = getSdkUserAgentToken(package_default2);
24019
+ installSdkUserAgentHeader(BaseAPI, SDK_USER_AGENT);
23743
24020
 
23744
24021
  // ../audit-sdk/generated/src/models/AuditEventStatus.ts
23745
24022
  var AuditEventStatus = {
@@ -24000,32 +24277,7 @@ class InvalidBaseUrlError extends Error {
24000
24277
  this.name = "InvalidBaseUrlError";
24001
24278
  }
24002
24279
  }
24003
- var DEFAULT_SCOPES = [
24004
- "offline_access",
24005
- "ProcessMining",
24006
- "OrchestratorApiUserAccess",
24007
- "StudioWebBackend",
24008
- "IdentityServerApi",
24009
- "ConnectionService",
24010
- "DataService",
24011
- "DataServiceApiUserAccess",
24012
- "DocumentUnderstanding",
24013
- "EnterpriseContextService",
24014
- "Directory",
24015
- "JamJamApi",
24016
- "LLMGateway",
24017
- "LLMOps",
24018
- "OMS",
24019
- "RCS.FolderAuthorization",
24020
- "RCS.TagsManagement",
24021
- "TestmanagerApiUserAccess",
24022
- "AutomationSolutions",
24023
- "StudioWebTypeCacheService",
24024
- "Docs.GPT.Search",
24025
- "Insights",
24026
- "ReferenceToken",
24027
- "Audit.Read"
24028
- ];
24280
+ var DEFAULT_SCOPES = ["openid", "profile", "offline_access"];
24029
24281
  var normalizeAndValidateBaseUrl = (rawUrl) => {
24030
24282
  let baseUrl = rawUrl;
24031
24283
  if (baseUrl.endsWith("/identity_/")) {
@@ -24075,7 +24327,8 @@ var resolveConfigAsync = async ({
24075
24327
  if (!clientSecret && fileAuth.clientSecret) {
24076
24328
  clientSecret = fileAuth.clientSecret;
24077
24329
  }
24078
- const scopes = customScopes && customScopes.length > 0 ? customScopes : fileAuth.scopes && fileAuth.scopes.length > 0 ? fileAuth.scopes : DEFAULT_SCOPES;
24330
+ const isExternalAppAuth = clientId !== DEFAULT_CLIENT_ID && Boolean(clientSecret);
24331
+ const scopes = customScopes && customScopes.length > 0 ? customScopes : fileAuth.scopes && fileAuth.scopes.length > 0 ? fileAuth.scopes : isExternalAppAuth ? [] : DEFAULT_SCOPES;
24079
24332
  return {
24080
24333
  clientId,
24081
24334
  clientSecret,
@@ -24575,6 +24828,129 @@ function normalizeTokenRefreshFailure() {
24575
24828
  function normalizeTokenRefreshUnavailableFailure() {
24576
24829
  return "token refresh failed before authentication completed";
24577
24830
  }
24831
+ function errorMessage(error) {
24832
+ return error instanceof Error ? error.message : String(error);
24833
+ }
24834
+ function computeExpirationThreshold(ensureTokenValidityMinutes) {
24835
+ return new Date(Date.now() + (ensureTokenValidityMinutes ?? 0) * 60 * 1000);
24836
+ }
24837
+ async function runRefreshLocked(inputs) {
24838
+ const {
24839
+ absolutePath,
24840
+ refreshToken: callerRefreshToken,
24841
+ customAuthority,
24842
+ ensureTokenValidityMinutes,
24843
+ loadEnvFile,
24844
+ saveEnvFile,
24845
+ refreshFn,
24846
+ resolveConfig
24847
+ } = inputs;
24848
+ const expirationThreshold = computeExpirationThreshold(ensureTokenValidityMinutes);
24849
+ let fresh;
24850
+ try {
24851
+ fresh = await loadEnvFile({ envPath: absolutePath });
24852
+ } catch (error) {
24853
+ return {
24854
+ kind: "fail",
24855
+ status: {
24856
+ loginStatus: "Refresh Failed",
24857
+ hint: "Could not read the auth file while refreshing. Retry, or run 'uip login' to re-authenticate.",
24858
+ tokenRefresh: {
24859
+ attempted: false,
24860
+ success: false,
24861
+ errorMessage: `auth file read failed: ${errorMessage(error)}`
24862
+ }
24863
+ }
24864
+ };
24865
+ }
24866
+ const freshAccess = fresh.UIPATH_ACCESS_TOKEN;
24867
+ const freshExp = freshAccess ? getTokenExpiration(freshAccess) : undefined;
24868
+ if (freshAccess && freshExp && freshExp > expirationThreshold) {
24869
+ return {
24870
+ kind: "ok",
24871
+ accessToken: freshAccess,
24872
+ refreshToken: fresh.UIPATH_REFRESH_TOKEN ?? callerRefreshToken,
24873
+ expiration: freshExp,
24874
+ tokenRefresh: { attempted: false, success: true }
24875
+ };
24876
+ }
24877
+ const tokenForIdP = fresh.UIPATH_REFRESH_TOKEN ?? callerRefreshToken;
24878
+ let refreshedAccess;
24879
+ let refreshedRefresh;
24880
+ try {
24881
+ const config = await resolveConfig({ customAuthority });
24882
+ const refreshed = await refreshFn({
24883
+ refreshToken: tokenForIdP,
24884
+ tokenEndpoint: config.tokenEndpoint,
24885
+ clientId: config.clientId,
24886
+ expectedAuthority: customAuthority
24887
+ });
24888
+ refreshedAccess = refreshed.accessToken;
24889
+ refreshedRefresh = refreshed.refreshToken;
24890
+ } catch (error) {
24891
+ const isOAuthFailure = isTokenRefreshOAuthFailure(error);
24892
+ const hint = isOAuthFailure ? "Run 'uip login' to re-authenticate — the stored refresh token is invalid or expired." : "Token refresh failed. Check your network connection, then retry or run 'uip login' to re-authenticate.";
24893
+ const message = isOAuthFailure ? normalizeTokenRefreshFailure() : normalizeTokenRefreshUnavailableFailure();
24894
+ return {
24895
+ kind: "fail",
24896
+ status: {
24897
+ loginStatus: "Refresh Failed",
24898
+ hint,
24899
+ tokenRefresh: {
24900
+ attempted: true,
24901
+ success: false,
24902
+ errorMessage: message
24903
+ }
24904
+ }
24905
+ };
24906
+ }
24907
+ const refreshedExp = getTokenExpiration(refreshedAccess);
24908
+ if (!refreshedExp || refreshedExp <= new Date) {
24909
+ return {
24910
+ kind: "fail",
24911
+ status: {
24912
+ loginStatus: "Refresh Failed",
24913
+ hint: "The identity server returned an unusable token. Run 'uip login' to re-authenticate.",
24914
+ tokenRefresh: {
24915
+ attempted: true,
24916
+ success: false,
24917
+ errorMessage: "refreshed token has no valid expiration claim"
24918
+ }
24919
+ }
24920
+ };
24921
+ }
24922
+ try {
24923
+ await saveEnvFile({
24924
+ envPath: absolutePath,
24925
+ data: {
24926
+ UIPATH_ACCESS_TOKEN: refreshedAccess,
24927
+ UIPATH_REFRESH_TOKEN: refreshedRefresh
24928
+ },
24929
+ merge: true
24930
+ });
24931
+ return {
24932
+ kind: "ok",
24933
+ accessToken: refreshedAccess,
24934
+ refreshToken: refreshedRefresh,
24935
+ expiration: refreshedExp,
24936
+ tokenRefresh: { attempted: true, success: true }
24937
+ };
24938
+ } catch (error) {
24939
+ const msg = errorMessage(error);
24940
+ return {
24941
+ kind: "ok",
24942
+ accessToken: refreshedAccess,
24943
+ refreshToken: refreshedRefresh,
24944
+ expiration: refreshedExp,
24945
+ persistenceWarning: `Access token refreshed in memory but could not be written to ${absolutePath}: ${msg}. The next CLI invocation will fail until the file can be updated — run 'uip login' to re-authenticate.`,
24946
+ tokenRefresh: {
24947
+ attempted: true,
24948
+ success: true,
24949
+ errorMessage: `persistence failed: ${msg}`
24950
+ }
24951
+ };
24952
+ }
24953
+ }
24578
24954
  var getLoginStatusWithDeps = async (options = {}, deps = {}) => {
24579
24955
  const {
24580
24956
  resolveEnvFilePath = resolveEnvFilePathAsync,
@@ -24649,73 +25025,103 @@ var getLoginStatusWithDeps = async (options = {}, deps = {}) => {
24649
25025
  let refreshToken = credentials.UIPATH_REFRESH_TOKEN;
24650
25026
  let expiration = getTokenExpiration(accessToken);
24651
25027
  let persistenceWarning;
25028
+ let lockReleaseFailed = false;
24652
25029
  let tokenRefresh;
24653
- const expirationThreshold = new Date(Date.now() + (ensureTokenValidityMinutes ?? 0) * 60 * 1000);
24654
- if (expiration && expiration <= expirationThreshold && refreshToken) {
24655
- let refreshedAccess;
24656
- let refreshedRefresh;
25030
+ const outerThreshold = computeExpirationThreshold(ensureTokenValidityMinutes);
25031
+ const tryGlobalCredsHint = async () => {
25032
+ const fs7 = getFs();
25033
+ const globalPath = fs7.path.join(fs7.env.homedir(), envFilePath);
25034
+ if (absolutePath === globalPath)
25035
+ return;
25036
+ if (!await fs7.exists(globalPath))
25037
+ return;
24657
25038
  try {
24658
- const config = await resolveConfig({
24659
- customAuthority: credentials.UIPATH_URL
24660
- });
24661
- const refreshed = await refreshTokenFn({
24662
- refreshToken,
24663
- tokenEndpoint: config.tokenEndpoint,
24664
- clientId: config.clientId,
24665
- expectedAuthority: credentials.UIPATH_URL
24666
- });
24667
- refreshedAccess = refreshed.accessToken;
24668
- refreshedRefresh = refreshed.refreshToken;
24669
- } catch (error) {
24670
- const isOAuthFailure = isTokenRefreshOAuthFailure(error);
24671
- const hint = isOAuthFailure ? "Run 'uip login' to re-authenticate — the stored refresh token is invalid or expired." : "Token refresh failed. Check your network connection, then retry or run 'uip login' to re-authenticate.";
24672
- const errorMessage = isOAuthFailure ? normalizeTokenRefreshFailure() : normalizeTokenRefreshUnavailableFailure();
24673
- return {
24674
- loginStatus: "Refresh Failed",
24675
- hint,
24676
- tokenRefresh: {
24677
- attempted: true,
24678
- success: false,
24679
- errorMessage
24680
- }
24681
- };
25039
+ const globalCreds = await loadEnvFile({ envPath: globalPath });
25040
+ if (!globalCreds.UIPATH_ACCESS_TOKEN)
25041
+ return;
25042
+ const globalExp = getTokenExpiration(globalCreds.UIPATH_ACCESS_TOKEN);
25043
+ if (globalExp && globalExp <= new Date)
25044
+ return;
25045
+ return `Local credentials file at ${absolutePath} has expired credentials. Valid credentials exist in ${globalPath}. Remove the local file or run 'uip login' to re-authenticate.`;
25046
+ } catch {
25047
+ return;
24682
25048
  }
24683
- const refreshedExp = getTokenExpiration(refreshedAccess);
24684
- if (!refreshedExp || refreshedExp <= new Date) {
25049
+ };
25050
+ if (expiration && expiration <= outerThreshold && refreshToken) {
25051
+ let release;
25052
+ try {
25053
+ release = await getFs().acquireLock(absolutePath);
25054
+ } catch (error) {
25055
+ const msg = errorMessage(error);
25056
+ const globalHint = await tryGlobalCredsHint();
25057
+ if (globalHint) {
25058
+ return {
25059
+ loginStatus: "Expired",
25060
+ accessToken,
25061
+ refreshToken,
25062
+ baseUrl: credentials.UIPATH_URL,
25063
+ organizationName: credentials.UIPATH_ORGANIZATION_NAME,
25064
+ organizationId: credentials.UIPATH_ORGANIZATION_ID,
25065
+ tenantName: credentials.UIPATH_TENANT_NAME,
25066
+ tenantId: credentials.UIPATH_TENANT_ID,
25067
+ expiration,
25068
+ source: "file" /* File */,
25069
+ hint: globalHint,
25070
+ tokenRefresh: {
25071
+ attempted: false,
25072
+ success: false,
25073
+ errorMessage: `lock acquisition failed: ${msg}`
25074
+ }
25075
+ };
25076
+ }
24685
25077
  return {
24686
25078
  loginStatus: "Refresh Failed",
24687
- hint: "The identity server returned an unusable token. Run 'uip login' to re-authenticate.",
25079
+ hint: "Could not acquire the auth-file lock — too many concurrent `uip` processes, or a permission issue on the auth directory. Retry, or run 'uip login' to re-authenticate.",
24688
25080
  tokenRefresh: {
24689
- attempted: true,
25081
+ attempted: false,
24690
25082
  success: false,
24691
- errorMessage: "refreshed token has no valid expiration claim"
25083
+ errorMessage: `lock acquisition failed: ${msg}`
24692
25084
  }
24693
25085
  };
24694
25086
  }
24695
- accessToken = refreshedAccess;
24696
- refreshToken = refreshedRefresh;
24697
- expiration = refreshedExp;
25087
+ let lockedFailure;
24698
25088
  try {
24699
- await saveEnvFile({
24700
- envPath: absolutePath,
24701
- data: {
24702
- UIPATH_ACCESS_TOKEN: accessToken,
24703
- UIPATH_REFRESH_TOKEN: refreshToken
24704
- },
24705
- merge: true
25089
+ const outcome = await runRefreshLocked({
25090
+ absolutePath,
25091
+ refreshToken,
25092
+ customAuthority: credentials.UIPATH_URL,
25093
+ ensureTokenValidityMinutes,
25094
+ loadEnvFile,
25095
+ saveEnvFile,
25096
+ refreshFn: refreshTokenFn,
25097
+ resolveConfig
24706
25098
  });
24707
- tokenRefresh = {
24708
- attempted: true,
24709
- success: true
24710
- };
24711
- } catch (error) {
24712
- const msg = error instanceof Error ? error.message : String(error);
24713
- persistenceWarning = `Access token refreshed in memory but could not be written to ${absolutePath}: ${msg}. The next CLI invocation will fail until the file can be updated — run 'uip login' to re-authenticate.`;
24714
- tokenRefresh = {
24715
- attempted: true,
24716
- success: true,
24717
- errorMessage: `persistence failed: ${msg}`
24718
- };
25099
+ if (outcome.kind === "fail") {
25100
+ lockedFailure = outcome.status;
25101
+ } else {
25102
+ accessToken = outcome.accessToken;
25103
+ refreshToken = outcome.refreshToken;
25104
+ expiration = outcome.expiration;
25105
+ tokenRefresh = outcome.tokenRefresh;
25106
+ if (outcome.persistenceWarning) {
25107
+ persistenceWarning = outcome.persistenceWarning;
25108
+ }
25109
+ }
25110
+ } finally {
25111
+ try {
25112
+ await release();
25113
+ } catch {
25114
+ lockReleaseFailed = true;
25115
+ }
25116
+ }
25117
+ if (lockedFailure) {
25118
+ const globalHint = await tryGlobalCredsHint();
25119
+ const base = globalHint ? {
25120
+ ...lockedFailure,
25121
+ loginStatus: "Expired",
25122
+ hint: globalHint
25123
+ } : lockedFailure;
25124
+ return lockReleaseFailed ? { ...base, lockReleaseFailed: true } : base;
24719
25125
  }
24720
25126
  }
24721
25127
  const result = {
@@ -24730,23 +25136,13 @@ var getLoginStatusWithDeps = async (options = {}, deps = {}) => {
24730
25136
  expiration,
24731
25137
  source: "file" /* File */,
24732
25138
  ...persistenceWarning ? { hint: persistenceWarning, persistenceFailed: true } : {},
25139
+ ...lockReleaseFailed ? { lockReleaseFailed: true } : {},
24733
25140
  ...tokenRefresh ? { tokenRefresh } : {}
24734
25141
  };
24735
25142
  if (result.loginStatus === "Expired") {
24736
- const fs7 = getFs();
24737
- const globalPath = fs7.path.join(fs7.env.homedir(), envFilePath);
24738
- if (absolutePath !== globalPath && await fs7.exists(globalPath)) {
24739
- try {
24740
- const globalCreds = await loadEnvFile({
24741
- envPath: globalPath
24742
- });
24743
- if (globalCreds.UIPATH_ACCESS_TOKEN) {
24744
- const globalExp = getTokenExpiration(globalCreds.UIPATH_ACCESS_TOKEN);
24745
- if (!globalExp || globalExp > new Date) {
24746
- result.hint = `Local credentials file at ${absolutePath} has expired credentials. Valid credentials exist in ${globalPath}. Remove the local file or run 'uip login' to re-authenticate.`;
24747
- }
24748
- }
24749
- } catch {}
25143
+ const globalHint = await tryGlobalCredsHint();
25144
+ if (globalHint) {
25145
+ result.hint = globalHint;
24750
25146
  }
24751
25147
  }
24752
25148
  return result;
@@ -24763,6 +25159,10 @@ var getLoginStatusAsync = async (options = {}) => {
24763
25159
  init_src();
24764
25160
  // ../../auth/src/logout.ts
24765
25161
  init_src();
25162
+
25163
+ // ../../auth/src/index.ts
25164
+ init_server();
25165
+
24766
25166
  // ../audit-sdk/src/client-factory.ts
24767
25167
  async function createAuditConfig(options) {
24768
25168
  const status = await getLoginStatusAsync({
@@ -24789,7 +25189,8 @@ async function createAuditConfig(options) {
24789
25189
  const bearerToken = options.s2sToken ?? status.accessToken;
24790
25190
  return new Configuration({
24791
25191
  basePath,
24792
- apiKey: () => `Bearer ${bearerToken}`
25192
+ apiKey: () => `Bearer ${bearerToken}`,
25193
+ headers: addSdkUserAgentHeader(undefined, SDK_USER_AGENT)
24793
25194
  });
24794
25195
  }
24795
25196
  async function createApiClient(ApiClass, options) {
@@ -24933,10 +25334,15 @@ async function extractErrorDetails(error, options) {
24933
25334
  }
24934
25335
  if (parsedBody?.errorCode && typeof parsedBody.errorCode === "string") {
24935
25336
  context.errorCode = parsedBody.errorCode;
25337
+ } else if (parsedBody?.code && typeof parsedBody.code === "string") {
25338
+ context.errorCode = parsedBody.code;
24936
25339
  }
24937
25340
  if (parsedBody?.requestId && typeof parsedBody.requestId === "string") {
24938
25341
  context.requestId = parsedBody.requestId;
24939
25342
  }
25343
+ if (parsedBody?.traceId && typeof parsedBody.traceId === "string") {
25344
+ context.traceId = parsedBody.traceId;
25345
+ }
24940
25346
  if (status === 429) {
24941
25347
  const resp = response;
24942
25348
  const headersObj = resp?.headers;
@@ -24956,7 +25362,35 @@ async function extractErrorDetails(error, options) {
24956
25362
  }
24957
25363
  }
24958
25364
  const hasContext = Object.keys(context).length > 0;
24959
- return { result, message, details, ...hasContext ? { context } : {} };
25365
+ let parsedErrors;
25366
+ if (parsedBody?.errors && typeof parsedBody.errors === "object") {
25367
+ const errors = {};
25368
+ for (const [field, raw] of Object.entries(parsedBody.errors)) {
25369
+ if (Array.isArray(raw)) {
25370
+ const messages = raw.map((entry) => {
25371
+ if (typeof entry === "string")
25372
+ return entry;
25373
+ if (entry && typeof entry === "object" && typeof entry.message === "string") {
25374
+ return entry.message;
25375
+ }
25376
+ return String(entry);
25377
+ }).filter(Boolean);
25378
+ if (messages.length > 0)
25379
+ errors[field] = messages;
25380
+ } else if (typeof raw === "string") {
25381
+ errors[field] = [raw];
25382
+ }
25383
+ }
25384
+ if (Object.keys(errors).length > 0)
25385
+ parsedErrors = errors;
25386
+ }
25387
+ return {
25388
+ result,
25389
+ message,
25390
+ details,
25391
+ ...hasContext ? { context } : {},
25392
+ ...parsedErrors ? { parsedErrors } : {}
25393
+ };
24960
25394
  }
24961
25395
  async function extractErrorMessage(error, options) {
24962
25396
  const { message } = await extractErrorDetails(error, options);
@@ -24968,36 +25402,6 @@ Command.prototype.examples = function(examples) {
24968
25402
  examplesByCommand.set(this, examples);
24969
25403
  return this;
24970
25404
  };
24971
- // ../../common/src/singleton.ts
24972
- var PREFIX = "@uipath/common/";
24973
- var _g = globalThis;
24974
- function singleton(ctorOrName) {
24975
- const name = typeof ctorOrName === "string" ? ctorOrName : ctorOrName.name;
24976
- const key = Symbol.for(PREFIX + name);
24977
- return {
24978
- get(fallback) {
24979
- return _g[key] ?? fallback;
24980
- },
24981
- set(value) {
24982
- _g[key] = value;
24983
- },
24984
- clear() {
24985
- delete _g[key];
24986
- },
24987
- getOrInit(factory, guard) {
24988
- const existing = _g[key];
24989
- if (existing != null && typeof existing === "object") {
24990
- if (!guard || guard(existing)) {
24991
- return existing;
24992
- }
24993
- }
24994
- const instance = factory();
24995
- _g[key] = instance;
24996
- return instance;
24997
- }
24998
- };
24999
- }
25000
-
25001
25405
  // ../../common/src/output-context.ts
25002
25406
  function createStorage() {
25003
25407
  const [error, mod] = catchError2(() => __require("node:async_hooks"));
@@ -30087,6 +30491,60 @@ function escapeNonAscii(jsonText) {
30087
30491
  function needsAsciiSafeJson(sink) {
30088
30492
  return process.platform === "win32" && !sink.capabilities.isInteractive;
30089
30493
  }
30494
+ function isPlainRecord(value) {
30495
+ if (value === null || typeof value !== "object")
30496
+ return false;
30497
+ const prototype = Object.getPrototypeOf(value);
30498
+ return prototype === Object.prototype || prototype === null;
30499
+ }
30500
+ function toLowerCamelCaseKey(key) {
30501
+ if (!key)
30502
+ return key;
30503
+ if (/[_\-\s]/.test(key)) {
30504
+ const [firstPart, ...restParts] = key.split(/[_\-\s]+/).filter(Boolean);
30505
+ if (!firstPart)
30506
+ return key;
30507
+ return [
30508
+ toLowerCamelCaseSimpleKey(firstPart),
30509
+ ...restParts.map((part) => {
30510
+ const normalized = toLowerCamelCaseSimpleKey(part);
30511
+ return normalized.charAt(0).toUpperCase() + normalized.slice(1);
30512
+ })
30513
+ ].join("");
30514
+ }
30515
+ return toLowerCamelCaseSimpleKey(key);
30516
+ }
30517
+ function toLowerCamelCaseSimpleKey(key) {
30518
+ if (/^[A-Z0-9]+$/.test(key))
30519
+ return key.toLowerCase();
30520
+ return key.replace(/^[A-Z]+(?=[A-Z][a-z]|\d|$)|^[A-Z]/, (match) => match.toLowerCase());
30521
+ }
30522
+ function toPascalCaseKey(key) {
30523
+ const lowerCamelKey = toLowerCamelCaseKey(key);
30524
+ return lowerCamelKey ? lowerCamelKey.charAt(0).toUpperCase() + lowerCamelKey.slice(1) : lowerCamelKey;
30525
+ }
30526
+ function toPascalCaseData(value) {
30527
+ if (Array.isArray(value))
30528
+ return value.map(toPascalCaseData);
30529
+ if (!isPlainRecord(value))
30530
+ return value;
30531
+ const result = {};
30532
+ for (const [key, nestedValue] of Object.entries(value)) {
30533
+ result[toPascalCaseKey(key)] = toPascalCaseData(nestedValue);
30534
+ }
30535
+ return result;
30536
+ }
30537
+ function normalizeDataKeys(data) {
30538
+ return toPascalCaseData(data);
30539
+ }
30540
+ function normalizeOutputKeys(data) {
30541
+ const result = {};
30542
+ for (const [key, value] of Object.entries(data)) {
30543
+ const pascalKey = toPascalCaseKey(key);
30544
+ result[pascalKey] = pascalKey === "Data" ? value : toPascalCaseData(value);
30545
+ }
30546
+ return result;
30547
+ }
30090
30548
  function printOutput(data, format = "json", logFn, asciiSafe = false) {
30091
30549
  if (!data) {
30092
30550
  logFn("Empty response object. No data to display.");
@@ -30149,7 +30607,7 @@ function wrapText(text, width) {
30149
30607
  function printTable(data, logFn, externalLogValue) {
30150
30608
  if (data.length === 0)
30151
30609
  return;
30152
- const keys = Object.keys(data[0]).filter((key) => key !== "Code" && key !== "Log");
30610
+ const keys = Object.keys(data[0]).filter((key) => !["code", "log"].includes(key.toLowerCase()));
30153
30611
  const maxWidths = keys.map((key) => Math.max(key.length, ...data.map((item) => cellToString(item[key]).length)));
30154
30612
  const header = keys.map((key, i2) => key.padEnd(maxWidths[i2])).join(" | ");
30155
30613
  logFn(header);
@@ -30164,7 +30622,7 @@ function printTable(data, logFn, externalLogValue) {
30164
30622
  }
30165
30623
  }
30166
30624
  function printVerticalTable(data, logFn = console.log, externalLogValue) {
30167
- const keys = Object.keys(data).filter((key) => key !== "Code" && key !== "Log");
30625
+ const keys = Object.keys(data).filter((key) => !["code", "log"].includes(key.toLowerCase()));
30168
30626
  if (keys.length === 0)
30169
30627
  return;
30170
30628
  const maxKeyWidth = Math.max(...keys.map((key) => key.length));
@@ -30180,7 +30638,7 @@ function printVerticalTable(data, logFn = console.log, externalLogValue) {
30180
30638
  function printResizableTable(data, logFn = console.log, externalLogValue) {
30181
30639
  if (data.length === 0)
30182
30640
  return;
30183
- const keys = Object.keys(data[0]).filter((key) => key !== "Code" && key !== "Log");
30641
+ const keys = Object.keys(data[0]).filter((key) => !["code", "log"].includes(key.toLowerCase()));
30184
30642
  if (keys.length === 0)
30185
30643
  return;
30186
30644
  if (!process.stdout.isTTY) {
@@ -30256,8 +30714,26 @@ function printResizableTable(data, logFn = console.log, externalLogValue) {
30256
30714
  function toYaml(data) {
30257
30715
  return dump(data);
30258
30716
  }
30717
+ class FilterEvaluationError extends Error {
30718
+ __brand = "FilterEvaluationError";
30719
+ filter;
30720
+ instructions;
30721
+ result = RESULTS.ValidationError;
30722
+ constructor(filter, cause) {
30723
+ const underlying = cause instanceof Error ? cause.message : String(cause);
30724
+ super(`Filter '${filter}' failed to evaluate: ${underlying}`);
30725
+ this.name = "FilterEvaluationError";
30726
+ this.filter = filter;
30727
+ this.instructions = `The --output-filter expression '${filter}' failed at evaluation time. ` + "Note that --output-filter operates on the 'Data' field of the envelope, not the full object. " + "For example, on a list result use 'length(@)' instead of 'Data | length(@)'.";
30728
+ }
30729
+ }
30259
30730
  function applyFilter(data, filter) {
30260
- const result = search(data, filter);
30731
+ let result;
30732
+ try {
30733
+ result = search(data, filter);
30734
+ } catch (err) {
30735
+ throw new FilterEvaluationError(filter, err);
30736
+ }
30261
30737
  if (result == null)
30262
30738
  return [];
30263
30739
  if (Array.isArray(result)) {
@@ -30274,13 +30750,18 @@ function applyFilter(data, filter) {
30274
30750
  }
30275
30751
  var OutputFormatter;
30276
30752
  ((OutputFormatter) => {
30277
- function success(data) {
30753
+ function success(data, options) {
30278
30754
  data.Log ??= getLogFilePath() || undefined;
30755
+ const normalize = !options?.preserveDataKeys;
30756
+ if (normalize) {
30757
+ data.Data = normalizeDataKeys(data.Data);
30758
+ }
30279
30759
  const filter = getOutputFilter();
30280
30760
  if (filter) {
30281
- data.Data = applyFilter(data.Data, filter);
30761
+ const filtered = applyFilter(data.Data, filter);
30762
+ data.Data = normalize ? normalizeDataKeys(filtered) : filtered;
30282
30763
  }
30283
- logOutput(data, getOutputFormat());
30764
+ logOutput(normalizeOutputKeys(data), getOutputFormat());
30284
30765
  }
30285
30766
  OutputFormatter.success = success;
30286
30767
  function error(data) {
@@ -30290,7 +30771,7 @@ var OutputFormatter;
30290
30771
  result: data.Result,
30291
30772
  message: data.Message
30292
30773
  });
30293
- logOutput(data, getOutputFormat());
30774
+ logOutput(normalizeOutputKeys(data), getOutputFormat());
30294
30775
  }
30295
30776
  OutputFormatter.error = error;
30296
30777
  function emitList(code, items, opts) {
@@ -30311,13 +30792,14 @@ var OutputFormatter;
30311
30792
  function log(data) {
30312
30793
  const format = getOutputFormat();
30313
30794
  const sink = getOutputSink();
30795
+ const normalized = toPascalCaseData(data);
30314
30796
  if (format === "json") {
30315
- const json2 = JSON.stringify(data);
30797
+ const json2 = JSON.stringify(normalized);
30316
30798
  const safe = needsAsciiSafeJson(sink) ? escapeNonAscii(json2) : json2;
30317
30799
  sink.writeErr(`${safe}
30318
30800
  `);
30319
30801
  } else {
30320
- for (const [key, value] of Object.entries(data)) {
30802
+ for (const [key, value] of Object.entries(normalized)) {
30321
30803
  sink.writeErr(`${key}: ${value}
30322
30804
  `);
30323
30805
  }
@@ -30326,12 +30808,16 @@ var OutputFormatter;
30326
30808
  OutputFormatter.log = log;
30327
30809
  function formatToString(data) {
30328
30810
  const filter = getOutputFilter();
30329
- if (filter && "Data" in data && data.Data != null) {
30330
- data.Data = applyFilter(data.Data, filter);
30811
+ if ("Data" in data && data.Data != null) {
30812
+ data.Data = normalizeDataKeys(data.Data);
30813
+ if (filter) {
30814
+ data.Data = normalizeDataKeys(applyFilter(data.Data, filter));
30815
+ }
30331
30816
  }
30817
+ const output = normalizeOutputKeys(data);
30332
30818
  const lines = [];
30333
30819
  const sink = getOutputSink();
30334
- printOutput(data, getOutputFormat(), (msg) => {
30820
+ printOutput(output, getOutputFormat(), (msg) => {
30335
30821
  lines.push(msg);
30336
30822
  }, needsAsciiSafeJson(sink));
30337
30823
  return lines.join(`
@@ -31760,6 +32246,22 @@ function parseBoundedInt(raw, optionName, bounds) {
31760
32246
  }
31761
32247
  return n;
31762
32248
  }
32249
+ // ../../common/src/polling/types.ts
32250
+ var PollOutcome = {
32251
+ Completed: "completed",
32252
+ Timeout: "timeout",
32253
+ Interrupted: "interrupted",
32254
+ Aborted: "aborted",
32255
+ Failed: "failed"
32256
+ };
32257
+
32258
+ // ../../common/src/polling/poll-failure-mapping.ts
32259
+ var REASON_BY_OUTCOME = {
32260
+ [PollOutcome.Timeout]: "poll_timeout",
32261
+ [PollOutcome.Failed]: "poll_failed",
32262
+ [PollOutcome.Interrupted]: "poll_failed",
32263
+ [PollOutcome.Aborted]: "poll_aborted"
32264
+ };
31763
32265
  // ../../common/src/polling/terminal-statuses.ts
31764
32266
  var TERMINAL_STATUSES = new Set([
31765
32267
  "completed",
@@ -31965,17 +32467,21 @@ Command.prototype.trackedAction = function(context, fn, properties) {
31965
32467
  const telemetryName = deriveCommandPath(command);
31966
32468
  const props = typeof properties === "function" ? properties(...args) : properties;
31967
32469
  const startTime = performance.now();
31968
- let errorMessage;
32470
+ let errorMessage2;
31969
32471
  const [error] = await catchError2(fn(...args));
31970
32472
  if (error) {
31971
- errorMessage = error instanceof Error ? error.message : String(error);
31972
- logger.error(`[trackedAction] ${telemetryName} failed: ${errorMessage}`);
32473
+ errorMessage2 = error instanceof Error ? error.message : String(error);
32474
+ logger.debug(`[trackedAction] ${telemetryName} failed: ${errorMessage2}`);
32475
+ const typed = error;
32476
+ const customInstructions = typeof typed.instructions === "string" ? typed.instructions : undefined;
32477
+ const customResult = typeof typed.result === "string" && typed.result !== RESULTS.Success && Object.values(RESULTS).includes(typed.result) ? typed.result : undefined;
32478
+ const finalResult = customResult ?? RESULTS.Failure;
31973
32479
  OutputFormatter.error({
31974
- Result: RESULTS.Failure,
31975
- Message: errorMessage,
31976
- Instructions: "An unexpected error occurred. Run with --log-level debug for details."
32480
+ Result: finalResult,
32481
+ Message: errorMessage2,
32482
+ Instructions: customInstructions ?? "An unexpected error occurred. Run with --log-level debug for details."
31977
32483
  });
31978
- context.exit(1);
32484
+ context.exit(EXIT_CODES[finalResult]);
31979
32485
  }
31980
32486
  const durationMs = performance.now() - startTime;
31981
32487
  const success = !error && (process.exitCode === undefined || process.exitCode === 0);
@@ -31984,7 +32490,7 @@ Command.prototype.trackedAction = function(context, fn, properties) {
31984
32490
  ...props,
31985
32491
  duration: String(durationMs),
31986
32492
  success: String(success),
31987
- ...errorMessage ? { errorMessage } : {}
32493
+ ...errorMessage2 ? { errorMessage: errorMessage2 } : {}
31988
32494
  }));
31989
32495
  });
31990
32496
  };