"Review the full diff, approve or deny, then git add + commit + push. Use at every commit checkpoint in the FLOW workflow."
Install
npx skillscat add benkruger/flow/flow-commit Install via the SkillsCat registry.
Commit
Review all pending changes as a diff before committing. You must get explicit approval before touching git.
Mode Detection
Determine the operating mode before proceeding:
- Run both commands in parallel (two Bash calls in one response):
git worktree list --porcelain— note the path on the firstworktreeline (this is the project root).git branch --show-current— this is the current branch.
- Read
<project_root>/.flow-states/<branch>.jsonwith the Read tool.- File exists (content returned) → FLOW mode
- File does not exist (error returned) → use Glob to check for
flow-phases.jsonin the project root.- Exists → Maintainer mode (this is the plugin source repo)
- Does not exist → Standalone mode
Keep the project root, branch, and detected mode in context for the rest of this skill.
Announce
At the very start, output the following banner in your response (not via Bash) inside a fenced code block:
FLOW mode:
```
============================================
FLOW v0.19.0 — flow:flow-commit — STARTING
============================================
```Maintainer and Standalone mode:
```
============================================
Commit — STARTING
============================================
```On completion (whether approved or denied), print the same way:
FLOW mode:
```
============================================
FLOW v0.19.0 — flow:flow-commit — COMPLETE
============================================
```Maintainer and Standalone mode:
```
============================================
Commit — COMPLETE
============================================
```Usage
/flow:flow-commit
/flow:flow-commit --auto
/flow:flow-commit --manual/flow:flow-commit— defaults to auto (no approval prompt)/flow:flow-commit --auto— skips the approval prompt/flow:flow-commit --manual— requires explicit approval
Mode Resolution
- If
--autowas passed → mode is auto - If
--manualwas passed → mode is manual - Otherwise → mode is auto
--auto is user-invoked only. Claude must never call /flow:flow-commit --auto programmatically — except in /flow:flow-learning, which is fully autonomous and commits without mid-process approval.
Process
Step 0 — Run tests
FLOW and Maintainer mode only. Skip for Standalone.
Run bin/flow ci --if-dirty. This skips the run if no files changed since the
last green run. If any test fails, stop and report the failure.
Do not proceed to diff review until tests pass.
Step 1 — Show the diff
First run git status to see what changed. If nothing to commit, tell the user and stop.
Then stage everything and diff the staged changes:
git add -Agit diff --cachedThis ensures new (untracked) files appear in the diff output — git diff HEAD
misses untracked files entirely. Staging first gives one unified diff with
consistent formatting for all changes.
Render the output directly in your response — do not ask the user to expand tool output.
If the diff is too large to render inline (the Bash tool truncates and
persists the output), use git diff --cached --stat for the summary
and read the persisted output file with the Read tool. Never redirect
output to /tmp/ — shell redirects trigger permission prompts.
Format the status as:
**Status**
modified: path/to/file.rb
new file: path/to/other.rb
deleted: path/to/removed.rbFormat the diff as a fenced diff code block:
```diff
- removed line
+ added line
```The diff code block renders red/green in most markdown environments.
Docs sync check
FLOW and Maintainer mode only. Skip for Standalone.
If the diff includes changes to any of these files:
skills/*/SKILL.md— checkdocs/skills/anddocs/phases/for matching updatesflow-phases.json— checkdocs/phases/,docs/skills/index.md,README.md,docs/index.htmldocs/reference/flow-state-schema.md— check againstconftest.make_state()fields
Flag any docs that may need updates before writing the commit message. If docs are already current, proceed.
Step 2 — Commit Message
Write a commit message that a developer reading git log six months from now would find genuinely useful.
Structure:
Short subject line (imperative verb, under 72 characters)
tl;dr
One or two sentences explaining the WHY — what problem this solves,
what behaviour changes, or what was wrong before.
- path/to/file.rb: What changed and why
- path/to/other.rb: What changed and why
- path/to/another.rb: What changed and whyBefore displaying your draft, verify it contains all of these in order:
- Subject line — imperative verb, ≤72 chars, no period
- Blank line
- The literal word
tl;dron its own line — no colon, no elaboration, justtl;dr - Blank line
- Explanation paragraph — the WHY, not the what
- Blank line
- File list — one bullet per changed file with reason
If any element is missing or out of order, rewrite before displaying.
Subject line rules:
- Start with an imperative verb: Add, Fix, Update, Remove, Refactor, Extract
- Describe the goal, not the mechanism — when a change has both, the subject says why it matters. "Consolidate 7 permission entries into 1" (goal) not "Move scripts from hooks/ to lib/" (mechanism)
- No prefix jargon (no
feat:,chore:,fix:— just the verb) - Under 72 characters
- No period at the end
Body rules:
- Blank line between subject and body
- Explain the motivation — what prompted this change?
- List each meaningful change with its file and a plain-English reason
- Call out explicitly if the diff includes migrations, schema changes, or Gemfile changes
- Do not pad with obvious restatements of the diff
Display the full message under the heading Commit Message before asking for approval.
Step 3 — Ask for approval
Unless --manual was explicitly passed, skip this step entirely — the default is auto.
If --manual was explicitly passed, use the AskUserQuestion tool with exactly these two options:
Question: "Approve this commit?"
- Option 1: Approve — "Looks good, commit and push"
- Option 2: Deny — "Something needs to be fixed first"
Step 4 — Commit and push (on approval)
Files are already staged from Step 1. No need to git add -A again.
Use the Write tool to write the commit message to
.flow-commit-msgin the project root.- Each worktree has its own project root, so concurrent sessions don't collide
- The file is inside the project, so the Write tool has permission without prompting
- The Write tool handles newlines and special characters safely — no shell escaping needed
- Never write to
/tmp/— paths outside the project trigger permission prompts that settings.json cannot suppress - Never use
python3 -cto write the message — literal$(...)in the body triggers command substitution warnings - Never use
git commit -mwith heredoc — the multi-line command fails permission pattern matching
Commit from the temp file:
git commit -F .flow-commit-msgDelete the temp file:
rm .flow-commit-msgThe
rmprevents the Write tool from showing a confusing diff of old→new message on the next commit.git pull origin <current-branch>— pull before pushing to pick up any changes merged while you were workingIf the pull produced merge conflicts:
- Run
git statusto identify every conflicting file - Read each conflicting file carefully — understand both sides:
<<<<<<<(HEAD) = our changes>>>>>>>(incoming) = what was merged to main
- For each conflict, attempt to resolve it intelligently:
- If both sides add different things that don't logically conflict → keep both
- If one side removes something the other side modified → understand intent, apply the right resolution
- If the resolution is obvious from context → fix it silently,
git add <file>
- Only escalate to the user if a conflict requires a domain or business decision you cannot make — show exactly that conflict and ask specifically what to do
- Once all conflicts are resolved:
git add -A, then continue to push
- Run
If pull was clean:
git pushConfirm success and show the commit SHA.
Step 5 — Handle denial
Unstage everything first (files were staged in Step 1 for diff purposes):
git reset HEADgit reset HEAD only unstages — it moves files back from staged to unstaged.
No code is deleted, no changes are lost. It is the opposite of git add.
Then ask: What needs to be addressed before committing?
Listen to the reason, acknowledge it clearly, and stop. Do not commit. The user
will make fixes and re-invoke the commit skill when ready.
Hard Rules
- Never commit without showing the diff first
- The default commit mode is auto — never prompt for approval unless
--manualwas explicitly passed --autois user-invoked only. Claude must never call/flow:flow-commit --autoprogrammatically — except in/flow:flow-learning, which is fully autonomous and commits without mid-process approval.- Never use
--no-verify - Never add Co-Authored-By trailers or attribution lines — commits are authored by the user alone
- Always pull before pushing — other sessions may have merged changes
- Never rebase — ever. Always merge.
git rebaseis forbidden.
Additional Rules
- FLOW mode only: If
bin/flow cihas not been run since the last code change, warn the user before asking for approval