The command was renamed and the Copilot integration changed. After upgrading:
/code-flowis now/code-flow.map. Delete the stale command file:.claude/commands/code-flow.mdor.gemini/commands/code-flow.toml.- Copilot now installs an invocable prompt at
.github/prompts/code-flow.map.prompt.md. The installer no longer edits.github/copilot-instructions.md.- If you use Copilot in VS Code, remove the old
## Code Flow — Documentation Generatorsection from.github/copilot-instructions.mdby hand — otherwise it lingers and contradicts the new prompt. - If you use Copilot anywhere else (github.com, JetBrains, Visual Studio, the CLI), keep that section. Prompt files are a documented VS Code feature; whether any other surface reads them has not been verified here, so assume the new prompt file does nothing for you. The instructions file is read across surfaces, and deleting it could leave you with no Code Flow skill at all. See the GitHub Copilot notes under Usage below.
- If you use Copilot in VS Code, remove the old
/code-flow.mapnow also writesCode_Flows/<feature_name>.jsonandCode_Flows/index.json. Flows mapped before 1.0 have no sidecar until re-mapped.
Everything 1.0 adds is listed in CHANGELOG.md.
A portable Code Flow skill for AI coding assistants — Claude Code, Gemini CLI, and GitHub Copilot. Installs a /code-flow.map command that asks the assistant to trace a feature through your codebase and produce both a markdown document and an interactive HTML page describing exactly how it works.
Given a feature or flow name (e.g. user login, password reset, checkout), the assistant will:
- Discover the relevant files and functions using glob + grep searches.
- Trace the call chain from entry point to final output, following every function that participates in the flow.
- Docstring any undocumented functions encountered along the way, editing them in place.
- Generate
Code_Flows/<feature_name>.mdcontaining:- A plain-language description of the flow's purpose and trigger conditions.
- A MermaidJS flow/sequence diagram with every participating function as a named node.
- A bullet list of all functions in the diagram.
- A reference table with each function's description and exact
file:linelocation.
- Generate
Code_Flows/<feature_name>.html— an interactive, self-contained view of the same flow (see below). - Write
Code_Flows/<feature_name>.json— the same flow data as plain JSON — and create or update the sharedCode_Flows/index.jsonregistry with an entry for this flow. (Also written:Code_Flows/inventory.json— the function catalog — written by whole-codebase mode only; andCode_Flows/quality-report.json/Code_Flows/quality-report.md/Code_Flows/quality-report.html— written by/code-flow.quality, see Quality reporting below.) - Report the paths to the generated files.
If you invoke the skill with no argument, the assistant will survey the project and suggest 3–5 candidate flows to pick from.
Alongside the markdown, the assistant produces a single self-contained HTML file you can explore in a browser — no server, no build step, no internet required. Just double-click it. It renders the flow as a browsable graph where you can:
- Pan/zoom the layered call graph and Fit it to view.
- Click any function node to open a side panel with its description,
file:line, a code snippet, an "Open in VS Code" link, and clickable Called by / Calls lists to walk the flow. - Search/filter functions by name, file, or description.
- Highlight a path — selecting a node lights up its full ancestor and descendant chain, answering "how did execution get here?" and "what happens next?".
- Toggle light/dark theme (persisted).
Node colors distinguish entry points, ordinary steps, external (third-party) boundaries, and io (DB/network/file) side effects. Edges distinguish plain calls, async calls (dashed), conditional branches (labeled), and back/cycle edges.
How it works: the installer drops a viewer scaffold at .code-flow/viewer.template.html. When you run the command, the assistant only has to emit a small JSON data block and inject it into that scaffold — so the interactive page is produced reliably, and the page self-validates (showing a clear error card, never a blank screen, if the data is malformed). If the scaffold is missing, the assistant falls back to a minimal Mermaid-based page.
After installing (see below), invoke from inside your project:
Claude Code
/code-flow.map user login
Gemini CLI
/code-flow.map password reset
GitHub Copilot
The installer writes an invocable prompt file to .github/prompts/code-flow.map.prompt.md.
Prompt files — .github/prompts/*.prompt.md with mode: agent frontmatter, which is what this one is — are a VS Code Copilot Chat feature. In VS Code, open Copilot Chat and select the prompt from the Prompts picker, or try:
/code-flow.map user login
Two things this project has not verified and therefore does not claim: that Copilot Chat exposes a dotted filename as a /-command (the code-flow.map name follows the GitHub Spec Kit prompt-file naming convention rather than any confirmed Copilot behavior), and whether Copilot surfaces other than VS Code read prompt files at all. If the slash form doesn't appear, use the Prompts picker.
If you don't use Copilot in VS Code, assume the prompt file does nothing for you. Instead, paste the body of templates/copilot/code-flow.map.prompt.md — everything below the --- frontmatter — into .github/copilot-instructions.md under a ## Code Flow heading; that file is read across Copilot surfaces. Upgrading from 0.x, you already have such a section: keep it instead of deleting it.
In all three, the assistant writes its output to Code_Flows/<feature_name>.md, Code_Flows/<feature_name>.html, and Code_Flows/<feature_name>.json at the project root, and creates or updates the shared Code_Flows/index.json registry.
Instead of one feature, map the entire repository:
/code-flow.map --whole-code-base
This runs two passes. The first walks the repository and catalogues every function
it finds into Code_Flows/inventory.json, recording a file census — size and
content hash — in Code_Flows/index.json. The second discovers entry points (HTTP
routes, CLI commands, main(), event handlers, scheduled jobs, exported API) and
traces each one into its own markdown, HTML and JSON, registering it in the index.
The second pass is the expensive one, and on a large repository it may not finish in
a single session. That is expected and not an error: re-run the command and it skips
the flows already registered in index.json and continues. coverage in that file
always records what was actually done — if flowsTraced is below
entryPointsFound, the map is partial and says so.
Whole-codebase mode never edits your source. Feature mode adds docstrings to undocumented functions as it traces; at repository scale that would be a sweeping unrequested rewrite, so this mode only reads.
Control how much evidence the catalog carries with --detail:
| Level | Each catalogued function carries | Use when |
|---|---|---|
thin |
signature, purpose, line count — no code snippet | Very large repositories |
standard (default) |
the above plus a snippet capped at ~20 lines | The balanced default |
verbose |
the above plus the full function body | Small repositories, or when you want artifacts that stand alone without the source tree |
/code-flow.map --whole-code-base --detail verbose
Discovery is search and reading, not a compiler's view of your code. The artifacts say "catalogued", never "all", and they mean it.
Once a whole-codebase map exists, analyze it:
/code-flow.quality
/code-flow.quality --read-code
This reads Code_Flows/index.json, inventory.json and every <flow>.json, then
writes Code_Flows/quality-report.json, Code_Flows/quality-report.md and
Code_Flows/quality-report.html. The JSON is the data; the other two are
renderings of it, and none of the three may contradict another. The .html is a
single self-contained page — no server, no build step, no internet required —
that you open straight from disk, with the same coverage banner, the same
"catalogued, never all" wording, and filters by severity and principle. Four
detectors run:
| Detector | Principle | Reports |
|---|---|---|
| duplicate-intent | DRY | The same work implemented in several places |
| repeated-sequence | DRY | Call chains repeated across flows |
| complexity-hotspot | KISS | High fan-out, deep nesting, very long functions |
| unreached | YAGNI | Catalogued functions no mapped flow reaches |
Severity is rule-based — thresholds, not impressions — so findings do not all drift toward "medium".
--read-code opens the files the candidate findings cite and confirms each
against current source, marking the survivors verified and dropping the rest;
without the flag every finding stays unverified. A candidate whose cited file
cannot be reopened at all — deleted, or unreadable — is neither: it stays
unverified and is then dropped as stale, which is why the dropped count is
usually, not always, zero under --read-code. It verifies candidates rather than
re-scanning the repository, so it costs far less than mapping. It requires the
source tree to be present and current, not just the artifacts.
The report never edits your code and never instructs deletion. Unreached findings are candidates: tracing here is search and reading, so it cannot see reflection, dependency injection, framework hooks or entry points declared in configuration. Anything exported is capped at low severity.
Coverage leads every report. If the trace pass mapped 14 of 17 entry points, the banner says so, and a clean section means clean within what was mapped — not a clean bill of health.
Three things stop the command rather than degrading it: no index.json (run
/code-flow.map first), no inventory.json (run /code-flow.map --whole-code-base first), and an index.json or inventory.json that does not
parse. A single unreadable <flow>.json does not stop it — that flow is skipped
and counted in the banner.
On a --detail thin map, duplicate-intent is skipped unless you pass
--read-code: a thin map carries no code snippets, so that detector has no
evidence to cite.
Back to /code-flow.map: Code_Flows/user_login.md will look roughly like:
# User Login — Flow
Brief description of what the flow does and when it runs.
## Diagram
```mermaid
flowchart TD
A[handle_login] --> B[validate_credentials]
B --> C[create_session]
C --> D[issue_token]
```
## Functions
- `handle_login`
- `validate_credentials`
- `create_session`
- `issue_token`
## Reference
| Function | Description | File |
|----------|-------------|------|
| `handle_login` | HTTP handler for POST /login | `src/auth/login.py:42` |
| `validate_credentials` | Verifies email + password against the user store | `src/auth/credentials.py:18` |
| ...A sibling Code_Flows/user_login.html is written at the same time — the interactive version of the same flow, ready to open in any browser. A Code_Flows/user_login.json sidecar (the same flow data as plain JSON) is written alongside it, and Code_Flows/index.json is created or updated to register the flow.
npm i @htst/code-flow-skillThe postinstall script copies the Claude, Gemini, and Copilot templates into your project.
Skip the auto-install with either:
npm i @htst/code-flow-skill --code_flow_skip_install=true
# or
CODE_FLOW_SKIP_INSTALL=1 npm i @htst/code-flow-skillnpm i -g @htst/code-flow-skill
code-flow-skill --tool all --target .uvx htst-code-flow-skill --tool all --target .If neither npm nor uvx is available, you only need to copy two or three small text files into your project. There is no code to build and no runtime dependency.
1. Get the templates. Pick whichever is easiest:
-
Download a release (recommended). Grab
code-flow-templates-*.zipfrom the latest release — it contains only thetemplates/directory, nothing else. Unzip it anywhere. -
Clone or download the repo:
git clone https://github.com/plearaj/code-flow-skill.git # or: download https://github.com/plearaj/code-flow-skill/archive/refs/heads/master.zip and unzip
You only need the templates/ directory. The rest of the repo (packaging, installer script, src/) can be ignored.
2. Copy the template(s) for the tool(s) you use into your target project.
From the project root where you want the skill available:
# Claude Code
mkdir -p .claude/commands
cp /path/to/code-flow-skill/templates/claude/code-flow.map.md .claude/commands/code-flow.map.md
cp /path/to/code-flow-skill/templates/claude/code-flow.quality.md .claude/commands/code-flow.quality.md
# Gemini CLI
mkdir -p .gemini/commands
cp /path/to/code-flow-skill/templates/gemini/code-flow.map.toml .gemini/commands/code-flow.map.toml
cp /path/to/code-flow-skill/templates/gemini/code-flow.quality.toml .gemini/commands/code-flow.quality.toml
# GitHub Copilot
mkdir -p .github/prompts
cp /path/to/code-flow-skill/templates/copilot/code-flow.map.prompt.md .github/prompts/code-flow.map.prompt.md
cp /path/to/code-flow-skill/templates/copilot/code-flow.quality.prompt.md .github/prompts/code-flow.quality.prompt.md
# Interactive HTML viewer + quality report scaffolds (needed for all tools)
mkdir -p .code-flow
cp /path/to/code-flow-skill/templates/shared/viewer.template.html .code-flow/viewer.template.html
cp /path/to/code-flow-skill/templates/shared/report.template.html .code-flow/report.template.htmlOn Windows PowerShell, substitute New-Item -ItemType Directory -Force for mkdir -p and Copy-Item for cp.
If you skip the .code-flow/viewer.template.html step, the command still works — the assistant just falls back to a minimal Mermaid-based HTML page instead of the full interactive viewer. If you skip the .code-flow/report.template.html step, /code-flow.quality still works too, but there is no fallback page for it: the command says so and still writes quality-report.json and quality-report.md.
3. Verify. Restart your assistant (or start a new session). In Claude Code or Gemini CLI, typing / should list both new commands — /code-flow.map and /code-flow.quality. For Copilot in VS Code, look for both prompts in the Prompts picker (or try /code-flow.map in chat); on other Copilot surfaces, see the GitHub Copilot notes under Usage.
That's it — no install step runs any code on your machine. If you later want to update the skill, just re-copy the template files.
code-flow-skill [--target PATH] [--tool claude|gemini|copilot|all]
Defaults: --tool all, --target ..
| Tool | Command | Path |
|---|---|---|
| Claude Code | /code-flow.map |
.claude/commands/code-flow.map.md |
| Claude Code | /code-flow.quality |
.claude/commands/code-flow.quality.md |
| Gemini CLI | /code-flow.map |
.gemini/commands/code-flow.map.toml |
| Gemini CLI | /code-flow.quality |
.gemini/commands/code-flow.quality.toml |
| GitHub Copilot | /code-flow.map |
.github/prompts/code-flow.map.prompt.md |
| GitHub Copilot | /code-flow.quality |
.github/prompts/code-flow.quality.prompt.md |
| All tools | — | .code-flow/viewer.template.html (interactive HTML scaffold) |
| All tools | — | .code-flow/report.template.html (quality report viewer scaffold) |
The .code-flow/viewer.template.html and .code-flow/report.template.html scaffolds are tool-agnostic and are installed regardless of which --tool you select, since every command template references one of them.
- npm:
@htst/code-flow-skill - PyPI / uvx:
htst-code-flow-skill
No test in this repository executes either scaffold's rendering — templates/shared/viewer.template.html
and templates/shared/report.template.html are checked for what their prompt-filled content
says, never for how a browser draws it. That gap is accepted (see
docs/superpowers/specs/2026-08-07-phase3b-report-viewer-design.md, Decision 1), on the
condition that a human closes it by hand before every release:
- Run
/code-flow.mapand/code-flow.qualityagainst any project and open the resultingCode_Flows/<flow>.htmlandCode_Flows/quality-report.htmlin a browser. Confirm each renders its diagram or findings instead of a blank page or a raw JSON dump. - Corrupt one of the two files' embedded JSON (edit a character inside the
<script type="application/json">block so it no longer parses) and reload it. Confirm the page shows the red error card instead of a blank page or a silent failure.
Do this for both files, every release — a change to either scaffold's rendering re-opens the gap and the test suite will not tell you.
Add the release's entry to CHANGELOG.md before bumping the version.
tests/test_packaging.py fails if the changelog's leading ## [version] heading does not
match the version both packages declare, so a forgotten entry is caught rather than shipped.
npm publish enforces this. scripts/prepublish-check.js runs as prepublishOnly, prints
the checklist and fails the publish until you acknowledge it. To read the checklist
without publishing anything:
npm run release-checkCODE_FLOW_RELEASE_CHECKED=1 npm publish --access publicuv publish has no equivalent hook, so the same checklist is on you here — run
npm run release-check first and work through it by hand.
uv build
uv publishLicensed under the Apache License, Version 2.0.
Commercial use is welcome. If you use, redistribute, or fork this project, you must:
- Keep the
LICENSEandNOTICEfiles intact. - Preserve the copyright and attribution notices (credit to Hightower Software Technologies) in any derivative work.
- State any significant changes you made to the files.
See the NOTICE file for the required attribution text.