Skip to main content

Word Documents (profy-docx)

Create, edit, and analyse Word documents. Understanding this capability starts with accepting one fact: a .docx file is a ZIP archive containing XML. Every constraint below that looks arbitrary follows from that structure.

Activation

profy-docx is user_selectable: falseautomatically available, nothing to tick.
contracts declares only skills: ["skills/"] and no tools. The expert runs scripts via bash in the sandbox; the skill document governs how. Triggers include: Word documents, .docx, requests for polished deliverables with tables of contents, headings, page numbers, or letterheads, plus extracting or reorganising content from existing docx files, inserting or replacing images, find-and-replace, and working with tracked changes or comments. PDFs, spreadsheets, and Google Docs do not take this path.

Three main routes

Reading

Converting legacy .doc

.doc is an entirely different binary format and must be converted before it can be edited.

Converting to images for visual inspection

Accepting tracked changes

Requires LibreOffice. Produces a clean document with every tracked change accepted.

Text replacement: use the script, do not write your own

Exit codes:
Do not hand-write python-docx scripts for simple find-and-replace. Word splits a single sentence across multiple run elements — because one word is bold, or because the spell checker inserted a marker — so the string you are searching for is not contiguous in the XML at all. Hand-written scripts therefore fail silently: no error, just no replacement. docx_replace.py handles run-boundary splitting and verifies the result afterwards, which is exactly what exit code 2 reports.
This is a good general lesson about document formats: the visual model (a sentence) and the storage model (a run sequence) do not correspond, and any tool that assumes they do will be wrong intermittently rather than consistently — the worst possible failure mode.

Creating documents: docx-js constraints

None of these are style preferences. Each corresponds to a concrete failure where the output either will not open or renders incorrectly somewhere.

Structure

Lists and tables

Tables of contents

Supported typesetting features

Page size, style overrides, multi-level lists, tables, images, page breaks, hyperlinks, footnotes, tab stops, multi-column layouts, tables of contents, headers and footers.

Boundaries and failure modes

  • .doc must be converted first. Editing it directly fails.
  • Hand-written replacement scripts fail silently (see the run-boundary warning above).
  • Accepting tracked changes depends on LibreOffice; without it accept_changes.py cannot run.
  • Unpacking and editing XML is a sharp tool. Malformed XML makes Word refuse to open the file rather than degrade gracefully, so edits must be validated afterwards.
  • Tables render inconsistently across renderers. Most of the constraints above (DXA, dual widths, CLEAR shading) exist to keep output correct outside Word — in Google Docs, WPS, and preview tools.

Troubleshooting

Verify your output

  1. Convert to images and look: soffice.py --convert-to pdf then pdftoppm. This catches the overwhelming majority of layout accidents and is far faster than reading XML.
  2. If there is a table of contents, confirm the entry count matches the actual heading count.
  3. If there are tables, open the file in Google Docs too — it is the least forgiving about width definitions, so passing there generally means passing everywhere.

Office documents overview

How the four document capabilities differ and when to use each

PDF documents

The alternative route when the deliverable needs real typesetting
Verified 2026-08-11. Sources: services/agent-runtime/src/plugins/builtin/docx/plugin.json, skills/SKILL.md, skills/scripts/office/docx_replace.py, skills/scripts/accept_changes.py, skills/scripts/office/{unpack,pack,soffice}.py.