@angar2/taskery 0.1.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/LICENSE +21 -0
- package/README.md +117 -0
- package/bin/create.js +52 -0
- package/bin/init.js +118 -0
- package/bin/lib.js +107 -0
- package/bin/taskery.js +57 -0
- package/bin/update.js +171 -0
- package/package.json +43 -0
- package/template/.claude/hooks/closed-immutable.sh +74 -0
- package/template/.claude/hooks/git-guard.sh +74 -0
- package/template/.claude/hooks/pre-commit-verify.sh +97 -0
- package/template/.claude/settings.json +19 -0
- package/template/.claude/skills/plan-init.md +140 -0
- package/template/.claude/skills/project-init.md +193 -0
- package/template/.claude/skills/refine.md +177 -0
- package/template/.claude/skills/task-close.md +178 -0
- package/template/.claude/skills/task-dev.md +155 -0
- package/template/.claude/skills/task-init.md +142 -0
- package/template/.claude/skills/task-plan.md +210 -0
- package/template/.claude/skills/task-test.md +189 -0
- package/template/.project/FRICTION_LOG.md +23 -0
- package/template/.project/changelog/.gitkeep +0 -0
- package/template/.project/flows/.gitkeep +0 -0
- package/template/.project/plans/.gitkeep +0 -0
- package/template/.project/rules/GIT_RULE.md +169 -0
- package/template/.project/rules/TASK_DOC_RULE.md +614 -0
- package/template/.project/shared/received/completed/.gitkeep +0 -0
- package/template/.project/shared/sent/completed/.gitkeep +0 -0
- package/template/.project/tasks/.gitkeep +0 -0
- package/template/CLAUDE.md +106 -0
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# .claude/hooks/closed-immutable.sh
|
|
3
|
+
# PreToolUse(Write|Edit) 훅 — closed 상태 task.md 재수정 차단
|
|
4
|
+
#
|
|
5
|
+
# 잡는 것 (단순화 — task.md 본 파일만 보호):
|
|
6
|
+
# 1. .project/tasks/<vX.X>/<NNN>_<slug>.md (단일 파일)
|
|
7
|
+
# 2. .project/tasks/<vX.X>/TASK-<NNN>_<slug>/task.md (폴더 승격)
|
|
8
|
+
# → 헤더 status가 'closed'면 차단
|
|
9
|
+
#
|
|
10
|
+
# 차단 안 함 (의도적):
|
|
11
|
+
# - .project/tasks/<vX.X>/spec-diffs/*.md — 역사적 자료, 자유 수정
|
|
12
|
+
# - .project/tasks/<vX.X>/screenshots/* — 자유
|
|
13
|
+
# - 폴더 승격 task 폴더 안 추가 자료 — 자유
|
|
14
|
+
# - 코드 영역 — closed task 코드 재수정은 *새 task로 처리*가 정상 흐름
|
|
15
|
+
#
|
|
16
|
+
# 우회 (의도적으로 closed task를 풀어 다시 진행해야 하는 경우):
|
|
17
|
+
# - 헤더 status를 closed → developing(또는 다른 상태)으로 직접 sed로 변경 (Bash 영역)
|
|
18
|
+
# - 그 후 정상 Edit 가능
|
|
19
|
+
#
|
|
20
|
+
# Catastrophic 영역 (완료 보호). 잘 지키면 작동 0회 (무해).
|
|
21
|
+
|
|
22
|
+
INPUT=$(cat)
|
|
23
|
+
|
|
24
|
+
# tool_input.file_path 추출
|
|
25
|
+
FILE_PATH=$(echo "$INPUT" | python3 -c "
|
|
26
|
+
import sys, json
|
|
27
|
+
try:
|
|
28
|
+
d = json.load(sys.stdin)
|
|
29
|
+
print(d.get('tool_input', {}).get('file_path', ''))
|
|
30
|
+
except Exception:
|
|
31
|
+
print('')
|
|
32
|
+
" 2>/dev/null)
|
|
33
|
+
|
|
34
|
+
# task.md 본 파일 매칭 (단일 + 폴더 승격)
|
|
35
|
+
# - 단일: .project/tasks/v*/<NNN>_<slug>.md (NNN_<slug> 패턴 — vX.X 직속, spec-diffs/screenshots 하위 X)
|
|
36
|
+
# - 폴더: .project/tasks/v*/TASK-<NNN>_<slug>/task.md
|
|
37
|
+
# spec-diffs/ + screenshots/ 직속 파일은 매칭 안 됨 (보호 대상 X)
|
|
38
|
+
if ! echo "$FILE_PATH" | grep -qE '\.project/tasks/v[^/]+/([0-9]+_[^/]+\.md|TASK-[^/]+/task\.md)$'; then
|
|
39
|
+
exit 0
|
|
40
|
+
fi
|
|
41
|
+
|
|
42
|
+
# task.md = file_path 자체
|
|
43
|
+
TASK_MD="$FILE_PATH"
|
|
44
|
+
|
|
45
|
+
# task.md 존재 안 하면 통과 (신규 생성 케이스)
|
|
46
|
+
if [ ! -f "$TASK_MD" ]; then
|
|
47
|
+
exit 0
|
|
48
|
+
fi
|
|
49
|
+
|
|
50
|
+
# 헤더 status 추출 (5컬럼 표 — 생성일 / 플랜 / 유형 / 규모 / 상태)
|
|
51
|
+
# python3 정규식 사용 (mac BSD grep -P 미지원)
|
|
52
|
+
STATUS=$(TM="$TASK_MD" python3 -c "
|
|
53
|
+
import os, re
|
|
54
|
+
try:
|
|
55
|
+
content = open(os.environ['TM']).read()
|
|
56
|
+
except Exception:
|
|
57
|
+
print('')
|
|
58
|
+
raise SystemExit(0)
|
|
59
|
+
# 7-state whitelist
|
|
60
|
+
WL = r'(draft|planned|developing|developed|testing|tested|closed)'
|
|
61
|
+
# 5-column row: | 생성일 | 플랜 | 유형 | 규모 | 상태 |
|
|
62
|
+
m = re.search(rf'^\|[^|]*\|[^|]*\|[^|]*\|[^|]*\|\s*{WL}\s*\|\s*\$', content, re.MULTILINE)
|
|
63
|
+
print(m.group(1) if m else '')
|
|
64
|
+
" 2>/dev/null)
|
|
65
|
+
|
|
66
|
+
# closed 상태면 차단
|
|
67
|
+
if [ "$STATUS" = "closed" ]; then
|
|
68
|
+
echo "closed-immutable: '$FILE_PATH' 차단. task '$TASK_MD' 상태가 'closed' — 재수정 금지." >&2
|
|
69
|
+
echo " 의도적 재진입 필요 시: sed로 헤더 status를 'developing' 또는 다른 상태로 직접 변경 후 Edit 가능." >&2
|
|
70
|
+
echo " *closed task 코드 / spec-diffs / screenshots*는 보호 영역 외 — 자유 수정. 단 코드 변경은 *새 task로 처리*가 정상 흐름." >&2
|
|
71
|
+
exit 2
|
|
72
|
+
fi
|
|
73
|
+
|
|
74
|
+
exit 0
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# .claude/hooks/git-guard.sh
|
|
3
|
+
# PreToolUse(Bash) 훅 — catastrophic git 명령 차단
|
|
4
|
+
#
|
|
5
|
+
# 잡는 것:
|
|
6
|
+
# 1. main / dev 브랜치 직접 커밋
|
|
7
|
+
# 2. git push --force / -f
|
|
8
|
+
# 3. git commit --no-verify
|
|
9
|
+
# 4. git branch -D (강제 삭제)
|
|
10
|
+
# 5. git reset --hard
|
|
11
|
+
# 6. git clean -fd
|
|
12
|
+
#
|
|
13
|
+
# 정상 흐름에서는 작동 0회 (무해). 사용자 명시 승인 케이스는 hook 비활성화 또는 직접 우회 필요.
|
|
14
|
+
#
|
|
15
|
+
# Single source of truth: .project/rules/GIT_RULE.md (없으면 ~/.claude/rules/GIT_RULE.md)
|
|
16
|
+
|
|
17
|
+
INPUT=$(cat)
|
|
18
|
+
|
|
19
|
+
# tool_input.command 추출
|
|
20
|
+
CMD=$(echo "$INPUT" | python3 -c "
|
|
21
|
+
import sys, json
|
|
22
|
+
try:
|
|
23
|
+
d = json.load(sys.stdin)
|
|
24
|
+
print(d.get('tool_input', {}).get('command', ''))
|
|
25
|
+
except Exception:
|
|
26
|
+
print('')
|
|
27
|
+
" 2>/dev/null)
|
|
28
|
+
|
|
29
|
+
# git 명령 아니면 통과
|
|
30
|
+
if ! echo "$CMD" | grep -qE '(^|;|&&|\|\|)\s*git\s'; then
|
|
31
|
+
exit 0
|
|
32
|
+
fi
|
|
33
|
+
|
|
34
|
+
# 1. main / dev 직접 커밋 차단
|
|
35
|
+
# 현재 브랜치 확인 + git commit 명령 감지 시 차단
|
|
36
|
+
if echo "$CMD" | grep -qE '(^|;|&&|\|\|)\s*git\s+commit\b'; then
|
|
37
|
+
CURRENT_BRANCH=$(git branch --show-current 2>/dev/null)
|
|
38
|
+
if [ "$CURRENT_BRANCH" = "main" ] || [ "$CURRENT_BRANCH" = "dev" ]; then
|
|
39
|
+
echo "git-guard: '$CURRENT_BRANCH' 브랜치 직접 커밋 차단. 작업 브랜치({타입}/{개발자}_TASK-NNN_slug)에서 커밋. (.project/rules/GIT_RULE.md §기본 원칙)" >&2
|
|
40
|
+
exit 2
|
|
41
|
+
fi
|
|
42
|
+
fi
|
|
43
|
+
|
|
44
|
+
# 2. git commit --no-verify 차단
|
|
45
|
+
if echo "$CMD" | grep -qE 'git\s+commit\b.*--no-verify'; then
|
|
46
|
+
echo "git-guard: 'git commit --no-verify' 차단. pre-commit-verify hook 우회 금지. (.project/rules/GIT_RULE.md §금지 사항)" >&2
|
|
47
|
+
exit 2
|
|
48
|
+
fi
|
|
49
|
+
|
|
50
|
+
# 3. git push --force / -f 차단
|
|
51
|
+
if echo "$CMD" | grep -qE 'git\s+push\b.*(\s--force(\s|$|=)|\s-f(\s|$))'; then
|
|
52
|
+
echo "git-guard: 'git push --force' 차단. 정상 흐름 사유 없음. 사용자 명시 승인 필요. (.project/rules/GIT_RULE.md §destructive 명령)" >&2
|
|
53
|
+
exit 2
|
|
54
|
+
fi
|
|
55
|
+
|
|
56
|
+
# 4. git branch -D 차단 (강제 삭제)
|
|
57
|
+
if echo "$CMD" | grep -qE 'git\s+branch\b.*\s-D(\s|$)'; then
|
|
58
|
+
echo "git-guard: 'git branch -D' 차단. 머지 안 된 브랜치 강제 삭제 사유 없음. 사용자 명시 승인 필요. (.project/rules/GIT_RULE.md §destructive 명령)" >&2
|
|
59
|
+
exit 2
|
|
60
|
+
fi
|
|
61
|
+
|
|
62
|
+
# 5. git reset --hard 차단
|
|
63
|
+
if echo "$CMD" | grep -qE 'git\s+reset\b.*--hard'; then
|
|
64
|
+
echo "git-guard: 'git reset --hard' 차단. 작업 손실 위험. 사용자 명시 승인 필요. (.project/rules/GIT_RULE.md §destructive 명령)" >&2
|
|
65
|
+
exit 2
|
|
66
|
+
fi
|
|
67
|
+
|
|
68
|
+
# 6. git clean -fd 차단
|
|
69
|
+
if echo "$CMD" | grep -qE 'git\s+clean\b.*\s-[a-zA-Z]*f[a-zA-Z]*d'; then
|
|
70
|
+
echo "git-guard: 'git clean -fd' 차단. untracked 파일 + 디렉토리 강제 삭제 사유 없음. 사용자 명시 승인 필요. (.project/rules/GIT_RULE.md §destructive 명령)" >&2
|
|
71
|
+
exit 2
|
|
72
|
+
fi
|
|
73
|
+
|
|
74
|
+
exit 0
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# .claude/hooks/pre-commit-verify.sh
|
|
3
|
+
# PreToolUse(Bash) 훅 — git commit 시점에 검증 명령 모두 PASS 게이트
|
|
4
|
+
#
|
|
5
|
+
# 잡는 것:
|
|
6
|
+
# git commit 명령 감지 → 프로젝트 루트 CLAUDE.md '## 검증 명령' 섹션의 명령 모두 실행
|
|
7
|
+
# 하나라도 fail (exit code != 0) → exit 2 (commit 차단)
|
|
8
|
+
#
|
|
9
|
+
# Process catastrophic — 결정적 영역(린트/타입/빌드/테스트). 합리적 변형 없음.
|
|
10
|
+
# 잘 지키면 작동 0회 (무해 — /task-dev self-check + /task-close 게이트로 이미 PASS 상태에서 commit).
|
|
11
|
+
# 부분 작업 / 환경 변화 / 가정 누설 시 catastrophic 차단 안전망.
|
|
12
|
+
#
|
|
13
|
+
# Single source of truth: 프로젝트 루트 CLAUDE.md '## 검증 명령' 섹션
|
|
14
|
+
# 형식 예:
|
|
15
|
+
# ## 검증 명령
|
|
16
|
+
# - 린트: `npm run lint`
|
|
17
|
+
# - 타입체크: `npm run typecheck`
|
|
18
|
+
# - 빌드: `npm run build`
|
|
19
|
+
# - 단위테스트: `npm test`
|
|
20
|
+
|
|
21
|
+
INPUT=$(cat)
|
|
22
|
+
|
|
23
|
+
# tool_input.command 추출
|
|
24
|
+
CMD=$(echo "$INPUT" | python3 -c "
|
|
25
|
+
import sys, json
|
|
26
|
+
try:
|
|
27
|
+
d = json.load(sys.stdin)
|
|
28
|
+
print(d.get('tool_input', {}).get('command', ''))
|
|
29
|
+
except Exception:
|
|
30
|
+
print('')
|
|
31
|
+
" 2>/dev/null)
|
|
32
|
+
|
|
33
|
+
# git commit 명령 아니면 통과
|
|
34
|
+
if ! echo "$CMD" | grep -qE '(^|;|&&|\|\|)\s*git\s+commit\b'; then
|
|
35
|
+
exit 0
|
|
36
|
+
fi
|
|
37
|
+
|
|
38
|
+
# CLAUDE.md 정독 — 프로젝트 루트
|
|
39
|
+
if [ ! -f "./CLAUDE.md" ]; then
|
|
40
|
+
echo "pre-commit-verify: 프로젝트 루트 CLAUDE.md 없음. 검증 명령 단일 진실 소스 누락 — commit 차단." >&2
|
|
41
|
+
echo " '/project-init' 또는 'npx @angar2/taskery init' 호출해 CLAUDE.md 생성." >&2
|
|
42
|
+
exit 2
|
|
43
|
+
fi
|
|
44
|
+
|
|
45
|
+
# '## 검증 명령' 섹션 추출 + 백틱(`...`) 안 명령 추출
|
|
46
|
+
COMMANDS=$(python3 <<'PYEOF'
|
|
47
|
+
import re
|
|
48
|
+
|
|
49
|
+
try:
|
|
50
|
+
with open('./CLAUDE.md') as f:
|
|
51
|
+
content = f.read()
|
|
52
|
+
except Exception:
|
|
53
|
+
raise SystemExit('claude_md_read_failed')
|
|
54
|
+
|
|
55
|
+
# '## 검증 명령' 섹션 (다음 ## 헤딩 또는 EOF까지)
|
|
56
|
+
m = re.search(r'^##\s*검증\s*명령\s*$([\s\S]*?)(?=^##\s|\Z)', content, re.MULTILINE)
|
|
57
|
+
if not m:
|
|
58
|
+
raise SystemExit('section_missing')
|
|
59
|
+
|
|
60
|
+
section = m.group(1)
|
|
61
|
+
# 백틱 안 명령 추출 — list item(`-`로 시작) 줄에서만
|
|
62
|
+
# (blockquote `>` 메타 텍스트 등 비-list 백틱 오인식 방지)
|
|
63
|
+
cmds = []
|
|
64
|
+
for line in section.split('\n'):
|
|
65
|
+
stripped = line.strip()
|
|
66
|
+
if stripped.startswith('-'):
|
|
67
|
+
cmds.extend(re.findall(r'`([^`]+)`', stripped))
|
|
68
|
+
for c in cmds:
|
|
69
|
+
print(c)
|
|
70
|
+
PYEOF
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
# 섹션 누락 / 추출 실패 케이스
|
|
74
|
+
if [ -z "$COMMANDS" ]; then
|
|
75
|
+
echo "pre-commit-verify: CLAUDE.md '## 검증 명령' 섹션 없거나 명령 없음. commit 차단." >&2
|
|
76
|
+
echo " CLAUDE.md에 '## 검증 명령' 섹션 추가 + 백틱 안에 명령 작성 (예: \`npm run lint\`)." >&2
|
|
77
|
+
exit 2
|
|
78
|
+
fi
|
|
79
|
+
|
|
80
|
+
# 각 명령 실행 — 하나라도 fail → 차단
|
|
81
|
+
FAILED=""
|
|
82
|
+
while IFS= read -r cmd; do
|
|
83
|
+
[ -z "$cmd" ] && continue
|
|
84
|
+
echo "pre-commit-verify: 실행 — $cmd" >&2
|
|
85
|
+
if ! eval "$cmd" >/dev/null 2>&1; then
|
|
86
|
+
FAILED="$FAILED\n - FAIL: $cmd"
|
|
87
|
+
fi
|
|
88
|
+
done <<< "$COMMANDS"
|
|
89
|
+
|
|
90
|
+
if [ -n "$FAILED" ]; then
|
|
91
|
+
echo "pre-commit-verify: 검증 명령 실패 — commit 차단." >&2
|
|
92
|
+
printf "%b\n" "$FAILED" >&2
|
|
93
|
+
echo " /task-dev self-check 또는 /task-close 게이트 통과 후 다시 시도." >&2
|
|
94
|
+
exit 2
|
|
95
|
+
fi
|
|
96
|
+
|
|
97
|
+
exit 0
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"hooks": {
|
|
3
|
+
"PreToolUse": [
|
|
4
|
+
{
|
|
5
|
+
"matcher": "Bash",
|
|
6
|
+
"hooks": [
|
|
7
|
+
{ "type": "command", "command": ".claude/hooks/git-guard.sh" },
|
|
8
|
+
{ "type": "command", "command": ".claude/hooks/pre-commit-verify.sh" }
|
|
9
|
+
]
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
"matcher": "Write|Edit",
|
|
13
|
+
"hooks": [
|
|
14
|
+
{ "type": "command", "command": ".claude/hooks/closed-immutable.sh" }
|
|
15
|
+
]
|
|
16
|
+
}
|
|
17
|
+
]
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: plan 버전 단위 9 기획 문서 작성 — 신규 vX.X/ 또는 기존 카피 후 변경 인터뷰
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# /plan-init
|
|
6
|
+
|
|
7
|
+
## 개요
|
|
8
|
+
|
|
9
|
+
plan 버전(vX.X)마다 호출. `.project/plans/<vX.X>/` 안에 9 기획 문서 생성. 사용자 결정 버전명(v1.0 / alpha / mvp 등 자유).
|
|
10
|
+
|
|
11
|
+
9 기획 문서:
|
|
12
|
+
- PLAN.md (진입 인덱스 + 체크리스트)
|
|
13
|
+
- SERVICE-POLICY.md (백엔드/풀스택)
|
|
14
|
+
- FEATURES.md
|
|
15
|
+
- UX-UI.md (프론트엔드/풀스택)
|
|
16
|
+
- TECH-STACK.md
|
|
17
|
+
- ARCHITECTURE.md
|
|
18
|
+
- DATA-MODEL.md (백엔드/풀스택)
|
|
19
|
+
- API-SPEC.md
|
|
20
|
+
- ROADMAP.md
|
|
21
|
+
|
|
22
|
+
## 호출 시점
|
|
23
|
+
|
|
24
|
+
- `/project-init` 직후 첫 plan 생성 시.
|
|
25
|
+
- 새 plan 버전(예: v1.0 → v1.1) 시작 시.
|
|
26
|
+
- 기존 plan 분기/리비전 시.
|
|
27
|
+
|
|
28
|
+
## 입력 처리
|
|
29
|
+
|
|
30
|
+
인자 = 버전명 (예: `/plan-init v1.0`). 인자 없으면 사용자에게 *"어느 버전?"* 질문.
|
|
31
|
+
|
|
32
|
+
두 분기:
|
|
33
|
+
- **분기 1 (신규)**: `.project/plans/v*/` 없음 → 새 vX.X/ 생성 + 9 문서별 질문 라운드.
|
|
34
|
+
- **분기 2 (이어가기)**: 기존 plans/vY.Y/ 있음 → 가장 최신 카피 → 새 vX.X/ 생성 → 변경 인터뷰 → 변경된 문서만 갱신 → AGENT-GUIDE.md 활성 버전 갱신.
|
|
35
|
+
|
|
36
|
+
## 단계
|
|
37
|
+
|
|
38
|
+
### Step 1 — 분기 판단
|
|
39
|
+
|
|
40
|
+
1. `.project/plans/` 디렉토리 존재 확인.
|
|
41
|
+
2. 하위 vX.X 폴더 목록 추출 (`ls .project/plans/`).
|
|
42
|
+
3. 비어 있음 → 분기 1 (신규).
|
|
43
|
+
4. 1개 이상 있음 → 분기 2 (이어가기).
|
|
44
|
+
|
|
45
|
+
### Step 2 — 버전명 확정
|
|
46
|
+
|
|
47
|
+
1. 인자로 들어왔으면 그대로 사용 (단 기존 충돌 시 사용자 confirm).
|
|
48
|
+
2. 인자 없으면 사용자에게 질문:
|
|
49
|
+
- 분기 1: *"첫 plan 버전명? (예: v1.0, alpha, mvp)"*
|
|
50
|
+
- 분기 2: *"기존 최신은 vY.Y. 새 버전명? (예: vY.Y+1)"*
|
|
51
|
+
3. 형식 강제 X. 사용자 자유.
|
|
52
|
+
|
|
53
|
+
### Step 3 — 분기 1 처리 (신규)
|
|
54
|
+
|
|
55
|
+
1. `.project/plans/<vX.X>/` 디렉토리 생성.
|
|
56
|
+
2. 프로젝트 타입(PROJECT.md에서 추출) 확인:
|
|
57
|
+
- frontend → SERVICE-POLICY/DATA-MODEL 제외 가능 (선택)
|
|
58
|
+
- backend → UX-UI 제외 가능 (선택)
|
|
59
|
+
- fullstack → 9개 모두
|
|
60
|
+
3. 9 문서별 질문 라운드 — *한 문서씩, 핵심 질문 1~3개*:
|
|
61
|
+
- **SERVICE-POLICY.md** (해당 시): 사용자 권한 / 데이터 보존 / 결제 정책 등
|
|
62
|
+
- **FEATURES.md**: 핵심 기능 목록 (기능 단위 — 짧게)
|
|
63
|
+
- **UX-UI.md** (해당 시): 페이지/화면 목록 + 핵심 인터랙션
|
|
64
|
+
- **TECH-STACK.md**: 언어/프레임워크/주요 라이브러리 + 선택 이유
|
|
65
|
+
- **ARCHITECTURE.md**: 시스템 구조 (멀티 리포 / 레이어드 / 마이크로서비스 등)
|
|
66
|
+
- **DATA-MODEL.md** (해당 시): 주요 엔티티 + 관계
|
|
67
|
+
- **API-SPEC.md**: 엔드포인트 목록 + 인증 방식
|
|
68
|
+
- **ROADMAP.md**: 마일스톤 + 시기 + 우선순위
|
|
69
|
+
4. 받은 답 기반으로 각 문서 작성.
|
|
70
|
+
5. 마지막에 **PLAN.md** 작성 — 9 문서 인덱스 + 체크리스트.
|
|
71
|
+
6. **`.project/AGENT-GUIDE.md`의 활성 plan 버전 vX.X로 갱신** (신규도 동일 — 분기 2와 일관).
|
|
72
|
+
|
|
73
|
+
### Step 4 — 분기 2 처리 (이어가기)
|
|
74
|
+
|
|
75
|
+
1. 가장 최신 vY.Y/ 디렉토리 전체 카피 → vX.X/.
|
|
76
|
+
2. 변경 인터뷰 — 사용자에게 *"이번 버전에서 어느 문서가 변경되나? (다중 선택)"*:
|
|
77
|
+
- SERVICE-POLICY / FEATURES / UX-UI / TECH-STACK / ARCHITECTURE / DATA-MODEL / API-SPEC / ROADMAP
|
|
78
|
+
3. 선택된 문서별 변경 사항 인터뷰 — *"이 문서에서 무엇이 달라지나?"*.
|
|
79
|
+
4. 받은 답으로 해당 문서만 수정. 나머지는 카피 그대로.
|
|
80
|
+
5. PLAN.md 갱신 — 변경 문서 표시.
|
|
81
|
+
6. **`.project/AGENT-GUIDE.md`의 활성 plan 버전 vX.X로 갱신**.
|
|
82
|
+
|
|
83
|
+
### Step 5 — `tasks/<vX.X>/` 디렉토리 준비
|
|
84
|
+
|
|
85
|
+
1. `.project/tasks/<vX.X>/` 디렉토리 생성 (빈 폴더).
|
|
86
|
+
2. `.project/tasks/<vX.X>/spec-diffs/`, `.project/tasks/<vX.X>/screenshots/` 빈 폴더 미리 생성.
|
|
87
|
+
|
|
88
|
+
### Step 6 — `PLAN.md` 작성/갱신
|
|
89
|
+
|
|
90
|
+
```markdown
|
|
91
|
+
# PLAN <vX.X>
|
|
92
|
+
|
|
93
|
+
## 9 기획 문서 인덱스
|
|
94
|
+
|
|
95
|
+
- [x] SERVICE-POLICY.md (해당 / 미해당)
|
|
96
|
+
- [x] FEATURES.md
|
|
97
|
+
- [x] UX-UI.md (해당 / 미해당)
|
|
98
|
+
- [x] TECH-STACK.md
|
|
99
|
+
- [x] ARCHITECTURE.md
|
|
100
|
+
- [x] DATA-MODEL.md (해당 / 미해당)
|
|
101
|
+
- [x] API-SPEC.md
|
|
102
|
+
- [x] ROADMAP.md
|
|
103
|
+
|
|
104
|
+
## 변경 이력
|
|
105
|
+
| 버전 | 날짜 | 변경 문서 | 요약 |
|
|
106
|
+
|------|------|----------|------|
|
|
107
|
+
| <vX.X> | <YYYY-MM-DD> | <목록 또는 "전체 (신규)"> | <요약> |
|
|
108
|
+
|
|
109
|
+
## 활성 task 버전
|
|
110
|
+
- `.project/tasks/<vX.X>/` 사용
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Step 7 — 결과 보고
|
|
114
|
+
|
|
115
|
+
작성/갱신된 문서 목록 + 다음 단계 안내:
|
|
116
|
+
- *"<vX.X>/ 9 기획 문서 작성 완료. AGENT-GUIDE.md 활성 버전 <vX.X>로 갱신. 다음은 `/task-init`으로 첫 task 생성."*
|
|
117
|
+
|
|
118
|
+
**결과 commit 흐름** (GIT_RULE 정합):
|
|
119
|
+
- dev 직접 commit *금지* (git-guard.sh 차단). 두 가지 default 흐름:
|
|
120
|
+
1. **첫 task에 묶기 (권장)**: 분기 1(신규)에서 `/project-init` 직후 본 스킬 호출이면 `/project-init` 산출물과 같은 작업 브랜치(보통 TASK-001 부트스트랩 chore)에 함께 commit. 분기 2(이어가기)면 새 task 브랜치 또는 임시 docs 브랜치에서.
|
|
121
|
+
2. **임시 docs 브랜치**: `git checkout -b docs/{개발자}_plan-{vX.X}` 후 commit → dev에 `--no-ff` 머지. 다음 task 생성 *전*에 plan 산출물을 깔끔히 박고 싶을 때.
|
|
122
|
+
|
|
123
|
+
## 도구 가이드
|
|
124
|
+
|
|
125
|
+
- **Read**: PROJECT.md / 기존 plans/vY.Y/ 정독
|
|
126
|
+
- **Bash**: `ls .project/plans/`, `cp -r plans/vY.Y plans/vX.X`, `mkdir -p plans/<vX.X> tasks/<vX.X>/{spec-diffs,screenshots}`
|
|
127
|
+
- **Write/Edit**: 9 기획 문서 작성/갱신
|
|
128
|
+
- **AskUserQuestion**: 9 문서별 핵심 질문 + 변경 인터뷰
|
|
129
|
+
|
|
130
|
+
## 주의사항
|
|
131
|
+
|
|
132
|
+
- 9 문서 *전부 강제 X*. 프로젝트 타입에 따라 일부 제외 가능 (frontend → SERVICE-POLICY/DATA-MODEL 미해당 등).
|
|
133
|
+
- 분기 2(이어가기)에서 *전체 재작성 금지*. 변경된 문서만 갱신.
|
|
134
|
+
- 질문 라운드는 *한 번에 한 문서씩*. 한꺼번에 9 문서 질문 X.
|
|
135
|
+
- 답 받기 전 자동 추정 진행 X. 단 PROJECT.md / 기존 plans 정보로 *제안*은 OK (사용자 confirm 후).
|
|
136
|
+
- AGENT-GUIDE.md 활성 버전 갱신 *반드시*. 누락 시 메인 세션이 옛 plan 보고 헤맴.
|
|
137
|
+
|
|
138
|
+
## 상태 전이
|
|
139
|
+
|
|
140
|
+
해당 없음 (plan 레벨 — task 상태 X).
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: taskery 도입 직후 1회성 — PROJECT.md / AGENT-GUIDE.md / LINKED-REPOS.md / .env 빈 골격 생성
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# /project-init
|
|
6
|
+
|
|
7
|
+
## 개요
|
|
8
|
+
|
|
9
|
+
taskery 도입 직후 **1회성**으로 호출. 사용자 또는 동료가 새 리포에 npx로 taskery 세팅 직후 처음 부르는 스킬. `.project/` 영역의 사람용/메인용 진입 문서 골격을 만든다.
|
|
10
|
+
|
|
11
|
+
## 호출 시점
|
|
12
|
+
|
|
13
|
+
- `npx @angar2/taskery init` 또는 `npx -p @angar2/taskery create-taskery <name>` 직후 첫 메인 세션.
|
|
14
|
+
- 또는 기존 리포에 taskery 사후 도입 후 첫 세션.
|
|
15
|
+
|
|
16
|
+
## 입력 처리
|
|
17
|
+
|
|
18
|
+
인자 없음. 두 분기:
|
|
19
|
+
- **빈 프로젝트**: 사용자에게 질문 라운드 (프로젝트명/타입/멀티리포 여부 등).
|
|
20
|
+
- **기존 코드 있음**: 코드베이스 분석 → 메타 추정 + 사용자 confirm.
|
|
21
|
+
|
|
22
|
+
`.project/PROJECT.md` 이미 존재 시 → 경고 + confirm. *덮어쓰기 default X*.
|
|
23
|
+
|
|
24
|
+
## 단계
|
|
25
|
+
|
|
26
|
+
### Step 1 — 환경 점검 + 분기 판단
|
|
27
|
+
|
|
28
|
+
1. `.project/PROJECT.md` 존재 확인.
|
|
29
|
+
- 존재 시: 사용자에게 *"이미 있는데 덮어쓸까? (y/N)"* 묻고 N이면 종료.
|
|
30
|
+
2. `package.json`, `Cargo.toml`, `go.mod`, `pyproject.toml`, `pom.xml` 등 *기존 프로젝트 마커* 확인.
|
|
31
|
+
- 있음 → "기존 코드 분석" 분기.
|
|
32
|
+
- 없음 → "빈 프로젝트 인터뷰" 분기.
|
|
33
|
+
|
|
34
|
+
### Step 2 — 메타 수집 (분기별)
|
|
35
|
+
|
|
36
|
+
**기존 코드 분석 분기**:
|
|
37
|
+
1. README.md / package.json / 디렉토리 구조 정독.
|
|
38
|
+
2. 프로젝트 추정값 작성 (이름 / 타입 / 도메인).
|
|
39
|
+
3. 사용자에게 *"이렇게 이해했는데 맞아?"* 한 번 confirm.
|
|
40
|
+
|
|
41
|
+
**빈 프로젝트 인터뷰 분기**:
|
|
42
|
+
1. 질문 라운드 — 한 번에 한 질문씩, 사용자 답 받고 다음:
|
|
43
|
+
- Q1: 프로젝트 이름?
|
|
44
|
+
- Q2: 타입? (frontend / backend / fullstack / cli / library / other)
|
|
45
|
+
- Q3: 도메인/한 줄 비전?
|
|
46
|
+
- Q4: 단일 리포 / 멀티 리포?
|
|
47
|
+
- Q5: (멀티 리포 시) 연결 리포 목록 + 각 역할?
|
|
48
|
+
|
|
49
|
+
### Step 3 — `.project/PROJECT.md` 작성
|
|
50
|
+
|
|
51
|
+
사람용 진입 문서. 개발자가 *"이 프로젝트 뭐 하는 거야?"* 알 수 있게.
|
|
52
|
+
|
|
53
|
+
```markdown
|
|
54
|
+
# <프로젝트명>
|
|
55
|
+
|
|
56
|
+
## 개요
|
|
57
|
+
<한 줄 비전>
|
|
58
|
+
|
|
59
|
+
## 도메인
|
|
60
|
+
<예: 이커머스 / SaaS / 개인 블로그 등>
|
|
61
|
+
|
|
62
|
+
## 타입
|
|
63
|
+
<frontend / backend / fullstack / ...>
|
|
64
|
+
|
|
65
|
+
## 멀티리포 여부
|
|
66
|
+
<단일 / 멀티 — 멀티면 LINKED-REPOS.md 참조>
|
|
67
|
+
|
|
68
|
+
## 시작
|
|
69
|
+
- 의존성 설치: `<명령>`
|
|
70
|
+
- 개발 서버: `<명령>`
|
|
71
|
+
- 빌드: `<명령>`
|
|
72
|
+
- 테스트: `<명령>`
|
|
73
|
+
|
|
74
|
+
## 디렉토리 구조
|
|
75
|
+
- `src/` — 소스 코드
|
|
76
|
+
- `.project/` — taskery 메타 영역
|
|
77
|
+
- ...
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Step 4 — `.project/AGENT-GUIDE.md` 작성
|
|
81
|
+
|
|
82
|
+
메인 세션 진입 가이드. 새 메인 세션이 부르는 *"읽고 시작"* 문서.
|
|
83
|
+
|
|
84
|
+
```markdown
|
|
85
|
+
# AGENT-GUIDE.md
|
|
86
|
+
|
|
87
|
+
## 활성 plan 버전
|
|
88
|
+
<예: v1.0 — `.project/plans/v1.0/` 참조>
|
|
89
|
+
|
|
90
|
+
## 메인이 매 세션 시작 시 읽을 것
|
|
91
|
+
1. `CLAUDE.md` — 프로젝트 메타 + 검증 명령 + 룰 참조
|
|
92
|
+
2. `.project/PROJECT.md` — 프로젝트 개요
|
|
93
|
+
3. `.project/plans/<활성버전>/PLAN.md` — 활성 plan 진입 (이게 9 기획 문서 인덱스)
|
|
94
|
+
4. `.project/AGENT-GUIDE.md` — 본 파일 (그대로)
|
|
95
|
+
|
|
96
|
+
## 작업 흐름
|
|
97
|
+
- task 시작: `/task-init` 또는 `/task-plan`
|
|
98
|
+
- task 진행: `/task-dev` → `/task-test` → `/task-close`
|
|
99
|
+
- 회고: `/refine` (5 task마다 또는 사용자 호출)
|
|
100
|
+
|
|
101
|
+
## 폴더 구조
|
|
102
|
+
- `.project/rules/` — 코어 룰 (TASK_DOC_RULE / GIT_RULE)
|
|
103
|
+
- `.project/plans/<vX.X>/` — 9 기획 문서
|
|
104
|
+
- `.project/tasks/<vX.X>/` — task 문서
|
|
105
|
+
- `.project/flows/` — 도메인 흐름
|
|
106
|
+
- `.project/shared/` — 멀티리포 메시지
|
|
107
|
+
- `.project/changelog/` — 월별 변경 이력
|
|
108
|
+
- `.project/FRICTION_LOG.md` — 짜증 데이터
|
|
109
|
+
|
|
110
|
+
## 멀티리포
|
|
111
|
+
<단일 리포면 "단일 리포. LINKED-REPOS.md 빈 템플릿."
|
|
112
|
+
멀티 리포면 "LINKED-REPOS.md 참조">
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Step 5 — `.project/LINKED-REPOS.md` 작성
|
|
116
|
+
|
|
117
|
+
```markdown
|
|
118
|
+
# LINKED-REPOS.md
|
|
119
|
+
|
|
120
|
+
## 멀티리포 여부
|
|
121
|
+
<단일 / 멀티>
|
|
122
|
+
|
|
123
|
+
## 연결 리포 목록
|
|
124
|
+
<단일 리포면 "해당 없음">
|
|
125
|
+
<멀티 리포면 표로 정리>
|
|
126
|
+
|
|
127
|
+
| 리포명 | 역할 | 경로 (.env 변수명) |
|
|
128
|
+
|--------|------|------|
|
|
129
|
+
| ... | ... | ... |
|
|
130
|
+
|
|
131
|
+
## 세션 간 통신
|
|
132
|
+
- 송신: `.project/shared/sent/<filename>.md` 작성
|
|
133
|
+
- 수신: `.project/shared/received/<filename>.md` 정독
|
|
134
|
+
- 처리 완료: `sent/completed/` 또는 `received/completed/`로 이동
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### Step 6 — `.project/.env` 빈 템플릿
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
# 멀티리포 환경 변수 (gitignore 대상)
|
|
141
|
+
# 예시:
|
|
142
|
+
# REPO_FRONTEND_PATH=/Users/.../my-app-frontend
|
|
143
|
+
# REPO_BACKEND_PATH=/Users/.../my-app-backend
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### Step 7 — `.project/` 빈 골격 점검
|
|
147
|
+
|
|
148
|
+
`npx @angar2/taskery init`이 이미 다음 빈 골격 폴더 생성:
|
|
149
|
+
- `.project/changelog/` (`.gitkeep`)
|
|
150
|
+
- `.project/flows/` (`.gitkeep`)
|
|
151
|
+
- `.project/plans/` (`.gitkeep` — `/plan-init`이 `vX.X/` 하위 작성)
|
|
152
|
+
- `.project/tasks/` (`.gitkeep` — `/task-init`이 `vX.X/<NNN>_<slug>.md` 작성)
|
|
153
|
+
- `.project/shared/{sent,received}/completed/` (`.gitkeep`)
|
|
154
|
+
- `.project/FRICTION_LOG.md` (빈 템플릿)
|
|
155
|
+
- `.project/rules/{TASK_DOC_RULE,GIT_RULE}.md` (코어 룰)
|
|
156
|
+
|
|
157
|
+
→ `/project-init`은 폴더 생성 X. 누락 시(`init` 안 거치고 수동 셋업한 경우)에만 `mkdir -p` 실행.
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
# 누락 시에만:
|
|
161
|
+
mkdir -p .project/{changelog,flows,plans,tasks}
|
|
162
|
+
mkdir -p .project/shared/sent/completed .project/shared/received/completed
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
`.project/FRICTION_LOG.md`도 `init`이 카피한 빈 템플릿 그대로 사용. **이미 있으면 덮어쓰기 X** — 사용자 데이터 보호.
|
|
166
|
+
|
|
167
|
+
### Step 8 — 결과 보고
|
|
168
|
+
|
|
169
|
+
작성된 파일 목록 + 다음 단계 안내:
|
|
170
|
+
- *"PROJECT.md / AGENT-GUIDE.md / LINKED-REPOS.md / .env 생성. (FRICTION_LOG.md / 빈 골격 폴더는 npx init이 이미 카피한 것 그대로). 다음은 `/plan-init <버전명>`으로 9 기획 문서 작성."*
|
|
171
|
+
|
|
172
|
+
**결과 commit 흐름** (GIT_RULE 정합):
|
|
173
|
+
- dev 직접 commit *금지* (git-guard.sh 차단). 두 가지 default 흐름:
|
|
174
|
+
1. **첫 task에 묶기 (권장)**: `/plan-init` 끝나고 첫 `/task-init` (보통 TASK-001 부트스트랩 chore)으로 만든 작업 브랜치에서 init 산출물(PROJECT/AGENT-GUIDE/LINKED-REPOS/.env)도 함께 commit. task-close 단계의 "태스크 문서 커밋"에 자연스럽게 묶임.
|
|
175
|
+
2. **임시 docs 브랜치**: `git checkout -b docs/{개발자}_init-bootstrap` 후 commit → dev에 `--no-ff` 머지. 첫 task 생성 *전*에 init 결과를 깔끔히 박고 싶을 때.
|
|
176
|
+
|
|
177
|
+
## 도구 가이드
|
|
178
|
+
|
|
179
|
+
- **Read**: 기존 README / package.json 정독
|
|
180
|
+
- **Write**: 신규 .md 파일 생성
|
|
181
|
+
- **Bash**: `mkdir -p .project/changelog .project/flows`, `ls`, `cat package.json | head -20`
|
|
182
|
+
- **AskUserQuestion**: 인터뷰 분기 시 질문 라운드 (한 번에 한 질문씩)
|
|
183
|
+
|
|
184
|
+
## 주의사항
|
|
185
|
+
|
|
186
|
+
- *덮어쓰기 default 금지* — 이미 PROJECT.md 있으면 confirm.
|
|
187
|
+
- 인터뷰 분기에서 *자동 추정 진행 금지*. 빈 프로젝트면 사용자 답 받고 작성.
|
|
188
|
+
- 한 번에 너무 많은 질문 X. 사용자 답 받고 다음 질문.
|
|
189
|
+
- 이 스킬은 **1회성**. 두 번째 호출은 의미 X (덮어쓰기 confirm 거치게 됨).
|
|
190
|
+
|
|
191
|
+
## 상태 전이
|
|
192
|
+
|
|
193
|
+
해당 없음 (project 레벨 — task 상태 X).
|