Files
HMDesign/scripts/create-ai-reference-package.mjs
T

116 lines
6.4 KiB
JavaScript

import fs from 'node:fs';
import path from 'node:path';
import { execFileSync } from 'node:child_process';
const root = process.cwd();
const out = path.join(root, 'HMDesignSystem-AI-Reference-Test');
const zip = path.join(root, 'HMDesignSystem-AI-Reference-Test.zip');
fs.rmSync(out, { recursive: true, force: true });
fs.rmSync(zip, { force: true });
fs.mkdirSync(out, { recursive: true });
const copy = (from, to, options = {}) => {
const src = path.join(root, from);
if (!fs.existsSync(src)) return false;
const dest = path.join(out, to);
fs.mkdirSync(path.dirname(dest), { recursive: true });
fs.cpSync(src, dest, { recursive: true, force: true, ...options });
return true;
};
// Preserve repository-relative paths for source references and imports.
copy('packages/ui/src', 'source/packages/ui/src');
copy('packages/ui/package.json', 'source/packages/ui/package.json');
copy('packages/ui/tsconfig.json', 'source/packages/ui/tsconfig.json');
copy('packages/ui/tsconfig.build.json', 'source/packages/ui/tsconfig.build.json');
copy('packages/ui/components.json', 'source/packages/ui/components.json');
copy('packages/center-graphic/src', 'source/packages/center-graphic/src');
copy('packages/center-graphic/package.json', 'source/packages/center-graphic/package.json');
copy('packages/center-graphic/tsconfig.json', 'source/packages/center-graphic/tsconfig.json');
copy('packages/center-graphic/tsconfig.build.json', 'source/packages/center-graphic/tsconfig.build.json');
copy('.storybook', 'storybook/config');
copy('src', 'storybook/source');
copy('storybook-static', 'storybook/static');
copy('dist', 'packages/app-build');
copy('dist-dashboard', 'packages/dashboard-export-build');
copy('packages/ui/dist', 'packages/ui-dist');
copy('packages/center-graphic/dist', 'packages/center-graphic-dist');
copy('theme-dist', 'theme/generated');
copy('themes', 'theme/source');
copy('packages/ui/src/theme.css', 'theme/source/packages-ui-theme.css');
copy('packages/ui/src/theme', 'theme/source/packages-ui-theme');
copy('docs', 'docs/source');
copy('AGENTS.md', 'docs/AGENTS.md');
copy('CLAUDE.md', 'docs/CLAUDE.md');
copy('README.md', 'docs/README.md');
copy('package.json', 'docs/root-package.json');
copy('package-lock.json', 'docs/package-lock.json');
copy('src/exports', 'examples/react-and-html/src/exports');
copy('src/exports/dashboard', 'examples/react-and-html/src/exports/dashboard');
copy('index.html', 'examples/react-and-html/index.html');
copy('vite.dashboard-export.config.ts', 'examples/react-and-html/vite.dashboard-export.config.ts');
copy('scripts/finalize-dashboard-export.mjs', 'examples/react-and-html/finalize-dashboard-export.mjs');
copy('public/fonts', 'assets/fonts');
copy('packages/center-graphic/src/assets', 'assets/center-graphic');
const files = (dir) => fs.existsSync(dir) ? fs.readdirSync(dir, { recursive: true }).filter((p) => fs.statSync(path.join(dir, p)).isFile()).length : 0;
const countFiles = (rel, suffix) => {
const dir = path.join(root, rel);
if (!fs.existsSync(dir)) return 0;
return fs.readdirSync(dir, { recursive: true }).filter((p) => String(p).endsWith(suffix)).length;
};
const publicComponentFiles = countFiles('packages/ui/src/components', '.tsx');
const patternFiles = countFiles('packages/ui/src/patterns', '.tsx');
const storyFiles = ['.stories.tsx', '.stories.ts', '.stories.jsx', '.stories.js'].reduce((n, s) => n + countFiles('src', s), 0);
const generatedAt = new Date().toISOString();
const startHere = `# HM Design System AI Reference
이 ZIP은 빌드 패키지만이 아니라 HM Design System의 실제 구현·Storybook·Theme·문서를 함께 참조하기 위한 테스트 배포본입니다.
## AI 참조 순서
1. \`docs/AGENTS.md\`와 \`docs/README.md\`를 읽습니다.
2. \`docs/source/components\`, \`docs/source/patterns\`, \`docs/source/guidelines\`에서 사용 규칙을 확인합니다.
3. \`source/packages/ui/src\`와 \`source/packages/center-graphic/src\`의 실제 TSX 구현을 재사용합니다.
4. \`storybook/source\`의 Story에서 상태·조합·레이아웃을 확인합니다.
5. \`theme/source\` 및 \`theme/generated\`의 Token/CSS Custom Properties를 사용합니다.
6. \`packages/ui-dist\`와 declarations는 소비자 Export 형태를 확인할 때 사용합니다.
임의의 색상·spacing·radius·Typography 값을 추가하거나 디자인을 재해석하지 않습니다. 신규 화면은 기존 공개 Component/Pattern과 Theme 계약을 우선 재사용합니다.
## 구조
- \`source/\`: 원본 공개 패키지 구현 및 내부 의존 코드
- \`storybook/\`: Storybook 설정, Story/Pattern/Foundation 소스, 정적 Storybook
- \`packages/\`: 기존 빌드 산출물 및 TypeScript declarations
- \`theme/\`: Token 원본, Generated CSS, Runtime Theme 자료
- \`docs/\`: 원본 사용 규칙, AI 공통 가이드, 컴포넌트·패턴 문서
- \`examples/\`: React/HTML export 관련 예제 및 계약
- \`assets/\`: Font와 Center Graphic asset
## 재현 범위
React는 기존 공개 패키지를 직접 import하는 방식을 우선합니다. HTML은 \`examples/react-and-html\`의 기존 export와 Runtime 계약을 먼저 확인합니다. 이 배포본 자체에서 무료 AI에 의한 신규 화면 생성이나 브라우저 시각 검증은 수행하지 않았습니다.
`;
fs.writeFileSync(path.join(out, 'AI_START_HERE.md'), startHere, 'utf8');
const manifest = {
package: 'HMDesignSystem-AI-Reference-Test', generatedAt,
source: { publicComponentSourceFiles: publicComponentFiles, centerGraphicSourceFiles: files(path.join(out, 'source/packages/center-graphic/src')) },
storybook: { storyFiles, sourceFiles: files(path.join(out, 'storybook/source')), staticIncluded: fs.existsSync(path.join(out, 'storybook/static')) },
patterns: { patternSourceFiles: patternFiles },
theme: { sourceIncluded: fs.existsSync(path.join(out, 'theme/source')), generatedIncluded: fs.existsSync(path.join(out, 'theme/generated')) },
assets: { fontFiles: files(path.join(out, 'assets/fonts')), centerGraphicAssetFiles: files(path.join(out, 'assets/center-graphic')) },
verification: { aiReproduction: 'NOT_RUN', browserVisualVerification: 'NOT_RUN', sourceMutation: 'NOT_RUN (packaging-only)' }
};
fs.writeFileSync(path.join(out, 'MANIFEST.json'), JSON.stringify(manifest, null, 2) + '\n', 'utf8');
execFileSync('tar', ['-a', '-c', '-f', zip, '-C', root, path.basename(out)], { stdio: 'inherit' });
console.log(JSON.stringify({ out, zip, manifest }, null, 2));