issue-flow 0.2.2__tar.gz → 0.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- issue_flow-0.3.0/PKG-INFO +279 -0
- issue_flow-0.3.0/README.md +255 -0
- {issue_flow-0.2.2 → issue_flow-0.3.0}/pyproject.toml +1 -1
- issue_flow-0.3.0/src/issue_flow/cli.py +114 -0
- {issue_flow-0.2.2 → issue_flow-0.3.0}/src/issue_flow/config.py +14 -3
- issue_flow-0.3.0/src/issue_flow/dependencies.py +198 -0
- issue_flow-0.3.0/src/issue_flow/graphify.py +249 -0
- {issue_flow-0.2.2 → issue_flow-0.3.0}/src/issue_flow/init.py +64 -3
- issue_flow-0.3.0/src/issue_flow/templates/commands/build.md.j2 +63 -0
- issue_flow-0.3.0/src/issue_flow/templates/commands/iflow.md.j2 +78 -0
- issue_flow-0.3.0/src/issue_flow/templates/commands/issue-cleanup.md.j2 +60 -0
- issue_flow-0.3.0/src/issue_flow/templates/commands/issue-close.md.j2 +65 -0
- {issue_flow-0.2.2 → issue_flow-0.3.0}/src/issue_flow/templates/commands/issue-init.md.j2 +35 -8
- issue_flow-0.3.0/src/issue_flow/templates/commands/issue-pause.md.j2 +57 -0
- issue_flow-0.3.0/src/issue_flow/templates/commands/issue-plan.md.j2 +82 -0
- issue_flow-0.3.0/src/issue_flow/templates/commands/issue-start.md.j2 +51 -0
- issue_flow-0.3.0/src/issue_flow/templates/commands/issue-yolo.md.j2 +75 -0
- issue_flow-0.3.0/src/issue_flow/templates/docs/cursor-issue-workflow.md.j2 +263 -0
- issue_flow-0.3.0/src/issue_flow/templates/rules/issueflow-rules.mdc.j2 +135 -0
- issue_flow-0.3.0/src/issue_flow/templates/skills/issueflow_build/SKILL.md.j2 +61 -0
- issue_flow-0.3.0/src/issue_flow/templates/skills/issueflow_history_update/SKILL.md.j2 +84 -0
- issue_flow-0.3.0/src/issue_flow/templates/skills/issueflow_iflow/SKILL.md.j2 +55 -0
- issue_flow-0.3.0/src/issue_flow/templates/skills/issueflow_issue_cleanup/SKILL.md.j2 +44 -0
- issue_flow-0.3.0/src/issue_flow/templates/skills/issueflow_issue_close/SKILL.md.j2 +62 -0
- issue_flow-0.3.0/src/issue_flow/templates/skills/issueflow_issue_comments/SKILL.md.j2 +96 -0
- issue_flow-0.3.0/src/issue_flow/templates/skills/issueflow_issue_init/SKILL.md.j2 +74 -0
- issue_flow-0.3.0/src/issue_flow/templates/skills/issueflow_issue_pause/SKILL.md.j2 +44 -0
- issue_flow-0.3.0/src/issue_flow/templates/skills/issueflow_issue_plan/SKILL.md.j2 +49 -0
- issue_flow-0.3.0/src/issue_flow/templates/skills/issueflow_issue_start/SKILL.md.j2 +50 -0
- issue_flow-0.3.0/src/issue_flow/templates/skills/issueflow_issue_yolo/SKILL.md.j2 +49 -0
- {issue_flow-0.2.2 → issue_flow-0.3.0}/src/issue_flow/templating.py +47 -9
- issue_flow-0.2.2/PKG-INFO +0 -157
- issue_flow-0.2.2/README.md +0 -133
- issue_flow-0.2.2/src/issue_flow/cli.py +0 -60
- issue_flow-0.2.2/src/issue_flow/templates/commands/issue-close.md.j2 +0 -50
- issue_flow-0.2.2/src/issue_flow/templates/commands/issue-start.md.j2 +0 -16
- issue_flow-0.2.2/src/issue_flow/templates/docs/cursor-issue-workflow.md.j2 +0 -120
- issue_flow-0.2.2/src/issue_flow/templates/rules/issueflow-rules.mdc.j2 +0 -86
- issue_flow-0.2.2/src/issue_flow/templates/skills/issueflow_issue_close/SKILL.md.j2 +0 -49
- issue_flow-0.2.2/src/issue_flow/templates/skills/issueflow_issue_init/SKILL.md.j2 +0 -53
- issue_flow-0.2.2/src/issue_flow/templates/skills/issueflow_issue_start/SKILL.md.j2 +0 -39
- {issue_flow-0.2.2 → issue_flow-0.3.0}/LICENSE +0 -0
- {issue_flow-0.2.2 → issue_flow-0.3.0}/src/issue_flow/__init__.py +0 -0
- {issue_flow-0.2.2 → issue_flow-0.3.0}/src/issue_flow/py.typed +0 -0
- {issue_flow-0.2.2 → issue_flow-0.3.0}/src/issue_flow/templates/__init__.py +0 -0
- {issue_flow-0.2.2 → issue_flow-0.3.0}/src/issue_flow/templates/commands/__init__.py +0 -0
- {issue_flow-0.2.2 → issue_flow-0.3.0}/src/issue_flow/templates/docs/__init__.py +0 -0
- {issue_flow-0.2.2 → issue_flow-0.3.0}/src/issue_flow/templates/rules/__init__.py +0 -0
- {issue_flow-0.2.2 → issue_flow-0.3.0}/src/issue_flow/templates/skills/issueflow_version_bump/SKILL.md.j2 +0 -0
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: issue-flow
|
|
3
|
+
Version: 0.3.0
|
|
4
|
+
Summary: Agents should behave. Let them follow the issue flow.
|
|
5
|
+
Keywords: cursor,ai,agents,issue-tracking,workflow
|
|
6
|
+
Author: jepegit
|
|
7
|
+
Author-email: jepegit <jepe@ife.no>
|
|
8
|
+
License-Expression: MIT
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Topic :: Software Development :: Build Tools
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
15
|
+
Requires-Dist: jinja2>=3.1.6
|
|
16
|
+
Requires-Dist: python-dotenv>=1.2.2
|
|
17
|
+
Requires-Dist: rich>=14.3.3
|
|
18
|
+
Requires-Dist: typer>=0.24.1
|
|
19
|
+
Requires-Python: >=3.13
|
|
20
|
+
Project-URL: Homepage, https://github.com/jepegit/issue-flow
|
|
21
|
+
Project-URL: Repository, https://github.com/jepegit/issue-flow
|
|
22
|
+
Project-URL: Issues, https://github.com/jepegit/issue-flow/issues
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
|
|
25
|
+
# issue-flow
|
|
26
|
+
|
|
27
|
+
Agents should behave. Let them follow the issue flow.
|
|
28
|
+
|
|
29
|
+
**issue-flow** scaffolds a lightweight issue-tracking workflow into your project so that Cursor AI agents can pick up GitHub issues, plan work, and land PRs in a consistent way.
|
|
30
|
+
|
|
31
|
+
## What it does
|
|
32
|
+
|
|
33
|
+
Running `issue-flow init` in your project root creates:
|
|
34
|
+
|
|
35
|
+
```text
|
|
36
|
+
your-project/
|
|
37
|
+
.issueflows/
|
|
38
|
+
00-tools/ # Helper scripts for agents
|
|
39
|
+
01-current-issues/ # Active issue markdown files
|
|
40
|
+
02-partly-solved-issues/ # Parked / in-progress issues
|
|
41
|
+
03-solved-issues/ # Completed issues archive
|
|
42
|
+
.cursor/
|
|
43
|
+
commands/
|
|
44
|
+
iflow.md # /iflow — smart dispatcher (quick start)
|
|
45
|
+
issue-init.md # /issue-init — fetch a GitHub issue locally
|
|
46
|
+
issue-plan.md # /issue-plan — write issue<N>_plan.md and confirm
|
|
47
|
+
issue-start.md # /issue-start — implement the plan
|
|
48
|
+
issue-pause.md # /issue-pause — park work in 02-partly-solved-issues/
|
|
49
|
+
issue-close.md # /issue-close — test, commit, push, PR
|
|
50
|
+
issue-cleanup.md # /issue-cleanup — post-merge branch hygiene
|
|
51
|
+
issue-yolo.md # /issue-yolo — all-in-one for small, low-risk issues
|
|
52
|
+
build.md # /build — rebuild the graphify knowledge graph (optional)
|
|
53
|
+
skills/ # Optional Agent Skills (explicit / @ invoke)
|
|
54
|
+
issueflow-iflow/SKILL.md
|
|
55
|
+
issueflow-issue-init/SKILL.md
|
|
56
|
+
issueflow-issue-plan/SKILL.md
|
|
57
|
+
issueflow-issue-start/SKILL.md
|
|
58
|
+
issueflow-issue-pause/SKILL.md
|
|
59
|
+
issueflow-issue-close/SKILL.md
|
|
60
|
+
issueflow-issue-cleanup/SKILL.md
|
|
61
|
+
issueflow-issue-yolo/SKILL.md
|
|
62
|
+
issueflow-version-bump/SKILL.md
|
|
63
|
+
issueflow-history-update/SKILL.md
|
|
64
|
+
issueflow-build/SKILL.md
|
|
65
|
+
rules/
|
|
66
|
+
issueflow-rules.mdc # Always-on Cursor rule for the workflow
|
|
67
|
+
docs/
|
|
68
|
+
cursor-issue-workflow.md # Human-readable overview of the workflow
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
The Cursor slash commands give agents a repeatable flow. The linear path is:
|
|
72
|
+
|
|
73
|
+
1. `/issue-init 42` — pulls GitHub issue #42 into `.issueflows/01-current-issues/` and archives older issues.
|
|
74
|
+
2. `/issue-plan` — drafts `issue<N>_plan.md` (Goal / Constraints / Approach / Files to touch / Test strategy / Open questions) and stops for your confirmation.
|
|
75
|
+
3. `/issue-start` — reads the confirmed plan and implements it. If no plan file exists, it offers to run `/issue-plan` first, proceed without a plan, or abort.
|
|
76
|
+
4. `/issue-close` — runs tests, optionally bumps version with `uv version --bump`, appends a `HISTORY.md` entry (or promotes `[Unreleased]` to a new release section on a bump), updates status files, commits, pushes, and opens a PR.
|
|
77
|
+
5. `/issue-cleanup` — after the PR merges, switches to the default branch, fast-forwards, prunes, and deletes the merged local branch.
|
|
78
|
+
|
|
79
|
+
Plus a few off-path commands:
|
|
80
|
+
|
|
81
|
+
- `/iflow` — **quick start**: inspects the current issue's state and dispatches to the right linear step automatically. A branch-derived number (`42-fix-login` → `N=42`) is authoritative, so `/iflow` works from a fresh branch too.
|
|
82
|
+
- `/issue-pause` — park the current issue in `02-partly-solved-issues/` with a **Remaining work** note; optional WIP commit + switch back to the default branch.
|
|
83
|
+
- `/issue-yolo` — all-in-one chain (`init → plan → start → close`) for small, low-risk issues, with up-front safeguards (refuses on the default branch, refuses with dirty unrelated changes, requires passing tests, single consolidated confirm).
|
|
84
|
+
|
|
85
|
+
The matching **Agent Skills** (under `.cursor/skills/`) carry the same workflows for on-demand use with `/issueflow-iflow`, `/issueflow-issue-init`, `/issueflow-issue-plan`, `/issueflow-issue-start`, `/issueflow-issue-pause`, `/issueflow-issue-close`, `/issueflow-issue-cleanup`, `/issueflow-issue-yolo`, `@issueflow-version-bump` when you need only the bump steps, or `@issueflow-history-update` when you need only the changelog update (see [Cursor Agent Skills](https://cursor.com/docs/context/skills)).
|
|
86
|
+
|
|
87
|
+
## Prerequisites
|
|
88
|
+
|
|
89
|
+
issue-flow itself is a small Python CLI, but the **scaffolded slash commands
|
|
90
|
+
it writes into your project shell out to a few external tools**. If they are
|
|
91
|
+
missing, the slash commands will fail at runtime — so `issue-flow init` now
|
|
92
|
+
checks for them up front and prints install hints before it does anything.
|
|
93
|
+
|
|
94
|
+
Required:
|
|
95
|
+
|
|
96
|
+
- **[Git](https://git-scm.com/downloads)** — used by every slash command for
|
|
97
|
+
branch, fetch, status, commit, and push operations. Almost certainly already
|
|
98
|
+
installed if you're here, but the check covers it for completeness.
|
|
99
|
+
- **[GitHub CLI (`gh`)](https://cli.github.com/)** — used by `/issue-init` to
|
|
100
|
+
fetch issues, by `/issue-close` to open PRs, and by `/issue-cleanup` to check
|
|
101
|
+
PR merge status. After installing, run `gh auth login` once to authenticate.
|
|
102
|
+
|
|
103
|
+
Recommended:
|
|
104
|
+
|
|
105
|
+
- **[uv](https://docs.astral.sh/uv/)** — how issue-flow itself is meant to be
|
|
106
|
+
installed, and how this repo manages its own Python environment.
|
|
107
|
+
|
|
108
|
+
Quick install pointers for `gh`:
|
|
109
|
+
|
|
110
|
+
| Platform | Command |
|
|
111
|
+
|---|---|
|
|
112
|
+
| macOS (Homebrew) | `brew install gh` |
|
|
113
|
+
| Windows (winget) | `winget install --id GitHub.cli -e` |
|
|
114
|
+
| Linux (Debian/Ubuntu) | `sudo apt install gh` (or see [cli.github.com](https://cli.github.com/) for the official repo) |
|
|
115
|
+
|
|
116
|
+
If a dependency is missing, `issue-flow init` prints the installation hints
|
|
117
|
+
and asks whether to continue anyway. You can bypass the prompt in automation
|
|
118
|
+
with `issue-flow init --skip-dep-check` (the same flag is available on
|
|
119
|
+
`issue-flow update`), and the prompt is also auto-skipped when stdin is not
|
|
120
|
+
a TTY (e.g. CI pipelines).
|
|
121
|
+
|
|
122
|
+
### Optional: graphify integration
|
|
123
|
+
|
|
124
|
+
issue-flow has a lightweight integration with [graphify](https://graphify.net)
|
|
125
|
+
(PyPI: `graphifyy`, CLI: `graphify`) — a tool that turns the project into a
|
|
126
|
+
queryable knowledge graph that AI assistants can read instead of grepping
|
|
127
|
+
through files. The integration is **opt-in by installing `graphifyy` as its
|
|
128
|
+
own tool** (the same way you installed issue-flow): there is no flag, no
|
|
129
|
+
`.env` switch, no extras to remember. Detection is purely PATH-based.
|
|
130
|
+
|
|
131
|
+
What `issue-flow` does when `graphify` is on PATH:
|
|
132
|
+
|
|
133
|
+
- `issue-flow init` and `issue-flow update` run `graphify cursor install` so
|
|
134
|
+
the graphify Cursor skill is registered alongside the issue-flow scaffold.
|
|
135
|
+
If graphify is not installed, both commands just print install hints and
|
|
136
|
+
continue — they never block.
|
|
137
|
+
- A new slash command `/build` (and matching `/issueflow-build` skill) wraps
|
|
138
|
+
`issue-flow build`, which forwards every argument to the `graphify` CLI
|
|
139
|
+
verbatim (`--update`, `--no-viz`, `--mode deep`, `--watch`, …).
|
|
140
|
+
- The scaffolded rules and `/issue-start` mention `graphify-out/GRAPH_REPORT.md`
|
|
141
|
+
as a recommended pre-read when the file exists. `/build` is **off-path** —
|
|
142
|
+
`/iflow` never auto-dispatches to it.
|
|
143
|
+
|
|
144
|
+
To enable, install graphify as its own standalone tool:
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
uv tool install graphifyy # recommended
|
|
148
|
+
# or
|
|
149
|
+
pipx install graphifyy
|
|
150
|
+
# or
|
|
151
|
+
pip install graphifyy
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
> **Why not an `issue-flow[graphify]` extra (or `uv tool install issue-flow --with graphifyy`)?**
|
|
155
|
+
> `uv tool install` only puts the **host package's** entry-point scripts on
|
|
156
|
+
> PATH. An extra (or `--with graphifyy`) pulls graphifyy into issue-flow's
|
|
157
|
+
> venv but leaves the `graphify` CLI invisible to the shell, so `/build`
|
|
158
|
+
> and `graphify cursor install` would still fail. Installing graphify as
|
|
159
|
+
> its own tool puts a real `graphify` shim on PATH and matches how we
|
|
160
|
+
> treat `git` / `gh`.
|
|
161
|
+
|
|
162
|
+
> **Just installed graphifyy and `issue-flow init` says it's still missing?**
|
|
163
|
+
> uv prints `~/.local/bin is not on your PATH` after the first
|
|
164
|
+
> `uv tool install`. Run `uv tool update-shell` (refreshes shell rc files),
|
|
165
|
+
> then **restart your shell and Cursor** so the new PATH takes effect.
|
|
166
|
+
> issue-flow's missing-CLI hint also detects this case and tells you the
|
|
167
|
+
> exact directory to add.
|
|
168
|
+
|
|
169
|
+
After installing, run `issue-flow update` once so the graphify Cursor skill
|
|
170
|
+
gets registered.
|
|
171
|
+
|
|
172
|
+
## Installation
|
|
173
|
+
|
|
174
|
+
Requires Python 3.13+ and [uv](https://docs.astral.sh/uv/).
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
uv tool install issue-flow
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
Or add it as a dev dependency to your project:
|
|
181
|
+
|
|
182
|
+
```bash
|
|
183
|
+
uv add --dev issue-flow
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
## Quick start
|
|
187
|
+
|
|
188
|
+
```bash
|
|
189
|
+
cd your-project
|
|
190
|
+
issue-flow init
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
That's it. Open the project in Cursor and start with `/iflow` (or step through `/issue-init`, `/issue-plan`, `/issue-start`, `/issue-close`, `/issue-cleanup` explicitly).
|
|
194
|
+
|
|
195
|
+
## Usage
|
|
196
|
+
|
|
197
|
+
```
|
|
198
|
+
issue-flow init [PROJECT_DIR] [--force] [--skip-dep-check]
|
|
199
|
+
issue-flow update [PROJECT_DIR] [--skip-dep-check]
|
|
200
|
+
issue-flow build [PROJECT_DIR] [-- ...graphify args]
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
### `issue-flow init`
|
|
204
|
+
|
|
205
|
+
| Argument / Option | Description |
|
|
206
|
+
|---|---|
|
|
207
|
+
| `PROJECT_DIR` | Project root directory. Defaults to `.` (current directory). |
|
|
208
|
+
| `--force`, `-f` | Overwrite generated Cursor commands, rules, and workflow doc instead of skipping them. |
|
|
209
|
+
| `--skip-dep-check` | Skip the external-CLI dependency check (`git`, `gh`) and the confirmation prompt that follows if anything is missing. Useful in automation. |
|
|
210
|
+
|
|
211
|
+
Running `init` again without `--force` is safe: generated scaffold files that already exist are skipped, and **issue markdown under `.issueflows/` is never touched** by `init` or `update`. When the CLI detects an existing scaffold, it reminds you about `update` and `--force`.
|
|
212
|
+
|
|
213
|
+
### `issue-flow update`
|
|
214
|
+
|
|
215
|
+
| Argument / Option | Description |
|
|
216
|
+
|---|---|
|
|
217
|
+
| `PROJECT_DIR` | Project root directory. Defaults to `.` (current directory). |
|
|
218
|
+
| `--skip-dep-check` | Skip the external-CLI dependency check (`git`, `gh`) and the confirmation prompt that follows if anything is missing. |
|
|
219
|
+
|
|
220
|
+
Use `update` after upgrading the **issue-flow** package to refresh the packaged slash commands, Cursor rule, and `docs/cursor-issue-workflow.md` from the version you have installed. This **overwrites** those generated files (unlike a plain second `init`). It still does not modify arbitrary files under `.issueflows/` (for example your `issue*_original.md` / `issue*_status.md` files), and it creates any **new** `.issueflows/` subdirectories required by the current package.
|
|
221
|
+
|
|
222
|
+
### `issue-flow build`
|
|
223
|
+
|
|
224
|
+
| Argument / Option | Description |
|
|
225
|
+
|---|---|
|
|
226
|
+
| `PROJECT_DIR` | Project root directory to scan with graphify. Defaults to `.`. |
|
|
227
|
+
| `...graphify args` | Any extra arguments are forwarded **verbatim** to the `graphify` CLI (`--update`, `--no-viz`, `--mode deep`, `--watch`, …). |
|
|
228
|
+
|
|
229
|
+
`build` requires `graphifyy` to be installed (`uv tool install graphifyy`). When the `graphify` CLI is missing, the command prints install hints and exits with code `2`. Outputs land in `graphify-out/` (`graph.html`, `GRAPH_REPORT.md`, `graph.json`).
|
|
230
|
+
|
|
231
|
+
### When to use which
|
|
232
|
+
|
|
233
|
+
| Goal | Command |
|
|
234
|
+
|---|---|
|
|
235
|
+
| First-time setup, or add missing files only | `issue-flow init` |
|
|
236
|
+
| Pull newer templates after `uv tool upgrade issue-flow` (or similar) | `issue-flow update` |
|
|
237
|
+
| Replace generated scaffolds without upgrading logic | `issue-flow init --force` |
|
|
238
|
+
| Rebuild the graphify knowledge graph | `issue-flow build` |
|
|
239
|
+
|
|
240
|
+
## Configuration
|
|
241
|
+
|
|
242
|
+
issue-flow reads a `.env` file from the project root (via python-dotenv). The following environment variables are supported:
|
|
243
|
+
|
|
244
|
+
| Variable | Default | Description |
|
|
245
|
+
|---|---|---|
|
|
246
|
+
| `ISSUEFLOW_DIR` | `.issueflows` | Name of the issue-tracking directory. |
|
|
247
|
+
| `ISSUEFLOW_AGENT_DIR` | `.cursor` | Name of the agent/IDE config directory (currently `.cursor`). |
|
|
248
|
+
| `ISSUEFLOW_DOCS_DIR` | `docs` | Where to write the workflow documentation file. |
|
|
249
|
+
| `ISSUEFLOW_HISTORY_FILE` | `HISTORY.md` | Changelog file that `/issue-close` updates (set to e.g. `CHANGELOG.md` for different conventions). |
|
|
250
|
+
|
|
251
|
+
## Development
|
|
252
|
+
|
|
253
|
+
```bash
|
|
254
|
+
git clone https://github.com/jepegit/issue-flow.git
|
|
255
|
+
cd issue-flow
|
|
256
|
+
uv sync
|
|
257
|
+
|
|
258
|
+
# Run tests
|
|
259
|
+
uv run pytest
|
|
260
|
+
|
|
261
|
+
# Lint
|
|
262
|
+
uv run ruff check src/ tests/
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
## Changelog
|
|
266
|
+
|
|
267
|
+
See [HISTORY.md](HISTORY.md) for release notes.
|
|
268
|
+
|
|
269
|
+
## Future plans
|
|
270
|
+
|
|
271
|
+
- **Multi-tool support** — generate config for other AI coding tools (Claude Code, Windsurf, etc.) in addition to Cursor.
|
|
272
|
+
- **`issue-flow status`** — show a dashboard of current, partly-solved, and solved issues.
|
|
273
|
+
- **Custom templates** — let users supply their own Jinja2 templates to tailor slash commands and rules to their team's conventions.
|
|
274
|
+
- **Git hook integration** — optionally move issue files on commit based on status markers.
|
|
275
|
+
- **GitHub Actions workflow** — ship a reusable action that syncs issue state between `.issueflows/` and GitHub issue labels/milestones.
|
|
276
|
+
|
|
277
|
+
## License
|
|
278
|
+
|
|
279
|
+
This project is released under the MIT License. See the full text in the repository: [LICENSE](https://github.com/jepegit/issue-flow/blob/main/LICENSE).
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
# issue-flow
|
|
2
|
+
|
|
3
|
+
Agents should behave. Let them follow the issue flow.
|
|
4
|
+
|
|
5
|
+
**issue-flow** scaffolds a lightweight issue-tracking workflow into your project so that Cursor AI agents can pick up GitHub issues, plan work, and land PRs in a consistent way.
|
|
6
|
+
|
|
7
|
+
## What it does
|
|
8
|
+
|
|
9
|
+
Running `issue-flow init` in your project root creates:
|
|
10
|
+
|
|
11
|
+
```text
|
|
12
|
+
your-project/
|
|
13
|
+
.issueflows/
|
|
14
|
+
00-tools/ # Helper scripts for agents
|
|
15
|
+
01-current-issues/ # Active issue markdown files
|
|
16
|
+
02-partly-solved-issues/ # Parked / in-progress issues
|
|
17
|
+
03-solved-issues/ # Completed issues archive
|
|
18
|
+
.cursor/
|
|
19
|
+
commands/
|
|
20
|
+
iflow.md # /iflow — smart dispatcher (quick start)
|
|
21
|
+
issue-init.md # /issue-init — fetch a GitHub issue locally
|
|
22
|
+
issue-plan.md # /issue-plan — write issue<N>_plan.md and confirm
|
|
23
|
+
issue-start.md # /issue-start — implement the plan
|
|
24
|
+
issue-pause.md # /issue-pause — park work in 02-partly-solved-issues/
|
|
25
|
+
issue-close.md # /issue-close — test, commit, push, PR
|
|
26
|
+
issue-cleanup.md # /issue-cleanup — post-merge branch hygiene
|
|
27
|
+
issue-yolo.md # /issue-yolo — all-in-one for small, low-risk issues
|
|
28
|
+
build.md # /build — rebuild the graphify knowledge graph (optional)
|
|
29
|
+
skills/ # Optional Agent Skills (explicit / @ invoke)
|
|
30
|
+
issueflow-iflow/SKILL.md
|
|
31
|
+
issueflow-issue-init/SKILL.md
|
|
32
|
+
issueflow-issue-plan/SKILL.md
|
|
33
|
+
issueflow-issue-start/SKILL.md
|
|
34
|
+
issueflow-issue-pause/SKILL.md
|
|
35
|
+
issueflow-issue-close/SKILL.md
|
|
36
|
+
issueflow-issue-cleanup/SKILL.md
|
|
37
|
+
issueflow-issue-yolo/SKILL.md
|
|
38
|
+
issueflow-version-bump/SKILL.md
|
|
39
|
+
issueflow-history-update/SKILL.md
|
|
40
|
+
issueflow-build/SKILL.md
|
|
41
|
+
rules/
|
|
42
|
+
issueflow-rules.mdc # Always-on Cursor rule for the workflow
|
|
43
|
+
docs/
|
|
44
|
+
cursor-issue-workflow.md # Human-readable overview of the workflow
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
The Cursor slash commands give agents a repeatable flow. The linear path is:
|
|
48
|
+
|
|
49
|
+
1. `/issue-init 42` — pulls GitHub issue #42 into `.issueflows/01-current-issues/` and archives older issues.
|
|
50
|
+
2. `/issue-plan` — drafts `issue<N>_plan.md` (Goal / Constraints / Approach / Files to touch / Test strategy / Open questions) and stops for your confirmation.
|
|
51
|
+
3. `/issue-start` — reads the confirmed plan and implements it. If no plan file exists, it offers to run `/issue-plan` first, proceed without a plan, or abort.
|
|
52
|
+
4. `/issue-close` — runs tests, optionally bumps version with `uv version --bump`, appends a `HISTORY.md` entry (or promotes `[Unreleased]` to a new release section on a bump), updates status files, commits, pushes, and opens a PR.
|
|
53
|
+
5. `/issue-cleanup` — after the PR merges, switches to the default branch, fast-forwards, prunes, and deletes the merged local branch.
|
|
54
|
+
|
|
55
|
+
Plus a few off-path commands:
|
|
56
|
+
|
|
57
|
+
- `/iflow` — **quick start**: inspects the current issue's state and dispatches to the right linear step automatically. A branch-derived number (`42-fix-login` → `N=42`) is authoritative, so `/iflow` works from a fresh branch too.
|
|
58
|
+
- `/issue-pause` — park the current issue in `02-partly-solved-issues/` with a **Remaining work** note; optional WIP commit + switch back to the default branch.
|
|
59
|
+
- `/issue-yolo` — all-in-one chain (`init → plan → start → close`) for small, low-risk issues, with up-front safeguards (refuses on the default branch, refuses with dirty unrelated changes, requires passing tests, single consolidated confirm).
|
|
60
|
+
|
|
61
|
+
The matching **Agent Skills** (under `.cursor/skills/`) carry the same workflows for on-demand use with `/issueflow-iflow`, `/issueflow-issue-init`, `/issueflow-issue-plan`, `/issueflow-issue-start`, `/issueflow-issue-pause`, `/issueflow-issue-close`, `/issueflow-issue-cleanup`, `/issueflow-issue-yolo`, `@issueflow-version-bump` when you need only the bump steps, or `@issueflow-history-update` when you need only the changelog update (see [Cursor Agent Skills](https://cursor.com/docs/context/skills)).
|
|
62
|
+
|
|
63
|
+
## Prerequisites
|
|
64
|
+
|
|
65
|
+
issue-flow itself is a small Python CLI, but the **scaffolded slash commands
|
|
66
|
+
it writes into your project shell out to a few external tools**. If they are
|
|
67
|
+
missing, the slash commands will fail at runtime — so `issue-flow init` now
|
|
68
|
+
checks for them up front and prints install hints before it does anything.
|
|
69
|
+
|
|
70
|
+
Required:
|
|
71
|
+
|
|
72
|
+
- **[Git](https://git-scm.com/downloads)** — used by every slash command for
|
|
73
|
+
branch, fetch, status, commit, and push operations. Almost certainly already
|
|
74
|
+
installed if you're here, but the check covers it for completeness.
|
|
75
|
+
- **[GitHub CLI (`gh`)](https://cli.github.com/)** — used by `/issue-init` to
|
|
76
|
+
fetch issues, by `/issue-close` to open PRs, and by `/issue-cleanup` to check
|
|
77
|
+
PR merge status. After installing, run `gh auth login` once to authenticate.
|
|
78
|
+
|
|
79
|
+
Recommended:
|
|
80
|
+
|
|
81
|
+
- **[uv](https://docs.astral.sh/uv/)** — how issue-flow itself is meant to be
|
|
82
|
+
installed, and how this repo manages its own Python environment.
|
|
83
|
+
|
|
84
|
+
Quick install pointers for `gh`:
|
|
85
|
+
|
|
86
|
+
| Platform | Command |
|
|
87
|
+
|---|---|
|
|
88
|
+
| macOS (Homebrew) | `brew install gh` |
|
|
89
|
+
| Windows (winget) | `winget install --id GitHub.cli -e` |
|
|
90
|
+
| Linux (Debian/Ubuntu) | `sudo apt install gh` (or see [cli.github.com](https://cli.github.com/) for the official repo) |
|
|
91
|
+
|
|
92
|
+
If a dependency is missing, `issue-flow init` prints the installation hints
|
|
93
|
+
and asks whether to continue anyway. You can bypass the prompt in automation
|
|
94
|
+
with `issue-flow init --skip-dep-check` (the same flag is available on
|
|
95
|
+
`issue-flow update`), and the prompt is also auto-skipped when stdin is not
|
|
96
|
+
a TTY (e.g. CI pipelines).
|
|
97
|
+
|
|
98
|
+
### Optional: graphify integration
|
|
99
|
+
|
|
100
|
+
issue-flow has a lightweight integration with [graphify](https://graphify.net)
|
|
101
|
+
(PyPI: `graphifyy`, CLI: `graphify`) — a tool that turns the project into a
|
|
102
|
+
queryable knowledge graph that AI assistants can read instead of grepping
|
|
103
|
+
through files. The integration is **opt-in by installing `graphifyy` as its
|
|
104
|
+
own tool** (the same way you installed issue-flow): there is no flag, no
|
|
105
|
+
`.env` switch, no extras to remember. Detection is purely PATH-based.
|
|
106
|
+
|
|
107
|
+
What `issue-flow` does when `graphify` is on PATH:
|
|
108
|
+
|
|
109
|
+
- `issue-flow init` and `issue-flow update` run `graphify cursor install` so
|
|
110
|
+
the graphify Cursor skill is registered alongside the issue-flow scaffold.
|
|
111
|
+
If graphify is not installed, both commands just print install hints and
|
|
112
|
+
continue — they never block.
|
|
113
|
+
- A new slash command `/build` (and matching `/issueflow-build` skill) wraps
|
|
114
|
+
`issue-flow build`, which forwards every argument to the `graphify` CLI
|
|
115
|
+
verbatim (`--update`, `--no-viz`, `--mode deep`, `--watch`, …).
|
|
116
|
+
- The scaffolded rules and `/issue-start` mention `graphify-out/GRAPH_REPORT.md`
|
|
117
|
+
as a recommended pre-read when the file exists. `/build` is **off-path** —
|
|
118
|
+
`/iflow` never auto-dispatches to it.
|
|
119
|
+
|
|
120
|
+
To enable, install graphify as its own standalone tool:
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
uv tool install graphifyy # recommended
|
|
124
|
+
# or
|
|
125
|
+
pipx install graphifyy
|
|
126
|
+
# or
|
|
127
|
+
pip install graphifyy
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
> **Why not an `issue-flow[graphify]` extra (or `uv tool install issue-flow --with graphifyy`)?**
|
|
131
|
+
> `uv tool install` only puts the **host package's** entry-point scripts on
|
|
132
|
+
> PATH. An extra (or `--with graphifyy`) pulls graphifyy into issue-flow's
|
|
133
|
+
> venv but leaves the `graphify` CLI invisible to the shell, so `/build`
|
|
134
|
+
> and `graphify cursor install` would still fail. Installing graphify as
|
|
135
|
+
> its own tool puts a real `graphify` shim on PATH and matches how we
|
|
136
|
+
> treat `git` / `gh`.
|
|
137
|
+
|
|
138
|
+
> **Just installed graphifyy and `issue-flow init` says it's still missing?**
|
|
139
|
+
> uv prints `~/.local/bin is not on your PATH` after the first
|
|
140
|
+
> `uv tool install`. Run `uv tool update-shell` (refreshes shell rc files),
|
|
141
|
+
> then **restart your shell and Cursor** so the new PATH takes effect.
|
|
142
|
+
> issue-flow's missing-CLI hint also detects this case and tells you the
|
|
143
|
+
> exact directory to add.
|
|
144
|
+
|
|
145
|
+
After installing, run `issue-flow update` once so the graphify Cursor skill
|
|
146
|
+
gets registered.
|
|
147
|
+
|
|
148
|
+
## Installation
|
|
149
|
+
|
|
150
|
+
Requires Python 3.13+ and [uv](https://docs.astral.sh/uv/).
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
uv tool install issue-flow
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
Or add it as a dev dependency to your project:
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
uv add --dev issue-flow
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
## Quick start
|
|
163
|
+
|
|
164
|
+
```bash
|
|
165
|
+
cd your-project
|
|
166
|
+
issue-flow init
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
That's it. Open the project in Cursor and start with `/iflow` (or step through `/issue-init`, `/issue-plan`, `/issue-start`, `/issue-close`, `/issue-cleanup` explicitly).
|
|
170
|
+
|
|
171
|
+
## Usage
|
|
172
|
+
|
|
173
|
+
```
|
|
174
|
+
issue-flow init [PROJECT_DIR] [--force] [--skip-dep-check]
|
|
175
|
+
issue-flow update [PROJECT_DIR] [--skip-dep-check]
|
|
176
|
+
issue-flow build [PROJECT_DIR] [-- ...graphify args]
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### `issue-flow init`
|
|
180
|
+
|
|
181
|
+
| Argument / Option | Description |
|
|
182
|
+
|---|---|
|
|
183
|
+
| `PROJECT_DIR` | Project root directory. Defaults to `.` (current directory). |
|
|
184
|
+
| `--force`, `-f` | Overwrite generated Cursor commands, rules, and workflow doc instead of skipping them. |
|
|
185
|
+
| `--skip-dep-check` | Skip the external-CLI dependency check (`git`, `gh`) and the confirmation prompt that follows if anything is missing. Useful in automation. |
|
|
186
|
+
|
|
187
|
+
Running `init` again without `--force` is safe: generated scaffold files that already exist are skipped, and **issue markdown under `.issueflows/` is never touched** by `init` or `update`. When the CLI detects an existing scaffold, it reminds you about `update` and `--force`.
|
|
188
|
+
|
|
189
|
+
### `issue-flow update`
|
|
190
|
+
|
|
191
|
+
| Argument / Option | Description |
|
|
192
|
+
|---|---|
|
|
193
|
+
| `PROJECT_DIR` | Project root directory. Defaults to `.` (current directory). |
|
|
194
|
+
| `--skip-dep-check` | Skip the external-CLI dependency check (`git`, `gh`) and the confirmation prompt that follows if anything is missing. |
|
|
195
|
+
|
|
196
|
+
Use `update` after upgrading the **issue-flow** package to refresh the packaged slash commands, Cursor rule, and `docs/cursor-issue-workflow.md` from the version you have installed. This **overwrites** those generated files (unlike a plain second `init`). It still does not modify arbitrary files under `.issueflows/` (for example your `issue*_original.md` / `issue*_status.md` files), and it creates any **new** `.issueflows/` subdirectories required by the current package.
|
|
197
|
+
|
|
198
|
+
### `issue-flow build`
|
|
199
|
+
|
|
200
|
+
| Argument / Option | Description |
|
|
201
|
+
|---|---|
|
|
202
|
+
| `PROJECT_DIR` | Project root directory to scan with graphify. Defaults to `.`. |
|
|
203
|
+
| `...graphify args` | Any extra arguments are forwarded **verbatim** to the `graphify` CLI (`--update`, `--no-viz`, `--mode deep`, `--watch`, …). |
|
|
204
|
+
|
|
205
|
+
`build` requires `graphifyy` to be installed (`uv tool install graphifyy`). When the `graphify` CLI is missing, the command prints install hints and exits with code `2`. Outputs land in `graphify-out/` (`graph.html`, `GRAPH_REPORT.md`, `graph.json`).
|
|
206
|
+
|
|
207
|
+
### When to use which
|
|
208
|
+
|
|
209
|
+
| Goal | Command |
|
|
210
|
+
|---|---|
|
|
211
|
+
| First-time setup, or add missing files only | `issue-flow init` |
|
|
212
|
+
| Pull newer templates after `uv tool upgrade issue-flow` (or similar) | `issue-flow update` |
|
|
213
|
+
| Replace generated scaffolds without upgrading logic | `issue-flow init --force` |
|
|
214
|
+
| Rebuild the graphify knowledge graph | `issue-flow build` |
|
|
215
|
+
|
|
216
|
+
## Configuration
|
|
217
|
+
|
|
218
|
+
issue-flow reads a `.env` file from the project root (via python-dotenv). The following environment variables are supported:
|
|
219
|
+
|
|
220
|
+
| Variable | Default | Description |
|
|
221
|
+
|---|---|---|
|
|
222
|
+
| `ISSUEFLOW_DIR` | `.issueflows` | Name of the issue-tracking directory. |
|
|
223
|
+
| `ISSUEFLOW_AGENT_DIR` | `.cursor` | Name of the agent/IDE config directory (currently `.cursor`). |
|
|
224
|
+
| `ISSUEFLOW_DOCS_DIR` | `docs` | Where to write the workflow documentation file. |
|
|
225
|
+
| `ISSUEFLOW_HISTORY_FILE` | `HISTORY.md` | Changelog file that `/issue-close` updates (set to e.g. `CHANGELOG.md` for different conventions). |
|
|
226
|
+
|
|
227
|
+
## Development
|
|
228
|
+
|
|
229
|
+
```bash
|
|
230
|
+
git clone https://github.com/jepegit/issue-flow.git
|
|
231
|
+
cd issue-flow
|
|
232
|
+
uv sync
|
|
233
|
+
|
|
234
|
+
# Run tests
|
|
235
|
+
uv run pytest
|
|
236
|
+
|
|
237
|
+
# Lint
|
|
238
|
+
uv run ruff check src/ tests/
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
## Changelog
|
|
242
|
+
|
|
243
|
+
See [HISTORY.md](HISTORY.md) for release notes.
|
|
244
|
+
|
|
245
|
+
## Future plans
|
|
246
|
+
|
|
247
|
+
- **Multi-tool support** — generate config for other AI coding tools (Claude Code, Windsurf, etc.) in addition to Cursor.
|
|
248
|
+
- **`issue-flow status`** — show a dashboard of current, partly-solved, and solved issues.
|
|
249
|
+
- **Custom templates** — let users supply their own Jinja2 templates to tailor slash commands and rules to their team's conventions.
|
|
250
|
+
- **Git hook integration** — optionally move issue files on commit based on status markers.
|
|
251
|
+
- **GitHub Actions workflow** — ship a reusable action that syncs issue state between `.issueflows/` and GitHub issue labels/milestones.
|
|
252
|
+
|
|
253
|
+
## License
|
|
254
|
+
|
|
255
|
+
This project is released under the MIT License. See the full text in the repository: [LICENSE](https://github.com/jepegit/issue-flow/blob/main/LICENSE).
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
"""Command-line interface for issue-flow."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
import typer
|
|
8
|
+
from rich.console import Console
|
|
9
|
+
|
|
10
|
+
app = typer.Typer(
|
|
11
|
+
name="issue-flow",
|
|
12
|
+
add_completion=False,
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
_console = Console()
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@app.callback()
|
|
19
|
+
def _callback() -> None:
|
|
20
|
+
"""Agents should behave. Let them follow the issue flow."""
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@app.command()
|
|
24
|
+
def init(
|
|
25
|
+
project_dir: Path = typer.Argument(
|
|
26
|
+
default=Path("."),
|
|
27
|
+
help="Project root directory (defaults to current directory).",
|
|
28
|
+
exists=True,
|
|
29
|
+
file_okay=False,
|
|
30
|
+
resolve_path=True,
|
|
31
|
+
),
|
|
32
|
+
force: bool = typer.Option(
|
|
33
|
+
False,
|
|
34
|
+
"--force",
|
|
35
|
+
"-f",
|
|
36
|
+
help="Overwrite existing files without asking.",
|
|
37
|
+
),
|
|
38
|
+
skip_dep_check: bool = typer.Option(
|
|
39
|
+
False,
|
|
40
|
+
"--skip-dep-check",
|
|
41
|
+
help=(
|
|
42
|
+
"Skip the external-CLI dependency check (git, gh) and the "
|
|
43
|
+
"confirmation prompt that follows if anything is missing."
|
|
44
|
+
),
|
|
45
|
+
),
|
|
46
|
+
) -> None:
|
|
47
|
+
"""Scaffold issue-flow directories and Cursor config files in a project."""
|
|
48
|
+
from issue_flow.init import run_init
|
|
49
|
+
|
|
50
|
+
run_init(
|
|
51
|
+
project_root=project_dir, force=force, skip_dep_check=skip_dep_check
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
@app.command()
|
|
56
|
+
def update(
|
|
57
|
+
project_dir: Path = typer.Argument(
|
|
58
|
+
default=Path("."),
|
|
59
|
+
help="Project root directory (defaults to current directory).",
|
|
60
|
+
exists=True,
|
|
61
|
+
file_okay=False,
|
|
62
|
+
resolve_path=True,
|
|
63
|
+
),
|
|
64
|
+
skip_dep_check: bool = typer.Option(
|
|
65
|
+
False,
|
|
66
|
+
"--skip-dep-check",
|
|
67
|
+
help=(
|
|
68
|
+
"Skip the external-CLI dependency check (git, gh) and the "
|
|
69
|
+
"confirmation prompt that follows if anything is missing."
|
|
70
|
+
),
|
|
71
|
+
),
|
|
72
|
+
) -> None:
|
|
73
|
+
"""Refresh packaged Cursor commands, rules, and workflow doc from this package."""
|
|
74
|
+
from issue_flow.init import run_update
|
|
75
|
+
|
|
76
|
+
run_update(project_root=project_dir, skip_dep_check=skip_dep_check)
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
@app.command(
|
|
80
|
+
context_settings={
|
|
81
|
+
"allow_extra_args": True,
|
|
82
|
+
"ignore_unknown_options": True,
|
|
83
|
+
},
|
|
84
|
+
)
|
|
85
|
+
def build(
|
|
86
|
+
ctx: typer.Context,
|
|
87
|
+
project_dir: Path = typer.Argument(
|
|
88
|
+
default=Path("."),
|
|
89
|
+
help=(
|
|
90
|
+
"Project root directory to scan with graphify. "
|
|
91
|
+
"Defaults to the current directory."
|
|
92
|
+
),
|
|
93
|
+
exists=True,
|
|
94
|
+
file_okay=False,
|
|
95
|
+
resolve_path=True,
|
|
96
|
+
),
|
|
97
|
+
) -> None:
|
|
98
|
+
"""Rebuild the graphify knowledge graph for the project.
|
|
99
|
+
|
|
100
|
+
Forwards every extra argument to the ``graphify`` CLI verbatim, so
|
|
101
|
+
flags like ``--update``, ``--no-viz``, ``--mode deep``, or
|
|
102
|
+
``--watch`` pass straight through. Requires ``graphify`` to be on
|
|
103
|
+
``PATH`` (install with ``uv tool install graphifyy``).
|
|
104
|
+
"""
|
|
105
|
+
from issue_flow.graphify import run_build
|
|
106
|
+
|
|
107
|
+
exit_code = run_build(project_dir, ctx.args, _console)
|
|
108
|
+
if exit_code != 0:
|
|
109
|
+
raise typer.Exit(code=exit_code)
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def main() -> None:
|
|
113
|
+
"""Entry point for the `issue-flow` console script."""
|
|
114
|
+
app()
|