From 616319fe3533d61dfbba203f90e6a6a2951b47f3 Mon Sep 17 00:00:00 2001 From: chenbaowang <49091147+Rsweater@users.noreply.github.com> Date: Thu, 16 Apr 2026 11:18:20 +0800 Subject: [PATCH] fix(cli): replace execSync unzip with unzipper for cross-platform support - Add @types/unzipper for TypeScript support - Fix location header type assertion (string | string[] -> string) - Bump version to 1.0.5 --- skillhub-cli/package.json | 6 +- skillhub-cli/pnpm-lock.yaml | 116 ++++++++++++++++++++++++++ skillhub-cli/src/commands/download.ts | 2 +- skillhub-cli/src/commands/install.ts | 9 +- 4 files changed, 127 insertions(+), 6 deletions(-) diff --git a/skillhub-cli/package.json b/skillhub-cli/package.json index 65425aa0e..e6bbc3e2d 100644 --- a/skillhub-cli/package.json +++ b/skillhub-cli/package.json @@ -1,6 +1,6 @@ { "name": "motovis-skillhub", - "version": "1.0.3", + "version": "1.0.5", "type": "module", "description": "SkillHub CLI - 企业级 Agent Skill 管理工具,支持命名空间", "bin": { @@ -19,11 +19,13 @@ "ora": "^9.3.0", "picocolors": "^1.1.1", "semver": "^7.7.4", - "undici": "^7.24.0" + "undici": "^7.24.0", + "unzipper": "^0.12.3" }, "devDependencies": { "@types/node": "^22.0.0", "@types/semver": "^7.5.8", + "@types/unzipper": "^0.10.11", "typescript": "^5.6.0", "unbuild": "^3.0.0", "vitest": "^3.0.0" diff --git a/skillhub-cli/pnpm-lock.yaml b/skillhub-cli/pnpm-lock.yaml index bb051a695..4a105fa44 100644 --- a/skillhub-cli/pnpm-lock.yaml +++ b/skillhub-cli/pnpm-lock.yaml @@ -29,6 +29,9 @@ importers: undici: specifier: ^7.24.0 version: 7.24.7 + unzipper: + specifier: ^0.12.3 + version: 0.12.3 devDependencies: '@types/node': specifier: ^22.0.0 @@ -36,6 +39,9 @@ importers: '@types/semver': specifier: ^7.5.8 version: 7.7.1 + '@types/unzipper': + specifier: ^0.10.11 + version: 0.10.11 typescript: specifier: ^5.6.0 version: 5.9.3 @@ -603,6 +609,9 @@ packages: '@types/semver@7.7.1': resolution: {integrity: sha512-FmgJfu+MOcQ370SD0ev7EI8TlCAfKYU+B4m5T3yXc1CiRN94g/SZPtsCkk506aUDtlMnFZvasDwHHUcZUEaYuA==} + '@types/unzipper@0.10.11': + resolution: {integrity: sha512-D25im2zjyMCcgL9ag6N46+wbtJBnXIr7SI4zHf9eJD2Dw2tEB5e+p5MYkrxKIVRscs5QV0EhtU9rgXSPx90oJg==} + '@vitest/expect@3.2.4': resolution: {integrity: sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==} @@ -657,6 +666,9 @@ packages: engines: {node: '>=6.0.0'} hasBin: true + bluebird@3.7.2: + resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==} + boolbase@1.0.0: resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} @@ -722,6 +734,9 @@ packages: convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + core-util-is@1.0.3: + resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + css-declaration-sorter@7.3.1: resolution: {integrity: sha512-gz6x+KkgNCjxq3Var03pRYLhyNfwhkKF1g/yoLgDNtFvVu0/fOLV9C8fFEZRjACp/XQLumjAYo7JVjzH3wLbxA==} engines: {node: ^14 || ^16 || >=18} @@ -803,6 +818,9 @@ packages: domutils@3.2.2: resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==} + duplexer2@0.1.4: + resolution: {integrity: sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==} + electron-to-chromium@1.5.331: resolution: {integrity: sha512-IbxXrsTlD3hRodkLnbxAPP4OuJYdWCeM3IOdT+CpcMoIwIoDfCmRpEtSPfwBXxVkg9xmBeY7Lz2Eo2TDn/HC3Q==} @@ -864,6 +882,10 @@ packages: fraction.js@5.3.4: resolution: {integrity: sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==} + fs-extra@11.3.4: + resolution: {integrity: sha512-CTXd6rk/M3/ULNQj8FBqBWHYBVYybQ3VPBw0xGKFe3tuH7ytT6ACnvzpIQ3UZtB8yvUKC2cXn1a+x+5EVQLovA==} + engines: {node: '>=14.14'} + fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} @@ -876,6 +898,9 @@ packages: resolution: {integrity: sha512-CQ+bEO+Tva/qlmw24dCejulK5pMzVnUOFOijVogd3KQs07HnRIgp8TGipvCCRT06xeYEbpbgwaCxglFyiuIcmA==} engines: {node: '>=18'} + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + hasown@2.0.2: resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} engines: {node: '>= 0.4'} @@ -883,6 +908,9 @@ packages: hookable@5.5.3: resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==} + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + is-core-module@2.16.1: resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} engines: {node: '>= 0.4'} @@ -901,6 +929,9 @@ packages: resolution: {integrity: sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==} engines: {node: '>=18'} + isarray@1.0.0: + resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} + jiti@1.21.7: resolution: {integrity: sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==} hasBin: true @@ -915,6 +946,9 @@ packages: js-tokens@9.0.1: resolution: {integrity: sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==} + jsonfile@6.2.0: + resolution: {integrity: sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==} + knitwork@1.3.0: resolution: {integrity: sha512-4LqMNoONzR43B1W0ek0fhXMsDNW/zxa1NdFAVMY+k28pgZLovR4G3PB5MrpTxCy1QaZCqNoiaKPr5w5qZHfSNw==} @@ -980,6 +1014,9 @@ packages: engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true + node-int64@0.4.0: + resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} + node-releases@2.0.37: resolution: {integrity: sha512-1h5gKZCF+pO/o3Iqt5Jp7wc9rH3eJJ0+nh/CIoiRwjRxde/hAHyLPXYN4V3CqKAbiZPSeJFSWHmJsbkicta0Eg==} @@ -1200,6 +1237,12 @@ packages: resolution: {integrity: sha512-nODzvTiYVRGRqAOvE84Vk5JDPyyxsVk0/fbA/bq7RqlnhksGpset09XTxbpvLTIjoaF7K8Z8DG8yHtKGTPSYRw==} engines: {node: '>=20'} + process-nextick-args@2.0.1: + resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + + readable-stream@2.3.8: + resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} + resolve@1.22.11: resolution: {integrity: sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==} engines: {node: '>= 0.4'} @@ -1221,6 +1264,9 @@ packages: engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true + safe-buffer@5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + sax@1.6.0: resolution: {integrity: sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA==} engines: {node: '>=11.0.0'} @@ -1261,6 +1307,9 @@ packages: resolution: {integrity: sha512-6hJPQ8N0V0P3SNmP6h2J99RLuzrWz2gvT7VnK5tKvrNqJoyS9W4/Fb8mo31UiPvy00z7DQXkP2hnKBVav76thw==} engines: {node: '>=20'} + string_decoder@1.1.1: + resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + strip-ansi@7.2.0: resolution: {integrity: sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==} engines: {node: '>=12'} @@ -1329,10 +1378,17 @@ packages: resolution: {integrity: sha512-H/nlJ/h0ggGC+uRL3ovD+G0i4bqhvsDOpbDv7At5eFLlj2b41L8QliGbnl2H7SnDiYhENphh1tQFJZf+MyfLsQ==} engines: {node: '>=20.18.1'} + universalify@2.0.1: + resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} + engines: {node: '>= 10.0.0'} + untyped@2.0.0: resolution: {integrity: sha512-nwNCjxJTjNuLCgFr42fEak5OcLuB3ecca+9ksPFNvtfYSLpjf+iJqSIaSnIile6ZPbKYxI5k2AfXqeopGudK/g==} hasBin: true + unzipper@0.12.3: + resolution: {integrity: sha512-PZ8hTS+AqcGxsaQntl3IRBw65QrBI6lxzqDEL7IAo/XCEqRTKGfOX56Vea5TH9SZczRVxuzk1re04z/YjuYCJA==} + update-browserslist-db@1.2.3: resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==} hasBin: true @@ -1764,6 +1820,10 @@ snapshots: '@types/semver@7.7.1': {} + '@types/unzipper@0.10.11': + dependencies: + '@types/node': 22.19.15 + '@vitest/expect@3.2.4': dependencies: '@types/chai': 5.2.3 @@ -1823,6 +1883,8 @@ snapshots: baseline-browser-mapping@2.10.13: {} + bluebird@3.7.2: {} + boolbase@1.0.0: {} browserslist@4.28.2: @@ -1880,6 +1942,8 @@ snapshots: convert-source-map@2.0.0: {} + core-util-is@1.0.3: {} + css-declaration-sorter@7.3.1(postcss@8.5.8): dependencies: postcss: 8.5.8 @@ -1982,6 +2046,10 @@ snapshots: domelementtype: 2.3.0 domhandler: 5.0.3 + duplexer2@0.1.4: + dependencies: + readable-stream: 2.3.8 + electron-to-chromium@1.5.331: {} entities@4.5.0: {} @@ -2080,6 +2148,12 @@ snapshots: fraction.js@5.3.4: {} + fs-extra@11.3.4: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.2.0 + universalify: 2.0.1 + fsevents@2.3.3: optional: true @@ -2087,12 +2161,16 @@ snapshots: get-east-asian-width@1.5.0: {} + graceful-fs@4.2.11: {} + hasown@2.0.2: dependencies: function-bind: 1.1.2 hookable@5.5.3: {} + inherits@2.0.4: {} + is-core-module@2.16.1: dependencies: hasown: 2.0.2 @@ -2107,6 +2185,8 @@ snapshots: is-unicode-supported@2.1.0: {} + isarray@1.0.0: {} + jiti@1.21.7: {} jiti@2.6.1: {} @@ -2116,6 +2196,12 @@ snapshots: js-tokens@9.0.1: {} + jsonfile@6.2.0: + dependencies: + universalify: 2.0.1 + optionalDependencies: + graceful-fs: 4.2.11 + knitwork@1.3.0: {} lilconfig@3.1.3: {} @@ -2170,6 +2256,8 @@ snapshots: nanoid@3.3.11: {} + node-int64@0.4.0: {} + node-releases@2.0.37: {} nth-check@2.1.1: @@ -2382,6 +2470,18 @@ snapshots: pretty-bytes@7.1.0: {} + process-nextick-args@2.0.1: {} + + readable-stream@2.3.8: + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 1.0.0 + process-nextick-args: 2.0.1 + safe-buffer: 5.1.2 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + resolve@1.22.11: dependencies: is-core-module: 2.16.1 @@ -2435,6 +2535,8 @@ snapshots: '@rollup/rollup-win32-x64-msvc': 4.60.1 fsevents: 2.3.3 + safe-buffer@5.1.2: {} + sax@1.6.0: {} scule@1.3.0: {} @@ -2460,6 +2562,10 @@ snapshots: get-east-asian-width: 1.5.0 strip-ansi: 7.2.0 + string_decoder@1.1.1: + dependencies: + safe-buffer: 5.1.2 + strip-ansi@7.2.0: dependencies: ansi-regex: 6.2.2 @@ -2543,6 +2649,8 @@ snapshots: undici@7.24.7: {} + universalify@2.0.1: {} + untyped@2.0.0: dependencies: citty: 0.1.6 @@ -2551,6 +2659,14 @@ snapshots: knitwork: 1.3.0 scule: 1.3.0 + unzipper@0.12.3: + dependencies: + bluebird: 3.7.2 + duplexer2: 0.1.4 + fs-extra: 11.3.4 + graceful-fs: 4.2.11 + node-int64: 0.4.0 + update-browserslist-db@1.2.3(browserslist@4.28.2): dependencies: browserslist: 4.28.2 diff --git a/skillhub-cli/src/commands/download.ts b/skillhub-cli/src/commands/download.ts index 3b8d38ad3..8e963e6a5 100644 --- a/skillhub-cli/src/commands/download.ts +++ b/skillhub-cli/src/commands/download.ts @@ -46,7 +46,7 @@ export function registerDownload(program: Command) { spinner.fail(`Redirect response has no Location header`); process.exit(1); } - response = await request(location, { method: "GET" }); + response = await request(location as string, { method: "GET" }); } const { statusCode, body } = response; diff --git a/skillhub-cli/src/commands/install.ts b/skillhub-cli/src/commands/install.ts index 7d1415f82..840ecf572 100644 --- a/skillhub-cli/src/commands/install.ts +++ b/skillhub-cli/src/commands/install.ts @@ -2,7 +2,7 @@ import { Command } from "commander"; import { mkdtemp, rm, readFile } from "node:fs/promises"; import { tmpdir } from "node:os"; import { join } from "node:path"; -import { createWriteStream, existsSync, mkdirSync } from "node:fs"; +import { createWriteStream, createReadStream, existsSync, mkdirSync } from "node:fs"; import { ApiClient } from "../core/api-client.js"; import { loadConfig } from "../core/config.js"; import { readToken } from "../core/auth-token.js"; @@ -12,6 +12,7 @@ import { getAllAgents, detectInstalledAgents, getUniversalAgents, getNonUniversa import { parseSource, getCloneUrl } from "../core/source-parser.js"; import { addToLock } from "../core/skill-lock.js"; import { success, error, info, dim } from "../utils/logger.js"; +import unzipper from "unzipper"; import { multiSelect, sectionMultiSelect } from "../utils/prompts.js"; import { searchMultiselect, cancelSymbol } from "../utils/search-multiselect.js"; import { runInteractiveSearch, searchSkills } from "../core/interactive-search.js"; @@ -296,7 +297,7 @@ async function installFromRegistry(slug: string, opts: Record