$npx -y skills add deepklarity/harness-kit --skill hk-changelogGenerate changelog entries from git diffs, prepend to CHANGELOG.md, and optionally commit + PR. Use when the user wants to update the changelog.
| 1 | # Changelog Creator |
| 2 | |
| 3 | Generate a changelog entry from git changes, prepend it to `CHANGELOG.md`, and optionally commit + raise a PR. |
| 4 | |
| 5 | ## Usage |
| 6 | |
| 7 | ``` |
| 8 | /hk-changelog → full flow: write + commit + PR |
| 9 | /hk-changelog --dry-run → print the entry only (no file changes) |
| 10 | /hk-changelog --commit → write + commit (no PR) |
| 11 | ``` |
| 12 | |
| 13 | Arguments are passed via `$ARGUMENTS`. |
| 14 | |
| 15 | ## Instructions |
| 16 | |
| 17 | ### Step 1: Parse arguments |
| 18 | |
| 19 | Check `$ARGUMENTS` for `--dry-run` or `--commit`. Default behavior (no args) is the full flow: write, commit, and open a PR. |
| 20 | |
| 21 | ### Step 2: Gather raw git data |
| 22 | |
| 23 | Run these commands to collect the raw material. This is mechanical — just capture the output: |
| 24 | |
| 25 | ```bash |
| 26 | # What branch are we on? |
| 27 | git rev-parse --abbrev-ref HEAD |
| 28 | |
| 29 | # Commits on this branch that aren't on main |
| 30 | git log main..HEAD --oneline --no-merges 2>/dev/null |
| 31 | |
| 32 | # File-level summary |
| 33 | git diff --stat main...HEAD 2>/dev/null |
| 34 | git diff main...HEAD --name-status 2>/dev/null |
| 35 | |
| 36 | # Unstaged/untracked |
| 37 | git diff --stat HEAD |
| 38 | git diff --name-status HEAD |
| 39 | git status --short | grep "^??" |
| 40 | ``` |
| 41 | |
| 42 | If there are no commits diverging from main AND no staged/unstaged changes, tell the user there's nothing to changelog and stop. |
| 43 | |
| 44 | If on `main` with no diverging commits, fall back to diffing against the previous commit: |
| 45 | ```bash |
| 46 | git log -1 --oneline |
| 47 | git diff HEAD~1 --stat |
| 48 | git diff HEAD~1 --name-status |
| 49 | ``` |
| 50 | |
| 51 | Also read the existing `CHANGELOG.md` so the subagent can match the format. |
| 52 | |
| 53 | ### Step 3: Delegate to haiku subagent |
| 54 | |
| 55 | **Use the Task tool** with `subagent_type: "general-purpose"` and `model: "haiku"` to do the heavy lifting. The subagent reads diffs, understands the changes, and generates the changelog entry. |
| 56 | |
| 57 | Pass the subagent a prompt containing: |
| 58 | 1. All the git output from Step 2 |
| 59 | 2. The existing `CHANGELOG.md` content (for format reference) |
| 60 | 3. The full generation rules below |
| 61 | 4. A clear instruction: "Read the actual diffs by subsystem, then generate a changelog entry. Return ONLY the markdown entry, nothing else." |
| 62 | |
| 63 | The subagent prompt must include these instructions: |
| 64 | |
| 65 | --- |
| 66 | |
| 67 | **Read actual diffs by subsystem.** File names alone are not enough — read the actual diffs to understand what changed. Group by subsystem: |
| 68 | |
| 69 | ```bash |
| 70 | # Backend / orchestrator / CLI |
| 71 | git diff HEAD -- odin/src/ taskit/taskit-backend/ |
| 72 | |
| 73 | # Frontend — read separately, easy to miss |
| 74 | git diff HEAD -- taskit/taskit-frontend/src/ |
| 75 | |
| 76 | # Types, models, migrations |
| 77 | git diff HEAD -- taskit/taskit-frontend/src/types/ taskit/taskit-backend/tasks/models.py taskit/taskit-backend/tasks/migrations/ |
| 78 | |
| 79 | # Docs and config |
| 80 | git diff HEAD -- odin/docs/ odin/AGENTS.md odin/claude.md odin/README.md docs/ |
| 81 | |
| 82 | # Tests |
| 83 | git diff HEAD -- odin/tests/ taskit/taskit-backend/tests/ |
| 84 | ``` |
| 85 | |
| 86 | For new untracked files, read them to understand what they add. If a diff group is very large (>500 lines), skim the first 300 lines and the `--stat` for that group. |
| 87 | |
| 88 | **Generate a changelog entry** in this format: |
| 89 | |
| 90 | ```markdown |
| 91 | ## YYYY-MM-DD — [Short Human-Friendly Title] |
| 92 | **`<short-hash>`** — [plain-English summary of the theme] |
| 93 | |
| 94 | ### Added |
| 95 | - [what's new, described in terms of capability] |
| 96 | |
| 97 | ### Changed |
| 98 | - [what works differently now — user/developer impact] |
| 99 | |
| 100 | ### Deleted |
| 101 | - [what's gone] |
| 102 | |
| 103 | --- |
| 104 | ``` |
| 105 | |
| 106 | **Rules:** |
| 107 | |
| 108 | - **Completeness over brevity.** Every meaningful change should appear. Someone reading the changelog should understand everything that shipped without looking at the diff. |
| 109 | - Use today's date and the latest commit's short hash (or "unstaged" for uncommitted work) |
| 110 | - Only include sections (Added/Changed/Deleted) that have entries — omit empty ones |
| 111 | - **Write for humans, not machines.** Say "Added executing time tracking to task cards" not "Added `executingTimeMs` field to `Task` type in `types/index.ts`" |
| 112 | - Describe *what changed and why it matters*, not which files were touched |
| 113 | - **Scale detail to changeset size:** |
| 114 | - Small changeset (1-5 files): 2-4 bullets |
| 115 | - Medium changeset (5-20 files): 5-10 bullets |
| 116 | - Large changeset (20+ files): 10-20 bullets, organized by area if helpful |
| 117 | - **Don't collapse distinct changes into one bullet.** If the frontend got a new component AND the backend got a new comment type AND the CLI got restructured, those are three bullets. |
| 118 | - **Frontend changes deserve their own bullets.** New components, UX changes (e.g. multi-select → single-select), new fields on forms, visual changes (badges, icons, colors) — each gets called out. |
| 119 | - **Backend and API changes deserve their own bullets.** New fields on models/types, new API parameters, changed parsing logic, new migrations. |
| 120 | - Include file paths only when the file IS the feature (e.g. a new config module, a new migration) |
| 121 | - Match the tone and format of the existing CHANGELOG.md entries provided |
| 122 | |
| 123 | Return ONLY the markdown entry (from `## |