Coquill renderer
Document renderer for CoQuill. Takes a template, variable values, and produces rendered documents (docx or html+pdf). Validates output for unfilled placeholders. Called by the coquill orchestrator — not triggered directly by the user.From its SKILL.md
npx -y skills add houfu/coquill --skill coquill-rendererAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 3 stars3 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
4.6 KB, as published. Nobody here has run it
CoQuill — Document Renderer (v2)
You are running the CoQuill document renderer. Your job is to render a completed document from a template and a set of variable values, then validate the output.
Inputs
This skill is called by the CoQuill orchestrator. You receive:
- Template path — e.g.,
templates/_examples/Bonterms_Mutual_NDA/Bonterms-Mutual-NDA.docx - Format —
docx,html, ormarkdown - Variable dictionary — all collected values: flat key-value pairs, booleans as Python
True/False, and loop collections as lists of dicts - Output directory — e.g.,
output/
Step 1 — Output Structure
Each rendering job gets its own folder inside the output directory:
output/
└── {template_name}_{key_variable}_{date}/
├── {template_name}_{key_variable}_{date}.docx
└── {template_name}_{key_variable}_{date}.pdf ← when tooling available
key_variable: the most identifying variable (typically a person/company name) — slugified (lowercase, underscores, no special characters).date: today's date inYYYY-MM-DDformat.- Job folders deduplicate by appending
_2,_3, etc. if the folder already exists.
Step 2 — Write Context and Run Render Script
2a — Write context.json
Serialize the full variable dictionary as a JSON file to a temporary path. The render script reads this file.
2b — Resolve script path
The render script lives at scripts/render.py relative to the project root. If the CLAUDE_PLUGIN_ROOT environment variable is set, resolve the script as $CLAUDE_PLUGIN_ROOT/scripts/render.py.
2c — Run the render script
python <script_path> \
--template <template_path> \
--format <docx|html|markdown> \
--context <context_file> \
--output-dir <output_dir> \
--job-name <job_name> \
[--pdf]
The script handles boolean coercion, job folder creation, template rendering (docxtpl for docx, jinja2 for html/markdown), PDF conversion, and output validation. It prints a JSON result to stdout containing job_dir, files, pdf_produced, pdf_warning, and validation.
2d — Cowork DOCX to PDF fallback
The render script does not handle Cowork-specific docx-to-PDF conversion. If you are running inside Cowork (check for /home/user/.claude/ or the COWORK environment variable) and the format is docx with PDF requested:
- Run the render script without
--pdfto produce the.docx. - Use the Cowork built-in
docxskill to read the rendered.docxfile. - Use the Cowork built-in
pdfskill to produce a.pdffrom it. - Save the resulting PDF to the job folder as
{job_name}.pdf.
Do NOT attempt docx2pdf or soffice in Cowork — they fail due to sandbox restrictions.
Step 3 — Interpret Validation Results
The script's JSON output includes a validation object:
validation.passed == true: All placeholders and control tags were processed. The document is ready.validation.unfilled_variables(non-empty): Variable names that remain as{{ var }}in the rendered output. Check whether those variables exist in the manifest — if they do, something went wrong in rendering; if they don't, the template may have placeholders the Analyzer missed.validation.unprocessed_tags(non-empty): Remaining{% %}control tags indicate a rendering failure. Common causes: boolean value passed as a string, missing loop collection, or malformed template syntax.
If validation fails, report the issue back to the orchestrator so it can inform the user and offer to re-collect and re-render. Do NOT deliver a document with unfilled placeholders or unprocessed control tags.
Step 4 — Report Results
Return to the orchestrator:
- The
job_dirandfileslist from the script output - Whether validation passed or failed (with details if failed)
- Whether PDF was produced (
pdf_produced); if not, includepdf_warning
Soft-fail semantics for PDF: Always deliver the primary document (.docx, .html, or .md). Warn if PDF was not produced — never hard-fail because of missing PDF tooling.
Important Notes
- For docx templates, always use
docxtpl— not raw python-docx with string replacement.docxtplpreserves formatting around placeholders and natively supports Jinja2 control tags. - PDF output is soft-fail — always deliver the primary format even if PDF conversion fails.