How this skill is triggered — by the user, by Claude, or both
Slash command
/changedown:changedownThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Declare your identity using the `author` parameter on every `propose_change` and `review_changes` call.
Declare your identity using the author parameter on every propose_change and review_changes call.
Use propose_change for ALL edits to tracked files. Never use Edit/Write directly. If you do, hooks auto-wrap your edit in CriticMarkup — but with worse formatting and no annotations.
Read before you write. Call read_tracked_file first. It gives you the content, change status, and addressing information for precise targeting.
Use review_changes to approve, reject, or discuss. One call handles one or many reviews. Include a reason for every decision.
all) - Full annotations at point of contact. Default for most projects.simple) - Committed text with P/A flags in margin. Clean prose, change awareness.final) - Accept-all preview. Clean text for coherence checking.Default view is project-configured. Omit the view parameter to use the project default.
All views are writable projection surfaces. You can propose changes from any view using lines or coordinates from that view's output.1
Tool naming: This document uses short names (e.g.,
read_tracked_file). Your MCP client registers them with a prefix — look for tools ending in these suffixes in your available tool list.
| # | Tool | What it does |
|---|---|---|
| 1 | read_tracked_file | See what's there. Default: review view (three-zone format). |
| 2 | propose_change | Make changes. Your first read_tracked_file includes editing syntax for this project. |
| 3 | review_changes | Decide on changes. Accept/reject with reviews. Reply to threads with responses. |
| 4 | amend_change | Fix YOUR OWN proposals. Same-author enforcement. |
| 5 | list_changes | Change inventory with detail levels. detail=summary for overview, detail=context for surrounding lines, detail=full for threads and revision history. Use change_id or change_ids to fetch specific changes. Filter by status. Prefer using propose_change response data (contains change IDs, affected_lines, and per-change preview)2 over calling this — saves a round trip. |
| 6 | supersede_change | Replace someone else's proposal. Atomically rejects old + proposes new. |
Every line in the review view has three zones:
MARGIN | CONTENT | METADATA
P = pending proposal, A = accepted change.[sc-N] anchors link to Zone 3.{>>sc-N @author: reason | K replies<<} at end of line. WHO proposed and WHY.Example:
3:3f P| The service should use {~~REST~>GraphQL~~}[sc-4] for the external interface. {>>sc-4 @claude: paradigm shift | 2 replies<<}
4:b2 | Rate limiting should be set to 1000 requests per minute.
In review view, {--text--} means proposed for deletion — the text is still present in the committed document. The deleted text is still present in the committed content until the deletion is accepted. When targeting this text for further edits, account for the deletion markup in what you see.
propose_changereview_changes with reviews arrayreview_changes with responses arrayamend_change (same-author enforcement)supersede_change (rejects old, proposes new)list_changes with change_id + detail=fulllist_changes1. read_tracked_file(file) — get content + addressing
2. propose_change(file, ...) — make edits (use addressing from step 1)
3. Fire more propose_change calls — server auto-relocates shifted lines
4. review_changes(file, reviews=[...]) — approve/reject when done
Your first read_tracked_file call includes an editing guide tailored to this project — syntax, identity rules, and view semantics. That guide is your reference for how to structure propose_change calls.
Strict mode: In strict-mode projects, raw Read calls on tracked markdown files are blocked. Use read_tracked_file — it is the only path to tracked content.
Subagents: When spawning subagents (e.g., via Claude Code's Task tool), include include_guide: true in the subagent's first read_tracked_file call. All subagents share one MCP session, so only the first agent gets the guide automatically — subsequent agents must request it explicitly.3
Check rejection history before proposing. If you're modifying a section that others have reviewed, read it in review view first. Rejected proposals leave orphaned footnote refs ([^sc-N] with rejected status) visible in review mode — these tell you what was tried and why it was rejected, preventing wasted proposals. Read the rejection reason before proposing similar changes.
No re-reads needed between edits. Each propose_change response includes affected_lines (neighboring lines with content and addressing) and per-change preview in the applied array. Use those for your next edit.4 Re-read only after review (accept/reject) or when relocation is ambiguous.
UX: After applying changes, mention the modified file path in your reply so the user can click to open it.
Annotations: Skip for obvious edits (typos, formatting). Include when the "why" isn't clear from the "what."
When proposing changes to a file with existing proposals, batch all your changes in one propose_change call. The overlap guard will reject changes that conflict with existing proposals — use amend_change (for your own proposals) or supersede_change (for others' proposals) to modify existing work.
Review one or more changes in a single call:
review_changes(file, reviews=[
{change_id: "sc-1", decision: "approve", reason: "Correct fix for the timeout issue"},
{change_id: "sc-2", decision: "reject", reason: "This breaks backward compatibility"},
], author="ai:claude-opus-4.6")
Reasoning is required for every review decision.
Thread responses: To respond without approving/rejecting, use the responses array:
review_changes(file, responses=[
{change_id: "sc-1", response: "Good point, will revise", label: "thought"},
], author="ai:claude-opus-4.6")
Settlement: Handled by the server. When you approve a change, the project's config controls whether accepted markup is compacted immediately (common default). No separate settle step — approve is done.
Group cascade: Approving a group parent (e.g., sc-1) cascades to all children still at proposed status. Children with existing individual decisions (already accepted/rejected) are preserved.5
list_changes(file, change_id="sc-7", detail="full") — full thread + context for one change
list_changes(file, change_ids=["sc-5","sc-7"]) — batch lookup (defaults to detail=full)
list_changes(file, detail="context", context_lines=2) — all changes with surrounding lines
list_changes(file, status="proposed") — filter by status (summary detail)
Detail levels: summary (default for lists), context (adds markup + surrounding lines), full (adds footnote, discussion threads, participants, group info).
Revise your own proposal without losing the discussion thread:
amend_change(file, "sc-7", new_text="better text", reason="fixed the edge case", author="ai:claude-opus-4.6")
revised: + previous: entries to footnote history.read_tracked_file(file="path/to/file.md")
Views (canonical names):
review (aliases: all, meta) — full annotations at point of contact, deliberation summary header. Output includes P/A flags in the margin. CriticMarkup overlays show what's proposed. Best for evaluating and triaging proposals.changes (aliases: simple, committed) — committed text with P/A flags in the margin. No inline CriticMarkup. Clean prose with "fresh eyes." Best for copy-editing and independent judgment.settled (aliases: final) — document as if all proposals were accepted. Clean text. Best for coherence checks before approving.raw (aliases: content, full) — literal file bytes with all CriticMarkup markup and footnotes visible. Diagnostic/debugging only. Not a writable surface.P/A flags in the margin:
4:b2 | The API should use REST for the external interface.
5:6f P| Rate limiting should be set to 1000 requests per minute.
6:e1 A| Error responses include a human-readable message in the body.
P = pending proposal(s) on this lineA = accepted change(s) settled on this line (recent activity)Options: offset / limit for pagination (default: 500 lines, max: 2000), include_meta for change levels in header, include_guide: true to re-deliver the editing guide (for subagents sharing an MCP session).6
Always use read_tracked_file for tracked files, not the built-in read tool. read_tracked_file provides addressing, change awareness, and session binding. The built-in read returns raw bytes without any of these features.
Tracked files have <!-- changedown.com/v1: tracked --> at the top. The tooling manages this automatically.
propose_change (never Edit/Write)If propose_change fails with "file not tracked," the response includes diagnostic info.
| Situation | Action |
|---|---|
| propose_change fails with "file not tracked" | Check response diagnostic; file needs tracking header |
| File has accepted-but-unsettled markup | Re-read; compaction is automatic on approve. If markup persists, re-read the file — the settled view (read_tracked_file(file, view="settled")) confirms what the final text looks like |
| propose_change fails with unexpected content | Re-read with read_tracked_file for current content and fresh addressing |
| Batch fails with addressing mismatch | Re-read file for fresh addressing, then retry |
| Editing non-tracked files (.ts, .json) | Normal Edit/Write — hooks do not intercept |
You do not write CriticMarkup manually — the tools handle it. But you read and understand it when opening files with existing markup.
The API uses {~~REST~>GraphQL~~}[^sc-1] for the public interface.
We {--removed this--}[^sc-2] and {++added this++}[^sc-3] instead.
{==Rate limiting is set to 100 req/min==}{>>needs load testing<<}
| Type | Syntax |
|---|---|
| Substitution | {~~old~>new~~}[^sc-N] |
| Deletion | {--text--}[^sc-N] |
| Insertion | {++text++}[^sc-N] |
| Highlight | {==text==} |
| Comment | {>>text<<} |
Grouped changes use dotted IDs: [^sc-17.1], [^sc-17.2].
[^sc-1]: @ai:claude-opus-4.6 | 2026-02-10 | sub | proposed
context: "Authentication uses {API keys} for all endpoints"
@ai:claude-opus-4.6 2026-02-10T14:32:05Z: GraphQL gives clients query flexibility
approved: @carol 2026-02-11T09:15:22Z "Benchmarks look good"
Header: [^sc-N]: @author | date | type | status
proposed, accepted, rejectedins, del, sub, highlight, comment, groupTimestamps: System-generated events use full ISO 8601 UTC (2026-02-10T14:32:05Z). Human-written timestamps accept date-only (2026-02-10), informal time (2026-02-10 2:30pm), or full ISO. The system stores exactly what was written.
ChangeDown uses platform hooks to enforce tracking discipline:
Claude Code: PreToolUse blocks raw Edit/Write before execution (strict mode) or logs for batch-wrapping (safety-net mode).
Cursor: beforeReadFile blocks raw reads on tracked files (strict mode), beforeMCPExecution validates tool inputs, afterFileEdit + stop log and batch-wrap raw edits (safety-net mode).
Both platforms guarantee the same final state — tracked files end up with CriticMarkup. The difference is timing: Claude Code prevents; Cursor catches and wraps.
If a raw read is blocked: Use read_tracked_file instead. It provides deliberation context, addressing, and change metadata.
Safety-net wrapping produces worse formatting than propose_change — no annotations, no grouping, substitution markup instead of clean insertions/deletions. Always prefer propose_change.
When editing multiple tracked files, batch by phase — not by file:
1. read_tracked_file(file_A)
2. read_tracked_file(file_B)
3. propose_change(file_A, changes=[...]) — batch all edits per file
4. propose_change(file_B, changes=[...])
5. review_changes(file_A, reviews=[...]) — group-level: approve sc-1 to cascade
6. review_changes(file_B, reviews=[...])
Why: Reading all files first gives you the full picture before making changes. Proposing all before reviewing avoids interleaving that triggers unnecessary re-reads.
Group-level review is the key efficiency lever. When your batch creates sc-1.1 through sc-1.15, approve just sc-1 — it cascades to all children at proposed status.
When a user gives you a .docx or asks for one back, use the CLI to convert:
cdown import document.docx # → document-changedown.md (tracked)
cdown export document-changedown.md # → document-changedown.docx
cdown export document.md --mode clean # → clean DOCX, no tracked changes
Import converts Word tracked changes to CriticMarkup with footnotes (authors, dates, comments,
threads, images with positioning all preserved). The output is tracked — edit with
read_tracked_file and propose_change normally.
Export converts back to Word-native tracked changes. Modes: tracked (default — proposals
stay as revisions), settled (decided changes applied), clean (no revisions).
What round-trips: insertions, deletions, substitutions, author attribution, dates, comment threads, images (including floating/anchored positioning), formatting (bold, italic).
@ai:claude-opus-4.6 | 2026-02-25 | sub | accepted @ai:claude-opus-4.6 2026-02-25: consolidate view descriptions, add raw, remove token count details approved: @ai:claude-opus-4.6 2026-02-25 "Cleaner view descriptions with raw view added" ↩
@ai:claude-opus-4.6 | 2026-02-27 | sub | accepted approved: @ai:claude-opus-4.6 2026-02-27 "Update SKILL.md to reference affected_lines and per-change preview instead of deprecated updated_lines" (cascaded from sc-21) ↩
@ai:claude-opus-4.6 | 2026-02-26 | sub | accepted @ai:claude-opus-4.6 2026-02-26: document include_guide parameter for multi-agent sessions approved: @ai:claude-opus-4.6 2026-02-26 "Documents include_guide for subagent guide re-delivery" ↩
@ai:claude-opus-4.6 | 2026-02-27 | sub | accepted approved: @ai:claude-opus-4.6 2026-02-27 "Update SKILL.md to reference affected_lines and per-change preview instead of deprecated updated_lines" (cascaded from sc-21) ↩
@ai:claude-opus-4.6 | 2026-02-25 | ins | accepted @ai:claude-opus-4.6 2026-02-25: document new group cascade behavior approved: @ai:claude-opus-4.6 2026-02-25 "Documents new group cascade behavior" ↩
@ai:claude-opus-4.6 | 2026-02-26 | sub | accepted @ai:claude-opus-4.6 2026-02-26: add include_guide to options list approved: @ai:claude-opus-4.6 2026-02-26 "Adds include_guide to options list" ↩
npx claudepluginhub hackerbara/changedown --plugin changedownManages structured change proposals for design documents with PR-like reviews. Use /intent-changes start <file> to begin sessions, propose/add/modify/delete changes, accept/reject, and finalize applications to source files.
Saves, lists, views, restores, and deletes versioned markdown essay drafts in a checkpoints folder with incremental numbering. Useful for managing revision history and reverting changes.
Review diffs and files with inline annotations in a terminal TUI overlay. Works with git, hg, and jj repos. Also answers usage and configuration questions.