sleepcode 1.1.0 → 1.3.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.
package/README.md CHANGED
@@ -45,23 +45,15 @@ npx sleepcode
45
45
 
46
46
  ### 3. 실행
47
47
 
48
- **macOS / Linux:**
49
48
  ```bash
50
49
  # 1회 실행
51
- ./.sleepcode/ai_worker.sh
50
+ npx sleepcode run
52
51
 
53
- # 무한 루프 (tmux 권장)
54
- tmux new -s ai './.sleepcode/run_forever.sh'
52
+ # 무한 루프 (잠자기 )
53
+ npx sleepcode run --loop
55
54
  ```
56
55
 
57
- **Windows (PowerShell):**
58
- ```powershell
59
- # 1회 실행
60
- powershell -File .\.sleepcode\ai_worker.ps1
61
-
62
- # 무한 루프
63
- powershell -File .\.sleepcode\run_forever.ps1
64
- ```
56
+ OS에 맞는 스크립트를 자동으로 선택합니다 (macOS/Linux: `.sh`, Windows: `.ps1`).
65
57
 
66
58
  ### 4. 아침에 확인
67
59
 
@@ -96,6 +88,9 @@ npx sleepcode --type react-native --name my-app --role "쇼핑몰 앱 개발"
96
88
  | `--name <name>` | 프로젝트 이름 |
97
89
  | `--role <desc>` | AI 역할 설명 |
98
90
  | `--figma-key <key>` | Figma API Key (선택) |
91
+ | `--figma-file <name>` | Figma 참고 파일명 (선택) |
92
+ | `--notion-key <key>` | Notion API Key (선택) |
93
+ | `--notion-page <name>` | Notion 참고 페이지명 (선택) |
99
94
  | `--interval <sec>` | 반복 간격 초 (기본: 30) |
100
95
  | `-f, --force` | 기존 `.sleepcode/` 폴더 덮어쓰기 |
101
96
  | `-h, --help` | 도움말 |
@@ -106,17 +101,19 @@ npx sleepcode --type react-native --name my-app --role "쇼핑몰 앱 개발"
106
101
 
107
102
  ```
108
103
  .sleepcode/
109
- rules.md # AI 역할 + 작업 규칙 (프롬프트)
110
- tasks.md # 작업 목록 (체크리스트)
111
- docs/ # 참고 자료 (피그마 스크린샷, 기획서 등)
112
- ai_worker.sh/.ps1 # 1회 실행 스크립트 (OS별)
113
- run_forever.sh/.ps1 # 무한 루프 스크립트 (OS별)
114
- log_filter.py # 실시간 로그 필터
115
- logs/ # 실행 로그 (자동 생성)
116
- README.md # 사용 가이드
104
+ rules.md # ✏️ AI 역할 + 작업 규칙 (수정하세요)
105
+ tasks.md # ✏️ 작업 목록 (수정하세요)
106
+ docs/ # ✏️ 참고 자료 (피그마 스크린샷, 기획서 등)
107
+ scripts/ # ⚙️ 시스템 (수정하지 마세요)
108
+ base_rules.md # 공통 작업 규칙
109
+ ai_worker.sh/.ps1 # 1회 실행 스크립트 (OS별)
110
+ run_forever.sh/.ps1 # 무한 루프 스크립트 (OS별)
111
+ log_filter.py # 실시간 로그 필터
112
+ logs/ # 실행 로그 (자동 생성)
113
+ README.md # 사용 가이드
117
114
 
118
115
  .claude/
119
- settings.local.json # Claude 권한 설정
116
+ settings.local.json # Claude 권한 설정
120
117
  ```
121
118
 
122
119
  ---
@@ -152,7 +149,7 @@ rules.md + tasks.md → 프롬프트 조합 → claude -p (비대화형) → 코
152
149
 
153
150
  | 동작 | 명령어 |
154
151
  |------|--------|
155
- | 세션 생성 + 실행 | `tmux new -s ai './.sleepcode/run_forever.sh'` |
152
+ | 세션 생성 + 실행 | `tmux new -s ai 'npx sleepcode run --loop'` |
156
153
  | 백그라운드 전환 | `Ctrl+B` → `D` |
157
154
  | 세션 재접속 | `tmux attach -t ai` |
158
155
  | 실시간 로그 | `tail -f .sleepcode/logs/worker_*.log` |
@@ -214,7 +211,7 @@ Windows에서는 `.sh` 대신 **PowerShell 스크립트(`.ps1`)가 자동 생성
214
211
  - **AI 역할/규칙 변경**: `.sleepcode/rules.md` 수정
215
212
  - **작업 목록 변경**: `.sleepcode/tasks.md` 수정
216
213
  - **참고 자료 추가**: `.sleepcode/docs/`에 파일 추가 (스크린샷, 기획서 등)
217
- - **반복 간격 변경**: `.sleepcode/run_forever.sh` (또는 `.ps1`)의 sleep 값 수정
214
+ - **반복 간격 변경**: `.sleepcode/scripts/run_forever.sh` (또는 `.ps1`)의 sleep 값 수정
218
215
  - **Claude 권한 변경**: `.claude/settings.local.json` 수정
219
216
 
220
217
  ---
package/bin/index.js CHANGED
@@ -190,19 +190,30 @@ function parseArgs() {
190
190
  else if (args[i] === '--name' && args[i + 1]) parsed.name = args[++i];
191
191
  else if (args[i] === '--role' && args[i + 1]) parsed.role = args[++i];
192
192
  else if (args[i] === '--figma-key' && args[i + 1]) parsed.figmaKey = args[++i];
193
+ else if (args[i] === '--figma-file' && args[i + 1]) parsed.figmaFileNames = args[++i];
194
+ else if (args[i] === '--notion-key' && args[i + 1]) parsed.notionKey = args[++i];
195
+ else if (args[i] === '--notion-page' && args[i + 1]) parsed.notionPages = args[++i];
193
196
  else if (args[i] === '--interval' && args[i + 1]) parsed.interval = args[++i];
194
197
  else if (args[i] === '--force' || args[i] === '-f') parsed.force = true;
195
198
  else if (args[i] === '--help' || args[i] === '-h') {
196
199
  console.log(`
197
200
  사용법: sleepcode [옵션]
201
+ sleepcode run [--loop]
198
202
 
199
203
  옵션 없이 실행하면 인터랙티브 모드로 동작합니다.
200
204
 
205
+ 명령어:
206
+ run 1회 실행 (ai_worker 스크립트)
207
+ run --loop 무한 루프 실행 (run_forever 스크립트)
208
+
201
209
  옵션:
202
210
  --type <type> 프로젝트 타입 (spring-boot, react-native, nextjs, custom)
203
211
  --name <name> 프로젝트 이름
204
212
  --role <desc> AI 역할 설명
205
213
  --figma-key <key> Figma API Key
214
+ --figma-file <name> Figma 참고 파일명
215
+ --notion-key <key> Notion API Key
216
+ --notion-page <name> Notion 참고 페이지명
206
217
  --interval <sec> 반복 간격 (초, 기본 30)
207
218
  -f, --force 기존 .sleepcode/ 덮어쓰기
208
219
  -h, --help 도움말
@@ -246,22 +257,23 @@ function writeFile(filePath, content) {
246
257
  fs.writeFileSync(filePath, content);
247
258
  }
248
259
 
249
- function generateFiles(targetDir, { typeKey, projectName, role, buildCmd, testCmd, lintCmd, figmaKey, sleepInterval }) {
260
+ function generateFiles(targetDir, { typeKey, projectName, role, buildCmd, testCmd, lintCmd, figmaKey, figmaFileNames, notionKey, notionPages, sleepInterval }) {
250
261
  const scDir = path.join(targetDir, '.sleepcode');
251
262
  const claudeDir = path.join(targetDir, '.claude');
252
263
  fs.mkdirSync(path.join(scDir, 'docs'), { recursive: true });
264
+ fs.mkdirSync(path.join(scDir, 'scripts'), { recursive: true });
253
265
  fs.mkdirSync(path.join(scDir, 'logs'), { recursive: true });
254
266
  fs.mkdirSync(claudeDir, { recursive: true });
255
267
 
256
- // 공통 파일 복사 (OS별 분기)
268
+ // 스크립트 파일 → scripts/ 하위로 복사 (OS별 분기)
257
269
  const scriptFiles = IS_WIN
258
270
  ? ['ai_worker.ps1', 'run_forever.ps1']
259
271
  : ['ai_worker.sh', 'run_forever.sh'];
260
- const commonFiles = [...scriptFiles, 'log_filter.py', 'README.md'];
272
+ const allScriptFiles = [...scriptFiles, 'log_filter.py'];
261
273
 
262
- for (const file of commonFiles) {
274
+ for (const file of allScriptFiles) {
263
275
  const src = path.join(TEMPLATES_DIR, 'common', file);
264
- const dest = path.join(scDir, file);
276
+ const dest = path.join(scDir, 'scripts', file);
265
277
  if (fs.existsSync(src)) {
266
278
  let content = fs.readFileSync(src, 'utf-8');
267
279
  content = content.replace(/\{\{SLEEP_INTERVAL\}\}/g, sleepInterval);
@@ -269,11 +281,47 @@ function generateFiles(targetDir, { typeKey, projectName, role, buildCmd, testCm
269
281
  }
270
282
  }
271
283
 
284
+ // base_rules.md → scripts/ 하위로 복사 (Figma/Notion 섹션 조건부 처리)
285
+ const baseRulesSrc = path.join(TEMPLATES_DIR, 'common', 'base_rules.md');
286
+ if (fs.existsSync(baseRulesSrc)) {
287
+ let baseRules = fs.readFileSync(baseRulesSrc, 'utf-8');
288
+
289
+ // Figma 섹션
290
+ if (figmaKey) {
291
+ let figmaSection = `## Figma\n\n- **프론트엔드 디자인**: Figma MCP 도구로 직접 조회 가능 (API Key: \`${figmaKey}\`)`;
292
+ if (figmaFileNames) {
293
+ figmaSection += `\n- **참고 파일**: ${figmaFileNames}`;
294
+ }
295
+ baseRules = baseRules.replace('{{FIGMA_SECTION}}', figmaSection);
296
+ } else {
297
+ baseRules = baseRules.replace('\n{{FIGMA_SECTION}}\n', '');
298
+ }
299
+
300
+ // Notion 섹션
301
+ if (notionKey) {
302
+ let notionSection = `\n## Notion\n\n- **기획/문서**: Notion MCP 도구로 직접 조회 가능 (API Key: \`${notionKey}\`)`;
303
+ if (notionPages) {
304
+ notionSection += `\n- **참고 페이지**: ${notionPages}`;
305
+ }
306
+ baseRules = baseRules.replace('{{NOTION_SECTION}}', notionSection);
307
+ } else {
308
+ baseRules = baseRules.replace('\n{{NOTION_SECTION}}\n', '');
309
+ }
310
+
311
+ fs.writeFileSync(path.join(scDir, 'scripts', 'base_rules.md'), baseRules);
312
+ }
313
+
314
+ // README.md → .sleepcode/ 루트에 복사
315
+ const readmeSrc = path.join(TEMPLATES_DIR, 'common', 'README.md');
316
+ if (fs.existsSync(readmeSrc)) {
317
+ fs.writeFileSync(path.join(scDir, 'README.md'), fs.readFileSync(readmeSrc, 'utf-8'));
318
+ }
319
+
272
320
  // 실행 권한 (Unix만)
273
321
  if (!IS_WIN) {
274
- fs.chmodSync(path.join(scDir, 'ai_worker.sh'), 0o755);
275
- fs.chmodSync(path.join(scDir, 'run_forever.sh'), 0o755);
276
- fs.chmodSync(path.join(scDir, 'log_filter.py'), 0o755);
322
+ fs.chmodSync(path.join(scDir, 'scripts', 'ai_worker.sh'), 0o755);
323
+ fs.chmodSync(path.join(scDir, 'scripts', 'run_forever.sh'), 0o755);
324
+ fs.chmodSync(path.join(scDir, 'scripts', 'log_filter.py'), 0o755);
277
325
  }
278
326
 
279
327
  // docs/.gitkeep
@@ -301,12 +349,6 @@ function generateFiles(targetDir, { typeKey, projectName, role, buildCmd, testCm
301
349
  rules = rules.replace(/\{\{BUILD_CMD\}\}/g, buildCmd);
302
350
  rules = rules.replace(/\{\{TEST_CMD\}\}/g, testCmd);
303
351
  rules = rules.replace(/\{\{LINT_CMD\}\}/g, lintCmd);
304
- rules = rules.replace(/\{\{FIGMA_API_KEY\}\}/g, figmaKey);
305
-
306
- if (!figmaKey) {
307
- rules = rules.replace(/\n## Figma[\s\S]*?(?=\n## |$)/, '');
308
- }
309
-
310
352
  writeFile(path.join(scDir, 'rules.md'), rules);
311
353
  }
312
354
 
@@ -332,47 +374,72 @@ function printResult() {
332
374
  const foreverScript = IS_WIN ? 'run_forever.ps1' : 'run_forever.sh';
333
375
 
334
376
  console.log(`\n${C.bold}파일 생성 완료:${C.reset}\n`);
335
- console.log(` ${C.green}✓${C.reset} .sleepcode/rules.md`);
336
- console.log(` ${C.green}✓${C.reset} .sleepcode/tasks.md`);
337
- console.log(` ${C.green}✓${C.reset} .sleepcode/${workerScript}`);
338
- console.log(` ${C.green}✓${C.reset} .sleepcode/${foreverScript}`);
339
- console.log(` ${C.green}✓${C.reset} .sleepcode/log_filter.py`);
377
+ console.log(` ${C.green}✓${C.reset} .sleepcode/rules.md ${C.dim}← 수정하세요${C.reset}`);
378
+ console.log(` ${C.green}✓${C.reset} .sleepcode/tasks.md ${C.dim}← 수정하세요${C.reset}`);
379
+ console.log(` ${C.green}✓${C.reset} .sleepcode/docs/ ${C.dim}← 참고자료 추가${C.reset}`);
380
+ console.log(` ${C.green}✓${C.reset} .sleepcode/scripts/base_rules.md`);
381
+ console.log(` ${C.green}✓${C.reset} .sleepcode/scripts/${workerScript}`);
382
+ console.log(` ${C.green}✓${C.reset} .sleepcode/scripts/${foreverScript}`);
383
+ console.log(` ${C.green}✓${C.reset} .sleepcode/scripts/log_filter.py`);
340
384
  console.log(` ${C.green}✓${C.reset} .sleepcode/README.md`);
341
- console.log(` ${C.green}✓${C.reset} .sleepcode/docs/`);
342
385
  console.log(` ${C.green}✓${C.reset} .claude/settings.local.json`);
343
386
 
344
- if (IS_WIN) {
345
- console.log(`
387
+ console.log(`
346
388
  ${C.bold}${C.green}완료!${C.reset} 다음 단계:
347
389
 
348
390
  ${C.bold}1.${C.reset} .sleepcode/rules.md 를 프로젝트에 맞게 수정
349
391
  ${C.bold}2.${C.reset} .sleepcode/tasks.md 에 작업 목록 작성
350
- ${C.bold}3.${C.reset} 실행 (PowerShell):
351
- ${C.dim}# 1회 실행${C.reset}
352
- powershell -File .\\.sleepcode\\ai_worker.ps1
353
-
354
- ${C.dim}# 무한 루프${C.reset}
355
- powershell -File .\\.sleepcode\\run_forever.ps1
392
+ ${C.bold}3.${C.reset} 실행:
393
+ ${C.cyan}npx sleepcode run${C.reset} ${C.dim}# 1회 실행${C.reset}
394
+ ${C.cyan}npx sleepcode run --loop${C.reset} ${C.dim}# 무한 루프${C.reset}
356
395
  `);
357
- } else {
358
- console.log(`
359
- ${C.bold}${C.green}완료!${C.reset} 다음 단계:
396
+ }
360
397
 
361
- ${C.bold}1.${C.reset} .sleepcode/rules.md 프로젝트에 맞게 수정
362
- ${C.bold}2.${C.reset} .sleepcode/tasks.md 에 작업 목록 작성
363
- ${C.bold}3.${C.reset} 실행:
364
- ${C.dim}# 1회 실행${C.reset}
365
- ./.sleepcode/ai_worker.sh
398
+ // ─── 실행 명령어 ───
399
+ function runWorker(loop) {
400
+ const targetDir = process.cwd();
401
+ const scDir = path.join(targetDir, '.sleepcode', 'scripts');
366
402
 
367
- ${C.dim}# 무한 루프 (tmux)${C.reset}
368
- tmux new -s ai './.sleepcode/run_forever.sh'
369
- `);
403
+ if (!fs.existsSync(scDir)) {
404
+ console.error(`${C.red}.sleepcode/scripts/ 폴더가 없습니다. 먼저 'npx sleepcode'로 초기화하세요.${C.reset}`);
405
+ process.exit(1);
406
+ }
407
+
408
+ const scriptName = loop
409
+ ? (IS_WIN ? 'run_forever.ps1' : 'run_forever.sh')
410
+ : (IS_WIN ? 'ai_worker.ps1' : 'ai_worker.sh');
411
+ const scriptPath = path.join(scDir, scriptName);
412
+
413
+ if (!fs.existsSync(scriptPath)) {
414
+ console.error(`${C.red}스크립트를 찾을 수 없습니다: ${scriptPath}${C.reset}`);
415
+ process.exit(1);
416
+ }
417
+
418
+ const cmd = IS_WIN
419
+ ? `powershell -File "${scriptPath}"`
420
+ : `"${scriptPath}"`;
421
+
422
+ console.log(`${C.cyan}${loop ? '무한 루프' : '1회'} 실행: ${scriptName}${C.reset}\n`);
423
+
424
+ try {
425
+ execSync(cmd, { stdio: 'inherit', cwd: targetDir });
426
+ } catch (e) {
427
+ process.exit(e.status || 1);
370
428
  }
371
429
  }
372
430
 
373
431
  // ─── 메인 ───
374
432
  async function main() {
375
433
  const targetDir = process.cwd();
434
+
435
+ // 서브커맨드: sleepcode run / sleepcode run --loop
436
+ const firstArg = process.argv[2];
437
+ if (firstArg === 'run') {
438
+ const loop = process.argv.includes('--loop');
439
+ runWorker(loop);
440
+ return;
441
+ }
442
+
376
443
  const cliArgs = parseArgs();
377
444
 
378
445
  console.log(`
@@ -403,6 +470,9 @@ ${C.bold}${C.magenta} ╔══════════════════
403
470
  const projectName = cliArgs.name || path.basename(targetDir);
404
471
  const role = cliArgs.role || `${projectName} 서비스 개발`;
405
472
  const figmaKey = cliArgs.figmaKey || '';
473
+ const figmaFileNames = cliArgs.figmaFileNames || '';
474
+ const notionKey = cliArgs.notionKey || '';
475
+ const notionPages = cliArgs.notionPages || '';
406
476
  const sleepInterval = cliArgs.interval || '30';
407
477
 
408
478
  console.log(`${C.dim}타입: ${typeConfig.label}${C.reset}`);
@@ -417,6 +487,9 @@ ${C.bold}${C.magenta} ╔══════════════════
417
487
  testCmd: typeConfig.testCmd,
418
488
  lintCmd: typeConfig.lintCmd,
419
489
  figmaKey,
490
+ figmaFileNames,
491
+ notionKey,
492
+ notionPages,
420
493
  sleepInterval,
421
494
  });
422
495
 
@@ -469,7 +542,24 @@ ${C.bold}${C.magenta} ╔══════════════════
469
542
  console.log(`${C.dim} 린트: ${lintCmd || '(없음)'}${C.reset}`);
470
543
  }
471
544
 
472
- const figmaKey = await ask(rl, 'Figma API Key (없으면 Enter)', '');
545
+ // Figma 연동
546
+ let figmaKey = '';
547
+ let figmaFileNames = '';
548
+ const useFigma = await ask(rl, 'Figma 디자인을 참고하나요? (y/N)', 'N');
549
+ if (useFigma.toLowerCase() === 'y') {
550
+ figmaKey = await ask(rl, 'Figma API Key', '');
551
+ figmaFileNames = await ask(rl, '참고할 Figma 파일명 (예: 홈화면, 로그인)', '');
552
+ }
553
+
554
+ // Notion 연동
555
+ let notionKey = '';
556
+ let notionPages = '';
557
+ const useNotion = await ask(rl, 'Notion 문서를 참고하나요? (y/N)', 'N');
558
+ if (useNotion.toLowerCase() === 'y') {
559
+ notionKey = await ask(rl, 'Notion API Key', '');
560
+ notionPages = await ask(rl, '참고할 Notion 페이지명 (예: 기획서, API명세)', '');
561
+ }
562
+
473
563
  const sleepInterval = await ask(rl, '반복 간격 (초)', '30');
474
564
 
475
565
  rl.close();
@@ -482,6 +572,9 @@ ${C.bold}${C.magenta} ╔══════════════════
482
572
  testCmd,
483
573
  lintCmd,
484
574
  figmaKey,
575
+ figmaFileNames,
576
+ notionKey,
577
+ notionPages,
485
578
  sleepInterval,
486
579
  });
487
580
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sleepcode",
3
- "version": "1.1.0",
3
+ "version": "1.3.0",
4
4
  "description": "AI codes while you sleep — Claude AI 야간 자동화 세팅 CLI",
5
5
  "bin": {
6
6
  "sleepcode": "./bin/index.js"
@@ -8,13 +8,15 @@ AI codes while you sleep — 밤새 개발 작업을 자동화하는 시스템
8
8
 
9
9
  ```
10
10
  .sleepcode/
11
- rules.md # AI 역할 + 작업 규칙
12
- tasks.md # 오늘 진행할 작업 목록
13
- docs/ # 개발 참고 자료 (피그마 스크린샷, 기획서 등)
14
- ai_worker.sh # 1회 실행 스크립트
15
- run_forever.sh # 무한 루프 감시자 스크립트
16
- log_filter.py # 로그 필터 (핵심 메시지만 추출)
17
- logs/ # 실행 로그 (자동 생성)
11
+ rules.md # ✏️ AI 역할 + 작업 규칙 (수정하세요)
12
+ tasks.md # ✏️ 오늘 진행할 작업 목록 (수정하세요)
13
+ docs/ # ✏️ 개발 참고 자료 (피그마 스크린샷, 기획서 등)
14
+ scripts/ # ⚙️ 시스템 (수정하지 마세요)
15
+ base_rules.md # 공통 작업 규칙
16
+ ai_worker.* # 1회 실행 스크립트
17
+ run_forever.* # 무한 루프 감시자 스크립트
18
+ log_filter.py # 로그 필터 (핵심 메시지만 추출)
19
+ logs/ # 실행 로그 (자동 생성)
18
20
  ```
19
21
 
20
22
  ---
@@ -30,13 +32,7 @@ AI codes while you sleep — 밤새 개발 작업을 자동화하는 시스템
30
32
 
31
33
  ## 실행 방법
32
34
 
33
- ### 1. 권한 부여
34
-
35
- ```bash
36
- chmod +x .sleepcode/*.sh
37
- ```
38
-
39
- ### 2. (최초 1회) --dangerously-skip-permissions 수락
35
+ ### 1. (최초 1회) --dangerously-skip-permissions 수락
40
36
 
41
37
  ```bash
42
38
  claude --dangerously-skip-permissions
@@ -44,24 +40,22 @@ claude --dangerously-skip-permissions
44
40
 
45
41
  동의 프롬프트가 뜨면 수락 후 `Ctrl + C`로 나옵니다.
46
42
 
47
- ### 3. tmux 세션 생성 + 실행
43
+ ### 2. 실행
48
44
 
49
45
  ```bash
50
- tmux new -s ai './.sleepcode/run_forever.sh'
51
- ```
52
-
53
- ### 4. tmux 분리 (백그라운드 전환)
46
+ # 1회 실행
47
+ npx sleepcode run
54
48
 
55
- ```
56
- Ctrl + B → D
49
+ # 무한 루프 (잠자기 전)
50
+ npx sleepcode run --loop
57
51
  ```
58
52
 
59
- ---
53
+ OS에 맞는 스크립트를 자동으로 선택합니다.
60
54
 
61
- ## 수동 1회 실행
55
+ ### 3. tmux 분리 (백그라운드 전환, macOS/Linux)
62
56
 
63
- ```bash
64
- ./.sleepcode/ai_worker.sh
57
+ ```
58
+ Ctrl + B → D
65
59
  ```
66
60
 
67
61
  ---
@@ -94,4 +88,3 @@ tail -100 .sleepcode/logs/worker_*.log
94
88
  - **역할/규칙 변경**: `.sleepcode/rules.md` 수정
95
89
  - **태스크 변경**: `.sleepcode/tasks.md` 수정
96
90
  - **참고 자료 추가**: `.sleepcode/docs/` 에 파일 추가
97
- - **반복 간격 변경**: `run_forever.sh` 의 `sleep` 값 수정
@@ -2,19 +2,20 @@
2
2
  # run_forever.ps1 (무한 루프) 대신 수동으로 1회만 돌릴 때 사용
3
3
 
4
4
  $ErrorActionPreference = "Stop"
5
- Set-Location (Split-Path $PSScriptRoot -Parent)
5
+ Set-Location (Split-Path (Split-Path $PSScriptRoot -Parent) -Parent)
6
6
 
7
7
  $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
8
8
  Write-Host "[$timestamp] AI 단일 실행 시작"
9
9
 
10
+ $baseRules = Get-Content .sleepcode/scripts/base_rules.md -Raw -Encoding UTF8
10
11
  $rules = Get-Content .sleepcode/rules.md -Raw -Encoding UTF8
11
12
  $tasks = Get-Content .sleepcode/tasks.md -Raw -Encoding UTF8
12
13
 
13
- $prompt = "$rules`n`n---`n`n$tasks"
14
+ $prompt = "$baseRules`n`n---`n`n$rules`n`n---`n`n$tasks"
14
15
 
15
16
  # stream-json + verbose: 토큰 단위 실시간 출력
16
17
  $prompt | claude -p --dangerously-skip-permissions --output-format stream-json --verbose 2>&1 |
17
- python .sleepcode/log_filter.py
18
+ python .sleepcode/scripts/log_filter.py
18
19
 
19
20
  $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
20
21
  Write-Host "[$timestamp] AI 단일 실행 종료"
@@ -3,14 +3,19 @@
3
3
  # AI Worker - 1회 실행 스크립트
4
4
  # run_forever.sh (무한 루프) 대신 수동으로 1회만 돌릴 때 사용
5
5
 
6
- cd "$(dirname "$0")/.." || exit 1
6
+ cd "$(dirname "$0")/../.." || exit 1
7
7
 
8
8
  echo "[$(date '+%Y-%m-%d %H:%M:%S')] AI 단일 실행 시작"
9
9
 
10
+ BASE_RULES=$(cat .sleepcode/scripts/base_rules.md)
10
11
  RULES=$(cat .sleepcode/rules.md)
11
12
  TASKS=$(cat .sleepcode/tasks.md)
12
13
 
13
- PROMPT="${RULES}
14
+ PROMPT="${BASE_RULES}
15
+
16
+ ---
17
+
18
+ ${RULES}
14
19
 
15
20
  ---
16
21
 
@@ -18,6 +23,6 @@ ${TASKS}"
18
23
 
19
24
  # stream-json + verbose: 토큰 단위 실시간 출력
20
25
  claude -p "$PROMPT" --dangerously-skip-permissions --output-format stream-json --verbose 2>&1 \
21
- | python3 .sleepcode/log_filter.py
26
+ | python3 .sleepcode/scripts/log_filter.py
22
27
 
23
28
  echo "[$(date '+%Y-%m-%d %H:%M:%S')] AI 단일 실행 종료"
@@ -0,0 +1,39 @@
1
+ # 공통 작업 규칙
2
+
3
+ ## 기본 원칙
4
+
5
+ - 절대로 사용자에게 질문하지 않는다.
6
+ - 작업이 끝났다고 판단하지 않는다.
7
+ - 항상 다음 작업을 스스로 찾는다.
8
+ - 가능한 한 많은 기능을 구현하며 계속 진행한다.
9
+
10
+ ---
11
+
12
+ ## 참고 자료
13
+
14
+ - `.sleepcode/docs/` 디렉토리에 업로드된 파일 참고 (피그마 스크린샷, 기획서, 참고 이미지 등)
15
+
16
+ {{FIGMA_SECTION}}
17
+ {{NOTION_SECTION}}
18
+
19
+ ---
20
+
21
+ ## 태스크 완료 처리
22
+
23
+ - `.sleepcode/tasks.md` 파일에서 작업 목록을 확인한다.
24
+ - 태스크를 **한 항목씩** 순서대로 진행한다.
25
+ - 한 항목을 완료하면 반드시 아래 순서를 따른다:
26
+ 1. 해당 항목의 `[ ]`를 `[x]`로 변경한다.
27
+ 2. 관련 파일을 모두 `git add` 한다. (tasks.md 포함)
28
+ 3. `git commit` 한다. (커밋 메시지에 태스크 내용을 포함)
29
+ 4. 그 다음 항목으로 넘어간다.
30
+ - 여러 항목을 한꺼번에 작업하지 않는다. 반드시 1항목 = 1커밋이다.
31
+
32
+ ---
33
+
34
+ ## Git 작업 규칙
35
+
36
+ - tasks.md의 항목 1개 완료 = git commit 1개. 이 규칙을 반드시 지킨다.
37
+ - 작업 중간에는 commit 하지 않는다.
38
+ - 기능이 정상 동작한다고 판단되면 commit 한다.
39
+ - commit message 는 변경 내용을 구체적으로 설명한다.
@@ -1,8 +1,8 @@
1
1
  # AI Night Worker - 감시자 스크립트 (Windows PowerShell)
2
- # 사용법: powershell -File .\.sleepcode\run_forever.ps1
2
+ # 사용법: powershell -File .\.sleepcode\scripts\run_forever.ps1
3
3
 
4
4
  $ErrorActionPreference = "Continue"
5
- Set-Location (Split-Path $PSScriptRoot -Parent)
5
+ Set-Location (Split-Path (Split-Path $PSScriptRoot -Parent) -Parent)
6
6
 
7
7
  $logDir = ".sleepcode/logs"
8
8
  if (!(Test-Path $logDir)) { New-Item -ItemType Directory -Path $logDir -Force | Out-Null }
@@ -35,15 +35,16 @@ while ($true) {
35
35
  exit 0
36
36
  }
37
37
 
38
- # rules.md + tasks.md 를 합쳐서 프롬프트 구성
38
+ # base_rules.md + rules.md + tasks.md 를 합쳐서 프롬프트 구성
39
+ $baseRules = Get-Content .sleepcode/scripts/base_rules.md -Raw -Encoding UTF8
39
40
  $rules = Get-Content .sleepcode/rules.md -Raw -Encoding UTF8
40
41
  $tasks = Get-Content .sleepcode/tasks.md -Raw -Encoding UTF8
41
- $prompt = "$rules`n`n---`n`n$tasks"
42
+ $prompt = "$baseRules`n`n---`n`n$rules`n`n---`n`n$tasks"
42
43
 
43
44
  Log "claude 실행 중..."
44
45
  # stream-json -> log_filter.py 로 핵심 메시지만 추출
45
46
  $prompt | claude -p --dangerously-skip-permissions --output-format stream-json --verbose 2>&1 |
46
- python .sleepcode/log_filter.py |
47
+ python .sleepcode/scripts/log_filter.py |
47
48
  Tee-Object -Append $logFile
48
49
  $exitCode = $LASTEXITCODE
49
50
  Log "claude 종료 (exit code: $exitCode)"
@@ -1,9 +1,9 @@
1
1
  #!/bin/bash
2
2
 
3
3
  # AI Night Worker - 감시자 스크립트
4
- # 사용법: tmux new -s ai './.sleepcode/run_forever.sh'
4
+ # 사용법: tmux new -s ai './.sleepcode/scripts/run_forever.sh'
5
5
 
6
- cd "$(dirname "$0")/.." || exit 1
6
+ cd "$(dirname "$0")/../.." || exit 1
7
7
 
8
8
  LOG_DIR=".sleepcode/logs"
9
9
  mkdir -p "$LOG_DIR"
@@ -31,11 +31,16 @@ while true; do
31
31
  exit 0
32
32
  fi
33
33
 
34
- # rules.md + tasks.md 를 합쳐서 프롬프트 구성
34
+ # base_rules.md + rules.md + tasks.md 를 합쳐서 프롬프트 구성
35
+ BASE_RULES=$(cat .sleepcode/scripts/base_rules.md)
35
36
  RULES=$(cat .sleepcode/rules.md)
36
37
  TASKS=$(cat .sleepcode/tasks.md)
37
38
 
38
- PROMPT="${RULES}
39
+ PROMPT="${BASE_RULES}
40
+
41
+ ---
42
+
43
+ ${RULES}
39
44
 
40
45
  ---
41
46
 
@@ -44,7 +49,7 @@ ${TASKS}"
44
49
  log "claude 실행 중..."
45
50
  # stream-json → log_filter.py 로 핵심 메시지만 추출
46
51
  claude -p "$PROMPT" --dangerously-skip-permissions --output-format stream-json --verbose 2>&1 \
47
- | python3 .sleepcode/log_filter.py \
52
+ | python3 .sleepcode/scripts/log_filter.py \
48
53
  | tee -a "$LOG_FILE"
49
54
  EXIT_CODE=${PIPESTATUS[0]}
50
55
  log "claude 종료 (exit code: $EXIT_CODE)"
@@ -8,25 +8,6 @@
8
8
 
9
9
  ---
10
10
 
11
- ## 기본 원칙
12
-
13
- - 절대로 사용자에게 질문하지 않는다.
14
- - 작업이 끝났다고 판단하지 않는다.
15
- - 항상 다음 작업을 스스로 찾는다.
16
- - 가능한 한 많은 기능을 구현하며 계속 진행한다.
17
-
18
- ---
19
-
20
- ## 참고 자료
21
-
22
- - `.sleepcode/docs/` 디렉토리에 업로드된 파일 참고
23
-
24
- ## Figma
25
-
26
- - **프론트엔드 디자인**: Figma MCP 도구로 직접 조회 가능 (API Key: `{{FIGMA_API_KEY}}`)
27
-
28
- ---
29
-
30
11
  ## 작업 방식
31
12
 
32
13
  - 작은 단위로 작업하고 자주 확인한다.
@@ -45,25 +26,3 @@
45
26
 
46
27
  - 기존 프로젝트 구조와 패턴을 존중한다.
47
28
  - 중복 코드를 만들지 않는다.
48
-
49
- ---
50
-
51
- ## 태스크 완료 처리
52
-
53
- - `.sleepcode/tasks.md` 파일에서 작업 목록을 확인한다.
54
- - 태스크를 **한 항목씩** 순서대로 진행한다.
55
- - 한 항목을 완료하면 반드시 아래 순서를 따른다:
56
- 1. 해당 항목의 `[ ]`를 `[x]`로 변경한다.
57
- 2. 관련 파일을 모두 `git add` 한다. (tasks.md 포함)
58
- 3. `git commit` 한다. (커밋 메시지에 태스크 내용을 포함)
59
- 4. 그 다음 항목으로 넘어간다.
60
- - 여러 항목을 한꺼번에 작업하지 않는다. 반드시 1항목 = 1커밋이다.
61
-
62
- ---
63
-
64
- ## Git 작업 규칙
65
-
66
- - tasks.md의 항목 1개 완료 = git commit 1개. 이 규칙을 반드시 지킨다.
67
- - 작업 중간에는 commit 하지 않는다.
68
- - 기능이 정상 동작한다고 판단되면 commit 한다.
69
- - commit message 는 변경 내용을 구체적으로 설명한다.
@@ -8,25 +8,6 @@
8
8
 
9
9
  ---
10
10
 
11
- ## 기본 원칙
12
-
13
- - 절대로 사용자에게 질문하지 않는다.
14
- - 작업이 끝났다고 판단하지 않는다.
15
- - 항상 다음 작업을 스스로 찾는다.
16
- - 가능한 한 많은 기능을 구현하며 계속 진행한다.
17
-
18
- ---
19
-
20
- ## 참고 자료
21
-
22
- - `.sleepcode/docs/` 디렉토리에 업로드된 파일 참고 (피그마 스크린샷, 기획서, 참고 이미지 등)
23
-
24
- ## Figma
25
-
26
- - **프론트엔드 디자인**: Figma MCP 도구로 직접 조회 가능 (API Key: `{{FIGMA_API_KEY}}`)
27
-
28
- ---
29
-
30
11
  ## 작업 방식
31
12
 
32
13
  - 작은 단위로 작업하고 자주 확인한다.
@@ -53,25 +34,3 @@
53
34
  - 중복 코드를 만들지 않는다.
54
35
  - App Router 구조를 따른다.
55
36
  - Server Component / Client Component 를 적절히 구분한다.
56
-
57
- ---
58
-
59
- ## 태스크 완료 처리
60
-
61
- - `.sleepcode/tasks.md` 파일에서 작업 목록을 확인한다.
62
- - 태스크를 **한 항목씩** 순서대로 진행한다.
63
- - 한 항목을 완료하면 반드시 아래 순서를 따른다:
64
- 1. 해당 항목의 `[ ]`를 `[x]`로 변경한다.
65
- 2. 관련 파일을 모두 `git add` 한다. (tasks.md 포함)
66
- 3. `git commit` 한다. (커밋 메시지에 태스크 내용을 포함)
67
- 4. 그 다음 항목으로 넘어간다.
68
- - 여러 항목을 한꺼번에 작업하지 않는다. 반드시 1항목 = 1커밋이다.
69
-
70
- ---
71
-
72
- ## Git 작업 규칙
73
-
74
- - tasks.md의 항목 1개 완료 = git commit 1개. 이 규칙을 반드시 지킨다.
75
- - 작업 중간에는 commit 하지 않는다.
76
- - 기능이 정상 동작한다고 판단되면 commit 한다.
77
- - commit message 는 변경 내용을 구체적으로 설명한다.
@@ -8,25 +8,6 @@
8
8
 
9
9
  ---
10
10
 
11
- ## 기본 원칙
12
-
13
- - 절대로 사용자에게 질문하지 않는다.
14
- - 작업이 끝났다고 판단하지 않는다.
15
- - 항상 다음 작업을 스스로 찾는다.
16
- - 가능한 한 많은 기능을 구현하며 계속 진행한다.
17
-
18
- ---
19
-
20
- ## 참고 자료
21
-
22
- - `.sleepcode/docs/` 디렉토리에 업로드된 파일 참고 (피그마 스크린샷, 기획서, 참고 이미지 등)
23
-
24
- ## Figma
25
-
26
- - **프론트엔드 디자인**: Figma MCP 도구로 직접 조회 가능 (API Key: `{{FIGMA_API_KEY}}`)
27
-
28
- ---
29
-
30
11
  ## 작업 방식
31
12
 
32
13
  - 작은 단위로 작업하고 자주 확인한다.
@@ -52,25 +33,3 @@
52
33
  - 중복 코드를 만들지 않는다.
53
34
  - 기존 컴포넌트를 최대한 재사용한다.
54
35
  - 새 컴포넌트는 기존 디렉토리 구조에 맞게 배치한다.
55
-
56
- ---
57
-
58
- ## 태스크 완료 처리
59
-
60
- - `.sleepcode/tasks.md` 파일에서 작업 목록을 확인한다.
61
- - 태스크를 **한 항목씩** 순서대로 진행한다.
62
- - 한 항목을 완료하면 반드시 아래 순서를 따른다:
63
- 1. 해당 항목의 `[ ]`를 `[x]`로 변경한다.
64
- 2. 관련 파일을 모두 `git add` 한다. (tasks.md 포함)
65
- 3. `git commit` 한다. (커밋 메시지에 태스크 내용을 포함)
66
- 4. 그 다음 항목으로 넘어간다.
67
- - 여러 항목을 한꺼번에 작업하지 않는다. 반드시 1항목 = 1커밋이다.
68
-
69
- ---
70
-
71
- ## Git 작업 규칙
72
-
73
- - tasks.md의 항목 1개 완료 = git commit 1개. 이 규칙을 반드시 지킨다.
74
- - 작업 중간에는 commit 하지 않는다.
75
- - 기능이 정상 동작한다고 판단되면 commit 한다.
76
- - commit message 는 변경 내용을 구체적으로 설명한다.
@@ -8,25 +8,6 @@
8
8
 
9
9
  ---
10
10
 
11
- ## 기본 원칙
12
-
13
- - 절대로 사용자에게 질문하지 않는다.
14
- - 작업이 끝났다고 판단하지 않는다.
15
- - 항상 다음 작업을 스스로 찾는다.
16
- - 가능한 한 많은 기능을 구현하며 계속 진행한다.
17
-
18
- ---
19
-
20
- ## 참고 자료
21
-
22
- - `.sleepcode/docs/` 디렉토리에 업로드된 파일 참고 (ERD, 화면설계, API 명세 등)
23
-
24
- ## Figma
25
-
26
- - **프론트엔드 디자인**: Figma MCP 도구로 직접 조회 가능 (API Key: `{{FIGMA_API_KEY}}`)
27
-
28
- ---
29
-
30
11
  ## 작업 방식
31
12
 
32
13
  - 작은 단위로 작업하고 자주 테스트한다.
@@ -54,25 +35,3 @@
54
35
  - REST API는 일관된 응답 형식을 유지한다.
55
36
  - Entity ↔ DTO 변환을 명확히 분리한다.
56
37
  - Service 계층에 비즈니스 로직을 집중한다.
57
-
58
- ---
59
-
60
- ## 태스크 완료 처리
61
-
62
- - `.sleepcode/tasks.md` 파일에서 작업 목록을 확인한다.
63
- - 태스크를 **한 항목씩** 순서대로 진행한다.
64
- - 한 항목을 완료하면 반드시 아래 순서를 따른다:
65
- 1. 해당 항목의 `[ ]`를 `[x]`로 변경한다.
66
- 2. 관련 파일을 모두 `git add` 한다. (tasks.md 포함)
67
- 3. `git commit` 한다. (커밋 메시지에 태스크 내용을 포함)
68
- 4. 그 다음 항목으로 넘어간다.
69
- - 여러 항목을 한꺼번에 작업하지 않는다. 반드시 1항목 = 1커밋이다.
70
-
71
- ---
72
-
73
- ## Git 작업 규칙
74
-
75
- - tasks.md의 항목 1개 완료 = git commit 1개. 이 규칙을 반드시 지킨다.
76
- - 작업 중간에는 commit 하지 않는다.
77
- - 기능이 정상 동작한다고 판단되면 commit 한다.
78
- - commit message 는 변경 내용을 구체적으로 설명한다.