Back to projects
Active Started May 2026

Docx Builder

Claude Code plugin that builds production Word docs — locked typography, headings, tables, TOC, and callouts — via a plan, render, check, deliver workflow.

Private Repo
Claude Code Plugin python-docx Python

Install

claude plugin marketplace add tyroneross/RossLabs-AI-Toolkit
claude plugin install docx-builder@rosslabs-ai-toolkit

The Problem

Asking an LLM to “make a Word doc” produces a file that opens but looks wrong — inconsistent fonts, broken heading levels, tables without header shading, no real table of contents. The mechanics of python-docx (field codes, styles, section properties) are fiddly enough that each attempt re-derives them and gets them slightly wrong.

What I Built

A Claude Code plugin that owns the full Word production workflow — plan → render → post-check → deliver — against a locked spec so output is consistent every time: Arial 12pt body, H1–H3 hierarchy, 1″ margins, US Letter, 1.15 line spacing.

It ships copy-paste python-docx recipes for the parts that are easy to get wrong: TOC field codes that update in Word, table header shading, callout boxes with a left border accent, headers and footers, and list styles. The post-check step verifies the rendered document against the spec before delivery, so formatting drift is caught rather than shipped.

Architecture

The plugin ships no application code — no .py files, no server, no database. It ships a Claude Code skill (SKILL.md, 267 lines) plus a reference file of copy-paste python-docx recipes (references/python-docx-recipes.md, 319 lines) that together instruct the invoking Claude session how to write and run python-docx code against a locked formatting spec. The skill is the artifact; the host Claude Code session is the executor — there is no separate model call inside the plugin itself.

flowchart LR
  A[".docx request<br/>(report, brief, memo, playbook)"] --> B["doc-structure skill<br/>(tyrone-writing-system, optional)<br/>locks H1-H3 outline"]
  B --> C["docx-builder skill loads<br/>SKILL.md spec"]
  C --> D["Plan stage<br/>map sections to H1-H3 hierarchy"]
  D --> E["Render stage<br/>host Claude writes/runs python-docx<br/>using references/python-docx-recipes.md"]
  E --> F["Post-check stage<br/>verify fonts, headings, margins,<br/>table shading, TOC field codes"]
  F -->|fails spec| E
  F -->|passes| G[".docx file delivered<br/>+ F9 TOC-refresh note"]

Models — which, where, why:

Models: none. The plugin contains no LLM API call, no inference step, and no prompt template that generates prose. Every stage — plan, render, post-check — is spec lookup and python-docx code execution carried out by whatever Claude Code session has the skill loaded; the skill supplies fixed rules (fonts, sizes, hex colors, margins) and fixed code recipes, not model-generated formatting decisions. This is the load-bearing architecture fact: consistency comes from a locked spec applied deterministically, not from a model reasoning about formatting each time.

Tools & infra — which, why:

  • python-docx — the only third-party dependency; manipulates the underlying OOXML (<w:shd>, <w:pBdr>, <w:fldChar> field codes) to get table shading, callout borders, and an auto-updating TOC that plain python-docx calls can’t reach directly.
  • Python 3 — runtime for the generated render script; installed in the user’s/host’s environment, not bundled with the plugin (pip install python-docx --break-system-packages per the reference doc).
  • Claude Code plugin/skill packaging (.claude-plugin/plugin.json, SKILL.md, references/) — the distribution and invocation mechanism; no runtime service, no hosting, no network calls.
  • RossLabs AI Toolkit marketplace (tyroneross/RossLabs-AI-Toolkit) — install/update channel (claude plugin marketplace add / claude plugin install).

No database, vector store, or queue — output is a single .docx file written to disk per request; there is no persistence layer to hold state between runs.

How it works

  1. A request for a .docx (report, brief, memo, playbook) arrives. If the section structure isn’t locked yet, doc-structure (tyrone-writing-system plugin) runs first and produces an ordered H1/H2/H3 outline with a governing sentence and so-what per section — docx-builder explicitly refuses to open until that’s done.
  2. Plan stage — the docx-builder skill loads its locked spec (Arial 12pt body; H1 16pt bold / H2 14pt bold / H3 12pt bold italic; 1” margins; US Letter; 1.15 line spacing; 6pt paragraph spacing) and maps the incoming outline onto that hierarchy before any file is written.
  3. Render stage — the host Claude session writes and executes python-docx code using the reference recipes: new_doc() sets margins and style-level fonts once (never per-run, so edits in Word don’t break formatting); add_cover(), add_header_footer(), add_toc() (OOXML field code, placeholder text until the user presses F9), add_table_with_caption() (header row shaded D5E8F0), and add_callout() (F0F2F5 fill, 2B6CB0 3pt left border, max one per major section) compose the document.
  4. Post-check stage — the rendered file is checked against the same spec: fonts and sizes on body/headings, heading-level hierarchy is visually distinguishable, 1” margins, table header shading present, TOC field code present when there are more than 3 H1 sections. A table missing its header shading or a heading rendered at the wrong level is caught here, before delivery.
  5. Deliver — the file is handed off with a one-line note reminding the user to press F9 in Word to populate the TOC, since field codes don’t auto-populate on save.

Tech stack

Claude Code plugin (skill + reference docs, no application code shipped). python-docx is the sole third-party dependency, used for OOXML-level control of styles, table shading, callout borders, and TOC/PAGE field codes. Python 3 runs the generated render script in the host environment. Distributed via the RossLabs AI Toolkit Claude Code plugin marketplace. No database, vector store, queue, or hosted service — the entire system runs as skill instructions executed by the invoking Claude Code session, output is a single local .docx file.

Results

⚠️ no benchmark yet — no data on render time, defect catch rate, or documents processed.