- update only touches the recorded project root; project installs do not follow symlinks or junctions; repeated --force rotates .orig backups; uninstall never deletes outside the recorded root - run npm/npx without a shell on Windows and pin optional tool versions - skip the update check in CI and non-interactive output - lint: cross-document section pointers, preflight row ids, gate rule numbers, per-document size budgets, gate copy equality - eval: scenarios S19-S21, route and read-cost rejudging, interpretation card judging, temp-dir previews and table-form cards no longer fail
43 lines
1.9 KiB
JavaScript
43 lines
1.9 KiB
JavaScript
// publish 직전 최종 점검 — 스킬이 빠진 채로 배포되는 사고를 막는다.
|
|
import fs from "node:fs/promises";
|
|
import path from "node:path";
|
|
import { fileURLToPath } from "node:url";
|
|
import { isAllowedSkillFile } from "./skill-allowlist.mjs";
|
|
|
|
const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
|
const must = ["dist/index.js", "dist/skill/SKILL.md", "dist/skill/.designpaca_version"];
|
|
|
|
const missing = [];
|
|
for (const rel of must) {
|
|
try {
|
|
await fs.access(path.join(root, rel));
|
|
} catch {
|
|
missing.push(rel);
|
|
}
|
|
}
|
|
if (missing.length) {
|
|
console.error(`배포물에 빠진 파일:\n${missing.map((m) => ` - ${m}`).join("\n")}`);
|
|
console.error("pnpm build 를 먼저 실행해라.");
|
|
process.exit(1);
|
|
}
|
|
|
|
const pkg = JSON.parse(await fs.readFile(path.join(root, "package.json"), "utf8"));
|
|
const stamp = (await fs.readFile(path.join(root, "dist/skill/.designpaca_version"), "utf8")).trim();
|
|
if (stamp !== pkg.version) {
|
|
console.error(`버전 불일치: package.json=${pkg.version} / 스킬 스탬프=${stamp}`);
|
|
process.exit(1);
|
|
}
|
|
// 허용 목록 밖 파일(테스트·스크래치·.env 등)이 설치물에 섞였으면 배포하지 않는다
|
|
const skillDir = path.join(root, "dist/skill");
|
|
const unexpected = [];
|
|
for (const e of await fs.readdir(skillDir, { recursive: true, withFileTypes: true })) {
|
|
if (!e.isFile() && !e.isSymbolicLink()) continue;
|
|
const rel = path.relative(skillDir, path.join(e.parentPath ?? e.path, e.name)).split(path.sep).join("/");
|
|
if (e.isSymbolicLink() || !isAllowedSkillFile(rel)) unexpected.push(rel);
|
|
}
|
|
if (unexpected.length) {
|
|
console.error(`스킬 설치물에 허용 목록 밖 파일:\n${unexpected.map((m) => ` - ${m}`).join("\n")}`);
|
|
console.error("scripts/skill-allowlist.mjs 를 확인하고 pnpm build 를 다시 실행해라.");
|
|
process.exit(1);
|
|
}
|
|
console.log(`배포 점검 통과 (v${pkg.version})`);
|