Install
Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.
npx agentmarket install skill/cormacc-docx
Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.
Get the weekly diff
The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.
About
Use cases: documents, writing, productivity
Reviews
Write a reviewNo reviews yet. Installed it? Reviews come from verified installers only. How reviews work
Permissions
What this skill can do and what it asks for, from its SKILL.md. Checked Oct 25, 2026.
- Tools
- No tools found
- Secrets
- None asked for
- Install scripts
- None found
- Runs as
- Python package
Network hosts it talks to 1
codeload.github.com· found in install command
Files it touches
~/.claude/skills/docx
What's inside
- Skill name
docx- Description
- Review and edit Word .docx files without Word. Report header, footer and version history text; list tracked changes paragraph by paragraph; list comments with the text they anchor; apply an edit script as tracked changes with reason comments; produce a clean copy (all changes accepted, comments removed) checked against pandoc; compare two versions into a tracked-changes .docx (redline) with LibreOffice; and edit cells, checkboxes and footnotes from Babashka through docx.core and docx.edit. Use whenever a task needs what changed in a Word document, a redline or comparison, tracked edits or review comments in a .docx, a clean copy for publication, the version history or header of a .docx, or a programmatic edit of a .docx form or template. For plain reading of a document's text, use convert-documents-to-markdown instead.
- License
- MIT
- Compatibility
- Needs Babashka. clean checks its result with pandoc when pandoc is installed. compare needs LibreOffice; on Nix it finds the Python that LibreOffice links against.
- Instructions
- 131 lines in SKILL.md · view on GitHub
Before installing
- Ships executable scripts
Agent Skills spec issues
- files: referenced but missing: references/graph-client.md
Files (8)
- SKILL.md
- docx.clj · scripts/
- lo_compare.py · scripts/
- clean.clj · scripts/src/docx/
- core.clj · scripts/src/docx/
- edit.clj · scripts/src/docx/
- review.clj · scripts/src/docx/
- test-docx.bb · scripts/
SKILL.md (first lines)
# docx
Review and edit Word `.docx` packages as WordprocessingML. A `.docx` is a zip of XML parts; `word/document.xml` holds the body, `word/headerN.xml` and `word/footerN.xml` the headers and footers, `word/comments.xml` the comments.
## Commands
`scripts/docx.clj` prints JSON on success and a message on stderr on failure.
| Command | Output |
|---|---|
| `docx.clj inspect DOCX` | `headers`, `footers` (one string per part, paragraphs joined by ` \| `), `tracked_changes` (part name to `{ins, del}` counts), `version_history` (rows of cell text) |
| `docx.clj changes DOCX` | One object per paragraph with tracked changes: `heading` (nearest heading above, by paragraph style), `before`, `after`; header and footer changes follow, with `part` |
| `docx.clj comments DOCX` | One object per comment: `id`, `author`, `date`, `text`, `heading`, and the anchored text `before` and `after` the tracked changes |
| `docx.clj edit IN SCRIPT OUT --author NAME [--initials XX] [--date ISO] [--no-tracking]` | Applies an edit script (below) as tracked changes; reports each edit |
| `docx.clj clean IN OUT [--keep-tracking] [--no-verify]` | Writes the clean copy: supported changes accepted, comments removed, tracking turned off; refuses deleted paragraph marks; reports the pandoc check |
| `docx.clj compare OLD NEW OUT` | Writes `OUT`, a `.docx` that shows OLD to NEW as tracked changes |
Exit codes: 0 success; 1 usage, input or unsupported-change error; 2 an edit did not match (nothing written); 3 the clean copy differs from pandoc's accept view.
- Text reads as if all tracked changes were accepted: inserted text is included, deleted text is not. `changes` and `comments` give both sides.
- `version_history` is the last table with a header row that has a cell exactly `Version` and a cell that names a DCR or a description. Blank rows are dropped. A placeholder such as `<DD-Mmm-YYYY>` in the last row shows a field that the author has not completed.
- A large revision gives hundreds of `changes` entries. Redirect the output to a file and read it in slices.
- `changes` and `comments` report the nearest paragraph with a heading style. Many documents number sections without heading styles; then render the document (LibreOffice to PDF, `pdftotext -layout`) and look up the changed text to find its section number.
## Edit scripts
A JSON (`.json`) or EDN (`.edn`) list of edits, applied in order:
```json
[
{"op": "replace", "old": "ISO/IEC 62304", "new": "IEC 62304:2006+A1:2015",
"comment": "Cite the current amended edition (clause 1)."},
{"op": "replace", "in": {"starts": "The software system"}, "old": "shall", "new": "should"},
{"op": "insert-after", "after": {"starts": "The SDP shall identify"}, "text": "New requirement text.",
"comment": "Reason: clause 5.2.4."},
{"op": "delete", "paragraph": {"equals": "Obsolete sentence."}},
{"op": "replace", "part": "headers", "all": true, "old": "11.0 (CR-123)", "new": "12.0 (CR-456)"},
{"op": "insert-row-after", "row": {"starts": "11.0 | 123"}, "cells": ["12.0", "456", "Summary of changes.", "<DD-Mmm-YYYY>"],
"comment": "Version history row for the change record."},
{"op": "delete-row", "row": {"contains": "Obsolete row"}}
]
```
- `replace` changes the only occurrence of `old` in one paragraph: by default the paragraph that contains `old`; with `in`, the paragraph that the selector picks.
- A selector is a string (the paragraph contains it) or `{"starts" | "contains" | "equals": text}`. It must pick exactly one paragraph. Text is matched in the accepted view (insertions in, deletions out). Automatic section numbers are not paragraph text: select by the paragraph's words.
- `insert-after` copies the anchor's paragraph properties (or `"style": "StyleId"`) and the run properties of its first text run.
- `insert-row-after` adds a table row with one value for each cell (a blank line in a value starts a new paragraph); it copies the anchor row's row, cell, paragraph and run properties, without vertical merges. `delete-row` removes a row. A row selector matches the row text: the cell texts joined by ` | `.
- `"part": "headers"` or `"footers"` edits the header or footer parts instead of the body (default `"body"`); selection runs over all of them. A document often has the same header in several parts (first page, default): `"all": true` applies the edit to every match, where otherwise exactly one must match.
- Word has no comments in headers or footers, so an edit there cannot carry a `comment`; neither can an edit with `all`, because one comment anchors one place. Give those reasons in the check-in comment or the change record.
- `comment` is the reason for review and for change records; a blank line in it starts a new comment paragraph.
- A match must lie in plain text runs. Text that crosses a field (a citation, a cross-reference), an existing tracked change or other non-text content is refused, so that other authors' changes are never split. Edit around it.
- The whole script runs in memory first. The first edit that does not match aborts with its index, and no output file is written.
- Changes carry `--author` and the run time (or `--date`). `edit` also turns on tracking in the document, so later edits in Word are tracked too.
## Editing a SharePoint document
Use the `ms365` skill's Graph client (`references/graph-client.md` there) for the SharePoint steps:
1. `graph.clj checkout URL`, then `graph.clj download URL in.docx`.
2. `docx.clj edit in.docx script.json out.docx --author "Name"`; check the report and `docx.clj changes out.docx`.
3. `graph.clj upload URL out.docx`. Repeat steps 1 to 3 (without a new check-out) as often as the session needs.
4. `graph.clj checkin URL --comment "..."`: one minor version for the session.
For one small change, `graph.clj transaction URL --comment "..." --exec '~/.agents/skills/docx/scripts/docx.clj edit {in} script.json {out} --author "Name"'` does all four steps and discards the check-out if any step fails. `--exec` runs in a shell from the current directory: give the script by its path.
Reviewers see the tracked changes and comments in desktop Word without a check-out; in a library that requires check-out, Word Online shows them only after a check-out.
## Clean copy
`docx.clj clean IN OUT` accepts insertions, run deletions, moves, property changes, and table-row and cell changes. It removes comment anchors, references and comment parts with their relationships and content types, and removes `trackRevisions` from the settings unless `--keep-tracking`.
A deleted paragraph mark in the body, a header, footer, footnote or endnote stops `clean` with exit 1 before it writes output. This includes marks inside table cells and marks made by the script's `delete` operation. `--no-verify` and `--keep-tracking` do not bypass this refusal. Use Word's **Accept All Changes**, save the copy, then run `clean` on that copy. Word's formatting rules for joined paragraphs are not reproduced by this tool.
The check compares the clean copy with pandoc's accept view of the input, paragraph by paragraph, after it removes list markers and whitespace. It checks text, not formatting. Before publication, open the clean copy in Word and check lists and paragraph formatting. If the command fails, do not upload its output or use `--no-verify` to bypass the publication check; investigate the difference first.
`docx.clj comments` before `clean` keeps the review record: the comments are gone after it.
## Editing from Babashka
Add the namespaces to the classpath, then edit the parsed tree and write the package back:
```clojure
(require '[babashka.classpath :as cp] '[babashka.fs :as fs])
(cp/add-classpath (str (fs/expand-home "~/.agents/skills/docx/scripts/src")))
(require '[docx.core :as d :refer [w]] '[clojure.data.xml :as xml])
(let [entries (d/read-entries "form.docx")
doc (d/parse-entry entries "word/document.xml")
body (first (d/children doc (w "body")))
body (d/update-table body "Section 1"
(fn [t] (d/update-row t "Requested by"
#(d/update-cell % 1 (fn [c] (d/set-cell-text c "A. Person"))))))
doc (assoc doc :content (mapv #(if (d/tag= (w "body") %) body %) (:content doc)))]
(d/write-docx "out.docx" (d/replace-entries entries {"word/document.xml" (xml/emit-str doc)})))
```
Main functions (each has a docstring):
| Namespace | Area | Functions |
|---|---|---|
| `docx.core` | Package | `read-entries`, `entry-str`, `parse-entry`, `part-names`, `replace-entries`, `write-docx` |
| `docx.core` | Tree | `w`, `w14`, `el?`, `tag=`, `children`, `descendants`, `text`, `xform`, `with-kids`, `paras`, `rows`, `cells` |
| `docx.core` | Text | `set-par-text`, `set-cell-text`, `label+value` (keep a label, replace its hint), `append-run`, `update-para` |
| `docx.core` | Tables | `heading`, `row-idx`, `update-row`, `update-cell`, `update-table` |
| `docx.core` | Checkboxes | `checkbox?`, `n-checkboxes`, `set-checkbox`, `tick` (with `:expect n`) |
| `docx.core` | Footnotes | `prune-footnotes` (after you remove footnote references) |
| `docx.edit` | Tracked editing | `tracked-replace`, `tracked-insert-after`, `tracked-delete`, `tracked-insert-row-after`, `tracked-delete-row`, `row-text`, `update-paragraphs`, `update-unique-paragraph`, `max-id`, `id-source`, `enable-tracking` |
| `docx.edit` | Comments, scripts | `ensure-comments-part`, `add-comment`, `selector`, `apply-script` |
| `docx.clean` | Clean copy | `clean-xml`, `clean-entries` |
| `docx.review` | Review | `inspect`, `changes`, `comments`, `compare-docx`, `lo-python` |
- Find tables, rows and paragraphs by their text, not by index, so that a changed template fails instead of writing to the wrong place. Lookup functions throw `ex-info` with `{:docx/error :layout}`; matching in `docx.edit` throws `{:docx/error :match}`.
## Gotchas
- Namespace prefixes: `mc:Ignorable` lists prefixes by name, so a writer that renames prefixes produces a file that Word rejects. `clojure.data.xml` (in Babashka) keeps the original prefixes; keep to it.
- `python-docx` `cell.text` and `paragraph.text` skip runs inside `w:ins`, so they lose inserted text in a document with tracked changes. `docx.core/text` reads every `w:t`.
- Word writes a UTF-8 byte-order mark in some parts. `entry-str` removes it; a direct `xml/parse-str` on the raw bytes fails with "Content is not allowed in prolog".
- Word rejects `settings.xml` children out of schema order; `enable-tracking` inserts `w:trackRevisions` in its place.From cormacc/dotagents, MIT.
More from cormacc/dotagents
- 0.592score
logic-pro
cormacc
Read Apple Logic Pro projects (.logicx bundles) without Logic -- survey the binary ProjectData file and extract MIDI regions to a Standard MIDI File for…
SkillAFreshness: A★ 1Claude Code +9 - 0.592score
herdr-orch
cormacc
Delegate work to Herdr subagents with the in-skill `oh` CLI: spawn, fan out, or run a persona such as…
SkillAFreshness: A★ 1Claude Code +9 - 0.592score
ms365
cormacc
Read Microsoft 365 data through the ms365 MCP server -- SharePoint and OneDrive documents, Outlook mail and calendar, Teams chats and channels, and the user…
SkillAFreshness: A★ 1Claude Code +9 - 0.589score
clojure
cormacc
Clojure, ClojureScript, EDN, and Babashka development with runtime validation.
SkillAFreshness: A★ 1Claude Code +9 - 0.588score
doc-writing
cormacc
Write, restructure and check documentation -- Markdown and Org documents (READMEs, design records, architecture and onboarding guides) and code comments and…
SkillAFreshness: A★ 1Claude Code +9 - 0.587score
git-commit
cormacc
Generate standardized git commit messages following conventional commits spec, and concise merge/pull request descriptions.
SkillAFreshness: A★ 1Claude Code +9 - 0.583score
code-review
cormacc
Review software changes for high-confidence correctness, security, regression, test, and maintainability problems in the changed code.
SkillAFreshness: A★ 1Claude Code +9 - 0.562score
find-skills
cormacc
Helps users discover and install agent skills when they ask questions like "how do I do X", "find a skill for X", "is there a skill that can...", or express…
SkillAFreshness: A★ 1Claude Code +9 - 0.552score
dataspex
cormacc
Inspect or debug live runtime state in a running ClojureScript app: read inspected refs (app-state atoms, taps), audit/change history, nexus/action dispatch…
SkillBFreshness: B★ 1Claude Code +9 - 0.552score
technical-prose
cormacc
Use when English text must be parsed without a human to resolve ambiguity -- tool descriptions, error messages, inter-agent instructions, system prompts…
SkillBFreshness: B★ 1Claude Code +9 - 0.549score
gitlab-cli-skills
cormacc
GitLab CLI (glab) command reference and workflows; routes to sub-skills for auth, CI, MRs, issues, releases, repos, and 30+ other glab commands.
SkillBFreshness: B★ 1Claude Code +9 - 0.547score
simple-prose
cormacc
Write or rewrite explanatory prose in plain, front-loaded English adapted from the GOV.UK style guide.
SkillBFreshness: B★ 1Claude Code +9
Signals
- Stars
- 1
- Forks
- 1
- Open issues
- 0
- Last commit (this folder)
- Oct 24, 2026 (4 days ago)
From GitHub (fetched Oct 24, 2026).
Details
- License
- MIT
- Repository
- github.com/cormacc/dotagents
- First seen
- Oct 24, 2026
- Last checked
- Oct 24, 2026
- Source
- GitHubgithub-graphql
More from cormacc
- 0.592score
ms365
cormacc
Read Microsoft 365 data through the ms365 MCP server -- SharePoint and OneDrive documents, Outlook mail and calendar, Teams chats and channels, and the user…
SkillAFreshness: A★ 1Claude Code +9 - 0.592score
logic-pro
cormacc
Read Apple Logic Pro projects (.logicx bundles) without Logic -- survey the binary ProjectData file and extract MIDI regions to a Standard MIDI File for…
SkillAFreshness: A★ 1Claude Code +9 - 0.592score
herdr-orch
cormacc
Delegate work to Herdr subagents with the in-skill `oh` CLI: spawn, fan out, or run a persona such as…
SkillAFreshness: A★ 1Claude Code +9 - 0.589score
clojure
cormacc
Clojure, ClojureScript, EDN, and Babashka development with runtime validation.
SkillAFreshness: A★ 1Claude Code +9 - 0.588score
doc-writing
cormacc
Write, restructure and check documentation -- Markdown and Org documents (READMEs, design records, architecture and onboarding guides) and code comments and…
SkillAFreshness: A★ 1Claude Code +9 - 0.587score
git-commit
cormacc
Generate standardized git commit messages following conventional commits spec, and concise merge/pull request descriptions.
SkillAFreshness: A★ 1Claude Code +9
Cite this page
docx skill. Agent Mart. https://agentmart.dev/skills/cormacc-docx (last updated 2026-10-24)