gencow 0.1.77 → 0.1.78

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gencow",
3
- "version": "0.1.77",
3
+ "version": "0.1.78",
4
4
  "description": "Gencow — AI Backend Engine",
5
5
  "type": "module",
6
6
  "bin": {
@@ -17,7 +17,7 @@
17
17
  ],
18
18
  "scripts": {
19
19
  "build": "node scripts/bundle-server.mjs",
20
- "prepublishOnly": "npm run build"
20
+ "prepublishOnly": "npm run build && node scripts/pre-publish-check.mjs"
21
21
  },
22
22
  "dependencies": {
23
23
  "@modelcontextprotocol/sdk": "^1.27.1",
@@ -0,0 +1,118 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * pre-publish-check.mjs — npm publish 전 패키지 무결성 검증
4
+ *
5
+ * gencow.mjs의 모든 import 경로가 tarball에 포함되었는지 자동 검증.
6
+ * package.json의 prepublishOnly에서 빌드 후 실행됨.
7
+ *
8
+ * @see docs/analysis/analysis-npm-files-gap.md
9
+ */
10
+ import { execSync } from "child_process";
11
+ import { readFileSync, existsSync } from "fs";
12
+ import { resolve, dirname, relative, join } from "path";
13
+ import { fileURLToPath } from "url";
14
+
15
+ const __dirname = dirname(fileURLToPath(import.meta.url));
16
+ const CLI_ROOT = resolve(__dirname, "..");
17
+
18
+ // ── 1. 필수 파일 목록 (반드시 tarball에 포함되어야 함) ─────
19
+ const REQUIRED_FILES = [
20
+ "bin/gencow.mjs",
21
+ "bin/gencow-mcp.mjs",
22
+ "lib/readme-codegen.mjs",
23
+ "lib/deploy-auditor.mjs",
24
+ "server/index.js",
25
+ "core/index.js",
26
+ ];
27
+
28
+ // ── 2. gencow.mjs에서 import 경로 자동 추출 ───────────────
29
+ function extractImports(entryFile) {
30
+ const content = readFileSync(entryFile, "utf8");
31
+ const paths = new Set();
32
+
33
+ // 정적 import: import { ... } from "../lib/xxx.mjs"
34
+ const staticImports = content.matchAll(/from\s+["'](\.\.\/.+?)["']/g);
35
+ for (const m of staticImports) paths.add(m[1]);
36
+
37
+ // 동적 import: await import("../lib/xxx.mjs")
38
+ const dynamicImports = content.matchAll(/import\(["'](\.\.\/.+?)["']\)/g);
39
+ for (const m of dynamicImports) paths.add(m[1]);
40
+
41
+ // import 경로 → package 내부 상대 경로로 변환
42
+ // "../lib/foo.mjs" (from bin/gencow.mjs) → "lib/foo.mjs"
43
+ const entryDir = dirname(relative(CLI_ROOT, entryFile));
44
+ return [...paths].map(p => {
45
+ const resolved = join(entryDir, p);
46
+ return resolved.startsWith("/") ? resolved.slice(1) : resolved;
47
+ });
48
+ }
49
+
50
+ // ── 3. npm pack --dry-run 실행 → tarball 파일 목록 추출 ────
51
+ function getTarballFiles() {
52
+ const output = execSync("npm pack --dry-run --json 2>/dev/null", {
53
+ cwd: CLI_ROOT,
54
+ encoding: "utf8",
55
+ });
56
+ const parsed = JSON.parse(output);
57
+ // npm pack --json returns [{ files: [{ path: "..." }] }]
58
+ return parsed[0].files.map(f => f.path);
59
+ }
60
+
61
+ // ── 4. 검증 실행 ──────────────────────────────────────────
62
+ function main() {
63
+ console.log("\n📦 Pre-publish package integrity check\n");
64
+
65
+ let hasError = false;
66
+
67
+ // 4-1. tarball 파일 목록 가져오기
68
+ let tarballFiles;
69
+ try {
70
+ tarballFiles = getTarballFiles();
71
+ } catch (e) {
72
+ console.error("❌ npm pack --dry-run 실행 실패:", e.message);
73
+ process.exit(1);
74
+ }
75
+
76
+ const tarballSet = new Set(tarballFiles);
77
+
78
+ // 4-2. 필수 파일 존재 확인
79
+ console.log(" ── 필수 파일 확인 ──────────────────────");
80
+ for (const file of REQUIRED_FILES) {
81
+ if (tarballSet.has(file)) {
82
+ console.log(` ✅ ${file}`);
83
+ } else {
84
+ console.error(` ❌ ${file} — tarball에 없음!`);
85
+ hasError = true;
86
+ }
87
+ }
88
+
89
+ // 4-3. gencow.mjs import 경로 확인
90
+ const entryFile = resolve(CLI_ROOT, "bin/gencow.mjs");
91
+ if (existsSync(entryFile)) {
92
+ const importPaths = extractImports(entryFile);
93
+ if (importPaths.length > 0) {
94
+ console.log("\n ── import 경로 확인 ────────────────────");
95
+ for (const imp of importPaths) {
96
+ if (tarballSet.has(imp)) {
97
+ console.log(` ✅ ${imp}`);
98
+ } else {
99
+ console.error(` ❌ ${imp} — tarball에 없음! (gencow.mjs에서 import)`);
100
+ hasError = true;
101
+ }
102
+ }
103
+ }
104
+ }
105
+
106
+ // 4-4. 결과
107
+ console.log("");
108
+ if (hasError) {
109
+ console.error("❌ 패키지 무결성 검증 실패!");
110
+ console.error(" → package.json 'files' 배열에 누락된 디렉토리를 추가하세요.");
111
+ console.error(" → 참조: docs/analysis/analysis-npm-files-gap.md\n");
112
+ process.exit(1);
113
+ }
114
+
115
+ console.log(`✅ 패키지 무결성 검증 통과 (${tarballFiles.length}개 파일)\n`);
116
+ }
117
+
118
+ main();