byuckchon-frontend-cli 1.9.7 → 1.10.0

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.
Files changed (24) hide show
  1. package/README.md +39 -5
  2. package/package.json +8 -2
  3. package/src/commands/adopt.js +12 -3
  4. package/src/constants/versions.js +12 -46
  5. package/src/generators/createApp.js +13 -29
  6. package/src/generators/createBaseFiles.js +79 -311
  7. package/src/generators/createFolders.js +17 -1
  8. package/src/generators/createMonorepo.js +49 -236
  9. package/src/generators/createPackageJson.js +10 -11
  10. package/src/generators/scaffoldReviewAutomation.js +41 -31
  11. package/src/utils/ensureRequiredDependencies.js +35 -9
  12. package/src/utils/settingsAssets.js +27 -0
  13. package/templates/review-automation/github/workflows/eslint-convention-review.monorepo.yml +8 -6
  14. package/templates/review-automation/github/workflows/eslint-convention-review.single.yml +6 -6
  15. package/templates/review-automation/github/workflows/pr-check.monorepo.yml +51 -0
  16. package/templates/review-automation/github/workflows/pr-check.single.yml +47 -0
  17. package/templates/review-automation/tools/review.config.mjs +9 -0
  18. package/templates/review-automation/tools/eslint-rules/internal-blocking-conventions.js +0 -1242
  19. package/templates/review-automation/tools/eslint-rules/internal-plugin.cjs +0 -8
  20. package/templates/review-automation/tools/eslint-rules/internal-rdjson-formatter.js +0 -60
  21. package/templates/review-automation/tools/eslint-rules/internal-warning-conventions.js +0 -57
  22. package/templates/review-automation/tools/eslint-rules/package.json +0 -3
  23. package/templates/review-automation/tools/eslint-rules/review.config.mjs +0 -22
  24. package/templates/review-automation/tools/post-eslint-review-comments.cjs +0 -309
package/README.md CHANGED
@@ -225,19 +225,52 @@ https://www.figma.com/design/.../?node-id=12-34
225
225
  | **Components** 화 (♦ 마름모 아이콘) | 반복 UI 가 component 면 모델이 "이거 디자인 시스템 컴포넌트구나" 인식 → 코드에서도 재사용 컴포넌트를 만듭니다. |
226
226
  | frame 별로 **"Copy link to selection"** | 일반 share link 는 파일 전체. 특정 frame URL 을 받아야 AI 가 그것만 정확히 가져옵니다. |
227
227
 
228
+ ### 디자인 토큰 빌드
229
+
230
+ `bc init`으로 생성한 프로젝트에는 토큰 변환 설정이 함께 들어갑니다.
231
+
232
+ ```text
233
+ token.config.js # @byuckchon-frontend/settings/tokens 프리셋을 사용
234
+ src/tokens.json # 디자이너가 Figma(Tokens Studio)에서 export 한 파일을 여기에 덮어씀
235
+ src/tokens.css # 아래 명령으로 자동 생성 (직접 수정하지 않음)
236
+ ```
237
+
238
+ ```bash
239
+ npm run tokens:build
240
+ ```
241
+
242
+ color는 `@theme`의 `--color-*`로, typography는 `@utility text-*`로, motion 등 나머지 토큰은
243
+ `:root` 변수로 출력됩니다. duration 값이 단위 없는 숫자면 `ms`가 자동으로 붙고, settings에 없는
244
+ `--motion-*` 이름이 있으면 경고가 나옵니다. 변환 규칙은 `@byuckchon-frontend/settings`가
245
+ 관리하므로, 규칙이 바뀌면 패키지 버전만 올리면 기존 프로젝트에도 그대로 반영됩니다.
246
+
228
247
  ### ESLint Convention Review
229
248
 
230
249
  `bc init`과 `bc adopt`는 프로젝트 루트에 아래 파일을 준비합니다.
231
250
 
232
251
  ```text
233
- .github/workflows/eslint-convention-review.yml
234
- tools/eslint-rules/
235
- tools/post-eslint-review-comments.cjs
252
+ .github/workflows/eslint-convention-review.yml # 컨벤션 인라인 댓글
253
+ .github/workflows/pr-check.yml # lint / typecheck / build 통과 여부 (bc init 전용)
254
+ tools/review.config.mjs
236
255
  ```
237
256
 
257
+ `pr-check.yml` 은 `bc init` 으로 생성한 프로젝트에만 추가됩니다.
258
+ 스크립트 이름·대상 브랜치·패키지 매니저를 전제하기 때문에, 기존 프로젝트에
259
+ `bc adopt` 할 때는 추가하지 않습니다. 필요하면 위 파일을 참고해 직접 만드세요.
260
+
261
+ 워크플로 템플릿은 프로젝트 유형에 맞는 것만 복사됩니다.
262
+ (`<이름>.single.yml` / `<이름>.monorepo.yml` → `<이름>.yml`)
263
+ 단일 프로젝트는 npm, 모노레포는 pnpm + turbo 기준으로 만들어집니다.
264
+
265
+ 복사된 파일이므로 **프로젝트 소유**입니다. 대상 브랜치나 단계를 자유롭게 고치세요.
266
+ settings 를 올려도 이 파일은 바뀌지 않습니다.
267
+
238
268
  PR이 `dev` 브랜치를 대상으로 할 때, workflow가 기계적으로 판별 가능한 규칙을 검사하고
239
269
  변경 줄에 댓글을 게시합니다.
240
270
 
271
+ 컨벤션 규칙과 댓글 게시 스크립트는 `@byuckchon-frontend/settings`가 제공합니다.
272
+ 프로젝트에 규칙 사본을 두지 않으므로, 규칙이 바뀌면 settings 버전만 올리면 됩니다.
273
+
241
274
  | 구분 | 담당 | 결과 |
242
275
  | --- | --- | --- |
243
276
  | 일반 lint | 기존 ESLint 규칙 | Actions annotation |
@@ -317,8 +350,9 @@ bc chat --resume <session-id>
317
350
  - 기존 모노레포에 `bc adopt`를 적용할 때, 모노레포용 `review.config.mjs`는
318
351
  `packages/config-eslint/react.js` 구조를 전제로 합니다. ESLint 설정 구조가 다르면 해당 import를
319
352
  프로젝트에 맞게 조정해야 합니다.
320
- - AI Code Review typecheck·lint·build·test를 담당하는 PR Check workflow는 현재 자동 생성 대상이
321
- 아닙니다. 팀의 AI 제공자·테스트 전략에 맞춰 별도로 추가해야 합니다.
353
+ - AI Code Review workflow는 자동 생성 대상이 아닙니다. 팀의 AI 제공자에 맞춰 별도로 추가해야 합니다.
354
+ - PR Check workflow는 lint · typecheck · build 만 실행합니다. 테스트는 팀의 전략에 맞춰
355
+ 생성된 `pr-check.yml` 에 단계를 추가하세요.
322
356
 
323
357
  ## 제품 로드맵
324
358
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "byuckchon-frontend-cli",
3
- "version": "1.9.7",
3
+ "version": "1.10.0",
4
4
  "description": "Byuckchon Frontend Workbench — project starter + AI chat + codebase RAG + OpenAPI codegen",
5
5
  "type": "module",
6
6
  "engines": {
@@ -14,9 +14,12 @@
14
14
  "start": "node bin/index.js",
15
15
  "chat": "node bin/index.js chat",
16
16
  "init": "node bin/index.js init",
17
- "config": "node bin/index.js config show"
17
+ "config": "node bin/index.js config show",
18
+ "release": "changeset publish",
19
+ "version-packages": "changeset version"
18
20
  },
19
21
  "dependencies": {
22
+ "@byuckchon-frontend/settings": "^1.6.0",
20
23
  "@ai-sdk/anthropic": "^3.0.85",
21
24
  "@ai-sdk/openai": "^3.0.73",
22
25
  "ai": "^6.0.208",
@@ -65,5 +68,8 @@
65
68
  "repository": {
66
69
  "type": "git",
67
70
  "url": "git+https://github.com/RevolutionaryWarrior/byuckchon-frontend-cli.git"
71
+ },
72
+ "devDependencies": {
73
+ "@changesets/cli": "^2.29.8"
68
74
  }
69
75
  }
@@ -188,25 +188,34 @@ export async function adoptCommand(opts = {}) {
188
188
  projectRoot: reviewProjectRoot,
189
189
  projectType,
190
190
  overwrite: false,
191
+ // PR Check 는 스크립트 이름·브랜치·패키지 매니저를 전제하므로
192
+ // 기존 프로젝트에 말없이 깔면 CI 가 곧바로 실패한다. bc init 전용으로 둔다.
193
+ exclude: ['pr-check'],
191
194
  });
192
195
 
193
196
  if (reviewAutomation.workflows.length) {
194
197
  console.log(
195
198
  chalk.green(
196
- ` ✓ ESLint Convention Review 설정 추가: ${path.join(reviewProjectRoot, '.github', 'workflows')}`,
199
+ ` ✓ PR 워크플로 추가: ${path.join(reviewProjectRoot, '.github', 'workflows')}`,
200
+ ),
201
+ );
202
+ console.log(chalk.dim(` ${reviewAutomation.workflows.join(', ')}`));
203
+ console.log(
204
+ chalk.dim(
205
+ ' (PR Check 워크플로는 기존 프로젝트의 스크립트·브랜치 설정을 전제하므로 추가하지 않습니다)',
197
206
  ),
198
207
  );
199
208
  } else {
200
209
  console.log(
201
210
  chalk.dim(
202
- ` ESLint Convention Review 설정 유지: ${path.join(reviewProjectRoot, '.github', 'workflows')} (이미 존재)`,
211
+ ` PR 워크플로 유지: ${path.join(reviewProjectRoot, '.github', 'workflows')} (이미 존재)`,
203
212
  ),
204
213
  );
205
214
  }
206
215
  } catch (error) {
207
216
  console.log(
208
217
  chalk.yellow(
209
- ` ⚠ ESLint Convention Review 설정을 추가하지 못했습니다: ${error.message}`,
218
+ ` ⚠ PR 워크플로를 추가하지 못했습니다: ${error.message}`,
210
219
  ),
211
220
  );
212
221
  }
@@ -1,50 +1,16 @@
1
- export const versions = {
2
- // Core frameworks
3
- react: '^18.3.1',
4
- 'react-dom': '^18.3.1',
5
- 'next-react': '^19.2.1',
6
- 'next-react-dom': '^19.2.1',
7
- next: '15.1.9',
8
-
9
- // Build tool (React only)
10
- vite: '^6.0.0',
11
- '@vitejs/plugin-react': '^4.3.0',
12
- 'vite-plugin-svgr': '^4.3.0',
13
- '@svgr/webpack': '^8.1.0',
14
-
15
- // TypeScript
16
- typescript: '^5.7.0',
17
- '@types/react': '^18.3.3',
18
- '@types/react-dom': '^18.3.0',
19
- '@types/node': '^22.0.0',
1
+ /**
2
+ * 검증된 스택 버전 매트릭스.
3
+ *
4
+ * 본체는 @byuckchon-frontend/settings 가 관리한다.
5
+ * 여기서는 settings 자신의 버전만 얹는다 — 자기 자신의 버전을 자기가 들고 있으면
6
+ * 어긋나기 때문에, CLI 와 함께 설치된 settings 의 실제 버전을 읽어서 쓴다.
7
+ */
20
8
 
21
- // State & Data
22
- zustand: '^5.0.3',
23
- axios: '^1.8.4',
24
- 'react-router-dom': '^7.5.0',
25
- '@tanstack/react-query': '^5.74.4',
9
+ import { versions as shared } from '@byuckchon-frontend/settings/versions';
26
10
 
27
- // Styling
28
- tailwindcss: '^4.1.4',
29
- '@tailwindcss/vite': '^4.1.4',
30
- '@tailwindcss/postcss': '^4',
11
+ import { settingsVersion } from '../utils/settingsAssets.js';
31
12
 
32
- // Linting
33
- eslint: '^8.57.0',
34
- 'eslint-config-expo': '^8.0.0',
35
- 'eslint-config-next': '^15.0.0',
36
- 'eslint-import-resolver-typescript': '^3.6.0',
37
- 'eslint-plugin-import': '^2.29.0',
38
- 'eslint-plugin-react': '^7.34.0',
39
- 'eslint-plugin-react-hooks': '^4.6.0',
40
- '@typescript-eslint/eslint-plugin': '^7.0.0',
41
- '@typescript-eslint/parser': '^7.0.0',
42
-
43
- // Formatting
44
- prettier: '^3.3.0',
45
- 'prettier-plugin-tailwindcss': '^0.6.11',
46
- 'style-dictionary': '^5.4.0',
47
- zod: '^3.24.3',
48
- '@trivago/prettier-plugin-sort-imports': '^5.2.2',
49
- 'eslint-plugin-unused-imports': '^4.1.4',
13
+ export const versions = {
14
+ ...shared,
15
+ '@byuckchon-frontend/settings': `^${settingsVersion()}`,
50
16
  };
@@ -92,17 +92,18 @@ async function createAppPackageJson(appDir, config, scope) {
92
92
  }
93
93
  : {}),
94
94
  zod: versions.zod,
95
+ clsx: versions.clsx,
96
+ 'tailwind-merge': versions['tailwind-merge'],
95
97
  },
96
98
  devDependencies: {
97
99
  [`@${scope}/config-eslint`]: 'workspace:*',
98
100
  [`@${scope}/config-typescript`]: 'workspace:*',
101
+ // global.d.ts, App.css(motion), token.config.js 가 직접 참조한다.
102
+ '@byuckchon-frontend/settings': versions['@byuckchon-frontend/settings'],
99
103
  '@types/react': versions['@types/react'],
100
104
  '@types/react-dom': versions['@types/react-dom'],
101
105
  '@types/node': versions['@types/node'],
102
- // 모노레포 앱은 flat config(@scope/config-eslint) 를 쓰므로 ESLint 9 필요.
103
- // (단일 프로젝트의 eslintrc + eslint 8 과 별개)
104
- eslint: '^9.18.0',
105
- 'eslint-plugin-unused-imports': versions['eslint-plugin-unused-imports'],
106
+ eslint: versions.eslint,
106
107
  prettier: versions.prettier,
107
108
  'prettier-plugin-tailwindcss': versions['prettier-plugin-tailwindcss'],
108
109
  'style-dictionary': versions['style-dictionary'],
@@ -135,32 +136,18 @@ async function applyMonorepoConventions(appDir, config, scope) {
135
136
  const isReact = config.framework === 'react';
136
137
 
137
138
  // 루트에서 관리하는 설정들은 앱 레벨에서 제거.
138
- await rm(path.join(appDir, '.eslintrc.cjs'));
139
- await rm(path.join(appDir, '.prettierrc'));
139
+ await rm(path.join(appDir, 'eslint.config.js'));
140
+ await rm(path.join(appDir, 'eslint.config.mjs'));
141
+ await rm(path.join(appDir, 'prettier.config.js'));
140
142
  await rm(path.join(appDir, '.gitignore'));
141
143
  await rm(path.join(appDir, '.vscode'));
142
144
 
143
- // 공유 ESLint 프리셋을 extends 하는 flat config.
145
+ // 공유 ESLint 프리셋을 그대로 쓴다.
146
+ // 규칙 본체는 @byuckchon-frontend/settings 가 관리하고,
147
+ // 이 모노레포 전용 예외는 packages/config-eslint 에서 얹는다.
144
148
  await write(
145
149
  path.join(appDir, 'eslint.config.mjs'),
146
- `import { reactConfig } from '@${scope}/config-eslint/react';
147
- import unusedImports from 'eslint-plugin-unused-imports';
148
-
149
- export default [
150
- ...reactConfig,
151
- {
152
- plugins: { 'unused-imports': unusedImports },
153
- rules: {
154
- 'no-unused-vars': 'off',
155
- '@typescript-eslint/no-unused-vars': 'off',
156
- 'unused-imports/no-unused-imports': 'error',
157
- 'unused-imports/no-unused-vars': [
158
- 'warn',
159
- { vars: 'all', varsIgnorePattern: '^_', args: 'after-used', argsIgnorePattern: '^_' },
160
- ],
161
- },
162
- },
163
- ];
150
+ `export { default } from '@${scope}/config-eslint/${isReact ? 'react' : 'next'}';
164
151
  `
165
152
  );
166
153
 
@@ -174,11 +161,8 @@ export default [
174
161
  {
175
162
  extends: `@${scope}/config-typescript/react.json`,
176
163
  compilerOptions: {
164
+ // 공통 옵션은 config-typescript → settings 프리셋에 있다.
177
165
  tsBuildInfoFile: './node_modules/.tmp/tsconfig.tsbuildinfo',
178
- noUnusedLocals: true,
179
- noUnusedParameters: true,
180
- noUncheckedSideEffectImports: true,
181
- moduleDetection: 'force',
182
166
  baseUrl: '.',
183
167
  paths: {
184
168
  '@/*': ['src/*'],