From aeec2f86bdb71c0ac0680beff626e74e036c1eb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=BE=B7=E5=AE=87?= Date: Tue, 6 Oct 2026 15:25:31 +0800 Subject: [PATCH] =?UTF-8?q?skill=EF=BC=9A=E7=9B=AE=E5=BD=95=E5=81=87?= =?UTF-8?q?=E8=AE=BE=E6=94=B9=E6=88=90=20game/=EF=BC=9Bpack.mjs=20?= =?UTF-8?q?=E5=8E=BB=E6=8E=89=20--zip=20=E4=B8=8E=E4=BB=A3=E8=B7=91?= =?UTF-8?q?=E7=9A=84=E6=A0=A1=E9=AA=8C=EF=BC=8C=E4=BF=9D=E7=95=99=20--vite?= =?UTF-8?q?-built-dir?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - `SKILL.md` 的 vite 项目目录假设写的是 `games/`,实际是 `game/`;默认参数都按「cwd 就是 vite 项目根」给,非标准目录结构用 `--vite-built-dir` 指全路径; - `pack.mjs` 删掉打包后调用 `validate.mjs` 的那一步,连带 `--skip-validate` / `--no-strict`:校验归 `validate.mjs` 与项目构建脚本,pack 只管整理产物、写 zip、按体积门禁审计; - `pack.mjs` 删掉 `--zip` 与它专用的 `readPackageName()`(默认文件名):落点统一由 `--zip-out` 指定;`--vite-built-dir` 保留; - 参数解析改成「只认 `--vite-built-dir` / `--zip-out`」:不认识的参数、缺值、缺 `--zip-out` 都当场打印用法并退出 2,打包本身失败仍退出 1,不再有静默退回默认目录的路径; - `SKILL.md` 新增「脚本参数」一节,列出三个脚本各自的参数; - `pack.mjs` 的用例改成「CLI 拒绝不认识的参数,且不写出 zip」; - 同步 manifest 指纹(version=2026-08-26.49)。 --- .../resources/agc-skills/manifest.json | 4 +- .../vite-export-xhs-minitool/SKILL.md | 2 +- .../scripts/.pack.test.mjs | 12 +-- .../vite-export-xhs-minitool/scripts/pack.mjs | 99 ++++++++----------- 4 files changed, 50 insertions(+), 67 deletions(-) diff --git a/apps/ai-game-creator-shell/src-tauri/resources/agc-skills/manifest.json b/apps/ai-game-creator-shell/src-tauri/resources/agc-skills/manifest.json index 3bb654b3f..83f28936b 100644 --- a/apps/ai-game-creator-shell/src-tauri/resources/agc-skills/manifest.json +++ b/apps/ai-game-creator-shell/src-tauri/resources/agc-skills/manifest.json @@ -1,6 +1,6 @@ { "schemaVersion": "agc-skill-pack.v1", - "version": "2026-08-26.46", + "version": "2026-08-26.49", "skills": [ { "name": "agc-unity-editor", @@ -204,7 +204,7 @@ "scripts/validate.mjs", "scripts/vite.config.xhs-minitool.mjs" ], - "sha256": "e80b5c6a3f9a1619af1f789a74ea6e7577e58a4efa208d1d7b29e869f40b3725" + "sha256": "ad78485332009c5c72675a00ba525836b1ed94db34616256052ef9b30ca2d869" } ] } diff --git a/apps/ai-game-creator-shell/src-tauri/resources/agc-skills/vite-export-xhs-minitool/SKILL.md b/apps/ai-game-creator-shell/src-tauri/resources/agc-skills/vite-export-xhs-minitool/SKILL.md index 5382393c3..9320bd375 100644 --- a/apps/ai-game-creator-shell/src-tauri/resources/agc-skills/vite-export-xhs-minitool/SKILL.md +++ b/apps/ai-game-creator-shell/src-tauri/resources/agc-skills/vite-export-xhs-minitool/SKILL.md @@ -28,7 +28,7 @@ metadata: |---|---| | `scripts/vite.config.xhs-minitool.mjs` | `build.outDir`(与打包时的 `--vite-built-dir` 必须是同一个目录); `defineMinitoolConfig(overrides)`(项目已有 vite.config 时用它合并) | | `scripts/validate.mjs` | `[project]`、`--json`、`--strict` | -| `scripts/pack.mjs` | `--vite-built-dir `、`--zip-out `、`--zip `、`--skip-validate`、`--no-strict` | +| `scripts/pack.mjs` | `--vite-built-dir `、`--zip-out ` | # 一些情况: * 打包大小限制, 需要精简游戏内容/删减资源/压缩素材 请和用户讨论 diff --git a/apps/ai-game-creator-shell/src-tauri/resources/agc-skills/vite-export-xhs-minitool/scripts/.pack.test.mjs b/apps/ai-game-creator-shell/src-tauri/resources/agc-skills/vite-export-xhs-minitool/scripts/.pack.test.mjs index 2c41324de..83f5596c5 100644 --- a/apps/ai-game-creator-shell/src-tauri/resources/agc-skills/vite-export-xhs-minitool/scripts/.pack.test.mjs +++ b/apps/ai-game-creator-shell/src-tauri/resources/agc-skills/vite-export-xhs-minitool/scripts/.pack.test.mjs @@ -61,7 +61,6 @@ test('存在不支持文件时打包整体失败,且不删除任何文件', () cwd: BASE, viteBuiltDir: 'no-delete', zipOut: 'no-delete-out/xhs-minitool.zip', - skipValidate: true, }), /没有删除任何文件/, ); @@ -77,19 +76,20 @@ test('干净产物目录仍能正常打包', () => { cwd: BASE, viteBuiltDir: 'clean', zipOut, - skipValidate: true, }); assert.equal(code, 0); assert.ok(existsSync(zipOut), 'zip 未生成'); }); -test('CLI 拒绝旧名 --out-dir,不再静默退回默认目录', () => { +test('CLI 拒绝不认识的参数,不写出 zip', () => { const dir = writeBuiltDir('cli'); + const zipOut = join(BASE, 'cli-out.zip'); const result = spawnSync( process.execPath, - [PACK, '--vite-built-dir', dir, '--out-dir', dir, '--skip-validate'], + [PACK, '--vite-built-dir', dir, '--out-dir', dir, '--zip-out', zipOut], { cwd: BASE, encoding: 'utf8' }, ); - assert.equal(result.status, 1); - assert.match(result.stderr, /--vite-built-dir/); + assert.equal(result.status, 2); + assert.match(result.stderr, /不认识的参数/); + assert.equal(existsSync(zipOut), false, '参数被拒时不应写出 zip'); }); diff --git a/apps/ai-game-creator-shell/src-tauri/resources/agc-skills/vite-export-xhs-minitool/scripts/pack.mjs b/apps/ai-game-creator-shell/src-tauri/resources/agc-skills/vite-export-xhs-minitool/scripts/pack.mjs index 42c566927..e52528f90 100644 --- a/apps/ai-game-creator-shell/src-tauri/resources/agc-skills/vite-export-xhs-minitool/scripts/pack.mjs +++ b/apps/ai-game-creator-shell/src-tauri/resources/agc-skills/vite-export-xhs-minitool/scripts/pack.mjs @@ -5,7 +5,6 @@ * - 校正 HTML 资源为相对路径、去掉 module 痕迹 * - 将脚本移到 body 末尾并保持顺序 * - 用 node:zlib 写出 zip(index.html 在 zip 根目录、不多套一层目录) - * - 再跑一遍静态校验 */ import { copyFileSync, @@ -22,7 +21,7 @@ import { basename, dirname, join, relative, resolve, sep } from 'node:path'; import { fileURLToPath, pathToFileURL } from 'node:url'; import { deflateRawSync } from 'node:zlib'; -import { findUnsupportedFiles, runCli } from './validate.mjs'; +import { findUnsupportedFiles } from './validate.mjs'; const MIB = 1024 * 1024; const ZIP_HARD_LIMIT = 10 * MIB; @@ -31,17 +30,14 @@ const ZIP_RECOMMENDED = 2 * MIB; const FORBIDDEN_ENTRY = /(^|\/)(?:node_modules|\.git)\/|(^|\/)\.DS_Store$|\.map$|(^|\/)(?:vite|webpack|rollup)\.config\.[^/]+$/i; -const USAGE = `用法:node pack.mjs [--vite-built-dir ] [--zip ] [--zip-out ] [--skip-validate] [--no-strict] +const USAGE = `用法:node pack.mjs [--vite-built-dir ] --zip-out 把 vite 构建产物整理成符合小红书规范、根目录带 index.html 的 zip。 --vite-built-dir vite 的构建输出目录,必须与 vite config 的 build.outDir 一致。默认 dist-xhs-minitool。 该目录出现白名单之外的文件类型时直接报错退出并列出文件,不会删除任何文件。 ---zip 只给文件名时用:写到当前工作目录下。 ---zip-out 需要指定落点(例如 AGC 导出面板要求的 .export/xhs-minitool.zip)时用: - 相对路径按当前工作目录解析,父目录不存在会自动建。 ---skip-validate 写完 zip 后不再跑一遍静态校验。 ---no-strict 校验时不把 WARNING 当失败。`; +--zip-out 落点(例如 AGC 导出面板要求的 .export/xhs-minitool.zip): + 相对路径按当前工作目录解析,父目录不存在会自动建。`; /** * 打包前预检:产物目录里出现小红书白名单之外的文件类型时整体失败,列出路径但**不改磁盘**。 @@ -272,38 +268,22 @@ function makeZip(viteBuiltDir, zipPath) { console.log(`zip 已生成:${zipPath}(${entries.length} 个条目,${(size / MIB).toFixed(2)} MiB)`); } -function readPackageName(cwd) { - const pkgPath = join(cwd, 'package.json'); - if (!existsSync(pkgPath)) return 'minitool'; - try { - const pkg = JSON.parse(readFileSync(pkgPath, 'utf8')); - return pkg.name || 'minitool'; - } catch { - return 'minitool'; - } -} - /** * @param {{ * cwd?: string, * viteBuiltDir?: string, - * zipName?: string, - * zipOut?: string, + * zipOut: string, * publicDir?: string, - * skipValidate?: boolean, - * strict?: boolean, - * }} [options] + * }} options */ export function packMinitool(options = {}) { + if (!options.zipOut) { + throw new Error('缺少 --zip-out:打包要给出 zip 的落点'); + } const cwd = resolve(options.cwd || process.cwd()); const viteBuiltDir = resolve(cwd, options.viteBuiltDir || 'dist-xhs-minitool'); - const zipName = options.zipName || `${readPackageName(cwd)}-xhs-tool.zip`; - // `zipOut` 优先:调用方(如 .export/ 下的项目拷贝)要的是确定的落点,而不是"当前目录下叫什么名字"。 - const zipPath = options.zipOut - ? resolve(cwd, options.zipOut) - : resolve(cwd, zipName); + const zipPath = resolve(cwd, options.zipOut); const publicDir = resolve(cwd, options.publicDir || 'public'); - const strict = options.strict !== false; if (!existsSync(viteBuiltDir)) { throw new Error(`缺少 vite 构建产物目录 ${viteBuiltDir}`); @@ -328,16 +308,7 @@ export function packMinitool(options = {}) { makeZip(viteBuiltDir, zipPath); console.log(`\n小红书小工具包已整理:${viteBuiltDir}`); - - if (options.skipValidate) return 0; - - const args = [viteBuiltDir]; - if (strict) args.push('--strict'); - const code = runCli(args); - if (code !== 0) { - process.exitCode = code; - } - return code; + return 0; } export default packMinitool; @@ -359,33 +330,45 @@ function isMainModule() { if (isMainModule()) { const raw = process.argv.slice(2); - const flags = new Set(raw.filter((arg) => arg.startsWith('-'))); - if (flags.has('--help') || flags.has('-h')) { + if (raw.includes('--help') || raw.includes('-h')) { console.log(USAGE); process.exit(0); } - // 旧名不能静默退回默认目录:否则适配脚本里的 --out-dir 会被忽略,产物落到别处还查不出来。 - if (flags.has('--out-dir')) { - console.error('--out-dir 已更名为 --vite-built-dir,请改用新名字(`node pack.mjs --help`)。'); - process.exit(1); - } - - const getFlagValue = (name) => { + // 取走一个参数和它的值;剩下的非空参数说明调用方传了本脚本不认的东西。 + const takeFlag = (name) => { const idx = raw.indexOf(name); - return idx === -1 ? undefined : raw[idx + 1]; + if (idx === -1) return undefined; + const value = raw[idx + 1]; + if (!value || value.startsWith('-')) { + throw new Error(`${name} 后面要跟一个值`); + } + raw.splice(idx, 2); + return value; }; + let viteBuiltDir; + let zipOut; try { - const code = packMinitool({ - viteBuiltDir: getFlagValue('--vite-built-dir'), - zipName: getFlagValue('--zip'), - zipOut: getFlagValue('--zip-out'), - skipValidate: flags.has('--skip-validate'), - strict: !flags.has('--no-strict'), - }); - process.exit(code ?? 0); + viteBuiltDir = takeFlag('--vite-built-dir'); + zipOut = takeFlag('--zip-out'); + // 不认识的参数当场拒绝:否则调用方以为它生效了,产物落到别处还查不出来。 + if (raw.length > 0) { + throw new Error(`不认识的参数:${raw.join(' ')}`); + } + if (!zipOut) { + throw new Error('缺少 --zip-out'); + } + } catch (err) { + console.error(err instanceof Error ? err.message : err); + console.error(USAGE); + process.exit(2); + } + + try { + packMinitool({ viteBuiltDir, zipOut }); + process.exit(0); } catch (err) { console.error(err instanceof Error ? err.message : err); process.exit(1);