@kmgeon/taskflow 0.1.3
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 +374 -0
- package/bin/task-mcp.mjs +19 -0
- package/bin/task.mjs +19 -0
- package/docs/clean-code.md +29 -0
- package/docs/git.md +36 -0
- package/docs/guideline.md +25 -0
- package/docs/security.md +32 -0
- package/docs/step-by-step.md +29 -0
- package/docs/superpowers/specs/2026-03-21-cli-advisor-design.md +383 -0
- package/docs/superpowers/specs/2026-03-21-init-redesign-design.md +429 -0
- package/docs/superpowers/specs/2026-03-21-skill-architecture-design.md +362 -0
- package/docs/superpowers/specs/2026-03-23-t-create-task-run-design.md +40 -0
- package/docs/superpowers/specs/2026-03-23-task-run-design.md +44 -0
- package/docs/tdd.md +41 -0
- package/package.json +114 -0
- package/src/app/(protected)/dashboard/page.tsx +7 -0
- package/src/app/(protected)/layout.tsx +10 -0
- package/src/app/api/[[...hono]]/route.ts +13 -0
- package/src/app/example/page.tsx +11 -0
- package/src/app/favicon.ico +0 -0
- package/src/app/globals.css +168 -0
- package/src/app/layout.tsx +35 -0
- package/src/app/page.tsx +5 -0
- package/src/app/providers.tsx +57 -0
- package/src/backend/config/index.ts +36 -0
- package/src/backend/hono/app.ts +32 -0
- package/src/backend/hono/context.ts +38 -0
- package/src/backend/http/response.ts +64 -0
- package/src/backend/middleware/context.ts +23 -0
- package/src/backend/middleware/error.ts +31 -0
- package/src/backend/middleware/supabase.ts +23 -0
- package/src/backend/supabase/client.ts +17 -0
- package/src/cli/commands/__tests__/task-commands.test.ts +170 -0
- package/src/cli/commands/advisor.ts +45 -0
- package/src/cli/commands/ask.ts +50 -0
- package/src/cli/commands/board.ts +72 -0
- package/src/cli/commands/init.ts +184 -0
- package/src/cli/commands/list.ts +138 -0
- package/src/cli/commands/run.ts +143 -0
- package/src/cli/commands/set-status.ts +50 -0
- package/src/cli/commands/show.ts +28 -0
- package/src/cli/commands/tree.ts +72 -0
- package/src/cli/index.ts +38 -0
- package/src/cli/lib/__tests__/formatter.test.ts +123 -0
- package/src/cli/lib/error-boundary.test.ts +135 -0
- package/src/cli/lib/error-boundary.ts +70 -0
- package/src/cli/lib/formatter.ts +764 -0
- package/src/cli/lib/trd.ts +33 -0
- package/src/cli/lib/validate.test.ts +89 -0
- package/src/cli/lib/validate.ts +43 -0
- package/src/cli/prompts/task-run.md +25 -0
- package/src/components/layout/AppLayout.tsx +15 -0
- package/src/components/layout/Sidebar.tsx +124 -0
- package/src/components/ui/accordion.tsx +58 -0
- package/src/components/ui/avatar.tsx +50 -0
- package/src/components/ui/badge.tsx +36 -0
- package/src/components/ui/button.tsx +56 -0
- package/src/components/ui/card.tsx +79 -0
- package/src/components/ui/checkbox.tsx +30 -0
- package/src/components/ui/dialog.tsx +122 -0
- package/src/components/ui/dropdown-menu.tsx +200 -0
- package/src/components/ui/file-upload.tsx +50 -0
- package/src/components/ui/form.tsx +179 -0
- package/src/components/ui/input.tsx +25 -0
- package/src/components/ui/label.tsx +26 -0
- package/src/components/ui/scroll-area.tsx +48 -0
- package/src/components/ui/select.tsx +160 -0
- package/src/components/ui/separator.tsx +31 -0
- package/src/components/ui/sheet.tsx +140 -0
- package/src/components/ui/textarea.tsx +22 -0
- package/src/components/ui/toast.tsx +129 -0
- package/src/components/ui/toaster.tsx +35 -0
- package/src/core/ai/claude-client.ts +79 -0
- package/src/core/claude-runner/flag-builder.ts +57 -0
- package/src/core/claude-runner/index.ts +2 -0
- package/src/core/claude-runner/spawner.ts +86 -0
- package/src/core/prd/__tests__/auto-analyzer.test.ts +35 -0
- package/src/core/prd/__tests__/generator.test.ts +26 -0
- package/src/core/prd/__tests__/scanner.test.ts +35 -0
- package/src/core/prd/auto-analyzer.ts +9 -0
- package/src/core/prd/generator.ts +8 -0
- package/src/core/prd/scanner.ts +117 -0
- package/src/core/project/__tests__/claude-setup.test.ts +133 -0
- package/src/core/project/__tests__/config.test.ts +30 -0
- package/src/core/project/__tests__/init.test.ts +37 -0
- package/src/core/project/__tests__/skill-setup.test.ts +62 -0
- package/src/core/project/claude-setup.ts +224 -0
- package/src/core/project/config.ts +34 -0
- package/src/core/project/docs-setup.ts +26 -0
- package/src/core/project/docs-templates.ts +205 -0
- package/src/core/project/init.ts +40 -0
- package/src/core/project/skill-setup.ts +32 -0
- package/src/core/project/skill-templates.ts +277 -0
- package/src/core/task/index.ts +16 -0
- package/src/core/types.ts +58 -0
- package/src/features/example/backend/error.ts +9 -0
- package/src/features/example/backend/route.ts +52 -0
- package/src/features/example/backend/schema.ts +25 -0
- package/src/features/example/backend/service.ts +73 -0
- package/src/features/example/components/example-status.test.tsx +97 -0
- package/src/features/example/components/example-status.tsx +160 -0
- package/src/features/example/hooks/useExampleQuery.ts +23 -0
- package/src/features/example/lib/dto.test.ts +57 -0
- package/src/features/example/lib/dto.ts +5 -0
- package/src/features/kanban/backend/__tests__/sse-broadcaster.test.ts +137 -0
- package/src/features/kanban/backend/__tests__/sse-event-format.test.ts +55 -0
- package/src/features/kanban/backend/route.ts +55 -0
- package/src/features/kanban/backend/sse-broadcaster.ts +142 -0
- package/src/features/kanban/backend/sse-route.ts +43 -0
- package/src/features/kanban/components/KanbanBoard.tsx +105 -0
- package/src/features/kanban/components/KanbanColumn.tsx +51 -0
- package/src/features/kanban/components/KanbanError.tsx +29 -0
- package/src/features/kanban/components/KanbanSkeleton.tsx +46 -0
- package/src/features/kanban/components/ProgressCard.tsx +42 -0
- package/src/features/kanban/components/TaskCard.tsx +76 -0
- package/src/features/kanban/components/__tests__/kanban-components.test.tsx +86 -0
- package/src/features/kanban/hooks/useTaskSse.ts +66 -0
- package/src/features/kanban/hooks/useTasksQuery.ts +52 -0
- package/src/features/kanban/lib/__tests__/kanban-utils.test.ts +97 -0
- package/src/features/kanban/lib/kanban-utils.ts +37 -0
- package/src/features/taskflow/constants.ts +54 -0
- package/src/features/taskflow/index.ts +27 -0
- package/src/features/taskflow/lib/__tests__/filter.test.ts +89 -0
- package/src/features/taskflow/lib/__tests__/graph.test.ts +247 -0
- package/src/features/taskflow/lib/__tests__/repository.test.ts +233 -0
- package/src/features/taskflow/lib/__tests__/serializer.test.ts +98 -0
- package/src/features/taskflow/lib/advisor/__tests__/advisor-integration.test.ts +98 -0
- package/src/features/taskflow/lib/advisor/ai-advisor.test.ts +40 -0
- package/src/features/taskflow/lib/advisor/ai-advisor.ts +20 -0
- package/src/features/taskflow/lib/advisor/context-builder.test.ts +73 -0
- package/src/features/taskflow/lib/advisor/context-builder.ts +151 -0
- package/src/features/taskflow/lib/advisor/db.test.ts +106 -0
- package/src/features/taskflow/lib/advisor/db.ts +185 -0
- package/src/features/taskflow/lib/advisor/local-summary.test.ts +53 -0
- package/src/features/taskflow/lib/advisor/local-summary.ts +72 -0
- package/src/features/taskflow/lib/advisor/prompts.ts +86 -0
- package/src/features/taskflow/lib/filter.ts +54 -0
- package/src/features/taskflow/lib/fs-utils.ts +50 -0
- package/src/features/taskflow/lib/graph.ts +148 -0
- package/src/features/taskflow/lib/index-builder.ts +42 -0
- package/src/features/taskflow/lib/repository.ts +168 -0
- package/src/features/taskflow/lib/serializer.ts +62 -0
- package/src/features/taskflow/lib/watcher.ts +40 -0
- package/src/features/taskflow/types.ts +71 -0
- package/src/hooks/use-toast.ts +194 -0
- package/src/lib/remote/api-client.ts +40 -0
- package/src/lib/supabase/client.ts +8 -0
- package/src/lib/supabase/server.ts +46 -0
- package/src/lib/supabase/types.ts +3 -0
- package/src/lib/utils.ts +6 -0
- package/src/mcp/index.ts +7 -0
- package/src/mcp/server.ts +21 -0
- package/src/mcp/tools/brainstorm.ts +48 -0
- package/src/mcp/tools/prd.ts +71 -0
- package/src/mcp/tools/project.ts +39 -0
- package/src/mcp/tools/task-status.ts +40 -0
- package/src/mcp/tools/task.ts +82 -0
- package/src/mcp/util.ts +6 -0
|
@@ -0,0 +1,429 @@
|
|
|
1
|
+
# TaskFlow Init 재설계 — MCP-First 아키텍처
|
|
2
|
+
|
|
3
|
+
## 1. 개요
|
|
4
|
+
|
|
5
|
+
`task init` 명령어를 확장하여 프로젝트 초기화, Claude Code 연동, PRD 생성을 하나의 플로우로 통합한다. 동시에 전체 CLI 기능을 MCP 서버로 노출하여 Claude Code에서 직접 TaskFlow를 사용할 수 있게 한다.
|
|
6
|
+
|
|
7
|
+
### 핵심 결정 사항
|
|
8
|
+
|
|
9
|
+
| 항목 | 결정 |
|
|
10
|
+
|------|------|
|
|
11
|
+
| 아키텍처 | MCP-First — core 레이어를 CLI, MCP, Hono가 공유 |
|
|
12
|
+
| MCP 역할 범위 | 전체 CLI 기능 노출 (17개 도구) |
|
|
13
|
+
| 실행 환경 | 터미널 CLI + Claude Code MCP 둘 다 지원 |
|
|
14
|
+
| 브레인스토밍 | CLI에서 AI 멀티턴 대화 + Claude Code에서 brainstorm 스킬 |
|
|
15
|
+
| PRD 재생성 | `task init` 재실행 시 .taskflow 존재 여부로 분기 |
|
|
16
|
+
| MCP 전송 | stdio 전용 (SSE는 chokidar 파일 감시로 자동 처리) |
|
|
17
|
+
| CLAUDE.md | PRD 결과를 반영한 동적 생성 |
|
|
18
|
+
| MCP 라이브러리 | `@modelcontextprotocol/sdk` (공식 SDK) |
|
|
19
|
+
| AI 제공자 | Claude Max 전용 — API 키 불필요, 다른 옵션 없음 |
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## 2. Core 레이어 구조
|
|
24
|
+
|
|
25
|
+
비즈니스 로직을 `src/core/`로 통합한다. CLI(inquirer, ora, chalk) 의존성 없는 순수 로직만 포함.
|
|
26
|
+
|
|
27
|
+
```
|
|
28
|
+
src/core/
|
|
29
|
+
├── project/
|
|
30
|
+
│ ├── init.ts # 프로젝트 초기화 (폴더 생성, config 생성)
|
|
31
|
+
│ ├── config.ts # config.json 읽기/쓰기
|
|
32
|
+
│ └── claude-setup.ts # CLAUDE.md, .mcp.json 생성
|
|
33
|
+
│
|
|
34
|
+
├── prd/
|
|
35
|
+
│ ├── generator.ts # 프로젝트 PRD 마크다운 빌드
|
|
36
|
+
│ ├── feature-generator.ts # 기능별 PRD 마크다운 빌드
|
|
37
|
+
│ ├── auto-analyzer.ts # 코드 스캔 → AI PRD 생성
|
|
38
|
+
│ └── parser.ts # PRD → 태스크 파싱
|
|
39
|
+
│
|
|
40
|
+
├── task/
|
|
41
|
+
│ ├── repository.ts # CRUD (features/taskflow/lib/에서 이동)
|
|
42
|
+
│ ├── serializer.ts # 마크다운 ↔ Task 변환
|
|
43
|
+
│ ├── filter.ts # 필터/정렬
|
|
44
|
+
│ ├── graph.ts # 의존성 그래프
|
|
45
|
+
│ └── recommender.ts # next 추천 로직
|
|
46
|
+
│
|
|
47
|
+
├── ai/
|
|
48
|
+
│ ├── client.ts # Claude Agent SDK 래퍼 (query 호출, Claude Max 전용)
|
|
49
|
+
│ └── refine-engine.ts # refine 분석 엔진
|
|
50
|
+
│
|
|
51
|
+
└── types.ts # 공유 타입 정의 (PrdResult 등 중복 타입 통합)
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### 설계 원칙
|
|
55
|
+
|
|
56
|
+
- core 안의 모든 함수는 순수 로직 — CLI UI 의존성 없음
|
|
57
|
+
- 입출력은 인터페이스로 추상화
|
|
58
|
+
- 기존 `features/taskflow/lib/repository.ts`의 `projectRoot: string` 파라미터 패턴 유지 — `process.cwd()`를 내부에서 사용하지 않음
|
|
59
|
+
- 기존 `PrdResult`, `FeaturePrdResult` 타입 중복 (`auto.ts`, `interactive.ts`, `feature-prd-flow.ts`) → `core/types.ts`로 통합
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## 3. MCP 서버
|
|
64
|
+
|
|
65
|
+
`@modelcontextprotocol/sdk` 기반 stdio MCP 서버.
|
|
66
|
+
|
|
67
|
+
### 구조
|
|
68
|
+
|
|
69
|
+
```
|
|
70
|
+
src/mcp/
|
|
71
|
+
├── index.ts # MCP 서버 진입점 (stdio transport)
|
|
72
|
+
├── server.ts # Server 인스턴스 생성 + 도구 등록
|
|
73
|
+
└── tools/
|
|
74
|
+
├── project.ts # initialize_project, generate_claude_md
|
|
75
|
+
├── prd.ts # generate_prd, brainstorm_prd, auto_analyze_prd, generate_feature_prd (brainstorm_prd는 단일 도구로 시작/계속 분기)
|
|
76
|
+
├── task.ts # list_tasks, read_task, create_task, update_task, delete_task
|
|
77
|
+
├── task-status.ts # set_task_status, get_next_task
|
|
78
|
+
├── parse.ts # parse_prd
|
|
79
|
+
├── brainstorm.ts # brainstorm_task, expand_subtasks
|
|
80
|
+
└── refine.ts # refine_tasks
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### MCP 도구 목록 (17개)
|
|
84
|
+
|
|
85
|
+
| 도구 | 설명 | core 함수 |
|
|
86
|
+
|------|------|-----------|
|
|
87
|
+
| `initialize_project` | 프로젝트 초기화 | `core/project/init.ts` |
|
|
88
|
+
| `generate_claude_md` | CLAUDE.md 동적 생성/갱신 | `core/project/claude-setup.ts` |
|
|
89
|
+
| `generate_prd` | PRD 생성 | `core/prd/generator.ts` |
|
|
90
|
+
| `brainstorm_prd` | AI 브레인스토밍 멀티턴 대화 | `core/prd/generator.ts` (brainstorm 함수) |
|
|
91
|
+
| `auto_analyze_prd` | 코드 스캔 → PRD 자동 생성 | `core/prd/auto-analyzer.ts` |
|
|
92
|
+
| `generate_feature_prd` | 기능별 PRD 생성 | `core/prd/feature-generator.ts` |
|
|
93
|
+
| `parse_prd` | PRD → 태스크 분해 | `core/prd/parser.ts` |
|
|
94
|
+
| `list_tasks` | 태스크 목록 (필터/정렬) | `core/task/repository.ts` |
|
|
95
|
+
| `read_task` | 태스크 상세 조회 | `core/task/repository.ts` |
|
|
96
|
+
| `create_task` | 태스크 생성 | `core/task/repository.ts` |
|
|
97
|
+
| `update_task` | 태스크 수정 | `core/task/repository.ts` |
|
|
98
|
+
| `delete_task` | 태스크 삭제 | `core/task/repository.ts` |
|
|
99
|
+
| `set_task_status` | 상태 변경 | `core/task/repository.ts` |
|
|
100
|
+
| `get_next_task` | 다음 태스크 추천 | `core/task/recommender.ts` |
|
|
101
|
+
| `brainstorm_task` | 태스크 서브태스크 분해 | `core/ai/client.ts` (brainstormTask 함수) |
|
|
102
|
+
| `expand_subtasks` | 분해 결과 → 파일 생성 | `core/task/repository.ts` |
|
|
103
|
+
| `refine_tasks` | 변경사항 영향도 분석 | `core/ai/refine-engine.ts` |
|
|
104
|
+
|
|
105
|
+
### MCP 도구 `projectRoot` 처리
|
|
106
|
+
|
|
107
|
+
모든 MCP 도구는 `projectRoot` 파라미터를 **선택적으로** 받는다. 생략 시 MCP 서버 프로세스의 `process.cwd()`를 기본값으로 사용한다. 이를 공통 유틸 `resolveProjectRoot(input?: string)`로 처리한다.
|
|
108
|
+
|
|
109
|
+
### 주요 MCP 도구 입력 스키마
|
|
110
|
+
|
|
111
|
+
**`brainstorm_prd`** — 단일 도구로 세션 시작과 계속을 모두 처리:
|
|
112
|
+
```typescript
|
|
113
|
+
{
|
|
114
|
+
projectRoot?: string; // 프로젝트 경로 (선택)
|
|
115
|
+
session?: BrainstormSession; // 기존 세션 (없으면 새 세션 시작)
|
|
116
|
+
userMessage?: string; // 사용자 응답 (세션 계속 시 필수)
|
|
117
|
+
projectContext?: string; // 프로젝트 컨텍스트 (새 세션 시작 시 선택)
|
|
118
|
+
}
|
|
119
|
+
// session 없음 → startBrainstorm() 호출
|
|
120
|
+
// session 있음 + userMessage → continueBrainstorm() 호출
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
**`initialize_project`:**
|
|
124
|
+
```typescript
|
|
125
|
+
{ projectRoot?: string; projectName?: string; }
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
**`list_tasks`:**
|
|
129
|
+
```typescript
|
|
130
|
+
{ projectRoot?: string; status?: string; priority?: string; sortBy?: string; }
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
**`set_task_status`:**
|
|
134
|
+
```typescript
|
|
135
|
+
{ projectRoot?: string; taskId: string; status: string; }
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
**`generate_feature_prd`:**
|
|
139
|
+
```typescript
|
|
140
|
+
{ projectRoot?: string; featureName: string; goal: string; parentPrd?: string; }
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
**`brainstorm_task`:**
|
|
144
|
+
```typescript
|
|
145
|
+
{ projectRoot?: string; taskId: string; depth?: number; }
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
**`refine_tasks`:**
|
|
149
|
+
```typescript
|
|
150
|
+
{ projectRoot?: string; changes: string; }
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### 엔트리포인트
|
|
154
|
+
|
|
155
|
+
**`bin/task-mcp.mjs`:**
|
|
156
|
+
|
|
157
|
+
`spawn`을 사용한다 (기존 `bin/task.mjs`의 `execFileSync`와 다름 — MCP 서버는 장시간 실행되는 프로세스이므로 non-blocking이 필요).
|
|
158
|
+
|
|
159
|
+
```javascript
|
|
160
|
+
#!/usr/bin/env node
|
|
161
|
+
import { spawn } from "child_process";
|
|
162
|
+
spawn("node", ["--import", "tsx", new URL("../src/mcp/index.ts", import.meta.url).pathname], { stdio: "inherit" });
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
**`.mcp.json` (init 시 생성):**
|
|
166
|
+
```json
|
|
167
|
+
{
|
|
168
|
+
"mcpServers": {
|
|
169
|
+
"taskflow": {
|
|
170
|
+
"type": "stdio",
|
|
171
|
+
"command": "node",
|
|
172
|
+
"args": ["./bin/task-mcp.mjs"],
|
|
173
|
+
"env": {}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
API 키 불필요 — Claude Max 인증 사용.
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
## 4. `task init` 플로우
|
|
184
|
+
|
|
185
|
+
### 신규 초기화 (.taskflow 없음)
|
|
186
|
+
|
|
187
|
+
```
|
|
188
|
+
1. .taskflow/ 디렉토리 생성
|
|
189
|
+
2. .taskflow/config.json 생성
|
|
190
|
+
3. .mcp.json 생성 (프로젝트 루트)
|
|
191
|
+
4. PRD 생성 모드 선택
|
|
192
|
+
├─ "대화형 브레인스토밍" → AI 멀티턴 대화 → PRD 생성
|
|
193
|
+
└─ "AI 자동 분석" → 코드 스캔 → PRD 생성
|
|
194
|
+
5. PRD를 .taskflow/prd.md에 저장
|
|
195
|
+
6. .taskflow/CLAUDE.md 동적 생성 (프로젝트명, 스택, 도구 목록 반영)
|
|
196
|
+
7. 루트 CLAUDE.md에 @./.taskflow/CLAUDE.md import 추가
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
### PRD 재생성 (.taskflow 존재)
|
|
200
|
+
|
|
201
|
+
```
|
|
202
|
+
1. "PRD를 다시 생성하시겠습니까?"
|
|
203
|
+
2. YES → 모드 선택 → PRD 생성 → .taskflow/prd.md 덮어쓰기
|
|
204
|
+
3. .taskflow/CLAUDE.md도 PRD 내용 반영하여 재생성
|
|
205
|
+
4. NO → 종료
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
### PRD 저장 위치
|
|
209
|
+
|
|
210
|
+
- 변경 전: `{projectName}-docs/prd.md`
|
|
211
|
+
- 변경 후: `.taskflow/prd.md`
|
|
212
|
+
|
|
213
|
+
### 기존 form 기반 대화형 모드 (interactive.ts)
|
|
214
|
+
|
|
215
|
+
기존 `runInteractivePrd()`는 고정된 15개 질문을 순서대로 묻는 form 방식이다. 이 모드는 **AI 멀티턴 브레인스토밍으로 대체**된다. AI가 프로젝트 맥락에 맞는 질문을 동적으로 생성하고, 충분한 정보가 모이면 PRD를 자동 작성한다. 기존 form 방식은 유지하지 않는다.
|
|
216
|
+
|
|
217
|
+
---
|
|
218
|
+
|
|
219
|
+
## 5. CLAUDE.md 동적 생성
|
|
220
|
+
|
|
221
|
+
### `.taskflow/CLAUDE.md`
|
|
222
|
+
|
|
223
|
+
PRD에서 추출한 프로젝트 정보 + MCP 도구 가이드를 합쳐서 생성.
|
|
224
|
+
|
|
225
|
+
```markdown
|
|
226
|
+
# TaskFlow — {프로젝트명} 개발 가이드
|
|
227
|
+
|
|
228
|
+
## 프로젝트 정보
|
|
229
|
+
- 이름: {projectName}
|
|
230
|
+
- 설명: {summary}
|
|
231
|
+
- 기술 스택: {stack}
|
|
232
|
+
- 생성일: {date}
|
|
233
|
+
|
|
234
|
+
## TaskFlow MCP 도구
|
|
235
|
+
(17개 도구 목록 + 설명)
|
|
236
|
+
|
|
237
|
+
## 워크플로우
|
|
238
|
+
### 새 기능 구현 시
|
|
239
|
+
1. get_next_task → 다음 태스크 확인
|
|
240
|
+
2. set_task_status → in-progress
|
|
241
|
+
3. 구현 완료 후 set_task_status → done
|
|
242
|
+
|
|
243
|
+
### 요구사항 변경 시
|
|
244
|
+
1. refine_tasks → 영향 받는 태스크 분석
|
|
245
|
+
2. 영향 받는 태스크 확인 및 수정
|
|
246
|
+
|
|
247
|
+
## 파일 구조
|
|
248
|
+
- .taskflow/config.json — 프로젝트 설정
|
|
249
|
+
- .taskflow/prd.md — PRD 문서
|
|
250
|
+
- .taskflow/tasks/task-{NNN}.md — 개별 태스크 파일
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
`@./.taskflow/CLAUDE.md`는 Claude Code의 파일 import 문법이다. Claude Code 외의 도구에서는 일반 텍스트로 보인다.
|
|
254
|
+
|
|
255
|
+
### 루트 CLAUDE.md 처리
|
|
256
|
+
|
|
257
|
+
- CLAUDE.md 존재 → 파일 끝에 `@./.taskflow/CLAUDE.md` import 추가
|
|
258
|
+
- CLAUDE.md 없음 → 새 파일 생성 + import 포함
|
|
259
|
+
- 기존 사용자 내용은 절대 건드리지 않고 append만
|
|
260
|
+
|
|
261
|
+
---
|
|
262
|
+
|
|
263
|
+
## 6. AI 클라이언트 (Claude Max 전용)
|
|
264
|
+
|
|
265
|
+
### `core/ai/client.ts`
|
|
266
|
+
|
|
267
|
+
`@anthropic-ai/claude-agent-sdk`의 `query()` 사용. API 키 불필요. 다른 AI 제공자 옵션 없음.
|
|
268
|
+
|
|
269
|
+
```typescript
|
|
270
|
+
export interface AiRequest {
|
|
271
|
+
prompt: string;
|
|
272
|
+
systemPrompt: string;
|
|
273
|
+
maxTurns?: number;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
export interface AiResponse {
|
|
277
|
+
text: string;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
export async function askClaude(req: AiRequest): Promise<AiResponse>
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
### `core/prd/generator.ts` — PRD 브레인스토밍
|
|
284
|
+
|
|
285
|
+
PRD 생성을 위한 멀티턴 브레인스토밍 함수를 포함한다. **Stateless 설계** — 서버는 세션을 저장하지 않으며, 클라이언트(CLI 또는 MCP 호출자)가 매 호출마다 전체 `messages` 배열을 전달한다.
|
|
286
|
+
|
|
287
|
+
```typescript
|
|
288
|
+
export interface BrainstormSession {
|
|
289
|
+
sessionId: string; // 고유 식별자 (UUID)
|
|
290
|
+
messages: Array<{ role: "user" | "assistant"; content: string }>;
|
|
291
|
+
isComplete: boolean;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
export interface BrainstormTurn {
|
|
295
|
+
session: BrainstormSession; // 업데이트된 세션 (messages 포함)
|
|
296
|
+
aiMessage: string;
|
|
297
|
+
isComplete: boolean;
|
|
298
|
+
prdMarkdown?: string;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
// 새 세션 시작 — sessionId 자동 생성, 첫 AI 질문 반환
|
|
302
|
+
export function startBrainstorm(projectRoot: string, projectContext?: string): Promise<BrainstormTurn>
|
|
303
|
+
|
|
304
|
+
// 사용자 응답으로 다음 턴 진행 — 전체 session을 받아 다음 턴 반환
|
|
305
|
+
export function continueBrainstorm(session: BrainstormSession, userMessage: string): Promise<BrainstormTurn>
|
|
306
|
+
|
|
307
|
+
// PRD 마크다운 빌드 (브레인스토밍 완료 후 or 자동분석 결과로)
|
|
308
|
+
export function buildPrdMarkdown(answers: PrdData): string
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
- CLI: `startBrainstorm()` → inquirer 입력 → `continueBrainstorm()` → 반복
|
|
312
|
+
- MCP: `brainstorm_prd` 도구 호출 시 `session` 객체를 매번 전달. MCP 서버 재시작 시에도 클라이언트가 session을 보유하므로 대화 유실 없음.
|
|
313
|
+
|
|
314
|
+
### `core/ai/client.ts` — 태스크 브레인스토밍
|
|
315
|
+
|
|
316
|
+
태스크를 서브태스크로 분해하는 `brainstormTask()`도 이 파일에 위치한다. PRD 브레인스토밍(멀티턴 대화)과 달리, 태스크 브레인스토밍은 **싱글턴 호출** — 태스크 내용을 넘기면 AI가 서브태스크 목록을 반환한다.
|
|
317
|
+
|
|
318
|
+
```typescript
|
|
319
|
+
export interface TaskBrainstormResult {
|
|
320
|
+
subtasks: Array<{ title: string; description: string; priority: string }>;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
export function brainstormTask(projectRoot: string, taskId: string, depth?: number): Promise<TaskBrainstormResult>
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
---
|
|
327
|
+
|
|
328
|
+
## 7. CLI 명령어 정리
|
|
329
|
+
|
|
330
|
+
### 변경 사항
|
|
331
|
+
|
|
332
|
+
| 명령어 | 변경 |
|
|
333
|
+
|--------|------|
|
|
334
|
+
| `task init` | 확장 (전체 셋업 + PRD) |
|
|
335
|
+
| `task prd` | **제거** |
|
|
336
|
+
| `task fprd` | 유지 (core 이동) |
|
|
337
|
+
| `task parse-prd` | 유지 (core 이동) |
|
|
338
|
+
| `task list` | 유지 (core 이동) |
|
|
339
|
+
| `task show` | 유지 (core 이동) |
|
|
340
|
+
| `task set-status` | 유지 (core 이동) |
|
|
341
|
+
| `task next` | 유지 (core 이동) |
|
|
342
|
+
| `task brainstorm` | 유지 (core 이동) |
|
|
343
|
+
| `task expand` | 유지 (core 이동) |
|
|
344
|
+
| `task refine` | 유지 (core 이동) |
|
|
345
|
+
|
|
346
|
+
### CLI 레이어 역할
|
|
347
|
+
|
|
348
|
+
모든 CLI 명령어는 thin wrapper로 변경:
|
|
349
|
+
- core 함수 호출 → 결과를 터미널 포맷(chalk, ora)으로 출력
|
|
350
|
+
|
|
351
|
+
### index.ts 변경
|
|
352
|
+
|
|
353
|
+
```typescript
|
|
354
|
+
// 제거
|
|
355
|
+
- import { registerPrdCommand } from "./commands/prd.js";
|
|
356
|
+
- registerPrdCommand(program);
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
---
|
|
360
|
+
|
|
361
|
+
## 8. 파일 구조 요약
|
|
362
|
+
|
|
363
|
+
```
|
|
364
|
+
bin/
|
|
365
|
+
├── task.mjs # CLI 엔트리
|
|
366
|
+
└── task-mcp.mjs # MCP 서버 엔트리 (새로 추가)
|
|
367
|
+
|
|
368
|
+
src/
|
|
369
|
+
├── core/ # 비즈니스 로직 (순수, UI 의존성 없음)
|
|
370
|
+
│ ├── project/ # 프로젝트 초기화 + Claude 셋업
|
|
371
|
+
│ ├── prd/ # PRD 생성/파싱
|
|
372
|
+
│ ├── task/ # 태스크 CRUD + 추천
|
|
373
|
+
│ ├── ai/ # Claude Max AI 클라이언트
|
|
374
|
+
│ └── types.ts
|
|
375
|
+
├── mcp/ # MCP 서버 (@modelcontextprotocol/sdk)
|
|
376
|
+
│ ├── index.ts
|
|
377
|
+
│ ├── server.ts
|
|
378
|
+
│ └── tools/
|
|
379
|
+
├── cli/ # CLI (commander, thin wrapper)
|
|
380
|
+
│ ├── index.ts
|
|
381
|
+
│ ├── commands/
|
|
382
|
+
│ ├── flows/ # CLI 전용 UI 로직 (inquirer 대화 루프 등)
|
|
383
|
+
│ └── lib/
|
|
384
|
+
├── backend/ # Hono 웹 서버
|
|
385
|
+
└── features/ # 웹 프론트엔드 features
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
---
|
|
389
|
+
|
|
390
|
+
## 9. 에러 처리 정책
|
|
391
|
+
|
|
392
|
+
### 원칙
|
|
393
|
+
|
|
394
|
+
- Fail fast — 명확한 에러 메시지와 함께 즉시 실패
|
|
395
|
+
- core 함수는 예외를 throw — CLI와 MCP가 각자 방식으로 처리
|
|
396
|
+
- 복구 가능한 에러는 재시도, 복구 불가능한 에러는 명확한 안내
|
|
397
|
+
|
|
398
|
+
### 주요 실패 시나리오
|
|
399
|
+
|
|
400
|
+
| 시나리오 | 처리 방식 |
|
|
401
|
+
|---------|----------|
|
|
402
|
+
| AI 호출 실패 (네트워크, 타임아웃) | 지수 백오프 재시도 (최대 3회), 실패 시 에러 메시지 |
|
|
403
|
+
| 디스크 쓰기 실패 (권한, 용량) | 즉시 실패 + 권한/경로 확인 안내 |
|
|
404
|
+
| PRD 생성 결과가 비어있음 | 에러 throw + 재시도 안내 |
|
|
405
|
+
| `.mcp.json` 이미 존재 | 기존 내용에 taskflow 서버 설정을 merge (다른 MCP 서버 설정 보존) |
|
|
406
|
+
| 루트 CLAUDE.md 형식이 예상과 다름 | 파일 끝에 안전하게 append만 수행 (파싱 불필요) |
|
|
407
|
+
| 브레인스토밍 중 AI 호출 실패 | 현재까지 대화 내용 보존, 재시도 가능 안내 |
|
|
408
|
+
|
|
409
|
+
### CLI vs MCP 에러 처리
|
|
410
|
+
|
|
411
|
+
- CLI: `withCliErrorBoundary`로 감싸서 사용자 친화적 메시지 출력 (기존 패턴 유지)
|
|
412
|
+
- MCP: MCP 프로토콜의 에러 응답 형식으로 반환 (`isError: true` + 메시지)
|
|
413
|
+
|
|
414
|
+
---
|
|
415
|
+
|
|
416
|
+
## 10. 마이그레이션 전략
|
|
417
|
+
|
|
418
|
+
기존 코드를 한 번에 옮기지 않고, init 플로우에 필요한 것부터 점진적으로 core에 추출한다.
|
|
419
|
+
|
|
420
|
+
1. `core/project/` — init에 필요한 새 코드 작성
|
|
421
|
+
2. `core/prd/` — 기존 `flows/auto.ts`, `flows/interactive.ts`에서 순수 로직 추출
|
|
422
|
+
3. `core/ai/` — 기존 `auto.ts`의 `generateWithAI`를 `client.ts`로 이동
|
|
423
|
+
4. `core/task/` — 기존 `features/taskflow/lib/`를 이동
|
|
424
|
+
5. `src/mcp/` — core를 MCP로 래핑
|
|
425
|
+
6. CLI 명령어들을 core 호출로 전환
|
|
426
|
+
7. `task prd` 명령어 제거 — init의 AI 브레인스토밍 플로우가 완전히 동작한 후에만 제거
|
|
427
|
+
8. 기존 `PrdResult`, `FeaturePrdResult` 등 중복 타입을 `core/types.ts`로 통합
|
|
428
|
+
|
|
429
|
+
기존 CLI 명령어들은 core 이동 전까지 현재 코드로 계속 동작한다.
|