skills/flow-issues/SKILL.md
Group open issues by label into four sections (Blocked, Other, Vanilla, Decomposed) with mechanical sort and a copy-pasteable command per row.
npx skillsauth add benkruger/flow flow-issuesInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Fetch all open issues for the current repository, bucket them by label, and render four tables. Read-only — never create, edit, or close issues.
/flow:flow-issues
/flow:flow-issues --ready
/flow:flow-issues --blocked
/flow:flow-issues --decomposed
/flow:flow-issues --quick-start
/flow:flow-issues --label Bug
/flow:flow-issues --label Bug --label "Tech Debt"
/flow:flow-issues --milestone v1.2
/flow:flow-issues --label Bug --ready
Filter flags shape which issues the Rust subcommand emits. Filtering
happens at the data layer — bin/flow analyze-issues returns a
pre-filtered issues array, and the renderer simply buckets and
renders whatever it receives. Flags are mutually exclusive within
each family.
--ready — Rust drops blocked rows before delivery; no Blocked
section appears in the output.--blocked — Rust keeps only blocked rows; only the Blocked
section appears.--decomposed — Rust keeps only decomposed rows; only the
Decomposed section appears.--quick-start — Rust keeps only decomposed, non-blocked,
non-Flow-In-Progress rows; the Decomposed section renders with no
🟡 cluster.--label <name> — server-side filter passed to gh issue list
(repeatable; multiple labels combine with AND).--milestone <title> — server-side milestone filter
(single value; by title or number).--label and --milestone compose with the section flags. No flag
renders all four sections.
This flow is one of potentially many running simultaneously — on this
machine (multiple worktrees) and across machines (multiple engineers).
Your state file (.flow-states/<branch>/state.json) is yours alone. Never
read or write another branch's state. All local artifacts (logs, plan
files, temp files) are scoped by branch name. GitHub state (PRs, issues,
labels) is shared across all engineers — operations that create or modify
shared state must be idempotent.
At the very start, output the following banner in your response (not via Bash) inside a fenced code block:
```text
──────────────────────────────────────────────────
FLOW v2.6.1 — flow:flow-issues — STARTING
──────────────────────────────────────────────────
```
Run the analysis script. It calls gh issue list internally and emits
a single flat issues array with per-row label flags, assignees, and
URL-bearing blocked_by entries:
${CLAUDE_PLUGIN_ROOT}/bin/flow analyze-issues
${CLAUDE_PLUGIN_ROOT}/bin/flow analyze-issues --ready
${CLAUDE_PLUGIN_ROOT}/bin/flow analyze-issues --blocked
${CLAUDE_PLUGIN_ROOT}/bin/flow analyze-issues --decomposed
${CLAUDE_PLUGIN_ROOT}/bin/flow analyze-issues --quick-start
${CLAUDE_PLUGIN_ROOT}/bin/flow analyze-issues --label Bug
${CLAUDE_PLUGIN_ROOT}/bin/flow analyze-issues --label Bug --label "Tech Debt"
${CLAUDE_PLUGIN_ROOT}/bin/flow analyze-issues --milestone v1.2
${CLAUDE_PLUGIN_ROOT}/bin/flow analyze-issues --label Bug --ready
Use the first form when no filter flag was passed. Use the matching form when a flag was passed.
Parse the JSON output. The shape is:
{
"status": "ok",
"total": 12,
"issues": [
{
"number": 1547,
"title": "...",
"url": "https://github.com/owner/repo/issues/1547",
"labels": ["Decomposed"],
"decomposed": true,
"blocked": false,
"native_blocked": false,
"blocked_by": [
{"number": 1525, "url": "https://github.com/owner/repo/issues/1525"}
],
"assignees": ["alice"],
"vanilla": false,
"flow_in_progress": false,
"triage_in_progress": false,
"high_priority": false
}
]
}
If status is "error", show the error message and stop.
If total is 0 AND a filter flag was passed (--ready,
--blocked, --decomposed, --quick-start, --label,
--milestone), print "No issues matched the filter — run
/flow:flow-issues without flags to see every open issue."
before the COMPLETE banner. If total is 0 with no filter flag,
print the COMPLETE banner and stop.
Render four markdown tables in order: Blocked, Other, Vanilla, Decomposed. Each row belongs to exactly one section; flags resolve membership and sort order.
Walk the issues array once. For each row, assign to the first
section whose condition matches:
blocked == true (label OR native_blocked).decomposed == true AND blocked == false.vanilla == true AND decomposed == false AND
blocked == false.The bucket assignment is independent of flow_in_progress and
triage_in_progress — in-progress signals are visual treatment
applied AFTER bucketing (see Color treatment below). A row that is
in-progress lands in whichever bucket its primary labels select; the
colored prefix and suppressed Command cell follow regardless of
which bucket received the row.
The Blocked section renders five columns:
| Issue # | Title | Assignee | Blocked By | Command | |---|---|---|---|---|
The Other, Vanilla, and Decomposed sections render four columns:
| Issue # | Title | Assignee | Command | |---|---|---|---|
[#N](url) — a markdown link to the issue. Always
rendered.**title**) for rows where
flow_in_progress or triage_in_progress is true; plain otherwise.assignees, or — when the array
is empty. (Comma-separate additional logins if present.)[#N](url) entries from blocked_by, or — when blocked_by is
empty but blocked == true (label-only block).flow_in_progress == true OR triage_in_progress == true,
the Command cell renders — REGARDLESS of bucket — the colored
prefix signals "someone else owns this" and the empty Command
prevents a second engineer from firing a redundant slash command.
Otherwise:
—./flow:flow-explore work on issue #N/flow:flow-plan #N/flow:flow-start #N—.|, \, \n, \r
in every Title and Assignee cell (replace | with \|, \ with
\\, newlines and carriage returns with spaces). Never render
HTML from titles — treat angle brackets, [, ], (, ) as
literal characters by wrapping the cell content in backticks for
any title that contains them. The same escaping applies to
Blocked-By URL link text. Per
.claude/rules/subprocess-argument-escaping.md, external data
must be escaped at the rendering boundary; an unescaped pipe in
a title breaks the table for every downstream row, and an
unescaped image tag in a title can exfiltrate the viewer's
request to a third-party server.Rows carrying the canonical FLOW labels get visual treatment that applies regardless of bucket:
flow_in_progress == true (Flow In-Progress label) → 🟡 prefix
on the bold Title cell, Command suppressed.triage_in_progress == true (Triage In-Progress label) → 🔍
prefix on the bold Title cell, Command suppressed.high_priority == true (High Priority label) → 🔥 prefix on the
Title cell. 🔥 itself is not a Title-bolding signal and is not a
Command-suppressing signal — bucket-level Cell rules still
decide bolding and Command (a 🔥 row in the Blocked bucket
still renders Command as — per the Blocked bucket's rule).
The prefix applies regardless of bucket and is additive, not
exclusive with the other prefixes.The prefix follows the row into whichever bucket it lands; a
Flow-In-Progress row in the Vanilla bucket still renders 🟡, a
Triage-In-Progress row in the Blocked bucket still renders 🔍, and
a High-Priority row in any bucket still renders 🔥. The
cross-engineer WIP signal documented in CLAUDE.md "The 'Flow
In-Progress' label on issues is the cross-engineer WIP detection
mechanism" is honored from every section.
When 🔥 stacks with 🟡 or 🔍 on the same row, 🔥 leads:
🔥 🟡 **Title** or 🔥 🔍 **Title**. The bolding and Command
suppression still come from the in-progress signal; 🔥 is additive
and does not change either behavior.
number
descending (newest issue numbers first).number descending within each cluster.high_priority does not participate in sort clustering; 🔥 rows
stay in their bucket's normal number-descending order.Filtering happens in bin/flow analyze-issues at the Rust layer,
not at the rendering layer — the issues array delivered to the
renderer already reflects the active filter. Empty sections do not
render. The user-facing effect of each flag:
--ready → Blocked section absent (Rust dropped blocked rows).--blocked → only Blocked section appears.--decomposed → only Decomposed section appears.--quick-start → only Decomposed section appears, no 🟡 cluster
(Rust dropped both blocked AND flow_in_progress rows before
delivery).--label / --milestone → whichever sections the surviving
rows populate.After the sections are rendered, output the following banner in your response (not via Bash) inside a fenced code block:
```text
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✓ FLOW v2.6.1 — flow:flow-issues — COMPLETE
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
```
data-ai
Clear the autonomous-flow halt set when the user spoke mid-flow. Invokes `bin/flow clear-halt` so the next assistant turn resumes execution. User-only: the model cannot invoke this skill.
data-ai
Open a problem-statement conversation. Stays in discussion mode with PM as default voice; on user signal, files a vanilla What/Why/Acceptance Criteria issue against the current repo. Usage: /flow:flow-explore <topic>
tools
Display the FLOW skill catalog grouped by user role. Maintainer and Private buckets render only when invoked inside the FLOW plugin repo.
documentation
Phase 3: Review — six tenants assessed by four cognitively isolated agents (reviewer, pre-mortem, adversarial, documentation) launched in parallel. Parent session gathers context, triages findings, and fixes.