@getmagical/cli 0.1.13 → 0.1.16

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/README.md CHANGED
@@ -69,10 +69,6 @@ Once installed, users can update from the same channel with:
69
69
  mgcl --update
70
70
  ```
71
71
 
72
- Installed CLIs also check the configured npm dist-tag before running
73
- subcommands. If the local version is behind, `mgcl` blocks the command and
74
- asks the user to run `mgcl update` before rerunning it.
75
-
76
72
  To remove the managed install:
77
73
 
78
74
  ```bash
package/dist/index.js CHANGED
@@ -6885,6 +6885,7 @@ function getErrorMessage(error) {
6885
6885
  }
6886
6886
 
6887
6887
  // src/program.ts
6888
+ import { readFile as readFile4 } from "fs/promises";
6888
6889
  import path6 from "path";
6889
6890
 
6890
6891
  // ../common/dist/src/stdlib/json.util.js
@@ -7693,6 +7694,8 @@ var operationSpecs = [
7693
7694
  query GetAgents($ids: [ID!]!) {
7694
7695
  agents(ids: $ids) {
7695
7696
  id
7697
+ agentVersionId
7698
+ automationVersionId
7696
7699
  name
7697
7700
  description
7698
7701
  instructions
@@ -7714,6 +7717,7 @@ ${agentLimitationsSelection}
7714
7717
  taskQueue
7715
7718
  waitUponQueueing
7716
7719
  queueableAgentIds
7720
+ systemPrompt
7717
7721
  additionalSystemPrompt
7718
7722
  ignoreUnstableSessionState
7719
7723
  }
@@ -7777,6 +7781,7 @@ ${agentLimitationsSelection}
7777
7781
  taskQueue
7778
7782
  waitUponQueueing
7779
7783
  queueableAgentIds
7784
+ systemPrompt
7780
7785
  additionalSystemPrompt
7781
7786
  ignoreUnstableSessionState
7782
7787
  }
@@ -7939,7 +7944,9 @@ query GetAgentRun($id: ID!) {
7939
7944
  query GetAutomationAgents($ids: [ID!]!) {
7940
7945
  automationAgents(ids: $ids) {
7941
7946
  automationId
7947
+ automationVersionId
7942
7948
  agentId
7949
+ agentVersionId
7943
7950
  isTrigger
7944
7951
  agent {
7945
7952
  id
@@ -8664,13 +8671,15 @@ mutation StopAutomationRun($automationRunId: ID!) {
8664
8671
  jsonOption({
8665
8672
  inputKey: "input",
8666
8673
  flagName: "input-json",
8667
- description: "UpdateAutomationInput payload.",
8674
+ description: "UpdateAutomationInput payload. Must include baseVersionId from a fresh automations get/list call.",
8668
8675
  required: true
8669
8676
  })
8670
8677
  ]
8671
8678
  },
8672
8679
  mcp: { fileName: "updateAutomation.graphql" },
8673
8680
  document: `# Mutation to update an automation
8681
+ # Before calling, fetch the automation and agents again. Pass the fetched draftVersionId as input.baseVersionId.
8682
+ # If this mutation returns a draft-automation-version-conflict, discard the generated update, refetch the automation and agents, inspect what changed, then regenerate the update on top of the latest version.
8674
8683
  # Returns only id and lastSavedAt for MCP tool simplicity
8675
8684
  mutation UpdateAutomationById($id: ID!, $input: UpdateAutomationInput!) {
8676
8685
  updateAutomation(id: $id, input: $input) {
@@ -8686,6 +8695,8 @@ import { Command as Command2, InvalidArgumentError as InvalidArgumentError2, Opt
8686
8695
 
8687
8696
  // src/api.ts
8688
8697
  import { z as z3 } from "zod";
8698
+ var OTTO_AUTHORIZATION_HEADER_NAME = "X-Otto-Authorization";
8699
+ var OTTO_AUTHORIZATION_ISSUER = "magical:otto";
8689
8700
  var workosOrganizationsResponseSchema = z3.object({
8690
8701
  organizations: z3.array(
8691
8702
  z3.object({
@@ -8752,6 +8763,50 @@ function getApiErrorDetail(responseBody) {
8752
8763
  function trimTrailingSlash(value) {
8753
8764
  return value.replace(/\/+$/u, "");
8754
8765
  }
8766
+ function isRecord2(value) {
8767
+ return typeof value === "object" && value !== null && !Array.isArray(value);
8768
+ }
8769
+ function decodeJwtPayload(token) {
8770
+ const [, payloadSegment] = token.split(".");
8771
+ if (!payloadSegment) {
8772
+ return null;
8773
+ }
8774
+ const payloadResult = safeJsonParse(
8775
+ Buffer.from(payloadSegment, "base64url").toString("utf8")
8776
+ );
8777
+ if (isErr(payloadResult)) {
8778
+ return null;
8779
+ }
8780
+ return isRecord2(payloadResult.value) ? payloadResult.value : null;
8781
+ }
8782
+ function isOttoAuthorizationToken(token) {
8783
+ return decodeJwtPayload(token)?.["iss"] === OTTO_AUTHORIZATION_ISSUER;
8784
+ }
8785
+ function applyAuthenticationHeaders({
8786
+ accessToken,
8787
+ allowOttoAuthorization,
8788
+ headers,
8789
+ impersonatedOrganizationId,
8790
+ organizationId
8791
+ }) {
8792
+ if (!isOttoAuthorizationToken(accessToken)) {
8793
+ headers.set("authorization", `Bearer ${accessToken}`);
8794
+ if (impersonatedOrganizationId) {
8795
+ headers.set("x-organization-id", impersonatedOrganizationId);
8796
+ }
8797
+ return;
8798
+ }
8799
+ if (!allowOttoAuthorization) {
8800
+ throw new CliError(
8801
+ "Otto authorization is only supported for GraphQL requests."
8802
+ );
8803
+ }
8804
+ if (!organizationId) {
8805
+ throw new CliError("Otto authorization requires an organization ID.");
8806
+ }
8807
+ headers.set(OTTO_AUTHORIZATION_HEADER_NAME, `Bearer ${accessToken}`);
8808
+ headers.set("x-organization-id", organizationId);
8809
+ }
8755
8810
  function createMagicalApiClient({
8756
8811
  apiBaseUrl,
8757
8812
  fetchFn = fetch
@@ -8759,12 +8814,21 @@ function createMagicalApiClient({
8759
8814
  const resolveApiBaseUrl = typeof apiBaseUrl === "string" ? () => apiBaseUrl : apiBaseUrl;
8760
8815
  async function fetchJson({
8761
8816
  accessToken,
8817
+ impersonatedOrganizationId,
8818
+ allowOttoAuthorization,
8762
8819
  path: path7,
8763
- init
8820
+ init,
8821
+ organizationId
8764
8822
  }) {
8765
8823
  const url = `${trimTrailingSlash(await resolveApiBaseUrl())}${path7}`;
8766
8824
  const headers = new Headers(init?.headers);
8767
- headers.set("authorization", `Bearer ${accessToken}`);
8825
+ applyAuthenticationHeaders({
8826
+ accessToken,
8827
+ ...allowOttoAuthorization ? { allowOttoAuthorization } : {},
8828
+ headers,
8829
+ ...impersonatedOrganizationId ? { impersonatedOrganizationId } : {},
8830
+ ...organizationId ? { organizationId } : {}
8831
+ });
8768
8832
  const response = await fetchFn(url, {
8769
8833
  ...init,
8770
8834
  headers
@@ -8801,6 +8865,8 @@ function createMagicalApiClient({
8801
8865
  return {
8802
8866
  async executeGraphQl({
8803
8867
  accessToken,
8868
+ impersonatedOrganizationId,
8869
+ organizationId,
8804
8870
  query,
8805
8871
  resultKey,
8806
8872
  variables
@@ -8810,6 +8876,9 @@ function createMagicalApiClient({
8810
8876
  const parsedResponse = graphQlResponseSchema.safeParse(
8811
8877
  await fetchJson({
8812
8878
  accessToken,
8879
+ ...impersonatedOrganizationId ? { impersonatedOrganizationId } : {},
8880
+ allowOttoAuthorization: true,
8881
+ ...organizationId ? { organizationId } : {},
8813
8882
  path: "/graphql",
8814
8883
  init: {
8815
8884
  method: "POST",
@@ -8849,11 +8918,13 @@ function createMagicalApiClient({
8849
8918
  },
8850
8919
  async fetchUser({
8851
8920
  accessToken,
8921
+ organizationId,
8852
8922
  userId
8853
8923
  }) {
8854
8924
  const parsedResponse = workosUserSchema.safeParse(
8855
8925
  await fetchJson({
8856
8926
  accessToken,
8927
+ ...organizationId ? { organizationId } : {},
8857
8928
  path: `/workos/user/${userId}`
8858
8929
  })
8859
8930
  );
@@ -8863,11 +8934,15 @@ function createMagicalApiClient({
8863
8934
  return parsedResponse.data;
8864
8935
  },
8865
8936
  async listNangoIntegrations({
8866
- accessToken
8937
+ accessToken,
8938
+ impersonatedOrganizationId,
8939
+ organizationId
8867
8940
  }) {
8868
8941
  const parsedResponse = nangoIntegrationsResponseSchema.safeParse(
8869
8942
  await fetchJson({
8870
8943
  accessToken,
8944
+ ...impersonatedOrganizationId ? { impersonatedOrganizationId } : {},
8945
+ ...organizationId ? { organizationId } : {},
8871
8946
  path: "/nango/integrations"
8872
8947
  })
8873
8948
  );
@@ -8877,11 +8952,15 @@ function createMagicalApiClient({
8877
8952
  return parsedResponse.data;
8878
8953
  },
8879
8954
  async listNangoAuthentications({
8880
- accessToken
8955
+ accessToken,
8956
+ impersonatedOrganizationId,
8957
+ organizationId
8881
8958
  }) {
8882
8959
  const parsedResponse = organizationAuthenticationsResponseSchema.safeParse(
8883
8960
  await fetchJson({
8884
8961
  accessToken,
8962
+ ...impersonatedOrganizationId ? { impersonatedOrganizationId } : {},
8963
+ ...organizationId ? { organizationId } : {},
8885
8964
  path: "/authentications/organization?type=nangoConnection"
8886
8965
  })
8887
8966
  );
@@ -9199,6 +9278,22 @@ function resolveOpenCommand(url) {
9199
9278
 
9200
9279
  // src/program-session.ts
9201
9280
  import { readFile as readFile2, rm as rm2 } from "fs/promises";
9281
+
9282
+ // ../common/dist/src/stdlib/url.utils.js
9283
+ var import_handlebars = __toESM(require_lib(), 1);
9284
+ function safeUrlConstructor(url, baseUrl) {
9285
+ try {
9286
+ return Ok(baseUrl ? new URL(url, baseUrl) : new URL(url));
9287
+ } catch {
9288
+ return Err({
9289
+ type: "invalid-url",
9290
+ message: `Invalid URL`,
9291
+ url
9292
+ });
9293
+ }
9294
+ }
9295
+
9296
+ // src/program-session.ts
9202
9297
  async function withOrgScopedAccessToken({
9203
9298
  dependencies,
9204
9299
  organizationId,
@@ -9263,10 +9358,20 @@ async function loadDirectAccessToken({
9263
9358
  if (!accessTokenFileContents) {
9264
9359
  return null;
9265
9360
  }
9266
- const claims = dependencies.authClient.decodeAccessTokenClaims(
9267
- accessTokenFileContents
9361
+ const claimsResult = fromThrowable(
9362
+ () => dependencies.authClient.decodeAccessTokenClaims(accessTokenFileContents),
9363
+ "decode-otto-session-access-token-failed"
9268
9364
  );
9365
+ if (isErr(claimsResult)) {
9366
+ return null;
9367
+ }
9368
+ const claims = claimsResult.value;
9269
9369
  if (isExpiredAccessTokenClaims(claims)) {
9370
+ if (claims.iss === "magical:otto") {
9371
+ throw new CliError(
9372
+ "The Otto session authorization token expired. Start a new Otto session from Magical."
9373
+ );
9374
+ }
9270
9375
  return null;
9271
9376
  }
9272
9377
  if (claims.org_id && claims.org_id !== organizationId) {
@@ -9288,29 +9393,10 @@ import { spawn as spawn2 } from "child_process";
9288
9393
  import fs from "fs";
9289
9394
  import path3 from "path";
9290
9395
  import { fileURLToPath } from "url";
9291
-
9292
- // ../common/dist/src/stdlib/url.utils.js
9293
- var import_handlebars = __toESM(require_lib(), 1);
9294
- function safeUrlConstructor(url, baseUrl) {
9295
- try {
9296
- return Ok(baseUrl ? new URL(url, baseUrl) : new URL(url));
9297
- } catch {
9298
- return Err({
9299
- type: "invalid-url",
9300
- message: `Invalid URL`,
9301
- url
9302
- });
9303
- }
9304
- }
9305
-
9306
- // src/self-update.ts
9307
9396
  var CLI_PACKAGE_NAME = "@getmagical/cli";
9308
9397
  var DEFAULT_CLI_DIST_TAG2 = "latest";
9309
9398
  var DEFAULT_NPM_REGISTRY_URL = "https://registry.npmjs.org/";
9310
9399
  var MANAGED_NODE_SUBPATH = "runtime/node";
9311
- function isRecord2(value) {
9312
- return typeof value === "object" && value !== null && !Array.isArray(value);
9313
- }
9314
9400
  function resolveInstalledPackageRoot({
9315
9401
  entryFilePath,
9316
9402
  packageName
@@ -9351,154 +9437,6 @@ function resolveInstallPrefixFromPackageRoot(packageRootPath) {
9351
9437
  currentPath = parentPath;
9352
9438
  }
9353
9439
  }
9354
- function readInstalledPackageVersion({
9355
- packageName,
9356
- packageRootPath
9357
- }) {
9358
- const packageManifestPath2 = path3.join(packageRootPath, "package.json");
9359
- if (!fs.existsSync(packageManifestPath2)) {
9360
- throw new CliError(
9361
- `Installed package metadata was not found at ${packageManifestPath2}. Reinstall mgcl and try again.`
9362
- );
9363
- }
9364
- const packageManifestResult2 = safeJsonParse(
9365
- fs.readFileSync(packageManifestPath2, "utf8")
9366
- );
9367
- if (isErr(packageManifestResult2)) {
9368
- throw new CliError(`Failed to parse ${packageManifestPath2}.`, {
9369
- cause: packageManifestResult2.error.cause
9370
- });
9371
- }
9372
- const packageManifest = packageManifestResult2.value;
9373
- if (packageManifest.name !== packageName) {
9374
- throw new CliError(
9375
- `Expected installed package ${packageName} at ${packageManifestPath2}. Reinstall mgcl and try again.`
9376
- );
9377
- }
9378
- if (typeof packageManifest.version !== "string" || !packageManifest.version) {
9379
- throw new CliError(
9380
- `Installed package version is missing from ${packageManifestPath2}. Reinstall mgcl and try again.`
9381
- );
9382
- }
9383
- return packageManifest.version;
9384
- }
9385
- function parseVersionSegment(segment, version) {
9386
- if (!/^\d+$/u.test(segment)) {
9387
- throw new CliError(`Invalid CLI version "${version}".`);
9388
- }
9389
- return Number(segment);
9390
- }
9391
- function parseSemanticVersion(version) {
9392
- const normalizedVersion = version.trim().replace(/^v/u, "");
9393
- const [versionWithoutBuildMetadata = ""] = normalizedVersion.split("+");
9394
- if (!versionWithoutBuildMetadata) {
9395
- throw new CliError(`Invalid CLI version "${version}".`);
9396
- }
9397
- const [releasePart, prereleasePart] = versionWithoutBuildMetadata.split("-");
9398
- if (!releasePart) {
9399
- throw new CliError(`Invalid CLI version "${version}".`);
9400
- }
9401
- return {
9402
- prerelease: prereleasePart ? prereleasePart.split(".") : null,
9403
- release: releasePart.split(".").map((segment) => parseVersionSegment(segment, version))
9404
- };
9405
- }
9406
- function comparePrereleaseIdentifiers(left, right) {
9407
- const leftIsNumeric = /^\d+$/u.test(left);
9408
- const rightIsNumeric = /^\d+$/u.test(right);
9409
- if (leftIsNumeric && rightIsNumeric) {
9410
- return Number(left) - Number(right);
9411
- }
9412
- if (leftIsNumeric) {
9413
- return -1;
9414
- }
9415
- if (rightIsNumeric) {
9416
- return 1;
9417
- }
9418
- return left.localeCompare(right);
9419
- }
9420
- function compareSemanticVersions(leftVersion, rightVersion) {
9421
- const left = parseSemanticVersion(leftVersion);
9422
- const right = parseSemanticVersion(rightVersion);
9423
- const releaseLength = Math.max(left.release.length, right.release.length);
9424
- for (let index = 0; index < releaseLength; index += 1) {
9425
- const difference = (left.release[index] ?? 0) - (right.release[index] ?? 0);
9426
- if (difference !== 0) {
9427
- return difference;
9428
- }
9429
- }
9430
- if (!left.prerelease && !right.prerelease) {
9431
- return 0;
9432
- }
9433
- if (!left.prerelease) {
9434
- return 1;
9435
- }
9436
- if (!right.prerelease) {
9437
- return -1;
9438
- }
9439
- const prereleaseLength = Math.max(
9440
- left.prerelease.length,
9441
- right.prerelease.length
9442
- );
9443
- for (let index = 0; index < prereleaseLength; index += 1) {
9444
- const leftIdentifier = left.prerelease[index];
9445
- const rightIdentifier = right.prerelease[index];
9446
- if (leftIdentifier === void 0) {
9447
- return -1;
9448
- }
9449
- if (rightIdentifier === void 0) {
9450
- return 1;
9451
- }
9452
- const difference = comparePrereleaseIdentifiers(
9453
- leftIdentifier,
9454
- rightIdentifier
9455
- );
9456
- if (difference !== 0) {
9457
- return difference;
9458
- }
9459
- }
9460
- return 0;
9461
- }
9462
- async function fetchPublishedPackageVersion({
9463
- distTag,
9464
- fetchFn = fetch,
9465
- packageName,
9466
- registryUrl
9467
- }) {
9468
- const distTagUrlResult = safeUrlConstructor(
9469
- `${registryUrl.replace(/\/?$/u, "/")}-/package/${encodeURIComponent(packageName)}/dist-tags`
9470
- );
9471
- if (isErr(distTagUrlResult)) {
9472
- throw new CliError(`Invalid npm registry URL "${registryUrl}".`);
9473
- }
9474
- const response = await fetchFn(distTagUrlResult.value, {
9475
- headers: {
9476
- accept: "application/json"
9477
- }
9478
- });
9479
- if (!response.ok) {
9480
- throw new CliError(
9481
- `Could not check the latest published mgcl version (status ${response.status}).`
9482
- );
9483
- }
9484
- const distTagsResult = safeJsonParse(await response.text());
9485
- if (isErr(distTagsResult)) {
9486
- throw new CliError("Could not parse the npm dist-tags response for mgcl.", {
9487
- cause: distTagsResult.error.cause
9488
- });
9489
- }
9490
- if (!isRecord2(distTagsResult.value)) {
9491
- throw new CliError("Could not parse the npm dist-tags response for mgcl.");
9492
- }
9493
- const distTags = distTagsResult.value;
9494
- const publishedVersion = distTags[distTag];
9495
- if (typeof publishedVersion !== "string" || publishedVersion.length === 0) {
9496
- throw new CliError(
9497
- `Could not find npm dist-tag "${distTag}" for ${packageName}.`
9498
- );
9499
- }
9500
- return publishedVersion;
9501
- }
9502
9440
  function resolveNpmCommandFromPath() {
9503
9441
  return {
9504
9442
  argsPrefix: [],
@@ -9612,45 +9550,6 @@ async function selfUpdateInstalledCli({
9612
9550
  registryUrl
9613
9551
  });
9614
9552
  }
9615
- async function getInstalledCliUpdateRequirement({
9616
- distTag = DEFAULT_CLI_DIST_TAG2,
9617
- entryFilePath = fileURLToPath(import.meta.url),
9618
- fetchFn = fetch,
9619
- packageName = CLI_PACKAGE_NAME,
9620
- registryUrl = DEFAULT_NPM_REGISTRY_URL
9621
- } = {}) {
9622
- const packageRootPath = resolveInstalledPackageRoot({
9623
- entryFilePath,
9624
- packageName
9625
- });
9626
- if (!packageRootPath) {
9627
- return null;
9628
- }
9629
- const installedVersion = readInstalledPackageVersion({
9630
- packageName,
9631
- packageRootPath
9632
- });
9633
- const publishedVersionResult = await fromThrowable(
9634
- async () => fetchPublishedPackageVersion({
9635
- distTag,
9636
- fetchFn,
9637
- packageName,
9638
- registryUrl
9639
- }),
9640
- "cli-update-check-failed"
9641
- );
9642
- if (isErr(publishedVersionResult)) {
9643
- return null;
9644
- }
9645
- const publishedVersion = publishedVersionResult.value;
9646
- if (compareSemanticVersions(installedVersion, publishedVersion) >= 0) {
9647
- return null;
9648
- }
9649
- return {
9650
- installedVersion,
9651
- latestVersion: publishedVersion
9652
- };
9653
- }
9654
9553
 
9655
9554
  // src/settings-command.ts
9656
9555
  import { Command, InvalidArgumentError, Option } from "commander";
@@ -9911,6 +9810,7 @@ var tokenErrorSchema = z6.object({
9911
9810
  });
9912
9811
  var accessTokenClaimsSchema = z6.object({
9913
9812
  exp: z6.number().int().positive().optional(),
9813
+ iss: z6.string().min(1).optional(),
9914
9814
  org_id: z6.string().min(1).optional(),
9915
9815
  sid: z6.string().min(1).optional(),
9916
9816
  sub: z6.string().min(1)
@@ -10251,39 +10151,16 @@ async function handleSelfUpdate(dependencies, options) {
10251
10151
  `Updated mgcl via npm (${updateResult.packageSpecifier}) in ${updateResult.installPrefix}.`
10252
10152
  );
10253
10153
  }
10254
- function isRootUpdateCommand(program2, actionCommand) {
10255
- return actionCommand.parent === program2 && actionCommand.name() === "update";
10256
- }
10257
- async function enforceLatestCliVersionIfNeeded({
10258
- dependencies,
10259
- program: program2,
10260
- actionCommand
10261
- }) {
10262
- if (actionCommand === program2 || isRootUpdateCommand(program2, actionCommand)) {
10263
- return;
10264
- }
10265
- const updateRequirement = await dependencies.ensureLatestCliVersion?.();
10266
- if (!updateRequirement) {
10267
- return;
10268
- }
10269
- throw new CliError(
10270
- `mgcl ${updateRequirement.installedVersion} is outdated. Upgrade to ${updateRequirement.latestVersion} with "mgcl update", then rerun your command.`
10271
- );
10272
- }
10273
10154
  async function handleOperationCommand(dependencies, operationSpec, commandOptions) {
10274
- const state = requireLoggedInState(await dependencies.stateStore.load());
10275
- const organization = resolveSelectedOrganization({
10276
- state,
10277
- ...commandOptions.org ? { organizationSelector: commandOptions.org } : {}
10278
- });
10279
- const variables = collectOperationVariables(operationSpec, commandOptions);
10280
- const { accessToken } = await withOrgScopedAccessToken({
10155
+ const { accessToken, impersonatedOrganizationId, organization, state } = await withSelectedOrganizationAndAccessToken({
10281
10156
  dependencies,
10282
- organizationId: organization.id,
10283
- state
10157
+ options: commandOptions
10284
10158
  });
10159
+ const variables = collectOperationVariables(operationSpec, commandOptions);
10285
10160
  const result = await dependencies.apiClient.executeGraphQl({
10286
10161
  accessToken,
10162
+ ...impersonatedOrganizationId ? { impersonatedOrganizationId } : {},
10163
+ organizationId: organization.id,
10287
10164
  query: operationSpec.document,
10288
10165
  resultKey: operationSpec.cli.resultKey,
10289
10166
  variables
@@ -10307,12 +10184,19 @@ async function withSelectedOrganizationAndAccessToken({
10307
10184
  state,
10308
10185
  ...options.org ? { organizationSelector: options.org } : {}
10309
10186
  });
10187
+ const authenticatedOrganizationId = await resolveDirectAccessTokenOrganizationId({ dependencies });
10188
+ const shouldImpersonateOrganization = authenticatedOrganizationId !== null && organization.id !== authenticatedOrganizationId;
10310
10189
  const { accessToken } = await withOrgScopedAccessToken({
10311
10190
  dependencies,
10312
- organizationId: organization.id,
10191
+ organizationId: shouldImpersonateOrganization && authenticatedOrganizationId ? authenticatedOrganizationId : organization.id,
10313
10192
  state
10314
10193
  });
10315
- return { accessToken, organization, state };
10194
+ return {
10195
+ accessToken,
10196
+ ...shouldImpersonateOrganization ? { impersonatedOrganizationId: organization.id } : {},
10197
+ organization,
10198
+ state
10199
+ };
10316
10200
  }
10317
10201
  function writeCommandOutput({
10318
10202
  dependencies,
@@ -10326,12 +10210,16 @@ function writeCommandOutput({
10326
10210
  dependencies.io.info(formatHumanReadableOutput(result));
10327
10211
  }
10328
10212
  async function handleNangoIntegrationsListCommand(dependencies, options) {
10329
- const { accessToken, organization, state } = await withSelectedOrganizationAndAccessToken({ dependencies, options });
10213
+ const { accessToken, impersonatedOrganizationId, organization, state } = await withSelectedOrganizationAndAccessToken({ dependencies, options });
10330
10214
  const listNangoIntegrations = requireApiClientMethod(
10331
10215
  dependencies.apiClient,
10332
10216
  "listNangoIntegrations"
10333
10217
  );
10334
- const integrations = await listNangoIntegrations({ accessToken });
10218
+ const integrations = await listNangoIntegrations({
10219
+ accessToken,
10220
+ ...impersonatedOrganizationId ? { impersonatedOrganizationId } : {},
10221
+ organizationId: organization.id
10222
+ });
10335
10223
  await saveLastUsedOrganization({
10336
10224
  dependencies,
10337
10225
  organizationId: organization.id,
@@ -10354,13 +10242,15 @@ function normalizeListedNangoAuthentication(authentication) {
10354
10242
  };
10355
10243
  }
10356
10244
  async function handleNangoAuthsListCommand(dependencies, options) {
10357
- const { accessToken, organization, state } = await withSelectedOrganizationAndAccessToken({ dependencies, options });
10245
+ const { accessToken, impersonatedOrganizationId, organization, state } = await withSelectedOrganizationAndAccessToken({ dependencies, options });
10358
10246
  const listNangoAuthentications = requireApiClientMethod(
10359
10247
  dependencies.apiClient,
10360
10248
  "listNangoAuthentications"
10361
10249
  );
10362
10250
  const organizationAuthentications = await listNangoAuthentications({
10363
- accessToken
10251
+ accessToken,
10252
+ ...impersonatedOrganizationId ? { impersonatedOrganizationId } : {},
10253
+ organizationId: organization.id
10364
10254
  });
10365
10255
  const authentications = organizationAuthentications.filter((authentication) => {
10366
10256
  if (options.integration && authentication.providerConfigKey !== options.integration) {
@@ -10382,6 +10272,29 @@ async function handleNangoAuthsListCommand(dependencies, options) {
10382
10272
  result: authentications
10383
10273
  });
10384
10274
  }
10275
+ async function resolveDirectAccessTokenOrganizationId({
10276
+ dependencies
10277
+ }) {
10278
+ const { accessTokenFilePath } = dependencies.runtimeConfig;
10279
+ if (!accessTokenFilePath) {
10280
+ return null;
10281
+ }
10282
+ const accessToken = await readFile4(accessTokenFilePath, "utf8").then((value) => value.trim()).catch((error) => {
10283
+ if (error instanceof Error && "code" in error && error.code === "ENOENT") {
10284
+ return null;
10285
+ }
10286
+ throw error;
10287
+ });
10288
+ if (!accessToken) {
10289
+ return null;
10290
+ }
10291
+ try {
10292
+ const claims = dependencies.authClient.decodeAccessTokenClaims(accessToken);
10293
+ return claims.org_id ?? null;
10294
+ } catch {
10295
+ return null;
10296
+ }
10297
+ }
10385
10298
  async function saveLastUsedOrganization({
10386
10299
  dependencies,
10387
10300
  organizationId,
@@ -10507,7 +10420,6 @@ function createDefaultDependencies() {
10507
10420
  accessTokenFilePath
10508
10421
  },
10509
10422
  refreshTokenStore: runtimeConfig.refreshTokenStoreKind === "file" ? createFileRefreshTokenStore(refreshTokenFilePath) : createKeytarRefreshTokenStore(runtimeConfig.keychainServiceName),
10510
- ensureLatestCliVersion: async () => getInstalledCliUpdateRequirement(selfUpdateOptions),
10511
10423
  settingsStore,
10512
10424
  selfUpdateCli: async () => selfUpdateInstalledCli(selfUpdateOptions),
10513
10425
  stateStore: createFileStateStore(runtimeConfig.stateFilePath)
@@ -10542,13 +10454,6 @@ ${formatOutputModesNote()}`
10542
10454
  }
10543
10455
  this.outputHelp();
10544
10456
  });
10545
- program2.hook("preAction", async (_command, actionCommand) => {
10546
- await enforceLatestCliVersionIfNeeded({
10547
- actionCommand,
10548
- dependencies,
10549
- program: program2
10550
- });
10551
- });
10552
10457
  const authCommand = configureCommandPresentation(
10553
10458
  new Command2("auth").description("Manage CLI authentication.")
10554
10459
  ).helpGroup("Workspace:").addHelpText(