@zapier/zapier-sdk-cli 0.52.0 → 0.52.2

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/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @zapier/zapier-sdk-cli
2
2
 
3
+ ## 0.52.2
4
+
5
+ ### Patch Changes
6
+
7
+ - 4460a5a: Added `--skip-prompts` flag to the `login` command. When passed, the command skips all interactive prompts: it uses `email@hostname` as the credential name where possible, and errors instead of prompting when re-authentication or migration is required. Useful in CI environments, piped output, or any setup where TTY detection is unreliable.
8
+
9
+ ## 0.52.1
10
+
11
+ ### Patch Changes
12
+
13
+ - c8655a4: Added non-interactive support to the `login` command. When running in a headless environment (no TTY — such as CI, piped scripts, or an MCP server), `login` now automatically uses `email@hostname` as the credential name instead of hanging on interactive prompts. If re-authentication or migration is required and a terminal is unavailable, the command now exits with a clear error pointing to `logout` or an interactive terminal.
14
+
3
15
  ## 0.52.0
4
16
 
5
17
  ### Minor Changes
package/README.md CHANGED
@@ -178,15 +178,16 @@ Log in to Zapier to access your account
178
178
 
179
179
  **Options:**
180
180
 
181
- | Option | Type | Required | Default | Possible Values | Description |
182
- | ----------------- | --------- | -------- | ------- | --------------- | -------------------------------------------------------------- |
183
- | `--timeout` | `string` | ❌ | — | — | Login timeout in seconds (default: 300) |
184
- | `--use-approvals` | `boolean` | ❌ | — | — | Require approvals for actions performed with these credentials |
181
+ | Option | Type | Required | Default | Possible Values | Description |
182
+ | ----------------- | --------- | -------- | ------- | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
183
+ | `--timeout` | `string` | ❌ | — | — | Login timeout in seconds (default: 300) |
184
+ | `--use-approvals` | `boolean` | ❌ | — | — | Require approvals for actions performed with these credentials |
185
+ | `--skip-prompts` | `boolean` | ❌ | — | — | Skip interactive prompts. Uses defaults where possible; errors instead of prompting when input is required. Useful in CI, piped output, or environments where TTY detection is unreliable. |
185
186
 
186
187
  **Usage:**
187
188
 
188
189
  ```bash
189
- npx zapier-sdk login [--timeout] [--use-approvals]
190
+ npx zapier-sdk login [--timeout] [--use-approvals] [--skip-prompts]
190
191
  ```
191
192
 
192
193
  #### `logout`
package/dist/cli.cjs CHANGED
@@ -1572,7 +1572,7 @@ var SHARED_COMMAND_CLI_OPTIONS = [
1572
1572
 
1573
1573
  // package.json
1574
1574
  var package_default = {
1575
- version: "0.52.0"};
1575
+ version: "0.52.2"};
1576
1576
 
1577
1577
  // src/telemetry/builders.ts
1578
1578
  function createCliBaseEvent(context = {}) {
@@ -3884,6 +3884,9 @@ var LoginSchema = zod.z.object({
3884
3884
  timeout: zod.z.string().optional().describe("Login timeout in seconds (default: 300)"),
3885
3885
  useApprovals: zod.z.boolean().optional().describe(
3886
3886
  "Require approvals for actions performed with these credentials"
3887
+ ),
3888
+ skipPrompts: zod.z.boolean().optional().describe(
3889
+ "Skip interactive prompts. Uses defaults where possible; errors instead of prompting when input is required. Useful in CI, piped output, or environments where TTY detection is unreliable."
3887
3890
  )
3888
3891
  }).describe("Log in to Zapier to access your account");
3889
3892
 
@@ -3899,7 +3902,12 @@ function toPkceCredentials(credentials2) {
3899
3902
  }
3900
3903
  return void 0;
3901
3904
  }
3902
- async function confirmRevokeAndRelogin(activeCredentials) {
3905
+ async function confirmRevokeAndRelogin(activeCredentials, skipPrompts) {
3906
+ if (skipPrompts) {
3907
+ throw new ZapierCliValidationError(
3908
+ `Already logged in as "${activeCredentials.name}". Run \`logout\` first or use an interactive terminal to re-authenticate.`
3909
+ );
3910
+ }
3903
3911
  const { confirmed } = await inquirer__default.default.prompt([
3904
3912
  {
3905
3913
  type: "confirm",
@@ -3916,7 +3924,12 @@ Log out and log in again?`,
3916
3924
  }
3917
3925
  return true;
3918
3926
  }
3919
- async function confirmJwtMigration() {
3927
+ async function confirmJwtMigration(skipPrompts) {
3928
+ if (skipPrompts) {
3929
+ throw new ZapierCliValidationError(
3930
+ "Legacy JWT login detected. Run `logout` first or use an interactive terminal to migrate to client credentials."
3931
+ );
3932
+ }
3920
3933
  const { confirmed } = await inquirer__default.default.prompt([
3921
3934
  {
3922
3935
  type: "confirm",
@@ -3931,7 +3944,12 @@ async function confirmJwtMigration() {
3931
3944
  }
3932
3945
  return true;
3933
3946
  }
3934
- async function confirmLocalLoginReset() {
3947
+ async function confirmLocalLoginReset(skipPrompts) {
3948
+ if (skipPrompts) {
3949
+ throw new ZapierCliValidationError(
3950
+ "Login cleanup failed and cannot be reset without confirmation. Re-run with an interactive terminal."
3951
+ );
3952
+ }
3935
3953
  const { confirmed } = await inquirer__default.default.prompt([
3936
3954
  {
3937
3955
  type: "confirm",
@@ -3953,13 +3971,22 @@ function parseTimeoutSeconds(timeout) {
3953
3971
  }
3954
3972
  return timeoutSeconds;
3955
3973
  }
3956
- async function promptCredentialsName(email, baseUrl2) {
3974
+ async function promptCredentialsName(email, skipPrompts, baseUrl2) {
3975
+ const fallback = `${email}@${os.hostname()}`;
3976
+ if (skipPrompts) {
3977
+ if (credentialsNameExists({ name: fallback, baseUrl: baseUrl2 })) {
3978
+ throw new ZapierCliValidationError(
3979
+ `Credentials named "${fallback}" already exist. Run \`logout\` first or use an interactive terminal to choose a different name.`
3980
+ );
3981
+ }
3982
+ return fallback;
3983
+ }
3957
3984
  const { credentialName } = await inquirer__default.default.prompt([
3958
3985
  {
3959
3986
  type: "input",
3960
3987
  name: "credentialName",
3961
3988
  message: "Enter a name to identify them:",
3962
- default: `${email}@${os.hostname()}`,
3989
+ default: fallback,
3963
3990
  validate: (input) => {
3964
3991
  if (!input.trim()) return "Name cannot be empty";
3965
3992
  if (credentialsNameExists({ name: input.trim(), baseUrl: baseUrl2 })) {
@@ -4008,6 +4035,7 @@ var loginPlugin = zapierSdk.definePlugin(
4008
4035
  supportsJsonOutput: false,
4009
4036
  handler: async ({ sdk: sdk2, options }) => {
4010
4037
  const timeoutSeconds = parseTimeoutSeconds(options.timeout);
4038
+ const skipPrompts = options.skipPrompts === true || !process.stdin.isTTY || !process.stdout.isTTY;
4011
4039
  const resolvedCredentials = await sdk2.context.resolveCredentials();
4012
4040
  const pkceCredentials = toPkceCredentials(resolvedCredentials);
4013
4041
  const credentialsBaseUrl2 = await resolveCredentialsBaseUrl({
@@ -4018,21 +4046,22 @@ var loginPlugin = zapierSdk.definePlugin(
4018
4046
  baseUrl: credentialsBaseUrl2
4019
4047
  });
4020
4048
  if (activeCredentials) {
4021
- if (!await confirmRevokeAndRelogin(activeCredentials)) return;
4049
+ if (!await confirmRevokeAndRelogin(activeCredentials, skipPrompts))
4050
+ return;
4022
4051
  try {
4023
4052
  await revokeCredentials({
4024
4053
  api: sdk2.context.api,
4025
4054
  credentials: activeCredentials
4026
4055
  });
4027
4056
  } catch {
4028
- if (!await confirmLocalLoginReset()) return;
4057
+ if (!await confirmLocalLoginReset(skipPrompts)) return;
4029
4058
  await deleteStoredClientCredentials({
4030
4059
  name: activeCredentials.name,
4031
4060
  baseUrl: activeCredentials.baseUrl
4032
4061
  });
4033
4062
  }
4034
4063
  } else if (hasLegacyJwtConfig()) {
4035
- if (!await confirmJwtMigration()) return;
4064
+ if (!await confirmJwtMigration(skipPrompts)) return;
4036
4065
  }
4037
4066
  const { accessToken } = await runOauthFlow({
4038
4067
  timeoutMs: timeoutSeconds * 1e3,
@@ -4050,6 +4079,7 @@ var loginPlugin = zapierSdk.definePlugin(
4050
4079
  );
4051
4080
  const credentialName = await promptCredentialsName(
4052
4081
  profile.email,
4082
+ skipPrompts,
4053
4083
  credentialsBaseUrl2
4054
4084
  );
4055
4085
  const useApprovals = options.useApprovals === true;
@@ -6626,7 +6656,7 @@ var watchTriggerInboxCliPlugin = zapierSdk.definePlugin(
6626
6656
  // package.json with { type: 'json' }
6627
6657
  var package_default2 = {
6628
6658
  name: "@zapier/zapier-sdk-cli",
6629
- version: "0.52.0"};
6659
+ version: "0.52.2"};
6630
6660
 
6631
6661
  // src/sdk.ts
6632
6662
  zapierSdk.injectCliLogin(login_exports);
package/dist/cli.mjs CHANGED
@@ -1530,7 +1530,7 @@ var SHARED_COMMAND_CLI_OPTIONS = [
1530
1530
 
1531
1531
  // package.json
1532
1532
  var package_default = {
1533
- version: "0.52.0"};
1533
+ version: "0.52.2"};
1534
1534
 
1535
1535
  // src/telemetry/builders.ts
1536
1536
  function createCliBaseEvent(context = {}) {
@@ -3842,6 +3842,9 @@ var LoginSchema = z.object({
3842
3842
  timeout: z.string().optional().describe("Login timeout in seconds (default: 300)"),
3843
3843
  useApprovals: z.boolean().optional().describe(
3844
3844
  "Require approvals for actions performed with these credentials"
3845
+ ),
3846
+ skipPrompts: z.boolean().optional().describe(
3847
+ "Skip interactive prompts. Uses defaults where possible; errors instead of prompting when input is required. Useful in CI, piped output, or environments where TTY detection is unreliable."
3845
3848
  )
3846
3849
  }).describe("Log in to Zapier to access your account");
3847
3850
 
@@ -3857,7 +3860,12 @@ function toPkceCredentials(credentials2) {
3857
3860
  }
3858
3861
  return void 0;
3859
3862
  }
3860
- async function confirmRevokeAndRelogin(activeCredentials) {
3863
+ async function confirmRevokeAndRelogin(activeCredentials, skipPrompts) {
3864
+ if (skipPrompts) {
3865
+ throw new ZapierCliValidationError(
3866
+ `Already logged in as "${activeCredentials.name}". Run \`logout\` first or use an interactive terminal to re-authenticate.`
3867
+ );
3868
+ }
3861
3869
  const { confirmed } = await inquirer.prompt([
3862
3870
  {
3863
3871
  type: "confirm",
@@ -3874,7 +3882,12 @@ Log out and log in again?`,
3874
3882
  }
3875
3883
  return true;
3876
3884
  }
3877
- async function confirmJwtMigration() {
3885
+ async function confirmJwtMigration(skipPrompts) {
3886
+ if (skipPrompts) {
3887
+ throw new ZapierCliValidationError(
3888
+ "Legacy JWT login detected. Run `logout` first or use an interactive terminal to migrate to client credentials."
3889
+ );
3890
+ }
3878
3891
  const { confirmed } = await inquirer.prompt([
3879
3892
  {
3880
3893
  type: "confirm",
@@ -3889,7 +3902,12 @@ async function confirmJwtMigration() {
3889
3902
  }
3890
3903
  return true;
3891
3904
  }
3892
- async function confirmLocalLoginReset() {
3905
+ async function confirmLocalLoginReset(skipPrompts) {
3906
+ if (skipPrompts) {
3907
+ throw new ZapierCliValidationError(
3908
+ "Login cleanup failed and cannot be reset without confirmation. Re-run with an interactive terminal."
3909
+ );
3910
+ }
3893
3911
  const { confirmed } = await inquirer.prompt([
3894
3912
  {
3895
3913
  type: "confirm",
@@ -3911,13 +3929,22 @@ function parseTimeoutSeconds(timeout) {
3911
3929
  }
3912
3930
  return timeoutSeconds;
3913
3931
  }
3914
- async function promptCredentialsName(email, baseUrl2) {
3932
+ async function promptCredentialsName(email, skipPrompts, baseUrl2) {
3933
+ const fallback = `${email}@${hostname()}`;
3934
+ if (skipPrompts) {
3935
+ if (credentialsNameExists({ name: fallback, baseUrl: baseUrl2 })) {
3936
+ throw new ZapierCliValidationError(
3937
+ `Credentials named "${fallback}" already exist. Run \`logout\` first or use an interactive terminal to choose a different name.`
3938
+ );
3939
+ }
3940
+ return fallback;
3941
+ }
3915
3942
  const { credentialName } = await inquirer.prompt([
3916
3943
  {
3917
3944
  type: "input",
3918
3945
  name: "credentialName",
3919
3946
  message: "Enter a name to identify them:",
3920
- default: `${email}@${hostname()}`,
3947
+ default: fallback,
3921
3948
  validate: (input) => {
3922
3949
  if (!input.trim()) return "Name cannot be empty";
3923
3950
  if (credentialsNameExists({ name: input.trim(), baseUrl: baseUrl2 })) {
@@ -3966,6 +3993,7 @@ var loginPlugin = definePlugin(
3966
3993
  supportsJsonOutput: false,
3967
3994
  handler: async ({ sdk: sdk2, options }) => {
3968
3995
  const timeoutSeconds = parseTimeoutSeconds(options.timeout);
3996
+ const skipPrompts = options.skipPrompts === true || !process.stdin.isTTY || !process.stdout.isTTY;
3969
3997
  const resolvedCredentials = await sdk2.context.resolveCredentials();
3970
3998
  const pkceCredentials = toPkceCredentials(resolvedCredentials);
3971
3999
  const credentialsBaseUrl2 = await resolveCredentialsBaseUrl({
@@ -3976,21 +4004,22 @@ var loginPlugin = definePlugin(
3976
4004
  baseUrl: credentialsBaseUrl2
3977
4005
  });
3978
4006
  if (activeCredentials) {
3979
- if (!await confirmRevokeAndRelogin(activeCredentials)) return;
4007
+ if (!await confirmRevokeAndRelogin(activeCredentials, skipPrompts))
4008
+ return;
3980
4009
  try {
3981
4010
  await revokeCredentials({
3982
4011
  api: sdk2.context.api,
3983
4012
  credentials: activeCredentials
3984
4013
  });
3985
4014
  } catch {
3986
- if (!await confirmLocalLoginReset()) return;
4015
+ if (!await confirmLocalLoginReset(skipPrompts)) return;
3987
4016
  await deleteStoredClientCredentials({
3988
4017
  name: activeCredentials.name,
3989
4018
  baseUrl: activeCredentials.baseUrl
3990
4019
  });
3991
4020
  }
3992
4021
  } else if (hasLegacyJwtConfig()) {
3993
- if (!await confirmJwtMigration()) return;
4022
+ if (!await confirmJwtMigration(skipPrompts)) return;
3994
4023
  }
3995
4024
  const { accessToken } = await runOauthFlow({
3996
4025
  timeoutMs: timeoutSeconds * 1e3,
@@ -4008,6 +4037,7 @@ var loginPlugin = definePlugin(
4008
4037
  );
4009
4038
  const credentialName = await promptCredentialsName(
4010
4039
  profile.email,
4040
+ skipPrompts,
4011
4041
  credentialsBaseUrl2
4012
4042
  );
4013
4043
  const useApprovals = options.useApprovals === true;
@@ -6584,7 +6614,7 @@ var watchTriggerInboxCliPlugin = definePlugin(
6584
6614
  // package.json with { type: 'json' }
6585
6615
  var package_default2 = {
6586
6616
  name: "@zapier/zapier-sdk-cli",
6587
- version: "0.52.0"};
6617
+ version: "0.52.2"};
6588
6618
 
6589
6619
  // src/sdk.ts
6590
6620
  injectCliLogin(login_exports);
@@ -1261,6 +1261,9 @@ var LoginSchema = zod.z.object({
1261
1261
  timeout: zod.z.string().optional().describe("Login timeout in seconds (default: 300)"),
1262
1262
  useApprovals: zod.z.boolean().optional().describe(
1263
1263
  "Require approvals for actions performed with these credentials"
1264
+ ),
1265
+ skipPrompts: zod.z.boolean().optional().describe(
1266
+ "Skip interactive prompts. Uses defaults where possible; errors instead of prompting when input is required. Useful in CI, piped output, or environments where TTY detection is unreliable."
1264
1267
  )
1265
1268
  }).describe("Log in to Zapier to access your account");
1266
1269
 
@@ -1276,7 +1279,12 @@ function toPkceCredentials(credentials) {
1276
1279
  }
1277
1280
  return void 0;
1278
1281
  }
1279
- async function confirmRevokeAndRelogin(activeCredentials) {
1282
+ async function confirmRevokeAndRelogin(activeCredentials, skipPrompts) {
1283
+ if (skipPrompts) {
1284
+ throw new ZapierCliValidationError(
1285
+ `Already logged in as "${activeCredentials.name}". Run \`logout\` first or use an interactive terminal to re-authenticate.`
1286
+ );
1287
+ }
1280
1288
  const { confirmed } = await inquirer__default.default.prompt([
1281
1289
  {
1282
1290
  type: "confirm",
@@ -1293,7 +1301,12 @@ Log out and log in again?`,
1293
1301
  }
1294
1302
  return true;
1295
1303
  }
1296
- async function confirmJwtMigration() {
1304
+ async function confirmJwtMigration(skipPrompts) {
1305
+ if (skipPrompts) {
1306
+ throw new ZapierCliValidationError(
1307
+ "Legacy JWT login detected. Run `logout` first or use an interactive terminal to migrate to client credentials."
1308
+ );
1309
+ }
1297
1310
  const { confirmed } = await inquirer__default.default.prompt([
1298
1311
  {
1299
1312
  type: "confirm",
@@ -1308,7 +1321,12 @@ async function confirmJwtMigration() {
1308
1321
  }
1309
1322
  return true;
1310
1323
  }
1311
- async function confirmLocalLoginReset() {
1324
+ async function confirmLocalLoginReset(skipPrompts) {
1325
+ if (skipPrompts) {
1326
+ throw new ZapierCliValidationError(
1327
+ "Login cleanup failed and cannot be reset without confirmation. Re-run with an interactive terminal."
1328
+ );
1329
+ }
1312
1330
  const { confirmed } = await inquirer__default.default.prompt([
1313
1331
  {
1314
1332
  type: "confirm",
@@ -1330,13 +1348,22 @@ function parseTimeoutSeconds(timeout) {
1330
1348
  }
1331
1349
  return timeoutSeconds;
1332
1350
  }
1333
- async function promptCredentialsName(email, baseUrl) {
1351
+ async function promptCredentialsName(email, skipPrompts, baseUrl) {
1352
+ const fallback = `${email}@${os.hostname()}`;
1353
+ if (skipPrompts) {
1354
+ if (credentialsNameExists({ name: fallback, baseUrl })) {
1355
+ throw new ZapierCliValidationError(
1356
+ `Credentials named "${fallback}" already exist. Run \`logout\` first or use an interactive terminal to choose a different name.`
1357
+ );
1358
+ }
1359
+ return fallback;
1360
+ }
1334
1361
  const { credentialName } = await inquirer__default.default.prompt([
1335
1362
  {
1336
1363
  type: "input",
1337
1364
  name: "credentialName",
1338
1365
  message: "Enter a name to identify them:",
1339
- default: `${email}@${os.hostname()}`,
1366
+ default: fallback,
1340
1367
  validate: (input) => {
1341
1368
  if (!input.trim()) return "Name cannot be empty";
1342
1369
  if (credentialsNameExists({ name: input.trim(), baseUrl })) {
@@ -1385,6 +1412,7 @@ var loginPlugin = zapierSdk.definePlugin(
1385
1412
  supportsJsonOutput: false,
1386
1413
  handler: async ({ sdk: sdk2, options }) => {
1387
1414
  const timeoutSeconds = parseTimeoutSeconds(options.timeout);
1415
+ const skipPrompts = options.skipPrompts === true || !process.stdin.isTTY || !process.stdout.isTTY;
1388
1416
  const resolvedCredentials = await sdk2.context.resolveCredentials();
1389
1417
  const pkceCredentials = toPkceCredentials(resolvedCredentials);
1390
1418
  const credentialsBaseUrl = await resolveCredentialsBaseUrl({
@@ -1395,21 +1423,22 @@ var loginPlugin = zapierSdk.definePlugin(
1395
1423
  baseUrl: credentialsBaseUrl
1396
1424
  });
1397
1425
  if (activeCredentials) {
1398
- if (!await confirmRevokeAndRelogin(activeCredentials)) return;
1426
+ if (!await confirmRevokeAndRelogin(activeCredentials, skipPrompts))
1427
+ return;
1399
1428
  try {
1400
1429
  await revokeCredentials({
1401
1430
  api: sdk2.context.api,
1402
1431
  credentials: activeCredentials
1403
1432
  });
1404
1433
  } catch {
1405
- if (!await confirmLocalLoginReset()) return;
1434
+ if (!await confirmLocalLoginReset(skipPrompts)) return;
1406
1435
  await deleteStoredClientCredentials({
1407
1436
  name: activeCredentials.name,
1408
1437
  baseUrl: activeCredentials.baseUrl
1409
1438
  });
1410
1439
  }
1411
1440
  } else if (hasLegacyJwtConfig()) {
1412
- if (!await confirmJwtMigration()) return;
1441
+ if (!await confirmJwtMigration(skipPrompts)) return;
1413
1442
  }
1414
1443
  const { accessToken } = await runOauthFlow({
1415
1444
  timeoutMs: timeoutSeconds * 1e3,
@@ -1427,6 +1456,7 @@ var loginPlugin = zapierSdk.definePlugin(
1427
1456
  );
1428
1457
  const credentialName = await promptCredentialsName(
1429
1458
  profile.email,
1459
+ skipPrompts,
1430
1460
  credentialsBaseUrl
1431
1461
  );
1432
1462
  const useApprovals = options.useApprovals === true;
@@ -3986,7 +4016,7 @@ var watchTriggerInboxCliPlugin = zapierSdk.definePlugin(
3986
4016
  // package.json with { type: 'json' }
3987
4017
  var package_default = {
3988
4018
  name: "@zapier/zapier-sdk-cli",
3989
- version: "0.52.0"};
4019
+ version: "0.52.2"};
3990
4020
 
3991
4021
  // src/experimental.ts
3992
4022
  experimental.injectCliLogin(login_exports);
@@ -1225,6 +1225,9 @@ var LoginSchema = z.object({
1225
1225
  timeout: z.string().optional().describe("Login timeout in seconds (default: 300)"),
1226
1226
  useApprovals: z.boolean().optional().describe(
1227
1227
  "Require approvals for actions performed with these credentials"
1228
+ ),
1229
+ skipPrompts: z.boolean().optional().describe(
1230
+ "Skip interactive prompts. Uses defaults where possible; errors instead of prompting when input is required. Useful in CI, piped output, or environments where TTY detection is unreliable."
1228
1231
  )
1229
1232
  }).describe("Log in to Zapier to access your account");
1230
1233
 
@@ -1240,7 +1243,12 @@ function toPkceCredentials(credentials) {
1240
1243
  }
1241
1244
  return void 0;
1242
1245
  }
1243
- async function confirmRevokeAndRelogin(activeCredentials) {
1246
+ async function confirmRevokeAndRelogin(activeCredentials, skipPrompts) {
1247
+ if (skipPrompts) {
1248
+ throw new ZapierCliValidationError(
1249
+ `Already logged in as "${activeCredentials.name}". Run \`logout\` first or use an interactive terminal to re-authenticate.`
1250
+ );
1251
+ }
1244
1252
  const { confirmed } = await inquirer.prompt([
1245
1253
  {
1246
1254
  type: "confirm",
@@ -1257,7 +1265,12 @@ Log out and log in again?`,
1257
1265
  }
1258
1266
  return true;
1259
1267
  }
1260
- async function confirmJwtMigration() {
1268
+ async function confirmJwtMigration(skipPrompts) {
1269
+ if (skipPrompts) {
1270
+ throw new ZapierCliValidationError(
1271
+ "Legacy JWT login detected. Run `logout` first or use an interactive terminal to migrate to client credentials."
1272
+ );
1273
+ }
1261
1274
  const { confirmed } = await inquirer.prompt([
1262
1275
  {
1263
1276
  type: "confirm",
@@ -1272,7 +1285,12 @@ async function confirmJwtMigration() {
1272
1285
  }
1273
1286
  return true;
1274
1287
  }
1275
- async function confirmLocalLoginReset() {
1288
+ async function confirmLocalLoginReset(skipPrompts) {
1289
+ if (skipPrompts) {
1290
+ throw new ZapierCliValidationError(
1291
+ "Login cleanup failed and cannot be reset without confirmation. Re-run with an interactive terminal."
1292
+ );
1293
+ }
1276
1294
  const { confirmed } = await inquirer.prompt([
1277
1295
  {
1278
1296
  type: "confirm",
@@ -1294,13 +1312,22 @@ function parseTimeoutSeconds(timeout) {
1294
1312
  }
1295
1313
  return timeoutSeconds;
1296
1314
  }
1297
- async function promptCredentialsName(email, baseUrl) {
1315
+ async function promptCredentialsName(email, skipPrompts, baseUrl) {
1316
+ const fallback = `${email}@${hostname()}`;
1317
+ if (skipPrompts) {
1318
+ if (credentialsNameExists({ name: fallback, baseUrl })) {
1319
+ throw new ZapierCliValidationError(
1320
+ `Credentials named "${fallback}" already exist. Run \`logout\` first or use an interactive terminal to choose a different name.`
1321
+ );
1322
+ }
1323
+ return fallback;
1324
+ }
1298
1325
  const { credentialName } = await inquirer.prompt([
1299
1326
  {
1300
1327
  type: "input",
1301
1328
  name: "credentialName",
1302
1329
  message: "Enter a name to identify them:",
1303
- default: `${email}@${hostname()}`,
1330
+ default: fallback,
1304
1331
  validate: (input) => {
1305
1332
  if (!input.trim()) return "Name cannot be empty";
1306
1333
  if (credentialsNameExists({ name: input.trim(), baseUrl })) {
@@ -1349,6 +1376,7 @@ var loginPlugin = definePlugin(
1349
1376
  supportsJsonOutput: false,
1350
1377
  handler: async ({ sdk: sdk2, options }) => {
1351
1378
  const timeoutSeconds = parseTimeoutSeconds(options.timeout);
1379
+ const skipPrompts = options.skipPrompts === true || !process.stdin.isTTY || !process.stdout.isTTY;
1352
1380
  const resolvedCredentials = await sdk2.context.resolveCredentials();
1353
1381
  const pkceCredentials = toPkceCredentials(resolvedCredentials);
1354
1382
  const credentialsBaseUrl = await resolveCredentialsBaseUrl({
@@ -1359,21 +1387,22 @@ var loginPlugin = definePlugin(
1359
1387
  baseUrl: credentialsBaseUrl
1360
1388
  });
1361
1389
  if (activeCredentials) {
1362
- if (!await confirmRevokeAndRelogin(activeCredentials)) return;
1390
+ if (!await confirmRevokeAndRelogin(activeCredentials, skipPrompts))
1391
+ return;
1363
1392
  try {
1364
1393
  await revokeCredentials({
1365
1394
  api: sdk2.context.api,
1366
1395
  credentials: activeCredentials
1367
1396
  });
1368
1397
  } catch {
1369
- if (!await confirmLocalLoginReset()) return;
1398
+ if (!await confirmLocalLoginReset(skipPrompts)) return;
1370
1399
  await deleteStoredClientCredentials({
1371
1400
  name: activeCredentials.name,
1372
1401
  baseUrl: activeCredentials.baseUrl
1373
1402
  });
1374
1403
  }
1375
1404
  } else if (hasLegacyJwtConfig()) {
1376
- if (!await confirmJwtMigration()) return;
1405
+ if (!await confirmJwtMigration(skipPrompts)) return;
1377
1406
  }
1378
1407
  const { accessToken } = await runOauthFlow({
1379
1408
  timeoutMs: timeoutSeconds * 1e3,
@@ -1391,6 +1420,7 @@ var loginPlugin = definePlugin(
1391
1420
  );
1392
1421
  const credentialName = await promptCredentialsName(
1393
1422
  profile.email,
1423
+ skipPrompts,
1394
1424
  credentialsBaseUrl
1395
1425
  );
1396
1426
  const useApprovals = options.useApprovals === true;
@@ -3950,7 +3980,7 @@ var watchTriggerInboxCliPlugin = definePlugin(
3950
3980
  // package.json with { type: 'json' }
3951
3981
  var package_default = {
3952
3982
  name: "@zapier/zapier-sdk-cli",
3953
- version: "0.52.0"};
3983
+ version: "0.52.2"};
3954
3984
 
3955
3985
  // src/experimental.ts
3956
3986
  injectCliLogin(login_exports);