docx
Skill1 starsChanged 3 months agoMITView on GitHub
Create, edit, redline, and verify Word .docx files. Use when generating documents with the docx npm package, editing a .docx's XML directly, adding tracked changes (redlining) or comments, or verifying rendered output. Not for .odt, .rtf, .pages, or PDF files.
- Installs packages
194 other projects use a version of this.
Adopted by
Most recently taken up by
- CloudChef/atlasclaw-providerstheir own version, first seen Nov 8, 2026
- holon-run/holontheir own version, first seen Nov 8, 2026
- rvdbreemen/OTGW-firmwaretheir own version, first seen Nov 8, 2026
- BrightGold70/skillstheir own version, first seen Nov 8, 2026
- ashleysbrain/skillstheir own version, first seen Nov 8, 2026
- EvanLee2004/finance-skillstheir own version, first seen Nov 8, 2026
Used with
Projects with it also use Video Generation, VLM and 10 more.
Other files people use alongside this one.
Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
huang-x-hSkillVideo Generation
Implement AI-powered video generation capabilities using the z-ai-web-dev-sdk. Use this skill when the user needs to generate videos from text prompts or images, create video content programmatically, or build applications that produce video outputs. Supports asynchronous task management with status polling and result retrieval.
Also in 6 projects that use this
huang-x-hSkillVLM
Implement vision-based AI chat capabilities using the z-ai-web-dev-sdk. Use this skill when the user needs to analyze images, describe visual content, or create applications that combine image understanding with conversational AI. Supports image URLs and base64 encoded images for multimodal interactions.
Also in 6 projects that use this
dav-niu474Skillgift-evaluator
The PRIMARY tool for Spring Festival gift analysis and social interaction generation. Use this skill when users upload photos of gifts (alcohol, tea, supplements, etc.) to inquire about their value, authenticity, or how to respond socially. Integrates visual perception, market valuation, and HTML card generation.
Also in 5 projects that use this
dav-niu474SkillPodcast Generate
Generate podcast episodes from user-provided content or by searching the web for specified topics. If user uploads a text file/article, creates a dual-host dialogue podcast (or single-host upon request). If no content is provided, searches the web for information about the user-specified topic and generates a podcast. Duration scales with content size (3-20 minutes, ~240 chars/min). Uses z-ai-web-dev-sdk for LLM script generation and TTS audio synthesis. Outputs both a podcast script (Markdown) and a complete audio file (WAV).
Also in 5 projects that use this
Liang-MHSkillstock_analysis
获取 A 股、基金和港股的实时行情和技术分析数据
Also in 5 projects that use this
SeifBenayedSkillfile-reading
Use this skill when a file has been uploaded but its content is NOT in your context — only its path at /mnt/user-data/uploads/ is listed in an uploaded_files block. This skill is a router: it tells you which tool to use for each file type (pdf, docx, xlsx, csv, json, images, archives, ebooks) so you read the right amount the right way instead of blindly running cat on a binary. Triggers: any mention of /mnt/user-data/uploads/, an uploaded_files section, a file_path tag, or a user asking about an uploaded file you have not yet read. Do NOT use this skill if the file content is already visible in your context inside a documents block — you already have it.
Also in 5 projects that use this
- +1 more from huang-x-h
- +5 more from dav-niu474
Other versions194 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 194
- anthropics/skills★ 189ksame name
- spinabot/brigade★ 11ksame name
- netease-youdao/LobsterAI★ 6.2ksame name
- OpenBMB/PilotDeck★ 5ksame name
- nextlevelbuilder/goclaw★ 3.7ksame name
- jjyaoao/HelloAgents★ 3.2ksame name
- anthropics/claude-agent-sdk-demos★ 2.8ksame name
- K-Dense-AI/claude-scientific-writer★ 2.6ksame name
- OpenCoworkAI/open-cowork★ 2.2ksame name
- ChenglinPoly/infiAgent★ 1.2ksame name
184 more not listed
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository45 other files it gives its agents.
- AGENTS.mdAGENTS.md
- blast-radiusSkill
- broSkill
- codebase-designSkill
- code-reviewSkill
- confluence-workflowSkill
- creating-a-pr-mrSkill
- defuddleSkill
- diagram-designSkill
- domain-modelingSkill
- engineering-principlesSkill
- forgejo-cliSkill
- frontend-designSkill
- gh-cliSkill
- git-conventional-commitsSkill
- git-working-agreementSkill
- glab-cliSkill
- grillingSkill
- grill-meSkill
- grill-with-docsSkill
- howSkill
- improve-codebase-architectureSkill
- jira-workflowSkill
- json-canvasSkill
- k8s-opsSkill
- obsidian-basesSkill
- obsidian-cliSkill
- obsidian-markdownSkill
- openspec-workflowSkill
- pdfSkill
- pptxSkill
- prototypeSkill
- researchSkill
- setup-matt-pocock-skillsSkill
- skill-minerSkill
- technical-writingSkill
- theme-factorySkill
- to-specSkill
- to-ticketsSkill
- triageSkill
- unslopSkill
- wayfinderSkill
- whySkill
- writing-for-agentsSkill
- xlsxSkill
The file
We split this skill into the rules it gives an agent
5 rules. 0 are common, 2 are distinctive, and 3 are very specific to this project.
0
Common
Most of the 189 edited versions we read keep these.
2
Distinctive
This author's own choices. Worth a look.
3
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 136
All state lives in word/document.xml (plus w:author/w:date):
- Very specific: line 149
Every w:id must be unique document-wide.
- Very specific: line 161
Verify redlines mechanically, not by eye: pandoc -f docx --track-changes=all -t markdown renders [text]{.insertion ...} / [text]{.deletion …
- Distinctive: line 201
Never trust generation code — render and read back:
- Distinctive: line 223
Check, then install what's missing:
“Common” is measured: kept by at least 6 in 10 of the 189 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Word documents (.docx)
A .docx is a zip of XML parts. Generating from scratch is easiest through the
docx npm package; changing an existing file is usually surgical XML editing
of its unpacked parts. Pick the row that matches the task:
| Task | Approach |
| Create a new document | Write a Node script with the docx package, Packer.toBuffer to a file |
| Edit an existing document | Unzip, edit word/document.xml (and friends), rezip from inside the directory |
| Read the text | pandoc -t markdown file.docx (or textutil -convert txt on macOS) |
| Verify visually | soffice --headless --convert-to pdf then pdftoppm -png and inspect |
| Redline / tracked changes | Edit XML: wrap runs in w:ins / w:del (see below) |
| Add a comment | scripts/add_comment.py to create the parts and print/insert the anchor |
Generating with the docx npm package
Everything below is verified against docx 9.x behavior; treat older versions with suspicion.
const { Document, Packer, Paragraph, TextRun, HeadingLevel, Table, TableRow,
TableCell, WidthType, ShadingType, AlignmentType, LevelFormat,
TableOfContents, ImageRun, PageBreak, PositionalTab, PositionalTabAlignment,
PositionalTabLeader, PositionalTabRelativeTo, PageOrientation } = require("docx");
const doc = new Document({
numbering: { config: [{ reference: "bullets",
levels: [{ level: 0, format: LevelFormat.BULLET, text: "\u2022",
style: { paragraph: { indent: { left: 720, hanging: 360 } } } }] }] },
sections: [{
properties: { page: { size: { width: 12240, height: 15840 } } }, // US Letter
children: [ /* Paragraphs and Tables */ ],
}],
});
Packer.toBuffer(doc).then((buf) => fs.writeFileSync("out.docx", buf));Dimensions are DXA: 1440 DXA = 1 inch. The default page is A4
(11906 x 16838); for US Letter pass width: 12240, height: 15840 explicitly.
Landscape keeps the same two numbers swapped plus
orientation: PageOrientation.LANDSCAPE — the library writes both the
swapped w:pgSz values and w:orient="landscape", so don't pre-swap them
yourself.
Hard-won gotchas:
- Tables need widths twice:
columnWidths: [dxa, ...]on the Table ANDwidth: { size: dxa, type: WidthType.DXA }on every TableCell. DXA only — percentage widths resolve against different bases in Word, LibreOffice, and pandoc, and tables come out squashed or sprawling somewhere. - Cell shading is
ShadingType.CLEAR, never SOLID. SOLID darkens the fill; CLEAR (the Word defaultw:shd w:val="clear") renders the plain fill color you chose. - Bullets come from a numbering config (
numbering.config+ a Paragraph withnumbering: { reference, level }). Never type a literal "•" into a run — it loses list semantics, indentation, and hanging indents. ImageRunneeds an explicittype: "png"(or jpeg/gif/svg). Omit it and docx 9.x silently stores the media part asimage.undefinedwith no content type; LibreOffice tolerates that, Word offers to "repair" the file.PageBreakmust sit inside a Paragraph's children, not bare in a section. A break not wrapped in a paragraph is dropped or corrupts output.- No
\ninside a TextRun. It is written to the XML as a literal backslash-n and shows up in the document as that text. One paragraph per line, ornew TextRun({ break: 1 })for a line break within a paragraph. TableOfContentswrites an empty field marked dirty (TOC \h \o "1-2"withw:dirty="true"). It renders empty everywhere until a field update: Word populates it on open/print, LibreOffice via Tools > Update > Indexes —soffice --headless --convert-to pdfdoes NOT populate it, so don't panic when the PDF shows no TOC.- TOC and pandoc headings need heading styles that resolve. Give body
headings
heading: HeadingLevel.HEADING_1(oroutlineLevel). pandoc recognizes headings through the styles part; docx-js emits<w:basedOn w:val="Normal"/>on every style but never defines aNormalstyle, and pandoc's style resolution then fails, demoting every heading to a plain paragraph in the pandoc read-back. Fix by injecting one style intoword/styles.xmlbefore (or after) generation:<w:style w:type="paragraph" w:styleId="Normal"><w:name w:val="Normal"/><w:qFormat/></w:style> - Dot leaders are positional tabs, not padded dots:
new PositionalTab({ alignment: PositionalTabAlignment.RIGHT, leader: PositionalTabLeader.DOT, relativeTo: PositionalTabRelativeTo.MARGIN })inside the paragraph produces<w:ptab w:leader="dot"/>— real right-aligned dot leaders that survive font changes. - Namespaces in output are heavy but harmless. docx-js declares a dozen
namespaces and drops an empty self-closing
<w:comments .../>scaffold into the package. Word and LibreOffice ignore both.
Editing an existing .docx
Unzip to a directory and edit the XML parts by hand (or with a script):
mkdir dir && unzip -o file.docx -d dir # word/document.xml is the body
# ... edit ...
cd dir && zip -Xr ../out.docx . # rezip FROM INSIDE the directory- Check for symlink entries in untrusted files first.
zipinfo file.docxprints a mode column; any entry starting withl(e.g.lrwxrwxrwx) is a symlink, and command-lineunzipwill happily create it (pointing wherever the archive wants, e.g./etc/passwdwhen you later read or follow it). Python'szipfileis safe — it writes symlink entries as regular files — so for anything you didn't generate yourself, either extract with python or filter outl-mode entries. - Rezip from inside the directory (
cd dir && zip -Xr ../out.docx .). Zipping with paths (zip -r out.docx dir/) nests adir/prefix inside the archive and Word can't find the parts.-Xstrips filesystem extra fields; unlike odt/epub there is no stored-first entry requirement, so any entry order works. - Visible phrases are usually fragmented XML. Word splits text across
many
<w:r>runs (spellcheck markers, rsid revision ids, IME input), so "the quick brown fox" is rarely one<w:t>— you often can't wrap it in aw:ins, delete it, or anchor a comment to it directly. Runscripts/merge_runs.pyto coalesce adjacent same-format runs (it never changes text or formatting), then re-read. w:rsid*attributes are inert session bookkeeping — safe to ignore and safe to keep; don't try to "clean" them while editing.- Validate after every edit:
python3 -c "from xml.etree import ElementTree; ElementTree.parse('dir/word/document.xml')". Attribute order never matters; element order often does (see rPr below). - Legacy .doc is not .docx. It's an OLE2 compound file; python's zipfile
and your XML tooling will fail on it. Convert first with
soffice --headless --convert-to docx file.doc, edit the result, and convert back with--convert-to docif the user needs .doc again.
scripts/merge_runs.py dir/ merges in place on an unpacked directory;
scripts/merge_runs.py file.docx -o out.docx on an archive.
Tracked changes (redlining)
All state lives in word/document.xml (plus w:author/w:date):
<w:ins w:id="100" w:author="Reviewer" w:date="2026-09-06T10:00:00Z">
<w:r><w:t>inserted text</w:t></w:r>
</w:ins>
<w:del w:id="101" w:author="Reviewer" w:date="2026-09-06T10:00:00Z">
<w:r><w:delText>deleted text</w:delText></w:r>
</w:del>- Inside
w:del, the text element isw:delText, notw:t— a plainw:tinsidew:delrenders the text as if never deleted. - Every
w:idmust be unique document-wide. Use one author name consistently; a mix of authors looks like several people edited the file. - Deleting a whole paragraph is two operations: wrap every run in
w:del, AND mark the paragraph mark itself deleted by adding<w:rPr><w:del w:id="N" .../></w:rPr>inside that paragraph'sw:pPr. Without the second part the paragraph mark survives and you get an empty line; with it, Word merges the paragraph with the next one when the change is accepted. - Element order inside
w:rPris schema-constrained: in the paragraph-mark rPr (w:pPr > w:rPr),w:ins/w:delcome first, before other properties likew:rFonts/w:b. Order violations are tolerated by some readers and rejected by others — keep the schema order. - Verify redlines mechanically, not by eye:
pandoc -f docx --track-changes=all -t markdownrenders[text]{.insertion ...}/[text]{.deletion ...}/ paragraph-mark deletions as.paragraph-deletion; then diff--track-changes=acceptvs=rejectplain-text output to prove each edit flips the right way. As a second opinion,soffice --headless --convert-to docxround-trips the file — LibreOffice re-emits its ownw:ins/w:delfor anything it understood, and a round-trip that loses a change means your markup was wrong.
Comments
A visible comment is several cross-linked parts, not one:
word/comments.xml— the comment bodies (w:commentwithw:id,w:author,w:date,w:initials)word/commentsExtended.xml,word/commentsIds.xml,word/commentsExtensible.xml— modern Word state (resolved/resolved status, durable ids); linked byw14:paraIdon the comment's paragraphs- one relationship per part in
word/_rels/document.xml.relsand one<Override>per part in[Content_Types].xml - the anchor triplet in
word/document.xml— the comment is invisible until this exists:<w:commentRangeStart w:id="0"/> ...commented runs... <w:commentRangeEnd w:id="0"/><w:r><w:rPr><w:rStyle w:val="CommentReference"/> </w:rPr><w:commentReference w:id="0"/></w:r>
scripts/add_comment.py does all the parts bookkeeping (id allocation,
paraIds, threading via --parent, relationships, content types) and either
inserts the anchor itself (--insert, when the target phrase sits inside a
single run) or prints the exact anchor XML plus offsets to place by hand.
For a phrase that spans runs, run scripts/merge_runs.py first.
pandoc shows comments ONLY with --track-changes=all
([text]{.comment-start id="0" author="..." date="..."}anchored text
[]{.comment-end id="0"}); with the default accept-changes they vanish
silently. LibreOffice renders comments in the UI but headless PDF export
omits them unless you enable annotation export.
Verify the output
Never trust generation code — render and read back:
# render to images (best proxy for "what Word will show")
soffice --headless --convert-to pdf file.docx
pdftoppm -png -r 100 file.pdf page # then inspect page-*.png
# independent text read-back
pandoc -t plain file.docx # cross-platform
textutil -convert txt file.docx -output - # macOS built-in
# structural check (every edited part)
python3 -c "from xml.etree import ElementTree as ET; ET.parse('dir/word/document.xml')"Assertions worth scripting per task: the table's gridCol/tcW widths sum
to the table width; each redline edit appears inside a w:ins/w:del (and
w:delText inside w:del); comment anchors sit inside the same paragraph
as their target text; page count matches expectation via pdfinfo.
Dependencies
Check, then install what's missing:
node+docx:npm install docxin a scratch directory (v9.x assumed above).pandoc:brew install pandocorapt install pandoc.- LibreOffice (
soffice):brew install --cask libreofficeorapt install libreoffice. On some distros the binary is versioned, e.g.libreoffice25.2. - poppler (
pdftoppm,pdftotext,pdfinfo):brew install popplerorapt install poppler-utils. zip/unzip/zipinfo: system defaults.textutil: macOS built-in.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

