From dev-workflow
Use when the user says 'run phase', 'start phase N', 'next phase', '继续开发', '跑下一阶段', '开始第N阶段', or when continuing development guided by a dev-guide. Orchestrates the plan-execute-review cycle for one phase of a development guide.
npx claudepluginhub n0rvyn/indie-toolkit --plugin dev-workflowThis skill uses the workspace's default tool permissions.
This skill orchestrates one iteration of the development cycle. Opus handles judgment-intensive steps (planning, fixing) in main context; Sonnet handles mechanical execution as a dispatched agent; Opus reviews in dispatched agents for unbiased assessment.
Searches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.
Searches prompts.chat for AI prompt templates by keyword or category, retrieves by ID with variable handling, and improves prompts via AI. Use for discovering or enhancing prompts.
Designs and optimizes AI agent action spaces, tool definitions, observation formats, error recovery, and context for higher task completion rates.
This skill orchestrates one iteration of the development cycle. Opus handles judgment-intensive steps (planning, fixing) in main context; Sonnet handles mechanical execution as a dispatched agent; Opus reviews in dispatched agents for unbiased assessment.
Locate/Resume Phase
→ scope confirmation checkpoint (main context — opus)
→ write plan (main context — opus, full conversation context)
→ UX review checkpoint (main context — if design has UX Assertions)
→ verify plan (dispatch opus agent — unbiased review)
→ execute plan (dispatch sonnet agent — mechanical, follows verified plan)
→ dispatch feature-spec + review agents in parallel (separate contexts)
→ fix all issues (main context — opus: execution failures + review gaps)
→ Phase done
Location: .claude/dev-workflow-state.yml
This file tracks progress across sessions. Update it before starting each step (so crash-resume works). Read/write via the Read and Write tools.
project: <name>
current_phase: 2
phase_name: "Phase Name"
phase_step: plan # plan | ux-review | verify | execute | review | fix | done
dev_guide: docs/06-plans/YYYY-MM-DD-project-dev-guide.md
plan_file: null # set to docs/06-plans/YYYY-MM-DD-<name>-plan.md after Step 2
verification_report: null
task_progress: null
review_reports: []
gaps_remaining: 0
last_updated: "YYYY-MM-DDTHH:MM:SS"
.claude/dev-workflow-state.yml:
!cat .claude/dev-workflow-state.yml 2>/dev/null || echo "NO_STATE_FILE"
If output is "NO_STATE_FILE": proceed to step 2 (starting fresh).
Otherwise: parse the YAML content from the output.
phase_step is spec (legacy): treat as review and proceed to Step 5phase_step is build-test (legacy): treat as review and proceed to Step 5. Note: build/test from the old separate step was not run; finalize will catch any issues via full test suite.phase_step is not done:
phase_step is plan AND plan_file is not null): Read the Phase's current scope from the dev-guide and compare with the plan file's Scope: section. If they differ: "Dev-guide scope has changed since the plan was written. Re-run scope confirmation (Step 1.5)?" If user accepts: reset phase_step: plan, plan_file: null, and run Step 1.5. If user declines: proceed with existing plan. For steps after plan (verify/execute/review/fix): no check needed — the plan is the working document.phase_stepdocs/06-plans/*-dev-guide.md (if multiple, prefer the file with current: true in frontmatter; if no file has a current: field in frontmatter, treat all as candidates and ask user)project: <from dev-guide title>
current_phase: <N>
phase_name: "<Phase name>"
phase_step: plan
dev_guide: <dev-guide path>
plan_file: null
verification_report: null
task_progress: null
review_reports: []
gaps_remaining: 0
last_updated: "<now>"
If the user specifies a different Phase number, use that instead.
Before writing the plan, present the Phase scope and visual expectations for explicit user confirmation.
Skip condition: When resuming from state file with phase_step not plan, skip this step — scope was already confirmed in a prior session.
Freshness check: Before presenting, read the dev-guide's YAML frontmatter for confirmed_at:. If the timestamp is within 60 minutes of now, use lightweight mode (step 1b). Otherwise, use full mode (step 1a).
1a. Full mode (default):
Read the Phase's scope items and **用户可见的变化:** section from the dev-guide. Present to the user:
Phase {N} — confirm before planning:
范围:
1. {scope item 1}
2. {scope item 2}
...
用户可见的变化:
- {visual expectation 1, from dev-guide}
- {visual expectation 2}
(如果有需要补充的布局、交互细节,请在这一步告诉我)
确认以上内容,或补充/修正后继续。
If **用户可见的变化:** starts with "无" (infrastructure Phase, e.g., "无" or "无 — 纯基建阶段"), present scope only (omit the visual section).
1b. Lightweight mode (confirmed_at within 60 min):
Phase {N} 范围已在 dev-guide 中确认。
有新增视觉/交互细节要补充吗?没有则直接开始规划。
User responds:
Wait for user response (full mode only):
**Scope:** bulleted list in the dev-guide file to match user's corrections, then check acceptance criteria sync (see below), re-present for confirmationAcceptance criteria sync (after scope correction): Compare the Phase's **Acceptance criteria:** with the updated scope:
Auto-crystal (conditional): If the user's response contains any new visual/interaction detail not already in the dev-guide's 用户可见的变化 section, treat as "adds details" regardless of whether they also said "confirmed."
4a. Assemble decisions: Extract from the user's input:
[D-xxx] in imperative form## Rejected Alternatives + ## ConstraintsNone. for those sections4b. Confirm with user: Present the assembled decisions in-line:
以下视觉/交互决策将记录供后续规划使用:
- [D-001] {detail}
- [D-002] {detail}
约束:{constraints, or "无"}
确认记录,或修改后继续。
Apply user edits if any, then proceed to write.
4c. Write crystal file:
docs/11-crystals/*-crystal.md for an existing crystal file[D-xxx] entries (continuing the existing numbering) to ## Decisions (machine-readable), merge new items into ## Constraints and ## Scope Boundaries. Do not overwrite existing content.docs/11-crystals/YYYY-MM-DD-phase-{N}-visual-crystal.md using this format:# Decision Crystal: Phase {N} Visual Expectations
Date: YYYY-MM-DD
## Initial Idea
{User's original visual description, denoised but not rewritten}
## Discussion Points
{Any back-and-forth from the confirmation, if applicable}
## Rejected Alternatives
{Approaches the user explicitly rejected, or "None."}
## Decisions (machine-readable)
- [D-001] {confirmed visual/interaction detail in imperative form}
- [D-002] {detail}
## Constraints
{Explicitly rejected visual approaches, or "None."}
## Scope Boundaries
- IN: {items from user's visual additions}
## Source Context
- Design doc: {path or "none"}
- Dev-guide: {dev-guide path} Phase {N}
This checkpoint catches scope pollution and aligns visual expectations before writing the plan.
phase_step: plan, last_updated: <now>docs/06-plans/*-design-analysis.md; if exactly 1 file, use it; if multiple, use the one whose filename matches the Phase's feature topic; if still ambiguous, ask the user; if none, set to "none"docs/11-crystals/*-crystal.md; if exactly 1 file, use it; if multiple, ask the user which one applies; if none, set to "none"/crystallize to capture these decisions before planning. Do not block — user can decline and proceed without a crystal file.## UX Assertions section. Note the result — it controls Step 2.5.docs/09-lessons-learned/ for entries matching these keywords:
Grep(pattern="<keyword1>|<keyword2>|<keyword3>", path="docs/09-lessons-learned/", output_mode="content", context=5)${CLAUDE_PLUGIN_ROOT}/skills/write-plan/SKILL.md. Use the gathered Phase context as inputs. Save to docs/06-plans/YYYY-MM-DD-<feature-name>-plan.md.plan_file: <path>, last_updated: <now>## Decisions section of the plan file.
blocking decision: present to user via AskUserQuestion with options from the decision pointrecommended decisions: present as a group via a single AskUserQuestion. Critical: all DP content must be inside the question field — text printed before AskUserQuestion gets visually covered by the question widget. Read each recommended DP's full block (heading + Context + Options + Recommendation) from the plan file and concatenate them verbatim in the question field, separated by \n---\n. End with: \n\n全部接受推荐,还是逐个审查?**Recommendation:** or **Recommendation (unverified):** line with **Chosen:** {user's choice}--fast flag for Step 3 (use Sonnet for verification).
If task count ≥ 5: no flag (use Opus default).Trigger condition: The design doc contains a ## UX Assertions section with at least one assertion row (not just the header). If no design doc, no UX Assertions section, or the table has zero assertion rows, skip to Step 3.
phase_step: ux-review, last_updated: <now>## UX Assertions table and ## User Journeys sectionFor each UX assertion:
UX ref: UX-NNN matching this assertionUser interaction: line (if present)For each UI-facing plan task without a UX ref::
UX Assertion Coverage:
| UX ID | Assertion | Plan Task(s) | User Interaction | Status |
|-------|-----------|-------------|-----------------|--------|
| UX-001 | {assertion text} | Task 3, Task 5 | {from task's User interaction: line, or "—"} | ✅ Mapped |
| UX-002 | {assertion text} | — | — | ❌ No task |
| UX-003 | {assertion text} | Task 7 | {from task} | ✅ Mapped |
Unmapped UI tasks (no UX ref):
- Task 4: {task title} — {reason or "needs UX assertion?"}
Confirm this mapping is correct, or provide corrections.
Wait for user response:
UX ref: lines, adjust User interaction: text): edit the plan file directlyUpdate state: last_updated: <now>
Auto-approve condition: If ALL of the following are true:
Then skip full agent verification. Instead:
**Files:** and **Steps:** sectionsphase_step: verify, verification_report: "auto-approved (small plan)", last_updated: <now>Otherwise: proceed with full verification below.
phase_step: verify, last_updated: <now>dev-workflow:verify-plan with the plan from Step 2 (pass --fast flag if set in Step 2)verification_report: <summary>, last_updated: <now>If still "Must revise" after 2 revision cycles: Present the remaining issues to the user:
"Plan verification failed after 2 revision attempts. Remaining issues: [list specific issues from verifier output]
Options: A. Stop and manually revise the plan, then re-run this step B. Proceed with imperfect plan (issues noted in execution — treat as extra caution points)"
Wait for user choice. If A: stop. If B: mark state verification_report: "partial" and continue.
phase_step: execute, last_updated: <now>dev-workflow:execute-plan agent (sonnet) with the plan file path and project rootdocs/06-plans/execution-report.md (or the path from the agent's Report written to: line). If the file shows **Status:** in-progress, the agent was truncated — treat the partial results as the execution report.last_updated: <now>Update state: phase_step: review, last_updated: <now>
Determine agents to dispatch:
Feature spec agents (conditional):
dev-workflow:feature-spec-writer dispatch for each completed featureReview agents (always at least one):
dev-workflow:implementation-reviewer agentapple-dev:ui-reviewer — pass list of modified *View.swift filesapple-dev:design-reviewer — pass list of new View filesapple-dev:feature-reviewer — pass feature scope + key files/submission-preview skill after agents completeDispatch ALL agents in parallel using the Task tool in a single message:
For feature-spec-writer (if applicable):
Generate a feature spec with the following inputs:
Feature name: {name}
Feature scope: {scope}
Design doc paths:
{relevant design doc paths and sections}
Dev-guide: {dev-guide path} Phase {N}
Key implementation files:
{list of key files}
Project root: {project root}
For implementation-reviewer (always): pass plan file path, project root, and design doc path (from state or dev-guide; "none" if no design doc) For apple-dev agents (conditional):
apple-dev:ui-reviewer (if UI files modified): pass list of modified *View.swift filesapple-dev:design-reviewer (if new pages/components): pass list of new View filesapple-dev:feature-reviewer (if full user journey completed): pass feature scope + key filesEach agent receives a fresh context — they have no memory of how the code was written. This removes confirmation bias from self-review.
When all return: For each agent, check its report file:
Report: path → Read that fileReport: in return) → search .claude/reviews/ for the agent's report file pattern (e.g., implementation-reviewer-*.md). If found and **Status:** in-progress, the agent was truncated — use the partial results.Present a consolidated summary table:
| Agent | Verdict | Issues | Report/Spec |
|---|---|---|---|
| Feature Spec: {name} | ✅/❌ | {user story counts} | {path} |
| Implementation | ✅/❌ | {gap counts} — Tests: {required}/{exist}/{covered} | {path} |
| UI | ✅/❌ | {counts} | {path} |
| Design | ✅/❌ | {counts} | {path} |
| Feature Review | ✅/❌ | {counts} | {path} |
Feature spec decision points: If feature-spec-writer was dispatched, check its return for Decisions: count.
## Decisions section from the spec fileblocking decision: present to user via AskUserQuestion with options from the decision pointrecommended decisions: present as a group via a single AskUserQuestion. Critical: all DP content must be inside the question field — text printed before AskUserQuestion gets visually covered by the question widget. Read each recommended DP's full block (heading + Context + Options + Recommendation) from the spec file and concatenate them verbatim in the question field, separated by \n---\n. End with: \n\n全部接受推荐,还是逐个审查?**Recommendation:** or **Recommendation (unverified):** line with **Chosen:** {user's choice}Surface human verification items: If any review report's compact summary shows 人工验证项 > 0 or 设备验证项 > 0:
### Part C: 人工验证清单### Part B: 设备验证清单### Part C: 设备验证清单以下需要在设备上确认(来自 review 报告):
- {item, translated to spatial language — use screen position and appearance, NO code identifiers}
- {item}
- ⚠️ 需真机:{animation/transition items}
This is informational — do not block with AskUserQuestion. The user can raise issues during Step 6 (Fix Gaps).
Surface test coverage summary: If implementation-reviewer's compact return includes a Tests: line:
⚠️ 测试覆盖不完整:{N} 个计划要求的测试中,{M} 个为空壳或未覆盖核心路径
Update state: review_reports: [<report file paths from agent summaries>], last_updated: <now>
If any of the following have issues: execution report (blocked/failed tasks) or review reports (gaps):
Update state: phase_step: fix, last_updated: <now>
Collect all issues from two sources:
a. Execution failures (from Step 4): blocked/failed tasks from the execute-plan agent report (includes build/test failures from the plan's final verification task)
b. Review gaps (from Step 5): plan-vs-code gaps, pre-existing issues
Read the relevant report files for full details. Skip entries that are not file paths (e.g., "user-override" sentinel values).
List all issues sorted by severity (critical first, then warnings) Separate by origin:
- {blocked/failed tasks with reasons, including build/test failures}
- {plan-vs-code gaps}
- {pre-existing issues from implementation-reviewer}
Ask the user: "Fix these issues before moving on, or mark as known issues?"
If fixing: a. Separate design issues from code issues. If design-reviewer report exists among review_reports:
设计问题({N} 个必须修复):
- {category}: {count} 代码/UI 问题({M} 个):
- {summary} b. Fix all issues (design + code), then re-run only the reviews that had failures c. Design re-verification limit: If design-reviewer still fails after 1 fix cycle, report remaining design issues and proceed — do not loop. Other reviewers (implementation, UI, feature) follow existing behavior.
If skipping: note the known issues and proceed
Update state: gaps_remaining: <count>, last_updated: <now>
Decision Points: Check each review report for Decisions: count.
## Decisions section from that reportblocking decision: present to user via AskUserQuestion with options from the decision pointrecommended decisions: present as a group via a single AskUserQuestion. Critical: all DP content must be inside the question field — text printed before AskUserQuestion gets visually covered by the question widget. Read each recommended DP's full block (heading + Context + Options + Recommendation) from the report file and concatenate them verbatim in the question field, separated by \n---\n. End with: \n\n全部接受推荐,还是逐个审查?**Recommendation:** or **Recommendation (unverified):** line with **Chosen:** {user's choice}Pre-completion gate (structural enforcement):
review_reports from state filereview_reports is empty (no reports):
BLOCK: "Cannot complete phase: no review reports found. Run Step 5 before marking phase as done."
Do NOT proceed. Use AskUserQuestion:
review_reports: ["user-override"], log override, proceedgaps_remaining > 0:
BLOCK: "Cannot complete phase: {gaps_remaining} unresolved gaps."
Do NOT proceed. Use AskUserQuestion:
Update state: phase_step: done, last_updated: <now>
Update the dev-guide:
**Status:** ✅ Completed — YYYY-MM-DD after the Phase headingIssue archival (conditional): If Step 6 has items marked as "known issues" or skipped gaps:
gh label list --json name -q '.[].name'deferred label doesn't exist, create it: gh label create "deferred" --color "FBCA04" --description "Deferred from phase review"phase-{N} label doesn't exist, create it: gh label create "phase-{N}" --color "0E8A16" --description "Phase {N}"gh issue create with labels deferred and phase-{current phase number}. Use the item description as issue body under ### Symptom.Remind the user to update project docs:
docs/07-changelog/ — record changesdocs/03-decisions/ — if architectural decisions were madeReport:
Detect if this is the last phase: After checking off this Phase's acceptance criteria (step 2 above), re-read the dev-guide. If ALL phases now have all acceptance criteria checked (- [x]), this is the last phase.
If more phases remain:
Phase N complete. Next: Phase N+1 — [name]: [goal]. Run
/run-phaseto continue, or/committo save progress first.
If all phases are complete:
Phase N complete. All phases done. Run
/finalizefor cross-phase validation, or/committo save progress.
phase_step set to done