Skip to content
Development
Skill

/flow-next-deps

Show spec dependency graph and execution order. Use when asking 'what's blocking what', 'execution order', 'dependency graph', 'what order should specs run', 'critical path', 'which specs can run in parallel'.

From plugin
flow-next
72129 skills21 agents26 commands

Claude Code

$ npx -y skills add gmickel/flow-next --skill flow-next-deps --agent claude-code

SKILL.md

flow-next-deps.SKILL.md
name: flow-next-deps
description: "Show spec dependency graph and execution order. Use when asking 'what's blocking what', 'execution order', 'dependency graph', 'what order should specs run', 'critical path', 'which specs can run in parallel'."

Flow-Next Dependency Graph

Visualize spec dependencies, blocking chains, and execution phases.

Preamble

flowctl is bundled with the plugin (not on PATH). Define once; subsequent blocks use `$FLOWCTL`:

FLOWCTL="${DROID_PLUGIN_ROOT:-${CLAUDE_PLUGIN_ROOT}}/scripts/flowctl"
[ -x "$FLOWCTL" ] || FLOWCTL="<plugin-root>/scripts/flowctl"   # <plugin-root> = the directory two levels above this skill's SKILL.md file (the harness gave you that file's absolute path when the skill loaded); substitute it literally
[ -x "$FLOWCTL" ] || FLOWCTL=".flow/bin/flowctl"

Setup

$FLOWCTL detect --json | jq -e '.exists' >/dev/null && echo "OK: .flow/ exists" || echo "ERROR: run $FLOWCTL init"
command -v jq >/dev/null 2>&1 && echo "OK: jq installed" || echo "ERROR: brew install jq"

Step 1: Gather Spec Data

Build a consolidated view of all specs with their dependencies — a single per-spec loop for the whole skill, over open specs only (a done spec needs only its status, which the specs list carries). Steps 2 and 3 reuse the cached file (bash vars do not survive across tool calls, so the cache is a file at a literal agent-composed path — compose `<suffix>` once, e.g. 4 random chars, and reuse the same literal path in every later block):

# ONE gather — Steps 2 and 3 read this file; never re-run the per-spec loop
SPECS_FILE="${TMPDIR:-/tmp}/flow-deps-specs-<suffix>.json"
SPECS_LIST="$($FLOWCTL specs --json)"
{
  printf '%s' "$SPECS_LIST" | jq -c '.specs[] | select(.status == "done") | {id, title, status}'
  printf '%s' "$SPECS_LIST" | jq -r '.specs[] | select(.status != "done") | .id' | while read -r id; do
    $FLOWCTL show "$id" --json | jq -c '{
      id: .id,
      title: .title,
      status: .status,
      plan_review: .plan_review_status,
      deps: (.depends_on_epics // [])
    }'
  done
} | jq -s '.' > "$SPECS_FILE"
cat "$SPECS_FILE"

Done when

  • `$SPECS_FILE` exists at the composed literal path and parses as a JSON array with one object per spec returned by `flowctl specs --json`.
  • The per-spec `flowctl show` loop has run exactly once for this invocation, over the open specs. **Steps 2 and 3 read that file.** A second run of the gather loop has broken this.

Step 2: Identify Blocking Chains

Determine which specs are ready vs blocked (pure jq, works on any shell):

# Reuse the Step 1 gather — same literal path, NO re-fetch (one heavy loop total)
SPECS_FILE="${TMPDIR:-/tmp}/flow-deps-specs-<suffix>.json"

# Compute blocking status
jq -r '
  # Build status lookup
  (map({(.id): .status}) | add // {}) as $status |

  # Check each non-done spec
  .[] | select(.status != "done") |
  .id as $id | .title as $title |

  # Find deps that are not done
  ([.deps[] | select($status[.] != "done")] | join(", ")) as $blocked_by |

  if ($blocked_by | length) == 0 then
    "READY: \($id) - \($title)"
  else
    "BLOCKED: \($id) - \($title) (by: \($blocked_by))"
  end
' "$SPECS_FILE"

Done when

  • Every non-`done` spec in `$SPECS_FILE` emitted exactly one `READY:` or `BLOCKED:` line, and each `BLOCKED:` line names the specific deps holding it.
  • The jq ran against the cached file, not a fresh `flowctl show` sweep.

Step 3: Compute Execution Phases

Group specs into parallel execution phases:

# Reuse the Step 1 gather — same literal path, NO re-fetch (one heavy loop total)
SPECS_FILE="${TMPDIR:-/tmp}/flow-deps-specs-<suffix>.json"

# fence:deps-phases
# Phase assignment algorithm (run in jq for reliability)
jq '
  # Build status lookup
  (map({(.id): .status}) | add // {}) as $status |

  # Filter to non-done specs
  [.[] | select(.status != "done")] as $open |

  # Assign phases until a round places nothing, so a chain of any depth is phased
  {assigned: [], result: [], open: $open, stalled: false} |
  until(.stalled;
    .assigned as $assigned |

    # Find specs not yet assigned whose deps are all done or in earlier phases
    ([.open[] | select(
      ([.id] | inside($assigned) | not) and
      ((.deps // []) | all(. as $d | $status[$d] == "done" or ($assigned | index($d))))
    )] | map(.id)) as $ready |

    if ($ready | length) > 0 then
      .result += [{phase: ((.result | length) + 1), specs: [.open[] | select(.id | IN($ready[]))]}] |
      .assigned += $ready
    else .stalled = true end
  ) |
  # Emit the phases AND the residue: any open spec never assigned can never start.
  # Dropping it silently is the one way /deps gives a WRONG answer (the graph it exists to
  # expose hides the deadlock). Surface it with its unresolved deps and its cause: on a
  # dependency cycle (with the path), a dep that is not among the specs, or blocked only
  # by another deadlocked spec.
  .assigned as $asg |
  ([ $open[] | select(.id as $i | ($asg | index($i)) | not)
     | {key: .id, value: [ (.deps // [])[] | select(. as $d | ($asg | index($d)) or ($status[$d] == "done") | not) ]} ]
   | from_entries) as $unres |
  # Breadth-first walk over unresolved deps back to $id; the path, or null
  def cycle_of($id):
    {queue: [$id], parent: {}, last: null} |
    until((.queue | length) == 0 or .last != null;
      .queue[0] as $n | .queue |= .[1:] |
      reduce $unres[$n][] as $d (.;
        if .last != null then .
        elif $d == $id then .last = $n
        elif .parent[$d] != null or $unres[$d] == null then .
        else .parent[$d] = $n | .queue += [$d] end)) |
    .parent as $p |
    if .last == null then null
    else [ .last | recurse(if . == $id then empty else $p[.] end) ] | reverse + [$id] end;
  { phases: .result,
    deadlocked: [ $open[] | select($unres[.id] != null) | .id as $i | cycle_of($i) as $cycle
                  | { id, status, unresolved_deps: $unres[$i],
Read more
@gmickel
Ships withflow-next

Faster than your agent alone. And better. A workflow plugin that takes a bug, idea or ticket to a verified pull request: specs, cross-model review by risk, live QA, receipts in your repo. Claude Code · Codex · Cursor · Droid · Grok Build · OpenCode · Muse Code.

72129 skills21 agents
Get the whole plugin

Stars on GitHub

Momentum

stars in total
721
Star history of gmickel/flow-next on GitHub, a chart by star-history.com

Other skills on flow-next.

flow-next-audit

flow-next-audit

Audit `.flow/memory/` entries against the current codebase and decide Keep / Update / Consolidate / Replace / Delete / Harden per…

@gmickel@gmickelInstall Skill
flow-next-capture

flow-next-capture

Synthesize the current conversation context into a flow-next spec at `.flow/specs/<spec-id>.md` via `flowctl spec create…

@gmickel@gmickelInstall Skill
flow-next-chart

flow-next-chart

Decision-map discovery for one oversized/unclear idea before capture. Triggers on /flow-next:chart with an unshaped idea, chart…

@gmickel@gmickelInstall Skill
flow-next-drive

flow-next-drive

Drive any UI surface like a real user - a web app, a Chromium-backed desktop app (Electron / WebView2, reached over CDP), or a…

@gmickel@gmickelInstall Skill
flow-next-features

flow-next-features

Seed or maintain the committed user-POV feature map at `.flow/features/` so QA and drive reuse how a user reaches each feature.…

@gmickel@gmickelInstall Skill
flow-next-flow

flow-next-flow

Use first in a project that uses Flow-Next for any request to implement, build, continue or deliver its specs, whatever delivery…

@gmickel@gmickelInstall Skill

More skills from other plugins.

brainstorming
Auto-invoked

brainstorming

You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…

@obra@obraInstall Skill
ask-matt

ask-matt

Ask which skill or flow fits your situation. A router over the skills in this repo.

skills11d309k
@mattpocock@mattpocockInstall Skill
accessibility
Auto-invoked

accessibility

Design, implement, and audit accessible UI to WCAG 2.2 Level AA across Web, iOS, and Android — semantic ARIA roles and labels,…

ecc12d293k
@affaan-m@affaan-mInstall Skill
compiler-commit

compiler-commit

Use when you want to verify compiler changes and commit with the correct convention. Runs tests, lint, and format, then commits…

react2d252k
@facebook@facebookInstall Skill

Questions about flow-next-deps.

Which coding agents can use flow-next-deps?
flow-next-deps 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.