@walwal-harness/cli 2.0.1 → 2.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/README.md +296 -89
  2. package/assets/templates/config.json +41 -1
  3. package/bin/init.js +65 -3
  4. package/package.json +5 -2
  5. package/scripts/harness-next.sh +36 -1
  6. package/scripts/harness-user-prompt-submit.sh +106 -0
  7. package/scripts/lib/harness-render-progress.sh +15 -1
  8. package/scripts/scan-project.sh +24 -2
  9. package/skills/brainstorming/SKILL.md +200 -0
  10. package/skills/brainstorming/references/attribution.md +109 -0
  11. package/skills/brainstorming/references/spec-document-reviewer-prompt.md +49 -0
  12. package/skills/brainstorming/references/visual-companion.md +287 -0
  13. package/skills/brainstorming/scripts/frame-template.html +214 -0
  14. package/skills/brainstorming/scripts/helper.js +88 -0
  15. package/skills/brainstorming/scripts/server.cjs +354 -0
  16. package/skills/brainstorming/scripts/start-server.sh +148 -0
  17. package/skills/brainstorming/scripts/stop-server.sh +56 -0
  18. package/skills/dispatcher/SKILL.md +114 -2
  19. package/skills/dispatcher/references/pipeline-definitions.md +53 -5
  20. package/skills/evaluator-functional-flutter/SKILL.md +198 -0
  21. package/skills/evaluator-functional-flutter/references/ia-compliance.md +77 -0
  22. package/skills/evaluator-functional-flutter/references/scoring-rubric.md +132 -0
  23. package/skills/evaluator-functional-flutter/references/static-check-rules.md +99 -0
  24. package/skills/generator-frontend-flutter/SKILL.md +138 -0
  25. package/skills/generator-frontend-flutter/references/anti-patterns.md +288 -0
  26. package/skills/generator-frontend-flutter/references/api-layer-pattern.md +233 -0
  27. package/skills/generator-frontend-flutter/references/i18n-pattern.md +102 -0
  28. package/skills/generator-frontend-flutter/references/riverpod-pattern.md +199 -0
  29. package/skills/planner/SKILL.md +23 -1
  30. package/skills/planner/references/fe-stack-detection.md +131 -0
@@ -18,6 +18,7 @@ PROJECT_ROOT="$(resolve_harness_root "${1:-.}")" || {
18
18
 
19
19
  PROGRESS="$PROJECT_ROOT/.harness/progress.json"
20
20
  CONFIG="$PROJECT_ROOT/.harness/config.json"
21
+ PIPELINE_JSON="$PROJECT_ROOT/.harness/actions/pipeline.json"
21
22
  NEXT_PROMPT="$PROJECT_ROOT/.harness/next-prompt.txt"
22
23
 
23
24
  check_jq || exit 1
@@ -40,6 +41,29 @@ next_agent=$(jq -r '.next_agent // "null"' "$PROGRESS")
40
41
  retry_count=$(jq -r '.sprint.retry_count // 0' "$PROGRESS")
41
42
  max_retries=$(jq -r '.flow.max_retries_per_sprint // 10' "$CONFIG" 2>/dev/null || echo 10)
42
43
 
44
+ # fe_stack 치환 (Flutter 지원) — pipeline.json 에서 읽음
45
+ fe_stack="react"
46
+ if [ -f "$PIPELINE_JSON" ]; then
47
+ fe_stack=$(jq -r '.fe_stack // "react"' "$PIPELINE_JSON" 2>/dev/null || echo "react")
48
+ fi
49
+
50
+ # ─────────────────────────────────────────
51
+ # fe_stack 치환 헬퍼
52
+ # pipeline_selection.pipelines에서 읽은 에이전트명을 fe_stack에 따라 치환
53
+ # - react: 그대로
54
+ # - flutter: generator-frontend → generator-frontend-flutter 등, __skip__ 은 건너뜀
55
+ # ─────────────────────────────────────────
56
+ substitute_fe_stack() {
57
+ local agent="$1"
58
+ if [ "$fe_stack" != "flutter" ]; then
59
+ echo "$agent"
60
+ return
61
+ fi
62
+ local sub
63
+ sub=$(jq -r ".flow.pipeline_selection.fe_stack_substitution.flutter[\"${agent}\"] // \"${agent}\"" "$CONFIG" 2>/dev/null)
64
+ echo "$sub"
65
+ }
66
+
43
67
  # ─────────────────────────────────────────
44
68
  # Determine next agent
45
69
  # ─────────────────────────────────────────
@@ -73,8 +97,18 @@ compute_next_agent() {
73
97
  return
74
98
  fi
75
99
 
100
+ local -a raw_agents
101
+ mapfile -t raw_agents < <(jq -r ".flow.pipeline_selection.pipelines[\"${pipeline}\"][]" "$CONFIG" 2>/dev/null | sed 's/:.*//')
102
+
103
+ # fe_stack 치환 + __skip__ 필터링
76
104
  local -a agents
77
- mapfile -t agents < <(jq -r ".flow.pipeline_selection.pipelines[\"${pipeline}\"][]" "$CONFIG" 2>/dev/null | sed 's/:.*//')
105
+ for a in "${raw_agents[@]}"; do
106
+ local sub
107
+ sub=$(substitute_fe_stack "$a")
108
+ if [ "$sub" != "__skip__" ]; then
109
+ agents+=("$sub")
110
+ fi
111
+ done
78
112
 
79
113
  local found=false
80
114
  for agent in "${agents[@]}"; do
@@ -82,6 +116,7 @@ compute_next_agent() {
82
116
  echo "$agent"
83
117
  return
84
118
  fi
119
+ # current 비교 시에도 치환된 이름으로 (Flutter 변형 에이전트가 실행되는 경우)
85
120
  if [ "$agent" = "$current" ]; then
86
121
  found=true
87
122
  fi
@@ -0,0 +1,106 @@
1
+ #!/bin/bash
2
+ # harness-user-prompt-submit.sh
3
+ # ─────────────────────────────────────────
4
+ # Claude Code UserPromptSubmit hook
5
+ # 모든 사용자 프롬프트를 harness-dispatcher 로 라우팅하도록 Claude 에게
6
+ # 지시하는 컨텍스트를 stdout 에 주입한다.
7
+ #
8
+ # 활성 조건:
9
+ # 1) 현재 cwd 에 .harness/config.json 존재
10
+ # 2) .harness/config.json 의 behavior.auto_route_dispatcher != false
11
+ #
12
+ # 비활성 상황에서는 아무것도 출력하지 않고 exit 0 (pass-through).
13
+ # ─────────────────────────────────────────
14
+ set -e
15
+
16
+ # stdin 의 JSON payload 읽기 (Claude Code 가 {prompt, cwd, session_id, ...} 전달)
17
+ INPUT=$(cat)
18
+
19
+ # cwd 추출 (payload 에 없으면 PWD fallback)
20
+ CWD=$(echo "$INPUT" | jq -r '.cwd // empty' 2>/dev/null || true)
21
+ if [ -z "$CWD" ]; then
22
+ CWD="$PWD"
23
+ fi
24
+
25
+ # 조건 1: 하네스 초기화 확인
26
+ if [ ! -f "$CWD/.harness/config.json" ]; then
27
+ exit 0
28
+ fi
29
+
30
+ # 조건 2: opt-out 플래그 확인 (기본값 true)
31
+ AUTO_ROUTE="true"
32
+ if command -v jq >/dev/null 2>&1; then
33
+ AUTO_ROUTE=$(jq -r '.behavior.auto_route_dispatcher // true' "$CWD/.harness/config.json" 2>/dev/null || echo "true")
34
+ fi
35
+ if [ "$AUTO_ROUTE" != "true" ]; then
36
+ exit 0
37
+ fi
38
+
39
+ # 프롬프트 내용 추출 (opt-out 문구 감지용)
40
+ PROMPT=$(echo "$INPUT" | jq -r '.prompt // empty' 2>/dev/null || true)
41
+ # 사용자가 명시적으로 건너뛰기 요청하면 pass-through
42
+ if echo "$PROMPT" | grep -qiE "harness\s*(skip|off|bypass|없이)|without\s*harness|just\s*(answer|chat|reply)"; then
43
+ exit 0
44
+ fi
45
+
46
+ # 현재 세션 상태 읽기
47
+ PIPELINE="none"
48
+ CURRENT_AGENT="none"
49
+ NEXT_AGENT="none"
50
+ SPRINT_NUM="0"
51
+ SPRINT_STATUS="init"
52
+ FE_STACK="react"
53
+
54
+ if [ -f "$CWD/.harness/progress.json" ] && command -v jq >/dev/null 2>&1; then
55
+ PIPELINE=$(jq -r '.pipeline // "none"' "$CWD/.harness/progress.json" 2>/dev/null || echo "none")
56
+ CURRENT_AGENT=$(jq -r '.current_agent // "none"' "$CWD/.harness/progress.json" 2>/dev/null || echo "none")
57
+ NEXT_AGENT=$(jq -r '.next_agent // "none"' "$CWD/.harness/progress.json" 2>/dev/null || echo "none")
58
+ SPRINT_NUM=$(jq -r '.sprint.number // 0' "$CWD/.harness/progress.json" 2>/dev/null || echo "0")
59
+ SPRINT_STATUS=$(jq -r '.sprint.status // "init"' "$CWD/.harness/progress.json" 2>/dev/null || echo "init")
60
+ fi
61
+
62
+ if [ -f "$CWD/.harness/actions/pipeline.json" ] && command -v jq >/dev/null 2>&1; then
63
+ FE_STACK=$(jq -r '.fe_stack // "react"' "$CWD/.harness/actions/pipeline.json" 2>/dev/null || echo "react")
64
+ fi
65
+
66
+ # ─────────────────────────────────────────
67
+ # Context 주입 (stdout → Claude 컨텍스트)
68
+ # ─────────────────────────────────────────
69
+ cat <<EOF
70
+ [walwal-harness] Auto-routing is ACTIVE for this project.
71
+
72
+ 이 프로젝트는 walwal-harness 가 초기화되어 있으며, auto_route_dispatcher 플래그가
73
+ 켜져 있습니다. 사용자의 모든 프롬프트는 **harness-dispatcher** 스킬을 통해
74
+ 분류/라우팅된 뒤 처리되어야 합니다.
75
+
76
+ ## 분류 규칙 (Dispatcher Request Classification)
77
+ - **기능 요청** (만들어줘, 추가, 고쳐줘, PRD, OpenAPI) → Pipeline Flow
78
+ - **실수 지적** (아니, 잘못됐어, 그렇게 하면 안 돼, X로 해야지) → Gotcha Flow
79
+ - **혼합** → Gotcha 먼저 기록 → Pipeline 이어서
80
+ - **메타/인사/Claude 자체 질문** → 짧게 일반 응답 (dispatcher skip 허용)
81
+
82
+ ## 현재 harness 세션 상태
83
+ - pipeline: $PIPELINE
84
+ - current_agent: $CURRENT_AGENT
85
+ - next_agent: $NEXT_AGENT
86
+ - sprint: $SPRINT_NUM ($SPRINT_STATUS)
87
+ - fe_stack: $FE_STACK
88
+
89
+ ## 지시
90
+ 1. 먼저 위 상태를 읽고, 사용자 메시지가 어떤 분류에 해당하는지 판단
91
+ 2. **pipeline 이 'none' 또는 dispatcher 미실행 상태**면 harness-dispatcher 스킬 호출
92
+ 3. **pipeline 이 이미 활성**이면:
93
+ - 실수 지적이면 → dispatcher 로 gotcha 기록
94
+ - 기능 연속 작업이면 → next_agent 또는 current_agent 의 컨텍스트로 계속
95
+ 4. 응답 전 반드시 \`.harness/progress.json\` 을 읽고 세션 경계 프로토콜 준수
96
+
97
+ ## 이 라우팅을 건너뛰려면
98
+ - **단일 메시지**: 사용자가 "harness skip", "without harness", "harness 없이", "just answer" 등을 명시
99
+ - **전역 비활성**: \`.harness/config.json\` 에서 \`behavior.auto_route_dispatcher = false\` 설정
100
+
101
+ ## 참고
102
+ 이 안내는 \`scripts/harness-user-prompt-submit.sh\` UserPromptSubmit 훅에 의해
103
+ 매 프롬프트마다 자동 주입됩니다. 중복 안내처럼 보여도 무시하지 말고 위 규칙을 따르세요.
104
+ EOF
105
+
106
+ exit 0
@@ -282,12 +282,17 @@ render_progress() {
282
282
  render_agent_bar() {
283
283
  local PROGRESS="${1:-.}/.harness/progress.json"
284
284
  local CONFIG="${1:-.}/.harness/config.json"
285
+ local PIPELINE_JSON="${1:-.}/.harness/actions/pipeline.json"
285
286
 
286
287
  if [ ! -f "$PROGRESS" ] || [ ! -f "$CONFIG" ]; then return 1; fi
287
288
 
288
- local pipeline current_agent
289
+ local pipeline current_agent fe_stack
289
290
  pipeline=$(jq -r '.pipeline // "unknown"' "$PROGRESS")
290
291
  current_agent=$(jq -r '.current_agent // "none"' "$PROGRESS")
292
+ fe_stack="react"
293
+ if [ -f "$PIPELINE_JSON" ]; then
294
+ fe_stack=$(jq -r '.fe_stack // "react"' "$PIPELINE_JSON" 2>/dev/null || echo "react")
295
+ fi
291
296
 
292
297
  local completed_agents
293
298
  completed_agents=$(jq -r '.completed_agents // [] | .[]' "$PROGRESS")
@@ -299,6 +304,15 @@ render_agent_bar() {
299
304
 
300
305
  while IFS= read -r agent; do
301
306
  agent=$(echo "$agent" | sed 's/:.*//') # strip mode suffix like :light, :api-only
307
+
308
+ # fe_stack 치환 적용
309
+ if [ "$fe_stack" = "flutter" ]; then
310
+ local sub
311
+ sub=$(jq -r ".flow.pipeline_selection.fe_stack_substitution.flutter[\"${agent}\"] // \"${agent}\"" "$CONFIG" 2>/dev/null)
312
+ if [ "$sub" = "__skip__" ]; then continue; fi
313
+ agent="$sub"
314
+ fi
315
+
302
316
  if [ "$first" = true ]; then
303
317
  first=false
304
318
  else
@@ -61,7 +61,13 @@ elif [ -f "${PROJECT_ROOT}/pom.xml" ] || [ -f "${PROJECT_ROOT}/build.gradle" ];
61
61
  fi
62
62
 
63
63
  # Frontend
64
- if [ -f "${PROJECT_ROOT}/next.config.js" ] || [ -f "${PROJECT_ROOT}/next.config.ts" ] || [ -f "${PROJECT_ROOT}/next.config.mjs" ]; then
64
+ # Flutter 우선 감지 — pubspec.yaml 존재하면 Flutter 프로젝트로 판정 (TECH_LANG도 보정)
65
+ FE_STACK="react" # react | flutter (기본값은 react 계열)
66
+ if [ -f "${PROJECT_ROOT}/pubspec.yaml" ] && grep -q "flutter:" "${PROJECT_ROOT}/pubspec.yaml" 2>/dev/null; then
67
+ TECH_FRONTEND="flutter"
68
+ TECH_LANG="dart"
69
+ FE_STACK="flutter"
70
+ elif [ -f "${PROJECT_ROOT}/next.config.js" ] || [ -f "${PROJECT_ROOT}/next.config.ts" ] || [ -f "${PROJECT_ROOT}/next.config.mjs" ]; then
65
71
  TECH_FRONTEND="nextjs"
66
72
  elif [ -f "${PROJECT_ROOT}/vite.config.ts" ] || [ -f "${PROJECT_ROOT}/vite.config.js" ]; then
67
73
  TECH_FRONTEND="vite-react"
@@ -75,11 +81,26 @@ fi
75
81
  if [ -d "${PROJECT_ROOT}/apps/web" ]; then
76
82
  if [ -f "${PROJECT_ROOT}/apps/web/next.config.js" ] || [ -f "${PROJECT_ROOT}/apps/web/next.config.ts" ]; then
77
83
  TECH_FRONTEND="nextjs"
84
+ FE_STACK="react"
78
85
  elif [ -f "${PROJECT_ROOT}/apps/web/vite.config.ts" ]; then
79
86
  TECH_FRONTEND="vite-react"
87
+ FE_STACK="react"
80
88
  fi
81
89
  fi
82
90
 
91
+ # Flutter 서브디렉토리 감지 (monorepo 또는 서브 프로젝트 케이스)
92
+ if [ "$TECH_FRONTEND" = "unknown" ]; then
93
+ # 대표적인 Flutter 서브폴더 이름을 얕게 탐색
94
+ for d in apps/mobile mobile clue_mobile_app flutter_app; do
95
+ if [ -f "${PROJECT_ROOT}/${d}/pubspec.yaml" ] && grep -q "flutter:" "${PROJECT_ROOT}/${d}/pubspec.yaml" 2>/dev/null; then
96
+ TECH_FRONTEND="flutter"
97
+ TECH_LANG="dart"
98
+ FE_STACK="flutter"
99
+ break
100
+ fi
101
+ done
102
+ fi
103
+
83
104
  # Database
84
105
  if grep -rq "typeorm\|prisma\|sequelize\|knex" "${PROJECT_ROOT}/package.json" 2>/dev/null; then
85
106
  if grep -q "pg\|postgres" "${PROJECT_ROOT}/package.json" 2>/dev/null; then
@@ -203,6 +224,7 @@ cat > "$OUTPUT" << JSONEOF
203
224
  "tech_stack": {
204
225
  "backend": "${TECH_BACKEND}",
205
226
  "frontend": "${TECH_FRONTEND}",
227
+ "fe_stack": "${FE_STACK}",
206
228
  "database": "${TECH_DB}",
207
229
  "monorepo": "${TECH_MONOREPO}",
208
230
  "language": "${TECH_LANG}"
@@ -260,7 +282,7 @@ echo "=== Scan Complete ==="
260
282
  echo "Output: ${OUTPUT}"
261
283
  echo ""
262
284
  echo "--- Summary ---"
263
- echo "Tech Stack: ${TECH_BACKEND} / ${TECH_FRONTEND} / ${TECH_DB}"
285
+ echo "Tech Stack: ${TECH_BACKEND} / ${TECH_FRONTEND} (fe_stack=${FE_STACK}) / ${TECH_DB}"
264
286
  echo "Monorepo: ${TECH_MONOREPO}"
265
287
  echo "OpenAPI: ${OPENAPI}"
266
288
  echo "Git: ${GIT_INIT} (${GIT_COMMITS} commits, branch: ${GIT_BRANCH})"
@@ -0,0 +1,200 @@
1
+ ---
2
+ name: harness-brainstorming
3
+ description: "사용자의 러프한(바이브코딩) 요구사항을 대화형으로 구체화하여 Planner가 바로 쓸 수 있는 디자인/스펙 문서(.harness/actions/brainstorm-spec.md)로 만든다. Dispatcher가 사용자에게 '브레인스토밍 필요?' 라고 확인한 뒤에만 호출된다. 원본: obra/superpowers MIT."
4
+ disable-model-invocation: true
5
+ ---
6
+
7
+ # Brainstormer — 요구사항 구체화 (obra/superpowers 파생)
8
+
9
+ > **Attribution**: 이 스킬의 방법론은 [obra/superpowers](https://github.com/obra/superpowers)
10
+ > (MIT License) 의 `skills/brainstorming` 을 walwal-harness 파이프라인에 맞게 이식한 것입니다.
11
+ > 원본 저자(J. Hubbard 등)에게 감사드립니다. 상세 원본 텍스트 + 라이센스는
12
+ > [references/attribution.md](references/attribution.md) 참조.
13
+
14
+ ## 역할
15
+
16
+ walwal-harness 에서 Brainstormer 의 유일한 목적은 **러프한 바이브코딩 아이디어를
17
+ Planner 가 곧바로 plan.md / feature-list.json / api-contract.json 으로 변환할 수 있는
18
+ 수준의 fit 한 요구사항 문서**로 구체화하는 것이다. 결과물은 단 하나:
19
+
20
+ ```
21
+ .harness/actions/brainstorm-spec.md
22
+ ```
23
+
24
+ 이 파일이 생성되면 Planner 는 이것을 PRD 대체 입력으로 읽는다.
25
+
26
+ ## 언제 호출되는가
27
+
28
+ **Dispatcher 가 사용자에게 명시적으로 "브레인스토밍 과정이 필요합니까?" 라고 묻고
29
+ 사용자가 승인한 경우에만 실행된다.** 이외의 모든 경로 (피드백, 이터레이션, 직접 에이전트
30
+ 명령, Gotcha 교정, 스프린트 retry) 에서는 호출되지 않는다. 사용자가 명확한 PRD 를
31
+ 제공하거나 브레인스토밍 불필요를 선언하면 Dispatcher 는 곧바로 `next_agent = planner`
32
+ 로 라우팅한다.
33
+
34
+ ## Session Boundary Protocol
35
+
36
+ ### On Start
37
+ 1. `.harness/progress.json` 읽기 — `next_agent == "brainstormer"` 인지 확인
38
+ - 아니면 즉시 STOP + "Dispatcher 를 먼저 실행하세요" 안내
39
+ 2. progress.json 업데이트: `current_agent` → `"brainstormer"`, `agent_status` → `"running"`, `updated_at` 갱신
40
+ 3. **Skip 조건 검사**: `.harness/actions/brainstorm-spec.md` 가 이미 존재하고
41
+ 사용자가 "새로 브레인스토밍" 을 명시하지 않았다면:
42
+ - 사용자에게 "기존 brainstorm-spec.md 가 있습니다. 재사용(Y) / 새로 작성(N)?" 질문
43
+ - Y → 즉시 On Complete 로 이동 (interactive 단계 전부 스킵)
44
+ - N → 기존 파일을 `.harness/archive/brainstorm-spec-<timestamp>.md` 로 이동 후 interactive 시작
45
+
46
+ ### On Complete
47
+ 1. `.harness/actions/brainstorm-spec.md` 가 존재하고 "User Review Gate" 를 통과했는지 확인
48
+ 2. progress.json 업데이트:
49
+ - `agent_status` → `"completed"`
50
+ - `completed_agents` 에 `"brainstormer"` 추가
51
+ - `next_agent` → `"planner"`
52
+ 3. `.harness/progress.log` 에 요약 추가: `Brainstormer → Planner (spec: <경로>)`
53
+ 4. **STOP. 다음 에이전트를 직접 호출하지 않는다.**
54
+ 5. 출력: `"✓ Brainstormer 완료. bash scripts/harness-next.sh 실행하여 Planner 단계로 진행."`
55
+
56
+ ### On Fail / Abort
57
+ 사용자가 중간에 "중단" / "취소" / "abort" 를 요청하면:
58
+ 1. progress.json 업데이트: `agent_status` → `"blocked"`, `failure.message` → `"user aborted brainstorming"`
59
+ 2. 작성 중이던 `brainstorm-spec.md` 는 `.harness/archive/brainstorm-spec-draft-<timestamp>.md` 로 이동
60
+ 3. **STOP**. 사용자에게 "재시작 원하면 'dispatcher 다시'" 안내
61
+
62
+ ## HARD-GATE (원본에서 계승)
63
+
64
+ > **Planner / Generator / 어떤 구현 에이전트도 호출하지 말라. 사용자가 "이 디자인 승인한다" 고
65
+ > 명시적으로 말하기 전까지는 brainstorm-spec.md 를 저장하지도 않는다.**
66
+
67
+ 아무리 간단해 보이는 프로젝트라도 이 게이트를 건너뛰지 않는다. "Simple" 한 프로젝트가
68
+ 오히려 검증되지 않은 가정 때문에 가장 많은 시간을 낭비시킨다.
69
+
70
+ ## 체크리스트 (Brainstormer 내부 워크플로우)
71
+
72
+ 각 항목을 **순서대로** 수행하고 각 단계 끝에서 사용자 확인을 받는다:
73
+
74
+ 1. **프로젝트 컨텍스트 탐색** — 기존 파일, docs, 최근 커밋, `AGENTS.md`, `.harness/actions/`
75
+ 2. **Visual Companion 제안** (시각 요소가 많을 예정이라면, 단일 메시지로) — [visual-companion 가이드](references/visual-companion.md)
76
+ 3. **명확화 질문** — 한 번에 **하나씩**, 목적/제약/성공 기준 파악 (가능하면 객관식)
77
+ 4. **스코프 점검** — 여러 독립 서브시스템이 섞여 있으면 먼저 분할 제안 (예: "플랫폼 A + 채팅 + 결제" → 먼저 A 만)
78
+ 5. **2~3 개 접근법 제시** — 각 접근의 장단점 + 추천안 + 추천 이유
79
+ 6. **디자인 섹션별 제시** — 복잡도에 맞춰 섹션별 길이 조절, 각 섹션 끝에 사용자 확인
80
+ - 아키텍처, 컴포넌트, 데이터 흐름, 에러 처리, 테스트
81
+ 7. **사용자 디자인 승인** 받기
82
+ 8. **brainstorm-spec.md 저장** — `.harness/actions/brainstorm-spec.md` 에 커밋 (아래 스펙 포맷)
83
+ 9. **Spec Self-Review** — 플레이스홀더, 모순, 애매성, 스코프, YAGNI 체크. 발견 시 inline 수정
84
+ 상세 → [spec-document-reviewer-prompt.md](references/spec-document-reviewer-prompt.md)
85
+ 10. **User Review Gate** — 사용자에게 작성된 파일을 리뷰 요청. 변경 요청 시 → 8번으로 복귀
86
+ 11. **Planner 로 핸드오프** — Session Boundary Protocol On Complete 실행
87
+
88
+ ## 핵심 원칙 (원본 계승)
89
+
90
+ - **한 번에 한 질문** — 질문 폭탄 금지
91
+ - **객관식 우선** — 가능하면 A/B/C/D 형태로
92
+ - **YAGNI** — 요청되지 않은 기능은 전부 제거
93
+ - **대안 탐색** — 결정하기 전에 항상 2-3 개 접근법 제시
94
+ - **점진적 검증** — 섹션별로 제시하고 승인 후 다음
95
+ - **유연성** — 중간에 "이건 안 맞는 것 같아" 가 나오면 언제든 이전 단계로 복귀
96
+
97
+ ## 출력 포맷: `.harness/actions/brainstorm-spec.md`
98
+
99
+ ```markdown
100
+ ---
101
+ docmeta:
102
+ id: brainstorm-spec
103
+ title: Brainstorm Spec — <프로젝트/기능 이름>
104
+ type: output
105
+ createdAt: <ISO 8601>
106
+ updatedAt: <ISO 8601>
107
+ source:
108
+ producer: agent
109
+ skillId: harness-brainstorming
110
+ inputs:
111
+ - documentId: user-conversation
112
+ uri: (inline — 사용자와의 대화 전체)
113
+ relation: output-from
114
+ tags: [brainstorming, spec, planner-input]
115
+ ---
116
+
117
+ # Brainstorm Spec — <프로젝트/기능 이름>
118
+
119
+ ## 1. 목적 (Purpose)
120
+ <무엇을, 왜 만드는가 — 1-2 문단>
121
+
122
+ ## 2. 성공 기준 (Success Criteria)
123
+ - [ ] ...
124
+ - [ ] ...
125
+
126
+ ## 3. 스코프 (Scope)
127
+ ### In
128
+ - ...
129
+ ### Out (명시적 제외)
130
+ - ...
131
+
132
+ ## 4. 제약 (Constraints)
133
+ - 기술 스택:
134
+ - 성능:
135
+ - 보안/컴플라이언스:
136
+ - 기타:
137
+
138
+ ## 5. 선택된 접근법 (Chosen Approach)
139
+ <2-3 개 대안 중 사용자가 승인한 것 + 이유>
140
+
141
+ ### 고려했던 대안
142
+ - **Alt A**: ... (장/단점)
143
+ - **Alt B**: ... (장/단점)
144
+
145
+ ## 6. 아키텍처 스케치
146
+ <구성요소 + 상호작용 — ASCII 다이어그램 또는 간단한 설명>
147
+
148
+ ## 7. 주요 컴포넌트 / 엔티티
149
+ - Component A — 책임:
150
+ - Entity X — 필드/관계:
151
+
152
+ ## 8. 데이터 흐름 (Data Flow)
153
+ <입력 → 처리 → 출력 → 저장 경로>
154
+
155
+ ## 9. 에러 처리 전략
156
+ - 경계 에러:
157
+ - 내부 에러:
158
+ - 사용자 노출 메시지:
159
+
160
+ ## 10. 테스트 전략 (High-level)
161
+ - Unit:
162
+ - Integration:
163
+ - E2E:
164
+
165
+ ## 11. Open Questions (Planner 가 확정할 것)
166
+ - Q1: ...
167
+ - Q2: ...
168
+
169
+ ## 12. 사용자 승인 로그
170
+ - YYYY-MM-DD HH:MM — 섹션 <N> 승인 ("네, 좋아요")
171
+ - YYYY-MM-DD HH:MM — 디자인 전체 승인
172
+ - YYYY-MM-DD HH:MM — 작성 스펙 파일 리뷰 통과
173
+ ```
174
+
175
+ ## Planner 와의 인터페이스
176
+
177
+ Planner 는 On Start 에 이 파일을 읽고:
178
+
179
+ 1. `1. 목적`, `2. 성공 기준`, `3. 스코프` → `plan.md` 의 사양서 도입부로 직접 반영
180
+ 2. `5. 선택된 접근법`, `6. 아키텍처 스케치` → MSA 서비스 분할 (full 모드) 또는 컴포넌트 설계의 베이스
181
+ 3. `7. 주요 컴포넌트 / 엔티티` → `feature-list.json` 초기 feature 목록 시드
182
+ 4. `11. Open Questions` → Planner 가 해소 (API 계약으로 확정)
183
+
184
+ Planner 는 brainstorm-spec.md 에 있는 **승인된 결정** 을 뒤엎지 않는다. 필요한 경우
185
+ `## Change Request` 섹션을 추가해 Dispatcher 를 통한 재논의 요청.
186
+
187
+ ## 금지 사항
188
+
189
+ - `brainstorm-spec.md` 승인 전에 `plan.md`, `feature-list.json`, `api-contract.json` 작성
190
+ - 코드 작성 / scaffolding / 파일 생성 (scripts/visual-companion 제외)
191
+ - 여러 질문을 한 메시지에 몰아 넣기
192
+ - 사용자 승인 없이 임의로 다음 섹션으로 진행
193
+ - `.harness/archive/` 쓰기 금지 원칙 위반 (skip/abort 시 draft 이동 외에는 금지)
194
+
195
+ ## 참고
196
+
197
+ - 원본 방법론 + 라이센스 → [references/attribution.md](references/attribution.md)
198
+ - Visual Companion (브라우저 기반 목업/다이어그램 서버) → [references/visual-companion.md](references/visual-companion.md)
199
+ - Spec self-review 상세 → [references/spec-document-reviewer-prompt.md](references/spec-document-reviewer-prompt.md)
200
+ - Visual Companion 실행 스크립트 → `scripts/start-server.sh` (실행은 선택)
@@ -0,0 +1,109 @@
1
+ ---
2
+ docmeta:
3
+ id: brainstorming-attribution
4
+ title: Brainstorming Skill — Attribution & Original Source
5
+ type: output
6
+ createdAt: 2026-04-09T00:00:00Z
7
+ updatedAt: 2026-04-09T00:00:00Z
8
+ source:
9
+ producer: agent
10
+ skillId: harness-brainstorming
11
+ inputs:
12
+ - documentId: obra-superpowers-brainstorming-skill
13
+ uri: https://github.com/obra/superpowers/blob/main/skills/brainstorming/SKILL.md
14
+ relation: output-from
15
+ sections:
16
+ - sourceRange:
17
+ startLine: 1
18
+ endLine: 165
19
+ targetRange:
20
+ startLine: 21
21
+ endLine: 32
22
+ - sourceRange:
23
+ startLine: 29
24
+ endLine: 33
25
+ targetRange:
26
+ startLine: 36
27
+ endLine: 42
28
+ - sourceRange:
29
+ startLine: 12
30
+ endLine: 18
31
+ targetRange:
32
+ startLine: 55
33
+ endLine: 62
34
+ - documentId: obra-superpowers-spec-reviewer
35
+ uri: https://github.com/obra/superpowers/blob/main/skills/brainstorming/spec-document-reviewer-prompt.md
36
+ relation: output-from
37
+ sections:
38
+ - sourceRange:
39
+ startLine: 1
40
+ endLine: 50
41
+ targetRange:
42
+ startLine: 23
43
+ endLine: 24
44
+ - documentId: obra-superpowers-visual-companion
45
+ uri: https://github.com/obra/superpowers/blob/main/skills/brainstorming/visual-companion.md
46
+ relation: output-from
47
+ sections:
48
+ - sourceRange:
49
+ startLine: 1
50
+ endLine: 287
51
+ targetRange:
52
+ startLine: 25
53
+ endLine: 27
54
+ tags: [attribution, license, mit, obra-superpowers]
55
+ ---
56
+
57
+ # Attribution — obra/superpowers brainstorming skill
58
+
59
+ walwal-harness 의 `harness-brainstorming` 스킬은 아래 원본을 기반으로
60
+ 파이프라인 통합(Session Boundary Protocol, Planner 인터페이스, 출력 경로 등)을
61
+ 추가한 파생 저작물입니다.
62
+
63
+ ## 원본
64
+
65
+ - **Repo**: [obra/superpowers](https://github.com/obra/superpowers)
66
+ - **Path**: `skills/brainstorming/`
67
+ - **Files reused**:
68
+ - `SKILL.md` — 방법론 (HARD-GATE, 한 번에 한 질문, 2-3 접근법, spec self-review)
69
+ - `spec-document-reviewer-prompt.md` — spec 리뷰 서브에이전트 프롬프트 템플릿
70
+ - `visual-companion.md` — 브라우저 기반 시각 도우미 가이드
71
+ - `scripts/frame-template.html`, `helper.js`, `server.cjs`, `start-server.sh`, `stop-server.sh` — visual companion 서버 구현
72
+ - **License**: MIT License
73
+
74
+ ## 변경점 (walwal-harness 통합)
75
+
76
+ 1. **Session Boundary Protocol 추가** — On Start / On Complete / On Fail 프로토콜로
77
+ harness 다중 에이전트 흐름에 맞춤
78
+ 2. **Terminal state 변경** — 원본의 "invoke writing-plans skill" → "hand off to
79
+ harness-planner"
80
+ 3. **출력 경로 변경** — 원본의 `docs/superpowers/specs/YYYY-MM-DD-<topic>-design.md`
81
+ → `.harness/actions/brainstorm-spec.md` (Planner 의 입력 위치)
82
+ 4. **출력 포맷 변경** — walwal-harness docmeta 프론트매터 + Planner 가 사용하는
83
+ 12 개 섹션 (목적/성공기준/스코프/제약/접근법/아키텍처/컴포넌트/데이터흐름/
84
+ 에러처리/테스트전략/Open Questions/승인로그) 로 구조화
85
+ 5. **조건부 호출** — 원본은 "모든 창작 작업 전 필수" 였으나, harness 에서는 Dispatcher 가
86
+ 사용자에게 "브레인스토밍 필요?" 확인 후에만 호출 (피드백/이터레이션 케이스에서
87
+ 피로 최소화)
88
+ 6. **Skip 로직** — 기존 brainstorm-spec.md 존재 시 재사용 여부 확인
89
+
90
+ ## 보존된 핵심
91
+
92
+ - HARD-GATE (구현 전 디자인 필수)
93
+ - "Too simple to need a design" 안티패턴 경고
94
+ - 한 번에 한 질문 원칙
95
+ - 객관식 우선
96
+ - 2-3 개 접근법 탐색
97
+ - YAGNI
98
+ - Spec self-review loop
99
+ - User review gate
100
+ - Visual Companion 옵션
101
+
102
+ ## MIT License
103
+
104
+ 원본 저장소 [obra/superpowers](https://github.com/obra/superpowers) 의 MIT License
105
+ 전문은 아래 링크에서 확인할 수 있습니다:
106
+ https://github.com/obra/superpowers/blob/main/LICENSE
107
+
108
+ MIT License 하에 원본 저작권 표시 및 라이센스 고지 의무를 이 파일로 대체합니다.
109
+ 파생물 배포 시에도 이 attribution 파일을 유지해야 합니다.
@@ -0,0 +1,49 @@
1
+ # Spec Document Reviewer Prompt Template
2
+
3
+ Use this template when dispatching a spec document reviewer subagent.
4
+
5
+ **Purpose:** Verify the spec is complete, consistent, and ready for implementation planning.
6
+
7
+ **Dispatch after:** Spec document is written to docs/superpowers/specs/
8
+
9
+ ```
10
+ Task tool (general-purpose):
11
+ description: "Review spec document"
12
+ prompt: |
13
+ You are a spec document reviewer. Verify this spec is complete and ready for planning.
14
+
15
+ **Spec to review:** [SPEC_FILE_PATH]
16
+
17
+ ## What to Check
18
+
19
+ | Category | What to Look For |
20
+ |----------|------------------|
21
+ | Completeness | TODOs, placeholders, "TBD", incomplete sections |
22
+ | Consistency | Internal contradictions, conflicting requirements |
23
+ | Clarity | Requirements ambiguous enough to cause someone to build the wrong thing |
24
+ | Scope | Focused enough for a single plan — not covering multiple independent subsystems |
25
+ | YAGNI | Unrequested features, over-engineering |
26
+
27
+ ## Calibration
28
+
29
+ **Only flag issues that would cause real problems during implementation planning.**
30
+ A missing section, a contradiction, or a requirement so ambiguous it could be
31
+ interpreted two different ways — those are issues. Minor wording improvements,
32
+ stylistic preferences, and "sections less detailed than others" are not.
33
+
34
+ Approve unless there are serious gaps that would lead to a flawed plan.
35
+
36
+ ## Output Format
37
+
38
+ ## Spec Review
39
+
40
+ **Status:** Approved | Issues Found
41
+
42
+ **Issues (if any):**
43
+ - [Section X]: [specific issue] - [why it matters for planning]
44
+
45
+ **Recommendations (advisory, do not block approval):**
46
+ - [suggestions for improvement]
47
+ ```
48
+
49
+ **Reviewer returns:** Status, Issues (if any), Recommendations