docx-cli CLAUDE.md

Repository instructions for docx-cli, a command-line tool that lets AI agents read, edit, and comment on Word .docx files.

In plain words
What is it for?
Use them when changing docx-cli code, adding subsystem guidance, running commands, or checking its tests.
Why use it?
They keep changes consistent with the project's rules and prevent subtle output, file-ordering, and testing mistakes.

Instructions file

Install

Getting it into your agent

One page per mod, every tool's command on it. A separate URL per tool would split the same page into five that compete with each other.

agentmods
npx agentmods add instructions/kklimuk/docx-cli/claude-md
Clone the repo
git clone --depth 1 https://github.com/kklimuk/docx-cli
Per session 8,873 This file is loaded in full into every session.
When invoked 8,873 The same file — it is already loaded in full.
Security scan A 0 findings. Scan, not verified.
Origin original No closer match found in the catalogue.
Token cost

What it costs to keep this loaded

Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.

ModelPer sessionOnce invoked
Fable 5 $0.08873 $0.08873
Opus 5 $0.04437 $0.04437
Sonnet 5 $0.01775 $0.01775
Haiku 4.5 $0.00887 $0.00887

Measured 2d ago against content hash 665a4ac135ea, method: parsed. Prices are Anthropic first-party input rates as of 2026-08-30, from the pricing page.

Security

Grade A, and why

docx-cli CLAUDE.md scanned grade A with 0 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured 2d ago.

A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.

Nothing flagged

None of the 26 patterns this scan looks for appear in this file: no shell pipes, no recursive deletes, no credential paths, no hidden text, no instruction-override or anti-refusal phrasing, no agent-config snooping. That is not a guarantee, it is the absence of the things that are checkable.

CLAUDE.md · 106 lines

How it starts

The opening of the file, as written. The whole thing — 106 lines — stays where its author put it; the contents beside it link to each section on GitHub.

docx-cli

CLI for AI agents to read, edit, and comment on .docx files. JSON-AST output, locator-based addressing, full format fidelity via in-place XML mutation.

Bun, not Node. Use Bun.file, Bun.write, Bun.env, Bun.$. Bun loads .env automatically — no dotenv.

Subsystem-specific guidance lives in nested CLAUDE.md files that load when you edit those folders. If you need to add a new CLAUDE.md to describe a new practice for a part of the system, do so.

Conventions

These conventions are NOT SUGGESTIONS. These are rules.

  • All stdout goes through respond() (JSON ack) or writeStdout() (text) from src/cli/respond.ts — never process.stdout.write. Both use Bun.write(Bun.stdout, ...); the 64 KB truncation that bites on early exit is real and silent, and these helpers are the only safe path.
  • File naming: kebab-case, named after the primary export (xml-node.tsXmlNode).
  • Newspaper ordering. The entry point (primary export) goes at the top; its dependencies follow in the order it uses them, then their dependencies, and so on — a file reads top-to-bottom like a newspaper. Use hoisted function declarations for internal helpers so this works at runtime; arrow functions only for inline callbacks and short utilities. Types are usually not the primary exports and should go below the functions/classes that are.
  • Feature nesting When a file accumulates too many dependencies to be read well with newspaper ordering (> 300 lines), split them into a separate folder/file named after the feature they're working on. It should be a folder if it is going to represent a logical feature of dependencies. This nesting can continue indefinitely if subfeatures have subfeatures of their own.
  • JSX is for emitters only. Files that construct fresh XML can be .tsx; readers/locators/analysis stay .ts. Components are PascalCase, accept props, may return NullableXmlNode (null skipped by flatten). Attribute names with colons use the hyphen shortcut (w-val="x"w:val="x") or JSX spread.
  • Component vs view vs lens vs free function vs transient cursor: five shapes, one decision tree.
    • A pure props → XmlNode builder is a PascalCase component — destructure its props in the signature (no props.x access), and don't take a Document (or any package state).
    • Stateful OOXML state lives in tree-owning views, embedded as fields on Document: Body, plus one view per OPC part — StylesView, NumberingView, CommentsView, NotesView, RelationshipsView, ContentTypesView, SettingsView, CorePropertiesView, MarginalsView. Each owns its part's XmlNode tree and any maps keyed to it, and exposes a fromPackage/fromXml/writeTo lifecycle (register too, for the lazily-provisioned ones). MarginalsView is the one that owns MANY parts (every word/header{N}.xml / word/footer{N}.xml) keyed by part name rather than one — so it has no single register; the Marginals lens mints each part's rel + content-type as it allocates it. Cross-view dependencies (e.g., NotesView.ensureNoteStyles(stylesView)) are passed as method arguments — no view reaches up to Document.
    • Cross-cutting lenses (Images, Hyperlinks, Equations, TrackChanges, Comments, Fonts, Marginals) are NOT fields on Document — they're stateless, constructed at the call site: new Images(document).add(source), new TrackChanges(document).accept(["tc0"]), new Marginals(document).set(sectPrs, "footer", "default", spec), await new Fonts(document).setDefault("Times New Roman"). They hold only a back-reference; the embedded views are the state they reach through. Marginals is the header/footer authoring lens — the noun pair docx headers/docx footers share it via MarginalKind the way footnotes/endnotes share Note — reaching through MarginalsView (part trees) + relationships/content-types (part registration) + settings (the even/odd toggle) + the live <w:sectPr> reference nodes (see src/core/marginals). Fonts is the one that also touches an UNMODELED part — the document font lives in BOTH word/styles.xml <w:docDefaults> (owned by StylesView) and word/theme/theme1.xml's <a:fontScheme> (not a view: read/mutated/staged through Pkg only when set-default-font runs, so unrelated saves never re-serialize the theme blob).
    • Free functions are reserved for: pure builders (the components above), the AST reader (src/core/ast/read.ts — Document's construction pass; populates the embedded views from XML and is the sole assigner of tcN ids), and emitter helpers in src/core/blocks/table/sections that thread a Document because they touch many slices in one call. If a free function's body operates on one slice of document, make it a method on that slice's view instead.
    • Transient cursors are the one stateful shape that is NEITHER a view nor a lens: a short-lived object holding position state over a SINGLE node's child list, valid only within one mutation pass (today CellInsertionCursor in src/core/table, which keeps a batch's inserts into one <w:tc> in entry order). It holds no Document, isn't embedded on one, and dies with the pass — so don't file it as a lens. It lives beside the primitives it sequences, and the CLI constructs one per target and calls it.
  • JSX.Element = XmlNode (single, not nullable). Fragment returns a #fragment sentinel unwrapped in flatten() and serialize(). Components return null to render nothing; jsx() converts that to an empty fragment. The jsx/jsxs/jsxDEV runtime exports are distinct functions, not = jsx aliases (knip flags aliased re-exports as duplicates) — don't collapse them.
  • Path aliases: @coresrc/core/index.ts, @core/*src/core/*. Use these in src/cli/*; src/core itself uses relative sibling imports. Import the body emitters from the @core/blocks and @core/table subpaths, not the @core barrel — ast/types already exports Paragraph/Table/TableCell/TableRow as types, and barrel-merging the same-named value emitters is confusing.
  • Variable names: descriptive, no single/two-letter (paragraph not p). Exception: regex-match destructuring (const [, prefix, idx] = match).
  • Inline props in the signature. When a component's props type is used only by that component, write it inline (function HeadingStyle({ styleId }: { styleId: BaselineStyleId; … })) rather than declaring a separate named Props type. Extract a named type only when it's shared.
  • knip runs strict (bun run check, no rule overrides in knip.json). An unused export is dead code — delete it (this is a CLI app, not a library; there are no external @core consumers). The one exception: an export staged for a named upcoming tier with no caller yet gets a @public JSDoc tag whose comment names the future consumer (knip honors @public) — e.g. HorizontalRule (S8) and the r/a/wp/pic image namespaces (S5). Don't silence knip by re-adding rule suppressions.
  • Style: tabs, double quotes (Biome enforced). Early returns over else-if chains.

Read the full file on GitHub · 106 lines

Changes

What this file has done since we first saw it

Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.

  1. 2d ago First seen · 106 lines · 8,873 tokens per session scan A 665a4ac135ea

Subscribe to this mod's changes

docx-cli CLAUDE.md is an instructions file published in the GitHub repository kklimuk/docx-cli (194 stars, last pushed 15d ago), licensed MIT. It adds 8,873 tokens to every session, about $0.0444 per session on Opus 5. A static security scan graded it A with 0 findings. No closer match exists in the catalogue, so it is treated as the original; first seen 2026-08-30.

Related

Other instructions, from other repositories

open-agent-hub AGENTS.md

AGENTS.md instructions for guanyang/open-agent-hub, covering agents.md, 1. think before coding, 2. simplicity first, 3. surgical changes and 4. goal-driven execution.

guanyang/open-agent-hub · 485 tokens

superdesign-skill AGENTS.md

Instructions for superdesigndev/superdesign-skill, covering project agent memory, what this repo is, skill flow invariant: two entry paths, ground truth for cli behavior and plugin packaging & release.

superdesigndev/superdesign-skill · 1,698 tokens

stewie-pixel guidelines

Behavioral guidelines to reduce common LLM coding mistakes. Use when writing, reviewing, or refactoring code to avoid overcomplication, make surgical changes, surface assumptions, and define verifiable success criteria.

Stewie-pixel/claude-with-leetcode · 827 tokens

vanguard-frontier-agentic copilot-instructions.md

Instructions for VincentChuWaiChow/vanguard-frontier-agentic, covering vanguard frontier agentic repository instructions, what to optimize for, repo structure, rules for changes and cross-platform asset rule.

VincentChuWaiChow/vanguard-frontier-agentic · 359 tokens

archeyes CLAUDE.md

Instructions for thisAAY/archeyes, covering archeyes — project guide, layout, design system, commands and publishing a release.

thisAAY/archeyes · 1,284 tokens

kleinanzeigen-reader CLAUDE.md

Instructions for its-me-prash/kleinanzeigen-reader, covering claude.md — kleinanzeigen-reader, what this repo is, auto-load instructions for claude code, quick command reference and fetch a listing.

its-me-prash/kleinanzeigen-reader · 834 tokens