@simplysm/sd-claude 13.0.69 → 13.0.71

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 (78) hide show
  1. package/README.md +12 -601
  2. package/claude/agents/sd-api-reviewer.md +0 -1
  3. package/claude/agents/sd-code-reviewer.md +0 -1
  4. package/claude/agents/sd-code-simplifier.md +1 -1
  5. package/claude/agents/sd-security-reviewer.md +0 -1
  6. package/claude/refs/sd-angular.md +26 -26
  7. package/claude/refs/sd-orm-v12.md +17 -17
  8. package/claude/rules/sd-refs-linker.md +14 -14
  9. package/claude/sd-statusline.js +21 -21
  10. package/claude/skills/sd-api-name-review/SKILL.md +1 -2
  11. package/claude/skills/sd-brainstorm/SKILL.md +3 -4
  12. package/claude/skills/sd-check/SKILL.md +1 -2
  13. package/claude/skills/sd-commit/SKILL.md +2 -3
  14. package/claude/skills/sd-debug/SKILL.md +1 -2
  15. package/claude/skills/sd-discuss/SKILL.md +1 -3
  16. package/claude/skills/sd-document/SKILL.md +99 -0
  17. package/claude/skills/sd-document/extract_docx.py +92 -0
  18. package/claude/skills/sd-document/extract_pdf.py +102 -0
  19. package/claude/skills/sd-document/extract_pptx.py +77 -0
  20. package/claude/skills/sd-document/extract_xlsx.py +83 -0
  21. package/claude/skills/sd-email-analyze/SKILL.md +6 -6
  22. package/claude/skills/sd-plan/SKILL.md +1 -3
  23. package/claude/skills/sd-plan-dev/SKILL.md +94 -111
  24. package/claude/skills/sd-plan-dev/code-quality-reviewer-prompt.md +1 -1
  25. package/claude/skills/sd-plan-dev/final-review-prompt.md +1 -1
  26. package/claude/skills/sd-plan-dev/spec-reviewer-prompt.md +1 -1
  27. package/claude/skills/sd-readme/SKILL.md +107 -88
  28. package/claude/skills/sd-review/SKILL.md +14 -16
  29. package/claude/skills/sd-skill/SKILL.md +6 -317
  30. package/claude/skills/sd-skill/cso-guide.md +161 -0
  31. package/claude/skills/sd-skill/writing-guide.md +163 -0
  32. package/claude/skills/sd-tdd/SKILL.md +1 -3
  33. package/claude/skills/sd-use/SKILL.md +1 -3
  34. package/claude/skills/sd-worktree/SKILL.md +52 -2
  35. package/dist/commands/auth-add.d.ts +2 -0
  36. package/dist/commands/auth-add.d.ts.map +1 -0
  37. package/dist/commands/auth-add.js +32 -0
  38. package/dist/commands/auth-add.js.map +6 -0
  39. package/dist/commands/auth-list.d.ts +2 -0
  40. package/dist/commands/auth-list.d.ts.map +1 -0
  41. package/dist/commands/auth-list.js +37 -0
  42. package/dist/commands/auth-list.js.map +6 -0
  43. package/dist/commands/auth-remove.d.ts +2 -0
  44. package/dist/commands/auth-remove.d.ts.map +1 -0
  45. package/dist/commands/auth-remove.js +22 -0
  46. package/dist/commands/auth-remove.js.map +6 -0
  47. package/dist/commands/auth-use.d.ts +2 -0
  48. package/dist/commands/auth-use.d.ts.map +1 -0
  49. package/dist/commands/auth-use.js +33 -0
  50. package/dist/commands/auth-use.js.map +6 -0
  51. package/dist/commands/auth-utils.d.ts +11 -0
  52. package/dist/commands/auth-utils.d.ts.map +1 -0
  53. package/dist/commands/auth-utils.js +57 -0
  54. package/dist/commands/auth-utils.js.map +6 -0
  55. package/dist/commands/install.js +3 -3
  56. package/dist/commands/install.js.map +1 -1
  57. package/dist/index.d.ts +5 -0
  58. package/dist/index.d.ts.map +1 -1
  59. package/dist/index.js +5 -0
  60. package/dist/index.js.map +1 -1
  61. package/dist/sd-claude.js +68 -3
  62. package/dist/sd-claude.js.map +1 -1
  63. package/package.json +3 -2
  64. package/scripts/sync-claude-assets.mjs +1 -1
  65. package/src/commands/auth-add.ts +36 -0
  66. package/src/commands/auth-list.ts +44 -0
  67. package/src/commands/auth-remove.ts +26 -0
  68. package/src/commands/auth-use.ts +53 -0
  69. package/src/commands/auth-utils.ts +65 -0
  70. package/src/commands/install.ts +19 -19
  71. package/src/index.ts +5 -0
  72. package/src/sd-claude.ts +81 -3
  73. package/tests/auth-add.spec.ts +74 -0
  74. package/tests/auth-list.spec.ts +175 -0
  75. package/tests/auth-remove.spec.ts +74 -0
  76. package/tests/auth-use.spec.ts +153 -0
  77. package/tests/auth-utils.spec.ts +173 -0
  78. package/claude/skills/sd-explore/SKILL.md +0 -78
@@ -0,0 +1,102 @@
1
+ #!/usr/bin/env python3
2
+ """PDF 파일에서 텍스트, 표, 이미지를 페이지별로 추출한다."""
3
+
4
+ import sys
5
+ import io
6
+ import subprocess
7
+ from pathlib import Path
8
+
9
+ sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8", errors="replace")
10
+ sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding="utf-8", errors="replace")
11
+
12
+
13
+ def ensure_packages():
14
+ packages = {"pdfplumber": "pdfplumber", "pypdf": "pypdf"}
15
+ for pip_name, import_name in packages.items():
16
+ try:
17
+ __import__(import_name)
18
+ except ImportError:
19
+ print(f"패키지 설치 중: {pip_name}...", file=sys.stderr)
20
+ subprocess.check_call([sys.executable, "-m", "pip", "install", pip_name],
21
+ stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
22
+
23
+
24
+ def extract(file_path):
25
+ import pdfplumber
26
+ from pypdf import PdfReader
27
+
28
+ stem = Path(file_path).stem
29
+ out_dir = Path(file_path).parent / f"{stem}_files"
30
+ img_idx = 0
31
+ total_text_len = 0
32
+
33
+ print(f"# {Path(file_path).name}\n")
34
+
35
+ # 텍스트 + 표 추출 (pdfplumber)
36
+ with pdfplumber.open(file_path) as pdf:
37
+ for page_num, page in enumerate(pdf.pages, 1):
38
+ print(f"## Page {page_num}\n")
39
+
40
+ text = page.extract_text()
41
+ if text and text.strip():
42
+ total_text_len += len(text.strip())
43
+ print(text.strip())
44
+ print()
45
+
46
+ tables = page.extract_tables()
47
+ for t_idx, table in enumerate(tables):
48
+ if table:
49
+ print(f"### Table {t_idx + 1}\n")
50
+ for row in table:
51
+ cells = [(c or "").strip().replace("\n", " ") for c in row]
52
+ print("| " + " | ".join(cells) + " |")
53
+ print()
54
+
55
+ # 이미지 추출 (pypdf)
56
+ reader = PdfReader(file_path)
57
+ for page_num, page in enumerate(reader.pages, 1):
58
+ if "/XObject" not in (page.get("/Resources") or {}):
59
+ continue
60
+ xobjects = page["/Resources"]["/XObject"].get_object()
61
+ for obj_name in xobjects:
62
+ obj = xobjects[obj_name].get_object()
63
+ if obj.get("/Subtype") == "/Image":
64
+ img_idx += 1
65
+ filters = obj.get("/Filter", "")
66
+ if isinstance(filters, list):
67
+ filters = filters[0] if filters else ""
68
+ ext = "png"
69
+ if "/DCTDecode" in str(filters):
70
+ ext = "jpg"
71
+ elif "/JPXDecode" in str(filters):
72
+ ext = "jp2"
73
+ out_dir.mkdir(parents=True, exist_ok=True)
74
+ img_path = out_dir / f"img_{img_idx:03d}.{ext}"
75
+ try:
76
+ img_path.write_bytes(obj.get_data())
77
+ except Exception:
78
+ img_path = out_dir / f"img_{img_idx:03d}.bin"
79
+ img_path.write_bytes(obj._data if hasattr(obj, "_data") else b"")
80
+ print(f"[IMG] (page={page_num}) {img_path}")
81
+
82
+ # OCR 안내
83
+ if total_text_len == 0:
84
+ print("\n⚠ 텍스트가 추출되지 않았습니다 (스캔 PDF일 수 있음).")
85
+ print("OCR이 필요합니다:")
86
+ print(" 1. Tesseract OCR 설치: https://github.com/tesseract-ocr/tesseract")
87
+ print(" 2. pip install pytesseract pdf2image")
88
+ print(" 3. pytesseract.image_to_string() 으로 추출")
89
+
90
+ print()
91
+ if img_idx > 0:
92
+ print(f"---\n이미지 {img_idx}개 저장: {out_dir}")
93
+ else:
94
+ print("---\n이미지 없음")
95
+
96
+
97
+ if __name__ == "__main__":
98
+ if len(sys.argv) < 2:
99
+ print("Usage: python extract_pdf.py <file.pdf>", file=sys.stderr)
100
+ sys.exit(1)
101
+ ensure_packages()
102
+ extract(sys.argv[1])
@@ -0,0 +1,77 @@
1
+ #!/usr/bin/env python3
2
+ """PPTX 파일에서 텍스트와 이미지를 슬라이드별 좌표와 함께 추출한다."""
3
+
4
+ import sys
5
+ import io
6
+ import subprocess
7
+ from pathlib import Path
8
+
9
+ sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8", errors="replace")
10
+ sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding="utf-8", errors="replace")
11
+
12
+
13
+ def ensure_packages():
14
+ packages = {"python-pptx": "pptx"}
15
+ for pip_name, import_name in packages.items():
16
+ try:
17
+ __import__(import_name)
18
+ except ImportError:
19
+ print(f"패키지 설치 중: {pip_name}...", file=sys.stderr)
20
+ subprocess.check_call([sys.executable, "-m", "pip", "install", pip_name],
21
+ stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
22
+
23
+
24
+ def emu_to_inches(emu):
25
+ """EMU를 인치로 변환 (소수점 1자리)."""
26
+ if emu is None:
27
+ return "?"
28
+ return f"{emu / 914400:.1f}"
29
+
30
+
31
+ def extract(file_path):
32
+ from pptx import Presentation
33
+ from pptx.enum.shapes import MSO_SHAPE_TYPE
34
+
35
+ prs = Presentation(file_path)
36
+ stem = Path(file_path).stem
37
+ out_dir = Path(file_path).parent / f"{stem}_files"
38
+ img_idx = 0
39
+
40
+ print(f"# {Path(file_path).name}\n")
41
+
42
+ for slide_num, slide in enumerate(prs.slides, 1):
43
+ print(f"## Slide {slide_num}\n")
44
+
45
+ for shape in slide.shapes:
46
+ left = emu_to_inches(shape.left)
47
+ top = emu_to_inches(shape.top)
48
+ pos = f"(left={left}\", top={top}\")"
49
+
50
+ if shape.shape_type == MSO_SHAPE_TYPE.PICTURE:
51
+ img_idx += 1
52
+ blob = shape.image.blob
53
+ content_type = shape.image.content_type
54
+ ext = content_type.split("/")[-1].replace("jpeg", "jpg")
55
+ out_dir.mkdir(parents=True, exist_ok=True)
56
+ img_path = out_dir / f"img_{img_idx:03d}.{ext}"
57
+ img_path.write_bytes(blob)
58
+ print(f"[IMG] {pos} {img_path}")
59
+
60
+ elif hasattr(shape, "text") and shape.text.strip():
61
+ text = shape.text.strip().replace("\n", "\n ")
62
+ print(f"[TXT] {pos} {text}")
63
+
64
+ print()
65
+
66
+ if img_idx > 0:
67
+ print(f"---\n이미지 {img_idx}개 저장: {out_dir}")
68
+ else:
69
+ print("---\n이미지 없음")
70
+
71
+
72
+ if __name__ == "__main__":
73
+ if len(sys.argv) < 2:
74
+ print("Usage: python extract_pptx.py <file.pptx>", file=sys.stderr)
75
+ sys.exit(1)
76
+ ensure_packages()
77
+ extract(sys.argv[1])
@@ -0,0 +1,83 @@
1
+ #!/usr/bin/env python3
2
+ """XLSX 파일에서 데이터와 이미지를 셀 위치와 함께 추출한다."""
3
+
4
+ import sys
5
+ import io
6
+ import os
7
+ import subprocess
8
+ from pathlib import Path
9
+
10
+ sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8", errors="replace")
11
+ sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding="utf-8", errors="replace")
12
+
13
+
14
+ def ensure_packages():
15
+ packages = {"openpyxl": "openpyxl"}
16
+ for pip_name, import_name in packages.items():
17
+ try:
18
+ __import__(import_name)
19
+ except ImportError:
20
+ print(f"패키지 설치 중: {pip_name}...", file=sys.stderr)
21
+ subprocess.check_call([sys.executable, "-m", "pip", "install", pip_name],
22
+ stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
23
+
24
+
25
+ def extract(file_path):
26
+ from openpyxl import load_workbook
27
+ from openpyxl.drawing.image import Image as XlImage
28
+
29
+ wb = load_workbook(file_path, data_only=True)
30
+ stem = Path(file_path).stem
31
+ out_dir = Path(file_path).parent / f"{stem}_files"
32
+ img_idx = 0
33
+
34
+ print(f"# {Path(file_path).name}\n")
35
+
36
+ for sheet_name in wb.sheetnames:
37
+ ws = wb[sheet_name]
38
+ print(f"## Sheet: {sheet_name}\n")
39
+
40
+ # 데이터 추출
41
+ rows = list(ws.iter_rows(values_only=False))
42
+ if not rows:
43
+ print("(빈 시트)\n")
44
+ continue
45
+
46
+ for row in rows:
47
+ cells = []
48
+ for cell in row:
49
+ val = cell.value
50
+ if val is None:
51
+ cells.append("")
52
+ else:
53
+ cells.append(str(val).strip())
54
+ print(f"[{row[0].coordinate.split('1')[0]}{row[0].row}] " + " | ".join(cells))
55
+
56
+ # 이미지 추출
57
+ if ws._images:
58
+ for img in ws._images:
59
+ img_idx += 1
60
+ anchor = ""
61
+ if hasattr(img.anchor, '_from'):
62
+ anchor = f" (near {img.anchor._from.col},{img.anchor._from.row})"
63
+ ext = "png"
64
+ out_dir.mkdir(parents=True, exist_ok=True)
65
+ img_path = out_dir / f"img_{img_idx:03d}.{ext}"
66
+ with open(img_path, "wb") as f:
67
+ f.write(img._data())
68
+ print(f"[IMG]{anchor} {img_path}")
69
+
70
+ print()
71
+
72
+ if img_idx > 0:
73
+ print(f"---\n이미지 {img_idx}개 저장: {out_dir}")
74
+ else:
75
+ print("---\n이미지 없음")
76
+
77
+
78
+ if __name__ == "__main__":
79
+ if len(sys.argv) < 2:
80
+ print("Usage: python extract_xlsx.py <file.xlsx>", file=sys.stderr)
81
+ sys.exit(1)
82
+ ensure_packages()
83
+ extract(sys.argv[1])
@@ -1,19 +1,19 @@
1
1
  ---
2
2
  name: sd-email-analyze
3
- description: Email file (.eml/.msg) parsing and attachment extraction
4
- disable-model-invocation: true
3
+ description: "Use when the user's request involves .eml or .msg files. Triggers: email file analysis, email content extraction, attachment extraction, email summary."
4
+ model: haiku
5
5
  ---
6
6
 
7
7
  # Email Analyzer
8
8
 
9
9
  ## Overview
10
10
 
11
- Python script that parses `.eml` and `.msg` (Outlook) email files. Extracts mail headers, body text, inline images, and attachments to disk. Content analysis of extracted files is delegated to Claude's Read tool and document-skills plugin.
11
+ Python script that parses `.eml` and `.msg` (Outlook) email files. Extracts mail headers, body text, inline images, and attachments to disk. Content analysis of extracted files is delegated to Claude's Read tool and `sd-document` skill.
12
12
 
13
13
  ## When to Use
14
14
 
15
15
  - User provides a `.eml` or `.msg` file to analyze or summarize
16
- - Korean email content needs proper decoding
16
+ - Email content needs proper decoding
17
17
 
18
18
  ## Usage
19
19
 
@@ -27,7 +27,7 @@ First run auto-installs: `extract-msg`.
27
27
 
28
28
  1. Read the markdown output (mail info, body text, file paths)
29
29
  2. **Inline images**: Use **Read** tool on each saved path to view
30
- 3. **Attachments**: Use **Read** tool (PDF, images) or let **document-skills** plugin handle (XLSX, PPTX, DOCX)
30
+ 3. **Attachments**: Use **Read** tool (images) or **sd-document** skill scripts (DOCX, XLSX, PPTX, PDF)
31
31
 
32
32
  ## Output
33
33
 
@@ -49,4 +49,4 @@ Two sources extracted:
49
49
 
50
50
  - **Wrong Python**: Ensure `python` points to Python 3.8+
51
51
  - **Firewall blocking pip**: First run needs internet for `extract-msg` install
52
- - **Forgetting inline images**: Always check "본문 삽입 이미지" section and Read each path
52
+ - **Forgetting inline images**: Always check the "Inline images" section and read each path
@@ -1,8 +1,6 @@
1
1
  ---
2
2
  name: sd-plan
3
- description: Implementation plan creation from brainstorm designs
4
- disable-model-invocation: true
5
- model: opus
3
+ description: "Implementation plan from brainstorm designs (explicit invocation only)"
6
4
  ---
7
5
 
8
6
  # Writing Plans
@@ -1,15 +1,13 @@
1
1
  ---
2
2
  name: sd-plan-dev
3
- description: Parallel execution of implementation plan tasks
4
- disable-model-invocation: true
5
- model: opus
3
+ description: "Parallel execution of plan tasks (explicit invocation only)"
6
4
  ---
7
5
 
8
6
  # Parallel Plan Execution
9
7
 
10
- Execute plan tasks via parallel Task agents with dependency-aware scheduling.
8
+ Execute plan tasks via parallel implementers with dependency-aware scheduling.
11
9
 
12
- **Core principle:** Dependency analysis + parallel Task agents + nested parallel reviews = maximum throughput
10
+ **Core principle:** Dependency analysis + parallel implementers + orchestrator-managed reviews = maximum throughput
13
11
 
14
12
  ## When to Use
15
13
 
@@ -28,11 +26,16 @@ digraph when_to_use {
28
26
 
29
27
  All execution uses `Task(general-purpose)` for parallel execution.
30
28
 
31
- - **task agent**: `Task(general-purpose)` — implements one task, launches sub-Tasks for review, fixes issues
32
- - **spec reviewer**: `Task(general-purpose, model: "opus")` — sub-Task launched by task agent (read-only)
33
- - **quality reviewer**: `Task(general-purpose, model: "opus")` — sub-Task launched by task agent (read-only)
29
+ - **implementer**: `Task(general-purpose, model: min(sonnet, current))` — implements one task, commits, reports
30
+ - **spec reviewer**: `Task(general-purpose)` — dispatched by orchestrator after implementer completes (read-only)
31
+ - **quality reviewer**: `Task(general-purpose)` — dispatched by orchestrator in parallel with spec reviewer (read-only)
32
+ - **final reviewer**: `Task(general-purpose)` — dispatched by orchestrator after all batches complete (read-only)
34
33
 
35
- Independent tasks run as **parallel Task calls in a single message**. Within each task agent, spec and quality reviews also run as **parallel sub-Task calls**.
34
+ **Model selection:**
35
+ - **implementer**: use `min(sonnet, current model)`. If the user's current model is haiku, use haiku. Otherwise use sonnet.
36
+ - **All other agents**: inherit current model (no explicit `model` parameter).
37
+
38
+ Independent tasks run as **parallel Task calls in a single message**. After implementers complete, spec and quality reviews run as **parallel Task calls**.
36
39
 
37
40
  **CRITICAL: Do NOT use `run_in_background: true`** — achieve parallelism by making multiple Task calls in a single message (foreground parallel). This ensures the orchestrator waits for all tasks to complete before proceeding to the next batch, and prevents Stop hooks from firing prematurely.
38
41
 
@@ -48,33 +51,38 @@ digraph process {
48
51
  subgraph cluster_batch {
49
52
  label="Per Batch (independent tasks)";
50
53
 
51
- subgraph cluster_parallel_tasks {
52
- label="Parallel Task calls (single message)";
54
+ subgraph cluster_parallel_implementers {
55
+ label="Parallel implementer Task calls (single message)";
53
56
  style=dashed;
54
57
 
55
- subgraph cluster_task_agent {
56
- label="Each Task Agent";
58
+ subgraph cluster_implementer {
59
+ label="Each Implementer";
57
60
  "Implement the task" [shape=box];
58
61
  "Questions?" [shape=diamond];
59
62
  "Return questions to orchestrator" [shape=box];
60
63
  "Re-launch with answers" [shape=box];
64
+ "Commit and report" [shape=box];
65
+ }
66
+ }
67
+
68
+ subgraph cluster_review {
69
+ label="Orchestrator review loop (per implementer)";
61
70
 
62
- subgraph cluster_nested_review {
63
- label="Parallel sub-Task calls";
64
- style=dashed;
65
- "sub-Task: spec reviewer" [shape=box];
66
- "sub-Task: quality reviewer" [shape=box];
67
- }
68
-
69
- "Any issues?" [shape=diamond];
70
- "Fix all issues" [shape=box];
71
- "Re-review failed aspects (parallel sub-Task)" [shape=box];
72
- "Report results" [shape=box];
71
+ subgraph cluster_parallel_reviewers {
72
+ label="Parallel reviewer Task calls (single message)";
73
+ style=dashed;
74
+ "Task: spec reviewer" [shape=box];
75
+ "Task: quality reviewer" [shape=box];
73
76
  }
77
+
78
+ "Any issues?" [shape=diamond];
79
+ "Task: implementer fix" [shape=box];
80
+ "Re-review (parallel Task calls)" [shape=box];
74
81
  }
75
82
  }
76
83
 
77
84
  "More batches?" [shape=diamond];
85
+ "Batch integration check (typecheck + lint)" [shape=box];
78
86
  "Task: final review for entire implementation" [shape=box];
79
87
  "Done" [shape=ellipse];
80
88
 
@@ -84,17 +92,17 @@ digraph process {
84
92
  "Questions?" -> "Return questions to orchestrator" [label="yes"];
85
93
  "Return questions to orchestrator" -> "Re-launch with answers";
86
94
  "Re-launch with answers" -> "Implement the task";
87
- "Questions?" -> "sub-Task: spec reviewer" [label="no"];
88
- "Questions?" -> "sub-Task: quality reviewer" [label="no"];
89
- "sub-Task: spec reviewer" -> "Any issues?";
90
- "sub-Task: quality reviewer" -> "Any issues?";
91
- "Any issues?" -> "Fix all issues" [label="yes"];
92
- "Fix all issues" -> "Re-review failed aspects (parallel sub-Task)";
93
- "Re-review failed aspects (parallel sub-Task)" -> "Any issues?";
94
- "Any issues?" -> "Report results" [label="no"];
95
- "Report results" -> "More batches?";
96
- "More batches?" -> "Batch integration check (typecheck + lint)" [label="yes"];
97
- "Batch integration check (typecheck + lint)" -> "Implement the task" [label="next batch"];
95
+ "Questions?" -> "Commit and report" [label="no"];
96
+ "Commit and report" -> "Task: spec reviewer";
97
+ "Commit and report" -> "Task: quality reviewer";
98
+ "Task: spec reviewer" -> "Any issues?";
99
+ "Task: quality reviewer" -> "Any issues?";
100
+ "Any issues?" -> "Task: implementer fix" [label="yes"];
101
+ "Task: implementer fix" -> "Re-review (parallel Task calls)";
102
+ "Re-review (parallel Task calls)" -> "Any issues?";
103
+ "Any issues?" -> "Batch integration check (typecheck + lint)" [label="no"];
104
+ "Batch integration check (typecheck + lint)" -> "More batches?";
105
+ "More batches?" -> "Implement the task" [label="yes, next batch"];
98
106
  "More batches?" -> "Task: final review for entire implementation" [label="no"];
99
107
  "Task: final review for entire implementation" -> "Done";
100
108
  }
@@ -122,46 +130,30 @@ Example: 5 tasks
122
130
  Batch 3: [Task 4] — depends on Task 1
123
131
  ```
124
132
 
125
- ## Task Agent Prompt
126
-
127
- Each task agent receives a prompt combining implementation + review instructions:
133
+ ## Implementer Prompt
128
134
 
129
- ```
130
- You are implementing and reviewing Task N: [task name]
135
+ Each implementer receives a prompt based on `./implementer-prompt.md`. Fill in all `[bracketed]` sections before dispatching.
131
136
 
132
- ## Task Description
137
+ ## Reviewer Dispatch
133
138
 
134
- [FULL TEXT of task from plan]
139
+ After an implementer completes and reports, the orchestrator dispatches reviewers:
135
140
 
136
- ## Context
137
-
138
- [Scene-setting: where this fits, dependencies, architectural context]
139
-
140
- ## Your Job
141
-
142
- 1. Implement exactly what the task specifies
143
- 2. Write tests (following TDD if task says to)
144
- 3. Verify implementation works
145
- 4. Self-review: did I implement everything? Did I over-build?
146
- 5. Commit your work (record the BASE_SHA before and HEAD_SHA after)
147
- 6. Launch TWO parallel sub-Tasks (spec review + quality review):
148
- - Sub-Task 1: spec reviewer — send spec-reviewer-prompt.md based prompt
149
- - Sub-Task 2: quality reviewer — send code-quality-reviewer-prompt.md based prompt, include BASE_SHA and HEAD_SHA
150
- 7. If either reviewer finds issues → fix them → re-review only failed aspects (parallel sub-Tasks again)
151
- 8. Repeat until both reviewers approve
152
- 9. Report back with: what you implemented, test results, files changed, commit SHA, review outcomes
153
-
154
- If you have questions about requirements — return them immediately WITHOUT implementing. Don't guess.
155
- If you encounter unexpected issues mid-implementation — ask rather than guess.
156
-
157
- Work from: [directory]
158
- ```
141
+ 1. Record the implementer's commit SHA and files changed from its report
142
+ 2. Dispatch TWO parallel Task calls (single message):
143
+ - spec reviewer fill `./spec-reviewer-prompt.md` with task requirements + implementer report
144
+ - quality reviewer — fill `./code-quality-reviewer-prompt.md` with implementer report + BASE_SHA/HEAD_SHA
145
+ 3. If either reviewer returns CHANGES_NEEDED:
146
+ - Re-dispatch implementer with fix instructions (all issues from both reviewers combined)
147
+ - After fix, re-dispatch only the failed reviewers (parallel Task calls)
148
+ - Repeat until both approve
149
+ 4. Proceed to next task or batch
159
150
 
160
151
  ## Prompt Templates
161
152
 
162
- - `./implementer-prompt.md` — base implementer instructions (referenced by task agent)
163
- - `./spec-reviewer-prompt.md` — spec compliance review sub-Task prompt
164
- - `./code-quality-reviewer-prompt.md` — code quality review sub-Task prompt
153
+ - `./implementer-prompt.md` — implementer instructions
154
+ - `./spec-reviewer-prompt.md` — spec compliance review prompt
155
+ - `./code-quality-reviewer-prompt.md` — code quality review prompt
156
+ - `./final-review-prompt.md` — final integration review prompt
165
157
 
166
158
  ## Example Workflow
167
159
 
@@ -181,56 +173,47 @@ You: Using sd-plan-dev to execute this plan.
181
173
  Batch 1: [Task 1, Task 2, Task 5]
182
174
  Batch 2: [Task 3, Task 4]
183
175
 
184
- --- Batch 1: parallel ---
176
+ --- Batch 1: parallel implementers ---
185
177
 
186
- [3 parallel Task calls in single message]
178
+ [3 parallel implementer Task calls in single message]
187
179
 
188
- Task 1 agent:
189
- - Implemented validator, tests 5/5 pass
190
- - Parallel sub-Tasks: spec ✅, quality
191
- → Done
180
+ Implementer 1: Implemented validator, tests 5/5 pass → committed
181
+ Implementer 2: "Should auth use JWT or session?" (question returned)
182
+ Implementer 5: Implemented endpoints, tests 3/3 pass → committed
192
183
 
193
- Task 2 agent:
194
- - "Should auth use JWT or session?" (question returned)
184
+ [Answer Implementer 2 question: "JWT"]
185
+ [Re-launch Implementer 2 with answer]
186
+ Implementer 2: Implemented auth hook with JWT, tests 4/4 pass → committed
195
187
 
196
- Task 5 agent:
197
- - Implemented endpoints, tests 3/3 pass
198
- - Parallel sub-Tasks: spec ✅, quality: Issues (magic number)
199
- - Fixed magic number
200
- - Parallel re-review: quality ✅
201
- → Done
188
+ [Orchestrator dispatches reviewers for each completed implementer]
202
189
 
203
- [Answer Task 2 question: "JWT"]
204
- [Re-launch Task 2 agent with answer]
190
+ Task 1 reviews: [parallel] spec ✅, quality ✅ → Done
191
+ Task 2 reviews: [parallel] spec ✅, quality ✅ → Done
192
+ Task 5 reviews: [parallel] spec ✅, quality ❌ (magic number)
193
+ → Re-dispatch Implementer 5 to fix → committed
194
+ → Re-review quality ✅ → Done
205
195
 
206
- Task 2 agent:
207
- - Implemented auth hook with JWT, tests 4/4 pass
208
- - Parallel sub-Tasks: spec ✅, quality ✅
209
- → Done
196
+ [Batch 1 complete → integration check]
210
197
 
211
- [Batch 1 complete]
198
+ --- Batch 2: parallel implementers ---
212
199
 
213
- --- Batch 2: parallel ---
200
+ [2 parallel implementer Task calls in single message]
214
201
 
215
- [2 parallel Task calls in single message]
202
+ Implementer 3: Implemented login component committed
203
+ Implementer 4: Updated validator → committed
216
204
 
217
- Task 3 agent:
218
- - Implemented login component using Task 2's auth hook
219
- - Parallel sub-Tasks: spec ❌ (missing error state), quality ✅
220
- - Fixed error state
221
- - spec re-review ✅
222
- → Done
205
+ [Orchestrator dispatches reviewers]
223
206
 
224
- Task 4 agent:
225
- - Updated validator with new rules
226
- - Parallel sub-Tasks: spec ✅, quality
227
- → Done
207
+ Task 3 reviews: [parallel] spec ❌ (missing error state), quality ✅
208
+ → Re-dispatch Implementer 3 to fix → committed
209
+ Re-review spec Done
210
+ Task 4 reviews: [parallel] spec ✅, quality ✅ → Done
228
211
 
229
- [Batch 2 complete]
212
+ [Batch 2 complete → integration check]
230
213
 
231
214
  --- Final ---
232
215
 
233
- [Task final review for entire implementation]
216
+ [Task: final review for entire implementation]
234
217
  Final reviewer: All requirements met, ready to merge
235
218
 
236
219
  Done!
@@ -256,26 +239,26 @@ This catches cross-task integration issues early — especially when the next ba
256
239
  - Proceed with unfixed issues
257
240
  - Put tasks with file overlap in the same parallel batch
258
241
  - Skip dependency analysis
259
- - Make task agent read plan file directly (provide full text instead)
242
+ - Make implementer read plan file directly (provide full text instead)
260
243
  - Skip scene-setting context
261
244
  - Accept "close enough" on spec compliance
262
245
  - Skip review loops (issue found → fix → re-review)
263
246
  - Skip batch integration checks between batches
264
247
  - Use `run_in_background: true` on Task calls (use foreground parallel instead)
265
248
 
266
- **If task agent returns questions:**
249
+ **If implementer returns questions:**
267
250
 
268
251
  - Answer clearly and completely
269
- - Re-launch that agent with answers included
270
- - Other parallel agents continue unaffected
252
+ - Re-launch that implementer with answers included
253
+ - Other parallel implementers continue unaffected
271
254
 
272
255
  **If reviewers find issues:**
273
256
 
274
- - Task agent fixes all issues from both reviewers at once
275
- - Re-review only the failed aspects (parallel sub-Tasks)
257
+ - Orchestrator re-dispatches implementer with all issues from both reviewers combined
258
+ - After fix, re-dispatch only the failed reviewers (parallel Task calls)
276
259
  - Repeat until both approved
277
260
 
278
- **If task agent fails or times out:**
261
+ **If implementer fails or times out:**
279
262
 
280
263
  - Do NOT silently proceed — the affected files may be in an indeterminate state
281
264
  - Check if other tasks in the same batch depend on the failed task's output
@@ -288,5 +271,5 @@ This catches cross-task integration issues early — especially when the next ba
288
271
  **Related skills:**
289
272
 
290
273
  - **sd-plan** — creates the plan this skill executes
291
- - **sd-tdd** — task agents follow TDD
274
+ - **sd-tdd** — implementers follow TDD
292
275
  - **sd-worktree** — branch isolation for worktree-based workflows
@@ -1,6 +1,6 @@
1
1
  # Code Quality Reviewer Prompt
2
2
 
3
- Template for `Task(general-purpose, model: "opus")`.
3
+ Template for `Task(general-purpose)`.
4
4
  Runs in parallel with spec reviewer. Fill in all `[bracketed]` sections.
5
5
 
6
6
  ```
@@ -1,6 +1,6 @@
1
1
  # Final Review Prompt
2
2
 
3
- Template for `Task(general-purpose, model: "opus")`.
3
+ Template for `Task(general-purpose)`.
4
4
  Run after all batches complete. Fill in all `[bracketed]` sections.
5
5
 
6
6
  ```
@@ -1,6 +1,6 @@
1
1
  # Spec Compliance Reviewer Prompt
2
2
 
3
- Template for `Task(general-purpose, model: "opus")`.
3
+ Template for `Task(general-purpose)`.
4
4
  Runs in parallel with quality reviewer. Fill in all `[bracketed]` sections.
5
5
 
6
6
  ```