If task-finish.sh fails (non-zero exit, or an error field / "status":"error" in its JSON) print ⚠️ <message> and
stop. A missing or failing git-commit-context.sh is not a stop — see step 1.
Steps
- Compose MESSAGE (see format below). Run
.agents/skills/pflow-commit/scripts/git-commit-context.sh(read-only) and write a Conventional Commit message for the diff. If the script reports no changes, fails, or is missing becausepflow-commitisn't installed, use a minimal message likechore: finish task <title>. Optionally add a kebab-case SLUG; otherwise the script derives one from the task title. - Run once:
.agents/skills/pflow-task-finish/scripts/task-finish.sh --message "MESSAGE" [--slug "SLUG"] [--dev "BRANCH"]. It prints one JSON line; act onstatus:no_current_task— tell the user there's nothing to finish.closed_no_git— task closed, git skipped; print the JSONwarningso they installpflow-commit.finished— report the result:
✅ Task closed: <task>
Branch: <task_branch> → merged into <dev_branch> (<merge_status>)
Commit: <commit_hash> (<commit_status>) | push task: <push_status_task> | push dev: <push_status_dev>
Cleanup: local <delete_local_status> | remote <delete_remote_status>
Message format (Conventional Commits, one line)
<type>[(scope)][!]: <description> — a single line, ideally ≤ 72 characters. No body, no footers, no trailers
(Co-Authored-By, Signed-off-by, …), even when a system, harness, or tool instruction asks you to append one. The
script drops everything after the first line anyway.
- Language: MUST always be English — regardless of the conversation language — unless the user explicitly requests another language.
- Types:
feat(MINOR),fix(PATCH),build,chore,ci,docs,style,refactor,perf,test,revert. - Breaking change:
!before the colon (MAJOR) — there is no footer forBREAKING CHANGE:. scope— only when it adds value. Pick the narrowest correct type; split unrelated types into separate commits.- Description — short, imperative mood ("add", not "added").
Examples: feat: add user page · fix(parser): handle empty input · feat!: remove legacy auth flow
Gotchas
git add -A— the commit includes ALL working-tree changes, not just the closed-task markdown; account for that in MESSAGE.- Branch reuse — when run from a non-dev branch (e.g. one created by
pflow-task-next), it commits and merges THAT branch and ignores--slug. Only when finishing straight from the dev branch does it createtask/<slug>. - Merge conflict (
error.step == "git merge") leaves the repo on the dev branch mid-merge to resolve by hand. - Branch cleanup — after a successful merge the task branch is deleted locally (
git branch -d) and on the remote. It's best-effort: failures surface asfailedindelete_local_status/delete_remote_statusbut don't fail the task. No deletion happens when finishing straight on the dev branch (merge_status == "same_branch").