@ascendkit/cli 0.3.12 → 0.3.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -40,13 +40,14 @@ Services:
40
40
  survey Surveys, questions, distribution, analytics
41
41
  journey Lifecycle journeys, nodes, transitions
42
42
  email-identity Email domains, sender identities, and DNS
43
- env Environment variable settings
43
+ vars Environment variable settings
44
44
  webhook Webhook endpoints and testing
45
45
  campaign Email campaigns, scheduling, analytics
46
46
  import Import users from external auth providers
47
47
 
48
48
  Project Management:
49
- project Projects and environment selection
49
+ project Projects and project creation
50
+ env List environments for a project
50
51
  environment Active environment operations
51
52
  verify Check all services in the active environment
52
53
 
@@ -57,10 +58,9 @@ const HELP_SECTION = {
57
58
 
58
59
  Commands:
59
60
  auth show
60
- auth update [--providers <p1,p2,...>] [--email-verification <true|false>] [--waitlist <true|false>] [--password-reset <true|false>] [--session-duration <duration>]
61
+ auth update [--providers <p1,p2,...>] [--email-verification <true|false>] [--waitlist <true|false>] [--password-reset <true|false>] [--session-duration <duration>] [--allowed-domains <d1,d2,...>] [--block-personal-domains <true|false>]
61
62
  auth provider list
62
63
  auth provider set <p1,p2,...>
63
- auth oauth open <provider>
64
64
  auth oauth set <provider> --client-id <id> [--client-secret <secret> | --client-secret-stdin]
65
65
  auth oauth remove <provider>
66
66
  auth user list
@@ -167,12 +167,18 @@ Commands:
167
167
  environment show
168
168
  environment update [<env-id>] [--name <name>] [--description <desc>]
169
169
  environment promote [<env-id>] --target <tier>`,
170
+ vars: `Usage: ascendkit vars <command>
171
+
172
+ Commands:
173
+ vars list
174
+ vars set <key> <value>
175
+ vars remove <key>`,
170
176
  env: `Usage: ascendkit env <command>
171
177
 
172
178
  Commands:
173
- env list
174
- env set <key> <value>
175
- env remove <key>`,
179
+ env list [--project <project-id>]
180
+
181
+ Lists environments for a project. Uses the active project if --project is not specified.`,
176
182
  import: `Usage: ascendkit import <source> <action> [options]
177
183
 
178
184
  Sources:
@@ -201,8 +207,7 @@ only that phase (e.g. "import clerk run --users ..." imports only users, not set
201
207
  Commands:
202
208
  project list
203
209
  project create --name <name> [--description <description>] [--services <s1,s2,...>]
204
- project show <project-id>
205
- project env list <project-id>`,
210
+ project show <project-id>`,
206
211
  };
207
212
  function printSectionHelp(section) {
208
213
  if (!section)
@@ -294,6 +299,9 @@ function printAuthSettingsSummary(data) {
294
299
  if (data.sessionDuration) {
295
300
  console.log(`Session: ${data.sessionDuration}`);
296
301
  }
302
+ const allowedDomains = Array.isArray(data.allowedDomains) ? data.allowedDomains : [];
303
+ console.log(`Allowed domains: ${allowedDomains.length > 0 ? allowedDomains.join(", ") : "none"}`);
304
+ console.log(`Block personal domains: ${data.blockPersonalDomains ? "on" : "off"}`);
297
305
  }
298
306
  function printTemplateSummary(data, opts) {
299
307
  console.log(`Template: ${data.name} (${data.id})`);
@@ -309,7 +317,7 @@ function printTemplateSummary(data, opts) {
309
317
  }
310
318
  if (Array.isArray(data.unconfiguredVariables) && data.unconfiguredVariables.length > 0) {
311
319
  console.log(`\n⚠ Unconfigured variables: ${data.unconfiguredVariables.join(", ")}`);
312
- console.log(` Set values with: ascendkit env set <key> <value>`);
320
+ console.log(` Set values with: ascendkit vars set <key> <value>`);
313
321
  }
314
322
  if (Array.isArray(data.relatedJourneys) && data.relatedJourneys.length > 0) {
315
323
  const refs = data.relatedJourneys.map((j) => `${j.name} (${j.id})`).join(", ");
@@ -636,7 +644,6 @@ async function run() {
636
644
  table(projects, [
637
645
  { key: "id", label: "ID" },
638
646
  { key: "name", label: "Name", width: 30 },
639
- { key: "enabledServices", label: "Services", width: 30 },
640
647
  ]);
641
648
  }
642
649
  else if (action === "show") {
@@ -646,9 +653,6 @@ async function run() {
646
653
  }
647
654
  printProjectSummary(await platform.showProject(args[2]));
648
655
  }
649
- else if (action === "env") {
650
- await runProjectEnvironment(args.slice(2));
651
- }
652
656
  else if (action === "create") {
653
657
  const flags = parseFlags(args.slice(2));
654
658
  if (!flags.name) {
@@ -677,7 +681,7 @@ async function run() {
677
681
  }
678
682
  }
679
683
  else {
680
- console.error('Usage: ascendkit project list|create|show|env');
684
+ console.error('Usage: ascendkit project list|create|show');
681
685
  return await exitCli(1);
682
686
  }
683
687
  return;
@@ -698,7 +702,10 @@ async function run() {
698
702
  await runEnvironment(action, args.slice(2));
699
703
  return;
700
704
  case "env":
701
- await runKeystore(action, args.slice(2));
705
+ await runEnv(action, args.slice(2));
706
+ return;
707
+ case "vars":
708
+ await runVars(action, args.slice(2));
702
709
  return;
703
710
  }
704
711
  // Service commands (need environment key)
@@ -899,26 +906,24 @@ async function runImport(client, source, rest) {
899
906
  function flagsFromLegacy(args) {
900
907
  return parseFlags(args);
901
908
  }
902
- async function runProjectEnvironment(rest) {
903
- const action = rest[0];
904
- const target = rest[1];
905
- switch (action) {
906
- case "list":
907
- if (!target) {
908
- console.error("Usage: ascendkit project env list <project-id>");
909
- return await exitCli(1);
910
- }
911
- table(await platform.listEnvironments(target), [
912
- { key: "id", label: "ID" },
913
- { key: "name", label: "Name", width: 20 },
914
- { key: "tier", label: "Tier" },
915
- { key: "publicKey", label: "Public Key" },
916
- ]);
917
- return;
918
- default:
919
- console.error("Usage: ascendkit project env list <project-id>");
920
- return await exitCli(1);
909
+ async function runEnv(action, rest) {
910
+ if (action !== "list") {
911
+ console.error("Usage: ascendkit env list [--project <project-id>]");
912
+ return await exitCli(1);
913
+ }
914
+ const flags = parseFlags(rest);
915
+ const projectId = flags.project || loadEnvContext()?.projectId;
916
+ if (!projectId) {
917
+ console.error("Provide --project <id> or run ascendkit set-env first.");
918
+ console.error(" List projects: ascendkit project list");
919
+ return await exitCli(1);
921
920
  }
921
+ table(await platform.listEnvironments(projectId), [
922
+ { key: "id", label: "ID" },
923
+ { key: "name", label: "Name", width: 20 },
924
+ { key: "tier", label: "Tier" },
925
+ { key: "publicKey", label: "Public Key" },
926
+ ]);
922
927
  }
923
928
  async function runEnvironment(action, rest) {
924
929
  const flags = parseFlags(rest);
@@ -997,7 +1002,7 @@ async function runEnvironment(action, rest) {
997
1002
  return await exitCli(1);
998
1003
  }
999
1004
  }
1000
- async function runKeystore(action, rest) {
1005
+ async function runVars(action, rest) {
1001
1006
  const ctx = loadEnvContext();
1002
1007
  if (!ctx) {
1003
1008
  console.error("No environment set. Run: ascendkit set-env <public-key>");
@@ -1013,7 +1018,7 @@ async function runKeystore(action, rest) {
1013
1018
  const key = rest[0];
1014
1019
  const value = rest[1];
1015
1020
  if (!key || value === undefined) {
1016
- console.error("Usage: ascendkit env set <key> <value>");
1021
+ console.error("Usage: ascendkit vars set <key> <value>");
1017
1022
  return await exitCli(1);
1018
1023
  }
1019
1024
  vars[key] = value;
@@ -1024,7 +1029,7 @@ async function runKeystore(action, rest) {
1024
1029
  case "remove": {
1025
1030
  const key = rest[0];
1026
1031
  if (!key) {
1027
- console.error("Usage: ascendkit env remove <key>");
1032
+ console.error("Usage: ascendkit vars remove <key>");
1028
1033
  return await exitCli(1);
1029
1034
  }
1030
1035
  if (!(key in vars)) {
@@ -1063,8 +1068,8 @@ async function runKeystore(action, rest) {
1063
1068
  return;
1064
1069
  }
1065
1070
  default:
1066
- console.error(`Unknown env command: ${action}`);
1067
- console.error("Usage: ascendkit env list|set|remove");
1071
+ console.error(`Unknown vars command: ${action}`);
1072
+ console.error("Usage: ascendkit vars list|set|remove");
1068
1073
  return await exitCli(1);
1069
1074
  }
1070
1075
  }
@@ -1094,7 +1099,15 @@ async function runAuth(client, action, rest) {
1094
1099
  }
1095
1100
  if (flags["session-duration"])
1096
1101
  params.sessionDuration = flags["session-duration"];
1097
- printAuthSettingsSummary(await auth.updateSettings(client, params));
1102
+ if (flags["allowed-domains"] !== undefined) {
1103
+ const raw = flags["allowed-domains"].trim();
1104
+ params.allowedDomains = raw === "" ? [] : raw.split(",").map((d) => d.trim()).filter(Boolean);
1105
+ }
1106
+ if (flags["block-personal-domains"] !== undefined)
1107
+ params.blockPersonalDomains = flags["block-personal-domains"] === "true";
1108
+ const updated = await auth.updateSettings(client, params);
1109
+ console.log("Updated.\n");
1110
+ printAuthSettingsSummary(updated);
1098
1111
  break;
1099
1112
  }
1100
1113
  case "provider":
@@ -1117,8 +1130,8 @@ async function runAuth(client, action, rest) {
1117
1130
  }
1118
1131
  break;
1119
1132
  case "oauth": {
1120
- const oauthAction = rest[0] === "open" || rest[0] === "set" || rest[0] === "remove" ? rest[0] : "open";
1121
- const provider = oauthAction === "open" && rest[0] !== "open" ? rest[0] : rest[1];
1133
+ const oauthAction = rest[0];
1134
+ const provider = rest[1];
1122
1135
  if (oauthAction === "set") {
1123
1136
  if (!provider || !flags["client-id"]) {
1124
1137
  console.error("Usage: ascendkit auth oauth set <provider> --client-id <id> [--client-secret <secret> | --client-secret-stdin]");
@@ -1149,7 +1162,7 @@ async function runAuth(client, action, rest) {
1149
1162
  const appUrl = (variables.APP_URL ?? "").trim();
1150
1163
  if (!appUrl) {
1151
1164
  console.error("Set APP_URL for this environment first. AscendKit uses APP_URL to generate the redirect URI for custom OAuth credentials.");
1152
- console.error("Use: ascendkit env set APP_URL https://your-app.com");
1165
+ console.error("Use: ascendkit vars set APP_URL https://your-app.com");
1153
1166
  return await exitCli(1);
1154
1167
  }
1155
1168
  await auth.updateOAuthCredentials(client, provider, flags["client-id"], clientSecret);
@@ -1164,15 +1177,8 @@ async function runAuth(client, action, rest) {
1164
1177
  console.log(`Removed OAuth credentials for ${provider}.`);
1165
1178
  }
1166
1179
  else {
1167
- if (!provider) {
1168
- console.error("Usage: ascendkit auth oauth open <provider>");
1169
- return await exitCli(1);
1170
- }
1171
- const portalUrl = process.env.ASCENDKIT_PORTAL_URL ?? "http://localhost:3000";
1172
- const url = auth.getOAuthSetupUrl(portalUrl, provider, client.currentPublicKey ?? undefined);
1173
- console.log(`Opening browser to configure ${provider} OAuth credentials...`);
1174
- console.log(url);
1175
- openBrowser(url);
1180
+ console.error("Usage: ascendkit auth oauth set|remove <provider>");
1181
+ return await exitCli(1);
1176
1182
  }
1177
1183
  break;
1178
1184
  }
@@ -1549,7 +1555,7 @@ function runStatus() {
1549
1555
  }
1550
1556
  else {
1551
1557
  console.log(" No environment set. Run: ascendkit set-env <public-key>");
1552
- console.log(" List environments: ascendkit project env list <project-id>");
1558
+ console.log(" List environments: ascendkit env list --project <project-id>");
1553
1559
  }
1554
1560
  console.log();
1555
1561
  }
@@ -8,6 +8,8 @@ export interface UpdateSettingsParams {
8
8
  requireUsername?: boolean;
9
9
  };
10
10
  sessionDuration?: string;
11
+ allowedDomains?: string[];
12
+ blockPersonalDomains?: boolean;
11
13
  }
12
14
  export declare function getSettings(client: AscendKitClient): Promise<unknown>;
13
15
  export declare function updateSettings(client: AscendKitClient, params: UpdateSettingsParams): Promise<unknown>;
@@ -9,6 +9,10 @@ export async function updateSettings(client, params) {
9
9
  body.features = params.features;
10
10
  if (params.sessionDuration !== undefined)
11
11
  body.sessionDuration = params.sessionDuration;
12
+ if (params.allowedDomains !== undefined)
13
+ body.allowedDomains = params.allowedDomains;
14
+ if (params.blockPersonalDomains !== undefined)
15
+ body.blockPersonalDomains = params.blockPersonalDomains;
12
16
  return client.managedPut("/api/auth/settings", body);
13
17
  }
14
18
  export async function updateProviders(client, providers) {
@@ -13,6 +13,11 @@ function formatAuthSettings(data) {
13
13
  ];
14
14
  if (data.sessionDuration)
15
15
  lines.push(`Session: ${data.sessionDuration}`);
16
+ const allowedDomains = Array.isArray(data.allowedDomains) ? data.allowedDomains : [];
17
+ if (allowedDomains.length > 0)
18
+ lines.push(`Allowed domains: ${allowedDomains.join(", ")}`);
19
+ if (data.blockPersonalDomains)
20
+ lines.push("Block personal domains: on");
16
21
  return lines.join("\n");
17
22
  }
18
23
  export function registerAuthTools(server, client) {
@@ -42,6 +47,24 @@ export function registerAuthTools(server, client) {
42
47
  const data = await auth.updateSettings(client, params);
43
48
  return { content: [{ type: "text", text: formatAuthSettings(data) }] };
44
49
  });
50
+ server.tool("auth_domain_restrictions", "Configure email domain restrictions for signups. Set an allowlist of specific domains, or block personal email providers (gmail, yahoo, etc.), or both. Allowlist takes precedence when both are set.", {
51
+ allowedDomains: z
52
+ .array(z.string())
53
+ .optional()
54
+ .describe('Allowed email domains for signup, e.g. ["company.com", "partner.org"]. Pass empty array to clear.'),
55
+ blockPersonalDomains: z
56
+ .boolean()
57
+ .optional()
58
+ .describe("Block signups from common personal email providers (gmail, yahoo, hotmail, etc.)"),
59
+ }, async (params) => {
60
+ const body = {};
61
+ if (params.allowedDomains !== undefined)
62
+ body.allowedDomains = params.allowedDomains;
63
+ if (params.blockPersonalDomains !== undefined)
64
+ body.blockPersonalDomains = params.blockPersonalDomains;
65
+ const data = await client.managedPut("/api/auth/settings", body);
66
+ return { content: [{ type: "text", text: formatAuthSettings(data) }] };
67
+ });
45
68
  server.tool("auth_provider_set", "Set which auth providers are enabled for the project. Credentials and magic-link are mutually exclusive. Social-only login (e.g. [\"google\"]) is valid. At least one provider required.", {
46
69
  providers: z
47
70
  .array(z.string())
@@ -206,7 +206,7 @@ export function registerPlatformTools(server, client) {
206
206
  };
207
207
  }
208
208
  });
209
- server.tool("env_list", "List environment variable values for the active environment. Uses the shared .ascendkit environment context by default.", {
209
+ server.tool("vars_list", "List environment variable values for the active environment. Uses the shared .ascendkit environment context by default.", {
210
210
  projectId: z.string().optional().describe("Optional project ID override (defaults to active environment project)"),
211
211
  envId: z.string().optional().describe("Optional environment ID override (defaults to active environment)"),
212
212
  }, async (params) => {
@@ -235,7 +235,7 @@ export function registerPlatformTools(server, client) {
235
235
  return { content: [{ type: "text", text: message }], isError: true };
236
236
  }
237
237
  });
238
- server.tool("env_replace", "Replace the full environment variable map for the active environment. Pass the full key-value map.", {
238
+ server.tool("vars_replace", "Replace the full environment variable map for the active environment. Pass the full key-value map.", {
239
239
  projectId: z.string().optional().describe("Optional project ID override (defaults to active environment project)"),
240
240
  envId: z.string().optional().describe("Optional environment ID override (defaults to active environment)"),
241
241
  variables: z.record(z.string()).describe("Key-value map of environment variables"),
@@ -265,7 +265,7 @@ export function registerPlatformTools(server, client) {
265
265
  };
266
266
  }
267
267
  });
268
- server.tool("env_set", "Set a single environment variable for the active environment.", {
268
+ server.tool("vars_set", "Set a single environment variable for the active environment.", {
269
269
  projectId: z.string().optional().describe("Optional project ID override (defaults to active environment project)"),
270
270
  envId: z.string().optional().describe("Optional environment ID override (defaults to active environment)"),
271
271
  key: z.string().describe("Environment variable key"),
@@ -291,7 +291,7 @@ export function registerPlatformTools(server, client) {
291
291
  return { content: [{ type: "text", text: message }], isError: true };
292
292
  }
293
293
  });
294
- server.tool("env_remove", "Remove a single environment variable from the active environment.", {
294
+ server.tool("vars_remove", "Remove a single environment variable from the active environment.", {
295
295
  projectId: z.string().optional().describe("Optional project ID override (defaults to active environment project)"),
296
296
  envId: z.string().optional().describe("Optional environment ID override (defaults to active environment)"),
297
297
  key: z.string().describe("Environment variable key to remove"),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ascendkit/cli",
3
- "version": "0.3.12",
3
+ "version": "0.3.14",
4
4
  "description": "AscendKit CLI and MCP server",
5
5
  "author": "ascendkit.dev",
6
6
  "license": "MIT",