@agentscope-ai/platform-cli 1.0.3 → 1.0.5

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
@@ -5,6 +5,7 @@ import {
5
5
  CLI_VERSION,
6
6
  DEFAULT_SCOPE,
7
7
  PLATFORM_URL,
8
+ PRE_PLATFORM_URL,
8
9
  clearCredentials,
9
10
  credentialsFromTokenResponse,
10
11
  getAspConfigDir,
@@ -12,7 +13,7 @@ import {
12
13
  loadCredentials,
13
14
  resolveConfig,
14
15
  saveCredentials
15
- } from "./chunk-IWWTP4LN.js";
16
+ } from "./chunk-IHANUO75.js";
16
17
 
17
18
  // src/cli.ts
18
19
  import { Command } from "commander";
@@ -68,6 +69,64 @@ function maskSecrets(text) {
68
69
  return text.replace(/Bearer\s+[A-Za-z0-9._-]+/gi, "Bearer [REDACTED]").replace(/"access_token"\s*:\s*"[^"]+"/gi, '"access_token":"[REDACTED]"').replace(/"refresh_token"\s*:\s*"[^"]+"/gi, '"refresh_token":"[REDACTED]"').replace(/"token"\s*:\s*"[^"]+"/gi, '"token":"[REDACTED]"');
69
70
  }
70
71
 
72
+ // src/utils/platform.ts
73
+ function detectPlatformEnv(url) {
74
+ const normalized = url.replace(/\/$/, "");
75
+ if (normalized === PLATFORM_URL) return "default";
76
+ if (normalized === PRE_PLATFORM_URL) return "pre";
77
+ return "custom";
78
+ }
79
+ function formatPlatformLabel(url) {
80
+ const env = detectPlatformEnv(url);
81
+ if (env === "default") return `platform (${PLATFORM_URL})`;
82
+ if (env === "pre") return `pre (${PRE_PLATFORM_URL})`;
83
+ return url;
84
+ }
85
+ function envCommandSuffix(platformUrl) {
86
+ return detectPlatformEnv(platformUrl) === "pre" ? " pre" : "";
87
+ }
88
+ function loginCommandHint(platformUrl) {
89
+ return `Run \`asp auth login${envCommandSuffix(platformUrl)}\`.`;
90
+ }
91
+ function withPlatformUrl(config, platformUrl) {
92
+ return { ...config, platformUrl: platformUrl.replace(/\/$/, "") };
93
+ }
94
+ async function requireCredentials(config, targetPlatformUrl) {
95
+ if (config.token) {
96
+ return {
97
+ config: withPlatformUrl(config, targetPlatformUrl),
98
+ creds: {
99
+ access_token: config.token,
100
+ token_type: "Bearer",
101
+ platform_url: targetPlatformUrl
102
+ }
103
+ };
104
+ }
105
+ const creds = await loadCredentials(targetPlatformUrl);
106
+ if (!creds?.access_token) {
107
+ throw new AspError("Not logged in.", {
108
+ code: "UNAUTHORIZED",
109
+ hint: loginCommandHint(targetPlatformUrl),
110
+ exitCode: 3
111
+ });
112
+ }
113
+ const credsUrl = creds.platform_url.replace(/\/$/, "");
114
+ const targetUrl = targetPlatformUrl.replace(/\/$/, "");
115
+ if (credsUrl !== targetUrl) {
116
+ const loggedIn = formatPlatformLabel(credsUrl);
117
+ const target = formatPlatformLabel(targetUrl);
118
+ throw new AspError(`Credential environment mismatch: logged in to ${loggedIn}, command targets ${target}.`, {
119
+ code: "ENV_MISMATCH",
120
+ hint: loginCommandHint(targetUrl),
121
+ exitCode: 1
122
+ });
123
+ }
124
+ return {
125
+ config: withPlatformUrl(config, targetUrl),
126
+ creds
127
+ };
128
+ }
129
+
71
130
  // src/auth/session.ts
72
131
  function isSessionInvalidError(err) {
73
132
  if (!(err instanceof AspError)) return false;
@@ -114,7 +173,7 @@ var HttpClient = class {
114
173
  return await this.doRequest(opts);
115
174
  } catch (err) {
116
175
  if (opts.auth !== false && !opts._retried && isSessionInvalidError(err) && !this.config.token) {
117
- const creds = await loadCredentials();
176
+ const creds = await loadCredentials(this.config.platformUrl);
118
177
  if (creds?.refresh_token) {
119
178
  await refreshStoredSession(configWithPlatform(this.config, creds), creds.refresh_token, creds.platform_url);
120
179
  return this.doRequest({ ...opts, _retried: true });
@@ -124,7 +183,7 @@ var HttpClient = class {
124
183
  }
125
184
  }
126
185
  async doRequest(opts) {
127
- const creds = opts.auth !== false && !this.config.token ? await loadCredentials() : null;
186
+ const creds = opts.auth !== false && !this.config.token ? await loadCredentials(this.config.platformUrl) : null;
128
187
  const platformUrl = creds?.platform_url ?? this.config.platformUrl;
129
188
  const prefix = opts.prefix ?? "";
130
189
  const url = `${platformUrl}${prefix}${opts.path}`;
@@ -169,7 +228,7 @@ var HttpClient = class {
169
228
  }
170
229
  async resolveAccessToken(existing) {
171
230
  if (this.config.token) return this.config.token;
172
- const creds = existing ?? await loadCredentials();
231
+ const creds = existing ?? await loadCredentials(this.config.platformUrl);
173
232
  if (!creds) return void 0;
174
233
  if (isTokenExpired(creds) && creds.refresh_token) {
175
234
  const refreshed = await refreshStoredSession(
@@ -351,56 +410,6 @@ function generatePkce() {
351
410
  return { codeVerifier, codeChallenge, state, nonce };
352
411
  }
353
412
 
354
- // src/utils/platform.ts
355
- function detectPlatformEnv(url) {
356
- const normalized = url.replace(/\/$/, "");
357
- if (normalized === PLATFORM_URL) return "default";
358
- return "custom";
359
- }
360
- function formatPlatformLabel(url) {
361
- const env = detectPlatformEnv(url);
362
- if (env === "default") return `platform (${PLATFORM_URL})`;
363
- return url;
364
- }
365
- function withPlatformUrl(config, platformUrl) {
366
- return { ...config, platformUrl: platformUrl.replace(/\/$/, "") };
367
- }
368
- async function requireCredentials(config, targetPlatformUrl) {
369
- if (config.token) {
370
- return {
371
- config: withPlatformUrl(config, targetPlatformUrl),
372
- creds: {
373
- access_token: config.token,
374
- token_type: "Bearer",
375
- platform_url: targetPlatformUrl
376
- }
377
- };
378
- }
379
- const creds = await loadCredentials();
380
- if (!creds?.access_token) {
381
- throw new AspError("Not logged in.", {
382
- code: "UNAUTHORIZED",
383
- hint: "Run `asp auth login`.",
384
- exitCode: 3
385
- });
386
- }
387
- const credsUrl = creds.platform_url.replace(/\/$/, "");
388
- const targetUrl = targetPlatformUrl.replace(/\/$/, "");
389
- if (credsUrl !== targetUrl) {
390
- const loggedIn = formatPlatformLabel(credsUrl);
391
- const target = formatPlatformLabel(targetUrl);
392
- throw new AspError(`Credential environment mismatch: logged in to ${loggedIn}, command targets ${target}.`, {
393
- code: "ENV_MISMATCH",
394
- hint: "Run `asp auth login` for the current target platform.",
395
- exitCode: 1
396
- });
397
- }
398
- return {
399
- config: withPlatformUrl(config, targetUrl),
400
- creds
401
- };
402
- }
403
-
404
413
  // src/utils/output.ts
405
414
  import chalk from "chalk";
406
415
  function printJson(data) {
@@ -647,9 +656,10 @@ function wantsPasswordLogin(opts) {
647
656
  async function ensureBrowserLoginEnabled(config) {
648
657
  const meta = await new CliApiClient(config).getMeta().catch(() => null);
649
658
  if (meta?.features?.browser_pkce_login === false) {
659
+ const suffix = envCommandSuffix(config.platformUrl);
650
660
  throw new AspError("Browser authorization login is not enabled on this platform.", {
651
661
  code: "FEATURE_DISABLED",
652
- hint: "Use `asp auth login --password` instead."
662
+ hint: `Use \`asp auth login --password${suffix}\` instead.`
653
663
  });
654
664
  }
655
665
  }
@@ -688,9 +698,10 @@ async function runLogin(config, opts) {
688
698
  return;
689
699
  }
690
700
  if (!process.stdin.isTTY) {
701
+ const suffix = envCommandSuffix(config.platformUrl);
691
702
  throw new AspError("Non-interactive login requires a login method flag.", {
692
703
  code: "INVALID_REQUEST",
693
- hint: "Use `asp auth login --browser` or `asp auth login --password --account <email> --pass <password>`."
704
+ hint: `Use \`asp auth login --browser${suffix}\` or \`asp auth login --password --account <email> --pass <password>${suffix}\`.`
694
705
  });
695
706
  }
696
707
  const method = await promptLoginMethod();
@@ -712,16 +723,16 @@ async function saveTokenLogin(config, token) {
712
723
  }
713
724
  async function runStatus(getConfig2) {
714
725
  const base = getConfig2();
715
- const creds = await loadCredentials();
726
+ const creds = await loadCredentials(base.platformUrl);
716
727
  if (!base.token && !creds) {
717
728
  printInfo("Not logged in.");
718
- printInfo("Run `asp auth login` to sign in.");
729
+ printInfo(loginCommandHint(base.platformUrl));
719
730
  return;
720
731
  }
721
732
  const { config: apiConfig } = await requireCredentials(base, base.platformUrl);
722
733
  const client = new CliApiClient(apiConfig);
723
734
  const me = await client.getMe();
724
- const latestCreds = await loadCredentials() ?? creds;
735
+ const latestCreds = await loadCredentials(base.platformUrl) ?? creds;
725
736
  if (base.json) {
726
737
  printJson({
727
738
  logged_in: true,
@@ -756,7 +767,7 @@ async function runRefresh(getConfig2) {
756
767
  if (!creds.refresh_token) {
757
768
  throw new AspError("No refresh token available.", {
758
769
  code: "UNAUTHORIZED",
759
- hint: "Run `asp auth login`.",
770
+ hint: loginCommandHint(config.platformUrl),
760
771
  exitCode: 3
761
772
  });
762
773
  }
@@ -766,7 +777,7 @@ async function runRefresh(getConfig2) {
766
777
  async function runLogout(getConfig2) {
767
778
  const base = getConfig2();
768
779
  const platformUrl = base.platformUrl;
769
- const creds = await loadCredentials();
780
+ const creds = await loadCredentials(platformUrl);
770
781
  if (!creds) {
771
782
  printInfo(`Not logged in to ${formatPlatformLabel(platformUrl)}.`);
772
783
  return;
@@ -776,7 +787,7 @@ async function runLogout(getConfig2) {
776
787
  await client.logout().catch(() => {
777
788
  });
778
789
  }
779
- await clearCredentials();
790
+ await clearCredentials(creds.platform_url);
780
791
  printSuccess(`Logged out from ${formatPlatformLabel(creds.platform_url)}.`);
781
792
  }
782
793
  async function runLogs(getConfig2, opts) {
@@ -808,7 +819,7 @@ async function runLogs(getConfig2, opts) {
808
819
  }
809
820
  function registerAuthCommands(program2, getConfig2) {
810
821
  const auth = program2.command("auth").description("Authentication commands");
811
- let login = auth.command("login").description("Log in (default platform is production)");
822
+ let login = auth.command("login").description("Log in (append `pre` for pre-production, e.g. asp auth login pre)");
812
823
  for (const [flags, desc] of LOGIN_OPTIONS) {
813
824
  login = login.option(flags, desc);
814
825
  }
@@ -1171,6 +1182,11 @@ var PLUGIN_CATEGORY_OPTIONS = [
1171
1182
  value: "general",
1172
1183
  label: "General Plugin",
1173
1184
  describe: "Does not fit the categories above, or combines multiple capabilities"
1185
+ },
1186
+ {
1187
+ value: "app",
1188
+ label: "App",
1189
+ describe: "Extend platform capabilities as a standalone application"
1174
1190
  }
1175
1191
  ];
1176
1192
  async function runCommand(command, args) {
@@ -1549,15 +1565,17 @@ async function runPublish(getConfig2, zipPath, opts) {
1549
1565
  publishOpts = { ...opts, category };
1550
1566
  }
1551
1567
  if (useUrlMode && zipPath) {
1568
+ const suffix = envCommandSuffix(config.platformUrl);
1552
1569
  throw new AspError("Do not pass zip path when using --url.", {
1553
1570
  code: "INVALID_REQUEST",
1554
- hint: "Use either `asp plugin publish ./plugin.zip` or `asp plugin publish --url <url>`."
1571
+ hint: `Use either \`asp plugin publish ./plugin.zip${suffix}\` or \`asp plugin publish --url <url>${suffix}\`.`
1555
1572
  });
1556
1573
  }
1557
1574
  if (!useUrlMode && !zipPath) {
1575
+ const suffix = envCommandSuffix(config.platformUrl);
1558
1576
  throw new AspError("Zip path is required unless --url is provided.", {
1559
1577
  code: "INVALID_REQUEST",
1560
- hint: "Use `asp plugin publish ./plugin.zip`."
1578
+ hint: `Use \`asp plugin publish ./plugin.zip${suffix}\`.`
1561
1579
  });
1562
1580
  }
1563
1581
  let submission;
@@ -1575,7 +1593,6 @@ async function runPublish(getConfig2, zipPath, opts) {
1575
1593
  code: "UPLOAD_URL_MISSING"
1576
1594
  });
1577
1595
  }
1578
- printInfo("Uploading plugin zip to object storage...");
1579
1596
  await uploadZipToSignedUrl(localSubmission.upload, fileBuffer);
1580
1597
  localSubmission = await client.completeArtifactSubmission(localSubmission.submission_id, {
1581
1598
  sha512,
@@ -1609,14 +1626,16 @@ async function runPublish(getConfig2, zipPath, opts) {
1609
1626
  printInfo(`Initial status: ${submission.status}`);
1610
1627
  const trackRef = publishOpts.artifactId ?? manifest?.id ?? urlPluginId ?? submission.submission_id;
1611
1628
  if (opts.noWait) {
1612
- printInfo(`Track progress: asp plugin publish status ${trackRef}`);
1613
- printInfo(`Show logs: asp plugin publish logs ${trackRef}`);
1629
+ const envSuffix2 = envCommandSuffix(config.platformUrl);
1630
+ printInfo(`Track progress: asp plugin publish status ${trackRef}${envSuffix2}`);
1631
+ printInfo(`Show logs: asp plugin publish logs ${trackRef}${envSuffix2}`);
1614
1632
  return;
1615
1633
  }
1616
1634
  if (!submission.terminal) {
1617
1635
  printSuccess("Upload submitted successfully. Scanning continues asynchronously.");
1618
- printInfo(`Track progress: asp plugin publish status ${trackRef} --watch`);
1619
- printInfo(`Show logs: asp plugin publish logs ${trackRef}`);
1636
+ const envSuffix2 = envCommandSuffix(config.platformUrl);
1637
+ printInfo(`Track progress: asp plugin publish status ${trackRef} --watch${envSuffix2}`);
1638
+ printInfo(`Show logs: asp plugin publish logs ${trackRef}${envSuffix2}`);
1620
1639
  return;
1621
1640
  }
1622
1641
  if (submission.status === "published") {
@@ -1630,7 +1649,8 @@ async function runPublish(getConfig2, zipPath, opts) {
1630
1649
  if (submission.failure?.message) {
1631
1650
  printWarn(`Failure: ${submission.failure.message}`);
1632
1651
  }
1633
- printInfo(`Inspect logs: asp plugin publish logs ${trackRef}`);
1652
+ const envSuffix = envCommandSuffix(config.platformUrl);
1653
+ printInfo(`Inspect logs: asp plugin publish logs ${trackRef}${envSuffix}`);
1634
1654
  }
1635
1655
  async function runPublishStatus(getConfig2, pluginRef, opts) {
1636
1656
  const base = getConfig2();
@@ -1715,7 +1735,7 @@ function registerPluginCommands(program2, getConfig2) {
1715
1735
  plugin.command("install <pluginId>").description("Install plugin via qwenpaw").option("--version <version>", "Specify version").option("--via <tool>", "Install tool (qwenpaw)", "qwenpaw").action(async (pluginId, opts) => {
1716
1736
  await runInstall(getConfig2, pluginId, opts);
1717
1737
  });
1718
- const publish = plugin.command("publish [zipPath]").description("Publish plugin from local zip or URL").option("--url <url>", "Publish from remote zip URL").option("--artifact-id <id>", "Optional plugin id override (must match plugin.json in zip mode)").option("--version <version>", "Optional version override").option("--category <code>", "Plugin category code (tool|provider|command|hook|frontend|general)").option("--repo-url <url>", "Repository URL").option("--publish-mode <mode>", "Publish mode", "auto_after_scan").option("--no-wait", "Do not wait for terminal status").action(async (zipPath, opts) => {
1738
+ const publish = plugin.command("publish [zipPath]").description("Publish plugin from local zip or URL").option("--url <url>", "Publish from remote zip URL").option("--artifact-id <id>", "Optional plugin id override (must match plugin.json in zip mode)").option("--version <version>", "Optional version override").option("--category <code>", "Plugin category code (tool|provider|command|hook|frontend|general|app)").option("--repo-url <url>", "Repository URL").option("--publish-mode <mode>", "Publish mode", "auto_after_scan").option("--no-wait", "Do not wait for terminal status").action(async (zipPath, opts) => {
1719
1739
  await runPublish(getConfig2, zipPath, opts);
1720
1740
  });
1721
1741
  publish.command("status <pluginId>").description("Show publish status by plugin id or submission id").option("--watch", "Poll until terminal status", false).action(async (pluginId, opts) => {
@@ -2147,15 +2167,17 @@ async function runPublish2(getConfig2, zipPath, opts) {
2147
2167
  }
2148
2168
  const useUrlMode = Boolean(opts.url);
2149
2169
  if (useUrlMode && zipPath) {
2170
+ const suffix = envCommandSuffix(config.platformUrl);
2150
2171
  throw new AspError("Do not pass zip path when using --url.", {
2151
2172
  code: "INVALID_REQUEST",
2152
- hint: "Use either `asp skill publish ./skill.zip` or `asp skill publish --url <url>`."
2173
+ hint: `Use either \`asp skill publish ./skill.zip${suffix}\` or \`asp skill publish --url <url>${suffix}\`.`
2153
2174
  });
2154
2175
  }
2155
2176
  if (!useUrlMode && !zipPath) {
2177
+ const suffix = envCommandSuffix(config.platformUrl);
2156
2178
  throw new AspError("Zip path is required unless --url is provided.", {
2157
2179
  code: "INVALID_REQUEST",
2158
- hint: "Use `asp skill publish ./skill.zip`."
2180
+ hint: `Use \`asp skill publish ./skill.zip${suffix}\`.`
2159
2181
  });
2160
2182
  }
2161
2183
  const manifest = useUrlMode ? void 0 : await readSkillManifestFromZip(zipPath);
@@ -2180,7 +2202,6 @@ async function runPublish2(getConfig2, zipPath, opts) {
2180
2202
  code: "UPLOAD_URL_MISSING"
2181
2203
  });
2182
2204
  }
2183
- printInfo("Uploading skill zip to object storage...");
2184
2205
  await uploadZipToSignedUrl2(localSubmission.upload, fileBuffer);
2185
2206
  localSubmission = await client.completeArtifactSubmission(localSubmission.submission_id, {
2186
2207
  sha512,
@@ -2225,14 +2246,16 @@ async function runPublish2(getConfig2, zipPath, opts) {
2225
2246
  printInfo(`Initial status: ${submission.status}`);
2226
2247
  const trackRef = publishOpts.artifactId ?? urlSkillId ?? submission.submission_id;
2227
2248
  if (opts.noWait) {
2228
- printInfo(`Track progress: asp skill publish status ${trackRef}`);
2229
- printInfo(`Show logs: asp skill publish logs ${trackRef}`);
2249
+ const envSuffix2 = envCommandSuffix(config.platformUrl);
2250
+ printInfo(`Track progress: asp skill publish status ${trackRef}${envSuffix2}`);
2251
+ printInfo(`Show logs: asp skill publish logs ${trackRef}${envSuffix2}`);
2230
2252
  return;
2231
2253
  }
2232
2254
  if (!submission.terminal) {
2233
2255
  printSuccess("Upload submitted successfully. Scanning continues asynchronously.");
2234
- printInfo(`Track progress: asp skill publish status ${trackRef} --watch`);
2235
- printInfo(`Show logs: asp skill publish logs ${trackRef}`);
2256
+ const envSuffix2 = envCommandSuffix(config.platformUrl);
2257
+ printInfo(`Track progress: asp skill publish status ${trackRef} --watch${envSuffix2}`);
2258
+ printInfo(`Show logs: asp skill publish logs ${trackRef}${envSuffix2}`);
2236
2259
  return;
2237
2260
  }
2238
2261
  if (submission.status === "published") {
@@ -2246,7 +2269,8 @@ async function runPublish2(getConfig2, zipPath, opts) {
2246
2269
  if (submission.failure?.message) {
2247
2270
  printWarn(`Failure: ${submission.failure.message}`);
2248
2271
  }
2249
- printInfo(`Inspect logs: asp skill publish logs ${trackRef}`);
2272
+ const envSuffix = envCommandSuffix(config.platformUrl);
2273
+ printInfo(`Inspect logs: asp skill publish logs ${trackRef}${envSuffix}`);
2250
2274
  }
2251
2275
  async function runPublishStatus2(getConfig2, skillRef, opts) {
2252
2276
  const base = getConfig2();
@@ -2347,9 +2371,20 @@ function registerSkillCommands(program2, getConfig2) {
2347
2371
 
2348
2372
  // src/cli.ts
2349
2373
  var globalOpts = {};
2350
- var program = new Command().name("asp").description("AgentScope Platform CLI").version(CLI_VERSION).option("--platform-url <url>", "Custom Platform base URL (advanced)").option("--token <token>", "Access token (overrides stored credentials)").option("-v, --verbose", "Verbose logging").option("--json", "Output JSON").hook("preAction", (thisCommand) => {
2374
+ function preprocessArgv(argv) {
2375
+ const args = [...argv];
2376
+ let pre = false;
2377
+ if (args.length >= 4 && args[args.length - 1] === "pre") {
2378
+ pre = true;
2379
+ args.pop();
2380
+ }
2381
+ return { argv: args, pre };
2382
+ }
2383
+ var { argv: cliArgv, pre: trailingPre } = preprocessArgv(process.argv);
2384
+ var program = new Command().name("asp").description("AgentScope Platform CLI").version(CLI_VERSION).option("--platform-url <url>", "Custom Platform base URL (advanced)").option("--pre", "Target pre-production environment (https://platform-pre.agentscope.io)").option("--token <token>", "Access token (overrides stored credentials)").option("-v, --verbose", "Verbose logging").option("--json", "Output JSON").hook("preAction", (thisCommand) => {
2351
2385
  const opts = thisCommand.opts();
2352
2386
  globalOpts.platformUrl = opts.platformUrl;
2387
+ globalOpts.pre = opts.pre || trailingPre;
2353
2388
  globalOpts.token = opts.token;
2354
2389
  globalOpts.verbose = opts.verbose;
2355
2390
  globalOpts.json = opts.json;
@@ -2360,7 +2395,7 @@ registerPluginCommands(program, getConfig);
2360
2395
  registerSkillCommands(program, getConfig);
2361
2396
  async function main() {
2362
2397
  try {
2363
- await program.parseAsync(process.argv);
2398
+ await program.parseAsync(cliArgv);
2364
2399
  } catch (err) {
2365
2400
  if (err instanceof AspError) {
2366
2401
  printError(`${err.message} [${err.code}]`);