Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions .issueflows/03-solved-issues/issue49_original.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Issue #49: add graphify

Source: https://github.com/jepegit/issue-flow/issues/49

## Original issue text



Graphify is a python library (package name is graphifyy). It has several cli commands (see https://graphify.net/graphify-cli-commands.html)
The code lives on https://github.com/safishamsi/graphify

Tasks:

Figure out how graphify can be implemented in issue-flow.

Implement graphify as a issue-flow feature (i.e. that we for example can run `issue-flow init --with graphify` (or `issue-flow update --with graphify`)), and that it then has graphify enabled. It could be that the markdown files (jina-templates, skills, rules) also needs to be updated. And graphify should also run when doing issue-flow init or update.

We should also add another cli command for issue-flow. It could be called 'build'. And that runs a graphify rebuilding of the graph.



60 changes: 60 additions & 0 deletions .issueflows/03-solved-issues/issue49_plan.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# Plan for issue #49: add graphify

## Goal

Wire [graphify](https://graphify.net) (PyPI: `graphifyy`, CLI: `graphify`) into issue-flow so that scaffolded projects automatically register the graphify Cursor skill, ship a new `issue-flow build` command (and `/build` slash command) that rebuilds the knowledge graph, and the existing rules / commands tell agents to consult `graphify-out/GRAPH_REPORT.md` when it exists.

## Decisions confirmed with user

- **Dependency model:** optional Python extra. `pyproject.toml` gains `[project.optional-dependencies] graphify = ["graphifyy>=0.7"]`. issue-flow always shells out to the `graphify` CLI; the extra just guarantees it gets installed.
- **Activation:** auto-detect, no `--with graphify` flag. If `graphify` is on `PATH` at init/update time we wire it in; otherwise we print a one-line hint. Graphify-aware lines in the scaffolded markdown are always rendered (they no-op when the graph isn't built).
- **Lifecycle depth:** medium. New `/build` slash command, `graphify cursor install` is auto-run from `init`/`update`, and `issueflow-rules.mdc` + `/issue-start` + `/issue-close` get short graphify-aware additions. No automatic `graphify .` rebuilds from `/issue-close` and no `graphify hook install`.

## Constraints

- Project rules (`uv` only, `uv add` / `uv sync`, `uv run`).
- Back-compat: existing `init` / `update` flows must keep working unchanged when `graphify` is not installed (no errors, just a hint). `update` must still leave `.issueflows/` issue files untouched.
- Don't add `graphifyy` as a hard dependency — it pulls a large transitive footprint.
- `graphify cursor install` must be best-effort: if it fails, we report and continue (don't fail `init`).

## Approach

1. **`graphify` helper module** — new `src/issue_flow/graphify.py` with `is_available`, `register_with_cursor` (best-effort `graphify cursor install`), and `run_build` (subprocess passthrough).
2. **Wire into `init` / `update`** — call a new `_graphify_postinstall(project_root)` near the end of `run_init` / `run_update`.
3. **Add `build` CLI command** — Typer command with extra-args passthrough so `issue-flow build --update`, `--no-viz`, etc. forward verbatim.
4. **New scaffolded `/build` slash command** + matching agent skill, registered in `TEMPLATE_MANIFEST`.
5. **Light edits to existing scaffold templates** — rules, `/iflow`, `/issue-start`, `/issue-close`, workflow doc.
6. **Recommended (non-blocking) dependency hint** for `graphify` in `dependencies.py`.
7. **Design decision record** under `.issueflows/04-designs-and-guides/`.

## Files to touch

- `pyproject.toml` — `[project.optional-dependencies] graphify = ["graphifyy>=0.7"]`.
- `src/issue_flow/cli.py` — `build` Typer command.
- `src/issue_flow/init.py` — `_graphify_postinstall` wiring.
- `src/issue_flow/graphify.py` — new module.
- `src/issue_flow/dependencies.py` — non-blocking recommended dep hint.
- `src/issue_flow/templating.py` — manifest entries for `build.md.j2` and `skills/issueflow_build/SKILL.md.j2`.
- `src/issue_flow/templates/commands/build.md.j2` — new `/build` slash command.
- `src/issue_flow/templates/commands/iflow.md.j2` — list `/build` as off-path.
- `src/issue_flow/templates/commands/issue-start.md.j2` — graphify reading hint.
- `src/issue_flow/templates/commands/issue-close.md.j2` — graphify rebuild hint.
- `src/issue_flow/templates/rules/issueflow-rules.mdc.j2` — "Knowledge graph" section.
- `src/issue_flow/templates/docs/cursor-issue-workflow.md.j2` — paragraph on graphify integration.
- `src/issue_flow/templates/skills/issueflow_build/SKILL.md.j2` — new matching skill.
- `readme.md` — integration docs, `[graphify]` extra, `build` command.
- `.issueflows/04-designs-and-guides/graphify-integration.md` — new decision record.

## Test strategy

- Re-run existing: `uv run pytest`, `uv run ruff check src/ tests/`.
- New tests:
- `tests/test_graphify.py` — `is_available`, `register_with_cursor` (success + failure), `run_build` (exit code + missing-CLI error).
- `tests/test_init.py` — extend with mocked `graphify.is_available()` branches.
- `tests/test_templating.py` — manifest renders new templates cleanly.
- `tests/test_cli.py` — `issue-flow build` exits 0/1 with mocked subprocess and forwards extra args.

## Open questions

- Build skill name `issueflow-build` (chosen for parity).
- Pure passthrough for `build` flags in v1.
39 changes: 39 additions & 0 deletions .issueflows/03-solved-issues/issue49_status.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Status for issue #49: add graphify

- [x] Done

## What landed

- **No Python dependency on graphify** (revised after initial draft — see "Plan deviations" below). graphify is treated as an external CLI, the same way `git` and `gh` are; users install it standalone via `uv tool install graphifyy`.
- **`src/issue_flow/graphify.py`** — `is_available`, `register_with_cursor` (best-effort `graphify cursor install`), and `run_build` (subprocess passthrough). Never raises; falls back to install hints when graphify is absent.
- **`src/issue_flow/dependencies.py`** — added `RECOMMENDED_DEPENDENCIES` (non-blocking) with the graphify entry and a `check_recommended` helper.
- **`src/issue_flow/init.py`** — `_graphify_postinstall` runs at the end of `run_init` and `run_update`, delegating to `register_with_cursor`. No flag plumbing.
- **`src/issue_flow/cli.py`** — new `build` Typer command with `allow_extra_args=True` so `issue-flow build [PROJECT_DIR] [--update --no-viz --mode deep ...]` forwards every flag verbatim to `graphify`. Exits `2` when graphify is missing, propagates graphify's exit code otherwise.
- **`src/issue_flow/templating.py`** — new manifest entries for `commands/build.md.j2` and `skills/issueflow_build/SKILL.md.j2` (manifest count: 21 → 23).
- **New scaffold templates** — `templates/commands/build.md.j2` and `templates/skills/issueflow_build/SKILL.md.j2`.
- **Edits to existing scaffold templates**:
- `iflow.md.j2` — lists `/build` as off-path; adds a graphify-stale hint.
- `issue-start.md.j2` — adds an optional "Knowledge graph" pre-read step pointing at `graphify-out/GRAPH_REPORT.md`.
- `issue-close.md.j2` — adds an optional "Graph freshness" suggestion in the sanity-check step.
- `issueflow-rules.mdc.j2` — new "Knowledge graph (optional, via graphify)" section.
- `cursor-issue-workflow.md.j2` — table updated, new section 7 for `/build`, skill table updated.
- **PATH-orphan detection** (added late) — `find_orphan_install()` probes well-known install dirs (`~/.local/bin`, plus a couple of Windows-specific Scripts dirs). When graphify is missing from PATH but found at a candidate location, the missing-CLI hint switches to a "found but not on PATH" message that names the directory and suggests `uv tool update-shell` plus a shell/Cursor restart. The plain "missing" branch also got an "already installed?" tail so users who just ran `uv tool install graphifyy` don't get confused. README has matching guidance.
- **Tests** — full suite green (100 passing). New files:
- `tests/test_graphify.py` — detection, register_with_cursor success/failure paths, run_build passthrough and missing-CLI handling, PATH-orphan detection (5 new tests).
- `tests/test_cli.py` — Typer CLI smoke tests for `build`.
- Extended `tests/test_init.py` (graphify register wiring, build template scaffold check, knowledge-graph rule section).
- Extended `tests/test_dependencies.py` (recommended graphify entry, `check_recommended`).
- Updated `tests/test_templating.py` manifest count and expected commands/skills.
- **Docs** — `readme.md` gains a "Optional: graphify integration" section, the directory listing, and an `issue-flow build` entry; `.issueflows/04-designs-and-guides/graphify-integration.md` captures the decisions.

## Verified

- `uv run pytest` — 95 passed.
- `uv run ruff check src/ tests/` — clean.

## Plan deviations

- **Dropped the `[project.optional-dependencies] graphify` extra** mid-implementation. Reason: `uv tool install <pkg>` only puts the host package's entry-point scripts on PATH, so `uv tool install 'issue-flow[graphify]'` would install graphifyy into issue-flow's venv but leave the `graphify` CLI invisible to the shell — the extra advertised something it could not deliver to the primary install audience. The integration now treats graphify like `git` / `gh`: an external CLI installed separately. README, `dependencies.py` install hints, and the design doc were all updated to match.
- The plan mentioned "or extend `format_missing_report`" — chose the dedicated `RECOMMENDED_DEPENDENCIES` list + `check_recommended` helper instead. Cleaner separation: required deps still block via `format_missing_report`; recommended deps only inform.
- `run_build` uses a narrow heuristic for path injection: if `extra_args` is empty *or* its first token starts with `-`, we inject the project root; otherwise we trust the user's positional. This handles `--mode deep` (where `deep` is a flag value, not a path) correctly.
- Did not add a `tests/__init__.py` for the new `templates/skills/issueflow_build/` folder (matches the existing skills, which also have none).
83 changes: 83 additions & 0 deletions .issueflows/04-designs-and-guides/graphify-integration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# Graphify integration: design decisions

**Issue:** [#49 — add graphify](https://github.com/jepegit/issue-flow/issues/49)
**Status:** decided 2026-05-14, implemented in the same issue.
**Scope:** how issue-flow integrates with [graphify](https://graphify.net) (PyPI: `graphifyy`, CLI: `graphify`).

## Context

Graphify turns a project (code + docs + papers + images + videos) into a queryable knowledge graph that AI assistants can read instead of grepping through files. Issue #49 asked for an opt-in integration so issue-flow's scaffold sets graphify up automatically, agents know the graph exists, and there is a one-shot command to refresh it.

## Decisions

### 1. External CLI, no Python dependency

issue-flow does **not** depend on `graphifyy` — not as a hard dependency and
not as an optional extra. The integration is purely a runtime PATH lookup
plus subprocess passthrough to the `graphify` CLI. Users install graphify as
its own standalone tool (`uv tool install graphifyy`), the same way they
install issue-flow.

**Alternatives considered**

- *Hard dependency* — pull `graphifyy` for every install. Rejected: graphify
has a large transitive footprint (tree-sitter, optional video/PDF/MCP
extras). issue-flow has 4 small dependencies today; we want to keep that.
- *Optional Python extra* (`uv tool install 'issue-flow[graphify]'`,
`pyproject.toml` declaring `[project.optional-dependencies] graphify =
["graphifyy>=0.7"]`). Initially shipped, then **rolled back** before
release. Reason: `uv tool install <pkg>` only exposes `<pkg>`'s own
entry-point scripts on PATH; extras get installed into the same venv but
their CLIs stay hidden. So `uv tool install 'issue-flow[graphify]'` would
pull graphifyy in but leave `/build` and `graphify cursor install`
broken — the extra promised something it could not deliver to the primary
install audience. Plain `pip install issue-flow[graphify]` would work,
but that is not the recommended install path.
- *`issue-flow install-graphify` helper* that runs `uv tool install
graphifyy` for the user. Rejected: too magic, picks the wrong installer
for some users, and the manual two-step install is one extra command for
what's now a fully external dependency. Same posture as `git` / `gh`.

### 2. Auto-detect at runtime, no `--with graphify` flag

`init` / `update` call `shutil.which("graphify")`. If the CLI is on `PATH`, they run `graphify cursor install` (best-effort; failures are reported but never abort the parent command). Otherwise they print install hints and continue.

The graphify-flavored mentions in our scaffolded markdown (rules, `/issue-start`, `/issue-close`, `/iflow`) are **always rendered** so there is nothing to "switch on". Agents are told to consult `graphify-out/GRAPH_REPORT.md` *if it exists* — when the user has not opted in, the file is absent and the guidance is a no-op.

**Alternatives considered**

- *`--with graphify` flag persisted in `.env`* (the original issue suggestion). Rejected: introduces hidden state, doubles the surface area of `init`/`update` (`--with` and `--without`), and the auto-detect path achieves the same UX with less code. Surfaced this trade-off to the user; they confirmed auto-detect.
- *One-shot flag, no persistence* — same surface area as the sticky version but with worse UX (must re-pass on every `update`).

### 3. Medium lifecycle integration

What we ship:

- New CLI: `issue-flow build [PROJECT_DIR] [...args]` — pure passthrough wrapper around `graphify` (forward every flag verbatim, do not re-implement graphify's flag set).
- New slash command `/build` and matching `/issueflow-build` agent skill.
- `init` / `update` auto-run `graphify cursor install` (best-effort) when graphify is on PATH.
- `issueflow-rules.mdc` gains a "Knowledge graph" section pointing at `graphify-out/GRAPH_REPORT.md`.
- `/issue-start` suggests skimming the graph report; `/issue-close` suggests `/build` after structural changes. Neither runs `graphify` automatically.

What we deliberately **do not** ship:

- No automatic `graphify .` from `/issue-close`. Building the graph can be slow (LLM passes for docs/PDFs) and may have cost implications; we keep it opt-in.
- No `graphify hook install`. The user can run it directly if they want post-commit rebuilds; we do not want to touch `.git/hooks` from `issue-flow`.
- No deep wrapper over graphify flags. `issue-flow build` is a thin passthrough; if graphify adds or renames flags upstream, we do not need a release.

**Alternatives considered**

- *Light* (only `/build` + `cursor install`, leave existing rules/commands untouched). Rejected: agents would not know the graph exists.
- *Heavy* (auto-rebuild from `/issue-close` and/or `graphify hook install`). Rejected: too much magic, surprises users who do not know their changes trigger an LLM pass.

## Consequences

- Two new modules: `src/issue_flow/graphify.py` (`is_available`, `register_with_cursor`, `run_build`) and a new `RECOMMENDED_DEPENDENCIES` list in `dependencies.py`.
- One new template (`commands/build.md.j2`) + one new skill (`skills/issueflow_build/SKILL.md.j2`); manifest count goes from 21 to 23.
- `issue-flow build` exits `2` (not `1`) when `graphify` is missing, to distinguish "tool not installed" from "graphify ran and failed".
- Graphify is a fast-moving upstream. Because we only shell out to the CLI, version-skew between issue-flow and graphify is harmless: agents see whatever flags the installed `graphify` supports.

## Notes for future work

- If we add `issue-flow status` (already on the README's Future plans), it could surface graph freshness (`graphify-out/manifest.json` mtime vs source tree) without re-implementing graphify's freshness check.
- If multi-tool support lands (Claude Code, Windsurf, etc.), `register_with_cursor` should grow a sibling `register_with_<tool>` that calls `graphify <tool> install`.
1 change: 1 addition & 0 deletions HISTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ than the GitHub release notes they link to.
## [Unreleased]

- `/issue-init` now fetches GitHub issue comments and writes a curated "Comments (curated summary)" section into `issue<N>_original.md` (later comments win over earlier ones). New `issueflow-issue-comments` skill documents the triage rules (three buckets, noise filtering, edge cases). (#45)
- **Optional graphify integration (#49).** New `issue-flow build` CLI and `/build` slash command (plus matching `/issueflow-build` skill) wrap the [graphify](https://graphify.net) CLI. `issue-flow init` / `update` auto-run `graphify cursor install` when `graphify` is on PATH and otherwise print install hints — including PATH-orphan detection that surfaces "found at `<path>` but not on PATH" when the user installed `graphifyy` but uv's bin directory has not been added to PATH yet. The scaffolded rules and `/issue-start` / `/issue-close` point agents at `graphify-out/GRAPH_REPORT.md` when present so they can navigate by graph instead of grepping. Graphify is treated like `git` / `gh` — install standalone with `uv tool install graphifyy`, no Python extra (an `[graphify]` extra or `uv tool install issue-flow --with graphifyy` would leave the `graphify` CLI off PATH).

## [0.2.3] - 2026-04-19

Expand Down
Loading
Loading