@kood/claude-code 0.1.7 → 0.1.9
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/dist/index.js +118 -3
- package/package.json +8 -2
- package/templates/hono/CLAUDE.md +53 -326
- package/templates/hono/docs/architecture/architecture.md +93 -747
- package/templates/hono/docs/deployment/cloudflare.md +59 -513
- package/templates/hono/docs/deployment/docker.md +41 -356
- package/templates/hono/docs/deployment/index.md +49 -190
- package/templates/hono/docs/deployment/railway.md +36 -306
- package/templates/hono/docs/deployment/vercel.md +49 -434
- package/templates/hono/docs/library/ai-sdk/index.md +53 -290
- package/templates/hono/docs/library/ai-sdk/openrouter.md +19 -387
- package/templates/hono/docs/library/ai-sdk/providers.md +28 -394
- package/templates/hono/docs/library/ai-sdk/streaming.md +52 -353
- package/templates/hono/docs/library/ai-sdk/structured-output.md +63 -395
- package/templates/hono/docs/library/ai-sdk/tools.md +62 -431
- package/templates/hono/docs/library/hono/env-setup.md +24 -313
- package/templates/hono/docs/library/hono/error-handling.md +34 -295
- package/templates/hono/docs/library/hono/index.md +24 -122
- package/templates/hono/docs/library/hono/middleware.md +21 -188
- package/templates/hono/docs/library/hono/rpc.md +40 -341
- package/templates/hono/docs/library/hono/validation.md +35 -195
- package/templates/hono/docs/library/pino/index.md +42 -333
- package/templates/hono/docs/library/prisma/cloudflare-d1.md +64 -367
- package/templates/hono/docs/library/prisma/config.md +19 -260
- package/templates/hono/docs/library/prisma/index.md +64 -320
- package/templates/hono/docs/library/zod/index.md +53 -257
- package/templates/npx/CLAUDE.md +58 -276
- package/templates/npx/docs/references/patterns.md +160 -0
- package/templates/tanstack-start/CLAUDE.md +0 -4
- package/templates/tanstack-start/docs/architecture/architecture.md +44 -589
- package/templates/tanstack-start/docs/design/index.md +119 -12
- package/templates/tanstack-start/docs/guides/conventions.md +103 -0
- package/templates/tanstack-start/docs/guides/env-setup.md +34 -340
- package/templates/tanstack-start/docs/guides/getting-started.md +22 -209
- package/templates/tanstack-start/docs/guides/hooks.md +166 -0
- package/templates/tanstack-start/docs/guides/routes.md +166 -0
- package/templates/tanstack-start/docs/guides/services.md +143 -0
- package/templates/tanstack-start/docs/library/tanstack-query/index.md +18 -2
- package/templates/tanstack-start/docs/library/zod/index.md +16 -1
- package/templates/tanstack-start/docs/design/accessibility.md +0 -163
- package/templates/tanstack-start/docs/design/color.md +0 -93
- package/templates/tanstack-start/docs/design/spacing.md +0 -122
- package/templates/tanstack-start/docs/design/typography.md +0 -80
- package/templates/tanstack-start/docs/guides/best-practices.md +0 -950
- package/templates/tanstack-start/docs/guides/husky-lint-staged.md +0 -303
- package/templates/tanstack-start/docs/guides/prettier.md +0 -189
- package/templates/tanstack-start/docs/guides/project-templates.md +0 -710
- package/templates/tanstack-start/docs/library/tanstack-query/setup.md +0 -48
- package/templates/tanstack-start/docs/library/zod/basic-types.md +0 -74
package/templates/npx/CLAUDE.md
CHANGED
|
@@ -1,315 +1,97 @@
|
|
|
1
|
-
# CLAUDE.md -
|
|
1
|
+
# CLAUDE.md - NPX CLI 프로젝트
|
|
2
2
|
|
|
3
|
-
>
|
|
3
|
+
> Node.js CLI 도구 개발 지침
|
|
4
4
|
|
|
5
5
|
## Instructions
|
|
6
6
|
|
|
7
|
-
@../../commands/git.md
|
|
8
7
|
@docs/library/commander/index.md
|
|
9
8
|
@docs/library/fs-extra/index.md
|
|
10
9
|
@docs/library/prompts/index.md
|
|
11
10
|
|
|
12
11
|
---
|
|
13
12
|
|
|
14
|
-
##
|
|
13
|
+
## 금지 사항
|
|
15
14
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
│ 📖 작업 유형별 상세 문서: docs/ 폴더 참조 │
|
|
22
|
-
└─────────────────────────────────────────────────────────────┘
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
---
|
|
15
|
+
### Git 커밋
|
|
16
|
+
- `Generated with Claude Code` 포함 금지
|
|
17
|
+
- AI 관련 이모지/표시 금지
|
|
18
|
+
- `Co-Authored-By:` 헤더 금지
|
|
19
|
+
- 여러 줄 커밋 메시지 금지
|
|
26
20
|
|
|
27
|
-
|
|
21
|
+
### CLI 구현
|
|
22
|
+
- `process.exit()` 없이 에러 종료 금지
|
|
23
|
+
- `console.log` 직접 사용 금지 (logger 사용)
|
|
24
|
+
- 동기 파일 작업 (`fs.readFileSync` 등) 금지
|
|
25
|
+
- hardcoded 경로 금지 (`path.join` 사용)
|
|
26
|
+
- 사용자 입력 미검증 처리 금지
|
|
28
27
|
|
|
29
|
-
###
|
|
30
|
-
|
|
31
|
-
❌ "Generated with Claude Code" 포함 금지
|
|
32
|
-
❌ "🤖" 또는 AI 관련 이모지 포함 금지
|
|
33
|
-
❌ "Co-Authored-By:" 헤더 포함 금지
|
|
34
|
-
❌ AI/봇이 작성했다는 어떤 표시도 금지
|
|
35
|
-
❌ 커밋 메시지 여러 줄 작성 금지
|
|
36
|
-
❌ 커밋 메시지에 이모지 사용 금지
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
### CLI 구현 금지 사항
|
|
40
|
-
```
|
|
41
|
-
❌ process.exit() 없이 에러 상황 종료 금지
|
|
42
|
-
❌ console.log 직접 사용 금지 (logger 사용)
|
|
43
|
-
❌ 동기 파일 작업 (fs.readFileSync 등) 금지
|
|
44
|
-
❌ hardcoded 경로 사용 금지 (path.join 사용)
|
|
45
|
-
❌ 사용자 입력 검증 없이 처리 금지
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
### 코드 검색 금지 사항
|
|
49
|
-
```
|
|
50
|
-
❌ grep, rg 등 기본 검색 도구 사용 금지
|
|
51
|
-
❌ find 명령어로 코드 검색 금지
|
|
52
|
-
✅ 코드베이스 검색 시 sgrep 사용 필수
|
|
53
|
-
```
|
|
28
|
+
### 코드 검색
|
|
29
|
+
- `grep`, `rg` 사용 금지 → `ast-grep` 필수
|
|
54
30
|
|
|
55
31
|
---
|
|
56
32
|
|
|
57
|
-
##
|
|
58
|
-
|
|
59
|
-
### 1. 작업 전: 관련 문서 읽기
|
|
60
|
-
```
|
|
61
|
-
CLI 작업 → docs/library/commander/ 읽기
|
|
62
|
-
파일 작업 → docs/library/fs-extra/ 읽기
|
|
63
|
-
사용자 입력 → docs/library/prompts/ 읽기
|
|
64
|
-
```
|
|
33
|
+
## 필수 사항
|
|
65
34
|
|
|
66
|
-
###
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
**상세**: `docs/mcp/` 참고
|
|
35
|
+
### 작업 전
|
|
36
|
+
| 작업 | 참조 문서 |
|
|
37
|
+
|------|----------|
|
|
38
|
+
| CLI 작업 | `docs/library/commander/` |
|
|
39
|
+
| 파일 작업 | `docs/library/fs-extra/` |
|
|
40
|
+
| 사용자 입력 | `docs/library/prompts/` |
|
|
73
41
|
|
|
74
|
-
###
|
|
75
|
-
```bash
|
|
76
|
-
git add .
|
|
77
|
-
git commit -m "<prefix>: <설명>"
|
|
42
|
+
### 커밋 형식
|
|
78
43
|
```
|
|
79
|
-
|
|
80
|
-
**커밋 형식**: `<prefix>: <설명>` (한 줄, 본문 없음)
|
|
81
|
-
|
|
82
|
-
**Prefix**: `feat` | `fix` | `refactor` | `style` | `docs` | `test` | `chore` | `perf` | `ci`
|
|
83
|
-
|
|
84
|
-
**예시**:
|
|
85
|
-
```bash
|
|
86
|
-
feat: 템플릿 복사 기능 추가
|
|
87
|
-
fix: 경로 처리 오류 수정
|
|
88
|
-
docs: README 업데이트
|
|
44
|
+
<prefix>: <설명>
|
|
89
45
|
```
|
|
90
46
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
|
96
|
-
|
|
97
|
-
|
|
|
98
|
-
| **Commander** | `docs/library/commander/` | 🔴 필수 |
|
|
99
|
-
| **fs-extra** | `docs/library/fs-extra/` | 🔴 필수 |
|
|
100
|
-
| **prompts** | `docs/library/prompts/` | 🔴 필수 |
|
|
47
|
+
| Prefix | 용도 |
|
|
48
|
+
|--------|------|
|
|
49
|
+
| feat | 새 기능 |
|
|
50
|
+
| fix | 버그 수정 |
|
|
51
|
+
| refactor | 리팩토링 |
|
|
52
|
+
| docs | 문서 수정 |
|
|
53
|
+
| chore | 빌드/설정 |
|
|
101
54
|
|
|
102
55
|
---
|
|
103
56
|
|
|
104
|
-
##
|
|
57
|
+
## Tech Stack
|
|
105
58
|
|
|
106
|
-
| 기술 | 버전 |
|
|
107
|
-
|
|
108
|
-
| Node.js | >= 18 | ESM 모듈
|
|
59
|
+
| 기술 | 버전 | 비고 |
|
|
60
|
+
|------|------|------|
|
|
61
|
+
| Node.js | >= 18 | ESM 모듈 |
|
|
109
62
|
| TypeScript | 5.x | strict mode |
|
|
110
63
|
| Commander | 12.x | CLI 프레임워크 |
|
|
111
|
-
| fs-extra | 11.x | 파일 시스템
|
|
112
|
-
| prompts | 2.x | Interactive
|
|
113
|
-
| picocolors | 1.x | 터미널 색상
|
|
114
|
-
| tsup | 8.x |
|
|
64
|
+
| fs-extra | 11.x | 파일 시스템 |
|
|
65
|
+
| prompts | 2.x | Interactive prompts |
|
|
66
|
+
| picocolors | 1.x | 터미널 색상 |
|
|
67
|
+
| tsup | 8.x | 번들러 |
|
|
115
68
|
|
|
116
69
|
---
|
|
117
70
|
|
|
118
|
-
##
|
|
71
|
+
## Directory Structure
|
|
119
72
|
|
|
120
73
|
```
|
|
121
74
|
src/
|
|
122
|
-
├── index.ts
|
|
123
|
-
├── commands/
|
|
124
|
-
│ └── init.ts
|
|
125
|
-
├── utils/
|
|
126
|
-
│ ├── copy.ts
|
|
127
|
-
│ └── logger.ts
|
|
128
|
-
└── types/
|
|
129
|
-
└── index.ts # 공통 타입
|
|
130
|
-
|
|
131
|
-
templates/ # 템플릿 파일 (빌드 시 복사)
|
|
132
|
-
scripts/ # 빌드 스크립트
|
|
133
|
-
dist/ # 빌드 결과물
|
|
134
|
-
```
|
|
135
|
-
|
|
136
|
-
---
|
|
137
|
-
|
|
138
|
-
## 🔧 Code Conventions
|
|
139
|
-
|
|
140
|
-
### File Naming
|
|
141
|
-
- **kebab-case**: `copy-template.ts`, `file-utils.ts`
|
|
142
|
-
- **index.ts**: 모듈 진입점
|
|
143
|
-
|
|
144
|
-
### TypeScript
|
|
145
|
-
- `const` 선언 사용 (function 대신)
|
|
146
|
-
- 명시적 return type
|
|
147
|
-
- `interface` (객체) / `type` (유니온)
|
|
148
|
-
- `any` 금지 → `unknown` 사용
|
|
149
|
-
|
|
150
|
-
### ESM Module
|
|
151
|
-
```typescript
|
|
152
|
-
// ✅ ESM import
|
|
153
|
-
import fs from 'fs-extra';
|
|
154
|
-
import path from 'path';
|
|
155
|
-
import { fileURLToPath } from 'url';
|
|
156
|
-
|
|
157
|
-
// __dirname 대체
|
|
158
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
159
|
-
const __dirname = path.dirname(__filename);
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
---
|
|
163
|
-
|
|
164
|
-
## 📝 Quick Patterns (복사용)
|
|
165
|
-
|
|
166
|
-
### CLI Entry Point
|
|
167
|
-
```typescript
|
|
168
|
-
#!/usr/bin/env node
|
|
169
|
-
import { Command } from 'commander';
|
|
170
|
-
|
|
171
|
-
const program = new Command();
|
|
172
|
-
|
|
173
|
-
program
|
|
174
|
-
.name('my-cli')
|
|
175
|
-
.description('CLI description')
|
|
176
|
-
.version('1.0.0');
|
|
177
|
-
|
|
178
|
-
program
|
|
179
|
-
.option('-t, --template <name>', 'template name')
|
|
180
|
-
.option('-f, --force', 'overwrite existing files')
|
|
181
|
-
.action(async (options) => {
|
|
182
|
-
// 명령어 실행
|
|
183
|
-
});
|
|
184
|
-
|
|
185
|
-
program.parse();
|
|
186
|
-
```
|
|
187
|
-
|
|
188
|
-
### Logger 유틸
|
|
189
|
-
```typescript
|
|
190
|
-
import pc from 'picocolors';
|
|
191
|
-
|
|
192
|
-
export const logger = {
|
|
193
|
-
info: (msg: string) => console.log(pc.blue('ℹ'), msg),
|
|
194
|
-
success: (msg: string) => console.log(pc.green('✔'), msg),
|
|
195
|
-
warn: (msg: string) => console.log(pc.yellow('⚠'), msg),
|
|
196
|
-
error: (msg: string) => console.log(pc.red('✖'), msg),
|
|
197
|
-
step: (msg: string) => console.log(pc.gray(' →'), msg),
|
|
198
|
-
blank: () => console.log(),
|
|
199
|
-
};
|
|
200
|
-
```
|
|
201
|
-
|
|
202
|
-
### Interactive Prompts
|
|
203
|
-
```typescript
|
|
204
|
-
import prompts from 'prompts';
|
|
205
|
-
|
|
206
|
-
// Select (단일 선택)
|
|
207
|
-
const { template } = await prompts({
|
|
208
|
-
type: 'select',
|
|
209
|
-
name: 'template',
|
|
210
|
-
message: 'Select a template:',
|
|
211
|
-
choices: [
|
|
212
|
-
{ title: 'Template A', value: 'a' },
|
|
213
|
-
{ title: 'Template B', value: 'b' },
|
|
214
|
-
],
|
|
215
|
-
});
|
|
216
|
-
|
|
217
|
-
// Multiselect (다중 선택)
|
|
218
|
-
const { templates } = await prompts({
|
|
219
|
-
type: 'multiselect',
|
|
220
|
-
name: 'templates',
|
|
221
|
-
message: 'Select templates:',
|
|
222
|
-
choices: [
|
|
223
|
-
{ title: 'Template A', value: 'a' },
|
|
224
|
-
{ title: 'Template B', value: 'b' },
|
|
225
|
-
],
|
|
226
|
-
min: 1,
|
|
227
|
-
hint: '- Space to select. Return to submit',
|
|
228
|
-
});
|
|
229
|
-
|
|
230
|
-
// Confirm
|
|
231
|
-
const { confirmed } = await prompts({
|
|
232
|
-
type: 'confirm',
|
|
233
|
-
name: 'confirmed',
|
|
234
|
-
message: 'Overwrite existing files?',
|
|
235
|
-
initial: false,
|
|
236
|
-
});
|
|
237
|
-
```
|
|
238
|
-
|
|
239
|
-
### File Copy 유틸
|
|
240
|
-
```typescript
|
|
241
|
-
import fs from 'fs-extra';
|
|
242
|
-
import path from 'path';
|
|
243
|
-
|
|
244
|
-
export const copyRecursive = async (
|
|
245
|
-
src: string,
|
|
246
|
-
dest: string,
|
|
247
|
-
): Promise<{ files: number; directories: number }> => {
|
|
248
|
-
const counter = { files: 0, directories: 0 };
|
|
249
|
-
|
|
250
|
-
const copy = async (s: string, d: string): Promise<void> => {
|
|
251
|
-
const stat = await fs.stat(s);
|
|
252
|
-
|
|
253
|
-
if (stat.isDirectory()) {
|
|
254
|
-
await fs.ensureDir(d);
|
|
255
|
-
counter.directories++;
|
|
256
|
-
|
|
257
|
-
const items = await fs.readdir(s);
|
|
258
|
-
for (const item of items) {
|
|
259
|
-
await copy(path.join(s, item), path.join(d, item));
|
|
260
|
-
}
|
|
261
|
-
} else {
|
|
262
|
-
await fs.copy(s, d);
|
|
263
|
-
counter.files++;
|
|
264
|
-
}
|
|
265
|
-
};
|
|
266
|
-
|
|
267
|
-
await copy(src, dest);
|
|
268
|
-
return counter;
|
|
269
|
-
};
|
|
270
|
-
```
|
|
271
|
-
|
|
272
|
-
### Package.json 설정
|
|
273
|
-
```json
|
|
274
|
-
{
|
|
275
|
-
"name": "@scope/my-cli",
|
|
276
|
-
"version": "1.0.0",
|
|
277
|
-
"type": "module",
|
|
278
|
-
"bin": "./dist/index.js",
|
|
279
|
-
"files": ["dist", "templates"],
|
|
280
|
-
"scripts": {
|
|
281
|
-
"build": "tsup",
|
|
282
|
-
"dev": "tsup --watch",
|
|
283
|
-
"prepublishOnly": "npm run build"
|
|
284
|
-
},
|
|
285
|
-
"engines": {
|
|
286
|
-
"node": ">=18"
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
```
|
|
290
|
-
|
|
291
|
-
### tsup.config.ts
|
|
292
|
-
```typescript
|
|
293
|
-
import { defineConfig } from 'tsup';
|
|
75
|
+
├── index.ts # CLI 진입점
|
|
76
|
+
├── commands/ # 명령어 모듈
|
|
77
|
+
│ └── init.ts
|
|
78
|
+
├── utils/ # 유틸리티
|
|
79
|
+
│ ├── copy.ts
|
|
80
|
+
│ └── logger.ts
|
|
81
|
+
└── types/ # 타입 정의
|
|
294
82
|
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
target: 'node18',
|
|
299
|
-
clean: true,
|
|
300
|
-
dts: true,
|
|
301
|
-
banner: {
|
|
302
|
-
js: '#!/usr/bin/env node',
|
|
303
|
-
},
|
|
304
|
-
});
|
|
83
|
+
templates/ # 템플릿 (빌드 시 복사)
|
|
84
|
+
scripts/ # 빌드 스크립트
|
|
85
|
+
dist/ # 빌드 결과물
|
|
305
86
|
```
|
|
306
87
|
|
|
307
88
|
---
|
|
308
89
|
|
|
309
|
-
##
|
|
90
|
+
## 참조
|
|
310
91
|
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
- [
|
|
315
|
-
|
|
92
|
+
| 문서 | 경로 |
|
|
93
|
+
|------|------|
|
|
94
|
+
| Commander 가이드 | [docs/library/commander/](docs/library/commander/index.md) |
|
|
95
|
+
| fs-extra 가이드 | [docs/library/fs-extra/](docs/library/fs-extra/index.md) |
|
|
96
|
+
| prompts 가이드 | [docs/library/prompts/](docs/library/prompts/index.md) |
|
|
97
|
+
| 코드 패턴 | [docs/references/patterns.md](docs/references/patterns.md) |
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
# NPX CLI Patterns
|
|
2
|
+
|
|
3
|
+
> 복사용 코드 패턴 모음
|
|
4
|
+
|
|
5
|
+
## CLI Entry Point
|
|
6
|
+
|
|
7
|
+
```typescript
|
|
8
|
+
#!/usr/bin/env node
|
|
9
|
+
import { Command } from 'commander';
|
|
10
|
+
|
|
11
|
+
const program = new Command();
|
|
12
|
+
|
|
13
|
+
program
|
|
14
|
+
.name('my-cli')
|
|
15
|
+
.description('CLI description')
|
|
16
|
+
.version('1.0.0');
|
|
17
|
+
|
|
18
|
+
program
|
|
19
|
+
.option('-t, --template <name>', 'template name')
|
|
20
|
+
.option('-f, --force', 'overwrite existing files')
|
|
21
|
+
.action(async (options) => {
|
|
22
|
+
// 명령어 실행
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
program.parse();
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Logger 유틸
|
|
29
|
+
|
|
30
|
+
```typescript
|
|
31
|
+
import pc from 'picocolors';
|
|
32
|
+
|
|
33
|
+
export const logger = {
|
|
34
|
+
info: (msg: string): void => console.log(pc.blue('ℹ'), msg),
|
|
35
|
+
success: (msg: string): void => console.log(pc.green('✔'), msg),
|
|
36
|
+
warn: (msg: string): void => console.log(pc.yellow('⚠'), msg),
|
|
37
|
+
error: (msg: string): void => console.log(pc.red('✖'), msg),
|
|
38
|
+
step: (msg: string): void => console.log(pc.gray(' →'), msg),
|
|
39
|
+
blank: (): void => console.log(),
|
|
40
|
+
};
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Interactive Prompts
|
|
44
|
+
|
|
45
|
+
```typescript
|
|
46
|
+
import prompts from 'prompts';
|
|
47
|
+
|
|
48
|
+
// Select (단일 선택)
|
|
49
|
+
const { template } = await prompts({
|
|
50
|
+
type: 'select',
|
|
51
|
+
name: 'template',
|
|
52
|
+
message: 'Select a template:',
|
|
53
|
+
choices: [
|
|
54
|
+
{ title: 'Template A', value: 'a' },
|
|
55
|
+
{ title: 'Template B', value: 'b' },
|
|
56
|
+
],
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
// Multiselect (다중 선택)
|
|
60
|
+
const { templates } = await prompts({
|
|
61
|
+
type: 'multiselect',
|
|
62
|
+
name: 'templates',
|
|
63
|
+
message: 'Select templates:',
|
|
64
|
+
choices: [
|
|
65
|
+
{ title: 'Template A', value: 'a' },
|
|
66
|
+
{ title: 'Template B', value: 'b' },
|
|
67
|
+
],
|
|
68
|
+
min: 1,
|
|
69
|
+
hint: '- Space to select. Return to submit',
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
// Confirm
|
|
73
|
+
const { confirmed } = await prompts({
|
|
74
|
+
type: 'confirm',
|
|
75
|
+
name: 'confirmed',
|
|
76
|
+
message: 'Overwrite existing files?',
|
|
77
|
+
initial: false,
|
|
78
|
+
});
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## File Copy 유틸
|
|
82
|
+
|
|
83
|
+
```typescript
|
|
84
|
+
import fs from 'fs-extra';
|
|
85
|
+
import path from 'path';
|
|
86
|
+
|
|
87
|
+
export const copyRecursive = async (
|
|
88
|
+
src: string,
|
|
89
|
+
dest: string,
|
|
90
|
+
): Promise<{ files: number; directories: number }> => {
|
|
91
|
+
const counter = { files: 0, directories: 0 };
|
|
92
|
+
|
|
93
|
+
const copy = async (s: string, d: string): Promise<void> => {
|
|
94
|
+
const stat = await fs.stat(s);
|
|
95
|
+
|
|
96
|
+
if (stat.isDirectory()) {
|
|
97
|
+
await fs.ensureDir(d);
|
|
98
|
+
counter.directories++;
|
|
99
|
+
|
|
100
|
+
const items = await fs.readdir(s);
|
|
101
|
+
for (const item of items) {
|
|
102
|
+
await copy(path.join(s, item), path.join(d, item));
|
|
103
|
+
}
|
|
104
|
+
} else {
|
|
105
|
+
await fs.copy(s, d);
|
|
106
|
+
counter.files++;
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
await copy(src, dest);
|
|
111
|
+
return counter;
|
|
112
|
+
};
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## ESM __dirname
|
|
116
|
+
|
|
117
|
+
```typescript
|
|
118
|
+
import { fileURLToPath } from 'url';
|
|
119
|
+
import path from 'path';
|
|
120
|
+
|
|
121
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
122
|
+
const __dirname = path.dirname(__filename);
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## Package.json
|
|
126
|
+
|
|
127
|
+
```json
|
|
128
|
+
{
|
|
129
|
+
"name": "@scope/my-cli",
|
|
130
|
+
"version": "1.0.0",
|
|
131
|
+
"type": "module",
|
|
132
|
+
"bin": "./dist/index.js",
|
|
133
|
+
"files": ["dist", "templates"],
|
|
134
|
+
"scripts": {
|
|
135
|
+
"build": "tsup",
|
|
136
|
+
"dev": "tsup --watch",
|
|
137
|
+
"prepublishOnly": "npm run build"
|
|
138
|
+
},
|
|
139
|
+
"engines": {
|
|
140
|
+
"node": ">=18"
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
## tsup.config.ts
|
|
146
|
+
|
|
147
|
+
```typescript
|
|
148
|
+
import { defineConfig } from 'tsup';
|
|
149
|
+
|
|
150
|
+
export default defineConfig({
|
|
151
|
+
entry: ['src/index.ts'],
|
|
152
|
+
format: ['esm'],
|
|
153
|
+
target: 'node18',
|
|
154
|
+
clean: true,
|
|
155
|
+
dts: true,
|
|
156
|
+
banner: {
|
|
157
|
+
js: '#!/usr/bin/env node',
|
|
158
|
+
},
|
|
159
|
+
});
|
|
160
|
+
```
|
|
@@ -27,9 +27,6 @@
|
|
|
27
27
|
- handler 내부에서 수동 검증/인증 체크 금지
|
|
28
28
|
- 클라이언트에서 Server Function 직접 호출 금지 → TanStack Query 필수
|
|
29
29
|
|
|
30
|
-
### 코드 검색
|
|
31
|
-
- `grep`/`rg`/`find` 금지 → `sgrep` 사용
|
|
32
|
-
|
|
33
30
|
### Custom Hook 순서
|
|
34
31
|
1. State (useState, zustand)
|
|
35
32
|
2. Global Hooks (useParams, useNavigate, useQueryClient)
|
|
@@ -63,7 +60,6 @@ prisma/schema/
|
|
|
63
60
|
| 인증 | docs/library/better-auth/ |
|
|
64
61
|
|
|
65
62
|
### MCP 도구
|
|
66
|
-
- 코드 검색: sgrep
|
|
67
63
|
- 분석/디버깅: Sequential Thinking
|
|
68
64
|
- 라이브러리 문서: Context7
|
|
69
65
|
|