/plan-workflow
PREVIEW Dynamic Workflow asset behind /lets:plan-workflow. Not auto-triggered - a workflow script invoked via scriptPath. The autonomous-planning chain, shipped for cross-project testing before it folds into native /lets:plan.
Claude Code
$ npx -y skills add restarter/lets-workflow --skill plan-workflow --agent claude-code
Codex
$ npx skills add restarter/lets-workflow --skill plan-workflow -a codex -y
Cursor
$ npx skills add restarter/lets-workflow --skill plan-workflow -a cursor -y
Gemini CLI
$ npx skills add restarter/lets-workflow --skill plan-workflow -a gemini-cli -y
GitHub Copilot
$ npx skills add restarter/lets-workflow --skill plan-workflow -a github-copilot -y
OpenCode
$ npx skills add restarter/lets-workflow --skill plan-workflow -a opencode -y
Windsurf
$ npx skills add restarter/lets-workflow --skill plan-workflow -a windsurf -y
SKILL.md
plan-workflow.SKILL.mdname: plan-workflow
description: PREVIEW Dynamic Workflow asset behind /lets:plan-workflow. Not auto-triggered - a workflow script invoked via scriptPath. The autonomous-planning chain, shipped for cross-project testing before it folds into native /lets:plan.
user-invocable: false
plan-workflow (PREVIEW Dynamic Workflow asset)
**Preview / experimental.** `plan.workflow.js` is the autonomous-planning chain, invoked by `/lets:plan-workflow` via:
Workflow({ scriptPath: "${CLAUDE_PLUGIN_ROOT}/skills/plan-workflow/plan.workflow.js", args })It runs the autonomous design without touching the heavily-used interactive `/lets:plan`. Once stable (after cross-project testing), the asset folds into native `/lets:plan` (as a `--workflow` mode or equivalent) and this standalone is retired (lets-jsw00).
Why this is autonomous-only (not a re-skin of review/opinion)
`/lets:review --workflow` and `/lets:opinion --workflow` are performance levers: same result, off-context. Native `/lets:plan` is interactive (clarify -> explore -> approaches -> architecture -> eval -> discuss); every checkpoint forces intermediate results back into context, which kills the off-context win. So the only workflow that pays off is the **autonomous whole-command** form: the user front-loads a RUBRIC, judge agents make the informed picks against it, and the run returns a plan + decision log. Steer-by-rubric + approve-at-end.
Stages (off-context, NO user gate between them)
1. **Explore** - fan out `lets:explorer` per focus area (`EXPLORE_SCHEMA`) -> codebase map. 2. **Approaches** - one `lets:architect` synthesizes 2-4 distinct approaches from the map + goal + rubric (`APPROACHES_SCHEMA`). 3. **Architect** - one `lets:architect` per approach -> full architecture (`ARCH_SCHEMA`). 4. **Judge** - a panel (default `pragmatist, backend, security` - never `architect`) scores each architecture against the rubric and picks a winner (`JUDGE_SCHEMA`); `aggregateJudges` tallies winner-votes (tiebreak: summed totals) over REAL approach ids only. 5. **Evaluate** - expert panel evaluates the winner for risks (`EVAL_SCHEMA`). 6. **Plan** - one `lets:architect` writes the bite-sized plan markdown, folding in eval findings (`PLAN_SCHEMA`). 7. **Plan Review** - fan out `lets:architect` + `lets:pragmatist` over the WRITTEN plan (mirror `/lets:review --plan`, `PLAN_REVIEW_SCHEMA`) -> verdict + findings. 8. **Revise** - one `lets:architect` applies the review findings -> revised plan (`REVISE_SCHEMA`); skipped if no findings; planMd never lost on agent error. 9. **Plan Check** - one `lets:pragmatist` runs a quick 5-lens sanity pass (mirror `/lets:check --plan`, `PLAN_CHECK_SCHEMA`) -> verdict + findings; catches regressions the revise introduced. 10. **Refine** - one `lets:architect` applies the check findings -> final plan; skipped if clean.
**Fast mode (`fast: true`) per-stage budget:** Explore = 1 explorer over a single merged focus area (instead of N). Approaches = 1 architect (best-first ordered against the rubric, since only the top one is architected). Architect = top-1 approach only (`approaches.slice(0,1)`). Judge = 1 judge (enum still constrained to the real architected id; if it errors with a single candidate, the lone approach is taken and `decision_log.forced = 'single-candidate'`). Evaluate = 1 expert. Plan = 1 architect. **Stages 7-8 (Plan Review -> Revise) are SKIPPED** - 0 agents; `refinement_log.review_skipped = true`. **Stages 9-10 (Plan Check -> Refine) RUN in both modes** - 1 checker, +1 refiner only on check findings. Net ~7 agents (+1 conditional) vs ~15-25. Default (no flag) is byte-identical to standard.
Stages 7-10 are a single-pass **self-repair loop**: the plan reviews + fixes itself off-context before it ever reaches the user (who still approves at the end). `refinement_log` records the review/check verdicts and whether fixes landed.
`args` contract
| key | type | meaning | |---|---|---| | `goal` | string | what to build/change | | `rubric` | string | the steering criteria (replaces interactive picks) | | `focusAreas` | `[{name, hint}]` | exploration areas (dispatcher-derived) | | `judges` | `[{name}]` | judge panel (exclude `architect`) | | `experts` | `[{name}]` | winner-evaluation panel | | `taskContext` | string | active tracker task context (or empty) | | `projectRoot` | string | absolute root (agents must not read outside it) | | `claudeMd` | string | CLAUDE.md context | | `fast` | boolean (optional) | lean budget — 1 agent/stage; merges focus areas to 1 explorer, architects only the top-ranked approach, 1 judge, 1 expert; SKIPS the heavy Plan Review/Revise pass, KEEPS the quick Plan Check/Refine. Default `false`. Distinct from native `/lets:plan --fast` (orchestrator-only, no subagents). | | `planReviewers` | `[{name}]` (optional) | self-repair Plan Review panel; default `architect, pragmatist`. Ignored in fast mode (review pass skipped). | | `planChecker` | `{name}` (optional) | Plan Check agent; default `pragmatist`. Runs in BOTH modes (fast keeps the quick check). | | `model` | string (optional) | model for EVERY spawned agent (`agentOpts`), overriding each agent type's own default (e.g. `lets:explorer`'s `sonnet` pin). Must match `^[A-Za-z0-9.\[\]_-]{1,64}$`, else ignored. Absent = each agent's default. | | `budget` | `{explorers, approaches, judges, evaluators, plan_reviewers, plan_checker}` (optional, any subset) | per-stage caps that can only LOWER a stage (`capStage` keeps the first N, logs the rest). Each value is clamped to MIN..MAX (`explorers`/`approaches`/`judges` 1..5/4/5, `evaluators` 0..5, `plan_reviewers` 0..4, `plan_checker` 0..1); a clamp is logged. `approaches` = how many proposed approaches get architected and judged (the Approaches prompt then asks for best-first order). `plan_reviewers: 0` / `plan_checker: 0` skip that pass as a named skip, never as a failure. Send only the stages the user changed. |
Returns
`{ plan_markdown, delivered_approach, dive
Read more
name: plan-workflow description: PREVIEW Dynamic Workflow asset behind /lets:plan-workflow. Not auto-triggered - a workflow script invoked via scriptPath. The autonomous-planning chain, shipped for cross-project testing before it folds into native /lets:plan. user-invocable: false
plan-workflow (PREVIEW Dynamic Workflow asset)
**Preview / experimental.** `plan.workflow.js` is the autonomous-planning chain, invoked by `/lets:plan-workflow` via:
Workflow({ scriptPath: "${CLAUDE_PLUGIN_ROOT}/skills/plan-workflow/plan.workflow.js", args })It runs the autonomous design without touching the heavily-used interactive `/lets:plan`. Once stable (after cross-project testing), the asset folds into native `/lets:plan` (as a `--workflow` mode or equivalent) and this standalone is retired (lets-jsw00).
Why this is autonomous-only (not a re-skin of review/opinion)
`/lets:review --workflow` and `/lets:opinion --workflow` are performance levers: same result, off-context. Native `/lets:plan` is interactive (clarify -> explore -> approaches -> architecture -> eval -> discuss); every checkpoint forces intermediate results back into context, which kills the off-context win. So the only workflow that pays off is the **autonomous whole-command** form: the user front-loads a RUBRIC, judge agents make the informed picks against it, and the run returns a plan + decision log. Steer-by-rubric + approve-at-end.
Stages (off-context, NO user gate between them)
1. **Explore** - fan out `lets:explorer` per focus area (`EXPLORE_SCHEMA`) -> codebase map. 2. **Approaches** - one `lets:architect` synthesizes 2-4 distinct approaches from the map + goal + rubric (`APPROACHES_SCHEMA`). 3. **Architect** - one `lets:architect` per approach -> full architecture (`ARCH_SCHEMA`). 4. **Judge** - a panel (default `pragmatist, backend, security` - never `architect`) scores each architecture against the rubric and picks a winner (`JUDGE_SCHEMA`); `aggregateJudges` tallies winner-votes (tiebreak: summed totals) over REAL approach ids only. 5. **Evaluate** - expert panel evaluates the winner for risks (`EVAL_SCHEMA`). 6. **Plan** - one `lets:architect` writes the bite-sized plan markdown, folding in eval findings (`PLAN_SCHEMA`). 7. **Plan Review** - fan out `lets:architect` + `lets:pragmatist` over the WRITTEN plan (mirror `/lets:review --plan`, `PLAN_REVIEW_SCHEMA`) -> verdict + findings. 8. **Revise** - one `lets:architect` applies the review findings -> revised plan (`REVISE_SCHEMA`); skipped if no findings; planMd never lost on agent error. 9. **Plan Check** - one `lets:pragmatist` runs a quick 5-lens sanity pass (mirror `/lets:check --plan`, `PLAN_CHECK_SCHEMA`) -> verdict + findings; catches regressions the revise introduced. 10. **Refine** - one `lets:architect` applies the check findings -> final plan; skipped if clean.
**Fast mode (`fast: true`) per-stage budget:** Explore = 1 explorer over a single merged focus area (instead of N). Approaches = 1 architect (best-first ordered against the rubric, since only the top one is architected). Architect = top-1 approach only (`approaches.slice(0,1)`). Judge = 1 judge (enum still constrained to the real architected id; if it errors with a single candidate, the lone approach is taken and `decision_log.forced = 'single-candidate'`). Evaluate = 1 expert. Plan = 1 architect. **Stages 7-8 (Plan Review -> Revise) are SKIPPED** - 0 agents; `refinement_log.review_skipped = true`. **Stages 9-10 (Plan Check -> Refine) RUN in both modes** - 1 checker, +1 refiner only on check findings. Net ~7 agents (+1 conditional) vs ~15-25. Default (no flag) is byte-identical to standard.
Stages 7-10 are a single-pass **self-repair loop**: the plan reviews + fixes itself off-context before it ever reaches the user (who still approves at the end). `refinement_log` records the review/check verdicts and whether fixes landed.
`args` contract
| key | type | meaning | |---|---|---| | `goal` | string | what to build/change | | `rubric` | string | the steering criteria (replaces interactive picks) | | `focusAreas` | `[{name, hint}]` | exploration areas (dispatcher-derived) | | `judges` | `[{name}]` | judge panel (exclude `architect`) | | `experts` | `[{name}]` | winner-evaluation panel | | `taskContext` | string | active tracker task context (or empty) | | `projectRoot` | string | absolute root (agents must not read outside it) | | `claudeMd` | string | CLAUDE.md context | | `fast` | boolean (optional) | lean budget — 1 agent/stage; merges focus areas to 1 explorer, architects only the top-ranked approach, 1 judge, 1 expert; SKIPS the heavy Plan Review/Revise pass, KEEPS the quick Plan Check/Refine. Default `false`. Distinct from native `/lets:plan --fast` (orchestrator-only, no subagents). | | `planReviewers` | `[{name}]` (optional) | self-repair Plan Review panel; default `architect, pragmatist`. Ignored in fast mode (review pass skipped). | | `planChecker` | `{name}` (optional) | Plan Check agent; default `pragmatist`. Runs in BOTH modes (fast keeps the quick check). | | `model` | string (optional) | model for EVERY spawned agent (`agentOpts`), overriding each agent type's own default (e.g. `lets:explorer`'s `sonnet` pin). Must match `^[A-Za-z0-9.\[\]_-]{1,64}$`, else ignored. Absent = each agent's default. | | `budget` | `{explorers, approaches, judges, evaluators, plan_reviewers, plan_checker}` (optional, any subset) | per-stage caps that can only LOWER a stage (`capStage` keeps the first N, logs the rest). Each value is clamped to MIN..MAX (`explorers`/`approaches`/`judges` 1..5/4/5, `evaluators` 0..5, `plan_reviewers` 0..4, `plan_checker` 0..1); a clamp is logged. `approaches` = how many proposed approaches get architected and judged (the Approaches prompt then asks for best-first order). `plan_reviewers: 0` / `plan_checker: 0` skip that pass as a named skip, never as a failure. Send only the stages the user changed. |
Returns
`{ plan_markdown, delivered_approach, dive
A development workflow plugin for Claude Code Stop babysitting your AI. Start shipping with it.
Other skills on lets-workflow.
goal-test
Local sandbox for experimenting with Claude Code's /goal command (stop-hook condition + LLM-evaluator driving autonomous work…
loop-bb-pr
Compose a /loop that monitors a Bitbucket PR for activity (new comments, review state changes, merge, decline) via the bb-api…
loop-gh-pr
Compose a /loop that watches all open GitHub PRs for activity (new PRs, new commits, new comments) and auto-prepares a READ-ONLY…
loop-test
Local sandbox for experimenting with Claude Code's /loop command (interval + dynamic/self-paced scheduling) applied to LETS…
actor-fetch-personalit…
Internal skill for commands. Fetch and validate personality from URL or file path for Actor agent. Do not trigger on user…
More skills from other plugins.
brainstorming
You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…
ask-matt
Ask which skill or flow fits your situation. A router over the skills in this repo.
Questions about plan-workflow.
- Which coding agents can use plan-workflow?
- plan-workflow installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.

