reskill 1.6.0 → 1.7.0

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.
@@ -1 +1 @@
1
- {"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/login.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAyFpC,eAAO,MAAM,YAAY,SAOH,CAAC;AAEvB,eAAe,YAAY,CAAC"}
1
+ {"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/login.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA0FpC,eAAO,MAAM,YAAY,SAOH,CAAC;AAEvB,eAAe,YAAY,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"whoami.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/whoami.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAmEpC,eAAO,MAAM,aAAa,SAMH,CAAC;AAExB,eAAe,aAAa,CAAC"}
1
+ {"version":3,"file":"whoami.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/whoami.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAoEpC,eAAO,MAAM,aAAa,SAMH,CAAC;AAExB,eAAe,aAAa,CAAC"}
package/dist/cli/index.js CHANGED
@@ -437,12 +437,39 @@ var external_node_fs_ = __webpack_require__("node:fs");
437
437
  * Hardcoded registry to scope mapping
438
438
  * TODO: Replace with dynamic fetching from /api/registry/info
439
439
  */ const REGISTRY_SCOPE_MAP = {
440
+ // rush-app (private registry, new)
441
+ 'https://rush-test.zhenguanyu.com': '@kanyun',
442
+ 'https://rush.zhenguanyu.com': '@kanyun',
443
+ // reskill-app (private registry, legacy)
440
444
  'https://reskill-test.zhenguanyu.com': '@kanyun',
441
- 'https://reskill-test.zhenguanyu.com/': '@kanyun',
442
445
  // Local development
443
- 'http://localhost:3000': '@kanyun',
444
- 'http://localhost:3000/': '@kanyun'
446
+ 'http://localhost:3000': '@kanyun'
445
447
  };
448
+ /**
449
+ * Registry API prefix mapping
450
+ *
451
+ * rush-app hosts reskill APIs under /api/reskill/ prefix.
452
+ * Default for unlisted registries: '/api'
453
+ */ const REGISTRY_API_PREFIX = {
454
+ 'https://rush-test.zhenguanyu.com': '/api/reskill',
455
+ 'https://rush.zhenguanyu.com': '/api/reskill',
456
+ 'http://localhost:3000': '/api/reskill'
457
+ };
458
+ /**
459
+ * Get the API path prefix for a given registry URL
460
+ *
461
+ * @param registryUrl - Registry URL
462
+ * @returns API prefix string (e.g., '/api' or '/api/reskill')
463
+ *
464
+ * @example
465
+ * getApiPrefix('https://rush-test.zhenguanyu.com') // '/api/reskill'
466
+ * getApiPrefix('https://reskill.info') // '/api'
467
+ * getApiPrefix('https://unknown.com') // '/api'
468
+ */ function getApiPrefix(registryUrl) {
469
+ if (!registryUrl) return '/api';
470
+ const normalized = registryUrl.endsWith('/') ? registryUrl.slice(0, -1) : registryUrl;
471
+ return REGISTRY_API_PREFIX[normalized] || '/api';
472
+ }
446
473
  /**
447
474
  * Get the scope for a given registry URL
448
475
  *
@@ -450,7 +477,7 @@ var external_node_fs_ = __webpack_require__("node:fs");
450
477
  * @returns Scope string (e.g., "@kanyun") or null if not found
451
478
  *
452
479
  * @example
453
- * getScopeForRegistry('https://reskill-test.zhenguanyu.com') // '@kanyun'
480
+ * getScopeForRegistry('https://rush-test.zhenguanyu.com') // '@kanyun'
454
481
  * getScopeForRegistry('https://unknown.com') // null
455
482
  */ function getScopeForRegistry(registry) {
456
483
  if (!registry) return null;
@@ -468,8 +495,8 @@ var external_node_fs_ = __webpack_require__("node:fs");
468
495
  * @returns Registry URL (with trailing slash) or null if not found
469
496
  *
470
497
  * @example
471
- * getRegistryForScope('@kanyun') // 'https://reskill-test.zhenguanyu.com/'
472
- * getRegistryForScope('kanyun') // 'https://reskill-test.zhenguanyu.com/'
498
+ * getRegistryForScope('@kanyun') // 'https://rush-test.zhenguanyu.com/'
499
+ * getRegistryForScope('kanyun') // 'https://rush-test.zhenguanyu.com/'
473
500
  * getRegistryForScope('@unknown') // null
474
501
  * getRegistryForScope('@mycompany', { '@mycompany': 'https://my.registry.com/' }) // 'https://my.registry.com/'
475
502
  */ function getRegistryForScope(scope, customRegistries) {
@@ -499,8 +526,8 @@ var external_node_fs_ = __webpack_require__("node:fs");
499
526
  * @throws Error if scope is provided but not found in the registry map
500
527
  *
501
528
  * @example
502
- * getRegistryUrl('@kanyun') // 'https://reskill-test.zhenguanyu.com/'
503
- * getRegistryUrl('kanyun') // 'https://reskill-test.zhenguanyu.com/'
529
+ * getRegistryUrl('@kanyun') // 'https://rush-test.zhenguanyu.com/'
530
+ * getRegistryUrl('kanyun') // 'https://rush-test.zhenguanyu.com/'
504
531
  * getRegistryUrl(null) // 'https://reskill.info/'
505
532
  * getRegistryUrl('') // 'https://reskill.info/'
506
533
  * getRegistryUrl('@unknown') // throws Error
@@ -2684,6 +2711,15 @@ class RegistryClient {
2684
2711
  this.config = config;
2685
2712
  }
2686
2713
  /**
2714
+ * Get API base URL (registry + apiPrefix)
2715
+ *
2716
+ * @returns Base URL for API calls, e.g., 'https://example.com/api' or 'https://rush.com/api/reskill'
2717
+ */ getApiBase() {
2718
+ const prefix = this.config.apiPrefix || '/api';
2719
+ const registry = this.config.registry.endsWith('/') ? this.config.registry.slice(0, -1) : this.config.registry;
2720
+ return `${registry}${prefix}`;
2721
+ }
2722
+ /**
2687
2723
  * Get authorization headers
2688
2724
  */ getAuthHeaders() {
2689
2725
  const headers = {
@@ -2696,7 +2732,7 @@ class RegistryClient {
2696
2732
  /**
2697
2733
  * Get current user info (whoami)
2698
2734
  */ async whoami() {
2699
- const url = `${this.config.registry}/api/auth/me`;
2735
+ const url = `${this.getApiBase()}/auth/me`;
2700
2736
  const response = await fetch(url, {
2701
2737
  method: 'GET',
2702
2738
  headers: this.getAuthHeaders()
@@ -2714,7 +2750,7 @@ class RegistryClient {
2714
2750
  * @returns User information if authentication succeeds
2715
2751
  * @throws RegistryError if authentication fails
2716
2752
  */ async loginCli() {
2717
- const url = `${this.config.registry}/api/auth/login-cli`;
2753
+ const url = `${this.getApiBase()}/auth/login-cli`;
2718
2754
  const response = await fetch(url, {
2719
2755
  method: 'POST',
2720
2756
  headers: this.getAuthHeaders()
@@ -2770,7 +2806,7 @@ class RegistryClient {
2770
2806
  * @returns Skill 基本信息
2771
2807
  * @throws RegistryError 如果 skill 不存在或请求失败
2772
2808
  */ async getSkillInfo(skillName) {
2773
- const url = `${this.config.registry}/api/skills/${encodeURIComponent(skillName)}`;
2809
+ const url = `${this.getApiBase()}/skills/${encodeURIComponent(skillName)}`;
2774
2810
  const response = await fetch(url, {
2775
2811
  method: 'GET',
2776
2812
  headers: this.getAuthHeaders()
@@ -2804,7 +2840,7 @@ class RegistryClient {
2804
2840
  // 如果是 semver 版本号,直接返回
2805
2841
  if (/^\d+\.\d+\.\d+/.test(version)) return version;
2806
2842
  // 否则视为 tag,需要查询 dist-tags
2807
- const url = `${this.config.registry}/api/skills/${encodeURIComponent(skillName)}`;
2843
+ const url = `${this.getApiBase()}/skills/${encodeURIComponent(skillName)}`;
2808
2844
  const response = await fetch(url, {
2809
2845
  method: 'GET',
2810
2846
  headers: this.getAuthHeaders()
@@ -2839,15 +2875,34 @@ class RegistryClient {
2839
2875
  * @example
2840
2876
  * const { tarball, integrity } = await client.downloadSkill('@kanyun/test-skill', '1.0.0');
2841
2877
  */ async downloadSkill(skillName, version) {
2842
- const url = `${this.config.registry}/api/skills/${encodeURIComponent(skillName)}/versions/${version}/download`;
2878
+ const url = `${this.getApiBase()}/skills/${encodeURIComponent(skillName)}/versions/${version}/download`;
2879
+ // Use redirect: 'manual' to capture x-integrity header from 302 responses.
2880
+ // The registry returns a 302 redirect to OSS with the integrity header,
2881
+ // which would be lost if fetch auto-follows the redirect.
2843
2882
  const response = await fetch(url, {
2844
2883
  method: 'GET',
2845
- headers: this.getAuthHeaders()
2884
+ headers: this.getAuthHeaders(),
2885
+ redirect: 'manual'
2846
2886
  });
2887
+ // Handle 302 redirect (registry → OSS signed URL)
2888
+ if (301 === response.status || 302 === response.status) {
2889
+ const integrity = response.headers.get('x-integrity') || '';
2890
+ const location = response.headers.get('location');
2891
+ if (!location) throw new RegistryError('Missing redirect location in download response', response.status);
2892
+ const downloadResponse = await fetch(location);
2893
+ if (!downloadResponse.ok) throw new RegistryError(`Download from storage failed: ${downloadResponse.status}`, downloadResponse.status);
2894
+ const arrayBuffer = await downloadResponse.arrayBuffer();
2895
+ const tarball = Buffer.from(arrayBuffer);
2896
+ return {
2897
+ tarball,
2898
+ integrity
2899
+ };
2900
+ }
2847
2901
  if (!response.ok) {
2848
2902
  const data = await response.json();
2849
2903
  throw new RegistryError(data.error || `Download failed: ${response.status}`, response.status, data);
2850
2904
  }
2905
+ // Direct response (no redirect) - read tarball and integrity directly
2851
2906
  const arrayBuffer = await response.arrayBuffer();
2852
2907
  const tarball = Buffer.from(arrayBuffer);
2853
2908
  const integrity = response.headers.get('x-integrity') || '';
@@ -2897,7 +2952,7 @@ class RegistryClient {
2897
2952
  /**
2898
2953
  * Publish a skill to the registry
2899
2954
  */ async publish(skillName, payload, skillPath, options = {}) {
2900
- const url = `${this.config.registry}/api/skills/publish`;
2955
+ const url = `${this.getApiBase()}/skills/publish`;
2901
2956
  // 提取短名称作为 tarball 顶层目录(不含 scope 前缀)
2902
2957
  const shortName = getShortName(skillName);
2903
2958
  // Create tarball with short name as top-level directory
@@ -3175,7 +3230,8 @@ class RegistryResolver {
3175
3230
  const registryUrl = getRegistryUrl(parsed.scope);
3176
3231
  // 3. 创建 client 并解析版本
3177
3232
  const client = new RegistryClient({
3178
- registry: registryUrl
3233
+ registry: registryUrl,
3234
+ apiPrefix: getApiPrefix(registryUrl)
3179
3235
  });
3180
3236
  const version = await client.resolveVersion(parsed.fullName, parsed.version);
3181
3237
  // 4. 下载 tarball
@@ -4040,7 +4096,8 @@ class RegistryResolver {
4040
4096
  const parsed = parseSkillIdentifier(ref);
4041
4097
  const registryUrl = getRegistryUrl(parsed.scope);
4042
4098
  const client = new RegistryClient({
4043
- registry: registryUrl
4099
+ registry: registryUrl,
4100
+ apiPrefix: getApiPrefix(registryUrl)
4044
4101
  });
4045
4102
  // 新增:先查询 skill 信息获取 source_type
4046
4103
  let skillInfo;
@@ -4181,7 +4238,8 @@ class RegistryResolver {
4181
4238
  /**
4182
4239
  * 安装 Local Folder 模式发布的 skill
4183
4240
  *
4184
- * 通过 Registry 的 /api/skills/:name/download API 下载 tarball
4241
+ * 通过 Registry 的 {apiPrefix}/skills/:name/download API 下载 tarball
4242
+ * (apiPrefix 根据 registry 不同而不同,如 /api 或 /api/reskill)
4185
4243
  */ async installFromRegistryLocal(_skillInfo, parsed, targetAgents, options = {}) {
4186
4244
  const registryUrl = getRegistryUrl(parsed.scope);
4187
4245
  // 构造下载 URL(通过 Registry API)
@@ -6008,7 +6066,8 @@ async function loginAction(options) {
6008
6066
  // Verify token by calling login-cli endpoint
6009
6067
  const client = new RegistryClient({
6010
6068
  registry,
6011
- token
6069
+ token,
6070
+ apiPrefix: getApiPrefix(registry)
6012
6071
  });
6013
6072
  try {
6014
6073
  const response = await client.loginCli();
@@ -7125,7 +7184,8 @@ async function publishAction(skillPath, options) {
7125
7184
  logger_logger.log(`Publishing to ${registry}...`);
7126
7185
  const client = new RegistryClient({
7127
7186
  registry,
7128
- token
7187
+ token,
7188
+ apiPrefix: getApiPrefix(registry)
7129
7189
  });
7130
7190
  try {
7131
7191
  // Get skill name from SKILL.md (primary source per agentskills.io spec)
@@ -7303,7 +7363,8 @@ async function whoamiAction(options) {
7303
7363
  // Verify with server
7304
7364
  const client = new RegistryClient({
7305
7365
  registry,
7306
- token
7366
+ token,
7367
+ apiPrefix: getApiPrefix(registry)
7307
7368
  });
7308
7369
  try {
7309
7370
  const response = await client.whoami();
@@ -8,6 +8,8 @@ import type { PublishPayload } from './publisher.js';
8
8
  export interface RegistryConfig {
9
9
  registry: string;
10
10
  token?: string;
11
+ /** API path prefix, e.g., '/api' (default) or '/api/reskill' for rush-app */
12
+ apiPrefix?: string;
11
13
  }
12
14
  export interface PublishRequest {
13
15
  name: string;
@@ -66,6 +68,12 @@ export declare class RegistryError extends Error {
66
68
  export declare class RegistryClient {
67
69
  private config;
68
70
  constructor(config: RegistryConfig);
71
+ /**
72
+ * Get API base URL (registry + apiPrefix)
73
+ *
74
+ * @returns Base URL for API calls, e.g., 'https://example.com/api' or 'https://rush.com/api/reskill'
75
+ */
76
+ private getApiBase;
69
77
  /**
70
78
  * Get authorization headers
71
79
  */
@@ -1 +1 @@
1
- {"version":3,"file":"registry-client.d.ts","sourceRoot":"","sources":["../../src/core/registry-client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"registry-client.d.ts","sourceRoot":"","sources":["../../src/core/registry-client.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"registry-resolver.d.ts","sourceRoot":"","sources":["../../src/core/registry-resolver.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAGL,KAAK,qBAAqB,EAE3B,MAAM,4BAA4B,CAAC;AAQpC,MAAM,WAAW,qBAAqB;IACpC,8BAA8B;IAC9B,MAAM,EAAE,qBAAqB,CAAC;IAC9B,uCAAuC;IACvC,SAAS,EAAE,MAAM,CAAC;IAClB,uBAAuB;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,mBAAmB;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,gCAAgC;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,iCAAiC;IACjC,SAAS,EAAE,MAAM,CAAC;CACnB;AAMD,qBAAa,gBAAgB;IAC3B;;;;;;;;;;;;;OAaG;IACH,MAAM,CAAC,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAwC1C;;;;;;;;;;OAUG;IACG,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,CAAC;IA+B1D;;;;;;OAMG;IACG,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAWjE"}
1
+ {"version":3,"file":"registry-resolver.d.ts","sourceRoot":"","sources":["../../src/core/registry-resolver.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAIL,KAAK,qBAAqB,EAE3B,MAAM,4BAA4B,CAAC;AAQpC,MAAM,WAAW,qBAAqB;IACpC,8BAA8B;IAC9B,MAAM,EAAE,qBAAqB,CAAC;IAC9B,uCAAuC;IACvC,SAAS,EAAE,MAAM,CAAC;IAClB,uBAAuB;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,mBAAmB;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,gCAAgC;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,iCAAiC;IACjC,SAAS,EAAE,MAAM,CAAC;CACnB;AAMD,qBAAa,gBAAgB;IAC3B;;;;;;;;;;;;;OAaG;IACH,MAAM,CAAC,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAwC1C;;;;;;;;;;OAUG;IACG,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,CAAC;IA+B1D;;;;;;OAMG;IACG,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAWjE"}
@@ -178,7 +178,8 @@ export declare class SkillManager {
178
178
  /**
179
179
  * 安装 Local Folder 模式发布的 skill
180
180
  *
181
- * 通过 Registry 的 /api/skills/:name/download API 下载 tarball
181
+ * 通过 Registry 的 {apiPrefix}/skills/:name/download API 下载 tarball
182
+ * (apiPrefix 根据 registry 不同而不同,如 /api 或 /api/reskill)
182
183
  */
183
184
  private installFromRegistryLocal;
184
185
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"skill-manager.d.ts","sourceRoot":"","sources":["../../src/core/skill-manager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"skill-manager.d.ts","sourceRoot":"","sources":["../../src/core/skill-manager.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -2398,12 +2398,39 @@ const installer_SKILLS_SUBDIR = 'skills';
2398
2398
  * Hardcoded registry to scope mapping
2399
2399
  * TODO: Replace with dynamic fetching from /api/registry/info
2400
2400
  */ const REGISTRY_SCOPE_MAP = {
2401
+ // rush-app (private registry, new)
2402
+ 'https://rush-test.zhenguanyu.com': '@kanyun',
2403
+ 'https://rush.zhenguanyu.com': '@kanyun',
2404
+ // reskill-app (private registry, legacy)
2401
2405
  'https://reskill-test.zhenguanyu.com': '@kanyun',
2402
- 'https://reskill-test.zhenguanyu.com/': '@kanyun',
2403
2406
  // Local development
2404
- 'http://localhost:3000': '@kanyun',
2405
- 'http://localhost:3000/': '@kanyun'
2407
+ 'http://localhost:3000': '@kanyun'
2406
2408
  };
2409
+ /**
2410
+ * Registry API prefix mapping
2411
+ *
2412
+ * rush-app hosts reskill APIs under /api/reskill/ prefix.
2413
+ * Default for unlisted registries: '/api'
2414
+ */ const REGISTRY_API_PREFIX = {
2415
+ 'https://rush-test.zhenguanyu.com': '/api/reskill',
2416
+ 'https://rush.zhenguanyu.com': '/api/reskill',
2417
+ 'http://localhost:3000': '/api/reskill'
2418
+ };
2419
+ /**
2420
+ * Get the API path prefix for a given registry URL
2421
+ *
2422
+ * @param registryUrl - Registry URL
2423
+ * @returns API prefix string (e.g., '/api' or '/api/reskill')
2424
+ *
2425
+ * @example
2426
+ * getApiPrefix('https://rush-test.zhenguanyu.com') // '/api/reskill'
2427
+ * getApiPrefix('https://reskill.info') // '/api'
2428
+ * getApiPrefix('https://unknown.com') // '/api'
2429
+ */ function getApiPrefix(registryUrl) {
2430
+ if (!registryUrl) return '/api';
2431
+ const normalized = registryUrl.endsWith('/') ? registryUrl.slice(0, -1) : registryUrl;
2432
+ return REGISTRY_API_PREFIX[normalized] || '/api';
2433
+ }
2407
2434
  /**
2408
2435
  * Get the registry URL for a given scope (reverse lookup)
2409
2436
  *
@@ -2412,8 +2439,8 @@ const installer_SKILLS_SUBDIR = 'skills';
2412
2439
  * @returns Registry URL (with trailing slash) or null if not found
2413
2440
  *
2414
2441
  * @example
2415
- * getRegistryForScope('@kanyun') // 'https://reskill-test.zhenguanyu.com/'
2416
- * getRegistryForScope('kanyun') // 'https://reskill-test.zhenguanyu.com/'
2442
+ * getRegistryForScope('@kanyun') // 'https://rush-test.zhenguanyu.com/'
2443
+ * getRegistryForScope('kanyun') // 'https://rush-test.zhenguanyu.com/'
2417
2444
  * getRegistryForScope('@unknown') // null
2418
2445
  * getRegistryForScope('@mycompany', { '@mycompany': 'https://my.registry.com/' }) // 'https://my.registry.com/'
2419
2446
  */ function getRegistryForScope(scope, customRegistries) {
@@ -2443,8 +2470,8 @@ const installer_SKILLS_SUBDIR = 'skills';
2443
2470
  * @throws Error if scope is provided but not found in the registry map
2444
2471
  *
2445
2472
  * @example
2446
- * getRegistryUrl('@kanyun') // 'https://reskill-test.zhenguanyu.com/'
2447
- * getRegistryUrl('kanyun') // 'https://reskill-test.zhenguanyu.com/'
2473
+ * getRegistryUrl('@kanyun') // 'https://rush-test.zhenguanyu.com/'
2474
+ * getRegistryUrl('kanyun') // 'https://rush-test.zhenguanyu.com/'
2448
2475
  * getRegistryUrl(null) // 'https://reskill.info/'
2449
2476
  * getRegistryUrl('') // 'https://reskill.info/'
2450
2477
  * getRegistryUrl('@unknown') // throws Error
@@ -2581,6 +2608,15 @@ class RegistryClient {
2581
2608
  this.config = config;
2582
2609
  }
2583
2610
  /**
2611
+ * Get API base URL (registry + apiPrefix)
2612
+ *
2613
+ * @returns Base URL for API calls, e.g., 'https://example.com/api' or 'https://rush.com/api/reskill'
2614
+ */ getApiBase() {
2615
+ const prefix = this.config.apiPrefix || '/api';
2616
+ const registry = this.config.registry.endsWith('/') ? this.config.registry.slice(0, -1) : this.config.registry;
2617
+ return `${registry}${prefix}`;
2618
+ }
2619
+ /**
2584
2620
  * Get authorization headers
2585
2621
  */ getAuthHeaders() {
2586
2622
  const headers = {
@@ -2593,7 +2629,7 @@ class RegistryClient {
2593
2629
  /**
2594
2630
  * Get current user info (whoami)
2595
2631
  */ async whoami() {
2596
- const url = `${this.config.registry}/api/auth/me`;
2632
+ const url = `${this.getApiBase()}/auth/me`;
2597
2633
  const response = await fetch(url, {
2598
2634
  method: 'GET',
2599
2635
  headers: this.getAuthHeaders()
@@ -2611,7 +2647,7 @@ class RegistryClient {
2611
2647
  * @returns User information if authentication succeeds
2612
2648
  * @throws RegistryError if authentication fails
2613
2649
  */ async loginCli() {
2614
- const url = `${this.config.registry}/api/auth/login-cli`;
2650
+ const url = `${this.getApiBase()}/auth/login-cli`;
2615
2651
  const response = await fetch(url, {
2616
2652
  method: 'POST',
2617
2653
  headers: this.getAuthHeaders()
@@ -2667,7 +2703,7 @@ class RegistryClient {
2667
2703
  * @returns Skill 基本信息
2668
2704
  * @throws RegistryError 如果 skill 不存在或请求失败
2669
2705
  */ async getSkillInfo(skillName) {
2670
- const url = `${this.config.registry}/api/skills/${encodeURIComponent(skillName)}`;
2706
+ const url = `${this.getApiBase()}/skills/${encodeURIComponent(skillName)}`;
2671
2707
  const response = await fetch(url, {
2672
2708
  method: 'GET',
2673
2709
  headers: this.getAuthHeaders()
@@ -2701,7 +2737,7 @@ class RegistryClient {
2701
2737
  // 如果是 semver 版本号,直接返回
2702
2738
  if (/^\d+\.\d+\.\d+/.test(version)) return version;
2703
2739
  // 否则视为 tag,需要查询 dist-tags
2704
- const url = `${this.config.registry}/api/skills/${encodeURIComponent(skillName)}`;
2740
+ const url = `${this.getApiBase()}/skills/${encodeURIComponent(skillName)}`;
2705
2741
  const response = await fetch(url, {
2706
2742
  method: 'GET',
2707
2743
  headers: this.getAuthHeaders()
@@ -2736,15 +2772,34 @@ class RegistryClient {
2736
2772
  * @example
2737
2773
  * const { tarball, integrity } = await client.downloadSkill('@kanyun/test-skill', '1.0.0');
2738
2774
  */ async downloadSkill(skillName, version) {
2739
- const url = `${this.config.registry}/api/skills/${encodeURIComponent(skillName)}/versions/${version}/download`;
2775
+ const url = `${this.getApiBase()}/skills/${encodeURIComponent(skillName)}/versions/${version}/download`;
2776
+ // Use redirect: 'manual' to capture x-integrity header from 302 responses.
2777
+ // The registry returns a 302 redirect to OSS with the integrity header,
2778
+ // which would be lost if fetch auto-follows the redirect.
2740
2779
  const response = await fetch(url, {
2741
2780
  method: 'GET',
2742
- headers: this.getAuthHeaders()
2781
+ headers: this.getAuthHeaders(),
2782
+ redirect: 'manual'
2743
2783
  });
2784
+ // Handle 302 redirect (registry → OSS signed URL)
2785
+ if (301 === response.status || 302 === response.status) {
2786
+ const integrity = response.headers.get('x-integrity') || '';
2787
+ const location = response.headers.get('location');
2788
+ if (!location) throw new RegistryError('Missing redirect location in download response', response.status);
2789
+ const downloadResponse = await fetch(location);
2790
+ if (!downloadResponse.ok) throw new RegistryError(`Download from storage failed: ${downloadResponse.status}`, downloadResponse.status);
2791
+ const arrayBuffer = await downloadResponse.arrayBuffer();
2792
+ const tarball = Buffer.from(arrayBuffer);
2793
+ return {
2794
+ tarball,
2795
+ integrity
2796
+ };
2797
+ }
2744
2798
  if (!response.ok) {
2745
2799
  const data = await response.json();
2746
2800
  throw new RegistryError(data.error || `Download failed: ${response.status}`, response.status, data);
2747
2801
  }
2802
+ // Direct response (no redirect) - read tarball and integrity directly
2748
2803
  const arrayBuffer = await response.arrayBuffer();
2749
2804
  const tarball = Buffer.from(arrayBuffer);
2750
2805
  const integrity = response.headers.get('x-integrity') || '';
@@ -2794,7 +2849,7 @@ class RegistryClient {
2794
2849
  /**
2795
2850
  * Publish a skill to the registry
2796
2851
  */ async publish(skillName, payload, skillPath, options = {}) {
2797
- const url = `${this.config.registry}/api/skills/publish`;
2852
+ const url = `${this.getApiBase()}/skills/publish`;
2798
2853
  // 提取短名称作为 tarball 顶层目录(不含 scope 前缀)
2799
2854
  const shortName = getShortName(skillName);
2800
2855
  // Create tarball with short name as top-level directory
@@ -3138,7 +3193,8 @@ class RegistryResolver {
3138
3193
  const registryUrl = getRegistryUrl(parsed.scope);
3139
3194
  // 3. 创建 client 并解析版本
3140
3195
  const client = new RegistryClient({
3141
- registry: registryUrl
3196
+ registry: registryUrl,
3197
+ apiPrefix: getApiPrefix(registryUrl)
3142
3198
  });
3143
3199
  const version = await client.resolveVersion(parsed.fullName, parsed.version);
3144
3200
  // 4. 下载 tarball
@@ -4030,7 +4086,8 @@ class RegistryResolver {
4030
4086
  const parsed = parseSkillIdentifier(ref);
4031
4087
  const registryUrl = getRegistryUrl(parsed.scope);
4032
4088
  const client = new RegistryClient({
4033
- registry: registryUrl
4089
+ registry: registryUrl,
4090
+ apiPrefix: getApiPrefix(registryUrl)
4034
4091
  });
4035
4092
  // 新增:先查询 skill 信息获取 source_type
4036
4093
  let skillInfo;
@@ -4171,7 +4228,8 @@ class RegistryResolver {
4171
4228
  /**
4172
4229
  * 安装 Local Folder 模式发布的 skill
4173
4230
  *
4174
- * 通过 Registry 的 /api/skills/:name/download API 下载 tarball
4231
+ * 通过 Registry 的 {apiPrefix}/skills/:name/download API 下载 tarball
4232
+ * (apiPrefix 根据 registry 不同而不同,如 /api 或 /api/reskill)
4175
4233
  */ async installFromRegistryLocal(_skillInfo, parsed, targetAgents, options = {}) {
4176
4234
  const registryUrl = getRegistryUrl(parsed.scope);
4177
4235
  // 构造下载 URL(通过 Registry API)
@@ -9,6 +9,18 @@
9
9
  * 用于无 scope 的 skill 安装
10
10
  */
11
11
  export declare const PUBLIC_REGISTRY = "https://reskill.info/";
12
+ /**
13
+ * Get the API path prefix for a given registry URL
14
+ *
15
+ * @param registryUrl - Registry URL
16
+ * @returns API prefix string (e.g., '/api' or '/api/reskill')
17
+ *
18
+ * @example
19
+ * getApiPrefix('https://rush-test.zhenguanyu.com') // '/api/reskill'
20
+ * getApiPrefix('https://reskill.info') // '/api'
21
+ * getApiPrefix('https://unknown.com') // '/api'
22
+ */
23
+ export declare function getApiPrefix(registryUrl: string): string;
12
24
  /**
13
25
  * Parsed skill name result
14
26
  */
@@ -41,7 +53,7 @@ export interface ParsedSkillIdentifier {
41
53
  * @returns Scope string (e.g., "@kanyun") or null if not found
42
54
  *
43
55
  * @example
44
- * getScopeForRegistry('https://reskill-test.zhenguanyu.com') // '@kanyun'
56
+ * getScopeForRegistry('https://rush-test.zhenguanyu.com') // '@kanyun'
45
57
  * getScopeForRegistry('https://unknown.com') // null
46
58
  */
47
59
  export declare function getScopeForRegistry(registry: string): string | null;
@@ -58,8 +70,8 @@ export type ScopeRegistries = Record<string, string>;
58
70
  * @returns Registry URL (with trailing slash) or null if not found
59
71
  *
60
72
  * @example
61
- * getRegistryForScope('@kanyun') // 'https://reskill-test.zhenguanyu.com/'
62
- * getRegistryForScope('kanyun') // 'https://reskill-test.zhenguanyu.com/'
73
+ * getRegistryForScope('@kanyun') // 'https://rush-test.zhenguanyu.com/'
74
+ * getRegistryForScope('kanyun') // 'https://rush-test.zhenguanyu.com/'
63
75
  * getRegistryForScope('@unknown') // null
64
76
  * getRegistryForScope('@mycompany', { '@mycompany': 'https://my.registry.com/' }) // 'https://my.registry.com/'
65
77
  */
@@ -76,8 +88,8 @@ export declare function getRegistryForScope(scope: string, customRegistries?: Sc
76
88
  * @throws Error if scope is provided but not found in the registry map
77
89
  *
78
90
  * @example
79
- * getRegistryUrl('@kanyun') // 'https://reskill-test.zhenguanyu.com/'
80
- * getRegistryUrl('kanyun') // 'https://reskill-test.zhenguanyu.com/'
91
+ * getRegistryUrl('@kanyun') // 'https://rush-test.zhenguanyu.com/'
92
+ * getRegistryUrl('kanyun') // 'https://rush-test.zhenguanyu.com/'
81
93
  * getRegistryUrl(null) // 'https://reskill.info/'
82
94
  * getRegistryUrl('') // 'https://reskill.info/'
83
95
  * getRegistryUrl('@unknown') // throws Error
@@ -1 +1 @@
1
- {"version":3,"file":"registry-scope.d.ts","sourceRoot":"","sources":["../../src/utils/registry-scope.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;GAGG;AACH,eAAO,MAAM,eAAe,0BAA0B,CAAC;AAcvD;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,gDAAgD;IAChD,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,4DAA4D;IAC5D,IAAI,EAAE,MAAM,CAAC;IACb,iEAAiE;IACjE,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;GAGG;AACH,MAAM,WAAW,qBAAqB;IACpC,oEAAoE;IACpE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,4DAA4D;IAC5D,IAAI,EAAE,MAAM,CAAC;IACb,gEAAgE;IAChE,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,qEAAqE;IACrE,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAcnE;AAED;;;GAGG;AACH,MAAM,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAErD;;;;;;;;;;;;GAYG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,MAAM,EACb,gBAAgB,CAAC,EAAE,eAAe,GACjC,MAAM,GAAG,IAAI,CAwBf;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAChC,gBAAgB,CAAC,EAAE,eAAe,GACjC,MAAM,CAgBR;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,eAAe,CAiBjE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAS7E;AAED;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,qBAAqB,CAwD9E"}
1
+ {"version":3,"file":"registry-scope.d.ts","sourceRoot":"","sources":["../../src/utils/registry-scope.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;GAGG;AACH,eAAO,MAAM,eAAe,0BAA0B,CAAC;AA8BvD;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAMxD;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,gDAAgD;IAChD,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,4DAA4D;IAC5D,IAAI,EAAE,MAAM,CAAC;IACb,iEAAiE;IACjE,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;GAGG;AACH,MAAM,WAAW,qBAAqB;IACpC,oEAAoE;IACpE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,4DAA4D;IAC5D,IAAI,EAAE,MAAM,CAAC;IACb,gEAAgE;IAChE,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,qEAAqE;IACrE,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAcnE;AAED;;;GAGG;AACH,MAAM,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAErD;;;;;;;;;;;;GAYG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,MAAM,EACb,gBAAgB,CAAC,EAAE,eAAe,GACjC,MAAM,GAAG,IAAI,CAwBf;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAChC,gBAAgB,CAAC,EAAE,eAAe,GACjC,MAAM,CAgBR;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,eAAe,CAiBjE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAS7E;AAED;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,qBAAqB,CAwD9E"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "reskill",
3
- "version": "1.6.0",
3
+ "version": "1.7.0",
4
4
  "description": "AI Skills Package Manager - Git-based skills management for AI agents",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",