@amaster.ai/runtime-cli 1.1.27 → 1.1.28

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.d.cts CHANGED
@@ -3,6 +3,15 @@ import { AmasterClient } from '@amaster.ai/client';
3
3
 
4
4
  declare function resolveAppCode(optionsApp: string | undefined): string;
5
5
  declare function createAmasterClient(appCode: string): AmasterClient;
6
+ declare function resolveInitBaseURL(options: {
7
+ appCode: string;
8
+ url?: string;
9
+ registry?: string;
10
+ }): {
11
+ baseURL: string;
12
+ registryName: string;
13
+ registryBaseURL: string;
14
+ };
6
15
  declare function isDirectCliExecution(entryArg?: string | undefined): boolean;
7
16
 
8
- export { createAmasterClient, isDirectCliExecution, resolveAppCode };
17
+ export { createAmasterClient, isDirectCliExecution, resolveAppCode, resolveInitBaseURL };
package/dist/cli.d.ts CHANGED
@@ -3,6 +3,15 @@ import { AmasterClient } from '@amaster.ai/client';
3
3
 
4
4
  declare function resolveAppCode(optionsApp: string | undefined): string;
5
5
  declare function createAmasterClient(appCode: string): AmasterClient;
6
+ declare function resolveInitBaseURL(options: {
7
+ appCode: string;
8
+ url?: string;
9
+ registry?: string;
10
+ }): {
11
+ baseURL: string;
12
+ registryName: string;
13
+ registryBaseURL: string;
14
+ };
6
15
  declare function isDirectCliExecution(entryArg?: string | undefined): boolean;
7
16
 
8
- export { createAmasterClient, isDirectCliExecution, resolveAppCode };
17
+ export { createAmasterClient, isDirectCliExecution, resolveAppCode, resolveInitBaseURL };
package/dist/cli.js CHANGED
@@ -25,18 +25,27 @@ var config_exports = {};
25
25
  __export(config_exports, {
26
26
  addApp: () => addApp,
27
27
  clearAuthSession: () => clearAuthSession,
28
+ ensureRegistry: () => ensureRegistry,
28
29
  getAccessToken: () => getAccessToken,
29
30
  getAppConfig: () => getAppConfig,
30
31
  getAuthSession: () => getAuthSession,
31
32
  getBaseURL: () => getBaseURL,
32
33
  getConfig: () => getConfig,
33
34
  getCurrentApp: () => getCurrentApp,
35
+ getCurrentRegistry: () => getCurrentRegistry,
36
+ getRegistryConfig: () => getRegistryConfig,
37
+ inferRegistryBaseURLFromAppBaseURL: () => inferRegistryBaseURLFromAppBaseURL,
34
38
  isAuthenticated: () => isAuthenticated,
35
39
  listApps: () => listApps,
40
+ listRegistries: () => listRegistries,
41
+ normalizeRegistryBaseURL: () => normalizeRegistryBaseURL,
36
42
  removeApp: () => removeApp,
43
+ resolveAppBaseURL: () => resolveAppBaseURL,
44
+ resolveRegistry: () => resolveRegistry,
37
45
  saveAuthSession: () => saveAuthSession,
38
46
  saveConfig: () => saveConfig,
39
47
  setCurrentApp: () => setCurrentApp,
48
+ setCurrentRegistry: () => setCurrentRegistry,
40
49
  shouldRefreshToken: () => shouldRefreshToken
41
50
  });
42
51
  function getConfig() {
@@ -99,6 +108,137 @@ function listApps() {
99
108
  const config = getConfig();
100
109
  return Object.keys(config.apps);
101
110
  }
111
+ function listRegistries() {
112
+ const config = getConfig();
113
+ const currentRegistry = config.currentRegistry || DEFAULT_REGISTRY_NAME;
114
+ const registryMap = /* @__PURE__ */ new Map();
115
+ for (const [name, baseURL] of Object.entries(BUILTIN_REGISTRY_DEFINITIONS)) {
116
+ registryMap.set(name, {
117
+ name,
118
+ baseURL,
119
+ builtin: true
120
+ });
121
+ }
122
+ for (const [name, registry] of Object.entries(config.registries || {})) {
123
+ registryMap.set(name, {
124
+ name,
125
+ baseURL: registry.baseURL,
126
+ builtin: false
127
+ });
128
+ }
129
+ const registries = Array.from(registryMap.values()).sort((left, right) => left.name.localeCompare(right.name));
130
+ const currentResolved = resolveRegistry(currentRegistry);
131
+ return registries.map((registry) => ({
132
+ ...registry,
133
+ name: registry.name === currentResolved.name ? registry.name : registry.name
134
+ }));
135
+ }
136
+ function getCurrentRegistry() {
137
+ const config = getConfig();
138
+ return config.currentRegistry || DEFAULT_REGISTRY_NAME;
139
+ }
140
+ function setCurrentRegistry(registryRef) {
141
+ const resolved = ensureRegistry(registryRef);
142
+ const config = getConfig();
143
+ config.currentRegistry = resolved.name;
144
+ saveConfig(config);
145
+ return resolved;
146
+ }
147
+ function getRegistryConfig(name) {
148
+ const config = getConfig();
149
+ return config.registries?.[name] || null;
150
+ }
151
+ function ensureRegistry(registryRef) {
152
+ const normalizedRef = registryRef.trim();
153
+ if (!normalizedRef) {
154
+ throw new Error("Registry cannot be empty");
155
+ }
156
+ const builtinBaseURL = BUILTIN_REGISTRY_DEFINITIONS[normalizedRef];
157
+ if (builtinBaseURL) {
158
+ return {
159
+ name: normalizedRef,
160
+ baseURL: builtinBaseURL,
161
+ builtin: true
162
+ };
163
+ }
164
+ const config = getConfig();
165
+ const existing = config.registries?.[normalizedRef];
166
+ if (existing) {
167
+ return {
168
+ name: normalizedRef,
169
+ baseURL: existing.baseURL,
170
+ builtin: false
171
+ };
172
+ }
173
+ const normalizedBaseURL = normalizeRegistryBaseURL(normalizedRef);
174
+ for (const [name, baseURL] of Object.entries(BUILTIN_REGISTRY_DEFINITIONS)) {
175
+ if (normalizeRegistryBaseURL(baseURL) === normalizedBaseURL) {
176
+ return {
177
+ name,
178
+ baseURL,
179
+ builtin: true
180
+ };
181
+ }
182
+ }
183
+ const inferredName = inferRegistryName(normalizedBaseURL);
184
+ const current = config.registries?.[inferredName];
185
+ const nextRegistry = {
186
+ baseURL: normalizedBaseURL,
187
+ createdAt: current?.createdAt || (/* @__PURE__ */ new Date()).toISOString()
188
+ };
189
+ config.registries = {
190
+ ...config.registries || {},
191
+ [inferredName]: nextRegistry
192
+ };
193
+ saveConfig(config);
194
+ return {
195
+ name: inferredName,
196
+ baseURL: normalizedBaseURL,
197
+ builtin: false
198
+ };
199
+ }
200
+ function resolveRegistry(registryRef) {
201
+ return ensureRegistry(registryRef || getCurrentRegistry());
202
+ }
203
+ function normalizeRegistryBaseURL(value) {
204
+ const trimmed = value.trim();
205
+ if (!trimmed) {
206
+ throw new Error("Registry cannot be empty");
207
+ }
208
+ const withProtocol = /^https?:\/\//i.test(trimmed) ? trimmed : `https://${trimmed}`;
209
+ const parsed = new URL(withProtocol);
210
+ if (parsed.username || parsed.password || parsed.search || parsed.hash) {
211
+ throw new Error(`Unsupported registry URL: ${value}`);
212
+ }
213
+ if (parsed.pathname && parsed.pathname !== "/") {
214
+ throw new Error(`Registry URL must not include a path: ${value}`);
215
+ }
216
+ parsed.pathname = "";
217
+ return parsed.toString().replace(/\/$/, "");
218
+ }
219
+ function resolveAppBaseURL(appCode, registryRef) {
220
+ const resolved = resolveRegistry(registryRef);
221
+ const registryUrl = new URL(resolved.baseURL);
222
+ if (isLocalLikeHost(registryUrl.hostname)) {
223
+ throw new Error(`Cannot infer app URL from registry ${resolved.baseURL}; please pass --url explicitly`);
224
+ }
225
+ return `${registryUrl.protocol}//${appCode}.${registryUrl.host}`;
226
+ }
227
+ function inferRegistryBaseURLFromAppBaseURL(appBaseURL, appCode) {
228
+ const parsed = new URL(appBaseURL);
229
+ const hostnameParts = parsed.hostname.split(".");
230
+ if (hostnameParts.length <= 2 || isLocalLikeHost(parsed.hostname)) {
231
+ parsed.pathname = "";
232
+ return parsed.toString().replace(/\/$/, "");
233
+ }
234
+ if (appCode && parsed.hostname.startsWith(`${appCode}.`)) {
235
+ parsed.hostname = parsed.hostname.slice(appCode.length + 1);
236
+ } else {
237
+ parsed.hostname = hostnameParts.slice(1).join(".");
238
+ }
239
+ parsed.pathname = "";
240
+ return parsed.toString().replace(/\/$/, "");
241
+ }
102
242
  function getBaseURL(appCode) {
103
243
  const code = appCode || getCurrentApp();
104
244
  if (!code) return null;
@@ -153,11 +293,29 @@ function shouldRefreshToken(appCode) {
153
293
  const fiveMinutes = 5 * 60 * 1e3;
154
294
  return expiresAt.getTime() - now.getTime() < fiveMinutes;
155
295
  }
156
- var AMASTER_CONFIG_DIR, CONFIG_FILE;
296
+ function inferRegistryName(baseURL) {
297
+ const parsed = new URL(baseURL);
298
+ return parsed.hostname.replace(/\./g, "-");
299
+ }
300
+ function isLocalLikeHost(hostname) {
301
+ if (hostname === "localhost") {
302
+ return true;
303
+ }
304
+ if (/^\d{1,3}(\.\d{1,3}){3}$/.test(hostname)) {
305
+ return true;
306
+ }
307
+ return false;
308
+ }
309
+ var AMASTER_CONFIG_DIR, CONFIG_FILE, DEFAULT_REGISTRY_NAME, BUILTIN_REGISTRY_DEFINITIONS;
157
310
  var init_config = __esm({
158
311
  "src/config.ts"() {
159
312
  AMASTER_CONFIG_DIR = join(homedir(), ".amaster");
160
313
  CONFIG_FILE = join(AMASTER_CONFIG_DIR, "config.json");
314
+ DEFAULT_REGISTRY_NAME = "helige";
315
+ BUILTIN_REGISTRY_DEFINITIONS = {
316
+ helige: "https://helige.cn",
317
+ "helige-int": "https://helige-int.cn"
318
+ };
161
319
  }
162
320
  });
163
321
 
@@ -2790,6 +2948,8 @@ async function initOpenClaw(options) {
2790
2948
  }
2791
2949
  addApp(options.appCode, {
2792
2950
  baseURL: options.baseURL,
2951
+ registry: options.registry,
2952
+ registryBaseURL: options.registryBaseURL,
2793
2953
  ossEndpoint,
2794
2954
  initializedAt: (/* @__PURE__ */ new Date()).toISOString()
2795
2955
  });
@@ -2803,6 +2963,8 @@ async function initOpenClaw(options) {
2803
2963
  {
2804
2964
  appCode: options.appCode,
2805
2965
  baseURL: options.baseURL,
2966
+ registry: options.registry || null,
2967
+ registryBaseURL: options.registryBaseURL || null,
2806
2968
  ossEndpoint,
2807
2969
  openClawDetected: false,
2808
2970
  installedSkills: 0,
@@ -2818,6 +2980,9 @@ async function initOpenClaw(options) {
2818
2980
  console.log(chalk4.blue("\n\u{1F4CB} Configuration:\n"));
2819
2981
  console.log(` App Code: ${chalk4.green(options.appCode)}`);
2820
2982
  console.log(` Base URL: ${chalk4.gray(options.baseURL)}`);
2983
+ if (options.registryBaseURL) {
2984
+ console.log(` Registry: ${chalk4.gray(`${options.registry || "custom"} -> ${options.registryBaseURL}`)}`);
2985
+ }
2821
2986
  console.log();
2822
2987
  }
2823
2988
  spinner.start("Downloading skills...");
@@ -2871,12 +3036,16 @@ async function initOpenClaw(options) {
2871
3036
  const config = getAppConfig(app);
2872
3037
  return {
2873
3038
  appCode: app,
2874
- baseURL: config?.baseURL || null
3039
+ baseURL: config?.baseURL || null,
3040
+ registry: config?.registry || null,
3041
+ registryBaseURL: config?.registryBaseURL || null
2875
3042
  };
2876
3043
  });
2877
3044
  const summary = {
2878
3045
  appCode: options.appCode,
2879
3046
  baseURL: options.baseURL,
3047
+ registry: options.registry || null,
3048
+ registryBaseURL: options.registryBaseURL || null,
2880
3049
  ossEndpoint,
2881
3050
  openClawDetected: true,
2882
3051
  installedSkills,
@@ -3057,6 +3226,24 @@ function createAmasterClient(appCode) {
3057
3226
  }
3058
3227
  return client;
3059
3228
  }
3229
+ function resolveInitBaseURL(options) {
3230
+ if (options.url) {
3231
+ const resolvedRegistry2 = resolveRegistry(
3232
+ options.registry || inferRegistryBaseURLFromAppBaseURL(options.url, options.appCode)
3233
+ );
3234
+ return {
3235
+ baseURL: options.url,
3236
+ registryName: resolvedRegistry2.name,
3237
+ registryBaseURL: resolvedRegistry2.baseURL
3238
+ };
3239
+ }
3240
+ const resolvedRegistry = resolveRegistry(options.registry);
3241
+ return {
3242
+ baseURL: resolveAppBaseURL(options.appCode, resolvedRegistry.name),
3243
+ registryName: resolvedRegistry.name,
3244
+ registryBaseURL: resolvedRegistry.baseURL
3245
+ };
3246
+ }
3060
3247
  var program = new Command();
3061
3248
  program.name("amaster").description("CLI for Amaster SDK - Multi-app support for OpenClaw").version(resolveCliVersion());
3062
3249
  program.command("apps").description("List all configured apps").addOption(createFormatOption()).action((options) => {
@@ -3067,6 +3254,8 @@ program.command("apps").description("List all configured apps").addOption(create
3067
3254
  return {
3068
3255
  appCode,
3069
3256
  baseURL: config?.baseURL || null,
3257
+ registry: config?.registry || null,
3258
+ registryBaseURL: config?.registryBaseURL || null,
3070
3259
  authenticated: isAuthenticated(appCode),
3071
3260
  current: appCode === current
3072
3261
  };
@@ -3083,6 +3272,9 @@ program.command("apps").description("List all configured apps").addOption(create
3083
3272
  const prefix = app.current ? chalk4.green("\u2192 ") : " ";
3084
3273
  console.log(`${prefix}${chalk4.bold(app.appCode)}${app.current ? chalk4.green(" (current)") : ""}`);
3085
3274
  console.log(` ${chalk4.gray(app.baseURL || "No URL")}`);
3275
+ if (app.registryBaseURL) {
3276
+ console.log(` ${chalk4.gray(`registry: ${app.registry} -> ${app.registryBaseURL}`)}`);
3277
+ }
3086
3278
  console.log(
3087
3279
  ` ${app.authenticated ? chalk4.green("\u25CF Authenticated") : chalk4.yellow("\u25CB Not authenticated")}`
3088
3280
  );
@@ -3093,6 +3285,45 @@ program.command("apps").description("List all configured apps").addOption(create
3093
3285
  }
3094
3286
  });
3095
3287
  });
3288
+ var registryCmd = program.command("registry").description("Manage addon and app registries");
3289
+ registryCmd.command("list").alias("ls").description("List available registries").addOption(createFormatOption()).action((options) => {
3290
+ const currentRegistry = getCurrentRegistry();
3291
+ const registries = listRegistries().map((registry) => ({
3292
+ ...registry,
3293
+ current: registry.name === currentRegistry
3294
+ }));
3295
+ renderOutput(registries, {
3296
+ format: options.format,
3297
+ pretty: () => {
3298
+ console.log(chalk4.blue("\n\u{1F310} Registries\n"));
3299
+ for (const registry of registries) {
3300
+ const prefix = registry.current ? chalk4.green("\u2192 ") : " ";
3301
+ const builtin = registry.builtin ? chalk4.gray("builtin") : chalk4.gray("custom");
3302
+ console.log(`${prefix}${chalk4.bold(registry.name)}${registry.current ? chalk4.green(" (current)") : ""}`);
3303
+ console.log(` ${chalk4.gray(registry.baseURL)} ${builtin}`);
3304
+ }
3305
+ console.log();
3306
+ }
3307
+ });
3308
+ });
3309
+ registryCmd.command("use <registry>").description("Set the default registry by name or URL").addOption(createFormatOption()).action((registry, options) => {
3310
+ const resolved = setCurrentRegistry(registry);
3311
+ renderOutput(
3312
+ {
3313
+ name: resolved.name,
3314
+ baseURL: resolved.baseURL,
3315
+ builtin: resolved.builtin,
3316
+ current: true
3317
+ },
3318
+ {
3319
+ format: options.format,
3320
+ pretty: () => {
3321
+ console.log(chalk4.green(`\u2705 Now using registry: ${resolved.name}`));
3322
+ console.log(chalk4.gray(resolved.baseURL));
3323
+ }
3324
+ }
3325
+ );
3326
+ });
3096
3327
  program.command("use <app-code>").description("Set the default app for subsequent commands").addOption(createFormatOption()).action((appCode, options) => {
3097
3328
  if (setCurrentApp(appCode)) {
3098
3329
  renderOutput(
@@ -3112,10 +3343,17 @@ program.command("use <app-code>").description("Set the default app for subsequen
3112
3343
  process.exit(1);
3113
3344
  }
3114
3345
  });
3115
- program.command("init").description("Initialize an app for OpenClaw integration").requiredOption("--app-code <code>", "Application code (e.g., fhv94bto1)").requiredOption("--url <url>", "Base URL (e.g., https://fhv94bto1.helige.cn)").option("--api-key <key>", "API Key for OSS access").option("--oss-endpoint <endpoint>", "OSS endpoint").option("--force", "Reinitialize an existing app").addOption(createFormatOption()).action(async (options) => {
3346
+ program.command("init").description("Initialize an app for OpenClaw integration").requiredOption("--app-code <code>", "Application code (e.g., fhv94bto1)").option("--url <url>", "Base URL (e.g., https://fhv94bto1.helige.cn)").option("--registry <registry>", "Registry name or URL (default: current registry)").option("--api-key <key>", "API Key for OSS access").option("--oss-endpoint <endpoint>", "OSS endpoint").option("--force", "Reinitialize an existing app").addOption(createFormatOption()).action(async (options) => {
3347
+ const resolvedInit = resolveInitBaseURL({
3348
+ appCode: options.appCode,
3349
+ url: options.url,
3350
+ registry: options.registry
3351
+ });
3116
3352
  await initOpenClaw({
3117
3353
  appCode: options.appCode,
3118
- baseURL: options.url,
3354
+ baseURL: resolvedInit.baseURL,
3355
+ registry: resolvedInit.registryName,
3356
+ registryBaseURL: resolvedInit.registryBaseURL,
3119
3357
  apiKey: options.apiKey,
3120
3358
  ossEndpoint: options.ossEndpoint,
3121
3359
  force: options.force,
@@ -3669,6 +3907,6 @@ if (isDirectCliExecution()) {
3669
3907
  );
3670
3908
  }
3671
3909
 
3672
- export { createAmasterClient, isDirectCliExecution, resolveAppCode };
3910
+ export { createAmasterClient, isDirectCliExecution, resolveAppCode, resolveInitBaseURL };
3673
3911
  //# sourceMappingURL=cli.js.map
3674
3912
  //# sourceMappingURL=cli.js.map