diff --git a/.cursor/rules/graphify.mdc b/.cursor/rules/graphify.mdc new file mode 100644 index 0000000..987bcd0 --- /dev/null +++ b/.cursor/rules/graphify.mdc @@ -0,0 +1,11 @@ +--- +description: graphify knowledge graph context +alwaysApply: true +--- + +This project has a graphify knowledge graph at graphify-out/. + +- For codebase or architecture questions, when `graphify-out/graph.json` exists, first run `graphify query ""` (or `graphify path "" ""` / `graphify explain ""`). These return a scoped subgraph, usually much smaller than `GRAPH_REPORT.md` or raw grep output. +- If graphify-out/wiki/index.md exists, navigate it instead of reading raw files +- Read graphify-out/GRAPH_REPORT.md only for broad architecture review or when query/path/explain do not surface enough context +- After modifying code files in this session, run `graphify update .` to keep the graph current (AST-only, no API cost) diff --git a/.cursor/rules/issueflow-rules.mdc b/.cursor/rules/issueflow-rules.mdc new file mode 100644 index 0000000..1537375 --- /dev/null +++ b/.cursor/rules/issueflow-rules.mdc @@ -0,0 +1,349 @@ +--- +description: Issue-flow workflow rules for cellpy-mcp +globs: + - "**/*" +alwaysApply: false +--- + + +# Issue-flow best practices + + +## Running python + +**Respect the project's existing toolchain first.** If this project already +documents how to run Python and manage dependencies — in its `README`, +`AGENTS.md`, `CLAUDE.md`, `.cursor/rules`, `environment.yml`, `pyproject.toml`, +`Makefile`, CI config, etc. — **follow that**, even where it conflicts with the +defaults below. These rules describe issue-flow's *default* assumptions, not a +mandate to override a project that has already chosen differently. + +The one tool-neutral principle: **don't call bare `python ...`** — invoke Python +through the project's environment (its runner, or an activated virtualenv/conda +env) so scripts and tests see the right interpreter and dependencies. + +### If the project uses conda + +When the project documents a conda environment, run **all** Python commands — +scripts **and `pytest`** — inside the **activated conda environment**. Do **not** +substitute `uv run`. + +```bash +# Either activate the environment first… +conda activate +python run_script.py +pytest + +# …or run one-off commands inside it: +conda run -n pytest +``` + +### If the project uses uv (issue-flow's default) + +For projects scaffolded fresh (and this is the default when nothing else is +documented), use `uv`: + +```bash +# ❌ BAD: bare interpreter +python run_script.py + +# ✅ GOOD: through uv +uv run run_script.py +``` + +**Package management with `uv`** + +- Install, synchronize, and lock dependencies with `uv`; don't reach for `pip`, + `pip-tools`, or `poetry` in a uv-managed project. + +```bash +# Add or upgrade dependencies +uv add + +# Remove dependencies +uv remove + +# Reinstall all dependencies from the lock file +uv sync + +# Run a script with the right environment +uv run script.py +``` + +### Other toolchains (plain venv / pip / poetry) + +If the project uses something else, use whatever it documents (e.g. activate its +`.venv` and use `pip`, or run `poetry run`). Match the project; don't force `uv`. + + +## Issue tracking structure + +```bash +cellpy-mcp/ + .issueflows/ + 00-tools/ + 01-current-issues/ + issueXX_original.md + issueXX_status.md + 02-partly-solved-issues/ + 03-solved-issues/ + 04-designs-and-guides/ + 05-epics/ + epicXX_plan.md + pyproject.toml + readme.md + ... +``` + + +## Development information + + +### Working on issues + +After each iteration, update the documents in `.issueflows/01-current-issues` (should contain one file labelled `_original` with the original issue description, a `_plan` file with the confirmed approach, and supplementary status files describing what has been done, current status, and remaining work). +Use an explicit status checkbox in the status file: +- `- [x] Done` when fully resolved +- `- [ ] Done` when not fully resolved + +### Chat invocation (no slash) + +On keyboard layouts where `/` and `@` are awkward to type (for example Norwegian), invoke lifecycle skills in **chat** without special keys. + +**Primary form:** `iflow ` (space-separated) — e.g. `iflow plan`, `iflow pick`, `iflow close`. Plain `iflow` runs the smart dispatcher. + +**Also recognized** (same obligation as slash-menu invocation): hyphen form (`iflow-plan`), slash form (`/iflow-plan`), slash + space (`/iflow plan`). + +When the user message is **exactly** one of these forms, or **starts with** it followed by a space and trailing arguments, **read and follow** the matching skill immediately. Forward trailing text verbatim (e.g. `iflow pick fix` → `iflow-pick` with arg `fix`). Do **not** treat incidental mid-sentence mentions as commands — the message must **start with** the invocation. + +| Chat / slash form | Skill | +|-------------------|-------| +| `iflow` / `/iflow` | `iflow` (dispatcher) | + +| `iflow archive`, `iflow-archive`, `/iflow-archive`, `/iflow archive` | `iflow-archive` | + +| `iflow auto`, `iflow-auto`, `/iflow-auto`, `/iflow auto` | `iflow-auto` | + +| `iflow build`, `iflow-build`, `/iflow-build`, `/iflow build` | `iflow-build` | + +| `iflow capture`, `iflow-capture`, `/iflow-capture`, `/iflow capture` | `iflow-capture` | + +| `iflow cleanup`, `iflow-cleanup`, `/iflow-cleanup`, `/iflow cleanup` | `iflow-cleanup` | + +| `iflow close`, `iflow-close`, `/iflow-close`, `/iflow close` | `iflow-close` | + +| `iflow cycle`, `iflow-cycle`, `/iflow-cycle`, `/iflow cycle` | `iflow-cycle` | + +| `iflow doctor`, `iflow-doctor`, `/iflow-doctor`, `/iflow doctor` | `iflow-doctor` | + +| `iflow drive`, `iflow-drive`, `/iflow-drive`, `/iflow drive` | `iflow-drive` | + +| `iflow epic`, `iflow-epic`, `/iflow-epic`, `/iflow epic` | `iflow-epic` | + +| `iflow fix`, `iflow-fix`, `/iflow-fix`, `/iflow fix` | `iflow-fix` | + +| `iflow graphify`, `iflow-graphify`, `/iflow-graphify`, `/iflow graphify` | `iflow-graphify` | + +| `iflow init`, `iflow-init`, `/iflow-init`, `/iflow init` | `iflow-init` | + +| `iflow issue`, `iflow-issue`, `/iflow-issue`, `/iflow issue` | `iflow-issue` | + +| `iflow ops`, `iflow-ops`, `/iflow-ops`, `/iflow ops` | `iflow-ops` | + +| `iflow pause`, `iflow-pause`, `/iflow-pause`, `/iflow pause` | `iflow-pause` | + +| `iflow pick`, `iflow-pick`, `/iflow-pick`, `/iflow pick` | `iflow-pick` | + +| `iflow plan`, `iflow-plan`, `/iflow-plan`, `/iflow plan` | `iflow-plan` | + +| `iflow pr-sync`, `iflow-pr-sync`, `/iflow-pr-sync`, `/iflow pr-sync` | `iflow-pr-sync` | + +| `iflow review`, `iflow-review`, `/iflow-review`, `/iflow review` | `iflow-review` | + +| `iflow setup`, `iflow-setup`, `/iflow-setup`, `/iflow setup` | `iflow-setup` | + +| `iflow split`, `iflow-split`, `/iflow-split`, `/iflow split` | `iflow-split` | + +| `iflow status`, `iflow-status`, `/iflow-status`, `/iflow status` | `iflow-status` | + +| `iflow yolo`, `iflow-yolo`, `/iflow-yolo`, `/iflow yolo` | `iflow-yolo` | + + +Skill `@` attachment is supported on some editors but is not the recommended keyboard-friendly path. + +### Command lifecycle + + +If the project itself is not ready yet — no git repo, no remote, `gh` not authenticated, or no Python project — run **`/iflow-setup`** (or type **`iflow setup`** in chat) first. It reads `issue-flow agent setup-status`, works out whether this is a brand-new or an existing project, and walks the blockers one confirmation at a time. Off-path (never auto-dispatched). + + +If you have not chosen an issue yet, run **`/iflow-pick`** (or type **`iflow pick`** in chat) — the front door that helps you select the next issue (parked work first, else ranked open GitHub issues), creates the branch, and runs `/iflow-capture`. It is off-path (never auto-dispatched). + +If you just want the next right step, run **`/iflow`** (or type **`iflow`** in chat) — it detects state (by file presence under `.issueflows/01-current-issues/` and the status-file `- [x] Done` marker) and dispatches to `/iflow-capture`, `/iflow-plan`, `/iflow-build`, or `/iflow-close`. With no focus issue, it checks active-epic `next_candidates` (`agent state` → `epic_hint`) and **recommends** `/iflow-pick` instead of a blind capture — it never auto-dispatches to the off-path commands (`/iflow-pick`, `/iflow-init`, `/iflow-pause`, `/iflow-cleanup`, `/iflow-yolo`, `/iflow-ops`). + +The full slash-command lifecycle is: + +1. **`/iflow-capture`** — capture the GitHub issue as `issue_original.md`. +2. **`/iflow-plan`** — design the approach in `issue_plan.md` and get explicit confirmation before any code changes. +3. **`/iflow-build`** — implement the confirmed plan. Asks to run `/iflow-plan` first if the plan file is missing. +4. **`/iflow-pause`** *(optional)* — park work mid-stream: update status, move the issue group to `02-partly-solved-issues`, optional WIP commit. +5. **`/iflow-close`** — tests, optional `uv version --bump`, **changelog/`HISTORY.md` update (in the PR commit)**, status update, commit, push, PR. Does not delete branches. Never offer a HISTORY/CHANGELOG update after close finishes or after merge; use `nohistory` only to skip intentionally. (A draft opened earlier via `/iflow-build` early PR does not skip the close HISTORY step.) + +6. **`/iflow-cleanup`** — post-merge: switch to default, `git pull --ff-only`, `git fetch --prune`, `git branch -d` on reachable local branches under a single consolidated confirm. If ff-only fails, classify with `issue-flow agent default-sync` (never rebase / force-push / push default to skip CI). Squash-landed branches (which `-d` always refuses) need `git branch -D`, offered only behind a **second** confirm that lists tip SHAs; branches with unique work are never deleted. Trailing `include GitHub` (or similar) adds a remote-branch audit with a further confirm for optional remote deletes / findings issue. + + +`/iflow-yolo` chains `capture → plan → build → close yolo` for small, low-risk issues with up-front safeguards (clean tree, passing tests, single consolidated confirm). Its close step is hands-off: changelog decided without a prompt, PR merged (`gh pr merge --squash`; on pending checks may `gh pr checks --watch` then retry, with `--auto` as last resort), then default-branch switch + pull. + + +`/iflow-ops` runs **ops / no-PR** work (staging→prod, flag flips, external deploys): execute the checklist, then `/iflow-close ops` — no push/PR. Product-code dirty trees are refused. Off-path (never auto-dispatched). + + + +`/iflow-init` cold-starts or checks the issue-flow harness (guides `issue-flow init` / `update`). It does **not** capture GitHub issues — that is `/iflow-capture`. Off-path (never auto-dispatched). + + + +Issue labels can select the flow: when an issue picked via `/iflow-pick` carries the **`yolo`** label, it is routed through `/iflow-yolo` (one combined confirmation). The **`ops`** label routes to `/iflow-ops` (no PR); when both labels are present, **ops wins**. Controlled by `label_flows` (default `true`), `yolo_label` (default `"yolo"`), and `ops_label` (default `"ops"`) under `[issueflow]` in `.issueflows/config.toml`; re-run `issue-flow update` after changing them. + + + +Lifecycle skills include a **`### MODEL & EXECUTION DIRECTIVE`** section that tells agents whether to prioritize **economy** (speed) or **reasoning** (depth) for that step. Toggle with `step_directives` under `[issueflow]`; override per step via `[issueflow.step_profiles]`; optional label hints during `/iflow-pick` via `model_label_flows`, `deep_model_label`, and `fast_model_label`. Re-run `issue-flow update` after changing any of these. + + + +`/iflow-fix` opens an interactive iterative-fixes session: it creates one GitHub issue + long-lived branch, then loops over many small fixes (each gets a short plan and is implemented only on confirmation, recorded as a dated bullet in `issue_status.md`), and ends with `/iflow-close`. It is off-path (never auto-dispatched); while a session is active, drive it with `/iflow-fix` + `/iflow-close`, not `/iflow`. With `fix_auto_name = false` (default), inventing a non-default slug asks once before the create confirm. Toggle via `fix_auto_name` under `[issueflow]` in `.issueflows/config.toml`; re-run `issue-flow update` after changing. + + +`/iflow-issue` creates **one well-specified normal GitHub issue** (context / spec / acceptance criteria), then optionally branches and runs `/iflow-capture` into the standard lifecycle. It fills the gap between `/iflow-fix` (iterative small-fixes) and `/iflow-epic` (multi-issue staged work). Off-path (never auto-dispatched). For an epic anchor: `/iflow-issue epic `. + + +`/iflow-split` cuts **one over-large existing issue** into 2–5 flat GitHub native sub-issues behind one consolidated confirm (parent stays open as the tracker). Off-path (never auto-dispatched). Staged work with dependencies still goes through `/iflow-epic`. `/iflow-pick` / `/iflow-issue` / `/iflow-plan` may *offer* split; they never create children themselves. + + +`/iflow-status` prints a **read-only** overview of where every issue stands — the local tracking state under `.issueflows/` (focus / parked / solved) plus open GitHub issues cross-referenced against it. It is off-path (never auto-dispatched) and changes nothing. + + +`/iflow-doctor` audits `.issueflows/` for **dirty** conditions (ambiguous multi-focus, leftovers in `01-current-issues/`, duplicates across folders, and similar) and can apply **safe repairs** on confirmation (`issue-flow doctor` / `agent audit` + `repair`). It is off-path and never auto-dispatched. + + +`/iflow-review` reviews open GitHub issues and applies labels (extendable kinds; v1: **yolo** → configured `yolo_label`). Off-path; consolidated confirm before any label create/apply; never auto-dispatched. CLI helpers: `issue-flow agent label-candidates` / `label-apply`. + + +`/iflow-epic ` plans a change **too large for one issue** as a staged epic: it drafts `.issueflows/05-epics/epic_plan.md` (anchored to GitHub issue ``), dividing the work into sequential stages of manageable issue specs with explicit dependencies and a per-issue yolo-fitness judgment. Drafting writes nothing on GitHub; **`/iflow-epic publish [stage ]`** creates a confirmed stage's issues behind one consolidated confirm (yolo labels per the recorded judgment, task list maintained on the anchor issue, `Published: #` recorded back into the plan so re-runs are idempotent). Off-path (never auto-dispatched); epics decompose into the normal single-issue lifecycle, never around it. + + +`/iflow-cycle ` processes **many issues hands-off in a row** under a single up-front confirmation — the batch equivalent of `/iflow-yolo`. It resolves a queue via `issue-flow agent queue` (explicit numbers, `label:`, or `epic [stage ]`), then runs each issue through the full yolo chain (PR auto-merged), interrupting you only when input is **strictly necessary** (unfixable failure, refused merge / non-fast-forward pull, ambiguous or not-actually-small spec, or anything outside the confirmed queue). It stops the whole cycle on the first such condition, leaving the repo clean on the default branch. **All yolo-labelled issues:** `/iflow-cycle yolo` (alias for `label:yolo`). Off-path (never auto-dispatched); never weakens a yolo safeguard to keep moving. + + +`/iflow-auto ` runs an **unattended large-change** path over a confirmed epic: select a stage, drive it via `/iflow-cycle`, record `auto_status.md`, then adversarial inter-epoch review (`review` token; may reopen/create issues under the overnight confirm). On findings, honour the loop budget (re-queue + re-review, or **stop and ask**: accept / grant N more loops / abort). Advance to stage `k+1` only when stage `k` is clear (`epic-status` done + no open blockers); otherwise `epoch_gated`. Budget baked as **2** (`loops:` overrides). Off-path (never auto-dispatched). See `.issueflows/04-designs-and-guides/advanced-auto-mode.md`. + + +`/iflow-drive ` runs a **compose-only** path from an existing GitHub issue: draft epic (auto-confirm unless grill-me) → publish every stage → `/iflow-auto` each epoch → final review (create leftover findings) → local cleanup **`-d` only** → `/iflow-status`. One confirm covers draft-accept, publish-all, auto-all, final-review creates, and reachable-only cleanup. User `abort` / `stop` / `cancel` / `halt` stops at the next boundary. Off-path (never auto-dispatched). See `.issueflows/04-designs-and-guides/drive-mode.md`. + + +`/iflow-archive` condenses old solved issue groups under `.issueflows/03-solved-issues/` into a single dated `YYYY-MM-DD_archived_issues.md` summary file (recording the pre-archive git ref for recovery via `git show :`), then deletes the original `issue_*` files. It is off-path and destructive: nothing is deleted before one consolidated confirmation. + + +`/iflow-pr-sync` refreshes **open** PR heads that went `DIRTY` after another merge (usually `HISTORY.md`): worktree → `issue-flow agent sync-branch` keep-both → `git push --force-with-lease`. Off-path; see `.issueflows/04-designs-and-guides/pr-queue-sync.md` (issue #260). + + + +> On tools without project slash commands (e.g. Codex CLI), invoke the mirrored Agent Skills instead (for example `iflow-capture` in place of `/iflow-capture`). + +### When finishing an issue + +If the issue is fully resolved (no additional subtasks present), move the original, plan, and status markdown files to `.issueflows/03-solved-issues`. Else, move them to `.issueflows/02-partly-solved-issues`. + +### Scripts that can help us when working on issues + +`.issueflows/00-tools/` is the project's durable toolbox of reusable helper scripts, with a `README.md` index describing each one. + +- **Check it first.** Before writing a new one-off helper for an issue, skim the `00-tools/README.md` index and the folder — a suitable tool may already exist. +- **Contribute back.** If you build something during an issue that could help on a future one, save it into `.issueflows/00-tools/` and add a one-line entry to the index (name, what it does, when to use it) so the next agent knows whether to reach for it. + + + +### Optional response styles + +A **caveman** Agent Skill is installed under `.cursor/skills/caveman/`. It +is a terse, "token-greedy" response style that keeps all technical substance +while dropping filler, articles, and pleasantries. It is **off by default** and +only kicks in when the user asks for it (e.g. "caveman", "token greedy", "be +terse"). Turn it off with **"stop caveman"** or **"normal mode"**. Code, +commits, PRs, security warnings, and destructive-action confirmations are always +written in normal prose, never caveman. (To make caveman on by default for this +project, set `caveman_default = true` under `[issueflow]` in +`.issueflows/config.toml` and re-run `issue-flow update`.) + + + + +### Planning aids + +A **grill-me** Agent Skill is installed under `.cursor/skills/grill-me/`. +It runs a relentless planning interview that stress-tests a plan or design — +one question at a time, each with a recommended answer — until every branch of +the decision tree is resolved. It is **off by default** and only kicks in when +you ask for it (e.g. "grill me", "poke holes in this"). Turn it off with **"stop +grilling"** or **"normal mode"**. (To make grilling on by default during planning +for this project, set `grill_me_default = true` under `[issueflow]` in +`.issueflows/config.toml` and re-run `issue-flow update`.) + + + + +### CI via GitHub CLI + +A **gh-ci** Agent Skill is installed under `.cursor/skills/gh-ci/`. Use +it whenever you need to know if CI finished: prefer `gh pr checks` / +`gh pr checks --watch --fail-fast` (budget: `checks_watch_minutes`, default +15); fall back to `gh run list` / `gh run watch` when PR +checks are empty. Always pass `--repo `. `/iflow-close` owns the +merge sequence; this skill is the shared command cheatsheet. + + + +### Designs and guides + +Long-lived design docs, design decisions, and project "good practices" live under `.issueflows/04-designs-and-guides/`. Unlike the issue folders, content here is **not** tied to a single issue and is **not** archived when an issue closes — it is the project's durable memory. + +- **Project brief:** if `.issueflows/04-designs-and-guides/this-project.md` exists, read it early for project-specific context (what the repo is, stack/runtime, how to run/test, conventions, entry points, and known limitations). +- **Before planning or implementing**, skim `.issueflows/04-designs-and-guides/` for existing docs relevant to the current issue and follow them (cite them in the plan when they influence the approach). +- **When a non-trivial design decision is made** during `/iflow-plan` or `/iflow-build`, add or update a markdown file here. Keep entries terse: context, the decision, alternatives considered, and a link back to the issue. +- **Never overwritten by `issue-flow update`.** The folder is recreated if missing, but existing files are left alone. + + +### Multi-root workspaces + +When an editor workspace contains **multiple sibling repositories**, each with its own `.issueflows/` scaffold: + +- **Resolve the target repo first** — explicit `root:` / `repo:` hints, then `issue-flow agent resolve`, then branch/single-scaffold heuristics, then the **workspace default** from `issueflow-workspace.toml` at the workspace root (create it with `issue-flow workspace init`); **ask** when still ambiguous. Never let `git` or `gh` infer the repo from cwd alone. +- **Scoped rules** — this repo's `issueflow-rules` apply under this project root only (path globs). Put **toolchain-specific** run/test commands in `.issueflows/04-designs-and-guides/this-project.md`, not in shared boilerplate that every repo merges. +- **Per-repo lifecycle** — `/iflow-cleanup`, branch hygiene, and focus issue folders are **per repository**; repeat commands in each repo when needed. +- **Design doc** — see `.issueflows/04-designs-and-guides/multi-repo-workspaces.md` when present (issue #67). + + +### Branch hygiene + +- Do issue work on an **issue branch** named like `-`, not on the default branch. +- Before starting or continuing work on an issue branch, run `git fetch --prune` and check where the branch sits relative to `origin/` (ahead/behind). A branch that is "several commits ahead" after a merged PR usually means the PR was merged (this project uses **`squash`**) and the local branch is stale. +- **Assume `squash` merges on GitHub.** After a PR merges, **remind** the user to run **`/iflow-cleanup`** (switch to default, `git pull --ff-only`, `git fetch --prune`, `git branch -d` on reachable locals under one confirm, plus a second confirm for the squash-landed branches that `-d` can never take). Do **not** auto-run cleanup from close/yolo/cycle; `/iflow-close` no longer does this step itself. + +- If an issue is already archived under `.issueflows/02-partly-solved-issues` or `.issueflows/03-solved-issues`, the matching local branch is stale; don't resume work on it silently — switch back to the default branch and, if the issue really needs re-opening, do it deliberately through `/iflow-capture` (which will ask for a second confirmation). + + +### Folder hygiene for `.issueflows/01-current-issues` + +- Only the **focus issue** (the one currently being worked on) should live in `.issueflows/01-current-issues`. +- `/iflow-capture` and `/iflow-build` both sweep that folder automatically: every `issue_*` group **other than the focus issue** is moved to `.issueflows/03-solved-issues` if a status file contains `- [x] Done`, otherwise to `.issueflows/02-partly-solved-issues`. Keep status files accurate so the sweep routes them correctly. + + +### Knowledge graph (optional, via [graphify](https://iflow-graphify.net)) + +If a `graphify-out/` folder exists in the project root, the project has the optional [graphify](https://iflow-graphify.net) integration enabled and a knowledge graph is available alongside the source. + +- **Before grepping**, skim `graphify-out/GRAPH_REPORT.md`. It surfaces god-nodes (most-connected concepts), surprising cross-module connections, and suggested questions the graph can answer — often a faster way to locate the files an issue actually touches than full-text search. +- **`/iflow-graphify`** (slash command) or **`issue-flow graphify`** (CLI) rebuild the graph. With no extra args this runs `graphify update ` — AST-only, **no LLM API key needed**. For richer semantic relationships (cross-file links surfaced by an LLM pass), run `issue-flow graphify extract` after setting `GEMINI_API_KEY` / `ANTHROPIC_API_KEY` / `OPENAI_API_KEY` / `MOONSHOT_API_KEY` (or pass `--backend ollama` for a local LLM). Other subcommands: `watch` (live), `cluster-only --no-viz` (re-cluster). Trailing flags pass through verbatim. Your agent's own LLM cannot be reused by subprocesses; graphify needs its own backend. +- `/iflow-graphify` is **off-path**: never auto-dispatched by `/iflow`, `/iflow-build`, or `/iflow-close`. It is the user's call. `/iflow-build` may *suggest* skimming `GRAPH_REPORT.md`; `/iflow-close` may *suggest* a rebuild after large structural changes — neither runs `graphify` automatically. +- If `graphify-out/` is not present, ignore graph-related guidance entirely. The integration is opt-in (install with `uv tool install graphifyy`, then `issue-flow update` to register the graphify skill). + diff --git a/.cursor/skills/caveman/SKILL.md b/.cursor/skills/caveman/SKILL.md new file mode 100644 index 0000000..6260492 --- /dev/null +++ b/.cursor/skills/caveman/SKILL.md @@ -0,0 +1,63 @@ +--- +name: caveman +description: >- + Respond in a terse "smart caveman" style that keeps all technical substance + but drops filler, articles, and pleasantries. Use when the user asks for + caveman mode, token-greedy / terse answers, or says "be brief" / "stop + wasting tokens". Stays active across the session once on; off via "stop + caveman" / "normal mode". +issue-flow-version: 0.4.2a4 +--- + +# Be token greedy - as a caveman + +Respond terse like smart caveman. All technical substance stay. Only fluff die. + +## Persistence + +ACTIVE EVERY RESPONSE once turned on. No revert after many turns. No filler drift. Still active if unsure. Off only: "stop caveman" / "normal mode". + +## Rules + +Drop: articles (a/an/the), filler (just/really/basically/actually/simply), pleasantries (sure/certainly/of course/happy to), hedging. Fragments OK. Short synonyms (big not extensive, fix not "implement a solution for"). No tool-call narration, no decorative tables/emoji, no dumping long raw error logs unless asked — quote shortest decisive line. Standard well-known tech acronyms OK (DB/API/HTTP); never invent new abbreviations reader can't decode. Technical terms exact. Code blocks unchanged. Errors quoted exact. + +No self-reference. Never name or announce the style. No "caveman mode on", "me caveman think", no third-person caveman tags. Output caveman-only — never normal answer plus "Caveman:" recap. Exception: user explicitly ask what the mode is. + +Pattern: `[thing] [action] [reason]. [next step].` + +Not: "Sure! I'd be happy to help you with that. The issue you're experiencing is likely caused by..." +Yes: "Bug in auth middleware. Token expiry check use `<` not `<=`. Fix:" + +English only. Caveman applies to English output; do not garble other languages. + +## Intensity + +Single level: **full**. Classic caveman — every rule above applies at full strength; there is no milder setting. + +Example — "Why React component re-render?" +- "New object ref each render. Inline object prop = new ref = re-render. Wrap in `useMemo`." + +Example — "Explain database connection pooling." +- "Pool reuse open DB connections. No new connection per request. Skip handshake overhead." + +## Auto-Clarity + +Drop caveman when: +- Security warnings +- Irreversible action confirmations +- Multi-step sequences where fragment order or omitted conjunctions risk misread +- Compression itself creates technical ambiguity (e.g., `"migrate table drop column backup first"` — order unclear without articles/conjunctions) +- User asks to clarify or repeats question + +Resume caveman after clear part done. + +Example — destructive op: +> **Warning:** This will permanently delete all rows in the `users` table and cannot be undone. +> ```sql +> DROP TABLE users; +> ``` +> Caveman resume. Verify backup exist first. + +## Boundaries + +Code/commits/PRs: write normal. "stop caveman" or "normal mode": revert. Mode persist until changed or session end. diff --git a/.cursor/skills/gh-ci/SKILL.md b/.cursor/skills/gh-ci/SKILL.md new file mode 100644 index 0000000..c0d5ade --- /dev/null +++ b/.cursor/skills/gh-ci/SKILL.md @@ -0,0 +1,60 @@ +--- +name: gh-ci +description: >- + Use GitHub CLI to snapshot or wait on CI for a pull request or workflow run. + Prefer gh pr checks / gh pr checks --watch; fall back to gh run list and + gh run watch when PR checks are empty or unavailable. Use when waiting for + CI, checking if checks are green, Actions are pending/failed, or the user + mentions gh run watch / gh pr checks / "CI green". +issue-flow-version: 0.4.2a4 +--- + +# gh-ci — wait on GitHub CI with `gh` + +Teach agents the concrete `gh` commands for **listing** and **watching** CI. +Always pass `--repo ` (never rely on `gh`'s cwd default). + +## Primary (PR-attached checks) + +Prefer these when a pull request number is known (usual `/iflow-close` path): + +```bash +# One-shot snapshot — exit 0 means green (or all pass / skipping) +gh pr checks --repo + +# Wait until checks finish (or fail-fast on red) +gh pr checks --repo --watch --fail-fast +``` + +**Budget:** honour **15 minutes** wall-clock for any +`--watch` (from `[issueflow].checks_watch_minutes` / +`ISSUEFLOW_CHECKS_WATCH_MINUTES`, default 15). `gh` has no max-duration flag — +the agent stops the watch when the cap hits. + +## Fallback (workflow runs) + +When `gh pr checks` returns empty, cannot resolve checks, or there is no PR yet +but a workflow run id is known: + +```bash +gh run list --repo --limit 10 +gh run watch --repo +``` + +Optional: `gh run view --repo --log-failed` after a red +run to surface failing job logs. + +## Semantics + +| Result | Meaning | Agent action | +|--------|---------|--------------| +| Exit 0 / all `pass` or `skipping` | CI green | Proceed (merge, report green, etc.) | +| Fail / `--fail-fast` | CI red | Stop hands-off paths; report failing check/run URLs | +| Still pending past budget | Unknown | Do not hang; report pending and follow the calling skill (e.g. close yolo may fall back to `--auto`) | + +## Where this fits + +- **`/iflow-close`** owns the merge / yolo watch-then-merge sequence; this skill + is the shared cheatsheet for the CI commands themselves. +- Design record: `.issueflows/04-designs-and-guides/gh-list-and-watch.md` + (issues #172, #220). diff --git a/.cursor/skills/grill-me/SKILL.md b/.cursor/skills/grill-me/SKILL.md new file mode 100644 index 0000000..e2d7d99 --- /dev/null +++ b/.cursor/skills/grill-me/SKILL.md @@ -0,0 +1,57 @@ +--- +name: grill-me +description: >- + Interview the user relentlessly about a plan or design until every branch of + the decision tree is resolved, then feed the conclusions into the issue plan. + Use when the user wants to stress-test a plan, asks to "grill me", or during + /iflow-plan when grilling is turned on. Off via "stop grilling" / "normal mode". +issue-flow-version: 0.4.2a4 +--- + +# Grill me — relentless planning interview + +Interview the user about every aspect of the plan until you reach a shared, +unambiguous understanding. Walk down each branch of the design tree, resolving +dependencies between decisions one at a time. The goal is to surface hidden +assumptions and edge cases **before** they get encoded in code or written into +`.issueflows/01-current-issues/issue_plan.md`. + +## When to use + +- The user asks to be grilled / stress-tested ("grill me", "poke holes in this"). +- During `/iflow-plan`, when grilling is active (see *Activation* below), to + pressure-test the approach before the plan file is drafted. + +## How to grill + +- **One question at a time.** Never batch questions. Wait for the answer before + moving to the next branch. +- **Always recommend an answer.** For each question, give your recommended option + and a one-line rationale, so the user can accept quickly or push back. +- **Explore before asking.** If a question can be answered by reading the code, + the issue text, or `.issueflows/04-designs-and-guides/`, explore first + and confirm what you found instead of asking the user to do your homework. +- **Follow the decision tree.** Resolve upstream decisions before the ones that + depend on them; let earlier answers prune later branches. +- **Stay on scope.** Grill the issue at hand. Park genuinely separate concerns as + follow-up notes rather than expanding the interview indefinitely. +- **Know when to stop.** End when every open branch is resolved (or explicitly + deferred) and you can restate the plan without ambiguity. Summarize the agreed + decisions so they can flow straight into the plan. + +## Activation + +This skill is **dormant by default**: it engages only when the user asks for it +("grill me") or when a project turns it on for planning. + +Turn it off again for the rest of a session with **"stop grilling"** or +**"normal mode"**. (To make grilling on by default during planning for this +project, set `grill_me_default = true` under `[issueflow]` in +`.issueflows/config.toml` and re-run `issue-flow update`.) + + +## Boundaries + +- Grilling is a **planning** aid: it questions and aligns, it does not write code. +- Hand the agreed decisions to `/iflow-plan` so they land in `issue_plan.md`; + implementation still goes through `/iflow-build`. diff --git a/.cursor/skills/iflow-archive/SKILL.md b/.cursor/skills/iflow-archive/SKILL.md new file mode 100644 index 0000000..d23a566 --- /dev/null +++ b/.cursor/skills/iflow-archive/SKILL.md @@ -0,0 +1,92 @@ +--- +name: iflow-archive +description: >- + Condense old solved issue groups into one dated summary file, then delete + the originals. Destructive, one consolidated confirm. +disable-model-invocation: true +issue-flow-version: 0.4.2a4 +--- + +# issue-flow — archive solved issues (`/iflow-archive`) + +Follow this skill to **shrink the solved-issues archive**: +old `issue_*` groups under `.issueflows/03-solved-issues/` are +summarised into one dated markdown file and the originals are deleted (they +stay recoverable through git history). + +Do **not** use this to park or close an active issue — that is `/iflow-pause` / `/iflow-close`. This skill only touches `.issueflows/03-solved-issues/`. + +## Input + +- **(nothing)** — smart default: propose archiving every solved group **except the 5 most recent** (highest issue numbers). +- **`keep `** — same, but keep the `` most recent groups instead. +- **an explicit list** (e.g. `12 13 24`) — archive exactly those issues. +- **`all`** — archive every solved group. + + +**Invoke:** type `iflow archive` in chat, or `/iflow-archive` from the slash menu (`iflow-archive` also works). + + + + +### MODEL & EXECUTION DIRECTIVE + + +**Profile: reasoning** — Prioritize deep thinking and careful trade-offs over speed or token economy. + +In Cursor: switch to a thinking-capable model before invoking this step (not Auto-only). + + + +Keep scope tight to what this step requires. + + + +## Instructions + +> **CLI fast path (optional).** If the `issue-flow` CLI is on `PATH`, the +> mechanical deletion step has a deterministic shortcut: +> `issue-flow agent archive [ ...]` (add `--dry-run` to preview, +> `--json` for a machine-readable object). It removes the chosen groups' +> files and reports the pre-archive HEAD sha — you still select candidates, +> confirm with the user, and write the summary file yourself. The CLI is +> optional: if it is missing or errors, fall back to the manual instructions +> below. + +1. **Preflight.** Require a **clean working tree** (`git status --porcelain`); if dirty, **stop** and ask the user to commit or stash first — the recovery ref is only meaningful when the deletion lands as its own commit. Capture the pre-archive ref: `git rev-parse HEAD`. + +2. **Select candidates.** List every `issue_*` group in `.issueflows/03-solved-issues/` with its number and title (from the `# Issue #N: ` heading of `issue<N>_original.md`). Apply the input rule (default: all except the 5 most recent by issue number). Show the resulting candidate list — number, title, file names — and let the user add/remove issues. + +3. **Consolidated confirm** (destructive — written in normal prose, never shortened). One prompt covering exactly: which issues get summarised, that their files will be **deleted**, and that recovery relies on git history via the recorded ref. Do not proceed without a clear yes. + +4. **Summarise (before deleting).** Append to `.issueflows/03-solved-issues/YYYY-MM-DD_archived_issues.md` (today's date; create the file if missing). Structure: + + ```markdown + # Archived issues — YYYY-MM-DD + + Pre-archive git ref: `<sha>` + Recover any archived file with `git show <sha>:<path>` (or browse `git log -- <path>`). + + ## Issue #<N>: <title> + + - Source: <GitHub issue URL, from the original file> + - Archived files: issue<N>_original.md, issue<N>_plan.md, issue<N>_status.md + - Summary: 2–4 sentences distilled from the original / plan / status files — + what the issue was, what was done, and the outcome. + ``` + + One `## Issue` section per archived issue. If the dated file already exists (same-day rerun), append a `---` separator followed by a fresh `Pre-archive git ref:` line for this run, then the new issue sections. The dated filename deliberately does **not** match `issue<N>_*`, so it never interferes with issue grouping. + +5. **Delete.** Remove the archived groups' files — CLI fast path (`issue-flow agent archive ...`), or manually `git rm .issueflows/03-solved-issues/issue<N>_*` per issue. + +6. **Commit offer.** Propose a single commit, e.g. `chore(iflow): archive <count> solved issues (pre-archive ref <short-sha>)`, including the new/updated dated file and the deletions. Ask before committing; never push from this skill. + +7. **Report.** Summarise: how many issues were archived, the dated file path, the pre-archive ref, and the one-line recovery recipe. + +## Constraints + +- **Off-path.** Never auto-dispatch from `/iflow`, `/iflow-build`, or `/iflow-close`. The user opts in explicitly. +- **Destructive, so gated.** Never delete anything before the consolidated confirm in step 3, and never delete files that were not summarised in step 4. +- Only `.issueflows/03-solved-issues/` is touched — never `01-current-issues/`, `02-partly-solved-issues/`, `00-tools/`, or `04-designs-and-guides/`. +- Requires a clean working tree; the deletion should land as its own commit so `git show <ref>:<path>` recovery always works. +- Summaries are interpretive (agent judgment); the CLI only ever does the mechanical deletion. diff --git a/.cursor/skills/iflow-auto/SKILL.md b/.cursor/skills/iflow-auto/SKILL.md new file mode 100644 index 0000000..9b2fd3d --- /dev/null +++ b/.cursor/skills/iflow-auto/SKILL.md @@ -0,0 +1,181 @@ +--- +name: iflow-auto +description: >- + Unattended large-change orchestrator over a confirmed epic: cycle a stage, + adversarial review, loop budget, next-epoch gate when the queue is clear. +disable-model-invocation: true +issue-flow-version: 0.4.2a4 +--- + +# issue-flow — advanced auto (`/iflow-auto`) + +Follow this skill to run an **unattended large-change flow** over a confirmed +epic: select a stage, drive it through `/iflow-cycle`, record durable state in +`auto_status.md`, run adversarial inter-epoch review (`review`), then honour +the adversarial **loop budget** (re-queue or stop-and-ask). + + +Contract: `.issueflows/04-designs-and-guides/advanced-auto-mode.md` +(criteria table, budget, outcomes). + +## Input + +- **`<N>`** — epic anchor issue number (requires `epic<N>_plan.md` with + `Status: confirmed`). +- **`stage <k>`** — optional stage index; default = earliest unfinished published + stage (`issue-flow agent epic-status <N> --json` → `current_stage`). +- **`loops:<n>`** — override adversarial loop budget for this run (baked default + **2** from `[issueflow].auto_adversarial_loops`). +- **`review`** — run only the adversarial procedure for epic `<N>` (and optional + `stage <k>`); skip cycle unless a full auto run is also intended. +- **`status`** — print `auto_status.md` / epic-status and stop (no confirm). +- **`dry-run`** — resolve stage + queue, show what would run, stop (no confirm). + + +**Invoke:** type `iflow auto` in chat, or `/iflow-auto` from the slash menu (`iflow-auto` also works). + + + + +### MODEL & EXECUTION DIRECTIVE + + +**Profile: reasoning** — Prioritize deep thinking and careful trade-offs over speed or token economy. + +In Cursor: switch to a thinking-capable model before invoking this step (not Auto-only). + + + +Keep scope tight to what this step requires. + + + + +### Resolve project root (multi-root workspaces) + +Before any `git`, `gh`, or `.issueflows/` path operation in this workflow: + +**Resolution order** (stop when unambiguous): + +1. **Explicit hints** in slash input — `root:<path>`, `repo:<folder-basename>` (directory name, e.g. `cellpy-core`), or `repo:owner/name`. +2. **CLI fast path** — `issue-flow agent resolve [-C <start>] [--from-file <active-file>] [--json]`. Use the returned `project_root` and `repo`; pass `-C <project_root>` to other `issue-flow agent …` subcommands. When the answer came from the workspace registry, the payload sets `resolved_via_workspace_default: true`. +3. **Branch context** — exactly one workspace repo whose branch matches `^\d+-` → that root. +4. **Single scaffold** — exactly one `.issueflows/` tree visible in the workspace → that root. +5. **Workspace default** — an `issueflow-workspace.toml` at the workspace root (created with `issue-flow workspace init`) may name a `default` member repo; use it when no scaffold matched above. Tell the user the default was used. +6. **Ambiguous** → **stop and ask**; never guess between sibling repos. + +After resolution, treat the result as `<project_root>` and `<owner/repo>`: + +- **Git:** `git -C <project_root> …` (or `issue-flow agent … -C <project_root>` for supported ops). +- **GitHub:** pass an explicit repo on every `gh` call — never rely on `gh`'s implicit cwd default. For most commands use `--repo <owner/repo>`; **exception:** `gh repo view` takes the repo as a **positional** arg (`gh repo view <owner/repo> …`) and rejects `--repo`. +- **Paths:** all `.issueflows/…` paths are under `<project_root>`. + +When `.issueflows/04-designs-and-guides/multi-repo-workspaces.md` exists, read it for layout and cross-repo guidance. + +## Instructions + +1. **Resolve epic.** Require `.issueflows/05-epics/epic<N>_plan.md` + with `Status: confirmed`. Run `issue-flow agent epic-status <N> --json`. If + the plan is draft/missing, **stop** and point at `/iflow-epic <N>`. + +2. **Select stage.** Use `stage <k>` if given; else `current_stage` from + epic-status. If every published stage is done, report done and stop. + +3. **Resolve loop budget.** Trailing `loops:<n>` (positive int) > baked + **2** > default 2. Record the effective budget. + +4. **`status` / `dry-run`.** If either token is present: show epic, stage, queue + (`issue-flow agent queue --epic <N> --json`), budget, loop count from + `auto_status.md` if present; **stop** without confirm or writes. + +5. **`review`-only path.** If `review` is present and this is not a full + overnight run: jump to **Adversarial procedure** (step 9). If + `auto_status.md` lacks overnight authorization for this epic/stage, present + one confirm (epic, stage, that create/reopen may happen) before proceeding. + +6. **Overnight confirm** (full auto; only planned interruption before the + budget ask). Present in normal prose: epic `#<N>`, stage index + title, + ordered queue (numbers + titles), that each issue runs full yolo + + auto-merge via `/iflow-cycle`, **loop budget**, and that adversarial review + may **reopen or create** GitHub issues under that confirm. Require explicit + yes. + +7. **Write / update `auto_status.md`** at + `.issueflows/01-current-issues/auto_status.md`: + epic, stage, `loop_count` (`0` at start of full run), `budget`, ISO + timestamp, last outcome `pending`, overnight authorization. Not an + `issue<N>_*` group — sweeps leave it alone. + +8. **Run the stage via `/iflow-cycle`.** Follow + `.cursor/skills/iflow-cycle/SKILL.md` for `epic <N>` (the CLI queues + the current stage). The overnight confirm above covers cycle's consolidated + confirm — do not re-ask. Honour cycle stop conditions and `onfail:stop`. + Update `auto_status.md` with the cycle outcome. + +9. **Adversarial procedure** (after cycle, or via `review`): + + a. Gather evidence (read-only first): stage issues + states from + `epic-status`; merged PR titles/bodies via `gh pr list` / + `gh pr view --repo <owner/repo>` for those issues; epic `## Goal` / + Constraints and stage Goal / paragraph from `epic<N>_plan.md`. + b. Apply the criteria table in + `.issueflows/04-designs-and-guides/advanced-auto-mode.md` + (stage goal, epic progress, spec honesty, blast radius). + c. If **clear**: set `last_outcome: adversarial_clear` and a short findings + summary in `auto_status.md`. Proceed to **Next-epoch gate** (step 11). + d. If **gaps**: for each finding, prefer `gh issue reopen <M> --repo + <owner/repo>` plus a comment with concrete remaining acceptance when an + existing stage issue owns the gap; otherwise `gh issue create --repo + <owner/repo>` with Spec, Goal, **`Model: deep`**, `Depends on`, and + `Part of epic #<N>.` — no new label in v1. Record numbers + notes in + `auto_status.md` with `last_outcome: adversarial_findings`. + e. No extra user prompts while acting under overnight / review confirm + (except the budget ask in step 10). + +10. **Loop control** (only after `adversarial_findings`): + + a. Increment `loop_count` in `auto_status.md` by 1 for this adversarial pass. + b. Collect open work: reopened stage issues + newly created inter-epoch + blockers still open (from the findings list / `epic-status`). + c. If open work remains and `loop_count` **<** `budget`: re-queue those + issue numbers via `/iflow-cycle` (explicit numbers; overnight confirm + already covers cycle confirms — do not re-ask), then **return to step 9** + (adversarial procedure). Keep yolo/cycle safeguards. + d. If open work remains and `loop_count` **>=** `budget`: set + `last_outcome: budget_ask` and **stop and ask** in normal prose — three + options only: + - **accept** current implementation (record `accepted`; do not re-queue) + - **grant N more loops** (raise effective `budget` by N for this run; + clear `budget_ask`; continue from 10c) + - **abort** (record `aborted`; stop) + e. If no open work remains after findings were addressed by a prior loop, + treat as clear for loop purposes and go to step 11. + f. After user **accept**, still run step 11 (gate will refuse advance if + open work remains). + +11. **Next-epoch gate** (after `adversarial_clear`, loops drained with no open + work, or budget **accept**): + + a. Re-run `issue-flow agent epic-status <N> --json`. Stage `k` is clear + only when that stage's `done` is true **and** no open inter-epoch + blocker numbers remain in `auto_status.md` findings. + b. If **not** clear: set `last_outcome: epoch_gated`, list open numbers / + blockers, **do not** start stage `k+1`, go to step 12. + c. If clear and a later unfinished published stage exists: under the same + overnight authorization, set `auto_status.md` stage to that index, + reset `loop_count` to `0`, `last_outcome: pending`, and **return to + step 2** (select/run that stage). Do not re-ask overnight confirm. + d. If every published stage is done: set `last_outcome: complete`. + +12. **Report.** Epic, stage, cycle results (if any), adversarial outcome + + issue numbers, `loop_count` / `budget`, gate result, `auto_status.md` + path. Remind `/iflow-cleanup` after merges + (do not auto-run it). + +## Constraints + +- **Off-path:** `/iflow` never auto-dispatches here. +- Do not weaken yolo/cycle safeguards. +- Do not run `/iflow-cleanup` from this skill. +- Never start stage `k+1` while stage `k` is not clear (`epoch_gated`). +- Compose `/iflow-epic` + `/iflow-cycle` + `/iflow-yolo`; do not fork them. diff --git a/.cursor/skills/iflow-build/SKILL.md b/.cursor/skills/iflow-build/SKILL.md new file mode 100644 index 0000000..622a4f2 --- /dev/null +++ b/.cursor/skills/iflow-build/SKILL.md @@ -0,0 +1,111 @@ +--- +name: iflow-build +description: >- + Implement the confirmed plan for the focus issue using the project's + documented conventions. +disable-model-invocation: true +issue-flow-version: 0.4.2a4 +--- + +# issue-flow — issue build (`/iflow-build`) + +Follow this skill to **begin implementation** from issue notes and project rules. Planning itself lives in `/iflow-plan`; this skill is implementation-only. Stay aligned with `.cursor/rules/issueflow-rules.mdc` when present. + + +**Invoke:** type `iflow build` in chat, or `/iflow-build` from the slash menu (`iflow-build` also works). + + + + +### MODEL & EXECUTION DIRECTIVE + + +**Profile: reasoning** — Prioritize deep thinking and careful trade-offs over speed or token economy. + +In Cursor: switch to a thinking-capable model before invoking this step (not Auto-only). + + + +Keep scope tight to what this step requires. + + + + +### Resolve project root (multi-root workspaces) + +Before any `git`, `gh`, or `.issueflows/` path operation in this workflow: + +**Resolution order** (stop when unambiguous): + +1. **Explicit hints** in slash input — `root:<path>`, `repo:<folder-basename>` (directory name, e.g. `cellpy-core`), or `repo:owner/name`. +2. **CLI fast path** — `issue-flow agent resolve [-C <start>] [--from-file <active-file>] [--json]`. Use the returned `project_root` and `repo`; pass `-C <project_root>` to other `issue-flow agent …` subcommands. When the answer came from the workspace registry, the payload sets `resolved_via_workspace_default: true`. +3. **Branch context** — exactly one workspace repo whose branch matches `^\d+-` → that root. +4. **Single scaffold** — exactly one `.issueflows/` tree visible in the workspace → that root. +5. **Workspace default** — an `issueflow-workspace.toml` at the workspace root (created with `issue-flow workspace init`) may name a `default` member repo; use it when no scaffold matched above. Tell the user the default was used. +6. **Ambiguous** → **stop and ask**; never guess between sibling repos. + +After resolution, treat the result as `<project_root>` and `<owner/repo>`: + +- **Git:** `git -C <project_root> …` (or `issue-flow agent … -C <project_root>` for supported ops). +- **GitHub:** pass an explicit repo on every `gh` call — never rely on `gh`'s implicit cwd default. For most commands use `--repo <owner/repo>`; **exception:** `gh repo view` takes the repo as a **positional** arg (`gh repo view <owner/repo> …`) and rejects `--repo`. +- **Paths:** all `.issueflows/…` paths are under `<project_root>`. + +When `.issueflows/04-designs-and-guides/multi-repo-workspaces.md` exists, read it for layout and cross-repo guidance. + +## Early PR tokens (command input) + +- **`early`** or **`pr`** → open a draft PR during this build after the first successful push (force on for this run). +- **`noearly`** → skip early PR for this run even when `[issueflow].early_pr` is true. +- Precedence: trailing token > baked `early_pr` (currently **False**) > default `false`. + +## Instructions + +> **CLI fast path (optional).** If the `issue-flow` CLI is on `PATH`, use +> `issue-flow agent preflight` for the branch status preflight (step 2) and +> `issue-flow agent sweep --except <N>` for the stale sweep (step 3; add +> `--dry-run` to preview). The CLI is optional: if it is missing or errors, +> fall back to the manual instructions below. (`issue-flow` is only present +> when the user installed it, e.g. `uv tool install issue-flow`.) + +1. **Select the issue** — Read `.issueflows/01-current-issues/`. If there is no `*_original.md` (or multiple ambiguous groups), **stop** and ask which issue to use. + +2. **Branch status preflight** (non-destructive) — Detect the default branch (prefer `gh repo view --json defaultBranchRef -q .defaultBranchRef.name`, else `git symbolic-ref --quiet --short refs/remotes/origin/HEAD`, else `main`). Run `git fetch --prune`. Report current branch, clean/dirty working tree, and ahead/behind counts vs `origin/<default>`. If on the default branch, propose creating an issue branch (`git switch -c <N>-<short-slug>`); ask before running. If the current branch matches `^(\d+)-.+` and files for that issue now live in `.issueflows/02-partly-solved-issues/` or `.issueflows/03-solved-issues/`, warn the branch looks stale and ask whether to switch back before continuing. If the branch is neither default nor an issue-style branch, warn and ask whether to continue. Never delete a branch from `/iflow-build`. + +3. **Sweep stale current issues** (auto-safe) — Group files in `.issueflows/01-current-issues/` by `issueNN_` prefix. For every group **other than the focus issue**, move the whole group to `.issueflows/03-solved-issues/` if any of its status files contains `- [x] Done` (case-insensitive on `done`), otherwise move it to `.issueflows/02-partly-solved-issues/`. Never move the focus issue's files. Report every move. + +4. **Plan precondition** — Look for `issue<N>_plan.md` in `.issueflows/01-current-issues/`. + - **Plan present:** read it and treat it as the source of truth for scope and approach. Before writing new modules, read **`### Prior art`** under **`## Constraints`** if present (skip if absent or it says "None found"). + - **Plan missing:** do **not** hard-stop. Ask the user to choose one of: + - **Run `/iflow-plan` now**, then continue into implementation after they confirm the plan. + - **Proceed without a plan** — add a short `- Skipped /iflow-plan on <date>` note to `issue<N>_status.md` and continue. + - **Abort.** + +5. **Seed the status file up front** — Before writing code, create `issue<N>_status.md` under `.issueflows/01-current-issues/` (if missing) with an unchecked `- [ ] Done` checkbox and short **What's done** / **Remaining work** sections. It is a living document that should exist *during* the work, not only at `/iflow-close`. + +6. **Implement** — Execute the plan (or the explicitly-acknowledged plan-less path). Prefer minimal, focused diffs. Match existing code style and tooling. + +7. **Project conventions** + - Use the project's **documented Python toolchain**, not bare `python`. Default to `uv run` (scripts, pytest, tools) and `uv add` / `uv remove` / `uv sync` for dependencies, **unless** the project documents otherwise — e.g. a conda project runs scripts and `pytest` inside the **activated conda environment** (`conda activate <env>` or `conda run -n <env> …`). Honour existing project rules over these defaults. + - **Ruff (when present).** If the project uses ruff (`[tool.ruff]` in `pyproject.toml`, ruff in dev dependencies, or `.issueflows/04-designs-and-guides/python-quality-tools.md` exists), run auto-fix lint after substantive code changes — e.g. `uv run ruff check --fix …` then `uv run ruff format …` (match paths to what the project documents). + - **Toolbox** — Before writing a one-off helper script, check `.issueflows/00-tools/` (start with its `README.md` index) for an existing tool. If you build something reusable during this issue, save it into `.issueflows/00-tools/` and add a one-line entry to that README's index (name, what it does, when to use it) for the next agent. + - If `.issueflows/04-designs-and-guides/this-project.md` exists, read it for project-specific context before implementing; then skim relevant design docs under `.issueflows/04-designs-and-guides/`. + - **Knowledge graph (optional).** If `graphify-out/GRAPH_REPORT.md` exists, skim it before grepping — god-nodes and surprising connections often point at the files you'll touch. If structure changed materially since the last build, *suggest* `/iflow-graphify` (do not run it automatically). If `graphify-out/` is absent, ignore this bullet. + - As you iterate, re-read and keep `issue<N>_status.md` current — move items between **What's done** and **Remaining work**, leaving `- [ ] Done` unchecked until fully resolved. + +8. **Early pull request (optional)** — After the **first successful push** of the issue branch (or when the branch already has a remote tip and no open PR), decide whether to open a PR now using the Early PR tokens above. When early PR is on: + - Require an issue-style branch matching `^\d+-.+` (never the default branch) with a remote tracking ref. + - Always pass `--repo <owner/repo>`. **List before create:** `gh pr list --repo <owner/repo> --head <branch> --state open --json number,url,title,isDraft`. If an open PR exists, note it and skip creating a second one. + - Otherwise create a **draft**: `gh pr create --draft --repo <owner/repo> …` with a WIP-friendly body and **`Refs #N`** (not `Closes #N` yet). + - Record `PR: <url> (#<n>, draft)` in `issue<N>_status.md`. + - Do **not** write `HISTORY.md` here — `/iflow-close` owns the changelog bullet (even while a draft PR exists). + +9. **Hand off** — When the implementation is ready to ship: tell the user to run `/iflow-close` (optionally with `bump`/`patch`/`minor`/`major`). Parking work mid-stream goes through `/iflow-pause`. + +10. **Reporting** — Summarize what changed, what remains, and where the issue docs live. Include any branch warnings from step 2, any group moves from step 3, whether an early PR was opened/reused, and whether the plan was followed or explicitly skipped. + +## Constraints + +- Do not invent issue text; treat `*_original.md` as a read-only source of requirements unless the user asks to edit it. +- The stale sweep in step 3 is the **only** automatic folder move `/iflow-build` performs, and it never touches the focus issue's own files. +- Never delete or force-update git branches from `/iflow-build`. +- Do not write or modify `issue<N>_plan.md` from here — changes to the plan go through `/iflow-plan`. diff --git a/.cursor/skills/iflow-capture/SKILL.md b/.cursor/skills/iflow-capture/SKILL.md new file mode 100644 index 0000000..2487ccf --- /dev/null +++ b/.cursor/skills/iflow-capture/SKILL.md @@ -0,0 +1,110 @@ +--- +name: iflow-capture +description: >- + Capture a GitHub issue locally as issue<number>_original.md and archive + other current issues by done status. +disable-model-invocation: true +issue-flow-version: 0.4.2a4 +--- + +# issue-flow — issue capture (`/iflow-capture`) + +Follow this skill to **capture a GitHub issue locally** under `.issueflows/01-current-issues/`. + + +**Invoke:** type `iflow capture` in chat, or `/iflow-capture` from the slash menu (`iflow-capture` also works). + + + + +### MODEL & EXECUTION DIRECTIVE + + +**Profile: economy** — Prioritize speed and token economy over deep reasoning. + +In Cursor: use **Auto** or a fast model before invoking this step. + + + +Keep scope tight to what this step requires. + + + + +### Resolve project root (multi-root workspaces) + +Before any `git`, `gh`, or `.issueflows/` path operation in this workflow: + +**Resolution order** (stop when unambiguous): + +1. **Explicit hints** in slash input — `root:<path>`, `repo:<folder-basename>` (directory name, e.g. `cellpy-core`), or `repo:owner/name`. +2. **CLI fast path** — `issue-flow agent resolve [-C <start>] [--from-file <active-file>] [--json]`. Use the returned `project_root` and `repo`; pass `-C <project_root>` to other `issue-flow agent …` subcommands. When the answer came from the workspace registry, the payload sets `resolved_via_workspace_default: true`. +3. **Branch context** — exactly one workspace repo whose branch matches `^\d+-` → that root. +4. **Single scaffold** — exactly one `.issueflows/` tree visible in the workspace → that root. +5. **Workspace default** — an `issueflow-workspace.toml` at the workspace root (created with `issue-flow workspace init`) may name a `default` member repo; use it when no scaffold matched above. Tell the user the default was used. +6. **Ambiguous** → **stop and ask**; never guess between sibling repos. + +After resolution, treat the result as `<project_root>` and `<owner/repo>`: + +- **Git:** `git -C <project_root> …` (or `issue-flow agent … -C <project_root>` for supported ops). +- **GitHub:** pass an explicit repo on every `gh` call — never rely on `gh`'s implicit cwd default. For most commands use `--repo <owner/repo>`; **exception:** `gh repo view` takes the repo as a **positional** arg (`gh repo view <owner/repo> …`) and rejects `--repo`. +- **Paths:** all `.issueflows/…` paths are under `<project_root>`. + +When `.issueflows/04-designs-and-guides/multi-repo-workspaces.md` exists, read it for layout and cross-repo guidance. + +## Instructions + +> **CLI fast path (optional).** If the `issue-flow` CLI is on `PATH`: +> - **Resolve root + repo (step 0):** `issue-flow agent resolve [--from-file <active-file>] [--json]` — use `project_root` and `repo` for all steps below. +> - **Fetch + write (steps 3 & 5):** `issue-flow agent capture <N> -C <project_root>` (use `--repo owner/repo` to override the resolved remote, `--force` to overwrite). It writes the `## Original issue text` body deterministically and prints the comments payload — you still triage comments (step 3a) and add the curated section yourself. +> - **Archive (step 4):** `issue-flow agent sweep --except <N> -C <project_root>` (add `--dry-run` to preview). +> +> The CLI is optional: if it is missing or errors, fall back to the manual +> instructions below. (`issue-flow` is only present when the user installed it, +> e.g. `uv tool install issue-flow`.) + +1. **Folders** — Ensure `.issueflows/00-tools/`, `.issueflows/01-current-issues/`, `.issueflows/02-partly-solved-issues/`, and `.issueflows/03-solved-issues/` exist (create only if the user allows; never delete issue markdown). + +2. **Resolve the reference** + - **URL** — Parse `owner`, `repo`, issue number. + - **Number only** — After resolving `<project_root>`, run `git -C <project_root> remote get-url origin` (HTTPS or SSH) to derive `owner/repo`. If parsing fails, ask for a full URL or `owner/repo`. + - **Empty / whitespace** — Run `git -C <project_root> branch --show-current`. If empty or `main`/`master` (case-insensitive), **stop** and ask for a number, URL, or `owner/repo/#n`. If the branch is an **issue-style branch** matching `^\d+-.+`, ask: "You have not provided an issue reference. Should I use issue #NN from the current branch `<branchname>`?" Do not proceed without a clear yes/no. + - **Archived-issue guard** — Before writing, check `.issueflows/02-partly-solved-issues/` and `.issueflows/03-solved-issues/` for existing `issue<n>_*` files. If the issue is already archived, warn and require a second explicit confirmation before re-opening it in `.issueflows/01-current-issues/`. + +3. **Fetch** — `gh issue view <n> --repo owner/repo --json title,body,url,number,comments`. The `comments` field returns an array of `{author.login, body, createdAt, ...}` that step 3a consumes. On failure, report the error and suggest `gh auth login`. After confirming `owner/repo`, change the chat/agent tab title to reflect the issue topic on the form "Issue <issue number> <short description of issue>" (e.g. "Issue 74 cell info"). + +3a. **Triage comments** (skip if `comments` is empty). Follow the [`iflow-comments`](../iflow-comments/SKILL.md) skill — it owns the triage rules (chronological precedence, three buckets, noise filtering) and the exact shape of the `## Comments (curated summary)` section. + +3.5 **Branch status preflight** (report only) — Run `git fetch --prune`. Report current branch, clean/dirty working tree, and ahead/behind counts vs `origin/<default>` (detect default via `gh repo view --json defaultBranchRef -q .defaultBranchRef.name`, else `git symbolic-ref --quiet --short refs/remotes/origin/HEAD`, else `main`). If the current branch matches `^(\d+)-.+` and files for that issue already live in `.issueflows/02-partly-solved-issues/` or `.issueflows/03-solved-issues/`, note that the branch looks stale. Never delete or move anything at this step. + +4. **Archive** — In `.issueflows/01-current-issues/`, group files by issue number (`issue121_*`). For each group **other than** the issue being created: move the whole group to `.issueflows/03-solved-issues/` only if a status file for that issue contains a checked **Done** line matching `- [x] Done` (case-insensitive on "done"). Otherwise move to `.issueflows/02-partly-solved-issues/`. If no status file or checkbox is unclear, treat as **not done**. + +5. **Write** — Create `.issueflows/01-current-issues/issue<number>_original.md` with: + + ```markdown + # Issue #<number>: <title> + + Source: <url> + + ## Original issue text + + <body exactly as returned by GitHub> + + ## Comments (curated summary) + + - **Additional tasks**: <bullets distilled from comments that add real work> + - **Clarifications / constraints**: <bullets the agent should honour> + - **Superseded / retracted**: <earlier points later contradicted or walked back> + + _Note: this section is an interpretive summary of the comment thread, not a verbatim dump. Source comments: <count>, last comment by @<login> on <date>._ + ``` + + Preserve the body **text** faithfully as returned by GitHub — don't paraphrase or edit it, but don't waste effort on trailing newlines or CRLF vs LF either (no second-pass byte-diffing). The `## Comments (curated summary)` section is **optional** — include it only when step 3a produced at least one bullet, and drop any of the three bullet groups that have no content. + +6. **Conflicts** — If `issue<number>_original.md` already exists, do not overwrite silently; ask the user. + +7. **Report** — Summarize number, `owner/repo`, branch inference (if used), path written, comment triage counts (fetched vs surfaced vs superseded, or "section omitted" when skipped), archive moves (source → destination), and success or failure. + +## Constraints + +- Allowed file operations: create/update the target `*_original.md`, and move pre-existing issue groups per the archive rules. Do not modify unrelated project files. diff --git a/.cursor/skills/iflow-cleanup/SKILL.md b/.cursor/skills/iflow-cleanup/SKILL.md new file mode 100644 index 0000000..df4f84d --- /dev/null +++ b/.cursor/skills/iflow-cleanup/SKILL.md @@ -0,0 +1,143 @@ +--- +name: iflow-cleanup +description: >- + Post-merge branch hygiene: switch to the default branch and delete landed + local branches (reachable via -d; squash-landed via -D behind its own + confirm). Optional GitHub remote audit via trailing "include GitHub" or + baked cleanup_include_github. Never --force, never deletes unique work. +disable-model-invocation: true +issue-flow-version: 0.4.2a4 +--- + +# issue-flow — issue cleanup (`/iflow-cleanup`) + +Follow this skill to **run post-merge branch hygiene** after a PR has been merged (typically the PR opened by `/iflow-close`). + + +**Invoke:** type `iflow cleanup` in chat, or `/iflow-cleanup` from the slash menu (`iflow-cleanup` also works). + + + + +### MODEL & EXECUTION DIRECTIVE + + +**Profile: economy** — Prioritize speed and token economy over deep reasoning. + +In Cursor: use **Auto** or a fast model before invoking this step. + + + +Keep scope tight to what this step requires. + + + + +### Resolve project root (multi-root workspaces) + +Before any `git`, `gh`, or `.issueflows/` path operation in this workflow: + +**Resolution order** (stop when unambiguous): + +1. **Explicit hints** in slash input — `root:<path>`, `repo:<folder-basename>` (directory name, e.g. `cellpy-core`), or `repo:owner/name`. +2. **CLI fast path** — `issue-flow agent resolve [-C <start>] [--from-file <active-file>] [--json]`. Use the returned `project_root` and `repo`; pass `-C <project_root>` to other `issue-flow agent …` subcommands. When the answer came from the workspace registry, the payload sets `resolved_via_workspace_default: true`. +3. **Branch context** — exactly one workspace repo whose branch matches `^\d+-` → that root. +4. **Single scaffold** — exactly one `.issueflows/` tree visible in the workspace → that root. +5. **Workspace default** — an `issueflow-workspace.toml` at the workspace root (created with `issue-flow workspace init`) may name a `default` member repo; use it when no scaffold matched above. Tell the user the default was used. +6. **Ambiguous** → **stop and ask**; never guess between sibling repos. + +After resolution, treat the result as `<project_root>` and `<owner/repo>`: + +- **Git:** `git -C <project_root> …` (or `issue-flow agent … -C <project_root>` for supported ops). +- **GitHub:** pass an explicit repo on every `gh` call — never rely on `gh`'s implicit cwd default. For most commands use `--repo <owner/repo>`; **exception:** `gh repo view` takes the repo as a **positional** arg (`gh repo view <owner/repo> …`) and rejects `--repo`. +- **Paths:** all `.issueflows/…` paths are under `<project_root>`. + +When `.issueflows/04-designs-and-guides/multi-repo-workspaces.md` exists, read it for layout and cross-repo guidance. + +## Input + +Optional free-form text after the command: + +- **No extra text** — Phase A: detect the current branch's PR, clean that up, plus any other local branches already merged into the default. Phase B stays off unless a GitHub-audit token is present. +- A **branch name** — Phase A targets that branch instead of the current one (e.g. `/iflow-cleanup 42-fix-login`). +- **GitHub remote audit (opt-in tokens)** — trailing text containing (case-insensitive) `include github`, `include gh`, `with github`, or a standalone `github` token enables **Phase B** after Phase A. +- **GitHub remote audit (opt-out tokens)** — trailing `no github`, `local only`, or `local-only` (case-insensitive) **skips Phase B** even when `cleanup_include_github` is baked true. + +**Phase B enable rule:** run Phase B when (`cleanup_include_github` is baked true **or** an opt-in GitHub token is present) **and** no opt-out token is present. + +## Instructions + +1. **Detect the default branch.** Prefer `gh repo view <owner/repo> --json defaultBranchRef -q .defaultBranchRef.name` (repo is **positional** on `gh repo view` — not `--repo`), else `git -C <project_root> symbolic-ref --quiet --short refs/remotes/origin/HEAD`, else `main`. + +2. **Identify the target branch.** If the user named a branch after `/iflow-cleanup` (ignoring GitHub-audit / opt-out tokens), use it. Else use the current branch (`git branch --show-current`). If the current branch **is** the default, skip to step 7 (folder sweep only) for Phase A. + +3. **Check PR / merge state.** Prefer `gh pr view <branch> --json state,mergedAt,mergeCommit,headRefName`. If `gh` is unavailable, approximate with `git fetch --prune` then `git cherry origin/<default> <branch>` (all commits marked `-` means squash-merged). + - **If not merged:** remind the user that the working copy is still on the issue branch; suggest `git switch <default>` before unrelated work and re-run `/iflow-cleanup` after the PR merges. **Stop Phase A.** Do not delete anything locally. If Phase B is enabled (see Input), you may still offer Phase B alone (remote audit does not require the issue branch to be merged). + - **If merged:** continue Phase A. + +4. **Classify the local branches.** Prefer the CLI fast path; fall back to manual `git`/`gh` when it is missing. + - **CLI:** `issue-flow agent local-branches --json -C <project_root>` (add `--no-fetch` only if `git fetch --prune` just ran). Buckets: `reachable`, `squash_landed`, `merged_pr_divergent`, `unique_work`, `skipped`. Every entry carries a `tip` short SHA. + - **Manual fallback**, per local branch (skipping the current branch and the default): + 1. `git merge-base --is-ancestor <branch> origin/<default>` — exit 0 → **`reachable`**. + 2. Else `git cherry origin/<default> <branch>` — no `+` lines → **`squash_landed`** (every commit has an equivalent patch upstream). + 3. Else `gh pr list --repo <owner/repo> --state all --head <branch> --json number,state,mergedAt,url`. With a merged PR, compare `git log --no-merges --format=%cI origin/<default>..<branch>` against its `mergedAt`: no commit **newer** than the merge → **`merged_pr_divergent`** (the squash rewrote these commits); any newer commit → **`unique_work`** (real work pushed after the PR merged). + 4. Anything else → **`unique_work`**. + 5. Record `git rev-parse --short <branch>` for every branch you might delete. + + > **Why the extra buckets:** this project merges PRs with **squash**, which lands a *new* commit on the default branch. A squash-merged branch tip is therefore never an ancestor of the default, so `git branch -d` refuses it forever — `-d` alone can never prune landed branches here. + +5. **Consolidated confirm (Phase A1 — local)** — one yes/no prompt listing every action: + - `git switch <default>` (home only; skip if already on default) + - `git pull --ff-only` — if it fails, **stop** A1 steps that assume default is current (apply-changelog, release tag) and recover via `default-sync` (see below). + + - `git fetch --prune` + - `issue-flow agent worktree-list --json` — for each **linked** worktree whose branch is **`reachable`**, `issue-flow agent worktree-remove <path>` (or the issue number) **before** deleting the branch. Git cannot `-d` a branch that is still checked out in a worktree. Never remove a worktree whose branch is `unique_work`. + - `git branch -d <branch>` for each **`reachable`** branch, listed explicitly by name first. If `-d` still refuses, report that branch and move on. + - **Planned release tag (tag-derived projects only).** When `/iflow-close` planned a tag it did not create — check the focus issue's status file and the newest `HISTORY.md` release section for a version whose tag is missing from `git tag -l` — include creating it here: `git tag <planned>` then `git push origin <planned>` (or `gh release create <planned> --generate-notes`). Run it **after** the pull so the tag lands on the merged squash commit. + +If `git pull --ff-only` fails on default (or home default is **ahead** of origin), run `issue-flow agent default-sync --json` (classify-only; never mutates). Print ahead/behind, unique commit onelines + paths, and the recommended `action`. Do **not** only dump `fatal: Not possible to fast-forward`. + +| `action` | What to offer | +| --- | --- | +| `even` / `ff_only` | Pull is safe; retry `git pull --ff-only`. | +| `report_ahead` | Print unique commits. Do not silent-push default. | +| `tracking_pr` | Merge `origin/<default>` **or** cherry-pick onto a chore branch, then open a tiny PR. Never push default. | +| `replay_tracking` | Replay the tracking commit onto `origin/<default>` (chore branch + PR). Do not stack another merge. | +| `stop_product` | Stop. User decides. Do not merge onto default. | + +Never: rebase default, `push --force` default, or push default to skip CI. + + +6. **Force-delete confirm (Phase A2 — only when `squash_landed` or `merged_pr_divergent` is non-empty).** A **separate** yes/no prompt; Phase A1's yes never implies it. Skip this step entirely when both buckets are empty. + - State plainly that these branches need `git branch -D` because a squash merge leaves no reachable tip, and that `-D` skips git's own safety check. + - List **`squash_landed`** as `<name> <tip>` with the evidence (every commit patch-equivalent to the default; merged PR number when known). + - List **`merged_pr_divergent`** *separately*, each with its `<tip>`, merged PR link, and unique-commit subjects — these are landed per GitHub but their tips differ, so the user should eyeball the subjects before agreeing. + - Show the recovery line: any deletion is undone with `git branch <name> <tip>`. + - On yes, `worktree-remove` each linked worktree whose branch is in these buckets (clean trees only; never `unique_work`), **then** try `git branch -d <name>` first and only fall back to `git branch -D <name>` when it refuses — `-d` also accepts a branch merged into its own upstream, so it sometimes still works while the remote-tracking ref survives. Report each `<name> <tip>` and which flag was used, so the SHAs stay in the transcript. On no, leave every branch and worktree in place. + - **Never** include a `unique_work` or `skipped` branch in this prompt, even if the user asks to "delete them all" — point at the branch's unique commits instead and let them delete it by hand. + +7. **Optional folder sweep** (safe; no destructive git). In `.issueflows/01-current-issues/`, for each `issue<N>_*` group whose status file contains `- [x] Done` (case-insensitive on `done`), move the group to `.issueflows/03-solved-issues/`. Leave groups without a checked `Done` in place — routing them to `.issueflows/02-partly-solved-issues/` is `/iflow-pause`'s job. + +8. **Epic stage gate (offer only).** If the just-merged issue belongs to an epic — its number appears in a `- Published: #<N>` line of an `epic<M>_plan.md` under `.issueflows/05-epics/` — check whether that closed the stage: run `issue-flow agent epic-status <M> --json` and see if the issue's stage now has no open issues left. If the stage just completed, **offer** (do not do automatically) to (a) post a short stage-summary comment on the epic anchor issue and (b) run `/iflow-epic <M> publish` to publish the next stage. Both are the user's explicit call — never auto-publish or auto-comment. + +9. **Phase B — GitHub remote audit** (only when Phase B is enabled per the Input enable rule). Prefer the CLI fast path; fall back to manual `git`/`gh` when the CLI is missing. + - **CLI:** `issue-flow agent branches --json -C <project_root>` (add `--no-fetch` only if `git fetch --prune` just ran). Payload buckets: `deletable`, `unique_work`, `skipped`. + - **Manual fallback:** `git fetch --prune`; list `refs/remotes/origin/*` (skip `HEAD` and the default); for each tip run `git cherry origin/<default> origin/<branch>` (`+` = unique); `git log --oneline origin/<default>..origin/<branch>` (cap ~20) + `git diff --shortstat`; `gh pr list --repo <owner/repo> --state all --head <branch> --json number,title,state,url,mergedAt`. Treat open-PR heads as unique work (never deletable). Protected branches (when `gh api …/branches/<name>` reports `protected: true`) go to skipped. + - **Report** the three buckets. For unique-work branches, summarise commit subjects (and open PR titles/URLs) in prose for the user. + - **Second consolidated confirm** (never folded into Phase A's yes): list every proposed action, then ask once: + - Optional: for each **deletable** name, `git push origin --delete <branch>` (or `gh api -X DELETE repos/<owner>/<repo>/git/refs/heads/<branch>`). Never `--force`. Never delete the default. On push failure (e.g. protection), report and continue. + - Optional: create a findings issue with `gh issue create --repo <owner/repo>` after showing the draft title/body (deletable list + unique-work summaries). Suggested title: `chore: remote branch audit (<YYYY-MM-DD>)`. Create only on yes. + - Phase B is **read-only until that second confirm**. Declining leaves remotes untouched. + +10. **Report.** Summarize: default branch, PR/merge status, Phase A1 commands and `-d` deletions, Phase A2 `-D` deletions with their tip SHAs (or "declined" / "none offered"), branches left alone as unique work, folder sweep, epic stage-gate offer, and (when run) Phase B bucket counts, remote deletes, findings issue URL or "skipped". If `issue-flow agent resolve --json` reports `sibling_roots`, list them and remind the user that **each scaffolded repo needs its own `/iflow-cleanup`** — do not loop automatically in this step. If other open PRs still show `DIRTY` / CONFLICTING (often `HISTORY.md`), **offer** `/iflow-pr-sync` — do not auto-run it. + +## Constraints + +- Never use `git push --force`. Never rebase default, force-push default, or push default to skip CI. +- `git branch -D` is allowed **only** for `squash_landed` / `merged_pr_divergent` branches, **only** after the Phase A2 confirm, and **only** with their tip SHAs reported. Never `-D` a branch holding unique work, a branch you could not classify, or the current branch. In Phase A1, a `-d` refusal is reported and left alone — it is never a licence to force-delete. +- Never delete the default branch (local or remote). +- Remote deletes and findings-issue creation require the **Phase B** confirm; the Phase A1 and A2 yeses must not imply them (nor each other). +- If anything is ambiguous (detached HEAD, multiple remotes, missing tracking info), report and stop rather than guess. +- Do not open or update PRs. Do not bump version fields — pyproject bumps belong to `/iflow-close`. The only version action allowed here is creating a release tag that `/iflow-close` **planned** (tag-derived strategy), inside the Phase A consolidated confirm. +- Do **not** offer to update `HISTORY.md` / CHANGELOG here — that belongs in `/iflow-close` before the PR. + diff --git a/.cursor/skills/iflow-close/SKILL.md b/.cursor/skills/iflow-close/SKILL.md new file mode 100644 index 0000000..ac0c83b --- /dev/null +++ b/.cursor/skills/iflow-close/SKILL.md @@ -0,0 +1,174 @@ +--- +name: iflow-close +description: >- + Finish and land the focus issue: tests, optional version bump, status + update, commit, push, and PR. +disable-model-invocation: true +issue-flow-version: 0.4.2a4 +--- + +# issue-flow — issue close (`/iflow-close`) + +Follow this skill to **finish and land** work: tests, optional version bump, issue-folder updates, git, and PR. + +Post-merge branch hygiene lives in `/iflow-cleanup` — this skill never deletes branches. + +## Optional version bump (command input) + +If the user included text after `/iflow-close` that requests a version bump: + +- **`bump`** (no level) → apply the pre-release-aware default. +- **A named level** (`patch`, `minor`, `major`, `stable`, `alpha`, `beta`, `rc`, `post`, `dev`) → use exactly that. +- Otherwise infer the level from natural language (e.g. "bugfix release" → `patch`); ask once if ambiguous. Never auto-pick `major`. + +The exact semantics and the default rule live in `.cursor/skills/iflow-version-bump/SKILL.md` — that skill is the source of truth. When a bump applies: read it, then run the bump from the **project root** **after** the sanity check and **before** issue-folder updates and **before** commit / push / PR. + +## Changelog update tokens (command input) + +- **`nohistory`** or **`skip history`** → skip step 3 entirely. +- **`log "..."`** or **`note "..."`** → override the bullet summary verbatim. Otherwise the GitHub issue title is used. + +## Branch switch tokens (command input) + +- **`stay`**, **`stay on branch`**, **`don't switch`**, or **`dont switch to main`** → after the PR step, stay on the issue branch instead of switching back to the default branch. + +## Draft PR token (command input) + +- **`draft`** → when creating a PR in step 8, use `gh pr create --draft`. If an open PR already exists, leave it draft (do not mark ready). **`draft` skips yolo merge** entirely (step 8a). + +## Hands-off token (command input) + +- **`yolo`** (used by `/iflow-yolo`) → close the loop without user input: write the `HISTORY.md` bullet without a confirm prompt (step 3), **merge the PR** right after opening/updating it (step 8a), then switch back to the default branch and `git pull --ff-only` (step 9, unless `stay` was also passed). + +## Ops / no-PR token (command input) + +- **`ops`**, **`nopr`**, or **`no-pr`** (used by `/iflow-ops`) → finish **without** a PR: skip version-bump prompts, skip `HISTORY.md` by default (same as `nohistory`; honour explicit `log "..."` / `note "..."` if the user insists on a bullet), skip sync/push/PR/yolo-merge. Still update local tracking, optionally commit `.issueflows/`-only changes (default branch allowed with confirm), run an ops checklist confirm, and `gh issue close`. **Mutually exclusive** with `yolo` and `draft` on the same invocation — if combined, stop and ask. When this token is present, follow **Ops close path** below instead of steps 1–11. + + +**Invoke:** type `iflow close` in chat, or `/iflow-close` from the slash menu (`iflow-close` also works). + + + + +### MODEL & EXECUTION DIRECTIVE + + +**Profile: economy** — Prioritize speed and token economy over deep reasoning. + +In Cursor: use **Auto** or a fast model before invoking this step. + + + +Keep scope tight to what this step requires. + + + + +### Resolve project root (multi-root workspaces) + +Before any `git`, `gh`, or `.issueflows/` path operation in this workflow: + +**Resolution order** (stop when unambiguous): + +1. **Explicit hints** in slash input — `root:<path>`, `repo:<folder-basename>` (directory name, e.g. `cellpy-core`), or `repo:owner/name`. +2. **CLI fast path** — `issue-flow agent resolve [-C <start>] [--from-file <active-file>] [--json]`. Use the returned `project_root` and `repo`; pass `-C <project_root>` to other `issue-flow agent …` subcommands. When the answer came from the workspace registry, the payload sets `resolved_via_workspace_default: true`. +3. **Branch context** — exactly one workspace repo whose branch matches `^\d+-` → that root. +4. **Single scaffold** — exactly one `.issueflows/` tree visible in the workspace → that root. +5. **Workspace default** — an `issueflow-workspace.toml` at the workspace root (created with `issue-flow workspace init`) may name a `default` member repo; use it when no scaffold matched above. Tell the user the default was used. +6. **Ambiguous** → **stop and ask**; never guess between sibling repos. + +After resolution, treat the result as `<project_root>` and `<owner/repo>`: + +- **Git:** `git -C <project_root> …` (or `issue-flow agent … -C <project_root>` for supported ops). +- **GitHub:** pass an explicit repo on every `gh` call — never rely on `gh`'s implicit cwd default. For most commands use `--repo <owner/repo>`; **exception:** `gh repo view` takes the repo as a **positional** arg (`gh repo view <owner/repo> …`) and rejects `--repo`. +- **Paths:** all `.issueflows/…` paths are under `<project_root>`. + +When `.issueflows/04-designs-and-guides/multi-repo-workspaces.md` exists, read it for layout and cross-repo guidance. + + +## Ops close path (`ops` / `nopr` / `no-pr`) + +Use this path **only** when the command input included `ops`, `nopr`, or `no-pr`. + +1. **Safeguard — dirty tree.** Prefer `issue-flow agent preflight --json` (`dirty_paths`, `issueflows_only`). If any dirty path is outside `.issueflows/`, **stop**: refuse silent no-PR; tell the user to use normal close or stash/discard product changes. `.issueflows/`-only dirty is OK. +2. **Safeguard — unique commits.** If on an issue-style branch `^\d+-.+` that has commits not reachable from `origin/<default>` **and** those commits touch product files (anything outside `.issueflows/`), **abort** ops close — that work needs a normal PR (or explicit discard). Tracking-only unique commits may proceed after confirm. +3. **Ops checklist confirm (always).** Show: what ran / where (env) / result / residual risk. Require an explicit yes before finishing. Include intent to `gh issue close <N>` and whether to commit `.issueflows/` tracking updates (on current branch, including default when that is where you stand). +4. **Skip** full pytest when the tree is clean or issueflows-only dirty. Never take this path when product files changed (already refused above). Skip version bump. Skip `HISTORY.md` unless the user passed `log "..."` / `note "..."` (then write that bullet under `## [Unreleased]` with confirm unless they also passed nothing conflicting — still no PR). +5. **Issue tracking.** Update `issue<N>_status.md` (`- [x] Done` when fully resolved). Move the issue group to `03-solved-issues/` or `02-partly-solved-issues/` per the Done checkbox. +6. **Optional commit.** If there are staged/unstaged `.issueflows/` (or intentional ops-doc) changes worth keeping, commit on the **current** branch after confirm — default branch is allowed for ops. Never open a PR for this commit. +7. **Close on GitHub.** `gh issue close <N> --repo <owner/repo>` (covered by the checklist confirm). +8. **Branch hygiene (light).** If on `<N>-*` with **no** unique commits vs `origin/<default>`, offer switch to default (no delete). Unique commits already aborted in step 2 when they touch product files. +9. **Output.** Summarize checklist, local archive path, whether a tracking commit was made, GitHub close result, and that **no PR** was opened. Do not remind `/iflow-cleanup` for a non-existent PR merge. + +## Instructions + +1. **Sanity check** — Run the project test suite (e.g. `uv run pytest`) and any checks the repo relies on. **Ruff (when present):** if the project uses ruff (`[tool.ruff]` in `pyproject.toml`, ruff in dev dependencies, or `.issueflows/04-designs-and-guides/python-quality-tools.md` exists), run auto-fix lint through the documented Python runner before committing — e.g. `uv run ruff check --fix …` then `uv run ruff format …` (match paths to what the project documents). Skim the diff; avoid bundling unrelated changes. Confirm that any design decisions or good practices that emerged from this issue are captured under `.issueflows/04-designs-and-guides/` before committing. If this change touched project structure (new modules, big refactor, removed files) and `graphify-out/` exists, *suggest* `/iflow-graphify` (AST-only default) — do not run it automatically. + +2. **Optional version bump** — If the user asked for a bump (see above), follow `.cursor/skills/iflow-version-bump/SKILL.md` — it resolves the project's **release strategy** first (the "Release & version bump" section of `.issueflows/04-designs-and-guides/this-project.md`, else `pyproject.toml` detection, else the uv default). **Static version:** run `uv version --bump <level>`. **Git-tag derived:** edit nothing — compute and report the **planned tag** (e.g. `v1.0.4a3`), record it in the status file, and defer creating it until after the merge (step 9 with `yolo`, else `/iflow-cleanup`). If neither strategy applies, skip and continue. + +3. **Update `HISTORY.md`** — Unless the user passed `nohistory`, follow `.cursor/skills/iflow-history-update/SKILL.md`. If step 2 did not bump (or plan) a version, append a bullet to the `## [Unreleased]` section. If step 2 bumped or planned a version, promote `## [Unreleased]` to `## [<new_version>] - <YYYY-MM-DD>` (for tag-derived projects use the planned tag's version) and open a fresh empty `## [Unreleased]` above it. Write without a confirm prompt (`confirm_changelog_update` is false) so the bullet is in the PR commit. Skip with a note if `HISTORY.md` does not exist at the project root. With the `yolo` token, do not ask — decide yourself and write the bullet (issue title, or `log "..."` text) directly. Write this step **even when a draft PR already exists** from `/iflow-build` early PR — the bullet must land in the close commit that updates that PR. **Never** propose a changelog update *after close finishes* (PR already updated/merged) or after merge. + + +4. **Issue tracking** — Under `.issueflows/01-current-issues/`, update the status file: remaining work, checklists, and **`- [x] Done`** only when the issue is fully resolved. If fully resolved, move that issue's markdown files (`issue<n>_*`) to `.issueflows/03-solved-issues/`. If partially resolved, move to `.issueflows/02-partly-solved-issues/`. Follow any stricter rules in `.cursor/rules/issueflow-rules.mdc` if present. + +5. **Commit** — First check `git status`; if any changes are **not relevant** to this issue, tell the user which ones and ask whether to include them — do not auto-include or drop silently. Then stage intentionally (include `pyproject.toml` and `uv.lock` if changed after a bump, and `HISTORY.md` if step 3 updated it); write a commit message in full sentences describing what changed and why. + +6. **Sync with the default branch before push** — The issue branch must carry whatever landed on `<default>` while this issue was in flight; otherwise the PR only fails later, at merge time, as `mergeable: CONFLICTING`. A plain `git pull --ff-only` on the issue branch cannot do this — it only follows that branch's own upstream. + - **CLI fast path (preferred).** `issue-flow agent sync-branch --json` does the whole step deterministically: refuses while the tree is dirty or you are on the default branch, fetches, replays the branch onto `origin/<default>`, and **auto-resolves a changelog-only conflict** (both sides appending bullets under `## [Unreleased]` — all bullets kept, the in-flight issue's last). Any other conflict aborts the rebase, leaves the branch exactly as it was, and exits 1: report its `notes` and **stop**. When the payload reports `needs_force_push: true`, the branch was rewritten — push with `--force-with-lease` in step 7. + - **Manual fallback.** `git fetch --prune`, then `git rebase origin/<default>`. If it conflicts **only** in `HISTORY.md` and both sides merely added `## [Unreleased]` bullets, keep them all (already-landed bullets first, this issue's bullet last — see `.cursor/skills/iflow-history-update/SKILL.md`), `git add HISTORY.md`, `git rebase --continue`. For **anything else** — a code conflict, an edited existing bullet, a renamed or promoted heading — run `git rebase --abort` and **stop**; that needs a human decision. + - Never rebase, force-push, or otherwise rewrite the **default** branch. Only the issue branch is ever rewritten. + +7. **Push** — Push to the remote the project uses (typically `origin`). If step 6 rewrote the branch (rebase), use `git push --force-with-lease` — never a bare `--force`, and never against the default branch. + +8. **Pull request** — Against the default branch; always pass `--repo <owner/repo>`. + - **List before create.** Run `gh pr list --repo <owner/repo> --head <branch> --state open --json number,url,title,isDraft`. If an open PR already exists for this head (including a draft from `/iflow-build` early PR), **update** it (title/body as needed; prefer `Closes #n` when shipping) instead of opening a second one. Otherwise `gh pr create` — add `--draft` when the user passed the `draft` token. Body should explain the change, how to test, and link the GitHub issue (`Closes #n` / `Refs #n`). + - **Ready from draft (when not `draft`).** If the open PR is still a draft and the user did **not** pass `draft`, mark it ready for review (`gh pr ready <number> --repo <owner/repo>`) before the checks snapshot / yolo merge. + - **Checks snapshot.** After the PR exists, run `gh pr checks <number> --repo <owner/repo>` and report pass / fail / pending. "CI is green" means this command exits 0 (or JSON buckets are all `pass` / `skipping`). Without `yolo`, prefer this one-shot list; offer `gh pr checks <number> --repo <owner/repo> --watch --fail-fast` only when the user wants to wait in-session, and still honour the **15-minute** wall-clock cap (agent-enforced — `gh` has no max-duration flag). Full CI/`gh` cheatsheet (including `gh run list` / `gh run watch` fallback when PR checks are empty): `.cursor/skills/gh-ci/SKILL.md`. If `gh pr checks` returns empty or cannot resolve checks, fall back to `gh run list --repo <owner/repo>` then `gh run watch <run-id> --repo <owner/repo>` under the same budget. + +8a. **Merge the PR (`yolo` token only)** — Never `--delete-branch`; branch deletion stays in `/iflow-cleanup`. Without the `yolo` token, skip this step — merging stays a user decision (step 10). With `yolo`: + 1. If the user passed `draft`, **skip merge entirely** and say so. + 2. Try `gh pr merge <number> --squash` immediately (repos with no required checks stay fast). + 3. If GitHub refuses for pending/required checks: run `gh pr checks <number> --repo <owner/repo> --watch --fail-fast` under a hard wall-clock budget of **15 minutes** (baked from `[issueflow].checks_watch_minutes` / `ISSUEFLOW_CHECKS_WATCH_MINUTES`, default 15; agent stops the watch when the cap hits). + 4. Watch succeeds (exit 0) within the cap → retry `gh pr merge <number> --squash`. + 5. Watch fails (red / `--fail-fast`) → stop hands-off behaviour, leave the PR open, report failing check links. + 6. Cap elapses while still pending, or checks never register / watch unavailable → last resort `gh pr merge <number> --squash --auto`, report the merge as queued, continue. If even `--auto` fails, stop hands-off, report the error, leave the PR open. + 7. **Refused as conflicted** (`mergeable: CONFLICTING` / `mergeStateStatus: DIRTY` — something merged into `<default>` after step 6): re-run step 6's sync (`issue-flow agent sync-branch --json`). If it resolved a changelog-only conflict, `git push --force-with-lease`, then re-watch checks under the same budget and retry the merge **once**. If the sync exits 1, or the retry is refused again, stop hands-off and leave the PR open with the reason. Never reach for `--admin` and never skip checks to get past a conflict — a rebased branch needs a fresh check run. + +9. **Switch back when safe** — If the input included `stay`, `stay on branch`, `don't switch`, or `dont switch to main`, stay on the issue branch and report that opt-out. Otherwise, after the PR is open or updated: + - **CLI fast path (preferred).** If the `issue-flow` CLI is on `PATH`, run `issue-flow agent switchback --json`. It performs this whole step deterministically: refuses while the working tree is dirty (listing the paths), else switches to the detected default branch and runs `git pull --ff-only`. On a **linked worktree** (`in_worktree: true`) it **skips** the switch (home already holds default) — then pull default from **home** (`issue-flow agent switchback -C <home>`). On exit 1, report its `notes` / `default_sync` and stop — do not force anything. If the payload shows home default **ahead** of origin, print the unique commits (oneline + paths). Never rebase, force-push, or push default to skip CI. + +If `git pull --ff-only` fails on default (or home default is **ahead** of origin), run `issue-flow agent default-sync --json` (classify-only; never mutates). Print ahead/behind, unique commit onelines + paths, and the recommended `action`. Do **not** only dump `fatal: Not possible to fast-forward`. + +| `action` | What to offer | +| --- | --- | +| `even` / `ff_only` | Pull is safe; retry `git pull --ff-only`. | +| `report_ahead` | Print unique commits. Do not silent-push default. | +| `tracking_pr` | Merge `origin/<default>` **or** cherry-pick onto a chore branch, then open a tiny PR. Never push default. | +| `replay_tracking` | Replay the tracking commit onto `origin/<default>` (chore branch + PR). Do not stack another merge. | +| `stop_product` | Stop. User decides. Do not merge onto default. | + +Never: rebase default, `push --force` default, or push default to skip CI. + + - **Manual fallback.** Detect the default branch (prefer `gh repo view --json defaultBranchRef -q .defaultBranchRef.name`, else `git symbolic-ref --quiet --short refs/remotes/origin/HEAD`, else `main`). If this checkout is a linked worktree, **do not** `git switch <default>` here (two checkouts of default are forbidden). Run `git status --porcelain`; if clean and this is the **home** tree, run `git switch <default>` and then `git pull --ff-only`. If dirty, stay put and list the uncommitted paths. + - Never delete the issue branch here. With the `yolo` token this step runs **after** the merge from step 8a so the pull brings the merged commit into the local default branch (a queued auto-merge arrives later; note that). Pull-on-default after yolo must run from **home**, not the issue worktree. + - **Planned release tag (`yolo` + tag-derived strategy only):** if step 2 planned a tag, create it now — after the pull, standing on the merge commit — with `git tag <planned>` then `git push origin <planned>` (covered by the yolo consolidated confirm). If the merge was only queued via `--auto`, leave the tag to `/iflow-cleanup` and say so. + +9a. **Remove the issue worktree** — Skip when: no linked worktree for `<N>` (`inplace`); input included `stay`; the PR is still `draft`; a `yolo` merge failed or was only queued via `--auto`; the worktree is dirty (report paths and leave the folder — never `--force`). + - Run from **home**: `issue-flow agent worktree-remove <N> -C <home> --json`. + - This project has `auto_remove_worktree = true`: remove without asking. + - Never delete the issue branch here. Continue from **home**. + + +10. **After review** — With the `yolo` token the PR was already merged in step 8a; skip to the `/iflow-cleanup` reminder. Otherwise address feedback, push updates, and merge when approved and `gh pr checks <number> --repo <owner/repo>` is green (exit 0). If step 9 switched back to the default branch, switch to the PR branch again before making review fixes. Remind the user to run **`/iflow-cleanup`** once the PR is merged (`git fetch --prune`, `git branch -d` on reachable local branches under a single consolidated confirm, plus a separate confirm for squash-landed branches that only `-D` can remove — and, for tag-derived projects, the offer to create the release tag planned in step 2). Do **not** auto-run cleanup from this skill. + +11. **Output** — Summarize commit, push result, PR URL, whether the working copy switched back to the default branch or stayed on the issue branch, whether the issue worktree was removed, the merge result when `yolo` applied (merged, or queued via `--auto`), and next step (`/iflow-cleanup` after merge, or "blocked on …" if stuck). + +## Constraints + +- Do not skip failing tests without the user's explicit agreement. +- Prefer focused commits; do not rewrite unrelated history unless asked. +- Never delete branches from `/iflow-close`. Branch deletion belongs to `/iflow-cleanup`. +- **Conflicts:** only a `HISTORY.md`-only conflict of two additive `## [Unreleased]` bullet lists is resolved automatically (step 6). Every other conflict aborts the sync and stops the flow. Never `gh pr merge --admin`, never skip CI, never force-push anything but the issue branch (`--force-with-lease`). +- The `ops` / `nopr` / `no-pr` token takes the **Ops close path** above and must not open a PR. +- **Changelog timing:** unless `nohistory`, the `HISTORY.md` bullet must be written in step 3 and staged in the close commit that feeds (or updates) the PR — including when a draft was opened earlier via `/iflow-build` early PR. Never offer a HISTORY/CHANGELOG update after close has finished or after merge. + diff --git a/.cursor/skills/iflow-comments/SKILL.md b/.cursor/skills/iflow-comments/SKILL.md new file mode 100644 index 0000000..9fa0914 --- /dev/null +++ b/.cursor/skills/iflow-comments/SKILL.md @@ -0,0 +1,101 @@ +--- +name: iflow-comments +description: >- + Triage a GitHub issue's comment thread into the curated, bucketed summary + section of issue<N>_original.md. +disable-model-invocation: true +issue-flow-version: 0.4.2a4 +--- + +# issue-flow — issue comments triage + +Follow this skill to turn a GitHub issue's comment thread into a short, decision-useful summary that lives next to the original issue body under `.issueflows/01-current-issues/issue<N>_original.md`. + +It is the playbook that `/iflow-capture` (and the `iflow-capture` skill) delegate to for anything beyond fetching raw comments. It also covers re-triage of an already-captured issue when new comments arrive (the issue body text stays unchanged; only the curated section is rewritten). + + +### MODEL & EXECUTION DIRECTIVE + + +**Profile: economy** — Prioritize speed and token economy over deep reasoning. + +In Cursor: use **Auto** or a fast model before invoking this step. + + + +Keep scope tight to what this step requires. + + + +## Inputs + +A JSON array of comments as returned by: + +``` +gh issue view <N> --repo owner/repo --json comments -q .comments +``` + +Each element has at least: + +- `author.login` — commenter handle +- `body` — markdown text +- `createdAt` — ISO timestamp + +If you only have raw comment text, ask for the structured form (author + date matter for tie-breaking and for the footer). + +## Triage rules + +1. **Chronological precedence.** Walk the comments oldest → newest. If a later comment contradicts or walks back an earlier point, the earlier point moves to **Superseded / retracted** and the later one takes its place in the appropriate bucket. + +2. **Three buckets, pick exactly one per surviving point.** + - **Additional tasks** — new, concrete work that is not already in the issue body. Phrase as imperatives ("also update X", "add Y to Z"). If the point is vague ("maybe do something about caching"), either sharpen it into a task or drop it. + - **Clarifications / constraints** — guidance on *how* to do the existing work: scope boundaries, non-goals, must-keep behaviors, stylistic or architectural preferences, acceptance criteria. Useful phrase: "when doing X, make sure Y". + - **Superseded / retracted** — earlier tasks, preferences, or decisions that a later comment explicitly or implicitly walked back. Keep these visible (don't silently delete them) so the agent doesn't redo retracted work. + +3. **Drop the noise.** Do not include: + - Bot comments (CI, coverage bots, auto-assign bots, etc.). + - Pure chit-chat, "LGTM", "+1", emoji-only reactions. + - Status pings ("any update?") without new content. + - Comments that only quote earlier ones without adding anything. + +4. **Collapse duplicates.** If two commenters make the same point, record it once. + +5. **Paraphrase; quote sparingly.** Short direct quotes are fine when exact wording matters (e.g. a feature name, an error message). Otherwise rewrite in your own words so the summary is scannable. + +6. **Handle open disagreement honestly.** If two authors openly disagree and no later comment resolves it, record the disagreement under *Clarifications* (for example: "author A prefers option X, author B prefers option Y — no resolution in thread"). Do not guess a winner. + +7. **Respect maintainer authority when obvious.** If the repo owner or a maintainer explicitly overrides an earlier suggestion, treat that as the winning position and move the overridden suggestion to *Superseded*. + +## Output contract + +Write exactly this block into `issue<N>_original.md`, immediately after the `## Original issue text` section: + +```markdown +## Comments (curated summary) + +- **Additional tasks**: <bullets distilled from comments that add real work> +- **Clarifications / constraints**: <bullets the agent should honour> +- **Superseded / retracted**: <earlier points later contradicted or walked back> + +_Note: this section is an interpretive summary of the comment thread, not a verbatim dump. Source comments: <count>, last comment by @<login> on <date>._ +``` + +Formatting rules: + +- Each bucket's bullet is itself a list if there is more than one item — nest concrete bullets under the bold label. +- **Drop any bucket that is empty** — do not leave `- **Additional tasks**: ` with no content. +- **Always keep the `_Note: ..._` footer** when the section exists. Use the total `comments` length for `<count>` and the `author.login` + date of the most recent non-dropped comment for `@<login>` / `<date>`. + +## Edge cases + +- **Zero comments** — skip the whole section. Do not write an empty `## Comments (curated summary)` header. +- **All comments are noise** (bot-only, pure chit-chat, emoji) — skip the whole section. Note this in the command's final report ("N comments fetched, all filtered as noise — section omitted"). +- **Every surviving point lands in a single bucket** — that's fine; just emit that one bucket. +- **Multi-author thread with heated disagreement** — log the disagreement under *Clarifications*, do not invent a resolution. +- **Comments reference external PRs, gists, or linked issues** — keep the reference (shortened URL or `owner/repo#N`) in the bullet, but do not fetch the linked content; it's out of scope for this skill. +- **Comments include code blocks the agent will need later** — summarize the intent in the bullet and mention that the full snippet is in the linked comment; do not paste large blocks into the summary. + +## Constraints + +- This skill only writes into the `## Comments (curated summary)` section of `issue<N>_original.md`. It never touches the issue body, the status file, or the plan file. +- It never calls `gh` or the network itself — it expects the caller (`/iflow-capture` or similar) to provide the comments JSON. diff --git a/.cursor/skills/iflow-cycle/SKILL.md b/.cursor/skills/iflow-cycle/SKILL.md new file mode 100644 index 0000000..a3a0867 --- /dev/null +++ b/.cursor/skills/iflow-cycle/SKILL.md @@ -0,0 +1,157 @@ +--- +name: iflow-cycle +description: >- + Process many issues hands-off in a row: resolve a queue, then run each + through the yolo chain under one up-front confirm. Stops only when input is + strictly necessary. +disable-model-invocation: true +issue-flow-version: 0.4.2a4 +--- + +# issue-flow — issue cycle (`/iflow-cycle`) + +Follow this skill to **process a queue of issues hands-off**, one after another, with a **single up-front confirmation** — the batch equivalent of `/iflow-yolo`. Each issue runs the full yolo chain (`capture → plan → build → close yolo`, PR auto-merged, switch back to default); the cycle interrupts you only when input is **strictly necessary**. + +Use only when every queued issue is genuinely yolo-fit (small, low-risk, well-specified, test-guarded). A queue of risky changes belongs in the individual commands. + +## Input — queue spec + +- **explicit numbers** — e.g. `12 15 18`. +- **`yolo`** — alias for **`label:yolo`**: every open issue carrying the configured yolo trigger label (default `"yolo"`). Case-insensitive. This is the one-token path for “auto-process all yolo issues.” +- **`label:<L>`** — every open issue carrying label `<L>` (use for labels other than the yolo trigger). +- **`epic <N> [stage <k>]`** — the current stage of epic `<N>` (or stage `<k>`). +- **`resume`** — pick up an interrupted cycle from its state file (see **Resuming** below). +- **`onfail:stop`** (default) / **`onfail:skip`** — failure policy (see step 7). +- **`max:<n>`** — raise the safety cap (default 10) for this run. +- **`stay`** — forward `stay` to each close so the working copy stays on each issue branch (rarely wanted in a cycle). + + +**Invoke:** type `iflow cycle` in chat, or `/iflow-cycle` from the slash menu (`iflow-cycle` also works). + + + + +### MODEL & EXECUTION DIRECTIVE + + +**Profile: reasoning** — Prioritize deep thinking and careful trade-offs over speed or token economy. + +In Cursor: switch to a thinking-capable model before invoking this step (not Auto-only). + + + +Keep scope tight to what this step requires. + + + + +### Resolve project root (multi-root workspaces) + +Before any `git`, `gh`, or `.issueflows/` path operation in this workflow: + +**Resolution order** (stop when unambiguous): + +1. **Explicit hints** in slash input — `root:<path>`, `repo:<folder-basename>` (directory name, e.g. `cellpy-core`), or `repo:owner/name`. +2. **CLI fast path** — `issue-flow agent resolve [-C <start>] [--from-file <active-file>] [--json]`. Use the returned `project_root` and `repo`; pass `-C <project_root>` to other `issue-flow agent …` subcommands. When the answer came from the workspace registry, the payload sets `resolved_via_workspace_default: true`. +3. **Branch context** — exactly one workspace repo whose branch matches `^\d+-` → that root. +4. **Single scaffold** — exactly one `.issueflows/` tree visible in the workspace → that root. +5. **Workspace default** — an `issueflow-workspace.toml` at the workspace root (created with `issue-flow workspace init`) may name a `default` member repo; use it when no scaffold matched above. Tell the user the default was used. +6. **Ambiguous** → **stop and ask**; never guess between sibling repos. + +After resolution, treat the result as `<project_root>` and `<owner/repo>`: + +- **Git:** `git -C <project_root> …` (or `issue-flow agent … -C <project_root>` for supported ops). +- **GitHub:** pass an explicit repo on every `gh` call — never rely on `gh`'s implicit cwd default. For most commands use `--repo <owner/repo>`; **exception:** `gh repo view` takes the repo as a **positional** arg (`gh repo view <owner/repo> …`) and rejects `--repo`. +- **Paths:** all `.issueflows/…` paths are under `<project_root>`. + +When `.issueflows/04-designs-and-guides/multi-repo-workspaces.md` exists, read it for layout and cross-repo guidance. + +## Instructions + +0. **Expand aliases.** If the queue spec is exactly `yolo` (case-insensitive), treat it as `label:yolo` (the baked config value; if `.issueflows/config.toml` has a different `yolo_label` than this skill's bake, prefer the live config). Keep the original token in `cycle_status.md` for humans (`queue: yolo` → resolved `label:yolo`). + +1. **Resolve the queue.** Run `issue-flow agent queue --label yolo --json` when the alias applied, else `issue-flow agent queue <spec> --json` (numbers, `--label`, or `--epic`). Use its `queue` (ordered), `blocked`, and `skipped_closed` output as the source of truth — do not re-derive the order by hand. If it reports a dependency `cycle`, **stop** and show it; nothing runs. If the CLI is unavailable, fall back to reading the issues and ordering by `Depends on #N` lines yourself, but prefer the CLI. An empty queue → report “nothing to queue” and stop (no confirm needed). + +2. **Cap check.** If the ordered queue is longer than **10** and the input did not pass `max:<n>` raising the limit, **stop** and ask the user to confirm a larger run explicitly. Long unattended runs compound risk. + +3. **One consolidated confirm** (the only planned interruption). Present, in normal prose: + - the **ordered** queue (numbers + titles), and which issues are **skipped** (closed) or **blocked** (open dependency outside the queue) with the reason; + - that each issue runs the **full yolo chain** and its PR is **auto-merged**; + - the failure policy (`onfail:stop`, the default, or `onfail:skip` — see step 7); + - the default-branch preflight that must hold before starting (clean tree, tests passing). + Require an explicit yes; anything else aborts before any work. + +4. **Write the cycle state file.** After the confirm, write `.issueflows/01-current-issues/cycle_status.md` — the durable record that makes the run resumable and visible to `/iflow-status`. Include: the queue spec, the `onfail` policy, an ISO timestamp, and the ordered queue as a checklist with one line per issue (`- [ ] #<N> — <title> — pending`). Update this file as the loop progresses (see step 5); it is a normal tracking file (not an `issue<N>_*` group), so the folder sweep never touches it. + +5. **Per-issue loop.** For each issue in order, from a clean default branch: + - mark it `in-progress` in `cycle_status.md`, then create/switch to its `<N>-<slug>` branch and follow `.cursor/skills/iflow-yolo/SKILL.md` **verbatim** — including its own preflight (refuse on default branch, refuse with dirty unrelated changes, tests pass up front) and its consolidated-confirm step, which the up-front batch confirm in step 3 satisfies (do not re-ask per issue). + - after the yolo close merges and switches back to the default branch, record the outcome in `cycle_status.md` (`- [x] #<N> — <title> — merged <PR-url>`) and continue to the next issue. + - Every yolo safeguard stays in force. A safeguard that trips is a **stop condition** (step 6), never a guard to skip. + +6. **Strictly-necessary-input rule.** Between issues the cycle runs unattended. **Stop and ask only** when: + a. tests or lint fail in a way you cannot fix within the current issue's scope; + b. a merge is refused, or a sync with the default branch will not complete — **but** a refusal whose only conflict is additive `HISTORY.md` bullets is **not** a stop: close's sync step (`issue-flow agent sync-branch`) resolves that and retries the merge once. Stop only when the sync itself exits 1, or the retry is refused again; + c. the issue spec is ambiguous, contradictory, or turns out **not** small (yolo's scope check aborts); + d. an action would fall **outside the confirmed queue** (touching an unlisted issue, an unrelated dirty file, a destructive op). + Anything else — routine implementation choices, passing tests, clean merges — proceeds without asking. + +7. **Failure policy** (from the `onfail:` token; default **stop**). When a stop condition (step 6) trips on an issue: + - **`onfail:stop`** (default) — **halt the cycle**: finish no further issues, leave the repo on the **default branch, clean** (the in-flight issue's branch stays as-is for the user to inspect), record the stop reason and the not-reached issues in `cycle_status.md`, and report. Do not attempt the rest of the queue. + - **`onfail:skip`** — **park and continue**: record the failure against that issue in `cycle_status.md` (`- [~] #<N> — <title> — failed: <reason>`), park its work per `.cursor/skills/iflow-pause/SKILL.md` conventions (status note + move to `02-partly-solved-issues/`), return to a clean default branch, and proceed to the next queued issue. A skip never bypasses a yolo safeguard — it records the trip and moves on. + +8. **Finish.** When the queue is exhausted (or halted), finalize `cycle_status.md` (mark it `- [x] Done`) and move it to `.issueflows/03-solved-issues/cycle_status_<YYYY-MM-DD>.md` so it is archived, not re-detected as in-flight. + +9. **Batch report.** Summarize the whole run: per issue — number, title, PR URL, merge result (merged / queued via `--auto` / failed-and-skipped / not reached), and duration if tracked; then the queue items **skipped** (closed), **blocked** (with blockers), and — on a halt — the **stop reason** and which issues were **not reached**. End by reminding the user to run `/iflow-cleanup` once to prune the merged local branches. + +## Resuming + +`/iflow-cycle resume` picks up an interrupted cycle: + +1. Read `.issueflows/01-current-issues/cycle_status.md`. If it is missing, tell the user there is no in-flight cycle and stop. +2. Take the **remaining** issues (those still `pending` / `in-progress`) and **re-verify** them with `issue-flow agent queue <original-spec> --json` — an issue that has since closed, or become blocked, is dropped/deferred with a note (state can move while a cycle is paused). +3. **Do not re-ask the original consolidated confirm** for the unchanged remaining items — the batch was already authorized. Ask again only if the re-verified queue differs materially from what was confirmed (new blockers, added issues), and only about the delta. +4. Continue the per-issue loop (step 5) with the same `onfail` policy recorded in the file. + +## Parallel dispatch (experimental, opt-in) + +By default the cycle is **sequential** — one issue fully lands before the next starts. When the input passes **`parallel:<n>`** *and* the harness supports background execution, provably independent issues may run concurrently (up to `n` at a time). This is experimental; the sequential path above is always the default and is never weakened to enable it. + +- **Only independent issues qualify.** Use `issue-flow agent queue`'s **`independent`** list — issues with *no* dependency relation (either direction) to any other queue member. Everything else runs sequentially. +- **Harness gate.** If you cannot confirm the harness supports background execution (worktrees + parallel agents/subagents), **refuse `parallel:<n>` and run sequentially** — never pretend to parallelize. +- **Worktree per issue.** `git worktree add ../<repo>-<N> <N>-<slug>` so each issue has an isolated tree; run the yolo work there. +- **Print the worktree path.** After each `worktree add`, run `issue-flow agent open-workspace <worktree-path> --json` (print-only) and show the path. Do not launch a window. Continue with worktree-only parallel — see `.issueflows/04-designs-and-guides/separate-workspaces.md`. +- **Serialize merges.** Never merge PRs concurrently — the coordinating session merges them one at a time on the default branch, pulling between merges and rebasing/retrying on a non-fast-forward or CI refusal. +- **Shared files via the coordinator only.** Parallel workers must **not** each edit `HISTORY.md`; each leaves its changelog bullet in its issue status file / PR body, and the coordinator appends them in **merge order** during the serial merge step — same ordering rule as the changelog resolver (already-landed bullets first, the newest last), so serial and parallel runs produce the same file. If a worker PR does go `DIRTY` on `[Unreleased]`, the coordinator resolves it with `issue-flow agent sync-branch` rather than hand-editing markers. + +When in doubt, prefer the sequential run — parallel dispatch trades safety for speed and every one of the rules above must hold. + +## All yolo issues + merge conflicts + +`/iflow-cycle yolo` (or `label:yolo`) is the supported way to +**auto-process every open yolo-labelled issue**. No separate batch skill. + +**Conflict stance (sequential default):** each issue's yolo close merges its PR +and returns to a **clean default branch** before the next issue starts, so +within the cycle shared files (`HISTORY.md`, etc.) stay single-writer. +Stop-on-fail leaves the tree clean on default. + +That single-writer property does **not** protect against the default branch +moving **externally** — another session or an already-open PR merging while one +queued issue is in its test/CI window. The collision is almost always the same: +two additive bullets under `## [Unreleased]`. Close's sync step owns that +(`issue-flow agent sync-branch`: rebase onto `origin/<default>`, keep both +bullet sets with the in-flight one last, force-with-lease push, retry the merge +once), so a changelog-only conflict no longer halts a batch. Everything else +still trips step 6b. For experimental concurrent work, see +**Parallel dispatch** above and `.issueflows/04-designs-and-guides/parallel-cycle.md` +(merges stay serialized there too). Labelling first is optional via +`/iflow-review yolo` — then run `/iflow-cycle yolo`. + +## Constraints + +- **Off-path**: `/iflow` never auto-dispatches to `/iflow-cycle`; it is an explicit, deliberate batch action. +- **Sequential is the default and floor.** Parallelism (`parallel:<n>`) is opt-in and experimental; refusing it must always leave a working sequential run. +- Never weaken a yolo safeguard to keep the cycle moving — safeguards are stop conditions, not obstacles. +- Never run `/iflow-cleanup` from this skill; batch branch deletion still needs the user to see the merged PRs first. +- One consolidated confirm covers the batch; never silently expand the queue beyond what was confirmed. +- `cycle_status.md` is the single source of truth for an in-flight cycle: keep it current so `resume` and `/iflow-status` stay accurate. It is not an `issue<N>_*` group, so the folder sweep leaves it alone; archive it (step 8) when the run ends. diff --git a/.cursor/skills/iflow-doctor/SKILL.md b/.cursor/skills/iflow-doctor/SKILL.md new file mode 100644 index 0000000..b086f90 --- /dev/null +++ b/.cursor/skills/iflow-doctor/SKILL.md @@ -0,0 +1,113 @@ +--- +name: iflow-doctor +description: >- + Audit .issueflows/ for dirty conditions and optionally apply safe repairs. +disable-model-invocation: true +issue-flow-version: 0.4.2a4 +--- + +# issue-flow — doctor (`.issueflows/` health) (`/iflow-doctor`) + +Follow this skill to **detect and optionally fix** inconsistent issue-tracking +folders under `.issueflows/`. + +Unlike `/iflow-status` (read-only overview), `/iflow-doctor` can **move issue +groups** when the user confirms repair — using the same safe sweep rules as +`/iflow-capture` and `/iflow-build`. + +Do **not** auto-dispatch from `/iflow`, `/iflow-build`, or `/iflow-close`. + + +**Invoke:** type `iflow doctor` in chat, or `/iflow-doctor` from the slash menu (`iflow-doctor` also works). + + + + +### MODEL & EXECUTION DIRECTIVE + + +**Profile: economy** — Prioritize speed and token economy over deep reasoning. + +In Cursor: use **Auto** or a fast model before invoking this step. + + + +Keep scope tight to what this step requires. + + + + +### Resolve project root (multi-root workspaces) + +Before any `git`, `gh`, or `.issueflows/` path operation in this workflow: + +**Resolution order** (stop when unambiguous): + +1. **Explicit hints** in slash input — `root:<path>`, `repo:<folder-basename>` (directory name, e.g. `cellpy-core`), or `repo:owner/name`. +2. **CLI fast path** — `issue-flow agent resolve [-C <start>] [--from-file <active-file>] [--json]`. Use the returned `project_root` and `repo`; pass `-C <project_root>` to other `issue-flow agent …` subcommands. When the answer came from the workspace registry, the payload sets `resolved_via_workspace_default: true`. +3. **Branch context** — exactly one workspace repo whose branch matches `^\d+-` → that root. +4. **Single scaffold** — exactly one `.issueflows/` tree visible in the workspace → that root. +5. **Workspace default** — an `issueflow-workspace.toml` at the workspace root (created with `issue-flow workspace init`) may name a `default` member repo; use it when no scaffold matched above. Tell the user the default was used. +6. **Ambiguous** → **stop and ask**; never guess between sibling repos. + +After resolution, treat the result as `<project_root>` and `<owner/repo>`: + +- **Git:** `git -C <project_root> …` (or `issue-flow agent … -C <project_root>` for supported ops). +- **GitHub:** pass an explicit repo on every `gh` call — never rely on `gh`'s implicit cwd default. For most commands use `--repo <owner/repo>`; **exception:** `gh repo view` takes the repo as a **positional** arg (`gh repo view <owner/repo> …`) and rejects `--repo`. +- **Paths:** all `.issueflows/…` paths are under `<project_root>`. + +When `.issueflows/04-designs-and-guides/multi-repo-workspaces.md` exists, read it for layout and cross-repo guidance. + + +## Instructions + +> **CLI fast path (optional).** If the `issue-flow` CLI is on `PATH`: +> - **Audit:** `issue-flow doctor [--json]` (or `issue-flow agent audit`). +> - **Repair:** `issue-flow doctor --fix [--except N] [--dry-run] [--json]` +> (or `issue-flow agent repair`). +> +> The CLI is optional: if it is missing or errors, fall back to the manual +> checklist in `.issueflows/04-designs-and-guides/dirty-issueflows.md`. + +1. **Resolve project root** — use `issue-flow agent resolve` when available. + +2. **Audit** — run `issue-flow doctor` (or manual checks per the design doc). + Present every finding: code, severity, message, suggested next step. + +3. **Repair (only on explicit user confirm)** — run + `issue-flow doctor --fix` with `--dry-run` first when anything will move; + pass `--except N` when multiple groups sit in `01-current-issues/` + and focus is ambiguous. Never repair duplicate-across-folders automatically. + +4. **Re-audit** after repair and report what changed. + +5. **Housekeeping commit (default when issueflows-only dirty)** — Doctor repair + is filesystem-only; it never runs `git commit`. After a successful repair, + check the working tree (`issue-flow agent preflight --json` when available, + else `git status --porcelain`): + - If **clean** — done. + - If dirty and **every** path is under `.issueflows/` + (`issueflows_only: true` in preflight JSON, or the same rule by hand) — + list the paths, propose + `chore: doctor housekeeping — archive/sweep .issueflows groups`, + and ask for **one confirm** with **yes as the recommended default**. + On yes: `git add` **only** those paths and commit (no push). If the + current branch is the **default**, commit on a chore branch (or a tiny + PR) instead — do not leave housekeeping unpushed on home default + (issue #303). On no: leave dirty and note that `/iflow-pick` will + offer the same commit again. + - If dirty with any path **outside** `.issueflows/` — report mixed + dirt; do **not** offer the housekeeping default (user must sort code + changes separately). + +## Constraints + +- **Off-path** — never auto-dispatch from `/iflow` or other lifecycle steps. +- **Safe repairs only** — mkdir missing tree folders; sweep non-focus groups + from `01-current-issues/` to `02-partly-solved-issues/` or + `03-solved-issues/` by Done status. No deletes, no duplicate merges. +- **Gated moves** — nothing moves without a consolidated user confirm. +- **No CLI auto-commit** — `doctor --fix` never commits; the agent commits + only after the step-5 confirm, and never stages paths outside + `.issueflows/`. +- Degrade gracefully when the CLI is absent (manual checklist + sweep steps). diff --git a/.cursor/skills/iflow-drive/SKILL.md b/.cursor/skills/iflow-drive/SKILL.md new file mode 100644 index 0000000..0b0dc9b --- /dev/null +++ b/.cursor/skills/iflow-drive/SKILL.md @@ -0,0 +1,187 @@ +--- +name: iflow-drive +description: >- + Compose-only orchestrator: draft an epic from an existing issue, publish + every stage, run /iflow-auto each epoch, final review, then local -d + cleanup and /iflow-status. +disable-model-invocation: true +issue-flow-version: 0.4.2a4 +--- + +# issue-flow — drive (`/iflow-drive`) + +Follow this skill to run a **compose-only** path from an existing GitHub +issue `<N>`: draft epic (auto-accept unless grill-me) → publish every +stage → `/iflow-auto` each epoch → final review (create leftover findings) +→ local cleanup **`-d` only** → `/iflow-status`. + + +Contract: `.issueflows/04-designs-and-guides/drive-mode.md`. + +Do **not** fork yolo / cycle / auto / epic internals. Read and follow +those skills; this one only sequences them and records `drive_status.md`. + +## Input + +- **`<N>`** — existing GitHub issue that becomes the epic anchor + (required). Drive never creates the anchor; if none exists, stop and + point at `/iflow-issue epic <intent>`. +- **`grill` / `grill-me`** — run grill-me on the epic goal before + confirming the draft. Else auto-set `Status: confirmed` after draft + (also honour project `grill_me_default`). +- **`loops:<n>`** — forwarded to `/iflow-auto`. +- **`dry-run`** — resolve planned stages / queue, show what would run, + **stop** (no confirm, no writes). +- **`abort` / `stop` / `cancel` / `halt` mid-run** — not start tokens. + Any user message that *is* (or starts with) `abort` / `stop` / + `cancel` / `halt` (case-insensitive, optional leading `/`) **stops** + at the next stage or issue boundary. Record `aborted` in + `drive_status.md`. Same floor as cycle `onfail:stop` (leave the repo + on the default branch, clean). + + +**Invoke:** type `iflow drive` in chat, or `/iflow-drive` from the slash menu (`iflow-drive` also works). + + + + +### MODEL & EXECUTION DIRECTIVE + + +**Profile: reasoning** — Prioritize deep thinking and careful trade-offs over speed or token economy. + +In Cursor: switch to a thinking-capable model before invoking this step (not Auto-only). + + + +Keep scope tight to what this step requires. + + + + +### Resolve project root (multi-root workspaces) + +Before any `git`, `gh`, or `.issueflows/` path operation in this workflow: + +**Resolution order** (stop when unambiguous): + +1. **Explicit hints** in slash input — `root:<path>`, `repo:<folder-basename>` (directory name, e.g. `cellpy-core`), or `repo:owner/name`. +2. **CLI fast path** — `issue-flow agent resolve [-C <start>] [--from-file <active-file>] [--json]`. Use the returned `project_root` and `repo`; pass `-C <project_root>` to other `issue-flow agent …` subcommands. When the answer came from the workspace registry, the payload sets `resolved_via_workspace_default: true`. +3. **Branch context** — exactly one workspace repo whose branch matches `^\d+-` → that root. +4. **Single scaffold** — exactly one `.issueflows/` tree visible in the workspace → that root. +5. **Workspace default** — an `issueflow-workspace.toml` at the workspace root (created with `issue-flow workspace init`) may name a `default` member repo; use it when no scaffold matched above. Tell the user the default was used. +6. **Ambiguous** → **stop and ask**; never guess between sibling repos. + +After resolution, treat the result as `<project_root>` and `<owner/repo>`: + +- **Git:** `git -C <project_root> …` (or `issue-flow agent … -C <project_root>` for supported ops). +- **GitHub:** pass an explicit repo on every `gh` call — never rely on `gh`'s implicit cwd default. For most commands use `--repo <owner/repo>`; **exception:** `gh repo view` takes the repo as a **positional** arg (`gh repo view <owner/repo> …`) and rejects `--repo`. +- **Paths:** all `.issueflows/…` paths are under `<project_root>`. + +When `.issueflows/04-designs-and-guides/multi-repo-workspaces.md` exists, read it for layout and cross-repo guidance. + +## Instructions + +1. **Require `<N>`.** If missing or not a positive integer, **stop** and + ask. Run `gh issue view <N> --repo <owner/repo>` to confirm the + issue exists. + +2. **`dry-run`.** If the token is present: show whether + `.issueflows/05-epics/epic<N>_plan.md` exists and + its `Status`; list unpublished vs published specs; run + `issue-flow agent epic-status <N> --json` when a plan exists; show + the queue `issue-flow agent queue --epic <N> --json` would return; + note that cleanup would be `local only` + skip A2 (`-d` / reachable + only). **Stop** without confirm or writes. + +3. **Drive confirm** (only planned interruption besides auto's budget + ask and cycle/yolo stop conditions). Present in normal prose: issue + `#<N>` as epic anchor; that this run will **draft-accept** (unless + grill-me / `grill_me_default`), **publish every unpublished stage**, + run **`/iflow-auto` for each unfinished published stage**, run a + **final adversarial review** that may create/reopen GitHub issues, + then **local cleanup `-d` only** (no Phase B, no `-D`), then + `/iflow-status`. Require explicit yes. This confirm **covers** + epic's plan-accept, per-stage publish confirms, auto's overnight + confirm, final-review creates, and reachable-only cleanup — do not + re-ask those mid-run. + +4. **Write / update `drive_status.md`** at + `.issueflows/01-current-issues/drive_status.md`: + anchor `<N>`, checklist (`draft`, `publish`, `auto`, `final_review`, + `cleanup`, `status`), `findings:` list (empty at start), last + outcome `pending`, ISO timestamp. Not an `issue<N>_*` group — + sweeps leave it alone. + +5. **Abort check** (repeat at every stage / issue boundary below). If + the latest user message is (or starts with) `abort` / `stop` / + `cancel` / `halt` (case-insensitive, optional leading `/`): set + `last_outcome: aborted` in `drive_status.md`, leave the repo on the + default branch clean, **stop**. Do not start the next stage or + issue. + +6. **Draft epic.** Follow `.cursor/skills/iflow-epic/SKILL.md` + for `/iflow-epic <N>` (write-free on GitHub). + - If `epic<N>_plan.md` already has `Status: confirmed`, **skip** + draft and publish; jump to step 8 (auto). + - If a draft exists, reuse it unless the user asked to revise. + - Grill only when the `grill` / `grill-me` token is present **or** + `grill_me_default` is baked true. Else set `Status: confirmed` + without a second plan-accept prompt (covered by the drive + confirm). + - Mark `draft` done in `drive_status.md`. + +7. **Publish all stages.** Loop `/iflow-epic <N> publish` (same skill) + until no unpublished specs remain. Honour `Published: #<M>` + idempotency. The drive confirm replaces each per-stage publish + confirm — do not re-ask. Commit `Published:` lines on a chore/issue + branch or tiny PR — **not** unpushed on default (issue #303). Mark + `publish` done in `drive_status.md`. + +8. **Auto each part.** While `issue-flow agent epic-status <N> --json` + reports an unfinished published stage: follow + `.cursor/skills/iflow-auto/SKILL.md` for `/iflow-auto <N>` + (forward `loops:<n>` when given). The drive confirm covers auto's + overnight authorization — do not re-ask. Honour `epoch_gated`, + cycle/yolo stop conditions, and auto's **budget ask** (accept / + grant N more loops / abort) as a **planned pause**, not a drive + failure. Append created/reopened numbers to `drive_status.md` + `findings:`. Abort-check at each stage / issue boundary. + +9. **Final review.** When every published stage is `done` (or the user + **accepted** a budget ask): run `/iflow-auto <N> review` (same + skill). Create/reopen GitHub issues for remaining gaps using the + criteria table in + `.issueflows/04-designs-and-guides/advanced-auto-mode.md`. + The drive confirm covers those creates. Record numbers in + `findings:`. Do **not** start another epoch unless the user later + runs `/iflow-auto` themselves. Mark `final_review` done. + +10. **Cleanup.** Follow `.cursor/skills/iflow-cleanup/SKILL.md` + with trailing `local only` **and skip Phase A2**: + - switch to default, `git pull --ff-only`, `git fetch --prune`; + - `issue-flow agent worktree-remove` for **`reachable`** worktrees + only; + - `git branch -d` on **`reachable`** branches only. + Leave `squash_landed`, `merged_pr_divergent`, and `unique_work`. + Never `git branch -D`. Never Phase B (no remote deletes, no + findings issue). The drive confirm covers this reachable-only + pass — do not re-ask. Mark `cleanup` done. + +11. **Report + status.** Summarize stages published, PRs merged, + findings issues (created/reopened numbers), cleanup counts + (`-d` deletions / worktrees removed / squash-landed left). Set + `last_outcome: done` in `drive_status.md`. Then follow + `.cursor/skills/iflow-status/SKILL.md` (`/iflow-status`). + Mark `status` done. + +## Constraints + +- **Off-path:** `/iflow` never auto-dispatches here. +- Compose `/iflow-epic` + `/iflow-auto` + `/iflow-cycle` + + `/iflow-yolo` + `/iflow-cleanup` + `/iflow-status`; do not fork them. +- Never rebase / force-push / push default. +- Cleanup never `git branch -D`, never Phase B. +- Do not leave `Published: #<M>` unpushed on home default (#303). +- Auto's budget ask remains a planned pause (accept / grant / abort). +- User abort tokens stop only at the next stage / issue boundary. diff --git a/.cursor/skills/iflow-epic/SKILL.md b/.cursor/skills/iflow-epic/SKILL.md new file mode 100644 index 0000000..3f3a7b4 --- /dev/null +++ b/.cursor/skills/iflow-epic/SKILL.md @@ -0,0 +1,142 @@ +--- +name: iflow-epic +description: >- + Plan a larger change as a staged epic: draft epic<N>_plan.md with stages of + manageable issue specs, then publish confirmed stages as GitHub issues. +disable-model-invocation: true +issue-flow-version: 0.4.2a4 +--- + +# issue-flow — epic planning (`/iflow-epic`) + +Follow this skill to plan a change that is **too large for one issue**: divide it into sequential **stages**, each stage into **manageable issues** that flow through the normal lifecycle (`/iflow-capture` → `/iflow-plan` → `/iflow-build` → `/iflow-close`). + +The surface has two actions. **Drafting** (the default) is write-free on GitHub: its deliverable is `.issueflows/05-epics/epic<N>_plan.md`, and it never creates GitHub issues, labels, or milestones. **`publish`** is the single exception — it turns a *confirmed* plan into real GitHub issues, stage by stage, behind one consolidated confirm. + +## Input + +- **`<N>`** — the GitHub issue number of the **epic anchor** (an umbrella issue describing the large change). Required: an epic without an anchor has nowhere to track progress. If no anchor issue exists yet, stop and point the user at **`/iflow-issue epic <intent>`** (creates the anchor with an `Epic:` title and the `epic` label when present) — then re-run `/iflow-epic <N>` with the new number. +- **`publish [stage <k>]`** — run the publish action (below) instead of drafting. Without a stage number, the earliest stage with unpublished specs is chosen. +- Optional free text — extra context, constraints, or a proposed stage split to seed the draft. + + +**Invoke:** type `iflow epic` in chat, or `/iflow-epic` from the slash menu (`iflow-epic` also works). + + + + +### MODEL & EXECUTION DIRECTIVE + + +**Profile: reasoning** — Prioritize deep thinking and careful trade-offs over speed or token economy. + +In Cursor: switch to a thinking-capable model before invoking this step (not Auto-only). + + + +Keep scope tight to what this step requires. + + + + +### Resolve project root (multi-root workspaces) + +Before any `git`, `gh`, or `.issueflows/` path operation in this workflow: + +**Resolution order** (stop when unambiguous): + +1. **Explicit hints** in slash input — `root:<path>`, `repo:<folder-basename>` (directory name, e.g. `cellpy-core`), or `repo:owner/name`. +2. **CLI fast path** — `issue-flow agent resolve [-C <start>] [--from-file <active-file>] [--json]`. Use the returned `project_root` and `repo`; pass `-C <project_root>` to other `issue-flow agent …` subcommands. When the answer came from the workspace registry, the payload sets `resolved_via_workspace_default: true`. +3. **Branch context** — exactly one workspace repo whose branch matches `^\d+-` → that root. +4. **Single scaffold** — exactly one `.issueflows/` tree visible in the workspace → that root. +5. **Workspace default** — an `issueflow-workspace.toml` at the workspace root (created with `issue-flow workspace init`) may name a `default` member repo; use it when no scaffold matched above. Tell the user the default was used. +6. **Ambiguous** → **stop and ask**; never guess between sibling repos. + +After resolution, treat the result as `<project_root>` and `<owner/repo>`: + +- **Git:** `git -C <project_root> …` (or `issue-flow agent … -C <project_root>` for supported ops). +- **GitHub:** pass an explicit repo on every `gh` call — never rely on `gh`'s implicit cwd default. For most commands use `--repo <owner/repo>`; **exception:** `gh repo view` takes the repo as a **positional** arg (`gh repo view <owner/repo> …`) and rejects `--repo`. +- **Paths:** all `.issueflows/…` paths are under `<project_root>`. + +When `.issueflows/04-designs-and-guides/multi-repo-workspaces.md` exists, read it for layout and cross-repo guidance. + +> **CLI fast path (optional).** If the `issue-flow` CLI is on `PATH`, run +> `issue-flow agent epic-status <N> --json` for a deterministic picture of an +> existing epic: stages, per-issue state and blockers, the current stage, and +> the next open, unblocked candidates. Use it before re-drafting a stage and +> in the publish action's stage selection. Read-only; add `--local` to skip +> the GitHub lookups. + +## Instructions + +1. **Gather context (read-only).** Read the epic anchor (`gh issue view <N> --repo <owner/repo>`), skim `.issueflows/04-designs-and-guides/` for relevant design docs (cite them in the plan when they shape the approach), and — when `graphify-out/GRAPH_REPORT.md` exists — skim it before grepping. + +2. **Draft the staged plan** at `.issueflows/05-epics/epic<N>_plan.md` using exactly this structure (the publish step parses it): + + ```markdown + # Epic #<N>: <title> + + Anchor: <GitHub issue URL> + Status: draft + + ## Goal + + <what the whole epic achieves, and how we know it is done> + + ## Constraints + + <hard boundaries, non-goals, ordering requirements> + + ## Stage 1 — <stage title> + + <one paragraph: what this stage proves or delivers> + - Goal: <one-line stage / epoch goal> + + ### Issue: <title as it will appear on GitHub> + + - Spec: <self-contained paragraph: context, scope, acceptance criteria> + - Goal: <crisp acceptance someone else can verify> + - Model: deep | fast | default + - Depends on: none | #<M> | stage <j> issue <k> + - yolo: yes | no — <one-line judgment against the yolo-fitness criteria> + + ### Issue: <next issue title> + ... + + ## Stage 2 — <stage title> + ... + ``` + + The `publish` action later appends a `- Published: #<M>` line to each spec it creates — never add those by hand. Older plans without `Goal:` / `Model:` markers still parse (`Model` defaults to `default`). + +3. **Sizing rules for issue specs** — every issue must be *manageable*: + - one issue = one branch = one PR, implementable in roughly a day or less; + - a **crisp Goal** (and Spec) someone else could verify; + - **Model:** `deep` (planning / judgment), `fast` (mechanical), or `default` (step profile) — copied into the GitHub issue body on publish; + - dependencies stated explicitly: `#<M>` for already-published issues, `stage <j> issue <k>` placeholders for unpublished ones (the publish step resolves placeholders to real numbers); + - a **yolo-fitness judgment** per issue: `yes` only when it is well-specified, mechanical or pattern-following, low blast radius, and guarded by existing tests — umbrella work, design decisions, and flag-day changes are `no`. + +4. **Stage discipline** — stages are sequential milestones, each small enough that finishing it can change the plan for the next. Front-load the stage that retires the most risk. Do not plan more than 2–3 stages in detail; sketch later stages as bullets under a `## Later (unstaged)` heading instead of fake-precise issue specs. + +5. **Review with the user.** Present the draft (stage titles, issue titles, dependency graph, yolo flags) and iterate until they confirm. Record the confirmation by changing `Status: draft` to `Status: confirmed` in the plan file. + +6. **Stop.** Creating the GitHub issues is the `publish` action below, with its own consolidated confirm — never create them from the drafting flow, even if asked to "just create them": run `/iflow-epic <N> publish` explicitly so the confirm gates stay distinct. + +## Action: publish + +Turn one stage of a **confirmed** plan into real GitHub issues. Requires `Status: confirmed` in `epic<N>_plan.md` — refuse drafts and point at the review step instead. + +1. **Select the stage.** A named `stage <k>` publishes exactly that stage; otherwise pick the earliest stage containing specs without a `Published:` line. Specs that already carry `- Published: #<M>` are **skipped** (this makes re-runs idempotent). +2. **Dry-run listing.** Show what would be created: per spec — title, labels (`yolo` when the judgment says yes **and** the label exists per `gh label list`; otherwise note the gap), and the dependency lines after placeholder resolution. `stage <j> issue <k>` placeholders pointing at already-published specs are rewritten to their real `#<M>`; placeholders at still-unpublished specs stay verbatim with a note. +3. **Consolidated confirm** (destructive-ish — outward-facing writes; normal prose, never shortened). One prompt covering exactly: which issues get created, with which labels, and that the anchor issue's task list will be updated. Do not proceed without a clear yes. +4. **Create, in dependency order within the stage.** For each spec: `gh issue create --repo <owner/repo>` with the self-contained body (context, scope, acceptance criteria, **Goal:** and **Model:** lines when present in the plan, resolved `Depends on: #<M>` lines, and a closing `Part of epic #<N>.` line). Immediately record the new number in the plan file as `- Published: #<M>` under that spec. +5. **Update the anchor issue's task list** (append/patch only — never rewrite the user's own body text): fetch the body, append a `## Stage <k> — <title>` section (or extend it) with one `- [ ] #<M>` line per created issue, and write it back via `gh issue edit <N> --body-file`. +6. **Commit `Published:` lines off default.** The plan-file edits in step 4 must not sit as unpushed commits on home default. If you are on default (or would commit there), use a chore/issue branch (or a tiny dedicated PR). Never leave `Published: #<M>` unpushed on home default — that is what later makes `git pull --ff-only` diverge after a squash (issue #303). +7. **Report.** Created issues (numbers + titles + labels), skipped already-published specs, unresolved placeholders, and the reminder that the next stage publishes only after this one's issues close. + +## Constraints + +- **Drafting writes nothing on GitHub**: no `gh issue create`, no label or milestone writes, no task-list edits on the anchor issue. Reading with `gh issue view` / `gh issue list` is always fine. The `publish` action is the single exception and never runs without its consolidated confirm. +- **Off-path**: `/iflow` never auto-dispatches to `/iflow-epic`; the user opts in explicitly. +- Epics decompose **into** the normal single-issue lifecycle, never around it — no issue spec may assume work happens outside a normal issue branch + PR. +- The plan file is user-owned working state under `.issueflows/`: `issue-flow update` never touches it. diff --git a/.cursor/skills/iflow-fix/SKILL.md b/.cursor/skills/iflow-fix/SKILL.md new file mode 100644 index 0000000..bedc103 --- /dev/null +++ b/.cursor/skills/iflow-fix/SKILL.md @@ -0,0 +1,109 @@ +--- +name: iflow-fix +description: >- + Interactive session: one long-lived branch + GitHub issue for a stream of + small iterative fixes, landed together via /iflow-close. +disable-model-invocation: true +issue-flow-version: 0.4.2a4 +--- + +# issue-flow — interactive iterative-fix session (`/iflow-fix`) + +Follow this skill for an **ongoing working session** of many small fixes (small bugs, typos, chores, polish) on one branch, landed via one PR — rather than a single well-defined deliverable. + +Do **not** use this skill from `/iflow`, `/iflow-build`, or `/iflow-close`. `/iflow-fix` is explicit-only because it creates GitHub issues and branches and drives an open-ended loop. While a session is active, drive it with `/iflow-fix` + `/iflow-close`, not `/iflow`. + +It **coexists** with `/iflow-pick fix` (one-shot general-fixes setup into `/iflow-plan` → `/iflow-build`) and `/iflow-issue` (one well-specified normal issue). `/iflow-fix` stays and runs the loop until close. + +## Input + +- **a name** (e.g. `polish-cli-output`) — used for the issue title and branch slug. +- **(nothing)** — default the slug to `iterative-small-fixes` (made unique via the new issue number). +- **a description** during an active session — run the next fix in the loop. + + +**Invoke:** type `iflow fix` in chat, or `/iflow-fix` from the slash menu (`iflow-fix` also works). + + + + +### MODEL & EXECUTION DIRECTIVE + + +**Profile: reasoning** — Prioritize deep thinking and careful trade-offs over speed or token economy. + +In Cursor: switch to a thinking-capable model before invoking this step (not Auto-only). + + + +Keep scope tight to what this step requires. + + + + +### Resolve project root (multi-root workspaces) + +Before any `git`, `gh`, or `.issueflows/` path operation in this workflow: + +**Resolution order** (stop when unambiguous): + +1. **Explicit hints** in slash input — `root:<path>`, `repo:<folder-basename>` (directory name, e.g. `cellpy-core`), or `repo:owner/name`. +2. **CLI fast path** — `issue-flow agent resolve [-C <start>] [--from-file <active-file>] [--json]`. Use the returned `project_root` and `repo`; pass `-C <project_root>` to other `issue-flow agent …` subcommands. When the answer came from the workspace registry, the payload sets `resolved_via_workspace_default: true`. +3. **Branch context** — exactly one workspace repo whose branch matches `^\d+-` → that root. +4. **Single scaffold** — exactly one `.issueflows/` tree visible in the workspace → that root. +5. **Workspace default** — an `issueflow-workspace.toml` at the workspace root (created with `issue-flow workspace init`) may name a `default` member repo; use it when no scaffold matched above. Tell the user the default was used. +6. **Ambiguous** → **stop and ask**; never guess between sibling repos. + +After resolution, treat the result as `<project_root>` and `<owner/repo>`: + +- **Git:** `git -C <project_root> …` (or `issue-flow agent … -C <project_root>` for supported ops). +- **GitHub:** pass an explicit repo on every `gh` call — never rely on `gh`'s implicit cwd default. For most commands use `--repo <owner/repo>`; **exception:** `gh repo view` takes the repo as a **positional** arg (`gh repo view <owner/repo> …`) and rejects `--repo`. +- **Paths:** all `.issueflows/…` paths are under `<project_root>`. + +When `.issueflows/04-designs-and-guides/multi-repo-workspaces.md` exists, read it for layout and cross-repo guidance. + +## Instructions + +### Phase 1 — set up the session (once) + +1. **Preflight.** Detect the default branch (`gh repo view --json defaultBranchRef -q .defaultBranchRef.name`; fall back to `git symbolic-ref --quiet --short refs/remotes/origin/HEAD`, else `main`). Run `git fetch --prune`. Report current branch + clean/dirty tree (`git status --porcelain`); if dirty with unrelated changes, ask to commit/stash first. +2. **Resolve the session name.** Baked `fix_auto_name = false`: use an explicit invoke name when given; otherwise default to `iterative-small-fixes`. If the invoke text is free-form (not already a slug) and you would invent a better name, **ask once** whether to use your proposed slug or keep the default — then proceed to create confirm. Configurable via `fix_auto_name` under `[issueflow]` in `.issueflows/config.toml` (re-run `issue-flow update` after changing). +3. **Create the GitHub issue (always, with confirmation).** Show the chosen title (e.g. `Iterative fixes: <name>`, or `Iterative small fixes`) and a body noting it is an interactive `/iflow-fix` session whose individual fixes are recorded in the status markdown and landed together via `/iflow-close`. Create it with `gh issue create` (add `--repo owner/repo` if ambiguous). Capture the returned number `N`. A fresh issue is created each time. Set the chat tab title to `Issue <N> <session name>`. +4. **Create the worktree (with confirmation).** Slug from the resolved name (kebab-case; default `iterative-small-fixes`); branch name `<N>-<slug>`. Require a clean tree. +**Worktree-first start (default, issue #255 / #303).** After the dirty-tree gate and slug confirm — unless the user passed `inplace` / `no worktree`, or ops chose stay-on-current/default: + +1. Home stays on the **default** branch. `git fetch --prune`. Do **not** `git switch -c` on home. +2. Run `issue-flow agent default-sync --json -C <home>`. If `action` is `even` or `ff_only`, `git pull --ff-only`. If home is ahead or diverged, **print** the classification and **still continue** — starting work must not wait for home to be ff-able. +3. `issue-flow agent worktree-add <N> --slug <slug> -C <home> --json` — path is `../<repo>-<N>`. Starts from fetched `origin/<default>`, not local default HEAD. On error, **stop and ask**; never silently fall back to inplace. +4. `issue-flow agent open-workspace <path> --json` (print-only). Tell the user the worktree path. Do **not** ask to open a window. +5. Run `/iflow-capture` (and later plan/build/close) with `-C <worktree-path>`. Continue the session in that folder. +6. Token `inplace` / `no worktree` keeps legacy `git switch -c <N>-<slug>` on home. + + On a non-default home branch → **ask** whether to FF/switch home to default first or use `inplace`. +5. **Capture locally.** Delegate to the `/iflow-capture` flow (or the `iflow-capture` skill) for `<N>`: write `.issueflows/01-current-issues/issue<N>_original.md` and run its archive sweep. Do not duplicate that logic. +6. **Seed the status file.** Create `.issueflows/01-current-issues/issue<N>_status.md` with a short header (interactive `/iflow-fix` session), an unchecked `- [ ] Done`, and an empty **`## Iterative fixes log`** section. + +### Phase 2 — the fix loop (repeat) + +For each proposed fix: + +1. **Restate** the fix in one line. +2. **Short plan** — a few lines (intent + file(s)); never a full `issue<N>_plan.md`. +3. **Ask to proceed** — implement **only on confirmation**; otherwise revise or drop. +4. **Implement** the confirmed fix, focused on that one change. +5. **Record** it: append a dated bullet to **`## Iterative fixes log`** in `issue<N>_status.md`. Offer proactively; always update when asked. + +If a "fix" is really a substantial feature or sprawls across unrelated areas, say so and suggest filing it as its own issue via `/iflow-issue` (then `/iflow-plan` → `/iflow-build`). + +### Phase 3 — finish + +Tell the user to run **`/iflow-close`** to land the session (tests, optional bump, status update, commit, push, PR). Do not auto-run it. Remind them to run `/iflow-cleanup` after the PR merges. + +## Constraints + +- Off-path: never auto-dispatch from `/iflow`, `/iflow-build`, or `/iflow-close`. +- Never create a GitHub issue or branch without explicit confirmation; show what will be created first. +- GitHub only (`gh`); GitLab is not supported. +- Branch off the detected default (or the current branch when chosen); never force-push or delete branches from this skill. +- Keep `- [ ] Done` unchecked during the session; `/iflow-close` flips it. +- Delegate local capture to `/iflow-capture` and finishing to `/iflow-close`; one fix per loop iteration, implemented only on explicit confirmation. diff --git a/.cursor/skills/iflow-graphify/SKILL.md b/.cursor/skills/iflow-graphify/SKILL.md new file mode 100644 index 0000000..b311d78 --- /dev/null +++ b/.cursor/skills/iflow-graphify/SKILL.md @@ -0,0 +1,79 @@ +--- +name: iflow-graphify +description: >- + Rebuild the graphify knowledge graph (graphify-out/) by shelling out to + `issue-flow graphify` or `graphify` directly. +disable-model-invocation: true +issue-flow-version: 0.4.2a4 +--- + +# issue-flow — graph rebuild (`/iflow-graphify`) + +Follow this skill to refresh the project's [graphify](https://iflow-graphify.net) knowledge graph — a stale `graphify-out/` after a large refactor, or the initial graph after installing `graphifyy`. + +Do **not** use this skill from `/iflow-build`, `/iflow-close`, or `/iflow`. `/iflow-graphify` is opt-in only. + + +**Invoke:** type `iflow graphify` in chat, or `/iflow-graphify` from the slash menu (`iflow-graphify` also works). + + + + +### MODEL & EXECUTION DIRECTIVE + + +**Profile: economy** — Prioritize speed and token economy over deep reasoning. + +In Cursor: use **Auto** or a fast model before invoking this step. + + + +Keep scope tight to what this step requires. + + + +## Instructions + +1. **Prefer `issue-flow graphify`** from the project root: + + ```bash + issue-flow graphify + ``` + + With no extra args this runs `graphify update <project>` — AST-only, **no LLM API key required**, produces the full `graphify-out/`. To pick a different graphify subcommand, pass it as the first arg: `issue-flow graphify extract` (adds the slower semantic LLM pass for richer relationships — needs an API key), `issue-flow graphify watch` (live), `issue-flow graphify cluster-only --no-viz`, etc. Use `-C <dir>` to scan a project other than the current directory. Trailing flags pass through verbatim. Do not invent new wrapper flags. + +2. **Fallback to `graphify` directly** when `issue-flow` is unavailable: + + ```bash + graphify update . + ``` + + `graphify` is subcommand-based — `graphify .` on its own is **not** valid (graphify reports `unknown command '.'`). Always pick a subcommand: `update` for the no-LLM AST build, `extract` for the full semantic pass, `watch` for a long-running watcher, etc. + +3. **If graphify exits with "no LLM API key found"**, the user picked `extract` (or another semantic subcommand) without configuring a backend. Cursor's own LLM is not available to subprocesses, so graphify cannot reuse it. Suggest one of: + + - Set an API key for `GEMINI_API_KEY` / `GOOGLE_API_KEY`, `ANTHROPIC_API_KEY`, `OPENAI_API_KEY`, or `MOONSHOT_API_KEY`. + - Run `issue-flow graphify extract --backend ollama` to use a local LLM via [Ollama](https://ollama.com) (requires Ollama installed with a model pulled). + - Drop the `extract` arg and use the default `issue-flow graphify` (AST-only, no LLM). + +4. **Handle missing graphify gracefully.** If the run reports `graphify` is not on PATH, do **not** retry blindly. Tell the user to install it once: + + ```bash + uv tool install graphifyy # recommended + pipx install graphifyy + pip install graphifyy + ``` + + `graphifyy` (double-y) is the official PyPI package; the CLI is still `graphify`. After installing, suggest `issue-flow update` so `graphify cursor install` registers the graphify Cursor skill alongside this one. + +5. **Verify and report.** + - Confirm `graphify-out/graph.json`, `graphify-out/graph.html`, and `graphify-out/GRAPH_REPORT.md` exist after a successful run. + - Surface non-zero exit codes verbatim; do not silently retry. + - When the user asks "what changed?", skim `GRAPH_REPORT.md` (god nodes, surprising connections) for a short summary. + +## Constraints + +- Never auto-dispatch `/iflow-graphify` from another slash command. The user opts in explicitly. +- Never commit `graphify-out/cost.json` or `graphify-out/manifest.json`; they are local-only. +- Long-running modes (`watch`) keep the process alive; ask the user before launching them in an agent context. +- Forward extra arguments verbatim. Do **not** translate or rewrite graphify's flag set inside issue-flow. diff --git a/.cursor/skills/iflow-history-update/SKILL.md b/.cursor/skills/iflow-history-update/SKILL.md new file mode 100644 index 0000000..778cc69 --- /dev/null +++ b/.cursor/skills/iflow-history-update/SKILL.md @@ -0,0 +1,113 @@ +--- +name: iflow-history-update +description: >- + Update the changelog when landing an issue: append a bullet to + [Unreleased], or promote it to a release section after a version bump. +disable-model-invocation: true +issue-flow-version: 0.4.2a4 +--- + +# issue-flow — history update + +Use this skill to decide the changelog bullet as part of `/iflow-close`. It never runs on its own schedule; it is driven by the "update HISTORY" step, and does not run when the user passed `nohistory` / `skip history`. The write happens now, on the issue branch, so the bullet lands in the PR commit. + + +### MODEL & EXECUTION DIRECTIVE + + +**Profile: economy** — Prioritize speed and token economy over deep reasoning. + +In Cursor: use **Auto** or a fast model before invoking this step. + + + +Keep scope tight to what this step requires. + + + +## Preconditions + +1. The changelog file (`HISTORY.md`) exists at the **project root**. If it does not, **skip** this step, print "no `HISTORY.md` — skipping changelog update" and continue the rest of `/iflow-close`. Never create the file from this skill. +2. The file is in **Keep a Changelog** shape: a top-level `## [Unreleased]` heading, with released versions below as `## [x.y.z] - YYYY-MM-DD` headings. If the shape does not match, **stop and report the mismatch** instead of guessing — let the user fix the file or pass `nohistory`. + + +## Inputs from `/iflow-close` + +| From | Used for | +|---|---| +| Issue number `N` | Reference suffix on the new bullet, e.g. `(#42)`. | +| Issue title (from `.issueflows/01-current-issues/issue<N>_original.md`) | Default bullet summary. | +| `log "..."` / `note "..."` input token | Override the bullet summary verbatim. | +| Version-bump outcome (from step 2 of `/iflow-close`) | Decides **append** vs **promote** (see below). | + +## Operation modes + +### A. No version bump — append to `[Unreleased]` + +1. Read `HISTORY.md`. Locate the first `## [Unreleased]` heading. The block ends at the next `## [` heading (or EOF). +2. Compose the new bullet: + + ``` + - <summary>. (#<N>) + ``` + + Summary = `log "..."` override if provided, else the issue title with sentence case, trailing period trimmed before the `.` we add. +3. Append the bullet to the end of the Unreleased bullet list. Preserve existing formatting (blank lines, list markers). Do not reorder existing entries. +4. Write the change without a confirm prompt (`confirm_changelog_update` is false; same as the `yolo` token's history behaviour). Still report what was written. + + + +### B. Version bump happened — promote `[Unreleased]` to a new release section + +Only runs when step 2 of `/iflow-close` actually changed `pyproject.toml` to a new version `NEW_VERSION`. + +1. Determine `NEW_VERSION` (e.g. read from `pyproject.toml`, or from the `uv version` command output). Determine `TODAY` as `YYYY-MM-DD` in the user's local timezone. +2. Read `HISTORY.md`. Find `## [Unreleased]`. +3. Compose the new bullet (same shape as mode A). If `[Unreleased]` was empty when the bump happened, still create the new release section with this bullet inside it — a version bump implies a release, and the focus issue's bullet is always meaningful. +4. Rename the existing heading from `## [Unreleased]` to `## [<NEW_VERSION>] - <TODAY>` and add the new bullet at the end of that section's bullet list. +5. Prepend a fresh, empty `## [Unreleased]` section above the just-closed release, with one blank line separating them: + + ```markdown + ## [Unreleased] + + ## [NEW_VERSION] - TODAY + + - …existing bullets from before the promote… + - <new bullet for this issue> (#N) + ``` + +6. Write the change without a confirm prompt (`confirm_changelog_update` is false). Still report what was written. + + +## Conflict resolution — keep both bullet sets + +When an unrelated PR lands on the default branch while this issue is in flight, both branches add a bullet to the **same** `## [Unreleased]` section and git cannot merge it. That is bookkeeping, not a design decision, so it has exactly one documented answer — used by `/iflow-close`'s sync step and by `/iflow-cycle`'s parallel coordinator, so every agent produces the same file. + +**Resolvable only when all of these hold:** + +1. the conflicted file is `HISTORY.md` and **nothing else** is conflicted; +2. every conflict region sits under `## [Unreleased]`; +3. both sides contain **only** list items (plus blank / wrapped continuation lines). + +**Resolution:** keep **all** bullets. The bullets already on the default branch keep their positions; this issue's bullet goes **last** — identical to mode A's append, so a resolved conflict looks exactly like having written the bullet after the other one landed. Byte-identical bullets collapse to one. + +**Refuse and stop** (a human decides) when the conflict touches any other file, an existing bullet was edited or deleted, a heading was renamed, or a `## [Unreleased]` section was promoted to a release section on either side. + +**Fast path:** `issue-flow agent sync-branch --json` applies exactly this rule during the rebase in `/iflow-close` step 6 and aborts on anything else. Prefer it over hand-editing conflict markers. + +## Staging + +When `/iflow-close` reaches its commit step: + +- Stage `HISTORY.md` alongside the issue's other changes so the bullet is in the **same commit** that feeds the PR. +- If a version bump also ran, `HISTORY.md` is staged in the same commit as `pyproject.toml` (and `uv.lock` if it changed). + +## Constraints + +- Read/write only `HISTORY.md` at the project root. Do not touch any other file from this skill. +- Never create `HISTORY.md` from scratch — scaffolding a starter changelog is out of scope for `issue-flow init` / `update`. +- **Timing:** this skill runs only from `/iflow-close` step 3 (before commit / push / PR update). Write even when a draft PR already exists from `/iflow-build` early PR. **Never** propose updating `HISTORY.md` after close has finished or after merge. + + +- Preserve existing formatting conventions (bullet style, sentence case, trailing punctuation). Match the style of the nearest existing entries when in doubt. +- The new bullet's `(#<N>)` suffix is always GitHub issue `#N`, matching the focus issue's number in `.issueflows/01-current-issues/issue<N>_original.md`. diff --git a/.cursor/skills/iflow-init/SKILL.md b/.cursor/skills/iflow-init/SKILL.md new file mode 100644 index 0000000..1b1b8b1 --- /dev/null +++ b/.cursor/skills/iflow-init/SKILL.md @@ -0,0 +1,145 @@ +--- +name: iflow-init +description: >- + Cold-start or check the issue-flow harness: guide issue-flow init when the + scaffold is missing; bootstrap a parent folder of git siblings; point at + update / doctor / iflow-capture when a project scaffold exists. +disable-model-invocation: true +issue-flow-version: 0.4.2a4 +--- + +# issue-flow — harness init (`/iflow-init`) + +Follow this skill to **cold-start or check the issue-flow harness** — the editor-facing counterpart of the CLI's `issue-flow init` and `issue-flow workspace bootstrap`. + +This is **not** the step that pulls a GitHub issue into `.issueflows/`. That is **`/iflow-capture`** (chat: `iflow capture`). `/iflow-init` is **off-path**: `/iflow` never auto-dispatches here. + +This skill is also written to the editor's **user-global** skill dir on `init` / `update` (placement `both`) so `iflow init` works in a folder that has no project scaffold yet. The first machine still needs one CLI `init`/`update` or `uvx issue-flow workspace bootstrap` to plant that global copy. A project-local copy still wins inside a repo. + + +**Invoke:** type `iflow init` in chat, or `/iflow-init` from the slash menu (`iflow-init` also works). + + + + +### MODEL & EXECUTION DIRECTIVE + + +**Profile: economy** — Prioritize speed and token economy over deep reasoning. + +In Cursor: use **Auto** or a fast model before invoking this step. + + + +Keep scope tight to what this step requires. + + + + +## Start directory (before member resolve) + +For this skill, the start dir is `root:` / `-C` if given, else **cwd**. Do **not** run `issue-flow agent resolve` first when cwd looks like a **parent folder of repos** — resolve may pick a workspace default member and hide the parent. The single-project path below still uses the usual resolve order. + +### Resolve project root (multi-root workspaces) + +Before any `git`, `gh`, or `.issueflows/` path operation in this workflow: + +**Resolution order** (stop when unambiguous): + +1. **Explicit hints** in slash input — `root:<path>`, `repo:<folder-basename>` (directory name, e.g. `cellpy-core`), or `repo:owner/name`. +2. **CLI fast path** — `issue-flow agent resolve [-C <start>] [--from-file <active-file>] [--json]`. Use the returned `project_root` and `repo`; pass `-C <project_root>` to other `issue-flow agent …` subcommands. When the answer came from the workspace registry, the payload sets `resolved_via_workspace_default: true`. +3. **Branch context** — exactly one workspace repo whose branch matches `^\d+-` → that root. +4. **Single scaffold** — exactly one `.issueflows/` tree visible in the workspace → that root. +5. **Workspace default** — an `issueflow-workspace.toml` at the workspace root (created with `issue-flow workspace init`) may name a `default` member repo; use it when no scaffold matched above. Tell the user the default was used. +6. **Ambiguous** → **stop and ask**; never guess between sibling repos. + +After resolution, treat the result as `<project_root>` and `<owner/repo>`: + +- **Git:** `git -C <project_root> …` (or `issue-flow agent … -C <project_root>` for supported ops). +- **GitHub:** pass an explicit repo on every `gh` call — never rely on `gh`'s implicit cwd default. For most commands use `--repo <owner/repo>`; **exception:** `gh repo view` takes the repo as a **positional** arg (`gh repo view <owner/repo> …`) and rejects `--repo`. +- **Paths:** all `.issueflows/…` paths are under `<project_root>`. + +When `.issueflows/04-designs-and-guides/multi-repo-workspaces.md` exists, read it for layout and cross-repo guidance. + + +## Package vs scaffold (read first) + +If the user asked to **upgrade** / **latest version** / **update the tool**, +that is the **package**, not this skill's scaffold path: + +1. `uv tool upgrade issue-flow` (or `uv tool install issue-flow` if missing) +2. Then `issue-flow update` (one repo) or `issue-flow workspace update` (parent folder with toml) + +`issue-flow update` alone does **not** upgrade the installed CLI. Full map: + +https://issue-flow.readthedocs.io/how-to/for-agents/ + +Also: https://issue-flow.readthedocs.io/llms.txt + +If they asked to **init globally**, plant user-global `iflow-init` with one +`issue-flow init` / `update` / `workspace bootstrap --yes` on this machine, +then follow the classify steps below. Do not `init` a parent folder of repos. + +## Parent-folder recipe + +When the start dir is a **folder of git sibling repos**, follow this public how-to — do **not** invent a different command order: + +https://issue-flow.readthedocs.io/how-to/workspaces/ + +| Situation | Command | +| --- | --- | +| First time (scaffold members + write toml) | `issue-flow workspace bootstrap --yes --default <name>` | +| Members already have `.issueflows/`; toml only | `issue-flow workspace init --default <name>` | +| Toml exists; refresh skills | `issue-flow workspace update` | + +Show the user those commands (or the how-to URL) when explaining the path. The classify / confirm steps below still gate any `--yes`. + +## Instructions + +1. **Workspace file already present** at the start dir (or `issue-flow agent resolve --json` reports `workspace_root` equal to the start dir): + - Say the workspace already exists. + - Offer `issue-flow workspace update` / per-member `issue-flow update` (same as the how-to). + - Do **not** re-bootstrap unless the user explicitly asks `--force` / re-init. + +2. **Parent-folder / workspace path** — run classify-only: + `issue-flow workspace bootstrap <start> --json` + - If **two or more** children have status `scaffolded` or `unscaffolded` (own-git members): + - Show the classified list (name, status, skip reasons). + - Propose `--default` (first `scaffolded`, else first `unscaffolded`, or ask). + - On **yes**, run + `issue-flow workspace bootstrap <start> --yes --default <name>` + (add `--skip-dep-check` / `--editor <id>` / `--force` only when the user asked). + - After success: remind `/iflow-pick` **per repo** (or open the default member). Stop. + - If fewer than two git members, continue with the single-project path below. + - Never `git init` children; point non-git folders at `/iflow-setup`. + - Never write `.issueflows/` on the parent. + +3. **Single-project detect** under `<project_root>` (now resolve is fine): + - `.issueflows/` present? + - Agent skills present? Prefer the marker `.cursor/skills/iflow-init/SKILL.md` (or any `iflow-*` skill under `.cursor/skills/`). + - Optional: `issue-flow agent resolve -C <project_root> --json` / `issue-flow doctor -C <project_root> --json` when the CLI is on `PATH`. + +4. **Scaffold missing** (no `.issueflows/` and/or no issue-flow skills): + - Tell the user the harness is not initialised. + - Show the exact cold-start command from the project root, e.g. `issue-flow init .` or `uvx issue-flow init .` (add `--editor <id>` when they named an editor). + - If `issue-flow` is on `PATH`, **offer** to run it after a yes; never run without confirm. Do **not** re-implement scaffolding in this skill. + - After a successful init, remind them to pick an issue with `/iflow-pick` or capture one with `/iflow-capture <N>`. + +5. **Harness already present**: + - Say so briefly. + - Point at: + - `issue-flow update .` — refresh templates after upgrading the CLI. + - `issue-flow update --editor <id>` / `/iflow-doctor` — add a missing editor scaffold (`missing_editor_scaffold`). + - **`/iflow-capture <N>`** — pull a GitHub issue into `.issueflows/01-current-issues/`. + - `/iflow-pick` — front door when no issue is chosen yet. + - Do not run `init --force` unless the user explicitly asks to re-scaffold. + +6. **Report** — workspace vs single-project path, missing vs present, commands shown or run, and the next suggested lifecycle step (usually `/iflow-pick` or `/iflow-capture`). + +## Constraints + +- Off-path: never auto-dispatched by `/iflow`. +- Never capture a GitHub issue, write `issue<N>_*.md`, or create an issue branch from this skill — that is `/iflow-capture` / `/iflow-pick`. +- Never invent a second scaffolder; only guide or confirm-run `issue-flow init` / `update` / `workspace bootstrap`. +- Never `init --force`, rewrite `issueflow-workspace.toml`, or delete scaffold files without an explicit user request. +- If a scaffold / update commit is needed, do not leave it unpushed on home default — use a chore branch or a tiny PR (issue #303). diff --git a/.cursor/skills/iflow-issue/SKILL.md b/.cursor/skills/iflow-issue/SKILL.md new file mode 100644 index 0000000..a8b4a53 --- /dev/null +++ b/.cursor/skills/iflow-issue/SKILL.md @@ -0,0 +1,109 @@ +--- +name: iflow-issue +description: >- + Create one well-specified normal GitHub issue, then optionally branch and + run /iflow-capture into the standard lifecycle. +disable-model-invocation: true +issue-flow-version: 0.4.2a4 +--- + +# issue-flow — create a normal issue (`/iflow-issue`) + +Follow this skill to **author and create one well-specified GitHub issue** (a single deliverable), then optionally set up the normal lifecycle (branch + `/iflow-capture` → hand off to `/iflow-plan`). + +Do **not** use this skill from `/iflow`, `/iflow-build`, or `/iflow-close`. `/iflow-issue` is explicit-only because it creates GitHub issues (and optionally branches). + +**Coexists** with: + +- **`/iflow-pick fix`** — one-shot *general-fixes chore bucket* into plan/start. +- **`/iflow-fix`** — iterative small-fixes *session* that stays in a loop. +- **`/iflow-epic`** — staged multi-issue work; use `/iflow-issue` first when the epic **anchor** does not exist yet. +- **`/iflow-split`** — cut an *existing* over-large issue into linked children. Do not use `/iflow-issue` for that. + +## Input + +- **free text** — seed for the issue title and/or short description (e.g. `iflow issue add dry-run flag to doctor`). +- **`epic`** (alone or as a leading token, e.g. `epic Large rewrite`) — epic-anchor mode: title prefixed with `Epic:`, and apply the `epic` label when it exists (`gh label list`). +- **(nothing)** — ask for a one-line intent before drafting. + + +**Invoke:** type `iflow issue` in chat, or `/iflow-issue` from the slash menu (`iflow-issue` also works). + + + + +### MODEL & EXECUTION DIRECTIVE + + +**Profile: reasoning** — Prioritize deep thinking and careful trade-offs over speed or token economy. + +In Cursor: switch to a thinking-capable model before invoking this step (not Auto-only). + + + +Keep scope tight to what this step requires. + + + + +### Resolve project root (multi-root workspaces) + +Before any `git`, `gh`, or `.issueflows/` path operation in this workflow: + +**Resolution order** (stop when unambiguous): + +1. **Explicit hints** in slash input — `root:<path>`, `repo:<folder-basename>` (directory name, e.g. `cellpy-core`), or `repo:owner/name`. +2. **CLI fast path** — `issue-flow agent resolve [-C <start>] [--from-file <active-file>] [--json]`. Use the returned `project_root` and `repo`; pass `-C <project_root>` to other `issue-flow agent …` subcommands. When the answer came from the workspace registry, the payload sets `resolved_via_workspace_default: true`. +3. **Branch context** — exactly one workspace repo whose branch matches `^\d+-` → that root. +4. **Single scaffold** — exactly one `.issueflows/` tree visible in the workspace → that root. +5. **Workspace default** — an `issueflow-workspace.toml` at the workspace root (created with `issue-flow workspace init`) may name a `default` member repo; use it when no scaffold matched above. Tell the user the default was used. +6. **Ambiguous** → **stop and ask**; never guess between sibling repos. + +After resolution, treat the result as `<project_root>` and `<owner/repo>`: + +- **Git:** `git -C <project_root> …` (or `issue-flow agent … -C <project_root>` for supported ops). +- **GitHub:** pass an explicit repo on every `gh` call — never rely on `gh`'s implicit cwd default. For most commands use `--repo <owner/repo>`; **exception:** `gh repo view` takes the repo as a **positional** arg (`gh repo view <owner/repo> …`) and rejects `--repo`. +- **Paths:** all `.issueflows/…` paths are under `<project_root>`. + +When `.issueflows/04-designs-and-guides/multi-repo-workspaces.md` exists, read it for layout and cross-repo guidance. + +## Instructions + +### Phase 1 — draft and create + +1. **Preflight.** Detect the default branch (`gh repo view --json defaultBranchRef -q .defaultBranchRef.name`; fall back to `git symbolic-ref --quiet --short refs/remotes/origin/HEAD`, else `main`). Run `git fetch --prune`. Report current branch + clean/dirty tree (`git status --porcelain`). +2. **Parse input.** If the first token is `epic` (case-insensitive), enable epic-anchor mode and treat the remainder as the seed. Bare `epic` with no remainder → ask for the epic intent. +3. **Draft title + body.** Propose a title and a body with this light structure (not a full `/iflow-plan`): + - **Problem / context** + - **Spec** (what to change) + - **Acceptance criteria** + - **Out of scope** (optional; omit the heading when empty) + Refine with the user until they confirm the text. If the draft is clearly over-large for one PR, **offer** `/iflow-split` (flat parent/child) or `/iflow-epic` (staged) — do **not** auto-create sub-issues. +4. **Create (confirm first).** Show the final title and body (and, in epic-anchor mode, the planned `epic` label when present). On yes: `gh issue create --repo <owner/repo>` (add `--label epic` only when epic-anchor mode is on **and** `gh label list` shows `epic`). Capture number `N`. Set the chat tab title to `Issue <N> <short title>`. Optional labels/milestones other than the epic-anchor label: only if the user asked for them in this turn — do not invent them. + +### Phase 2 — optional lifecycle setup + +5. **Offer branch + init (default path).** Ask whether to start work now. On yes (require a clean tree; if dirty, stop and ask to commit/stash): + - Slug from the title (kebab-case); branch `<N>-<slug>`. Confirm a non-obvious slug. +**Worktree-first start (default, issue #255 / #303).** After the dirty-tree gate and slug confirm — unless the user passed `inplace` / `no worktree`, or ops chose stay-on-current/default: + +1. Home stays on the **default** branch. `git fetch --prune`. Do **not** `git switch -c` on home. +2. Run `issue-flow agent default-sync --json -C <home>`. If `action` is `even` or `ff_only`, `git pull --ff-only`. If home is ahead or diverged, **print** the classification and **still continue** — starting work must not wait for home to be ff-able. +3. `issue-flow agent worktree-add <N> --slug <slug> -C <home> --json` — path is `../<repo>-<N>`. Starts from fetched `origin/<default>`, not local default HEAD. On error, **stop and ask**; never silently fall back to inplace. +4. `issue-flow agent open-workspace <path> --json` (print-only). Tell the user the worktree path. Do **not** ask to open a window. +5. Run `/iflow-capture` (and later plan/build/close) with `-C <worktree-path>`. Continue the session in that folder. +6. Token `inplace` / `no worktree` keeps legacy `git switch -c <N>-<slug>` on home. + + - On a non-default **home** branch → **ask** whether to FF/switch home to default first (required for worktree-add) or use `inplace` from current. + - Run `/iflow-capture` (or the `iflow-capture` skill) for `<N>` with `-C <worktree>` (or home if `inplace`). Do not duplicate its fetch/archive logic. + - **Ask** whether to continue with `/iflow-plan`. Do **not** auto-run it. +6. **Create-only.** If the user declines Phase 2, stop after create. Remind them they can pick it up later with `/iflow-pick` / `/iflow-capture`. + +## Constraints + +- Off-path: never auto-dispatch from `/iflow`, `/iflow-build`, or `/iflow-close`. +- Never create a GitHub issue or branch without explicit confirmation; show what will be created first. +- GitHub only (`gh`); GitLab is not supported. +- Branch off the detected default (or the current branch when chosen); never force-push or delete branches from this skill. +- Delegate local capture to `/iflow-capture`; do not write `issue<N>_plan.md` here. +- Do not merge with `/iflow-fix` or `/iflow-pick fix` — different intents. diff --git a/.cursor/skills/iflow-ops/SKILL.md b/.cursor/skills/iflow-ops/SKILL.md new file mode 100644 index 0000000..251c517 --- /dev/null +++ b/.cursor/skills/iflow-ops/SKILL.md @@ -0,0 +1,77 @@ +--- +name: iflow-ops +description: >- + Run ops / no-PR work for the focus issue (staging→prod, flag flips, external + deploys), then finish via /iflow-close ops. +disable-model-invocation: true +issue-flow-version: 0.4.2a4 +--- + +# issue-flow — ops / no-PR (`/iflow-ops`) + +Follow this skill for **work that does not deserve a PR**: promote staging→production, flip a feature flag, run an external deploy checklist, tag-only release steps with no issue-branch product diff, and similar ops. + +Do **not** use this for product code changes — those go through the normal lifecycle (or `/iflow-yolo` when small). + + +**Invoke:** type `iflow ops` in chat, or `/iflow-ops` from the slash menu (`iflow-ops` also works). + + + + +### MODEL & EXECUTION DIRECTIVE + + +**Profile: economy** — Prioritize speed and token economy over deep reasoning. + +In Cursor: use **Auto** or a fast model before invoking this step. + + + +Keep scope tight to what this step requires. + + + + +### Resolve project root (multi-root workspaces) + +Before any `git`, `gh`, or `.issueflows/` path operation in this workflow: + +**Resolution order** (stop when unambiguous): + +1. **Explicit hints** in slash input — `root:<path>`, `repo:<folder-basename>` (directory name, e.g. `cellpy-core`), or `repo:owner/name`. +2. **CLI fast path** — `issue-flow agent resolve [-C <start>] [--from-file <active-file>] [--json]`. Use the returned `project_root` and `repo`; pass `-C <project_root>` to other `issue-flow agent …` subcommands. When the answer came from the workspace registry, the payload sets `resolved_via_workspace_default: true`. +3. **Branch context** — exactly one workspace repo whose branch matches `^\d+-` → that root. +4. **Single scaffold** — exactly one `.issueflows/` tree visible in the workspace → that root. +5. **Workspace default** — an `issueflow-workspace.toml` at the workspace root (created with `issue-flow workspace init`) may name a `default` member repo; use it when no scaffold matched above. Tell the user the default was used. +6. **Ambiguous** → **stop and ask**; never guess between sibling repos. + +After resolution, treat the result as `<project_root>` and `<owner/repo>`: + +- **Git:** `git -C <project_root> …` (or `issue-flow agent … -C <project_root>` for supported ops). +- **GitHub:** pass an explicit repo on every `gh` call — never rely on `gh`'s implicit cwd default. For most commands use `--repo <owner/repo>`; **exception:** `gh repo view` takes the repo as a **positional** arg (`gh repo view <owner/repo> …`) and rejects `--repo`. +- **Paths:** all `.issueflows/…` paths are under `<project_root>`. + +When `.issueflows/04-designs-and-guides/multi-repo-workspaces.md` exists, read it for layout and cross-repo guidance. + + +## Instructions + +1. **Resolve the issue.** Prefer the focus issue under `.issueflows/01-current-issues/`. If missing, take a number/URL from the command input and run `/iflow-capture` first. Stop if still ambiguous. + +2. **Preflight.** Prefer `issue-flow agent preflight --json` (`clean` / `dirty_paths` / `issueflows_only` / branch). Else `git fetch --prune` + `git status --porcelain`. + - **Product-code dirty** (any path outside `.issueflows/`) → **stop**. Ops path refuses silent no-PR when product files changed; use normal `/iflow-close` or stash/discard. + - **Issueflows-only dirty** or clean → continue. + - **Default branch OK** for ops (unlike yolo). Optional issue branch: ask create `<N>-<slug>` vs stay on current/default when not already on a matching issue branch. + +3. **Execute the ops work.** Follow the issue body / acceptance criteria (external CLIs, deploy consoles, flag tools). Confirm each risky step with the user. Record what ran in `issue<N>_status.md` (dated bullets under **What's done**). + +4. **Hand off to close.** Follow `/iflow-close ops` (aliases `nopr` / `no-pr` also accepted by close). Do **not** duplicate archive / `gh issue close` logic here. Forward any `log "..."` text the user supplied. + +## Constraints + +- Off-path: never auto-dispatched by `/iflow`, `/iflow-build`, or `/iflow-close`. +- Never open a PR from this skill. +- Never force-push or delete branches. +- If unique unpushed product commits appear on the branch, **abort** and send the user to normal close — ops cannot skip review for those. +- When both `ops` and `yolo` labels are present, **ops wins** (announce the conflict). diff --git a/.cursor/skills/iflow-pause/SKILL.md b/.cursor/skills/iflow-pause/SKILL.md new file mode 100644 index 0000000..d612fdf --- /dev/null +++ b/.cursor/skills/iflow-pause/SKILL.md @@ -0,0 +1,80 @@ +--- +name: iflow-pause +description: >- + Park work on the current issue without closing it: update status, move + the group to 02-partly-solved-issues/, optional WIP commit. +disable-model-invocation: true +issue-flow-version: 0.4.2a4 +--- + +# issue-flow — issue pause (`/iflow-pause`) + +Follow this skill to **park work on the current issue** without closing it. The issue is **not** done — this is not `/iflow-close`. + + +**Invoke:** type `iflow pause` in chat, or `/iflow-pause` from the slash menu (`iflow-pause` also works). + + + + +### MODEL & EXECUTION DIRECTIVE + + +**Profile: economy** — Prioritize speed and token economy over deep reasoning. + +In Cursor: use **Auto** or a fast model before invoking this step. + + + +Keep scope tight to what this step requires. + + + + +### Resolve project root (multi-root workspaces) + +Before any `git`, `gh`, or `.issueflows/` path operation in this workflow: + +**Resolution order** (stop when unambiguous): + +1. **Explicit hints** in slash input — `root:<path>`, `repo:<folder-basename>` (directory name, e.g. `cellpy-core`), or `repo:owner/name`. +2. **CLI fast path** — `issue-flow agent resolve [-C <start>] [--from-file <active-file>] [--json]`. Use the returned `project_root` and `repo`; pass `-C <project_root>` to other `issue-flow agent …` subcommands. When the answer came from the workspace registry, the payload sets `resolved_via_workspace_default: true`. +3. **Branch context** — exactly one workspace repo whose branch matches `^\d+-` → that root. +4. **Single scaffold** — exactly one `.issueflows/` tree visible in the workspace → that root. +5. **Workspace default** — an `issueflow-workspace.toml` at the workspace root (created with `issue-flow workspace init`) may name a `default` member repo; use it when no scaffold matched above. Tell the user the default was used. +6. **Ambiguous** → **stop and ask**; never guess between sibling repos. + +After resolution, treat the result as `<project_root>` and `<owner/repo>`: + +- **Git:** `git -C <project_root> …` (or `issue-flow agent … -C <project_root>` for supported ops). +- **GitHub:** pass an explicit repo on every `gh` call — never rely on `gh`'s implicit cwd default. For most commands use `--repo <owner/repo>`; **exception:** `gh repo view` takes the repo as a **positional** arg (`gh repo view <owner/repo> …`) and rejects `--repo`. +- **Paths:** all `.issueflows/…` paths are under `<project_root>`. + +When `.issueflows/04-designs-and-guides/multi-repo-workspaces.md` exists, read it for layout and cross-repo guidance. + +## Instructions + +1. **Find the focus issue.** In `.issueflows/01-current-issues/`, identify the `issue<N>_*` group. If multiple groups exist and the focus is ambiguous, ask. If none exist, **stop** and say there is nothing to pause. + +2. **Update `issue<N>_status.md`.** Create or update it under `.issueflows/01-current-issues/` with: + - `- [ ] Done` (must remain **unchecked** — a pause is not a close). + - **Done so far** — short bullets of what has landed or been tried. + - **Remaining work** — explicit next steps so work can resume later. + - **Paused on** — date, branch name, any blockers. + + Preserve earlier user-written content; only add or update these sections. If the user passed a short note after `/iflow-pause`, use it verbatim as the **Remaining work** text. + +3. **Move the issue group.** Move every `issue<N>_*` file from `.issueflows/01-current-issues/` to `.issueflows/02-partly-solved-issues/`. Report each move. + +4. **Working-tree guard.** Run `git status --porcelain`. Report what is dirty, then offer — as **one** consolidated prompt — any combination of: + - **WIP commit** — stage tracked changes and commit `WIP: pause issue #<N> — <short note>`. List untracked files separately and ask before including them. + - **Switch to default branch** — detect default (prefer `gh repo view --json defaultBranchRef -q .defaultBranchRef.name`, else `git symbolic-ref --quiet --short refs/remotes/origin/HEAD`, else `main`) and run `git switch <default>`. Only after the WIP commit if the tree is dirty. + - **Stay put** — leave branch and working tree untouched. + +5. **Report.** Summarize the status update, the issue-group moves, working-tree actions taken, and remind the user how to resume (running `/iflow-capture <N>` re-opens the archived issue after its archived-issue guard, or they can simply switch back to the issue branch). + +## Constraints + +- The focus issue's `- [ ] Done` checkbox **must** stay unchecked. `/iflow-pause` is not `/iflow-close`. +- Do not delete branches. Do not `git reset`, `git stash drop`, or force-push. +- Do not open a PR. Do not bump versions. Do not run tests. diff --git a/.cursor/skills/iflow-pick/SKILL.md b/.cursor/skills/iflow-pick/SKILL.md new file mode 100644 index 0000000..6ed88f3 --- /dev/null +++ b/.cursor/skills/iflow-pick/SKILL.md @@ -0,0 +1,135 @@ +--- +name: iflow-pick +description: >- + Front door: choose the next issue, create the issue branch, and run + /iflow-capture. +disable-model-invocation: true +issue-flow-version: 0.4.2a4 +--- + +# issue-flow — pick next issue (`/iflow-pick`) + +Follow this skill to help the user **choose what to work on next** (parked work first, else ranked open GitHub issues) and get set up to start. + +Do **not** use this skill from `/iflow`, `/iflow-build`, or `/iflow-close`. `/iflow-pick` is explicit-only because it creates GitHub issues and branches. + +## Input + +- **(nothing)** — survey candidates and ask which to pick. +- **`fix`** — create a **new** general-fixes GitHub issue (a fresh one every time) and use it. +- **`label:<L>`** — **hard filter**: shortlist only open issues that carry GitHub label `<L>` (case-insensitive; strip whitespace after the colon). Compatible with `noplan` / `root:` / `repo:`. Empty after filter → stop (“no open issues with label `<L>`”). Never auto-pick even when only one match. For batch processing the same filter, use `/iflow-cycle label:<L>` (or `/iflow-cycle yolo` for the configured yolo trigger). +- **a hint** (milestone / topic) — soft-bias the candidate ranking when `label:<L>` is **absent**. Free-form text that happens to name a label is **not** a hard filter — use the `label:` token. +- **`noplan`** — skip the `auto_plan` chain for this run (ask before `/iflow-plan` even when `auto_plan` is true). + + +**Invoke:** type `iflow pick` in chat, or `/iflow-pick` from the slash menu (`iflow-pick` also works). + + + + +### MODEL & EXECUTION DIRECTIVE + + +**Profile: reasoning** — Prioritize deep thinking and careful trade-offs over speed or token economy. + +In Cursor: switch to a thinking-capable model before invoking this step (not Auto-only). + + + +Keep scope tight to what this step requires. + + + + +### Resolve project root (multi-root workspaces) + +Before any `git`, `gh`, or `.issueflows/` path operation in this workflow: + +**Resolution order** (stop when unambiguous): + +1. **Explicit hints** in slash input — `root:<path>`, `repo:<folder-basename>` (directory name, e.g. `cellpy-core`), or `repo:owner/name`. +2. **CLI fast path** — `issue-flow agent resolve [-C <start>] [--from-file <active-file>] [--json]`. Use the returned `project_root` and `repo`; pass `-C <project_root>` to other `issue-flow agent …` subcommands. When the answer came from the workspace registry, the payload sets `resolved_via_workspace_default: true`. +3. **Branch context** — exactly one workspace repo whose branch matches `^\d+-` → that root. +4. **Single scaffold** — exactly one `.issueflows/` tree visible in the workspace → that root. +5. **Workspace default** — an `issueflow-workspace.toml` at the workspace root (created with `issue-flow workspace init`) may name a `default` member repo; use it when no scaffold matched above. Tell the user the default was used. +6. **Ambiguous** → **stop and ask**; never guess between sibling repos. + +After resolution, treat the result as `<project_root>` and `<owner/repo>`: + +- **Git:** `git -C <project_root> …` (or `issue-flow agent … -C <project_root>` for supported ops). +- **GitHub:** pass an explicit repo on every `gh` call — never rely on `gh`'s implicit cwd default. For most commands use `--repo <owner/repo>`; **exception:** `gh repo view` takes the repo as a **positional** arg (`gh repo view <owner/repo> …`) and rejects `--repo`. +- **Paths:** all `.issueflows/…` paths are under `<project_root>`. + +When `.issueflows/04-designs-and-guides/multi-repo-workspaces.md` exists, read it for layout and cross-repo guidance. + +## Instructions + +### Phase 1 — choose the issue + +1. **Preflight.** Detect the default branch (`gh repo view --json defaultBranchRef -q .defaultBranchRef.name`; fall back to `git symbolic-ref --quiet --short refs/remotes/origin/HEAD`, else `main`). Run `git fetch --prune`. Report current branch + clean/dirty tree (`git status --porcelain`). +2. **`fix` shortcut.** If the user passed `fix`, skip selection and go to step 5 (create a new general-fixes issue), then Phase 2. +3. **Source candidates** (precedence): + - **Parse `label:<L>`** when present (case-insensitive label name after the colon). Announce the active filter in the shortlist header. + - **Parked work first** — list `issue<n>_*` groups in `.issueflows/02-partly-solved-issues/` as the primary candidates (already-started work to finish first). When `label:<L>` is active, keep only parked issues that carry `<L>` (`gh issue view <n> --json labels` when unclear). + - **Active epic next** — if an epic plan under `.issueflows/05-epics/` has open issues (or the user named one, e.g. `epic 144`), prefer its **current stage's unblocked issues**. Use the fast path `issue-flow agent epic-status <N> --json` when the CLI is on `PATH` — its `next_candidates` are exactly the open, dependency-satisfied issues of the current stage. Surface those at the top of the shortlist so an epic advances stage by stage instead of stalling. When `label:<L>` is active, keep only epic candidates that carry `<L>`. + - **Else GitHub** — `gh issue list --state open --json number,title,labels,milestone,updatedAt` (add `--repo owner/repo` if ambiguous). When `label:<L>` is active, add `--label <L>` (hard filter). Drop issues already captured under `01-current-issues/`, `02-partly-solved-issues/`, or `03-solved-issues/`. If the filtered set is empty, **stop** with “no open issues with label `<L>`.” +4. **Rank and present.** Rank by **epic membership** (an active epic's current-stage `next_candidates` first) + **milestone** (nearest/active, honour any hint) + **labels** (match recent work / soft hint when no `label:` filter) + **topical similarity** to recently solved issues (skim `.issueflows/03-solved-issues/` and recent branch names). Show a numbered shortlist (~3–7) with number, title, labels, milestone, and (for epic issues) the epic + stage, and **ask the user to confirm** the pick or override. Never pick silently — even when the filtered shortlist has a single entry. +5. **Create a `fix` issue (only when requested).** Use `gh issue create` (e.g. `chore: general fixes`), confirm title/body first, capture the new number. A fresh issue is created each time — never reuse an existing open general-fixes issue. +6. **Over-large issue (offer only).** If the chosen issue is too big for one PR, **mention** `/iflow-split` (flat parent/child) or `/iflow-epic` (staged) and ask. Default is proceed with the whole issue. Do **not** create children here. + +7. **Label-driven ops flow.** If the chosen issue carries the **`ops`** label (case-insensitive), announce it and fold `/iflow-ops` into the pick confirmation (one prompt: optional branch vs stay on default + ops work + `close ops`). On yes, run Phase 2 (ask whether to create `<N>-<slug>` or stay on current/default — default branch is allowed for ops) then follow the `iflow-ops` skill **instead of** Phase 3 / yolo. If the issue also carries **`yolo`**, **ops wins** — announce the conflict. Configurable via `label_flows` / `ops_label` under `[issueflow]` in `.issueflows/config.toml` (re-run `issue-flow update` after changing). + + +8. **Label-driven yolo flow.** If the chosen issue carries the **`yolo`** label (case-insensitive) **and** was not already routed to ops above, announce it and fold `/iflow-yolo`'s consolidated confirm into the pick confirmation (one prompt: branch + full `capture → plan → build → close yolo` chain). On yes, run Phase 2 then follow the `iflow-yolo` skill **instead of** the Phase 3 handoff — its preflight still applies, but do not re-ask its confirm. Configurable via `label_flows` / `yolo_label` under `[issueflow]` in `.issueflows/config.toml` (re-run `issue-flow update` after changing). + + + +### Phase 2 — create the branch + +1. **Working-tree gate** — Prefer `issue-flow agent preflight --json` (fields + `clean`, `dirty_paths`, `issueflows_only`); else `git status --porcelain` + and treat paths as issueflows-only when every path is under + `.issueflows/`. + - **Clean** — continue. + - **Issueflows-only dirty** (typical after `/iflow-doctor` repair) — one + consolidated prompt with **commit housekeeping on the current branch** as + the **recommended default** (message pattern: + `chore: doctor housekeeping — archive/sweep .issueflows groups`, + or a short edit). Alternatives: stash / abort. On commit: stage **only** + those paths, commit, **no push**, then continue. Do not branch on top of + the dirty tree. + - **Mixed / code dirty** — **stop**; list non-`.issueflows/` paths; + ask commit / stash / abort. Do **not** auto-offer “commit everything”. +2. **Issue worktree (default)** — confirm a non-obvious slug (`<N>-<short-slug>`). +**Worktree-first start (default, issue #255 / #303).** After the dirty-tree gate and slug confirm — unless the user passed `inplace` / `no worktree`, or ops chose stay-on-current/default: + +1. Home stays on the **default** branch. `git fetch --prune`. Do **not** `git switch -c` on home. +2. Run `issue-flow agent default-sync --json -C <home>`. If `action` is `even` or `ff_only`, `git pull --ff-only`. If home is ahead or diverged, **print** the classification and **still continue** — starting work must not wait for home to be ff-able. +3. `issue-flow agent worktree-add <N> --slug <slug> -C <home> --json` — path is `../<repo>-<N>`. Starts from fetched `origin/<default>`, not local default HEAD. On error, **stop and ask**; never silently fall back to inplace. +4. `issue-flow agent open-workspace <path> --json` (print-only). Tell the user the worktree path. Do **not** ask to open a window. +5. Run `/iflow-capture` (and later plan/build/close) with `-C <worktree-path>`. Continue the session in that folder. +6. Token `inplace` / `no worktree` keeps legacy `git switch -c <N>-<slug>` on home. + + **Ops exception:** when Phase 1 confirmed ops routing, ask whether to create the issue worktree/branch or stay on current/default; default branch is allowed (no worktree). +3. **Run `/iflow-capture`** for the now-known `<N>` by following the `iflow-capture` skill. Do not duplicate its fetch/archive logic. + +### Phase 3 — hand off + + +1. **Chain into `/iflow-plan`** (this project has `auto_plan = true`). After Phase 2, follow the `iflow-plan` skill immediately — briefly note that `auto_plan` chained the handoff. Trailing **`noplan`** (or the user declining on confirm) skips the chain once and falls back to asking. + + +2. **Exception (ops):** when the `ops`-label routing was confirmed in Phase 1, skip this handoff — the `iflow-ops` skill takes over after capture. + + +3. **Exception (yolo):** when the `yolo`-label routing was confirmed in Phase 1 (and ops did not win), skip this handoff — the `iflow-yolo` chain (which includes `/iflow-capture`) takes over after the branch is created. + + +## Constraints + +- Off-path: never auto-dispatch from `/iflow`, `/iflow-build`, or `/iflow-close`. +- Never create a GitHub issue or branch without explicit confirmation; show what will be created first. +- Branch off the detected default; never force-push or delete branches from this skill. +- Over-large splits are **offer-only**: never create child issues from this skill. Point at `/iflow-split` (flat) or `/iflow-epic` (staged). +- Delegate issue capture to `/iflow-capture` rather than re-implementing it. +- `auto_plan` only skips the post-init pause; pick confirm and label routing stay gated. diff --git a/.cursor/skills/iflow-plan/SKILL.md b/.cursor/skills/iflow-plan/SKILL.md new file mode 100644 index 0000000..945689b --- /dev/null +++ b/.cursor/skills/iflow-plan/SKILL.md @@ -0,0 +1,113 @@ +--- +name: iflow-plan +description: >- + Draft a structured plan in issue<N>_plan.md and get explicit user + confirmation before any implementation starts. +disable-model-invocation: true +issue-flow-version: 0.4.2a4 +--- + +# issue-flow — issue plan (`/iflow-plan`) + +Follow this skill to **design the approach** for the focus issue before touching code, and to get the plan confirmed ahead of `/iflow-build`. + + +**Invoke:** type `iflow plan` in chat, or `/iflow-plan` from the slash menu (`iflow-plan` also works). + + + + +### MODEL & EXECUTION DIRECTIVE + + +**Profile: reasoning** — Prioritize deep thinking and careful trade-offs over speed or token economy. + +In Cursor: switch to a thinking-capable model before invoking this step (not Auto-only). + + + +Keep scope tight to what this step requires. + + + + +### Resolve project root (multi-root workspaces) + +Before any `git`, `gh`, or `.issueflows/` path operation in this workflow: + +**Resolution order** (stop when unambiguous): + +1. **Explicit hints** in slash input — `root:<path>`, `repo:<folder-basename>` (directory name, e.g. `cellpy-core`), or `repo:owner/name`. +2. **CLI fast path** — `issue-flow agent resolve [-C <start>] [--from-file <active-file>] [--json]`. Use the returned `project_root` and `repo`; pass `-C <project_root>` to other `issue-flow agent …` subcommands. When the answer came from the workspace registry, the payload sets `resolved_via_workspace_default: true`. +3. **Branch context** — exactly one workspace repo whose branch matches `^\d+-` → that root. +4. **Single scaffold** — exactly one `.issueflows/` tree visible in the workspace → that root. +5. **Workspace default** — an `issueflow-workspace.toml` at the workspace root (created with `issue-flow workspace init`) may name a `default` member repo; use it when no scaffold matched above. Tell the user the default was used. +6. **Ambiguous** → **stop and ask**; never guess between sibling repos. + +After resolution, treat the result as `<project_root>` and `<owner/repo>`: + +- **Git:** `git -C <project_root> …` (or `issue-flow agent … -C <project_root>` for supported ops). +- **GitHub:** pass an explicit repo on every `gh` call — never rely on `gh`'s implicit cwd default. For most commands use `--repo <owner/repo>`; **exception:** `gh repo view` takes the repo as a **positional** arg (`gh repo view <owner/repo> …`) and rejects `--repo`. +- **Paths:** all `.issueflows/…` paths are under `<project_root>`. + +When `.issueflows/04-designs-and-guides/multi-repo-workspaces.md` exists, read it for layout and cross-repo guidance. + + +## Optional tokens (command input) + +- **`nobuild`** — skip the `auto_build` chain for this run (after Accept, ask / tell the user to run `/iflow-build` even when `auto_build` is true). + +## Instructions + +> **CLI fast path (optional).** If the `issue-flow` CLI is on `PATH`, run +> `issue-flow agent preflight` for the branch status preflight (step 2). The +> CLI is optional: if it is missing or errors, fall back to the manual commands +> below. (`issue-flow` is only present when the user installed it, e.g. +> `uv tool install issue-flow`.) + +1. **Find the focus issue.** Look in `.issueflows/01-current-issues/` for `issue<N>_original.md`. If it is missing or multiple groups are ambiguous, **stop** and ask. Suggest `/iflow-capture` first. + +2. **Branch status preflight** (non-destructive). Detect the default branch (prefer `gh repo view --json defaultBranchRef -q .defaultBranchRef.name`, else `git symbolic-ref --quiet --short refs/remotes/origin/HEAD`, else `main`). Run `git fetch --prune`. Report current branch, clean/dirty working tree, and ahead/behind vs `origin/<default>`. If on the default branch, suggest creating an issue branch (`git switch -c <N>-<short-slug>`) but do **not** auto-run it — planning itself does not require a branch switch. + +3. **Read context.** Load `issue<N>_original.md` and any existing `issue<N>_status.md`. If `.issueflows/04-designs-and-guides/this-project.md` exists, read it for project-specific context, then skim `.issueflows/04-designs-and-guides/` for relevant design docs. + +4. **Prior-art discovery** (before drafting the plan): + - **Toolbox:** Skim `.issueflows/00-tools/` (start with its `README.md` index) for an existing helper that already does part of the work, so the plan reuses it instead of proposing a new script. + - **Graph (optional):** If `graphify-out/GRAPH_REPORT.md` exists, skim **God Nodes**, **Communities**, and **Suggested Questions** whose names touch the affected area; note community numbers. If absent, skip (grep-only is fine). + - **Grep:** Search for sibling helpers / functions adjacent to the new work (domain prefixes like `filter_*`, `remove_*`, or names from the issue / graph). + - **Record:** Under **`## Constraints`**, add **`### Prior art`** listing each hit (function + module, convention, mirror / coexist / migrate later). If nothing relevant: `- None found (toolbox + grep + graph checked).` + - **Strong overlap:** Put merge-vs-coexist decisions in **`## Open questions`**, not silent choices in Approach. + +5. **Explore read-only** — search code, read files most likely to change, check existing tests; keep research proportional to the issue. + + +5a. **Grill the approach** (planning interview). The [`grill-me`](../grill-me/SKILL.md) skill is available to stress-test the approach before drafting: ask the user to "grill me" (or turn it on by default with `grill_me_default = true` in `.issueflows/config.toml`). It interviews one question at a time until every decision branch is resolved, then feeds the conclusions into the plan. + + +6. **Write `issue<N>_plan.md`** under `.issueflows/01-current-issues/` with these sections: + - **Goal** — one or two sentences. + - **Constraints** — project rules, back-compat, scope limits; include **`### Prior art`** (from step 4). + - **Approach** — concrete design, data flow, ordering. + - **Files to touch** — path + what changes for each. + - **Test strategy** — the project's documented test command (e.g. `uv run pytest`, or `pytest` inside the activated conda env) and any new tests. + - **Open questions** — anything that needs the user's call before coding. + + Keep it terse but specific. Use markdown links to files when useful. + +7. **Scope check.** If the plan is broad (many unrelated files, mixes refactors with feature work, multiple independent deliverables), propose `/iflow-split` (flat 2–5 children) or `/iflow-epic` (staged) before finalizing. Do not create children from this skill. + +8. **Confirm with the user.** Present the plan and **stop**. Accept one of: **Accept** (ready for `/iflow-build`), **Revise** (update `issue<N>_plan.md` in place and re-confirm), or **Abort**. + + On **Accept** (and no trailing **`nobuild`**), follow the `iflow-build` skill immediately — briefly note that `auto_build` chained the handoff. Still write no code *before* Accept. With **`nobuild`**, or when the user only wants to park the accepted plan, tell them to run `/iflow-build` later instead of chaining. + + +9. **Conflict on existing `issue<N>_plan.md`.** Do not overwrite silently. Offer: update in place (after review), keep both (`issue<N>_plan.v2.md`), or leave as is. + +## Constraints + +- `/iflow-plan` is **read-only on source code** until Accept. The only file it writes before Accept is `.issueflows/01-current-issues/issue<N>_plan.md`. +- Do not move files between `01-` / `02-` / `03-` folders from `/iflow-plan`. +- Do not run tests or package managers from planning itself; that belongs to `/iflow-build` and `/iflow-close`. + +- `auto_build` only skips the post-Accept pause; Accept / Revise / Abort stay gated. Trailing `nobuild` skips the chain once. + diff --git a/.cursor/skills/iflow-pr-sync/SKILL.md b/.cursor/skills/iflow-pr-sync/SKILL.md new file mode 100644 index 0000000..d6b8647 --- /dev/null +++ b/.cursor/skills/iflow-pr-sync/SKILL.md @@ -0,0 +1,106 @@ +--- +name: iflow-pr-sync +description: >- + Refresh open PR heads onto the default branch after another merge left them + DIRTY (usually HISTORY.md). Uses sync-branch keep-both + force-with-lease. +disable-model-invocation: true +issue-flow-version: 0.4.2a4 +--- + +# issue-flow — PR queue sync (`/iflow-pr-sync`) + +Follow this skill when **one or more open PRs need updating** after another PR +merged — typically `mergeable: CONFLICTING` / `mergeStateStatus: DIRTY` because +both sides edited `HISTORY.md`. + +Do **not** use this from `/iflow`. Off-path only. Sibling of `/iflow-cleanup` +(post-merge local hygiene) and of `issue-flow agent sync-branch` (single branch). + + +**Invoke:** type `iflow pr-sync` in chat, or `/iflow-pr-sync` from the slash menu (`iflow-pr-sync` also works). + + + + +### MODEL & EXECUTION DIRECTIVE + + +**Profile: economy** — Prioritize speed and token economy over deep reasoning. + +In Cursor: use **Auto** or a fast model before invoking this step. + + + +Keep scope tight to what this step requires. + + + + +### Resolve project root (multi-root workspaces) + +Before any `git`, `gh`, or `.issueflows/` path operation in this workflow: + +**Resolution order** (stop when unambiguous): + +1. **Explicit hints** in slash input — `root:<path>`, `repo:<folder-basename>` (directory name, e.g. `cellpy-core`), or `repo:owner/name`. +2. **CLI fast path** — `issue-flow agent resolve [-C <start>] [--from-file <active-file>] [--json]`. Use the returned `project_root` and `repo`; pass `-C <project_root>` to other `issue-flow agent …` subcommands. When the answer came from the workspace registry, the payload sets `resolved_via_workspace_default: true`. +3. **Branch context** — exactly one workspace repo whose branch matches `^\d+-` → that root. +4. **Single scaffold** — exactly one `.issueflows/` tree visible in the workspace → that root. +5. **Workspace default** — an `issueflow-workspace.toml` at the workspace root (created with `issue-flow workspace init`) may name a `default` member repo; use it when no scaffold matched above. Tell the user the default was used. +6. **Ambiguous** → **stop and ask**; never guess between sibling repos. + +After resolution, treat the result as `<project_root>` and `<owner/repo>`: + +- **Git:** `git -C <project_root> …` (or `issue-flow agent … -C <project_root>` for supported ops). +- **GitHub:** pass an explicit repo on every `gh` call — never rely on `gh`'s implicit cwd default. For most commands use `--repo <owner/repo>`; **exception:** `gh repo view` takes the repo as a **positional** arg (`gh repo view <owner/repo> …`) and rejects `--repo`. +- **Paths:** all `.issueflows/…` paths are under `<project_root>`. + +When `.issueflows/04-designs-and-guides/multi-repo-workspaces.md` exists, read it for layout and cross-repo guidance. + + +## Input + +- **(nothing)** — refresh every open PR GitHub marks as needing update (DIRTY / + BEHIND / CONFLICTING). +- **PR numbers** — e.g. `/iflow-pr-sync 259 261` — only those heads. +- **`dry-run` / `dryrun`** — list candidates; do not sync or push. +- **`nopush` / `no-push`** — sync locally but do not push. +- **`all`** — every open PR, not only dirty ones (rare). + +## Instructions + +1. **Preflight.** Resolve `<project_root>` / `<owner/repo>`. Prefer standing on + the **default** branch with a clean home tree (worktrees are used for each + head). `git fetch --prune`. +2. **List candidates.** Prefer CLI: + ```bash + issue-flow agent pr-sync --dry-run --json -C <project_root> + # or with numbers: + issue-flow agent pr-sync 259 261 --dry-run --json -C <project_root> + ``` + Show the user: PR number, head branch, mergeable / mergeStateStatus, URL. +3. **Confirm once.** Consolidated yes/no listing every head that will be + rebased (or merged) onto `origin/<default>` and force-with-lease pushed. + Decline → stop; nothing rewritten. +4. **Run.** On yes: + ```bash + issue-flow agent pr-sync [numbers…] --json -C <project_root> + ``` + Honour trailing `nopush` / `dry-run` / `all` as flags (`--no-push`, + `--dry-run`, `--all-open`). Default is `--fail-fast`: first non-HISTORY / + non-keep-both conflict stops the batch and leaves later PRs untouched. +5. **Report.** Per PR: synced / pushed / changelog_resolved / failure notes. + Remind that CI must re-run on rewritten heads. Do **not** auto-merge. +6. **When to offer.** After `/iflow-cleanup` when other open PRs remain dirty; + after `/iflow-yolo` / `/iflow-close` merge when siblings are open; whenever + the user says a PR “needs update” and the only conflict is changelog-shaped. + +## Constraints + +- Off-path; never auto-dispatch from `/iflow`. +- Never bare `--force`; only `--force-with-lease` via the CLI. +- Never `--admin` merge; never skip required checks. +- Non-changelog / heading-promote conflicts → stop that head (and the batch + under fail-fast); human decides. +- Prevention (`defer_changelog`) is separate — see + `.issueflows/04-designs-and-guides/pr-queue-sync.md`. diff --git a/.cursor/skills/iflow-review/SKILL.md b/.cursor/skills/iflow-review/SKILL.md new file mode 100644 index 0000000..68cef45 --- /dev/null +++ b/.cursor/skills/iflow-review/SKILL.md @@ -0,0 +1,138 @@ +--- +name: iflow-review +description: >- + Review open GitHub issues and apply labels (extendable kinds; v1: yolo). +disable-model-invocation: true +issue-flow-version: 0.4.2a4 +--- + +# issue-flow — review and label issues (`/iflow-review`) + +Follow this skill to **review open GitHub issues and apply labels**. It is +extendable by review *kind*; v1 supports **`yolo`** only (apply the configured +`yolo` label to issues that pass the yolo-fitness judgment). + +Do **not** auto-dispatch from `/iflow`, `/iflow-build`, or `/iflow-close`. Off-path +only. Do **not** create new GitHub issues here (use `/iflow-issue`, +`/iflow-pick fix`, or `/iflow-epic … publish`). Do **not** remove labels in v1. + + +**Invoke:** type `iflow review` in chat, or `/iflow-review` from the slash menu (`iflow-review` also works). + + + + +### MODEL & EXECUTION DIRECTIVE + + +**Profile: reasoning** — Prioritize deep thinking and careful trade-offs over speed or token economy. + +In Cursor: switch to a thinking-capable model before invoking this step (not Auto-only). + + + +Keep scope tight to what this step requires. + + + + +### Resolve project root (multi-root workspaces) + +Before any `git`, `gh`, or `.issueflows/` path operation in this workflow: + +**Resolution order** (stop when unambiguous): + +1. **Explicit hints** in slash input — `root:<path>`, `repo:<folder-basename>` (directory name, e.g. `cellpy-core`), or `repo:owner/name`. +2. **CLI fast path** — `issue-flow agent resolve [-C <start>] [--from-file <active-file>] [--json]`. Use the returned `project_root` and `repo`; pass `-C <project_root>` to other `issue-flow agent …` subcommands. When the answer came from the workspace registry, the payload sets `resolved_via_workspace_default: true`. +3. **Branch context** — exactly one workspace repo whose branch matches `^\d+-` → that root. +4. **Single scaffold** — exactly one `.issueflows/` tree visible in the workspace → that root. +5. **Workspace default** — an `issueflow-workspace.toml` at the workspace root (created with `issue-flow workspace init`) may name a `default` member repo; use it when no scaffold matched above. Tell the user the default was used. +6. **Ambiguous** → **stop and ask**; never guess between sibling repos. + +After resolution, treat the result as `<project_root>` and `<owner/repo>`: + +- **Git:** `git -C <project_root> …` (or `issue-flow agent … -C <project_root>` for supported ops). +- **GitHub:** pass an explicit repo on every `gh` call — never rely on `gh`'s implicit cwd default. For most commands use `--repo <owner/repo>`; **exception:** `gh repo view` takes the repo as a **positional** arg (`gh repo view <owner/repo> …`) and rejects `--repo`. +- **Paths:** all `.issueflows/…` paths are under `<project_root>`. + +When `.issueflows/04-designs-and-guides/multi-repo-workspaces.md` exists, read it for layout and cross-repo guidance. + + +## Input + +- **(nothing)** — list supported review kinds and ask which to run. +- **`yolo`** — examine open issues; propose adding the configured + `yolo_label` (default `"yolo"`) where fitness says yes. + +Trailing text after the kind is reserved for future filters; ignore unknown +tokens with a warning rather than inventing behaviour. + +## Review kinds (extendable) + +| Kind | Label applied | Fitness criteria | +|------|---------------|------------------| +| `yolo` | resolved `[issueflow].yolo_label` (default `"yolo"`) | Same as `/iflow-epic`: well-specified, mechanical or pattern-following, low blast radius, guarded by existing tests — umbrella work, design decisions, and flag-day changes are **no**. | + +Future kinds (e.g. model-profile labels) add a row here + optional CLI +`--kind` support — do not rename this skill. + +## Instructions + +> **CLI fast path (optional).** If the `issue-flow` CLI is on `PATH`: +> - **List:** `issue-flow agent label-candidates [--kind yolo] [--json]` +> - **Apply (after confirm):** `issue-flow agent label-apply <N> [<N>…] --label <name> [--dry-run] [--json]` +> +> The CLI never judges fitness. Judgment stays in this skill. If the CLI is +> missing or errors, fall back to the manual instructions below +> (`gh issue list` / `gh issue edit --add-label` with `--repo <owner/repo>`). + +1. **Resolve kind.** If the user omitted a kind, print the kinds table above + and **ask** which to run. Stop until they pick. Unknown kind → error and stop. + +2. **Resolve config.** Read `yolo_label` and `label_flows` from + `.issueflows/config.toml` (or use + `issue-flow agent label-candidates --json`, which includes both). If + `label_flows` is false, **still allow** labelling, but warn that + `/iflow-pick` will not route on the label until `label_flows` is true and + surfaces are re-rendered (`issue-flow update`). + +3. **Ensure the label exists.** `gh label list --repo <owner/repo>` (or the + `label_exists` field from `label-candidates`). If missing: propose + `gh label create '<name>' --color FBCA04 --repo <owner/repo>` (or + equivalent) under an explicit confirm; on decline, **stop**. On accept, + create then continue. + +4. **List candidates.** Load **all open issues** (include those that already + carry the target label — re-score; adds are no-ops when already present). + Prefer `issue-flow agent label-candidates --kind yolo --json`. + +5. **Judge.** For each open issue, decide **add** / **keep** / **skip**: + - **add** — fitness yes, label absent → propose `--add-label`. + - **keep** — fitness yes, label already present → no write. + - **skip** — fitness no → no write. Never auto-remove the label in v1 even + if the issue looks unfit. + Present a short table: `#N`, title, current labels, action, one-line reason. + +6. **Consolidated confirm** (writes; normal prose, never shortened). One prompt + covering exactly which issues get the label. Do not proceed without a clear + yes. Empty **add** set → report and stop (no confirm needed). + +7. **Apply.** `issue-flow agent label-apply <N>… --label <yolo_label>` (or + `gh issue edit <N> --add-label <name> --repo <owner/repo>` per issue). Prefer + `--dry-run` once when the set is large, then the real apply after confirm. + +8. **Report.** Applied / failed / skipped / already-labelled (keep). Remind + that labelled issues are picked up by `/iflow-pick` → `/iflow-yolo` when + `label_flows` is on. If any labels were added (or already present and kept), + hint the batch path: **to auto-process them, run `/iflow-cycle yolo`** + (alias for `label:yolo`). + +## Constraints + +- **Off-path.** Never auto-dispatch from `/iflow` or other lifecycle steps. +- **Confirm before writes** — label create and label apply each need explicit + user confirmation (may be one combined confirm when both are needed). +- **No removals / no issue create** in v1. +- Always pass `--repo <owner/repo>` to `gh`; never rely on cwd defaults. +- Degrade gracefully when `gh` is missing (report and stop; suggest + `gh auth login`). diff --git a/.cursor/skills/iflow-setup/SKILL.md b/.cursor/skills/iflow-setup/SKILL.md new file mode 100644 index 0000000..c783225 --- /dev/null +++ b/.cursor/skills/iflow-setup/SKILL.md @@ -0,0 +1,117 @@ +--- +name: iflow-setup +description: >- + Guide a new user from an empty folder or an unprepared existing project to + a working issue-flow setup: uv project, git repo, GitHub remote, and scaffold. +disable-model-invocation: true +issue-flow-version: 0.4.2a4 +--- + +# issue-flow — guided project setup (`/iflow-setup`) + +Follow this skill to get a project **ready to use issue-flow** — for someone who may never have driven an agentic workflow before. + +It covers both entry paths from a standing start: + +- **New project** — an empty (or nearly empty) folder that needs a Python project, a git repo, and a GitHub remote. +- **Existing project** — real code already, but some piece is missing (no remote, `gh` not authenticated, no issue-flow scaffold). + +This is **not** the issue-capture step. Capturing a GitHub issue into `.issueflows/01-current-issues/` is `/iflow-capture`; picking what to work on is `/iflow-pick`. `/iflow-init` only cold-starts the harness. + + +**Invoke:** type `iflow setup` in chat, or `/iflow-setup` from the slash menu (`iflow-setup` also works). + + + + +### MODEL & EXECUTION DIRECTIVE + + +**Profile: reasoning** — Prioritize deep thinking and careful trade-offs over speed or token economy. + +In Cursor: switch to a thinking-capable model before invoking this step (not Auto-only). + + + +Keep scope tight to what this step requires. + + + + +### Resolve project root (multi-root workspaces) + +Before any `git`, `gh`, or `.issueflows/` path operation in this workflow: + +**Resolution order** (stop when unambiguous): + +1. **Explicit hints** in slash input — `root:<path>`, `repo:<folder-basename>` (directory name, e.g. `cellpy-core`), or `repo:owner/name`. +2. **CLI fast path** — `issue-flow agent resolve [-C <start>] [--from-file <active-file>] [--json]`. Use the returned `project_root` and `repo`; pass `-C <project_root>` to other `issue-flow agent …` subcommands. When the answer came from the workspace registry, the payload sets `resolved_via_workspace_default: true`. +3. **Branch context** — exactly one workspace repo whose branch matches `^\d+-` → that root. +4. **Single scaffold** — exactly one `.issueflows/` tree visible in the workspace → that root. +5. **Workspace default** — an `issueflow-workspace.toml` at the workspace root (created with `issue-flow workspace init`) may name a `default` member repo; use it when no scaffold matched above. Tell the user the default was used. +6. **Ambiguous** → **stop and ask**; never guess between sibling repos. + +After resolution, treat the result as `<project_root>` and `<owner/repo>`: + +- **Git:** `git -C <project_root> …` (or `issue-flow agent … -C <project_root>` for supported ops). +- **GitHub:** pass an explicit repo on every `gh` call — never rely on `gh`'s implicit cwd default. For most commands use `--repo <owner/repo>`; **exception:** `gh repo view` takes the repo as a **positional** arg (`gh repo view <owner/repo> …`) and rejects `--repo`. +- **Paths:** all `.issueflows/…` paths are under `<project_root>`. + +When `.issueflows/04-designs-and-guides/multi-repo-workspaces.md` exists, read it for layout and cross-repo guidance. + + +## Input + +- **(nothing)** — inspect the current directory and guide from there. +- **`new`** — treat this as a brand-new project (skip the new-vs-existing question). +- **`existing`** — treat this as an existing project. +- **`check`** — report readiness only; change nothing, run nothing, ask nothing. + +## Instructions + +> **CLI fast path (optional).** If the `issue-flow` CLI is on `PATH`, run +> `issue-flow agent setup-status --json` for the whole readiness picture +> (tools on `PATH`, git repo / remote / commits, `gh` authentication, Python +> project, existing scaffold) plus an ordered `blockers` list where each entry +> carries the exact `fix` command. It never prompts, never mutates, and exits 0 +> even when the project is not ready. If the CLI is missing, run the equivalent +> probes by hand (`git rev-parse --is-inside-work-tree`, `git remote get-url +> origin`, `gh auth status`, and file checks for `pyproject.toml` / +> `.issueflows/`). + +1. **Read the state.** Run the readiness check and summarise it in a few plain lines — what is already fine, what is missing. Do not use issue-flow jargon the user has not met yet. + +2. **Stop early when nothing is missing.** If the verdict is `ready`, say so, point at the next step (step 6), and stop. Never re-run setup steps on a healthy project. + +3. **Decide new vs existing — and confirm it.** Infer from the readiness payload (a `pyproject.toml`, a git history, or source files means *existing*), then **state your inference and ask the user to confirm** before acting. A wrong guess here is the one that leads to `uv init` scribbling into a real project. `new` / `existing` in the input skips the question. + +4. **Walk the blockers in order, one confirmation per group.** Show exactly what you intend to run before running it, and run nothing the user has not approved. Stop the walk at the first blocker you cannot clear. + + | Missing | What to do | + |---|---| + | `uv` | **Print** the install command (`curl -LsSf https://astral.sh/uv/install.sh \| sh`, or `winget install --id=astral-sh.uv -e` on Windows) and **stop** — you cannot install a package manager for the user. Ask them to run it and re-invoke `/iflow-setup`. | + | Python project (new) | `uv init` (confirm the project name and whether they want a package or a script layout first), then `uv sync`. | + | Python project (existing, no `pyproject.toml`) | Do **not** run `uv init` blind. Ask what the project uses; if it documents conda / poetry / plain venv, record that and move on — issue-flow defers to the project's toolchain. | + | git repo | `git init`, then a first commit (`git add -A && git commit -m "Initial commit"`) once the user has seen what would be committed. Offer a `.gitignore` if none exists. | + | `gh` | **Print** the install hints and **stop** that branch — the GitHub CLI cannot be installed for them. | + | `gh` not authenticated | Tell the user to run **`gh auth login`** themselves in a terminal. It is an interactive browser flow: **never** try to drive it, pipe into it, or run it in the background. Wait for them to confirm, then re-check. | + | no `origin` remote | Offer `gh repo create <name> --source=. --private --remote=origin --push`. Confirm the name and the private/public choice explicitly — this creates a repository on their GitHub account. | + | no issue-flow scaffold | `issue-flow init` (see step 5 for the mode choice). | + +5. **Choose a starting mode when scaffolding.** For someone new to agentic coding, recommend **`issue-flow init --mode novice`**: it installs the linear lifecycle plus the safety nets (`/iflow`, `/iflow-setup`, `/iflow-pick`, `/iflow-init`, `/iflow-capture`, `/iflow-issue`, `/iflow-plan`, `/iflow-build`, `/iflow-pause`, `/iflow-close`, `/iflow-cleanup`, `/iflow-status`, `/iflow-doctor`) and leaves out the hands-off and batch machinery, and it seeds settings that ask before each step instead of chaining. Mention that `issue-flow init --mode standard` adds everything later — switching mode is just a re-run. + +6. **Hand off — never auto-dispatch.** End with the single next thing to type: + - GitHub issues already exist → **`/iflow-pick`** (`iflow pick` in chat). + - No issues yet → **`/iflow-issue`** to write a good first one. + - Then the ordinary path: `/iflow-plan` → `/iflow-build` → `/iflow-close`. + +7. **Report.** Summarise what was run, what the user still has to do themselves (`uv` / `gh` installs, `gh auth login`), and the one command to type next. + +## Constraints + +- **Confirm before every mutation.** `uv init`, `uv sync`, `git init`, the first commit, `gh repo create`, and `issue-flow init` each need explicit approval. Group related steps into one confirmation rather than asking a novice eight separate questions. +- **Never run `gh auth login` yourself**, and never install `uv` or `gh` on the user's behalf — print the command and stop. +- **Never run `uv init` in a directory that already holds a project.** When in doubt, ask. +- **`check` is read-only.** With that token, report and stop: no prompts, no commands. +- **Off-path.** Never auto-dispatch this skill from `/iflow`, `/iflow-plan`, or `/iflow-build`; the user invokes it. It never captures an issue, creates a branch, or opens a PR — that is `/iflow-capture` onward. +- **Plain language.** Assume the user has not read the workflow doc. Explain what each command will do to their machine or their GitHub account before asking. diff --git a/.cursor/skills/iflow-split/SKILL.md b/.cursor/skills/iflow-split/SKILL.md new file mode 100644 index 0000000..e4419c8 --- /dev/null +++ b/.cursor/skills/iflow-split/SKILL.md @@ -0,0 +1,114 @@ +--- +name: iflow-split +description: >- + Split one over-large GitHub issue into linked child issues (native + sub-issues), then optionally start the first child. +disable-model-invocation: true +issue-flow-version: 0.4.2a4 +--- + +# issue-flow — split an over-large issue (`/iflow-split`) + +Follow this skill to **cut one over-large GitHub issue into 2–5 flat child issues**, link each as a GitHub native sub-issue of the parent, and optionally start the first child. + +Do **not** use this skill from `/iflow`, `/iflow-build`, or `/iflow-close`. `/iflow-split` is explicit-only because it creates GitHub issues and parent/child links. + +**Coexists** with: + +- **`/iflow-issue`** — creates *one* new issue. Use split when an *existing* issue is too big for one PR. +- **`/iflow-epic`** — staged multi-issue work with `Depends on` and publish. If the cut needs stages or explicit deps, **stop** and point at `/iflow-epic` (create an anchor with `/iflow-issue epic` when missing). Do not create children here. + +## Input + +- **`<N>`** — parent issue number to split. +- **(nothing)** — use the focus issue in `.issueflows/01-current-issues/`, else the issue-style branch `^\d+-.+`. Ambiguous → ask. + + +**Invoke:** type `iflow split` in chat, or `/iflow-split` from the slash menu (`iflow-split` also works). + + + + +### MODEL & EXECUTION DIRECTIVE + + +**Profile: reasoning** — Prioritize deep thinking and careful trade-offs over speed or token economy. + +In Cursor: switch to a thinking-capable model before invoking this step (not Auto-only). + + + +Keep scope tight to what this step requires. + + + + +### Resolve project root (multi-root workspaces) + +Before any `git`, `gh`, or `.issueflows/` path operation in this workflow: + +**Resolution order** (stop when unambiguous): + +1. **Explicit hints** in slash input — `root:<path>`, `repo:<folder-basename>` (directory name, e.g. `cellpy-core`), or `repo:owner/name`. +2. **CLI fast path** — `issue-flow agent resolve [-C <start>] [--from-file <active-file>] [--json]`. Use the returned `project_root` and `repo`; pass `-C <project_root>` to other `issue-flow agent …` subcommands. When the answer came from the workspace registry, the payload sets `resolved_via_workspace_default: true`. +3. **Branch context** — exactly one workspace repo whose branch matches `^\d+-` → that root. +4. **Single scaffold** — exactly one `.issueflows/` tree visible in the workspace → that root. +5. **Workspace default** — an `issueflow-workspace.toml` at the workspace root (created with `issue-flow workspace init`) may name a `default` member repo; use it when no scaffold matched above. Tell the user the default was used. +6. **Ambiguous** → **stop and ask**; never guess between sibling repos. + +After resolution, treat the result as `<project_root>` and `<owner/repo>`: + +- **Git:** `git -C <project_root> …` (or `issue-flow agent … -C <project_root>` for supported ops). +- **GitHub:** pass an explicit repo on every `gh` call — never rely on `gh`'s implicit cwd default. For most commands use `--repo <owner/repo>`; **exception:** `gh repo view` takes the repo as a **positional** arg (`gh repo view <owner/repo> …`) and rejects `--repo`. +- **Paths:** all `.issueflows/…` paths are under `<project_root>`. + +When `.issueflows/04-designs-and-guides/multi-repo-workspaces.md` exists, read it for layout and cross-repo guidance. + +## Instructions + +### Phase 1 — draft children + +1. **Resolve parent `N`.** Trailing number, else the single `issue<n>_original.md` in `.issueflows/01-current-issues/`, else leading digits of a `^\d+-.+` branch. Ambiguous or missing → **stop and ask**. +2. **Preflight.** Detect the default branch (`gh repo view --json defaultBranchRef -q .defaultBranchRef.name`; fall back to `git symbolic-ref --quiet --short refs/remotes/origin/HEAD`, else `main`). Run `git fetch --prune`. Report current branch + clean/dirty tree. Creating children does **not** require a clean tree; branching onto a child later does. +3. **Draft 2–5 children.** Propose titles + light bodies (not a full `/iflow-plan`): + - **Problem / context** + - **Spec** + - **Acceptance criteria** + - **Out of scope** (optional; omit the heading when empty) + Each body **ends with** `Sub-issue of #<N>.` Refine until the user confirms the set. +4. **Size gate.** If the cut wants sequential stages or explicit `Depends on` lines → **stop**. Recommend `/iflow-epic`. Do not create. + +### Phase 2 — create and link + +5. **Consolidated confirm** (normal prose, never shortened). One prompt covering: parent `#N` stays **open** as the tracker; each listed child title will be created; each will be linked as a GitHub native sub-issue; a `- [ ] #<M>` task-list block will be appended on the parent under `## Sub-issues`. No yes → stop. +6. **Create + link (idempotent).** For each unpublished child: + 1. `gh issue create --repo <owner/repo>` (labels/milestones only if the user asked this turn). Capture number `M`. + 2. Link as a native sub-issue. Prefer the CLI fast path: + `issue-flow agent sub-issue-add <N> <M> -C <project_root> [--repo owner/repo] --json` + Fields: `linked`, `skipped` (already a child), `error`. On CLI missing or `error` set, fall back to the REST recipe below — then if that also fails (404 / permission / plan), **keep the created issue** and rely on the parent task list. + 3. **REST recipe** (single source — other skills point here; do not copy): + `sub_issue_id` is the child's numeric **database id**, not the issue number. `gh api -f` stringifies and **422s**. Send JSON: + + ```bash + CHILD_ID=$(gh api repos/<owner>/<repo>/issues/<M> --jq .id) + echo "{\"sub_issue_id\": ${CHILD_ID}}" | \ + gh api repos/<owner>/<repo>/issues/<N>/sub_issues -X POST --input - + ``` + + Re-runs: `GET repos/<owner>/<repo>/issues/<N>/sub_issues` (or the CLI `skipped` field) — skip children already linked. + 4. Append `- [ ] #<M>` under a `## Sub-issues` heading on the parent (`gh issue edit <N> --body-file`, append/patch only — never rewrite the user's own body). Task list is the fallback when the sub-issue API is unavailable. + 5. Record created numbers in the parent's local status file (create it if missing) so a later re-run can skip them. +7. **Local parent.** If `issue<N>_*` is in `.issueflows/01-current-issues/`, move the whole group to `.issueflows/02-partly-solved-issues/`. Status checkbox stays `- [ ] Done`. Do **not** close the GitHub parent. Do **not** write `issue<M>_*` groups for children. + +### Phase 3 — optional handoff + +8. **Ask** whether to start the first child: `/iflow-pick`-style branch `<M>-<slug>` off the default (clean-tree gate) + `/iflow-capture` for `M`. Do **not** auto-run `/iflow-plan` or `/iflow-build`. Declining leaves the children as open GitHub issues for a later pick. + +## Constraints + +- Off-path: never auto-dispatch from `/iflow`, `/iflow-build`, or `/iflow-close`. +- Never create a GitHub issue or sub-issue link without the consolidated confirm; show titles and bodies first. +- GitHub only (`gh` / `gh api`); GitLab is not supported. +- Parent stays open. Do not convert the parent into an epic plan file. +- Do not merge with `/iflow-epic` publish or `/iflow-issue` — different intents. +- Do not park generated children under `02-partly-solved-issues/`. diff --git a/.cursor/skills/iflow-status/SKILL.md b/.cursor/skills/iflow-status/SKILL.md new file mode 100644 index 0000000..4d82822 --- /dev/null +++ b/.cursor/skills/iflow-status/SKILL.md @@ -0,0 +1,89 @@ +--- +name: iflow-status +description: >- + Read-only snapshot of where every issue stands, locally and on GitHub. +disable-model-invocation: true +issue-flow-version: 0.4.2a4 +--- + +# issue-flow — issue status overview (`/iflow-status`) + +Follow this skill for a bird's-eye view of every issue's status — local tracking state (focus / parked / solved) plus open GitHub issues — rather than acting on the single focus issue. + +Do **not** use this skill to *change* anything. It is read-only and off-path; for acting on the focus issue use `/iflow`, and to choose the next issue use `/iflow-pick`. + + +**Invoke:** type `iflow status` in chat, or `/iflow-status` from the slash menu (`iflow-status` also works). + + + + +### MODEL & EXECUTION DIRECTIVE + + +**Profile: economy** — Prioritize speed and token economy over deep reasoning. + +In Cursor: use **Auto** or a fast model before invoking this step. + + + +Keep scope tight to what this step requires. + + + + +### Resolve project root (multi-root workspaces) + +Before any `git`, `gh`, or `.issueflows/` path operation in this workflow: + +**Resolution order** (stop when unambiguous): + +1. **Explicit hints** in slash input — `root:<path>`, `repo:<folder-basename>` (directory name, e.g. `cellpy-core`), or `repo:owner/name`. +2. **CLI fast path** — `issue-flow agent resolve [-C <start>] [--from-file <active-file>] [--json]`. Use the returned `project_root` and `repo`; pass `-C <project_root>` to other `issue-flow agent …` subcommands. When the answer came from the workspace registry, the payload sets `resolved_via_workspace_default: true`. +3. **Branch context** — exactly one workspace repo whose branch matches `^\d+-` → that root. +4. **Single scaffold** — exactly one `.issueflows/` tree visible in the workspace → that root. +5. **Workspace default** — an `issueflow-workspace.toml` at the workspace root (created with `issue-flow workspace init`) may name a `default` member repo; use it when no scaffold matched above. Tell the user the default was used. +6. **Ambiguous** → **stop and ask**; never guess between sibling repos. + +After resolution, treat the result as `<project_root>` and `<owner/repo>`: + +- **Git:** `git -C <project_root> …` (or `issue-flow agent … -C <project_root>` for supported ops). +- **GitHub:** pass an explicit repo on every `gh` call — never rely on `gh`'s implicit cwd default. For most commands use `--repo <owner/repo>`; **exception:** `gh repo view` takes the repo as a **positional** arg (`gh repo view <owner/repo> …`) and rejects `--repo`. +- **Paths:** all `.issueflows/…` paths are under `<project_root>`. + +When `.issueflows/04-designs-and-guides/multi-repo-workspaces.md` exists, read it for layout and cross-repo guidance. + +## Instructions + +> **CLI fast path (optional).** If the `issue-flow` CLI is on `PATH`, run +> `issue-flow status` (add `--local` to skip the GitHub query, `--json` for a +> machine-readable object) — it produces this whole overview deterministically. +> The CLI is optional: if it is missing or errors, fall back to the manual +> instructions below. (`issue-flow` is only present when the user installed it, +> e.g. `uv tool install issue-flow`.) + +1. **Context / preflight.** Detect the default branch (`gh repo view --json defaultBranchRef -q .defaultBranchRef.name`; fall back to `git symbolic-ref --quiet --short refs/remotes/origin/HEAD | sed 's|^origin/||'`, else `main`). Report current branch, clean/dirty tree (`git status --porcelain`), and ahead/behind vs `origin/<default>`. If the branch matches `^(\d+)-.+`, treat the leading digits as the focus issue `N`. + +2. **Focus issue** (`.issueflows/01-current-issues/`). For the focus group, read its title from `issue<n>_original.md` and classify the lifecycle stage with the `/iflow` first-match logic: + - **init** — no `issue<n>_original.md` → `/iflow-capture`. + - **plan** — original exists, no `issue<n>_plan.md` → `/iflow-plan`. + - **build** — plan exists, status missing or `- [x] Done` unchecked → `/iflow-build`. + - **close** — status contains `- [x] Done` (case-insensitive) → `/iflow-close`. + Report the stage and suggested next step. + +3. **Parked work** (`.issueflows/02-partly-solved-issues/`). List each `issue<n>_*` group: number, title, one-line status if present. + +4. **Solved archive** (`.issueflows/03-solved-issues/`). Report the count of distinct solved issue numbers and the most recent few. + +4a. **In-flight cycle.** If `.issueflows/01-current-issues/cycle_status.md` exists, a `/iflow-cycle` batch run is paused or active — report it and its progress (from the file's checklist), and note that `/iflow-cycle resume` continues it. (`issue-flow status --json` reports this as `cycle_active`.) + +5. **Open GitHub issues** (skip if the user passed `local`). Run `gh issue list --state open --json number,title,labels,milestone,updatedAt` and tag each issue's local state: **focus**, **parked**, **solved-locally**, or **untracked**. If `gh` is missing/unauthenticated, skip this section and note it (suggest `gh auth login`) — never fail. + +6. **Summary line.** One terse line, e.g. `Focus: #20 (start). Parked: 2. Solved: 31. Open on GitHub: 7 (5 untracked).` + +## Constraints + +- **Read-only.** Writes nothing, moves no files, creates no branches/commits/GitHub issues. Only reads `.issueflows/` and runs read-only `git` / `gh` queries. +- **Off-path.** Never auto-dispatch from `/iflow`, `/iflow-build`, or `/iflow-close`. +- **Degrade gracefully.** Missing `gh`, no network, or an empty `.issueflows/` must still yield a useful local report. +- Present sections in order (Context, Focus, Parked, Solved, Open GitHub, Summary); note any skipped section. diff --git a/.cursor/skills/iflow-version-bump/SKILL.md b/.cursor/skills/iflow-version-bump/SKILL.md new file mode 100644 index 0000000..f4dece2 --- /dev/null +++ b/.cursor/skills/iflow-version-bump/SKILL.md @@ -0,0 +1,116 @@ +--- +name: iflow-version-bump +description: >- + Bump the project version following the project's release strategy: static + pyproject versions via uv, or tag-derived versions via a planned git tag. +disable-model-invocation: true +issue-flow-version: 0.4.2a4 +--- + +# issue-flow — version bump + +Use this skill to **bump the project version** before landing work (often invoked from `/iflow-close`) — either at a specific level, or with the default rule below when none is given. What "bump" means depends on the **release strategy**, so resolve that first. + + +### MODEL & EXECUTION DIRECTIVE + + +**Profile: economy** — Prioritize speed and token economy over deep reasoning. + +In Cursor: use **Auto** or a fast model before invoking this step. + + + +Keep scope tight to what this step requires. + + + +> **CLI fast path (optional).** If the `issue-flow` CLI is on `PATH`, run +> `issue-flow agent version-plan [--bump <level>] --json`. It detects the +> strategy from `pyproject.toml`, reads the latest tag, does the PEP 440 +> next-version arithmetic, and returns the exact commands — read-only, it +> never edits files or creates tags. The `this-project.md` release section +> still wins over its detection: when the payload says +> `brief_release_section: "filled"`, read the section and follow it. If the +> CLI is missing or errors, fall back to the manual steps below. + +## Resolve the release strategy first + +In order — stop at the first that answers: + +1. **`.issueflows/04-designs-and-guides/this-project.md`** — if its **"Release & version bump"** section is filled in, follow it verbatim. It is the project's own documentation and beats every default below. +2. **Detect from `pyproject.toml`:** + - `dynamic = ["version"]` under `[project]`, together with a tag-driven backend (`[tool.setuptools_scm]`, `hatch-vcs` in the build requires, `versioningit`, or similar) → **git-tag derived** strategy. + - a static `version = "..."` under `[project]` → **static version (uv)** strategy. +3. **Neither** (no `pyproject.toml`, or no version at all) → **skip** the bump, explain why, and continue the rest of the flow (for example `/iflow-close`) without failing. + +**Record what you learn (self-healing).** When the strategy came from detection or from the user explaining it — i.e. *not* from `this-project.md` — add or fill in the **"Release & version bump"** section of `.issueflows/04-designs-and-guides/this-project.md` with a short description of the strategy and the exact commands, so no future session has to rediscover it. The brief is user-owned and never overwritten by `issue-flow update`, so the note is durable. + +## Bump levels (both strategies) + +Every level below is allowed; the same table drives both strategies (examples from `0.4.1a4`): + +| Level | Effect | +|---|---| +| `major` | `1.0.0` | +| `minor` | `0.5.0` | +| `patch` | `0.4.2` | +| `stable` | `0.4.1` — drop the pre-release/dev segment | +| `alpha` | `0.4.1a5` — next alpha pre-release | +| `beta` | `0.4.1b1` — promote/advance to beta | +| `rc` | `0.4.1rc1` — promote/advance to release candidate | +| `post` | `0.4.1a4.post1` — post-release | +| `dev` | dev release — **must** be paired with another component | + +## Choosing the level + +1. **The user named a level** (`patch`, `minor`, `major`, `stable`, `alpha`, `beta`, `rc`, `post`, `dev`) → use exactly that. +2. **The user asked to bump/release but gave no level** → apply the **pre-release-aware default**, based on the *current* version (static field, or latest tag): + - current is an **alpha** (`aN`) → next alpha + - current is a **beta** (`bN`) → next beta + - current is a **release candidate** (`rcN`) → next rc + - current is a **dev** release (`.devN`) → advance dev paired with the component being advanced (default `patch`) + - current is a **stable** release (no pre-release segment) → `patch` +3. **Free-text intent** (e.g. "bugfix release", "promote to beta") → map to the matching level (bugfix → `patch`, "to beta" → `beta`); if genuinely ambiguous, ask once rather than guessing **major**. + +## Strategy: static version (uv) + +For a **Python + uv** project whose `pyproject.toml` has a `[project]` `version` field. + +1. Run from the **project root** (the directory that contains `pyproject.toml`). +2. Use **only** `uv` with `--bump <level>`: + +```bash +uv version --bump patch # 0.4.1a4 -> 0.4.2 +uv version --bump alpha # 0.4.1a4 -> 0.4.1a5 +uv version --bump minor --bump alpha # combine: 0.4.1a4 -> 0.5.0a1 +``` + +Tip: preview without writing using `uv version --dry-run --bump <level> --short`. + +3. Afterwards: confirm the new version in `pyproject.toml` (or the `uv` output). When committing later, stage **`pyproject.toml`**; if **`uv.lock`** changed as well, stage it too — otherwise do not assume it changed. + +## Strategy: git-tag derived + +For projects whose built version comes from the **latest git tag** (setuptools-scm, hatch-vcs, versioningit, …). Here bumping means **planning a tag**, and the tag is created **after the PR merges** — never before. + +1. **Never edit a version into `pyproject.toml`** — the backend derives it. +2. **Find the current version**: latest tag via `git describe --tags --abbrev=0` (or `git tag --sort=-v:refname` and take the first). Keep the project's existing tag style (e.g. a leading `v`). +3. **Compute the planned next version** from the level table above (e.g. latest `v1.0.4a2` + `alpha` → planned `v1.0.4a3`). +4. **Do not create the tag during `/iflow-close`.** In a squash-merge world the issue-branch commit never lands on the default branch, so a pre-merge tag would point at an orphan. Instead: + - report the **planned tag** in the close output and record it in the issue's status file, + - let `HISTORY.md` promotion use the planned version, + - create the tag **after the merge**, standing on the updated default branch (this is offered by `/iflow-cleanup`, or happens right after the post-merge pull in a `yolo` close): + +```bash +git tag v1.0.4a3 +git push origin v1.0.4a3 +# or, to also cut a GitHub release: +gh release create v1.0.4a3 --generate-notes +``` + +## Constraints + +- Do not substitute `pip` or hand-edit versions unless the strategy's own tool fails and the user agrees to an alternative. +- Never silently jump release channels: don't promote an alpha to stable (or bump major/minor) just because no level was given — the default keeps you on the current pre-release channel. +- Tag-derived projects: never tag an issue-branch commit; the tag is created on the merged default branch only. diff --git a/.cursor/skills/iflow-yolo/SKILL.md b/.cursor/skills/iflow-yolo/SKILL.md new file mode 100644 index 0000000..db47aa3 --- /dev/null +++ b/.cursor/skills/iflow-yolo/SKILL.md @@ -0,0 +1,85 @@ +--- +name: iflow-yolo +description: >- + Chain capture → plan → build → close yolo for a small, low-risk issue under + one consolidated confirm. Stops on any ambiguity. +disable-model-invocation: true +issue-flow-version: 0.4.2a4 +--- + +# issue-flow — issue yolo (`/iflow-yolo`) + +Follow this skill to **blast through a small, low-risk issue** in one shot, with no mid-run confirmation checkpoints beyond the single consolidated confirm. + +Use only for minor fixes, doc tweaks, and similar low-risk changes. Anything non-trivial should go through the individual commands. + + +**Invoke:** type `iflow yolo` in chat, or `/iflow-yolo` from the slash menu (`iflow-yolo` also works). + + + + +### MODEL & EXECUTION DIRECTIVE + + +**Profile: reasoning** — Prioritize deep thinking and careful trade-offs over speed or token economy. + +In Cursor: switch to a thinking-capable model before invoking this step (not Auto-only). + + + +Keep scope tight to what this step requires. + + + + +### Resolve project root (multi-root workspaces) + +Before any `git`, `gh`, or `.issueflows/` path operation in this workflow: + +**Resolution order** (stop when unambiguous): + +1. **Explicit hints** in slash input — `root:<path>`, `repo:<folder-basename>` (directory name, e.g. `cellpy-core`), or `repo:owner/name`. +2. **CLI fast path** — `issue-flow agent resolve [-C <start>] [--from-file <active-file>] [--json]`. Use the returned `project_root` and `repo`; pass `-C <project_root>` to other `issue-flow agent …` subcommands. When the answer came from the workspace registry, the payload sets `resolved_via_workspace_default: true`. +3. **Branch context** — exactly one workspace repo whose branch matches `^\d+-` → that root. +4. **Single scaffold** — exactly one `.issueflows/` tree visible in the workspace → that root. +5. **Workspace default** — an `issueflow-workspace.toml` at the workspace root (created with `issue-flow workspace init`) may name a `default` member repo; use it when no scaffold matched above. Tell the user the default was used. +6. **Ambiguous** → **stop and ask**; never guess between sibling repos. + +After resolution, treat the result as `<project_root>` and `<owner/repo>`: + +- **Git:** `git -C <project_root> …` (or `issue-flow agent … -C <project_root>` for supported ops). +- **GitHub:** pass an explicit repo on every `gh` call — never rely on `gh`'s implicit cwd default. For most commands use `--repo <owner/repo>`; **exception:** `gh repo view` takes the repo as a **positional** arg (`gh repo view <owner/repo> …`) and rejects `--repo`. +- **Paths:** all `.issueflows/…` paths are under `<project_root>`. + +When `.issueflows/04-designs-and-guides/multi-repo-workspaces.md` exists, read it for layout and cross-repo guidance. + +## Preflight (abort on any failure) + +1. **Refuse on default branch.** If the current branch is `main` / `master` / the detected default, **stop** and tell the user to create or switch to an issue branch first. Do not silently create one from yolo. + +2. **Refuse with dirty unrelated changes.** Run `git status --porcelain`. If anything uncommitted is not clearly part of the target issue, ask once; if still unclear, **stop**. Suggest committing or stashing first. + +3. **Tests must pass up front.** Run `uv run pytest` (or the repo's documented test command). On any failure, **stop** before the chain starts. + +4. **Single consolidated confirm.** Present the full planned chain explicitly (issue reference, target branch, repo, downstream commands including any `bump` / `patch` / `draft` / `stay` flags). Require an explicit yes; any other input aborts. (When `/iflow-pick` routed here via the yolo issue label, its combined confirmation already covered this — do not ask twice.) + +## Chain + +Once preflight has passed and the user confirmed: + +1. **`/iflow-capture`** — capture the issue (or skip if `*_original.md` already exists for the focus issue). +2. **`/iflow-plan`** — write a **short** `issue<N>_plan.md` (Goal + Approach + Files to touch + Test strategy). Auto-confirm — the consolidated confirm above covered it. If the scope check reveals the change is not actually small, **abort the yolo chain** and tell the user to run the commands individually. +3. **`/iflow-build`** — implement the plan without an additional plan-mode prompt. Forward `early` / `pr` / `noearly` when present. When early PR is on (baked `early_pr` or trailing `early`/`pr`), build may open a **draft** PR after the first push; close will list-before-create, mark ready (unless `draft`), then merge. +4. **Re-run tests.** `uv run pytest` again. On failure, **stop** before commit / push / PR. +5. **`/iflow-close yolo`** — run the close flow with the `yolo` token (plus forwarded `bump` / `log` / `nohistory` / `draft` / `stay` tokens). The `yolo` token makes close hands-off: changelog bullet written without a confirm prompt; PR listed/reused via `gh pr list` (including an early draft), marked ready when not `draft`, then **merged** via `gh pr merge --squash` (on pending checks: `gh pr checks --watch --fail-fast` for up to **15** minutes, then retry merge; `--squash --auto` only as last resort when the cap elapses or checks never register; on a `CONFLICTING` / `DIRTY` refusal it re-syncs with the default branch via `issue-flow agent sync-branch`, which keeps both `HISTORY.md` bullet sets when that is the only conflict, then force-with-lease pushes and retries the merge once — any other conflict stops the run), then default-branch switch + `git pull --ff-only`; then remove the sibling issue worktree from home when the merge succeeded and the tree is clean. `draft` conflicts with auto-merge — when passed, skip the merge and say so. Do **not** chain `/iflow-cleanup` automatically — local branch deletion stays a user decision. + +## Post-run + +Report the PR URL, the merge result (merged, or queued via `--auto`), and the final branch. By default `/iflow-close yolo` merges the PR and switches back to the default branch with a pull; forwarded `stay` text leaves the user on the issue branch instead. Remind them that `/iflow-cleanup` will delete the now-merged local branch when they are ready. + +## Constraints + +- Do not override downstream commands' own constraints (never `git branch -D` — the squash-landed force-delete confirm belongs to an interactive `/iflow-cleanup`, no force-push beyond close's own `--force-with-lease` after a sync, etc.). `/iflow-yolo` is a chain, not a free pass. +- If **any** downstream step requires a human decision (unrelated changes in `git status`, ambiguous version bump, merge conflict, failed test), **stop** and hand back to the user. +- Never run `/iflow-cleanup` from this skill. Branch deletion always needs the user to see the merged PR first. diff --git a/.cursor/skills/iflow/SKILL.md b/.cursor/skills/iflow/SKILL.md new file mode 100644 index 0000000..fd96b05 --- /dev/null +++ b/.cursor/skills/iflow/SKILL.md @@ -0,0 +1,109 @@ +--- +name: iflow +description: >- + Smart dispatcher: detect where the focus issue stands and dispatch to + /iflow-capture, /iflow-plan, /iflow-build, or /iflow-close. +disable-model-invocation: true +issue-flow-version: 0.4.2a4 +--- + +# issue-flow — iflow smart dispatcher (`/iflow`) + +Follow this skill to run **the right next step** in the issue-flow lifecycle: it detects state and routes to `/iflow-capture`, `/iflow-plan`, `/iflow-build`, or `/iflow-close`, forwarding trailing args verbatim. + +Do **not** use this skill for `/iflow-setup`, `/iflow-pick`, `/iflow-init`, `/iflow-pause`, `/iflow-cleanup`, `/iflow-yolo`, `/iflow-ops`, `/iflow-fix`, `/iflow-issue`, `/iflow-split`, `/iflow-review`, or other off-path helpers. Those are explicit-only commands. (`/iflow-pick` is the front door *before* `/iflow-capture`, for when no issue has been chosen yet. `/iflow-init` cold-starts the harness — it does not capture issues. `/iflow-fix` runs an interactive iterative-fixes session, driven by `/iflow-fix` + `/iflow-close`. `/iflow-issue` creates one well-specified normal GitHub issue. `/iflow-ops` runs no-PR ops work. `/iflow-split` cuts an over-large issue into linked sub-issues.) + + +**Invoke:** type `iflow` in chat, or `/iflow` from the slash menu. + + + + +### MODEL & EXECUTION DIRECTIVE + + +**Profile: economy** — Prioritize speed and token economy over deep reasoning. + +In Cursor: use **Auto** or a fast model before invoking this step. + + + +Keep scope tight to what this step requires. + + + + +### Resolve project root (multi-root workspaces) + +Before any `git`, `gh`, or `.issueflows/` path operation in this workflow: + +**Resolution order** (stop when unambiguous): + +1. **Explicit hints** in slash input — `root:<path>`, `repo:<folder-basename>` (directory name, e.g. `cellpy-core`), or `repo:owner/name`. +2. **CLI fast path** — `issue-flow agent resolve [-C <start>] [--from-file <active-file>] [--json]`. Use the returned `project_root` and `repo`; pass `-C <project_root>` to other `issue-flow agent …` subcommands. When the answer came from the workspace registry, the payload sets `resolved_via_workspace_default: true`. +3. **Branch context** — exactly one workspace repo whose branch matches `^\d+-` → that root. +4. **Single scaffold** — exactly one `.issueflows/` tree visible in the workspace → that root. +5. **Workspace default** — an `issueflow-workspace.toml` at the workspace root (created with `issue-flow workspace init`) may name a `default` member repo; use it when no scaffold matched above. Tell the user the default was used. +6. **Ambiguous** → **stop and ask**; never guess between sibling repos. + +After resolution, treat the result as `<project_root>` and `<owner/repo>`: + +- **Git:** `git -C <project_root> …` (or `issue-flow agent … -C <project_root>` for supported ops). +- **GitHub:** pass an explicit repo on every `gh` call — never rely on `gh`'s implicit cwd default. For most commands use `--repo <owner/repo>`; **exception:** `gh repo view` takes the repo as a **positional** arg (`gh repo view <owner/repo> …`) and rejects `--repo`. +- **Paths:** all `.issueflows/…` paths are under `<project_root>`. + +When `.issueflows/04-designs-and-guides/multi-repo-workspaces.md` exists, read it for layout and cross-repo guidance. + +## Instructions + +> **CLI fast path (optional).** If the `issue-flow` CLI is on `PATH`, run +> `issue-flow agent state --json` to resolve the focus issue, its lifecycle +> stage, the suggested `next_command`, and (when there is no focus) +> `epic_hint` in one deterministic step (covers instructions 1–2), then +> dispatch — or stop for the epic gap. The CLI is optional: if it is not +> installed or it errors, fall back to the manual instructions below. +> (`issue-flow` is only present when the user installed it, e.g. +> `uv tool install issue-flow`.) + +1. **Resolve the focus issue number `N`.** + - Prefer `issue-flow agent state --json` when the CLI is on `PATH` (fields `focus`, `next_command`, `epic_hint`). + - Manual fallback: `git branch --show-current`. If it matches `^(\d+)-.+`, the leading digits are the **authoritative** `N`. + - List `issue<n>_*` groups in `.issueflows/01-current-issues/`, and also check `.issueflows/02-partly-solved-issues/` and `.issueflows/03-solved-issues/` for archived groups matching `N`. + - Pick `N` by precedence: + 1. **Branch-derived `N` wins**, regardless of whether a group for `N` exists in `01-current-issues/`. State **A** will apply when no `issue<N>_*` files are present yet. If `issue<N>_*` is archived under `02-partly-solved-issues/` or `03-solved-issues/`, warn the user that `/iflow-capture`'s archived-issue guard will ask for an explicit confirmation before re-opening. + 2. No branch-derived `N`, exactly one group exists in `01-current-issues/` → use it. + 3. No branch-derived `N`, no groups at all → **epic gap check** (step 1a), else state **A**. + 4. No branch-derived `N`, multiple groups → **stop and ask**. + +1a. **Epic gap (no focus)** — when step 1 finds no focus (`focus` is null / empty `01-current-issues/` and no `^\d+-.+` branch): + - Prefer `epic_hint` from `issue-flow agent state --json` (lists epics with non-empty `next_candidates`). Fallback: scan `.issueflows/05-epics/epic*_plan.md` and run `issue-flow agent epic-status <N> --json` per plan. + - If **any** `next_candidates`: **stop**. Print epic + stage + candidate numbers/titles. Recommend **`/iflow-pick`** (or `iflow pick`). Do **not** dispatch `/iflow-capture` yet — even when only one candidate (never pick silently). If the user's trailing text is already an explicit issue number `N`, then dispatch `/iflow-capture` with that `N` instead of stopping. + - If **no** epic candidates → continue to state **A** (`/iflow-capture`, which asks for a number). + +2. **Detect state and choose the dispatch target** (first match wins): + + - **A** — no `issue<N>_original.md` (or no focus issue, after the epic gap check) → dispatch to **`/iflow-capture`**. Reason: "no `*_original.md` yet". + - **B** — original exists, no `issue<N>_plan.md` → dispatch to **`/iflow-plan`**. Reason: "no plan file yet". + - **C** — plan exists, and status file is missing or its `- [x] Done` is unchecked → dispatch to **`/iflow-build`**. Reason: "plan is confirmed but status is not `- [x] Done`". + - **D** — status file contains `- [x] Done` (case-insensitive on `done`) → dispatch to **`/iflow-close`**. Reason: "status marks the issue `- [x] Done`". + + +3. **Announce and dispatch.** Print one line like `/iflow -> /iflow-plan (issue #N: no plan file yet)` and then follow the chosen command's playbook. Forward the user's trailing text verbatim. + +4. **Respect downstream checkpoints.** Never suppress the downstream command's own prompts (plan confirmation, unrelated-changes prompt, etc.). `/iflow` adds no new confirmation layer of its own. + +5. **Report.** Summarize: focus issue `N` and how it was resolved, which command was dispatched and why, the downstream output, and a one-line hint when an off-path command is the natural next step: + - state **D** + PR likely merged → "after the PR merges, run `/iflow-cleanup`" + - mid-stream context switch needed → "to park this work, run `/iflow-pause`" + - tiny fix that would benefit from a single-shot chain → "consider `/iflow-yolo` next time" + - state **D** / between issues, and an active epic still has `next_candidates` → "epic #<E> stage still has #<…> — run `/iflow-pick` when ready" + - `graphify-out/GRAPH_REPORT.md` looks stale (large refactor, new modules) → "consider `/iflow-graphify` to refresh the graph" + + +## Constraints + +- Never auto-dispatch to `/iflow-setup`, `/iflow-pick`, `/iflow-init`, `/iflow-pause`, `/iflow-cleanup`, `/iflow-yolo`, `/iflow-ops`, `/iflow-fix`, `/iflow-issue`, `/iflow-split`, `/iflow-review`, `/iflow-epic`, `/iflow-cycle`, `/iflow-auto`, or `/iflow-drive`. +- Epic gap (step 1a) only **suggests** `/iflow-pick`; it never runs pick or silently picks a candidate. +- If the focus issue cannot be resolved (multiple groups, branch ambiguous), stop and ask. +- Do not modify files beyond what the downstream command would normally modify. `/iflow` itself writes nothing — all file changes come from the dispatched command. +- Dispatch to at most one command per `/iflow` invocation. diff --git a/.gitignore b/.gitignore index 02f5814..5062b48 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ .venv/ +.env __pycache__/ *.py[cod] dist/ diff --git a/.issueflows/00-tools/.gitkeep b/.issueflows/00-tools/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/.issueflows/00-tools/README.md b/.issueflows/00-tools/README.md new file mode 100644 index 0000000..1864b0a --- /dev/null +++ b/.issueflows/00-tools/README.md @@ -0,0 +1,29 @@ +# `00-tools/` — shared helper tools + +This folder is the project's **durable toolbox** for issue-flow work. Small +scripts and utilities that are useful across more than one issue live here so +agents (and humans) can reuse them instead of re-writing throwaway helpers each +time. + +## When working an issue + +- **Check here first.** Before writing a new helper script for an issue, skim + the index below and the files in this folder — a suitable tool may already + exist. +- **Contribute back.** If you build something during an issue that could help + again later (a data-munging script, a checker, a one-off that turned out + reusable), save it here and add a one-line entry to the index so the next + agent knows what it does and when to reach for it. +- Keep tools small, self-contained, and runnable through the project's + documented toolchain (e.g. `uv run 00-tools/<script>.py`). + +This README is **not** overwritten by `issue-flow update`, so the index is safe +to grow over time. + +## Tool index + +<!-- Add one row per tool: name | what it does | when to use it --> + +| Tool | What it does | When to use | +| --- | --- | --- | +| _(none yet)_ | | | diff --git a/.issueflows/01-current-issues/.gitkeep b/.issueflows/01-current-issues/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/.issueflows/02-partly-solved-issues/.gitkeep b/.issueflows/02-partly-solved-issues/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/.issueflows/03-solved-issues/.gitkeep b/.issueflows/03-solved-issues/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/.issueflows/03-solved-issues/issue3_original.md b/.issueflows/03-solved-issues/issue3_original.md new file mode 100644 index 0000000..2d190ff --- /dev/null +++ b/.issueflows/03-solved-issues/issue3_original.md @@ -0,0 +1,9 @@ +# Issue #3: Iterative small fixes + +Source: https://github.com/cellpy/cellpy-mcp/issues/3 + +## Original issue text + +Interactive `/iflow-fix` session. + +Individual fixes are recorded in the local status markdown and landed together via `/iflow-close`. diff --git a/.issueflows/03-solved-issues/issue3_status.md b/.issueflows/03-solved-issues/issue3_status.md new file mode 100644 index 0000000..5a90fe6 --- /dev/null +++ b/.issueflows/03-solved-issues/issue3_status.md @@ -0,0 +1,9 @@ +# Issue #3 — Iterative small fixes + +Interactive `/iflow-fix` session on `cellpy/cellpy-mcp`. + +- [x] Done + +## Iterative fixes log + +- 2026-09-20: Bump `__version__` to 0.2.0 and point `docs/releasing.md` tag examples at `v0.2.0` (PyPI still 0.1.0; no tag yet). diff --git a/.issueflows/04-designs-and-guides/.gitkeep b/.issueflows/04-designs-and-guides/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/.issueflows/04-designs-and-guides/essential-tests.md b/.issueflows/04-designs-and-guides/essential-tests.md new file mode 100644 index 0000000..0823c6b --- /dev/null +++ b/.issueflows/04-designs-and-guides/essential-tests.md @@ -0,0 +1,70 @@ +# Essential tests (pytest) + +**Context.** Large suites (especially agent-written tests) make "run everything on +every PR" expensive. A common pattern: mark a small **essential** subset for +PR/push CI; run the full suite on a schedule and at release. + +**Opt-in.** Controlled by `[issueflow]` knobs (baked at `issue-flow update`): + +| Key | Default | Role | +|-----|---------|------| +| `essential_tests` | `false` | Master switch — skills ignore this guide when false | +| `test_runner` | `"pytest"` | v1 only `"pytest"`; other values → unsupported + invite PRs | +| `essential_marker` | `"essential"` | pytest mark name (`@pytest.mark.<name>`) | +| `essential_review` | `"close"` | When to triage issue-touched tests: `close` \| `build` \| `both` \| `never` | + +See also [skill-behaviour-knobs.md](./skill-behaviour-knobs.md) and the living +[test-registry.md](./test-registry.md). + +## Contract + +1. **Marker.** Register in `pyproject.toml` / `pytest.ini`, e.g. + `[tool.pytest.ini_options] markers = ["essential: …"]`. +2. **Dual CI (docs recipe, not auto-written):** + - PR/push workflow: `pytest -m essential` (plus lint as usual). + - Scheduled / release workflow: full `pytest`. +3. **Per-issue review** (when `essential_review` includes the step): agents + triage **tests added or changed by this issue only** — propose + `@pytest.mark.essential` vs leave unmarked, update the registry + row, confirm before bulk edits. +4. **Doctor sweep:** full-suite audit vs registry (drift, suite-too-large, + demotions) — off-path, consolidated confirm before marker churn. +5. **Close sanity when enabled:** run essential (`pytest -m essential`); + *remind* that full/scheduled coverage exists. Do not skip a failing essential + suite. + +## Non-goals (v1) + +- Non-pytest runners. +- Silently rewriting unrelated tests. +- Auto-writing consumer `.github/workflows/` (copy from this doc / recipes). +- Graphify bulk classification of an existing huge suite. + +## CI recipe (copy-paste) + +**PR / push (`ci.yml` excerpt):** + +```yaml +- name: Essential tests + run: uv run pytest -m essential -v +``` + +**Scheduled full suite (`ci-scheduled.yml` sketch):** + +```yaml +on: + schedule: + - cron: "0 3 * * 1" # weekly; adjust + workflow_dispatch: + +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + # … setup … + - name: Full test suite + run: uv run pytest -v +``` + +Link: issue #213. diff --git a/.issueflows/04-designs-and-guides/test-registry.md b/.issueflows/04-designs-and-guides/test-registry.md new file mode 100644 index 0000000..895f555 --- /dev/null +++ b/.issueflows/04-designs-and-guides/test-registry.md @@ -0,0 +1,21 @@ +# Test registry + +Living index of notable tests for the optional **essential tests** paradigm +(see [essential-tests.md](./essential-tests.md)). Seeded once by issue-flow; +**never overwritten** on `issue-flow update` — agents and humans grow the table. + +When `[issueflow].essential_tests` is true, `/iflow-close` / `/iflow-build` +(per `essential_review`) should add or update rows for tests **touched by the +current issue**. `/iflow-doctor` may audit the whole suite against this table. + +| Test (node id or path::name) | Essential? | Always? | Code under test | Issue | Notes / demote? | +| --- | --- | --- | --- | --- | --- | +| *(none yet)* | | | | | | + +**Columns** + +- **Essential?** — currently marked with the configured pytest marker. +- **Always?** — should stay essential even after the originating issue closes. +- **Code under test** — modules/symbols (graphify can help). +- **Issue** — GitHub number that introduced or last reviewed the test. +- **Notes / demote?** — why essential, or candidate for demotion. diff --git a/.issueflows/04-designs-and-guides/this-project.md b/.issueflows/04-designs-and-guides/this-project.md new file mode 100644 index 0000000..50700e4 --- /dev/null +++ b/.issueflows/04-designs-and-guides/this-project.md @@ -0,0 +1,48 @@ +# cellpy-mcp + +## What this project is + +TODO: Summarize the project in one short paragraph. Mention what it does, who it is for, and the main outcome it produces. + +## Stack / runtime + +- TODO: Primary language(s), runtime versions, package manager(s), and major frameworks. +- TODO: External services, CLIs, or local tools that agents should know about. + +## How to run / test + +```bash +TODO: command to install or sync dependencies +TODO: command to run the main test suite +TODO: command to run lint/format checks +``` + +## Conventions + +- TODO: Branch, commit, formatting, typing, testing, or review conventions that are specific to this project. +- TODO: Any project-specific workflow details that are easy for agents to miss. +- **Multi-root workspaces:** put this repo's Python/toolchain commands here (conda vs uv, test invocations, etc.) so they do not collide with sibling repos in a shared editor workspace. + +## Release & version bump + +<!-- The iflow-version-bump skill (used by /iflow-close) reads this section + first. Fill in ONE strategy and delete the rest; while it is a TODO the + skill falls back to auto-detection from pyproject.toml. --> + +- TODO: Describe how this project is versioned and released. Common patterns: + - **Static version (uv):** `[project] version` lives in `pyproject.toml`; + bump with `uv version --bump <level>` before the release commit. + - **Git-tag derived (setuptools-scm / hatch-vcs / versioningit):** the built + version comes from the latest tag; never edit a version into + `pyproject.toml`. Bumping = creating a tag on the default branch **after** + the PR merges, e.g. `git tag v1.2.3 && git push origin v1.2.3` (or + `gh release create v1.2.3 --generate-notes`). + +## Entry points + +- TODO: Main application/package/module entry point. +- TODO: Important directories or files to read first. + +## Non-goals / known limitations + +- TODO: Scope boundaries, known caveats, or things this project intentionally does not do. diff --git a/.issueflows/05-epics/.gitkeep b/.issueflows/05-epics/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/.issueflows/agent/skill-stamps.json b/.issueflows/agent/skill-stamps.json new file mode 100644 index 0000000..78f07ba --- /dev/null +++ b/.issueflows/agent/skill-stamps.json @@ -0,0 +1,36 @@ +{ + "format": "issueflow-skill-stamps-v1", + "hashes": { + ".cursor/skills/caveman": "0689fb6b8decb86e17c4c6e4b4e5d4b320442a4fe33781f4e2a3031ea0948f28", + ".cursor/skills/gh-ci": "f866df53b7ece14f98ddd89fb0b9323069a0ac84f7efd66faf6710582333e11b", + ".cursor/skills/grill-me": "eebf8df68f8a393eeb4c90f803b35b3328aba3934ff1bf89fee712be614b3313", + ".cursor/skills/iflow": "17d4e45bb28b5427677db979edeac9a2622e0569a85077362508cc2f6c97a850", + ".cursor/skills/iflow-archive": "f67ff91e5329bcbbfae16da2ef3b03ac60e76fc1f75b47cedba7c643679d8b0c", + ".cursor/skills/iflow-auto": "dca2b4649d1622367103a2fc34cc11424f52525c689adffb84301cba0e9b1a65", + ".cursor/skills/iflow-build": "68b7a8ecd594c133b05908fd31f545bd51dc018c2c67ce4ffe7073274f1af428", + ".cursor/skills/iflow-capture": "865534e247e9adf22f08a9bb4118503f94b894575514aec796cb6b15186f3d6c", + ".cursor/skills/iflow-cleanup": "cdaefc6b6a839ba655874a4cba73dfa5ee66758c8337bf822df1d4f3730c927d", + ".cursor/skills/iflow-close": "af32476832cd44d728d0c57849fa67fd2c364849988da1445b28151117b4b7f1", + ".cursor/skills/iflow-comments": "a2088e8a7ead34c6119ea8fb66acc0fdb5379835caa25fbe1c4d712e1f98d2f9", + ".cursor/skills/iflow-cycle": "4cd73cd9977cdb64299d7796a8ab5d9221f1ff942bbaec7b90854124e68d9e56", + ".cursor/skills/iflow-doctor": "38662f0301b0f122031957584a6d6133c987cc4bf09d715ccb5180595990e039", + ".cursor/skills/iflow-drive": "d76566e385d11010c22e7e61ef0603b0f78a2dcb3d9dc59eca2172515182a52c", + ".cursor/skills/iflow-epic": "5ad364a8616deed6b16e0a40346a99f2bd3529045d79a41166ede90607b0c630", + ".cursor/skills/iflow-fix": "932040d40f048258e6e099d884de127735163e41d420603fb6b03f0ab5085100", + ".cursor/skills/iflow-graphify": "71e446e9a789fc5e56721d3206d908cf98e3bbfd0f84350d5fa4143022785f66", + ".cursor/skills/iflow-history-update": "be1b3aee591dd6f9f1a03c9c1ce2fc4b133d71bd169aa968ef7c775a488e9d72", + ".cursor/skills/iflow-init": "faeca8f615f00d8cbda0ca64b599b9c6183b5507177d91508c35fe95eb6bf11a", + ".cursor/skills/iflow-issue": "28eaaffd4f8ddfa50d3c1f2241b22be428413ac02634c6823e11eb86e6f8f464", + ".cursor/skills/iflow-ops": "f038d3d355ea7bc5139143efe2a719f1b42213a997611f2240ba7c6bb8b1b15c", + ".cursor/skills/iflow-pause": "58bf21feca652d7e70fe2558946fb20332be437ebbdd239d2ecf234f0adb32c8", + ".cursor/skills/iflow-pick": "b99c5f0c501dc849a712fdbb90a74e662e3f03e7c2285e78e63ed8129da46791", + ".cursor/skills/iflow-plan": "c83838fbc0b5cf1ef4fe85a4094cb7362641aecd41699bb4928fe96bf4a2e1fd", + ".cursor/skills/iflow-pr-sync": "adf9812379d95bca7e915ffc49245cca1ba3004ef55a8a51066262090cfa644a", + ".cursor/skills/iflow-review": "593f72af0400319145527f1d78a66cb1ce1405b01bd4ddd3db7b3487fe977af7", + ".cursor/skills/iflow-setup": "080713087c2ab07d40bb54462af5381993b5c2aeaebc654cbfa70403d6c50c4b", + ".cursor/skills/iflow-split": "b0e03ac71a44eb6ac98e7c1d471a7ee5ad7fcf3afd06e928f004a3bda1120413", + ".cursor/skills/iflow-status": "a063e56897993b27bf27ce972f795d65c4ad404c08cadbd64ec62e1f7d7a0d78", + ".cursor/skills/iflow-version-bump": "27089e016337e6e35673852e8af456458dcc4c334a4c417a98762877205c4f09", + ".cursor/skills/iflow-yolo": "849955d5d780fbcb908b3cdb3278d3d4f420b8816e072c78d5f2330fe01767f2" + } +} diff --git a/.issueflows/config.toml b/.issueflows/config.toml new file mode 100644 index 0000000..dfa6b28 --- /dev/null +++ b/.issueflows/config.toml @@ -0,0 +1,5 @@ +# issue-flow project config. 'mode' is managed by 'issue-flow init'. + +[issueflow] +mode = "standard" +skill_level = "standard" diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..2266469 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,343 @@ +<!-- BEGIN issue-flow (managed: do not edit this block) --> +# Issue-flow best practices + + +## Running python + +**Respect the project's existing toolchain first.** If this project already +documents how to run Python and manage dependencies — in its `README`, +`AGENTS.md`, `CLAUDE.md`, `.cursor/rules`, `environment.yml`, `pyproject.toml`, +`Makefile`, CI config, etc. — **follow that**, even where it conflicts with the +defaults below. These rules describe issue-flow's *default* assumptions, not a +mandate to override a project that has already chosen differently. + +The one tool-neutral principle: **don't call bare `python ...`** — invoke Python +through the project's environment (its runner, or an activated virtualenv/conda +env) so scripts and tests see the right interpreter and dependencies. + +### If the project uses conda + +When the project documents a conda environment, run **all** Python commands — +scripts **and `pytest`** — inside the **activated conda environment**. Do **not** +substitute `uv run`. + +```bash +# Either activate the environment first… +conda activate <env-name> +python run_script.py +pytest + +# …or run one-off commands inside it: +conda run -n <env-name> pytest +``` + +### If the project uses uv (issue-flow's default) + +For projects scaffolded fresh (and this is the default when nothing else is +documented), use `uv`: + +```bash +# ❌ BAD: bare interpreter +python run_script.py + +# ✅ GOOD: through uv +uv run run_script.py +``` + +**Package management with `uv`** + +- Install, synchronize, and lock dependencies with `uv`; don't reach for `pip`, + `pip-tools`, or `poetry` in a uv-managed project. + +```bash +# Add or upgrade dependencies +uv add <package> + +# Remove dependencies +uv remove <package> + +# Reinstall all dependencies from the lock file +uv sync + +# Run a script with the right environment +uv run script.py +``` + +### Other toolchains (plain venv / pip / poetry) + +If the project uses something else, use whatever it documents (e.g. activate its +`.venv` and use `pip`, or run `poetry run`). Match the project; don't force `uv`. + + +## Issue tracking structure + +```bash +cellpy-mcp/ + .issueflows/ + 00-tools/ + 01-current-issues/ + issueXX_original.md + issueXX_status.md + 02-partly-solved-issues/ + 03-solved-issues/ + 04-designs-and-guides/ + 05-epics/ + epicXX_plan.md + pyproject.toml + readme.md + ... +``` + + +## Development information + + +### Working on issues + +After each iteration, update the documents in `.issueflows/01-current-issues` (should contain one file labelled `_original` with the original issue description, a `_plan` file with the confirmed approach, and supplementary status files describing what has been done, current status, and remaining work). +Use an explicit status checkbox in the status file: +- `- [x] Done` when fully resolved +- `- [ ] Done` when not fully resolved + +### Chat invocation (no slash) + +On keyboard layouts where `/` and `@` are awkward to type (for example Norwegian), invoke lifecycle skills in **chat** without special keys. + +**Primary form:** `iflow <step>` (space-separated) — e.g. `iflow plan`, `iflow pick`, `iflow close`. Plain `iflow` runs the smart dispatcher. + +**Also recognized** (same obligation as slash-menu invocation): hyphen form (`iflow-plan`), slash form (`/iflow-plan`), slash + space (`/iflow plan`). + +When the user message is **exactly** one of these forms, or **starts with** it followed by a space and trailing arguments, **read and follow** the matching skill immediately. Forward trailing text verbatim (e.g. `iflow pick fix` → `iflow-pick` with arg `fix`). Do **not** treat incidental mid-sentence mentions as commands — the message must **start with** the invocation. + +| Chat / slash form | Skill | +|-------------------|-------| +| `iflow` / `/iflow` | `iflow` (dispatcher) | + +| `iflow archive`, `iflow-archive`, `/iflow-archive`, `/iflow archive` | `iflow-archive` | + +| `iflow auto`, `iflow-auto`, `/iflow-auto`, `/iflow auto` | `iflow-auto` | + +| `iflow build`, `iflow-build`, `/iflow-build`, `/iflow build` | `iflow-build` | + +| `iflow capture`, `iflow-capture`, `/iflow-capture`, `/iflow capture` | `iflow-capture` | + +| `iflow cleanup`, `iflow-cleanup`, `/iflow-cleanup`, `/iflow cleanup` | `iflow-cleanup` | + +| `iflow close`, `iflow-close`, `/iflow-close`, `/iflow close` | `iflow-close` | + +| `iflow cycle`, `iflow-cycle`, `/iflow-cycle`, `/iflow cycle` | `iflow-cycle` | + +| `iflow doctor`, `iflow-doctor`, `/iflow-doctor`, `/iflow doctor` | `iflow-doctor` | + +| `iflow drive`, `iflow-drive`, `/iflow-drive`, `/iflow drive` | `iflow-drive` | + +| `iflow epic`, `iflow-epic`, `/iflow-epic`, `/iflow epic` | `iflow-epic` | + +| `iflow fix`, `iflow-fix`, `/iflow-fix`, `/iflow fix` | `iflow-fix` | + +| `iflow graphify`, `iflow-graphify`, `/iflow-graphify`, `/iflow graphify` | `iflow-graphify` | + +| `iflow init`, `iflow-init`, `/iflow-init`, `/iflow init` | `iflow-init` | + +| `iflow issue`, `iflow-issue`, `/iflow-issue`, `/iflow issue` | `iflow-issue` | + +| `iflow ops`, `iflow-ops`, `/iflow-ops`, `/iflow ops` | `iflow-ops` | + +| `iflow pause`, `iflow-pause`, `/iflow-pause`, `/iflow pause` | `iflow-pause` | + +| `iflow pick`, `iflow-pick`, `/iflow-pick`, `/iflow pick` | `iflow-pick` | + +| `iflow plan`, `iflow-plan`, `/iflow-plan`, `/iflow plan` | `iflow-plan` | + +| `iflow pr-sync`, `iflow-pr-sync`, `/iflow-pr-sync`, `/iflow pr-sync` | `iflow-pr-sync` | + +| `iflow review`, `iflow-review`, `/iflow-review`, `/iflow review` | `iflow-review` | + +| `iflow setup`, `iflow-setup`, `/iflow-setup`, `/iflow setup` | `iflow-setup` | + +| `iflow split`, `iflow-split`, `/iflow-split`, `/iflow split` | `iflow-split` | + +| `iflow status`, `iflow-status`, `/iflow-status`, `/iflow status` | `iflow-status` | + +| `iflow yolo`, `iflow-yolo`, `/iflow-yolo`, `/iflow yolo` | `iflow-yolo` | + + +Skill `@` attachment is supported on some editors but is not the recommended keyboard-friendly path. + +### Command lifecycle + + +If the project itself is not ready yet — no git repo, no remote, `gh` not authenticated, or no Python project — run **`/iflow-setup`** (or type **`iflow setup`** in chat) first. It reads `issue-flow agent setup-status`, works out whether this is a brand-new or an existing project, and walks the blockers one confirmation at a time. Off-path (never auto-dispatched). + + +If you have not chosen an issue yet, run **`/iflow-pick`** (or type **`iflow pick`** in chat) — the front door that helps you select the next issue (parked work first, else ranked open GitHub issues), creates the branch, and runs `/iflow-capture`. It is off-path (never auto-dispatched). + +If you just want the next right step, run **`/iflow`** (or type **`iflow`** in chat) — it detects state (by file presence under `.issueflows/01-current-issues/` and the status-file `- [x] Done` marker) and dispatches to `/iflow-capture`, `/iflow-plan`, `/iflow-build`, or `/iflow-close`. With no focus issue, it checks active-epic `next_candidates` (`agent state` → `epic_hint`) and **recommends** `/iflow-pick` instead of a blind capture — it never auto-dispatches to the off-path commands (`/iflow-pick`, `/iflow-init`, `/iflow-pause`, `/iflow-cleanup`, `/iflow-yolo`, `/iflow-ops`). + +The full slash-command lifecycle is: + +1. **`/iflow-capture`** — capture the GitHub issue as `issue<N>_original.md`. +2. **`/iflow-plan`** — design the approach in `issue<N>_plan.md` and get explicit confirmation before any code changes. +3. **`/iflow-build`** — implement the confirmed plan. Asks to run `/iflow-plan` first if the plan file is missing. +4. **`/iflow-pause`** *(optional)* — park work mid-stream: update status, move the issue group to `02-partly-solved-issues`, optional WIP commit. +5. **`/iflow-close`** — tests, optional `uv version --bump`, **changelog/`HISTORY.md` update (in the PR commit)**, status update, commit, push, PR. Does not delete branches. Never offer a HISTORY/CHANGELOG update after close finishes or after merge; use `nohistory` only to skip intentionally. (A draft opened earlier via `/iflow-build` early PR does not skip the close HISTORY step.) + +6. **`/iflow-cleanup`** — post-merge: switch to default, `git pull --ff-only`, `git fetch --prune`, `git branch -d` on reachable local branches under a single consolidated confirm. If ff-only fails, classify with `issue-flow agent default-sync` (never rebase / force-push / push default to skip CI). Squash-landed branches (which `-d` always refuses) need `git branch -D`, offered only behind a **second** confirm that lists tip SHAs; branches with unique work are never deleted. Trailing `include GitHub` (or similar) adds a remote-branch audit with a further confirm for optional remote deletes / findings issue. + + +`/iflow-yolo` chains `capture → plan → build → close yolo` for small, low-risk issues with up-front safeguards (clean tree, passing tests, single consolidated confirm). Its close step is hands-off: changelog decided without a prompt, PR merged (`gh pr merge --squash`; on pending checks may `gh pr checks --watch` then retry, with `--auto` as last resort), then default-branch switch + pull. + + +`/iflow-ops` runs **ops / no-PR** work (staging→prod, flag flips, external deploys): execute the checklist, then `/iflow-close ops` — no push/PR. Product-code dirty trees are refused. Off-path (never auto-dispatched). + + + +`/iflow-init` cold-starts or checks the issue-flow harness (guides `issue-flow init` / `update`). It does **not** capture GitHub issues — that is `/iflow-capture`. Off-path (never auto-dispatched). + + + +Issue labels can select the flow: when an issue picked via `/iflow-pick` carries the **`yolo`** label, it is routed through `/iflow-yolo` (one combined confirmation). The **`ops`** label routes to `/iflow-ops` (no PR); when both labels are present, **ops wins**. Controlled by `label_flows` (default `true`), `yolo_label` (default `"yolo"`), and `ops_label` (default `"ops"`) under `[issueflow]` in `.issueflows/config.toml`; re-run `issue-flow update` after changing them. + + + +Lifecycle skills include a **`### MODEL & EXECUTION DIRECTIVE`** section that tells agents whether to prioritize **economy** (speed) or **reasoning** (depth) for that step. Toggle with `step_directives` under `[issueflow]`; override per step via `[issueflow.step_profiles]`; optional label hints during `/iflow-pick` via `model_label_flows`, `deep_model_label`, and `fast_model_label`. Re-run `issue-flow update` after changing any of these. + + + +`/iflow-fix` opens an interactive iterative-fixes session: it creates one GitHub issue + long-lived branch, then loops over many small fixes (each gets a short plan and is implemented only on confirmation, recorded as a dated bullet in `issue<N>_status.md`), and ends with `/iflow-close`. It is off-path (never auto-dispatched); while a session is active, drive it with `/iflow-fix` + `/iflow-close`, not `/iflow`. With `fix_auto_name = false` (default), inventing a non-default slug asks once before the create confirm. Toggle via `fix_auto_name` under `[issueflow]` in `.issueflows/config.toml`; re-run `issue-flow update` after changing. + + +`/iflow-issue` creates **one well-specified normal GitHub issue** (context / spec / acceptance criteria), then optionally branches and runs `/iflow-capture` into the standard lifecycle. It fills the gap between `/iflow-fix` (iterative small-fixes) and `/iflow-epic` (multi-issue staged work). Off-path (never auto-dispatched). For an epic anchor: `/iflow-issue epic <intent>`. + + +`/iflow-split` cuts **one over-large existing issue** into 2–5 flat GitHub native sub-issues behind one consolidated confirm (parent stays open as the tracker). Off-path (never auto-dispatched). Staged work with dependencies still goes through `/iflow-epic`. `/iflow-pick` / `/iflow-issue` / `/iflow-plan` may *offer* split; they never create children themselves. + + +`/iflow-status` prints a **read-only** overview of where every issue stands — the local tracking state under `.issueflows/` (focus / parked / solved) plus open GitHub issues cross-referenced against it. It is off-path (never auto-dispatched) and changes nothing. + + +`/iflow-doctor` audits `.issueflows/` for **dirty** conditions (ambiguous multi-focus, leftovers in `01-current-issues/`, duplicates across folders, and similar) and can apply **safe repairs** on confirmation (`issue-flow doctor` / `agent audit` + `repair`). It is off-path and never auto-dispatched. + + +`/iflow-review` reviews open GitHub issues and applies labels (extendable kinds; v1: **yolo** → configured `yolo_label`). Off-path; consolidated confirm before any label create/apply; never auto-dispatched. CLI helpers: `issue-flow agent label-candidates` / `label-apply`. + + +`/iflow-epic <N>` plans a change **too large for one issue** as a staged epic: it drafts `.issueflows/05-epics/epic<N>_plan.md` (anchored to GitHub issue `<N>`), dividing the work into sequential stages of manageable issue specs with explicit dependencies and a per-issue yolo-fitness judgment. Drafting writes nothing on GitHub; **`/iflow-epic <N> publish [stage <k>]`** creates a confirmed stage's issues behind one consolidated confirm (yolo labels per the recorded judgment, task list maintained on the anchor issue, `Published: #<M>` recorded back into the plan so re-runs are idempotent). Off-path (never auto-dispatched); epics decompose into the normal single-issue lifecycle, never around it. + + +`/iflow-cycle <queue-spec>` processes **many issues hands-off in a row** under a single up-front confirmation — the batch equivalent of `/iflow-yolo`. It resolves a queue via `issue-flow agent queue` (explicit numbers, `label:<L>`, or `epic <N> [stage <k>]`), then runs each issue through the full yolo chain (PR auto-merged), interrupting you only when input is **strictly necessary** (unfixable failure, refused merge / non-fast-forward pull, ambiguous or not-actually-small spec, or anything outside the confirmed queue). It stops the whole cycle on the first such condition, leaving the repo clean on the default branch. **All yolo-labelled issues:** `/iflow-cycle yolo` (alias for `label:yolo`). Off-path (never auto-dispatched); never weakens a yolo safeguard to keep moving. + + +`/iflow-auto <N>` runs an **unattended large-change** path over a confirmed epic: select a stage, drive it via `/iflow-cycle`, record `auto_status.md`, then adversarial inter-epoch review (`review` token; may reopen/create issues under the overnight confirm). On findings, honour the loop budget (re-queue + re-review, or **stop and ask**: accept / grant N more loops / abort). Advance to stage `k+1` only when stage `k` is clear (`epic-status` done + no open blockers); otherwise `epoch_gated`. Budget baked as **2** (`loops:<n>` overrides). Off-path (never auto-dispatched). See `.issueflows/04-designs-and-guides/advanced-auto-mode.md`. + + +`/iflow-drive <N>` runs a **compose-only** path from an existing GitHub issue: draft epic (auto-confirm unless grill-me) → publish every stage → `/iflow-auto` each epoch → final review (create leftover findings) → local cleanup **`-d` only** → `/iflow-status`. One confirm covers draft-accept, publish-all, auto-all, final-review creates, and reachable-only cleanup. User `abort` / `stop` / `cancel` / `halt` stops at the next boundary. Off-path (never auto-dispatched). See `.issueflows/04-designs-and-guides/drive-mode.md`. + + +`/iflow-archive` condenses old solved issue groups under `.issueflows/03-solved-issues/` into a single dated `YYYY-MM-DD_archived_issues.md` summary file (recording the pre-archive git ref for recovery via `git show <ref>:<path>`), then deletes the original `issue<N>_*` files. It is off-path and destructive: nothing is deleted before one consolidated confirmation. + + +`/iflow-pr-sync` refreshes **open** PR heads that went `DIRTY` after another merge (usually `HISTORY.md`): worktree → `issue-flow agent sync-branch` keep-both → `git push --force-with-lease`. Off-path; see `.issueflows/04-designs-and-guides/pr-queue-sync.md` (issue #260). + + + +> On tools without project slash commands (e.g. Codex CLI), invoke the mirrored Agent Skills instead (for example `iflow-capture` in place of `/iflow-capture`). + +### When finishing an issue + +If the issue is fully resolved (no additional subtasks present), move the original, plan, and status markdown files to `.issueflows/03-solved-issues`. Else, move them to `.issueflows/02-partly-solved-issues`. + +### Scripts that can help us when working on issues + +`.issueflows/00-tools/` is the project's durable toolbox of reusable helper scripts, with a `README.md` index describing each one. + +- **Check it first.** Before writing a new one-off helper for an issue, skim the `00-tools/README.md` index and the folder — a suitable tool may already exist. +- **Contribute back.** If you build something during an issue that could help on a future one, save it into `.issueflows/00-tools/` and add a one-line entry to the index (name, what it does, when to use it) so the next agent knows whether to reach for it. + + + +### Optional response styles + +A **caveman** Agent Skill is installed under `.cursor/skills/caveman/`. It +is a terse, "token-greedy" response style that keeps all technical substance +while dropping filler, articles, and pleasantries. It is **off by default** and +only kicks in when the user asks for it (e.g. "caveman", "token greedy", "be +terse"). Turn it off with **"stop caveman"** or **"normal mode"**. Code, +commits, PRs, security warnings, and destructive-action confirmations are always +written in normal prose, never caveman. (To make caveman on by default for this +project, set `caveman_default = true` under `[issueflow]` in +`.issueflows/config.toml` and re-run `issue-flow update`.) + + + + +### Planning aids + +A **grill-me** Agent Skill is installed under `.cursor/skills/grill-me/`. +It runs a relentless planning interview that stress-tests a plan or design — +one question at a time, each with a recommended answer — until every branch of +the decision tree is resolved. It is **off by default** and only kicks in when +you ask for it (e.g. "grill me", "poke holes in this"). Turn it off with **"stop +grilling"** or **"normal mode"**. (To make grilling on by default during planning +for this project, set `grill_me_default = true` under `[issueflow]` in +`.issueflows/config.toml` and re-run `issue-flow update`.) + + + + +### CI via GitHub CLI + +A **gh-ci** Agent Skill is installed under `.cursor/skills/gh-ci/`. Use +it whenever you need to know if CI finished: prefer `gh pr checks` / +`gh pr checks --watch --fail-fast` (budget: `checks_watch_minutes`, default +15); fall back to `gh run list` / `gh run watch` when PR +checks are empty. Always pass `--repo <owner/repo>`. `/iflow-close` owns the +merge sequence; this skill is the shared command cheatsheet. + + + +### Designs and guides + +Long-lived design docs, design decisions, and project "good practices" live under `.issueflows/04-designs-and-guides/`. Unlike the issue folders, content here is **not** tied to a single issue and is **not** archived when an issue closes — it is the project's durable memory. + +- **Project brief:** if `.issueflows/04-designs-and-guides/this-project.md` exists, read it early for project-specific context (what the repo is, stack/runtime, how to run/test, conventions, entry points, and known limitations). +- **Before planning or implementing**, skim `.issueflows/04-designs-and-guides/` for existing docs relevant to the current issue and follow them (cite them in the plan when they influence the approach). +- **When a non-trivial design decision is made** during `/iflow-plan` or `/iflow-build`, add or update a markdown file here. Keep entries terse: context, the decision, alternatives considered, and a link back to the issue. +- **Never overwritten by `issue-flow update`.** The folder is recreated if missing, but existing files are left alone. + + +### Multi-root workspaces + +When an editor workspace contains **multiple sibling repositories**, each with its own `.issueflows/` scaffold: + +- **Resolve the target repo first** — explicit `root:` / `repo:` hints, then `issue-flow agent resolve`, then branch/single-scaffold heuristics, then the **workspace default** from `issueflow-workspace.toml` at the workspace root (create it with `issue-flow workspace init`); **ask** when still ambiguous. Never let `git` or `gh` infer the repo from cwd alone. +- **Scoped rules** — this repo's `issueflow-rules` apply under this project root only (path globs). Put **toolchain-specific** run/test commands in `.issueflows/04-designs-and-guides/this-project.md`, not in shared boilerplate that every repo merges. +- **Per-repo lifecycle** — `/iflow-cleanup`, branch hygiene, and focus issue folders are **per repository**; repeat commands in each repo when needed. +- **Design doc** — see `.issueflows/04-designs-and-guides/multi-repo-workspaces.md` when present (issue #67). + + +### Branch hygiene + +- Do issue work on an **issue branch** named like `<N>-<short-slug>`, not on the default branch. +- Before starting or continuing work on an issue branch, run `git fetch --prune` and check where the branch sits relative to `origin/<default>` (ahead/behind). A branch that is "several commits ahead" after a merged PR usually means the PR was merged (this project uses **`squash`**) and the local branch is stale. +- **Assume `squash` merges on GitHub.** After a PR merges, **remind** the user to run **`/iflow-cleanup`** (switch to default, `git pull --ff-only`, `git fetch --prune`, `git branch -d` on reachable locals under one confirm, plus a second confirm for the squash-landed branches that `-d` can never take). Do **not** auto-run cleanup from close/yolo/cycle; `/iflow-close` no longer does this step itself. + +- If an issue is already archived under `.issueflows/02-partly-solved-issues` or `.issueflows/03-solved-issues`, the matching local branch is stale; don't resume work on it silently — switch back to the default branch and, if the issue really needs re-opening, do it deliberately through `/iflow-capture` (which will ask for a second confirmation). + + +### Folder hygiene for `.issueflows/01-current-issues` + +- Only the **focus issue** (the one currently being worked on) should live in `.issueflows/01-current-issues`. +- `/iflow-capture` and `/iflow-build` both sweep that folder automatically: every `issue<n>_*` group **other than the focus issue** is moved to `.issueflows/03-solved-issues` if a status file contains `- [x] Done`, otherwise to `.issueflows/02-partly-solved-issues`. Keep status files accurate so the sweep routes them correctly. + + +### Knowledge graph (optional, via [graphify](https://iflow-graphify.net)) + +If a `graphify-out/` folder exists in the project root, the project has the optional [graphify](https://iflow-graphify.net) integration enabled and a knowledge graph is available alongside the source. + +- **Before grepping**, skim `graphify-out/GRAPH_REPORT.md`. It surfaces god-nodes (most-connected concepts), surprising cross-module connections, and suggested questions the graph can answer — often a faster way to locate the files an issue actually touches than full-text search. +- **`/iflow-graphify`** (slash command) or **`issue-flow graphify`** (CLI) rebuild the graph. With no extra args this runs `graphify update <project>` — AST-only, **no LLM API key needed**. For richer semantic relationships (cross-file links surfaced by an LLM pass), run `issue-flow graphify extract` after setting `GEMINI_API_KEY` / `ANTHROPIC_API_KEY` / `OPENAI_API_KEY` / `MOONSHOT_API_KEY` (or pass `--backend ollama` for a local LLM). Other subcommands: `watch` (live), `cluster-only --no-viz` (re-cluster). Trailing flags pass through verbatim. Your agent's own LLM cannot be reused by subprocesses; graphify needs its own backend. +- `/iflow-graphify` is **off-path**: never auto-dispatched by `/iflow`, `/iflow-build`, or `/iflow-close`. It is the user's call. `/iflow-build` may *suggest* skimming `GRAPH_REPORT.md`; `/iflow-close` may *suggest* a rebuild after large structural changes — neither runs `graphify` automatically. +- If `graphify-out/` is not present, ignore graph-related guidance entirely. The integration is opt-in (install with `uv tool install graphifyy`, then `issue-flow update` to register the graphify skill). + +<!-- END issue-flow (managed) --> diff --git a/docs/issue-workflow.md b/docs/issue-workflow.md new file mode 100644 index 0000000..3f714ac --- /dev/null +++ b/docs/issue-workflow.md @@ -0,0 +1,639 @@ +# Cursor issue workflow (Agent Skills) + +This repo uses Cursor **Agent Skills** under `.cursor/skills/` that line up with how we track GitHub issues in `.issueflows/01-current-issues/`. Skills appear in the slash menu as `/iflow`, `/iflow-plan`, and friends — or type **`iflow plan`** (space, no slash) in chat when `/` is awkward on your keyboard. + +> **Keyboard-friendly chat:** type **`iflow plan`**, **`iflow pick`**, **`iflow close`**, etc. in chat (letters + space only). Slash menu still uses `/iflow-plan`. Hyphen form `iflow-plan` also works. Norwegian and similar layouts often lack a dedicated `/` key; `@` is awkward too — the space form is intentional. + +**Quick start:** type **`iflow`** in chat or run **`/iflow`** from the slash menu. It inspects the state of the focus issue and dispatches to the right linear-flow skill (`iflow capture` / `/iflow-capture`, `iflow plan` / `/iflow-plan`, `iflow build` / `/iflow-build`, or `iflow close` / `/iflow-close`) — so you don't have to remember which step is next. Haven't chosen an issue yet? Start with **`iflow pick`** or **`/iflow-pick`**. + + +**Brand new to this?** If the project itself is not ready yet — no Python project, no git repo, no GitHub remote, or `gh` not signed in — start with **`iflow setup`** (or **`/iflow-setup`**) instead. It reports what is missing and walks you through each gap one confirmation at a time, for a fresh folder as well as an existing codebase. Run `issue-flow agent setup-status` yourself any time you want the same report without the conversation. + + +`issue-flow init` also creates a durable project brief at `.issueflows/04-designs-and-guides/this-project.md` when it is missing. Edit it by hand with project-specific context; `issue-flow update` and `issue-flow init --force` leave existing content untouched. + +It also seeds `.issueflows/00-tools/README.md` — the index of the project's **shared toolbox**. Drop reusable helper scripts there during issue work and add a one-line index entry; check the folder before writing a new one-off helper. Like the project brief, this README is never overwritten by `issue-flow update`, so its index grows over time. + +**Multi-root workspaces:** parent folder of git siblings — `issue-flow workspace bootstrap --yes --default <member>` (first time), `workspace init` (toml only), `workspace update` (refresh). Public recipe: https://issue-flow.readthedocs.io/how-to/workspaces/. When several sibling repos share one editor workspace, resolve the target repo first (`root:` / `repo:` hints, or `issue-flow agent resolve`). A workspace-root `issueflow-workspace.toml` names a **default member repo** used when a command runs from outside any single scaffold. Never let `git` or `gh` infer the repository from cwd alone. See `.issueflows/04-designs-and-guides/multi-repo-workspaces.md` when present. `/iflow-pick` / `/iflow-issue` / `/iflow-fix` start in a sibling worktree (`issue-flow agent worktree-add`) so the home checkout stays on default; starting does **not** require home default to fast-forward (`issue-flow agent default-sync`; see `04-designs-and-guides/default-branch-diverge.md`). `open-workspace` prints the path (see `04-designs-and-guides/separate-workspaces.md`). Token `inplace` keeps the old in-place `git switch -c`. + + +| Entry point | File | Role | +|--------|------|------| +| `/iflow-setup` | `iflow-setup/SKILL.md` | **Off-path.** Guided first-time setup: check what is missing (Python project, git repo, GitHub remote, `gh` login, scaffold) via `issue-flow agent setup-status`, then walk the gaps one confirmation at a time. For new *and* existing projects. | +| `/iflow-pick` | `iflow-pick/SKILL.md` | **Front door.** Help choose the next issue (parked work first, else ranked open GitHub issues), create the branch, and run `/iflow-capture`. Off-path; never auto-dispatched. | +| `/iflow` | `iflow/SKILL.md` | **Smart dispatcher.** Detect current state and run `/iflow-capture`, `/iflow-plan`, `/iflow-build`, or `/iflow-close` automatically. Never auto-dispatches to setup / pick / pause / cleanup / yolo / fix / issue / split / status / archive / epic / cycle / auto / graphify / init. | +| `/iflow-init` | `iflow-init/SKILL.md` | **Off-path.** Cold-start or check the issue-flow harness (guide `issue-flow init` / `update`, or `workspace bootstrap` for a parent folder of git siblings). Also installed user-global. Does **not** capture GitHub issues — that is `/iflow-capture`. | +| `/iflow-capture` | `iflow-capture/SKILL.md` | Pull an issue from GitHub into the repo as a local markdown file and tidy older current issues. | +| `/iflow-plan` | `iflow-plan/SKILL.md` | Write a structured `issue<N>_plan.md` and get explicit user confirmation before any code is touched. | +| `/iflow-build` | `iflow-build/SKILL.md` | Implement the confirmed plan (no planning step of its own any more). Optional early draft PR (`early_pr` / trailing `early`). | +| `/iflow-pause` | `iflow-pause/SKILL.md` | Park work safely: update status, move the issue group to `02-partly-solved-issues/`, optional WIP commit and branch switch. | +| `/iflow-close` | `iflow-close/SKILL.md` | Finish: tests, optional semver bump (`uv version --bump …`), `HISTORY.md` update, issue-folder housekeeping, commit, push, PR, and switch back to default when clean unless `stay` is passed. | +| `/iflow-cleanup` | `iflow-cleanup/SKILL.md` | Post-merge hygiene: switch to default, `git pull --ff-only`, `git fetch --prune`, delete merged local branches (single consolidated confirm). Optional `include GitHub` runs a remote-branch audit (second confirm). | +| `/iflow-yolo` | `iflow-yolo/SKILL.md` | All-in-one for small, low-risk issues: chains `capture → plan → build → close` with up-front safeguards and a single confirmation. | +| `/iflow-ops` | `iflow-ops/SKILL.md` | **Off-path.** Ops / no-PR work (staging→prod, flag flips, external deploys): checklist then `/iflow-close ops`. | +| `/iflow-fix` | `iflow-fix/SKILL.md` | **Off-path.** Interactive iterative-fixes session: create one issue + long-lived branch, then loop over many small fixes (short plan each, recorded in `issue<N>_status.md`), ending with `/iflow-close`. | +| `/iflow-issue` | `iflow-issue/SKILL.md` | **Off-path.** Create one well-specified normal GitHub issue (context / spec / acceptance), then optionally branch + `/iflow-capture` into the standard lifecycle. Epic anchors: `/iflow-issue epic …`. | +| `/iflow-split` | `iflow-split/SKILL.md` | **Off-path.** Cut one over-large existing issue into 2–5 flat GitHub native sub-issues (confirm-gated). Parent stays open as the tracker. Staged work → `/iflow-epic`. | +| `/iflow-status` | `iflow-status/SKILL.md` | **Off-path, read-only.** Snapshot of where every issue stands — local tracking state (focus / parked / solved) plus open GitHub issues cross-referenced against it. Changes nothing. | +| `/iflow-doctor` | `iflow-doctor/SKILL.md` | **Off-path.** Audit `.issueflows/` for dirty conditions; optional safe repair (mkdir + sweep). | +| `/iflow-review` | `iflow-review/SKILL.md` | **Off-path.** Review open GitHub issues and apply labels (extendable kinds; v1: yolo → configured `yolo_label`). Confirm before writes. | +| `/iflow-archive` | `iflow-archive/SKILL.md` | **Off-path, destructive (gated).** Condense old solved issue groups into a dated `YYYY-MM-DD_archived_issues.md` summary (recording the pre-archive git ref for recovery), then delete the original files after one consolidated confirm. | +| `/iflow-epic` | `iflow-epic/SKILL.md` | **Off-path.** Plan a larger change as a staged epic: `05-epics/epic<N>_plan.md` divides the work into stages of manageable issue specs (dependencies + per-issue yolo judgment). Drafting writes nothing on GitHub; `publish [stage <k>]` creates a confirmed stage's issues behind one consolidated confirm and maintains a task list on the anchor issue. | +| `/iflow-cycle` | `iflow-cycle/SKILL.md` | **Off-path.** Process a queue of yolo-fit issues hands-off in a row under one up-front confirm — the batch equivalent of `/iflow-yolo`. Resolves the queue via `issue-flow agent queue`, runs each issue through the full yolo chain (PR auto-merged), and stops only when input is strictly necessary. **All yolo-labelled issues:** `/iflow-cycle yolo` (alias for `label:yolo`). | +| `/iflow-auto` | `iflow-auto/SKILL.md` | **Off-path.** Unattended large-change orchestrator over a confirmed epic: cycle a stage via `/iflow-cycle`, record `auto_status.md`, run adversarial review (`review`; may reopen/create). Loop budget **2** (`[issueflow].auto_adversarial_loops`); override `loops:<n>`. See `.issueflows/04-designs-and-guides/advanced-auto-mode.md`. | +| `/iflow-drive` | `iflow-drive/SKILL.md` | **Off-path.** Compose-only path from an existing issue: draft epic (auto-confirm unless grill-me) → publish all stages → `/iflow-auto` each epoch → final review (create leftover findings) → local cleanup **`-d` only** → `/iflow-status`. See `.issueflows/04-designs-and-guides/drive-mode.md`. | +| `/iflow-graphify` | `iflow-graphify/SKILL.md` | **Off-path.** Rebuild the [graphify](https://iflow-graphify.net) knowledge graph (`graphify-out/graph.html`, `GRAPH_REPORT.md`, `graph.json`). Wraps `issue-flow graphify` / `graphify`. Optional: only meaningful when `graphifyy` is installed. | + + + +--- + +## Agent Skills + +`issue-flow init` / `issue-flow update` install **Cursor Agent Skills** under `.cursor/skills/` — longer, on-demand playbooks (plus a small helper for version bumps): + +| Skill folder | Invoke (examples) | Role | +|--------------|-------------------|------| +| `iflow-setup` | `iflow setup`, `iflow-setup`, `/iflow-setup` | Guided first-time project setup. Off-path. | +| `iflow-pick` | `iflow pick`, `iflow-pick`, `/iflow-pick` | Front door — choose issue, branch, init, hand off. | +| `iflow` | `iflow`, `/iflow` | Smart dispatcher — same state machine as `/iflow`. | +| `iflow-init` | `iflow init`, `iflow-init`, `/iflow-init` | Cold-start / check harness. Off-path. | +| `iflow-capture` | `iflow capture`, `iflow-capture`, `/iflow-capture` | Capture GitHub issue as `issue<N>_original.md`. | +| `iflow-plan` | `iflow plan`, `iflow-plan`, `/iflow-plan` | Write & confirm `issue<N>_plan.md`. | +| `iflow-build` | `iflow build`, `iflow-build`, `/iflow-build` | Implement from `.issueflows/01-current-issues/`. | +| `iflow-pause` | `iflow pause`, `iflow-pause`, `/iflow-pause` | Park work in `02-partly-solved-issues/`. | +| `iflow-close` | `iflow close`, `iflow-close`, `/iflow-close` | Tests, bump, commit, push, PR. | +| `iflow-cleanup` | `iflow cleanup`, `iflow-cleanup`, `/iflow-cleanup` | Post-merge branch cleanup; optional `include GitHub` remote audit. | +| `iflow-yolo` | `iflow yolo`, `iflow-yolo`, `/iflow-yolo` | Chain `capture → plan → build → close`. | +| `iflow-ops` | `iflow ops`, `iflow-ops`, `/iflow-ops` | Ops / no-PR work; ends with `/iflow-close ops`. Off-path. | +| `iflow-fix` | `iflow fix`, `iflow-fix`, `/iflow-fix` | Interactive iterative-fixes session. Off-path. | +| `iflow-issue` | `iflow issue`, `iflow-issue`, `/iflow-issue` | Create one well-specified normal GitHub issue. Off-path. | +| `iflow-split` | `iflow split`, `iflow-split`, `/iflow-split` | Split an over-large issue into linked sub-issues. Off-path. | +| `iflow-status` | `iflow status`, `iflow-status`, `/iflow-status` | Read-only issue overview. Off-path. | +| `iflow-doctor` | `iflow doctor`, `iflow-doctor`, `/iflow-doctor` | Audit/repair dirty `.issueflows/`. Off-path. | +| `iflow-review` | `iflow review`, `iflow-review`, `/iflow-review` | Review open issues and apply labels (v1: yolo). Off-path. | +| `iflow-epic` | `iflow epic`, `iflow-epic`, `/iflow-epic` | Staged epic plan + publish. Off-path. | +| `iflow-cycle` | `iflow cycle`, `iflow-cycle`, `/iflow-cycle` | Batch yolo queue (`yolo` / `label:<L>` / numbers / epic). Off-path. | +| `iflow-auto` | `iflow auto`, `iflow-auto`, `/iflow-auto` | Unattended epic orchestration (cycle stage + adversarial `review`). Off-path. | +| `iflow-drive` | `iflow drive`, `iflow-drive`, `/iflow-drive` | Compose epic → publish → auto-all → final review → local `-d` cleanup → status. Off-path. | +| `iflow-archive` | `iflow archive`, `iflow-archive`, `/iflow-archive` | Condense solved archive. Off-path; destructive. | +| `iflow-version-bump` | `@iflow-version-bump` (often used from `/iflow-close`) | Strategy-aware version bump: static `[project]` versions via `uv version --bump <level>` (any uv level: `major`/`minor`/`patch`/`stable`/`alpha`/`beta`/`rc`/`post`/`dev`); git-tag-derived versions via a planned post-merge tag. The project's own "Release & version bump" section in `this-project.md` wins; a bare `bump` stays on the current pre-release channel. | +| `iflow-history-update` | `@iflow-history-update` (used from `/iflow-close`) | Append an entry to `## [Unreleased]` in `HISTORY.md`, or promote it to a new `## [x.y.z] - YYYY-MM-DD` release section when a version bump happened. | +| `iflow-graphify` | `iflow graphify`, `iflow-graphify`, `/iflow-graphify` | Rebuild the graphify knowledge graph. Off-path. | + +Each skill sets `disable-model-invocation: true` so it is included when you **explicitly** invoke it, not on every chat. Every rendered `SKILL.md` also carries `issue-flow-version: <version>` in its YAML frontmatter (the package version at last `issue-flow init` / `issue-flow update`). Compare with `issue-flow --version`; if they differ, re-run `issue-flow update`. See [Agent Skills](https://cursor.com/help/customization/skills) in the Cursor docs. + +Lifecycle skills also carry a **`### MODEL & EXECUTION DIRECTIVE`** — **economy** (speed/token savings) or **reasoning** (design depth) — baked at `issue-flow update` from `[issueflow]` / `[issueflow.step_profiles]` in `.issueflows/config.toml`. `/iflow-pick` can announce label-based session overrides when `model_label_flows` is enabled (`deep_model_label` / `fast_model_label`). + + +--- + +## Branch and folder hygiene + +Two recurring pain points the workflows actively help with: + +- **Stale local branches that look "several commits ahead of main" after a merged PR.** `/iflow-close` switches back to the default branch after opening or updating the PR when the tree is clean, unless you pass `stay` / `don't switch`. `/iflow-cleanup` detects merge status after the PR is merged and offers (with one consolidated confirm) to `git fetch --prune` and run `git branch -d` on every local branch reachable from the default branch. Squash-landed branches are unreachable by definition, so `-d` refuses them; cleanup collects those into a **second, dedicated confirm** for `git branch -D` that prints each tip SHA (restore with `git branch <name> <tip>`). Branches with unique commits are never offered for deletion. +- **Left-overs in `.issueflows/01-current-issues/`.** Both `/iflow-capture` (when a new issue is captured) and `/iflow-build` (before implementation begins) sweep that folder: every `issue<n>_*` group **other than the focus issue** is moved automatically to `.issueflows/03-solved-issues/` if a status file contains `- [x] Done`, otherwise to `.issueflows/02-partly-solved-issues/`. + +All workflows that touch git also run a short **branch-status preflight**: `git fetch --prune`, current branch, ahead/behind vs the default branch, and a warning when the current branch's leading digits refer to an issue already archived in `02-`/`03-`. + +--- + +## 0a. `/iflow-pick` — choose the next issue (front door) + +**When:** You are on the default branch with nothing in progress and want help deciding what to work on next. + +**What you pass:** Nothing (survey + ask), `fix` (create a new general-fixes issue every time), `label:<L>` (hard-filter the shortlist to open issues with that GitHub label), or a hint (`milestone v0.4`, a topic) to soft-bias ranking when `label:` is absent. Free-form text that names a label is not a hard filter — use the `label:` token. Empty filter → stop. Batch the same filter with `/iflow-cycle label:<L>` (or `/iflow-cycle yolo`). + +**What the assistant does (three phases):** + +1. **Choose.** Prefers parked work in `.issueflows/02-partly-solved-issues/`; otherwise lists open GitHub issues (`gh issue list`) ranked by **milestone**, **labels**, and **topical similarity** to recently solved issues, then asks you to confirm a pick from a short shortlist. With `label:<L>`, hard-filters that shortlist (`--label <L>` on GitHub; parked/epic only if they carry `<L>`). `fix` skips the survey and creates a new `chore: general fixes` issue. +2. **Branch.** Requires a clean tree (or, when the only dirt is under `.issueflows/`, offers a default housekeeping commit first — typical after `/iflow-doctor`), then branches off the default with the GitHub numeric convention `git switch -c <N>-<short-slug>`, then runs the `/iflow-capture` flow automatically for `<N>`. +3. **Hand off.** When `auto_plan` is true (default), chains into `/iflow-plan` after capture; otherwise asks first. Trailing `noplan` skips the chain once. + +**Over-large issues:** if the chosen issue is too big for one PR, `/iflow-pick` **offers** `/iflow-split` (flat parent/child) or `/iflow-epic` (staged). It does not create children itself. + +**Off-path:** `/iflow` never auto-dispatches to `/iflow-pick`; it creates GitHub issues and branches, so you opt in explicitly. + +**Result:** A chosen issue captured on a fresh `<N>-<slug>` branch, ready for `/iflow-plan`. + +--- + +## 0. `/iflow` — smart dispatcher (quick start) + +**When:** Any time you want the next right step without remembering which specific command applies. + +**What you pass:** Nothing, or the same arguments the target command would take (e.g. `/iflow 42` on a fresh branch, `/iflow bump minor` when the issue is done). `/iflow` forwards the trailing text verbatim. + +**How it decides:** + +| State of the focus issue | Dispatches to | +|--------------------------|---------------| +| No focus, but an active epic has `next_candidates` (`agent state` → `epic_hint`) | **Stop** — list candidates; recommend `/iflow-pick` (never auto-pick) | +| No `issue<N>_original.md` (or no focus / no epic candidates) | `/iflow-capture` | +| `original` exists, no `issue<N>_plan.md` | `/iflow-plan` | +| Plan exists, status file missing or `- [ ] Done` | `/iflow-build` | +| Status file contains `- [x] Done` | `/iflow-close` | + +**Focus-issue resolution:** prefer the leading digits of the current branch when it matches `^<N>-.+`; else the single group in `.issueflows/01-current-issues/`; else the epic gap check; else ask. See `04-designs-and-guides/iflow-epic-awareness.md`. + +**Not auto-dispatched:** `/iflow-setup`, `/iflow-init`, `/iflow-pause`, `/iflow-cleanup`, `/iflow-yolo`, `/iflow-ops`, `/iflow-fix`, `/iflow-issue`, `/iflow-split`, `/iflow-status`, `/iflow-doctor`, `/iflow-review`, `/iflow-epic`, `/iflow-cycle`, `/iflow-auto`, `/iflow-drive`, and `/iflow-archive`. `/iflow` will mention them in its output when relevant (e.g. "after the PR merges, run `/iflow-cleanup`") but never picks them for you. The epic gap only **recommends** `/iflow-pick`. + +**Result:** One of the four linear commands runs (with its own checkpoints), or a stop with epic candidates listed. + +--- + +## 1. `/iflow-capture` — capture the issue locally + +**When:** You have a GitHub issue you want to work on (or archive older "current" issues before starting a new one). + +**What you pass:** Either an issue number (e.g. `42`), a full GitHub issue URL, or nothing after `/iflow-capture`—in that case, on a branch named like `42-short-description`, the assistant may ask to use `#42` from the branch (and refuses to guess on `main`/`master`). The assistant resolves `owner/repo` from `git remote origin` when you only pass a number. + +**What happens:** + +- The assistant uses **GitHub CLI** (`gh`) to fetch title, body, URL, and number. You need `gh` authenticated (`gh auth login` if needed). +- It creates **`.issueflows/01-current-issues/issue<number>_original.md`** with the title, source URL, and the **exact** issue body from GitHub. +- **Archive:** Other files already in `.issueflows/01-current-issues/` (grouped by issue number, e.g. `issue121_*`) may be **moved** to `.issueflows/02-partly-solved-issues/` or `.issueflows/03-solved-issues/`, based on whether a status file for that issue contains a checked **Done** line (`- [x] Done`). The new issue's files are never moved as part of this step. +- If the target `issue<number>_original.md` already exists, the assistant should not overwrite it without asking. + +**Result:** One canonical "original issue" file under `.issueflows/01-current-issues/` plus optional archive moves. + +> **Rename note (#241):** older docs and muscle memory used `/iflow-init` for this step. That name now cold-starts the harness (off-path). Use **`/iflow-capture`** to pull an issue. + +--- + +## 1a. `/iflow-init` — cold-start the harness (off-path) + +**When:** A project has no `.issueflows/` / no issue-flow skills yet, a parent folder of git siblings needs `workspace bootstrap`, or you want to check that the harness is present. + +**What happens:** On a parent folder of two or more own-git children, classifies with `issue-flow workspace bootstrap --json` and confirm-runs `--yes`. Otherwise guides `issue-flow init` (confirm before running if the CLI is on `PATH`). If the harness is already there, points at `issue-flow update`, `/iflow-doctor`, `/iflow-pick`, and `/iflow-capture`. Never captures a GitHub issue. + +**Off-path:** `/iflow` never auto-dispatches here. + +--- + +## 2. `/iflow-plan` — design the approach + +**When:** The issue is captured (`*_original.md` exists) and you want a confirmed plan **before** any code changes. + +**What you pass:** Optional free-form hints (constraints, design preferences). + +**What the assistant does:** + +1. Finds the focus issue in `.issueflows/01-current-issues/`. +2. Runs the branch-status preflight (non-destructive). +3. Reads the original issue and any prior status; reads `.issueflows/04-designs-and-guides/this-project.md` when present and consults other files under `.issueflows/04-designs-and-guides/` when relevant. +4. **Prior-art discovery** — skim `.issueflows/00-tools/` for an existing helper; if `graphify-out/GRAPH_REPORT.md` exists, skim God Nodes / Communities / Suggested Questions for the affected area; grep for adjacent helpers; record findings under **`### Prior art`** in **`## Constraints`** (or `- None found (toolbox + grep + graph checked).`). Strong overlaps become **Open questions**. +5. Explores read-only, then writes **`issue<N>_plan.md`** with sections: **Goal**, **Constraints** (including **Prior art**), **Approach**, **Files to touch**, **Test strategy**, **Open questions**. +6. Runs a scope check — if the change is broad, proposes splitting into smaller issues or phases. +7. **Stops and asks for explicit confirmation**: accept, revise, or abort. When `auto_build` is true (default), **Accept** chains into `/iflow-build`; trailing `nobuild` skips once. Planning itself still writes no code before Accept. + +**Result:** A confirmed `issue<N>_plan.md` ready for `/iflow-build` to execute. + +--- + +## 3. `/iflow-build` — implement the plan + +**When:** The issue has a confirmed `issue<N>_plan.md` (from `/iflow-plan`) and you are ready to code. + +**What you pass:** Optional implementation hints. Early-PR tokens: `early` / `pr` (force on), `noearly` (force off). Precedence: trailing > baked `[issueflow].early_pr` (default **False**) > `false`. + +**What the assistant does:** + +1. Confirms **which** issue file applies if several exist or things are ambiguous. +2. **Branch status preflight** — `git fetch --prune`, report current branch and ahead/behind vs the default branch, warn if the current branch looks stale or if you are still on the default branch. +3. **Sweeps stale current issues** — moves every `issue<n>_*` group **other than the focus issue** to `.issueflows/03-solved-issues/` (done) or `.issueflows/02-partly-solved-issues/` (not done). +4. **Plan precondition** — reads `issue<N>_plan.md`. If missing, asks the user to choose: run `/iflow-plan` now, proceed without a plan (note in status file), or abort. Does **not** hard-stop. +5. **Seeds `issue<N>_status.md` up front** (unchecked `- [ ] Done`, **What's done** / **Remaining work**) and keeps it current as work progresses — it lives *during* the work, not just at close. +6. **Implements** the plan, using `.issueflows/04-designs-and-guides/this-project.md` and relevant design docs for project context when present. Reuses helpers from `.issueflows/00-tools/` and contributes new reusable ones back there. +7. **Early pull request (optional)** — when early PR is on, after the first successful push: `gh pr list` then `gh pr create --draft` with `Refs #N`; record the PR in the status file. Does **not** write `HISTORY.md` (close owns that). + +**Result:** Implementation aligned with the confirmed plan and project rules (tests with `uv run`, dependency management with `uv`, etc.), optionally with a draft PR already open. + +--- + +## 4. `/iflow-pause` — park work safely + +**When:** You need to stop partway through an issue (context switch, blocked on input) without closing it. + +**What you pass:** Optional short note that becomes the **Remaining work** text. + +**What the assistant does:** + +1. Updates `issue<N>_status.md` with **Done so far**, **Remaining work**, and **Paused on** sections. The `- [ ] Done` checkbox stays unchecked. +2. Moves the whole `issue<N>_*` group from `.issueflows/01-current-issues/` to `.issueflows/02-partly-solved-issues/`. +3. Offers, as **one** consolidated prompt, a WIP commit and/or `git switch <default>`. Never deletes branches, never force-pushes, never runs tests. + +**Result:** The issue is safely archived under `02-partly-solved-issues/` with clear resume notes. Re-open via `/iflow-capture <N>` (which will ask for the archived-issue confirmation). + +--- + +## 5. `/iflow-close` — land the work + +**When:** Implementation is done and you want to ship (commit, push, PR). Post-merge branch cleanup is a **separate** step — see `/iflow-cleanup` below. + +**What you pass:** Optional notes (branch name, PR title, draft PR, or "skip issue doc update"). You can also ask for a **semver bump** in the same line, for example: + +- `/iflow-close bump` — **pre-release-aware default**: stays on the current channel (alpha→alpha, beta→beta, rc→rc, dev→dev) or `patch` when the version is already stable. +- `/iflow-close <level>` — any uv level: `patch`, `minor`, `major`, `stable`, `alpha`, `beta`, `rc`, `post`, `dev` (e.g. `/iflow-close minor`, `/iflow-close beta`). `dev` must be paired, e.g. `/iflow-close bump patch dev`. +- Free text that clearly describes the bump level — the assistant infers the level (e.g. "bugfix release" → `patch`, "promote to beta" → `beta`); it never auto-picks `major`. +- `/iflow-close nohistory` (or `skip history`) — skip the `HISTORY.md` update step for this run. +- `/iflow-close log "one-line summary"` (or `note "..."`) — override the `HISTORY.md` bullet summary instead of using the GitHub issue title. +- `/iflow-close stay` (or `stay on branch`, `don't switch`, `dont switch to main`) — skip the safe default-branch switch after the PR step. +- `/iflow-close draft` — create with `gh pr create --draft` (or leave an existing PR draft); skips yolo merge. + +The bump runs **after** tests and **before** issue-folder moves and **before** commit / push / PR so the PR includes the new version. If `pyproject.toml` has no bumpable version, the assistant skips the bump and continues. + +**Typical steps the assistant follows:** + +1. **Sanity check** — e.g. `uv run pytest`, review the diff. +2. **Optional version bump** — if requested, follow `.cursor/skills/iflow-version-bump/SKILL.md`. It resolves the project's **release strategy** first (the "Release & version bump" section of `.issueflows/04-designs-and-guides/this-project.md`, else `pyproject.toml` detection): static versions are bumped with `uv version --bump …` from the project root; **git-tag derived** versions (setuptools-scm and friends) get a **planned tag** instead — created after the merge (by `/iflow-cleanup`, or the yolo close's post-merge step), never on the issue branch. +3. **Update `HISTORY.md`** — unless `nohistory` was passed, follow `.cursor/skills/iflow-history-update/SKILL.md`. Append a bullet to `## [Unreleased]` (no bump) or promote `## [Unreleased]` to `## [<new_version>] - <YYYY-MM-DD>` and open a fresh empty `## [Unreleased]` above it (with bump). The bullet is staged in the **same commit** that feeds (or updates) the PR — including when a draft was opened earlier via `/iflow-build` early PR. Never offered after close finishes or after merge. With `confirm_changelog_update = false` (the default), the assistant writes without asking (same as the `yolo` token's history behaviour). If `HISTORY.md` is missing at the project root, the step is skipped with a note — never auto-created. + +4. **Issue folders** — update status markdown; use `- [x] Done` only when fully resolved. Move completed issue files from `.issueflows/01-current-issues/` to `.issueflows/03-solved-issues/`, or partly done work to `.issueflows/02-partly-solved-issues/`. +5. **Commit** — focused staging and a clear message (include `pyproject.toml` / `uv.lock` if the bump changed them, and `HISTORY.md` when step 3 updated it). +5a. **Sync with the default branch** — `issue-flow agent sync-branch --json` replays the issue branch onto `origin/<default>` so commits that landed while the issue was in flight are included instead of surfacing as a conflicted PR at merge time. A conflict confined to `HISTORY.md`, where both sides only added `## [Unreleased]` bullets, is resolved by keeping them all (the in-flight issue's bullet last); any other conflict aborts the rebase and stops close. +6. **Push** — to your usual remote (e.g. `origin`); `--force-with-lease` when the sync rebased the branch. +7. **Pull request** — `gh pr list --head <branch>` first (reuse an open PR, including an early draft); else `gh pr create` (with `--draft` when the `draft` token was passed). Mark ready from draft when not keeping `draft`. Afterward, snapshot CI with `gh pr checks` (see the `gh-ci` skill for `gh run list` / `gh run watch` fallback). Link the GitHub issue (`Closes #n` / `Refs #n`). +8. **Switch back when safe** — unless `stay` / `don't switch` was passed, run `git status --porcelain`; if clean, `git switch <default>` and `git pull --ff-only`; if dirty, stay put and report why switching is unsafe. +9. **After review** — if switched back, return to the PR branch before review fixes; merge when approved and `gh pr checks` is green; once the PR merges, remind the user to run `/iflow-cleanup` for the post-merge tidy-up (do not auto-run it). With `yolo`, close may `gh pr checks --watch` (budget: `checks_watch_minutes`, default 15) before merge, falling back to `--auto` only when the cap elapses. + +**Result:** Commit, push, PR link, and either a clean switch back to the default branch or a clear reason for staying on the issue branch. No branches are deleted from `/iflow-close` itself. + +--- + +## 6. `/iflow-cleanup` — post-merge branch hygiene + +**When:** The PR opened by `/iflow-close` has merged on GitHub. (The optional GitHub remote audit can also run when you only want a remote-branch report.) + +**What you pass:** Nothing (acts on the current branch), an explicit branch name, and/or a GitHub-audit token such as `include GitHub` / `with github` / `github`. Opt out of a baked-on Phase B with `no github` / `local only`. With `cleanup_include_github = true` in `config.toml`, Phase B runs by default without a token. + +**What the assistant does:** + +1. Detects the default branch. +2. Detects merge state via `gh pr view` (falls back to `git cherry origin/<default> <branch>` to catch squash-merges). +3. If **not merged**: reminds you to stay off the default for unrelated work and re-run after merge (Phase A stops; Phase B may still run when enabled). +4. If **merged**: classifies every local branch with `issue-flow agent local-branches --json` (or the manual `git`/`gh` fallback) into `reachable`, `squash_landed`, `merged_pr_divergent`, `unique_work`, and `skipped`. +5. **Phase A1** — one consolidated yes/no prompt covering `git switch <default>`, `git pull --ff-only`, `git fetch --prune`, and `git branch -d` on every `reachable` branch. If `-d` refuses, reports and moves on; it never escalates to `-D` here. If ff-only fails, run `issue-flow agent default-sync` and recover from its `action` — never rebase or force-push default. +6. **Phase A2** (only when something landed via squash) — a **separate** confirm listing each `squash_landed` branch as `<name> <tip>`, and each `merged_pr_divergent` branch (merged PR, but commits still differ) with its unique-commit subjects. On yes, `git branch -D` those branches only, reporting the tip SHAs; restore any of them with `git branch <name> <tip>`. `unique_work` branches are never listed here. +7. Optional safe folder sweep: moves any `issue<N>_*` group whose status file says `- [x] Done` to `.issueflows/03-solved-issues/`. +8. **Optional Phase B** (opt-in token, or baked `cleanup_include_github = true`, unless opt-out): run `issue-flow agent branches --json` (or the manual `git`/`gh` fallback) to classify `origin/*` as deletable / unique work / skipped; summarise unique commits; then a **second** confirm for optional `git push origin --delete` on deletable remotes and/or a findings issue via `gh issue create`. Never `--force`; never delete the default. + +**Result:** Working tree on the default, landed local branches deleted (with consent — `-d` for reachable ones, `-D` only for the squash-landed set you explicitly approved), unique work left untouched, folders tidy; when Phase B ran, remote audit report plus any consented remote deletes / findings issue. + +--- + +## 7. `/iflow-graphify` — rebuild the knowledge graph (optional) + +**When:** The project has the optional [graphify](https://iflow-graphify.net) integration enabled (the `graphify` CLI is on `PATH` and a `graphify-out/` folder is present), and the graph has gone stale relative to the source tree. + +**What you pass:** Optional graphify subcommand and args, forwarded verbatim. Common picks: + +- *(nothing)* — AST-only build of the project root (`graphify update <project>`). **No LLM API key required**; produces the full `graphify-out/`. The default. +- `extract` — adds the slower semantic LLM pass for richer cross-file relationships. Needs an API key (`GEMINI_API_KEY`, `ANTHROPIC_API_KEY`, `OPENAI_API_KEY`, `MOONSHOT_API_KEY`) or `--backend ollama` for a local LLM via [Ollama](https://ollama.com). Cursor's own LLM is **not** available to subprocesses. +- `watch` — long-running watcher that auto-rebuilds on save. +- `cluster-only` — rerun clustering on the existing `graph.json` without re-extraction (e.g. `cluster-only --no-viz`). +- `./subdir` — restrict the scan to a sub-directory (default subcommand: `update`). + +**What the assistant does:** + +1. Runs `issue-flow graphify` (which shells out to the `graphify` CLI). If `issue-flow` is unavailable, falls back to `graphify update .` directly (`graphify .` alone is **not** valid — graphify requires a subcommand). +2. If `graphify` is not installed, prints install hints (`uv tool install graphifyy`) and stops — never silently retries. +3. If `graphify extract` fails with "no LLM API key found", suggests setting one of the supported env vars, or using `--backend ollama`, or dropping back to the default `update` subcommand. +4. Verifies that `graphify-out/graph.html`, `GRAPH_REPORT.md`, and `graph.json` exist after a successful run. + +**Result:** A refreshed `graphify-out/` so `/iflow-build` can navigate by graph instead of grepping. `/iflow-graphify` is **off-path** — `/iflow`, `/iflow-build`, and `/iflow-close` may *suggest* a rebuild but never invoke `/iflow-graphify` automatically. + +--- + +## 8. `/iflow-yolo` — all-in-one for small issues + +**When:** The change is genuinely small and low-risk (typo, one-line fix, doc tweak) and you want to skip the usual checkpoints. For anything bigger, use the individual commands. + +**Preflight (any failure aborts before the chain starts):** + +- Refuses to run on `main` / `master`. +- Refuses if `git status --porcelain` shows unrelated uncommitted changes. +- Runs `uv run pytest` up front; refuses if anything fails. +- **Single consolidated confirmation** listing the full planned chain (issue, branch, repo, downstream flags). + +**Chain:** `/iflow-capture` → `/iflow-plan` (auto-confirmed short plan; aborts if the scope check reveals the change isn't actually small) → `/iflow-build` → `uv run pytest` again → `/iflow-close` (with any forwarded `bump`/`patch`/`minor`/`major`/`draft`/`stay`). Does **not** run `/iflow-cleanup` — the PR hasn't merged yet. + +**Result:** A commit, push, and PR ready for review, with the final branch reported — or an abort at the first ambiguity. + +--- + +## 8b. `/iflow-ops` — ops / no-PR work + +**When:** The work should not open a PR — staging→production promote, feature-flag flip, external deploy checklist, tag-only steps with no product diff. + +**What the assistant does:** + +1. Resolve / capture the focus issue. +2. Preflight: refuse product-code dirty trees; default branch allowed. +3. Run the ops checklist with user confirms; log bullets in `issue<N>_status.md`. +4. Finish with `/iflow-close ops` (aliases `nopr` / `no-pr`): checklist confirm, local archive, optional `.issueflows/` commit (default branch OK), `gh issue close` — **no PR**. + +**Label:** when `label_flows` is on, `/iflow-pick` routes issues carrying `ops` (default `"ops"`) here. If both `ops` and `yolo` are present, **ops wins**. + +**Result:** Local tracking solved + GitHub issue closed, without a pull request. + +--- + +## 9. `/iflow-fix` — interactive iterative-fixes session + +**When:** You have a bucket of small, iterative fixes (little bugs, typos, chores, polish) to knock out on one branch, rather than a single well-defined deliverable. + +**What you pass:** An optional session name (used for the issue title and branch slug). No name → defaults to `iterative-small-fixes` (or asks once if inventing a better slug; baked `fix_auto_name = false`). During an active session, a `/iflow-fix <description>` (or just describing a fix) means "run the next fix". Toggle with `fix_auto_name` under `[issueflow]` (re-run `issue-flow update`). + +**What the assistant does:** + +1. **Set up (once).** Preflight (default branch, `git fetch --prune`, clean tree); resolve the session name; create a GitHub issue with `gh issue create` (always, after confirmation) and capture `N`; create branch `<N>-<slug>` (off the default, or — when already on a non-default branch — ask whether to branch from current or default); delegate local capture to `/iflow-capture`; seed `issue<N>_status.md` with an unchecked `- [ ] Done` and an empty **`## Iterative fixes log`**. +2. **Loop.** For each proposed fix: restate it, write a short inline plan, implement **only on confirmation**, and append a dated bullet to the **Iterative fixes log**. A fix that turns out to be a real feature is split out into its own issue instead. +3. **Finish.** Tells you to run `/iflow-close` to land the session (it never auto-runs it); reminds you about `/iflow-cleanup` after the PR merges. + +**Coexists with `/iflow-pick fix` and `/iflow-issue`:** pick-fix is a one-shot general-fixes setup; `/iflow-issue` creates one well-specified normal issue; `/iflow-fix` stays and drives the small-fixes loop until close. + +**Off-path:** `/iflow` never auto-dispatches to `/iflow-fix`. While a session is active, drive it with `/iflow-fix` + `/iflow-close`, not `/iflow`. GitHub only (`gh`); GitLab is not supported. + +**Result:** A session issue + branch with a running fixes log, ready to land via `/iflow-close`. + +--- + +## 10. `/iflow-issue` — create a normal (non-epic) issue + +**When:** You want to file **one well-specified** GitHub issue — a single deliverable with a real body — then optionally start the normal lifecycle. Not for iterative small-fixes buckets (`/iflow-fix`) or multi-issue staged work (`/iflow-epic`). + +**What you pass:** Optional free text to seed the draft (title / short description). Leading `epic` (e.g. `/iflow-issue epic Large rewrite`) creates an epic **anchor** (`Epic:` title + `epic` label when present). Bare `/iflow-issue` → the assistant asks for a one-line intent. + +**What the assistant does:** + +1. **Preflight** — default branch, `git fetch --prune`, clean/dirty tree. +2. **Draft** — propose title + body with **Problem / context**, **Spec**, **Acceptance criteria**, and optional **Out of scope**. Refine until you confirm. If clearly over-large for one PR, offer `/iflow-split` (flat) or `/iflow-epic` (staged) — does not auto-split. +3. **Create** — show final title/body (and epic label when applicable); on confirm, `gh issue create` and capture `N`. +4. **Optional setup** — offer branch `<N>-<slug>` + `/iflow-capture`, then ask about `/iflow-plan` (never auto-runs plan). Decline → create-only; pick up later via `/iflow-pick` / `/iflow-capture`. + +**Off-path:** `/iflow` never auto-dispatches to `/iflow-issue`. GitHub only (`gh`); GitLab is not supported. + +**Result:** A new GitHub issue (and optionally a branch + local capture ready for `/iflow-plan`). + +--- + +## 10a. `/iflow-split` — linked sub-issues for an over-large issue + +**When:** An **existing** issue is too big for one PR but is not a multi-stage epic. Staged work with dependencies still uses `/iflow-epic`. + +**What you pass:** `/iflow-split <N>` or bare `/iflow-split` (focus issue / issue-style branch). + +**What the assistant does:** + +1. **Draft** 2–5 child specs (same light body as `/iflow-issue`). Size gate: stages or `Depends on` → stop and recommend `/iflow-epic`. +2. **Confirm** once: parent stays open; children will be created and linked as GitHub native sub-issues; a `## Sub-issues` task list is appended on the parent. +3. **Create + link** — `gh issue create`, then `issue-flow agent sub-issue-add <N> <M>` (REST `--input` JSON fallback; `sub_issue_id` is the database id). Idempotent. Task list is the fallback if the sub-issue API fails. +4. **Park** the parent group under `02-partly-solved-issues/` if it was the focus. Do not close the GitHub parent. +5. **Ask** whether to start the first child (branch + `/iflow-capture`). Does not auto-run plan/build. + +**Off-path:** `/iflow` never auto-dispatches to `/iflow-split`. GitHub only. + +**Result:** Open parent tracker + linked children ready for `/iflow-pick`. + +--- + +## 11. `/iflow-status` — status overview of all issues (read-only) + +**When:** You want a bird's-eye view of where every issue stands, rather than acting on the single focus issue. + +**What you pass:** Nothing (full report), `local` (skip the GitHub query), or a hint like `milestone v0.4` to bias the GitHub section. + +**What the assistant does (all read-only):** + +1. **Context** — current branch, default branch, clean/dirty tree, ahead/behind; focus issue `N` derived from the branch when it matches `^<N>-.+`. +2. **Focus issue** — the active group in `.issueflows/01-current-issues/` and its lifecycle stage (capture / plan / build / close) using the same file-presence logic as `/iflow`, plus the suggested next step. +3. **Parked work** — each `issue<n>_*` group under `.issueflows/02-partly-solved-issues/` with title and one-line status. +4. **Solved archive** — count of distinct solved issues under `.issueflows/03-solved-issues/` and the most recent few. +5. **Open GitHub issues** — `gh issue list` cross-referenced against the local folders, tagged **focus** / **parked** / **solved-locally** / **untracked**. Skipped gracefully when `gh` is unavailable or `local` was passed. +6. **Summary** — one terse line. + +**Off-path:** `/iflow` never auto-dispatches to `/iflow-status`. It writes nothing, moves no files, and creates no branches, commits, or GitHub issues. + +**Result:** A consolidated, read-only status report. Nothing on disk or GitHub changes. + +--- + +## 12. `/iflow-review` — review open issues and apply labels + +**When:** You want help deciding which open GitHub issues should carry workflow labels (v1: the configured `yolo` label). + +**What you pass:** Nothing (list kinds and ask), or `yolo` to run the yolo review. + +**What the assistant does:** + +1. **Kind** — if omitted, list supported review kinds and ask. +2. **Config / label** — resolve `yolo_label` (and note `label_flows`); create the label under confirm if missing. +3. **Candidates** — list all open issues (`issue-flow agent label-candidates`), including already-labelled ones for re-score. +4. **Judge** — yolo-fitness (same criteria as `/iflow-epic`); propose **add** / **keep** / **skip** (never auto-remove). +5. **Confirm + apply** — one consolidated confirm, then `issue-flow agent label-apply` (or `gh issue edit --add-label`). + +**Example:** + +```text +iflow review yolo +# → table of open issues with add / keep / skip +# → confirm → labels applied +iflow cycle yolo +# → batch-process every open issue that now carries the yolo label +``` + +**Off-path:** `/iflow` never auto-dispatches to `/iflow-review`. No issue creation; no label removals in v1. + +**Result:** Selected open issues carry the target label so `/iflow-pick` can route them (when `label_flows` is on), or `/iflow-cycle yolo` can batch them. + +--- + +## 13. `/iflow-epic` — plan a large change as staged issues + +**When:** The work is too big for one PR. You want a staged plan anchored to a GitHub issue, then publish one stage at a time as real issues. + +**What you pass:** `/iflow-epic <N>` to draft (or revise) `.issueflows/05-epics/epic<N>_plan.md`. Later: `/iflow-epic <N> publish [stage <k>]` to create that stage's issues on GitHub. No anchor yet → create one with `/iflow-issue epic <intent>`, then pass the new number. + +**What the assistant does (draft):** + +1. Reads the anchor issue and any design docs under `04-designs-and-guides/`. +2. Drafts stages of manageable issue specs (title, scope, acceptance, dependencies, **yolo: yes|no** judgment). +3. Writes `Status: draft` and iterates with you until you confirm → `Status: confirmed`. +4. **Does not** create GitHub issues while drafting. + +**What the assistant does (publish):** + +1. Requires `Status: confirmed`. Selects the named stage (or the earliest unpublished stage). +2. Dry-run lists titles + labels, then **one consolidated confirm**. +3. Creates issues in dependency order (`gh issue create`), records `Published: #<M>` in the plan, updates the anchor issue's task list. +4. Re-runs are idempotent (already-published specs are skipped). + +**Example:** + +```text +iflow epic 144 +# → drafts .issueflows/05-epics/epic144_plan.md (Status: draft) +# → you confirm → Status: confirmed +iflow epic 144 publish stage 1 +# → creates stage-1 issues (yolo labels per judgment), task list on #144 +issue-flow agent epic-status 144 --json +# → current stage + next_candidates for /iflow-pick / /iflow-cycle +``` + +**Off-path:** `/iflow` never auto-dispatches to `/iflow-epic`. Epics decompose into the normal single-issue lifecycle; they do not replace it. + +**Result:** A durable epic plan file; published stages become ordinary issues you pick/yolo/cycle as usual. + +--- + +## 14. `/iflow-cycle` — batch-process a queue of yolo-fit issues + +**When:** You have several small, well-specified issues and want them landed hands-off under **one** up-front confirm — the batch form of `/iflow-yolo`. + +**What you pass:** a queue spec, for example: + +- `yolo` — alias for `label:yolo` (all open issues with the configured yolo trigger label) +- `label:<L>` — every open issue with that label +- explicit numbers — e.g. `12 15 18` +- `epic <N> [stage <k>]` — current (or named) stage of an epic +- optional: `onfail:stop|skip`, `max:<n>`, `resume`, `parallel:<n>` (experimental) + +**What the assistant does:** + +1. Expands aliases, then resolves the queue with `issue-flow agent queue … --json`. +2. Cap check (default max 10 without `max:<n>`). +3. **One consolidated confirm** (ordered queue, skipped/blocked, auto-merge). +4. Writes `cycle_status.md`, then for each issue runs the full yolo chain from a clean default branch (merge → pull → next). +5. Stops only on strictly necessary input; `onfail:stop` (default) leaves the tree clean on default. + +**Example — all yolo-labelled issues:** + +```text +iflow cycle yolo +# → agent queue --label yolo +# → confirm the ordered list +# → each issue: capture → plan → build → close yolo (PR merged) +# → back on default, clean, between issues +``` + +**Conflict stance:** sequential cycles merge each PR and return to a clean default before the next issue, so shared files like `HISTORY.md` stay single-writer. See `04-designs-and-guides/parallel-cycle.md` for experimental `parallel:<n>` (merges still serialized) and `04-designs-and-guides/separate-workspaces.md` for one-window-per-worktree layout. + +**Off-path:** `/iflow` never auto-dispatches to `/iflow-cycle`. + +**Result:** A batch report of merged/failed/not-reached issues; remind the user to run `/iflow-cleanup` once afterward to prune merged local branches. + +--- + +## 15. `/iflow-auto` — unattended large-change orchestration + +**When:** You have a **confirmed** epic plan and want overnight hands-off progress through a stage, then an adversarial inter-epoch review. + +**What you pass:** epic `<N>`, optional `stage <k>`, optional `loops:<n>`, `review` (adversarial only), or `status` / `dry-run`. + +**What the assistant does:** + +1. Require `epic<N>_plan.md` with `Status: confirmed`; resolve stage via `epic-status`. +2. Resolve loop budget (`loops:<n>` > baked `auto_adversarial_loops` > 2). +3. Overnight confirm once (authorizes cycle auto-merge **and** adversarial reopen/create), then write `auto_status.md` and run `/iflow-cycle` for that stage. +4. Run adversarial review against epic/stage goals (criteria in `advanced-auto-mode.md`); record `adversarial_clear` or `adversarial_findings` in `auto_status.md`. Standalone: `/iflow-auto <N> review`. +5. **Loop control:** on findings, increment `loop_count`; if open work remains and `loop_count` < budget, re-queue via `/iflow-cycle` and re-review; when budget exhausted, **stop and ask** (accept / grant N more loops / abort). +6. **Next-epoch gate:** start stage `k+1` only when `epic-status` marks stage `k` `done` and no open blockers remain in `auto_status.md`; otherwise `epoch_gated`. When clear, may continue to the next unfinished stage under the same overnight confirm. + +**Off-path:** `/iflow` never auto-dispatches to `/iflow-auto`. See `04-designs-and-guides/advanced-auto-mode.md`. + +**Result:** Stage queue processed via cycle; durable `auto_status.md`; adversarial pass may reopen/create blockers; loops honour `auto_adversarial_loops` / `loops:<n>`; epochs advance only when the queue is clear. + +--- + +## 16. `/iflow-drive` — compose epic → publish → auto-all + +**When:** You have an **existing** GitHub issue `<N>` that should become an epic and you want the whole path hands-off: draft, publish every stage, `/iflow-auto` each epoch, a final review, then local `-d` cleanup and `/iflow-status`. + +**What you pass:** issue `<N>` (required), optional `grill` / `grill-me`, optional `loops:<n>`, or `dry-run`. Mid-run `abort` / `stop` / `cancel` / `halt` stops at the next stage or issue boundary. + +**What the assistant does:** + +1. Drive confirm once (covers draft-accept, publish-all, auto-all, final-review creates, reachable-only cleanup). Write `drive_status.md`. +2. Draft `epic<N>_plan.md` via `/iflow-epic <N>` (auto-confirm unless grill-me / `grill_me_default`). Skip draft/publish when the plan is already `Status: confirmed`. +3. Publish every unpublished stage (`Published: #<M>` off default — issue #303). +4. Run `/iflow-auto <N>` for each unfinished published stage. Honour `epoch_gated` and auto's budget ask (planned pause). +5. Final `/iflow-auto <N> review`; create/reopen leftover findings. Do not start another epoch. +6. `/iflow-cleanup` `local only` **and skip Phase A2**: `git branch -d` on reachable only (squash-landed locals stay). Then `/iflow-status`. + +**Off-path:** `/iflow` never auto-dispatches to `/iflow-drive`. See `04-designs-and-guides/drive-mode.md`. + +**Result:** Epic published and driven through auto; findings issues recorded; reachable local branches pruned; status report. + +--- + +## 17. `/iflow-archive` — condense the solved-issues archive (destructive, gated) + +**When:** `.issueflows/03-solved-issues/` has grown large and most of its `issue<N>_*` groups are no longer worth keeping as individual files. + +**What you pass:** Nothing (archive all but the 5 most recent solved groups), `keep <K>` (keep the `<K>` most recent), an explicit list of issue numbers, or `all`. + +**What the assistant does:** + +1. **Preflight** — requires a **clean working tree** (stop if dirty) and records the pre-archive ref via `git rev-parse HEAD`. +2. **Select** — lists every solved group (number + title), applies your input rule, and shows the candidate list for you to adjust. +3. **Consolidated confirm** — one prompt covering exactly which issues get summarised and that their files will be **deleted**; nothing proceeds without a clear yes. +4. **Summarise** — appends to `.issueflows/03-solved-issues/YYYY-MM-DD_archived_issues.md`: a header with the pre-archive ref and recovery recipe (`git show <ref>:<path>`), then one section per issue with source URL, archived file names, and a 2–4 sentence outcome summary. +5. **Delete** — removes the archived groups' files (`issue-flow agent archive <N> ...` when the CLI is installed, else `git rm`). +6. **Commit offer** — proposes a single commit so the deletion lands right after the recorded ref; asks first, never pushes. + +**Off-path:** `/iflow` never auto-dispatches to `/iflow-archive`. It deletes files, so you opt in explicitly. + +**Result:** One dated summary file replaces the archived groups; every original file remains recoverable from git history via the recorded ref. + +--- + +## End-to-end flow + +Tip: at any point in the linear flow below, you can just run `/iflow` and it will dispatch to the right step based on current state. + +```text +(no issue chosen yet) + │ /iflow-pick → choose issue, create branch, run /iflow-capture + ▼ +GitHub issue + │ /iflow-capture (or /iflow) + ▼ +.issueflows/01-current-issues/issueN_original.md + │ /iflow-plan + ▼ +issueN_plan.md (user confirmed) + │ /iflow-build + ▼ +Code + tests (+ status updates during work) + │ /iflow-close [optional: bump <patch|minor|major|alpha|beta|rc|…>] + ▼ +Commit → push → PR + │ + │ (PR merges on GitHub) + │ /iflow-cleanup + ▼ +Default branch, stale local branches deleted (with single confirm) + +Detours: + /iflow-setup — guided first-time project setup (off-path; never auto-dispatched) + /iflow-pick — front door: choose the next issue, branch, capture (before the linear flow) + /iflow-init — cold-start / check the harness (off-path; does not capture issues) + /iflow-pause — park mid-stream; moves issueN_* to 02-partly-solved-issues/ + /iflow-yolo — chain capture → plan → build → close for tiny fixes (safeguarded) + /iflow-ops — ops / no-PR work (staging→prod, flags, external deploys) + /iflow-fix — interactive session: one branch, many small fixes, then /iflow-close + /iflow-issue — create one well-specified normal GitHub issue (optional branch + capture) + /iflow-split — cut an over-large issue into linked GitHub sub-issues + /iflow-status — read-only overview of all issues (focus / parked / solved + GitHub) + /iflow-doctor — audit/repair dirty .issueflows/ folders + /iflow-review — review open issues and apply labels (v1: yolo) + /iflow-epic — stage a large change; publish stages as real issues + /iflow-cycle yolo — auto-process all open issues with the configured yolo label + /iflow-auto <N> — unattended epic stage via cycle + adversarial review + /iflow-drive <N> — compose epic → publish → auto-all → final review → local -d cleanup + /iflow-archive — condense old solved issues into a dated summary file (gated deletion) +``` + +The skill packages under `.cursor/skills/` are the primary workflow surface. This document is a readable overview only. diff --git a/docs/releasing.md b/docs/releasing.md index e8ac483..e6e834d 100644 --- a/docs/releasing.md +++ b/docs/releasing.md @@ -70,8 +70,8 @@ Worth doing for the first release, because the failure modes are all one-way. 3. Tag and push: ```bash - git tag v0.1.0 - git push origin v0.1.0 + git tag v0.2.0 + git push origin v0.2.0 ``` 4. Watch Actions. `build` checks that the tag matches `__version__`, runs the @@ -88,7 +88,7 @@ Worth doing for the first release, because the failure modes are all one-way. ## Things that will bite - **A version can never be reused.** Not after deleting the release, not after - yanking it. A bad `0.1.0` means `0.1.1`, so rehearse on TestPyPI. + yanking it. A bad `0.2.0` means `0.2.1`, so rehearse on TestPyPI. - **Renaming `publish.yml` or an environment breaks publishing**, because the pending publisher names both. Update PyPI in the same change. - **The tag is the version.** `build` refuses a tag that disagrees with diff --git a/src/cellpy_mcp/__init__.py b/src/cellpy_mcp/__init__.py index 2d0919d..276f395 100644 --- a/src/cellpy_mcp/__init__.py +++ b/src/cellpy_mcp/__init__.py @@ -22,7 +22,7 @@ from pathlib import Path -__version__ = "0.1.0" +__version__ = "0.2.0" __all__ = ["__version__", "serve", "install", "describe", "build_server", "Sandbox"]