@ascendkit/cli 0.3.9 → 0.3.12

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,7 +40,7 @@ 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
- keystore Environment runtime key-value settings
43
+ env 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
@@ -61,7 +61,7 @@ Commands:
61
61
  auth provider list
62
62
  auth provider set <p1,p2,...>
63
63
  auth oauth open <provider>
64
- auth oauth set <provider> --client-id <id> [--client-secret <secret> | --client-secret-stdin] [--callback-url <url>]
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
67
67
  auth user remove <user-id>
@@ -112,9 +112,14 @@ Commands:
112
112
  journey node update <journey-id> <node-name> [--action <json>] [--email-id <email>] [--terminal <true|false>]
113
113
  journey node remove <journey-id> <node-name>
114
114
  journey transition list <journey-id> [--from <node-name>] [--to <node-name>]
115
- journey transition add <journey-id> --from <node-name> --to <node-name> --trigger <json> [--priority <n>] [--name <transition-name>] [--quiet]
116
- journey transition update <journey-id> <transition-name> [--trigger <json>] [--priority <n>]
117
- journey transition remove <journey-id> <transition-name>`,
115
+ journey transition add <journey-id> --from <node-name> --to <node-name> --on <event> | --after <delay> [--priority <n>] [--name <transition-name>] [--quiet]
116
+ journey transition update <journey-id> <transition-name> [--on <event>] [--after <delay>] [--priority <n>]
117
+ journey transition remove <journey-id> <transition-name>
118
+
119
+ Trigger shortcuts:
120
+ --on <event> Event trigger (e.g. --on user.login, --on app.completed_onboarding)
121
+ --after <delay> Timer trigger (e.g. --after 2d, --after 12h, --after 30m)
122
+ --trigger <json> Raw JSON: {"type":"event","event":"user.login"} or {"type":"timer","delay":"3d"}`,
118
123
  "email-identity": `Usage: ascendkit email-identity <command>
119
124
 
120
125
  Commands:
@@ -162,12 +167,12 @@ Commands:
162
167
  environment show
163
168
  environment update [<env-id>] [--name <name>] [--description <desc>]
164
169
  environment promote [<env-id>] --target <tier>`,
165
- keystore: `Usage: ascendkit keystore <command>
170
+ env: `Usage: ascendkit env <command>
166
171
 
167
172
  Commands:
168
- keystore list
169
- keystore set <key> <value>
170
- keystore remove <key>`,
173
+ env list
174
+ env set <key> <value>
175
+ env remove <key>`,
171
176
  import: `Usage: ascendkit import <source> <action> [options]
172
177
 
173
178
  Sources:
@@ -209,7 +214,7 @@ function printSectionHelp(section) {
209
214
  key = "email-identity";
210
215
  if (key === "projects")
211
216
  key = "project";
212
- if (key === "env" || key === "environments")
217
+ if (key === "environments")
213
218
  key = "environment";
214
219
  const text = HELP_SECTION[key];
215
220
  if (!text)
@@ -304,7 +309,7 @@ function printTemplateSummary(data, opts) {
304
309
  }
305
310
  if (Array.isArray(data.unconfiguredVariables) && data.unconfiguredVariables.length > 0) {
306
311
  console.log(`\n⚠ Unconfigured variables: ${data.unconfiguredVariables.join(", ")}`);
307
- console.log(` Set values with: ascendkit keystore set <key> <value>`);
312
+ console.log(` Set values with: ascendkit env set <key> <value>`);
308
313
  }
309
314
  if (Array.isArray(data.relatedJourneys) && data.relatedJourneys.length > 0) {
310
315
  const refs = data.relatedJourneys.map((j) => `${j.name} (${j.id})`).join(", ");
@@ -692,7 +697,7 @@ async function run() {
692
697
  case "environment":
693
698
  await runEnvironment(action, args.slice(2));
694
699
  return;
695
- case "keystore":
700
+ case "env":
696
701
  await runKeystore(action, args.slice(2));
697
702
  return;
698
703
  }
@@ -1008,7 +1013,7 @@ async function runKeystore(action, rest) {
1008
1013
  const key = rest[0];
1009
1014
  const value = rest[1];
1010
1015
  if (!key || value === undefined) {
1011
- console.error("Usage: ascendkit keystore set <key> <value>");
1016
+ console.error("Usage: ascendkit env set <key> <value>");
1012
1017
  return await exitCli(1);
1013
1018
  }
1014
1019
  vars[key] = value;
@@ -1019,7 +1024,7 @@ async function runKeystore(action, rest) {
1019
1024
  case "remove": {
1020
1025
  const key = rest[0];
1021
1026
  if (!key) {
1022
- console.error("Usage: ascendkit keystore remove <key>");
1027
+ console.error("Usage: ascendkit env remove <key>");
1023
1028
  return await exitCli(1);
1024
1029
  }
1025
1030
  if (!(key in vars)) {
@@ -1058,8 +1063,8 @@ async function runKeystore(action, rest) {
1058
1063
  return;
1059
1064
  }
1060
1065
  default:
1061
- console.error(`Unknown keystore command: ${action}`);
1062
- console.error("Usage: ascendkit keystore list|set|remove");
1066
+ console.error(`Unknown env command: ${action}`);
1067
+ console.error("Usage: ascendkit env list|set|remove");
1063
1068
  return await exitCli(1);
1064
1069
  }
1065
1070
  }
@@ -1116,7 +1121,7 @@ async function runAuth(client, action, rest) {
1116
1121
  const provider = oauthAction === "open" && rest[0] !== "open" ? rest[0] : rest[1];
1117
1122
  if (oauthAction === "set") {
1118
1123
  if (!provider || !flags["client-id"]) {
1119
- console.error("Usage: ascendkit auth oauth set <provider> --client-id <id> [--client-secret <secret> | --client-secret-stdin] [--callback-url <url>]");
1124
+ console.error("Usage: ascendkit auth oauth set <provider> --client-id <id> [--client-secret <secret> | --client-secret-stdin]");
1120
1125
  return await exitCli(1);
1121
1126
  }
1122
1127
  const secretFromArg = flags["client-secret"];
@@ -1134,7 +1139,20 @@ async function runAuth(client, action, rest) {
1134
1139
  console.error("Client secret cannot be empty.");
1135
1140
  return await exitCli(1);
1136
1141
  }
1137
- await auth.updateOAuthCredentials(client, provider, flags["client-id"], clientSecret, flags["callback-url"]);
1142
+ const ctx = loadEnvContext();
1143
+ if (!ctx) {
1144
+ console.error("No environment set. Run: ascendkit set-env <public-key>");
1145
+ return await exitCli(1);
1146
+ }
1147
+ const env = await platform.getEnvironment(ctx.projectId, ctx.environmentId);
1148
+ const variables = (env.variables ?? {});
1149
+ const appUrl = (variables.APP_URL ?? "").trim();
1150
+ if (!appUrl) {
1151
+ 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");
1153
+ return await exitCli(1);
1154
+ }
1155
+ await auth.updateOAuthCredentials(client, provider, flags["client-id"], clientSecret);
1138
1156
  console.log(`Saved OAuth credentials for ${provider}.`);
1139
1157
  }
1140
1158
  else if (oauthAction === "remove") {
@@ -12,7 +12,7 @@ export interface UpdateSettingsParams {
12
12
  export declare function getSettings(client: AscendKitClient): Promise<unknown>;
13
13
  export declare function updateSettings(client: AscendKitClient, params: UpdateSettingsParams): Promise<unknown>;
14
14
  export declare function updateProviders(client: AscendKitClient, providers: string[]): Promise<unknown>;
15
- export declare function updateOAuthCredentials(client: AscendKitClient, provider: string, clientId: string, clientSecret: string, callbackUrl?: string): Promise<unknown>;
15
+ export declare function updateOAuthCredentials(client: AscendKitClient, provider: string, clientId: string, clientSecret: string): Promise<unknown>;
16
16
  export declare function deleteOAuthCredentials(client: AscendKitClient, provider: string): Promise<unknown>;
17
17
  export declare function getOAuthSetupUrl(portalUrl: string, provider: string, publicKey?: string): string;
18
18
  export declare function listUsers(client: AscendKitClient): Promise<unknown>;
@@ -14,11 +14,8 @@ export async function updateSettings(client, params) {
14
14
  export async function updateProviders(client, providers) {
15
15
  return client.managedPut("/api/auth/settings/providers", { providers });
16
16
  }
17
- export async function updateOAuthCredentials(client, provider, clientId, clientSecret, callbackUrl) {
18
- const body = { clientId, clientSecret };
19
- if (callbackUrl)
20
- body.callbackUrl = callbackUrl;
21
- return client.managedPut(`/api/auth/settings/oauth/${provider}`, body);
17
+ export async function updateOAuthCredentials(client, provider, clientId, clientSecret) {
18
+ return client.managedPut(`/api/auth/settings/oauth/${provider}`, { clientId, clientSecret });
22
19
  }
23
20
  export async function deleteOAuthCredentials(client, provider) {
24
21
  return client.managedDelete(`/api/auth/settings/oauth/${provider}`);
@@ -13,6 +13,8 @@ const ASCENDKIT_ENV_KEYS = [
13
13
  "ASCENDKIT_API_URL",
14
14
  "NEXT_PUBLIC_ASCENDKIT_ENV_KEY",
15
15
  "ASCENDKIT_ENV_KEY",
16
+ "APP_URL",
17
+ "ASCENDKIT_APP_URL",
16
18
  "ASCENDKIT_SECRET_KEY",
17
19
  "ASCENDKIT_WEBHOOK_SECRET",
18
20
  ];
@@ -135,6 +137,11 @@ function buildAscendKitEnvBlock(values) {
135
137
  `NEXT_PUBLIC_ASCENDKIT_ENV_KEY=${values.NEXT_PUBLIC_ASCENDKIT_ENV_KEY}`,
136
138
  `ASCENDKIT_ENV_KEY=${values.ASCENDKIT_ENV_KEY}`,
137
139
  "",
140
+ "# Public URL where your app is hosted (used for auth callbacks and redirects)",
141
+ "# Example: https://app.yourdomain.com",
142
+ "# Leave blank in local dev if the SDK should infer from the incoming request.",
143
+ `APP_URL=${values.APP_URL}`,
144
+ "",
138
145
  "# AscendKit secret key (server-only; never expose to client/browser)",
139
146
  `ASCENDKIT_SECRET_KEY=${values.ASCENDKIT_SECRET_KEY}`,
140
147
  "",
@@ -183,6 +190,8 @@ async function updateEnvExampleFile(filePath) {
183
190
  ASCENDKIT_API_URL: "",
184
191
  NEXT_PUBLIC_ASCENDKIT_ENV_KEY: "",
185
192
  ASCENDKIT_ENV_KEY: "",
193
+ APP_URL: "",
194
+ ASCENDKIT_APP_URL: "",
186
195
  ASCENDKIT_SECRET_KEY: "",
187
196
  ASCENDKIT_WEBHOOK_SECRET: "",
188
197
  });
@@ -208,6 +217,8 @@ async function updateRuntimeEnvFile(filePath, apiUrl, publicKey, secretKey, opti
208
217
  ASCENDKIT_API_URL: resolvedApiUrl,
209
218
  NEXT_PUBLIC_ASCENDKIT_ENV_KEY: resolvedPublicKey,
210
219
  ASCENDKIT_ENV_KEY: resolvedPublicKey,
220
+ APP_URL: readEnvValue(original, "APP_URL") ?? readEnvValue(original, "ASCENDKIT_APP_URL") ?? "",
221
+ ASCENDKIT_APP_URL: "",
211
222
  ASCENDKIT_SECRET_KEY: resolvedSecretKey,
212
223
  ASCENDKIT_WEBHOOK_SECRET: resolvedWebhookSecret,
213
224
  });
@@ -1,5 +1,6 @@
1
1
  import { z } from "zod";
2
2
  import * as auth from "../commands/auth.js";
3
+ import * as platform from "../commands/platform.js";
3
4
  function formatAuthSettings(data) {
4
5
  const providers = Array.isArray(data.providers) ? data.providers : [];
5
6
  const features = data.features ?? {};
@@ -60,7 +61,6 @@ export function registerAuthTools(server, client) {
60
61
  provider: z.string().describe('OAuth provider name, e.g. "google", "github"'),
61
62
  clientId: z.string().optional().describe("OAuth client ID (to set credentials directly)"),
62
63
  clientSecret: z.string().optional().describe("OAuth client secret (to set credentials directly)"),
63
- callbackUrl: z.string().optional().describe("Auth callback URL for this provider"),
64
64
  useProxy: z.boolean().optional().describe("Clear custom credentials and use AscendKit managed proxy credentials"),
65
65
  }, async (params) => {
66
66
  if (params.useProxy && (params.clientId || params.clientSecret)) {
@@ -91,7 +91,19 @@ export function registerAuthTools(server, client) {
91
91
  };
92
92
  }
93
93
  if (params.clientId && params.clientSecret) {
94
- const data = await auth.updateOAuthCredentials(client, params.provider, params.clientId, params.clientSecret, params.callbackUrl);
94
+ const env = await platform.mcpGetEnvironment(client, {});
95
+ const variables = env.variables ?? {};
96
+ const appUrl = (variables.APP_URL ?? "").trim();
97
+ if (!appUrl) {
98
+ return {
99
+ content: [{
100
+ type: "text",
101
+ text: "Set APP_URL for the active environment first. AscendKit uses APP_URL to generate the redirect URI for custom OAuth credentials.",
102
+ }],
103
+ isError: true,
104
+ };
105
+ }
106
+ const data = await auth.updateOAuthCredentials(client, params.provider, params.clientId, params.clientSecret);
95
107
  return {
96
108
  content: [{
97
109
  type: "text",
@@ -206,7 +206,7 @@ export function registerPlatformTools(server, client) {
206
206
  };
207
207
  }
208
208
  });
209
- server.tool("keystore_list", "List keystore values for the active environment. Uses the shared .ascendkit environment context by default.", {
209
+ server.tool("env_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,10 +235,10 @@ export function registerPlatformTools(server, client) {
235
235
  return { content: [{ type: "text", text: message }], isError: true };
236
236
  }
237
237
  });
238
- server.tool("keystore_replace", "Replace the full keystore for the active environment. Pass the full key-value map.", {
238
+ server.tool("env_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
- variables: z.record(z.string()).describe("Key-value map of keystore values"),
241
+ variables: z.record(z.string()).describe("Key-value map of environment variables"),
242
242
  }, async (params) => {
243
243
  try {
244
244
  const data = await platform.mcpUpdateEnvironmentVariables(client, params);
@@ -265,11 +265,11 @@ export function registerPlatformTools(server, client) {
265
265
  };
266
266
  }
267
267
  });
268
- server.tool("keystore_set", "Set a single keystore key for the active environment.", {
268
+ server.tool("env_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
- key: z.string().describe("Keystore key"),
272
- value: z.string().describe("Keystore value"),
271
+ key: z.string().describe("Environment variable key"),
272
+ value: z.string().describe("Environment variable value"),
273
273
  }, async (params) => {
274
274
  try {
275
275
  const env = await platform.mcpGetEnvironment(client, {
@@ -291,10 +291,10 @@ export function registerPlatformTools(server, client) {
291
291
  return { content: [{ type: "text", text: message }], isError: true };
292
292
  }
293
293
  });
294
- server.tool("keystore_remove", "Remove a single keystore key from the active environment.", {
294
+ server.tool("env_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
- key: z.string().describe("Keystore key to remove"),
297
+ key: z.string().describe("Environment variable key to remove"),
298
298
  }, async (params) => {
299
299
  try {
300
300
  const env = await platform.mcpGetEnvironment(client, {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ascendkit/cli",
3
- "version": "0.3.9",
3
+ "version": "0.3.12",
4
4
  "description": "AscendKit CLI and MCP server",
5
5
  "author": "ascendkit.dev",
6
6
  "license": "MIT",