Skip to content

fix(track-changes): register every revision kind inside headers/footers - #48

Open
kklimuk wants to merge 1 commit into
mainfrom
claude/triage-issue-37-header-revisions
Open

kklimuk wants to merge 1 commit into
mainfrom
claude/triage-issue-37-header-revisions

Conversation

@kklimuk

@kklimuk kklimuk commented Nov 6, 2026

Copy link
Copy Markdown
Owner

🤖 docx-cli triage

What was wrong

Header/footer parts registered only run-level ins/del/moveFrom/moveTo. A paragraph-mark revision, a pPrChange, or a table row/cell/property revision in a header didn't appear in track-changes list, so accept --all did nothing and exited 0 while the change stayed pending. This is the "Tracked changes" bullet of #37. On main, for a header with a centered-alignment pPrChange plus a deleted paragraph mark:

$ docx track-changes list doc.docx
no tracked changes
$ docx track-changes accept doc.docx --all
track-changes.accept 0 changes        # exit 0, both revisions still in header1.xml

What changed

  • core/ast/read.ts: the marginal walk now registers pPrChange, paragraph marks, and every table kind (tblPrChange, tblGridChange, rowIns/rowDel, cellIns/cellDel, tcPrChange), in the same order the body uses. It reuses the body's table-revision helpers, which now take a RevisionScope, so all ids are still minted in registerTrackedChange. Text-box stories are walked as block containers too.
  • A header paragraph isn't in Body.blockReferences, so its paragraph-mark reference now stores the owning paragraph/paragraphParent itself (TrackedChangeReference). core/track-changes/apply.ts uses those fields when present.
  • Apply now runs the table-grid resync and the empty-hyperlink prune over the header/footer trees as well as the body.
  • Rejecting the inserted mark of a story's only paragraph now strips the marker and keeps the paragraph. Before, it left an empty <w:hdr/> or <w:tc>.
  • Docs: REFERENCE.md, src/cli/track-changes/CLAUDE.md, and the list --help text.

Verification

  • Same file on this branch: list shows tc0 format hdr0 alignment ·→center and tc1 delete hdr0 ¶ paragraph mark. The read hint shows pending="tc0 tc1" and pending=2 (hdr0: 2). accept --all applies 2 changes, and headers list then shows "AcmeLetterhead" (the two lines merged).
  • 7 new tests in tests/cli/headers-footers.test.ts:
    • paragraph-mark del (accept merges the lines)
    • paragraph-mark ins (reject removes the line)
    • an inserted mark on a header's only paragraph
    • pPrChange with prior/current values, reject restores
    • a paragraph mark inside a text box (listed once, both branches)
    • every table kind, listed in body order, through a mixed apply, with the grid resync and validate passing
  • bun run check ✅ bun run test:unit ✅ (2097 tests)
  • /simplify (single pass; the Agent tool wasn't available): changed the header table walk to reuse the body's table-revision helpers instead of copying them.
  • /code-review xhigh: the forked run reviewed the wrong checkout and found nothing in this diff. I reviewed the diff by hand instead; that found the empty-story-on-reject problem fixed above.
  • No fixture added: no new verb or flag, only reader registration for Word-authored markup that no CLI verb produces. Not run through LibreOffice or Word.

Decisions for you

  • This is the first slice of feat(headers): treat headers and footers as rich-text block containers, not plain text #37 only. It does not make header parts into block containers, add hdr0:pN locators, render header blocks as Markdown, or let edit/insert/find work inside headers. Those parts need the product calls the issue lists as open: whether find/replace --all include headers by default, how wc counts them, and whether comments and footnotes are allowed in headers.
  • rPrChange is still not registered in headers, the same as in the body (it isn't modeled anywhere yet).

Refs #37 (first slice: track-changes completeness — does not close the issue)


Generated by Claude Code

Header/footer parts registered only run-level ins/del/moveFrom/moveTo, so a
paragraph mark, a pPrChange, or a row/cell/table-property revision in a header
was invisible to `track-changes list`, and `accept --all` reported "no tracked
changes" while leaving the markup pending. The marginal walk now registers
pPrChange, paragraph marks (with their owning paragraph on the reference, since
a header paragraph isn't in Body.blockReferences), and the table kinds through
the body's own table helpers, in the body's order; text-box stories walk as
block containers. Apply resyncs grids and prunes empty hyperlinks in marginal
trees too, and rejecting the inserted mark of a story's only paragraph keeps
the paragraph so the part stays valid.

First slice of #37 (track-changes completeness).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LkctENj7B2nTmUttTgfBhs
Triage-Routine: true
@kklimuk

kklimuk commented Nov 6, 2026

Copy link
Copy Markdown
Owner Author

🤖 docx-cli triage

This PR is the first slice of #37: track-changes completeness inside headers and footers. Every revision kind the body registers now lists in headers too, and accept/reject work on them. #37 stays open for the block-container, locator and Markdown-read work, which needs the product decisions listed in the PR description.

Action needed: approve/merge — review PR #48 and merge it if the slice looks right; then decide the open questions in #37 (find/replace default scope, wc scope, comments/footnotes in headers) before the block-container work starts.


Generated by Claude Code

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants