agentsclimarketplace

Create docx

Skill MaskedControl/skills/skills/create-docx

Claude Code skills for developers

Install
npx -y skills add MaskedControl/skills --skill create-docx

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 0 stars0 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.

What its author says it does

Copied from the file, not written here

Use when creating or generating a Word document (.docx) for a client, email, or report. Covers Windows setup, running docx-js scripts in a temp folder, cleanup, and formatting patterns (tables, bullets, callout boxes, screenshot placeholders). Triggers on requests like "create a Word doc", "generate a .docx", "make a report in Word", or "build a document for the client."

SKILL.md

8.5 KB, as published. Nobody here has run it

Create Word Documents (docx-js on Windows)

Overview

Word documents are generated by writing a JavaScript file that uses the docx npm package, running it with Node, then cleaning up the temp files. The docx package must be installed locally in the same folder as the script - global install does not work with require('docx').

The full docx-js API reference is in the example-skills:docx skill. Load it for syntax on tables, images, headers/footers, tracked changes, and anything not covered here.

Process

1. Write the script

Write the JS file to a working location (e.g. Desktop). Output path should be absolute.

const { Document, Packer, Paragraph, TextRun, Table, TableRow, TableCell,
        HeadingLevel, AlignmentType, LevelFormat, BorderStyle, WidthType,
        ShadingType, VerticalAlign, PageBreak } = require('docx');
const fs = require('fs');
// ... build doc ...
Packer.toBuffer(doc).then(buf => {
  fs.writeFileSync("C:/Users/rosem/Desktop/output.docx", buf);
  console.log("Done");
}).catch(err => { console.error(err); process.exit(1); });

2. Install and run

cd C:/Users/rosem/Desktop
npm init -y
npm install docx
node build-doc.js

3. Clean up

Remove-Item -Recurse -Force build-doc.js, package.json, package-lock.json, node_modules

Windows Validation Caveat

The validate.py script from example-skills:docx throws a UnicodeEncodeError on Windows consoles (cp1252 can't encode the arrow character it prints). This is a validator bug, not a document problem. Skip validation - open the file in Word to verify instead.

Page Setup (Always Set Explicitly)

docx-js defaults to A4. Always override:

sections: [{
  properties: {
    page: {
      size: { width: 12240, height: 15840 },        // US Letter
      margin: { top: 1080, right: 1080, bottom: 1080, left: 1080 } // 0.75" margins
    }
  },
  children: [...]
}]
// Content width = 12240 - (2 x 1080) = 10080 DXA

Numbering (Never Use Unicode Bullets Directly)

// Define once in Document
numbering: {
  config: [
    { reference: "bullets", levels: [{ level: 0, format: LevelFormat.BULLET, text: "•",
        alignment: AlignmentType.LEFT,
        style: { paragraph: { indent: { left: 720, hanging: 360 } } } }] },
    { reference: "steps",   levels: [{ level: 0, format: LevelFormat.DECIMAL, text: "%1.",
        alignment: AlignmentType.LEFT,
        style: { paragraph: { indent: { left: 720, hanging: 360 } } } }] },
  ]
}

// Use on paragraphs
new Paragraph({ numbering: { reference: "bullets", level: 0 }, children: [...] })

Use a separate reference for bullets inside table cells (avoids numbering continuation issues):

{ reference: "cell-bullets", levels: [{ level: 0, format: LevelFormat.BULLET, text: "•",
    alignment: AlignmentType.LEFT,
    style: { paragraph: { indent: { left: 360, hanging: 180 } } } }] }

Tables (Dual Widths Required)

Both columnWidths on the table AND width on each cell. They must match. Always use WidthType.DXA - never WidthType.PERCENTAGE (breaks in Google Docs). Always use ShadingType.CLEAR - never SOLID (causes black cell backgrounds).

const border = { style: BorderStyle.SINGLE, size: 4, color: "CCCCCC" };
const borders = { top: border, bottom: border, left: border, right: border };
const col1 = 5040, col2 = 5040; // must sum to content width (10080)

new Table({
  width: { size: 10080, type: WidthType.DXA },
  columnWidths: [col1, col2],
  rows: [new TableRow({ children: [
    new TableCell({
      borders,
      width: { size: col1, type: WidthType.DXA },
      shading: { fill: "F0F0F0", type: ShadingType.CLEAR },
      margins: { top: 80, bottom: 80, left: 120, right: 120 },
      children: [new Paragraph({ children: [new TextRun("Cell content")] })]
    }),
  ]})]
})

Screenshot Placeholder

For documents that will have screenshots inserted manually:

function screenshotBox(description) {
  const br = { style: BorderStyle.SINGLE, size: 8, color: "999999" };
  const borders = { top: br, bottom: br, left: br, right: br };
  return new Table({
    width: { size: 10080, type: WidthType.DXA },
    columnWidths: [10080],
    rows: [new TableRow({ children: [new TableCell({
      borders,
      width: { size: 10080, type: WidthType.DXA },
      shading: { fill: "DEDEDE", type: ShadingType.CLEAR },
      margins: { top: 280, bottom: 280, left: 280, right: 280 },
      verticalAlign: VerticalAlign.CENTER,
      children: [
        new Paragraph({ alignment: AlignmentType.CENTER, spacing: { before: 40, after: 60 },
          children: [new TextRun({ text: "[ INSERT SCREENSHOT ]", font: "Arial",
            size: 20, bold: true, color: "666666" })] }),
        new Paragraph({ alignment: AlignmentType.CENTER,
          children: [new TextRun({ text: description, font: "Arial",
            size: 18, italics: true, color: "666666" })] })
      ]
    })})]
  });
}

Callout Box

Coloured border box with a bold title and bulleted lines:

function callout(title, lines, fill, borderColor) {
  const br = { style: BorderStyle.SINGLE, size: 14, color: borderColor };
  const borders = { top: br, bottom: br, left: br, right: br };
  return new Table({
    width: { size: 10080, type: WidthType.DXA },
    columnWidths: [10080],
    rows: [new TableRow({ children: [new TableCell({
      borders,
      width: { size: 10080, type: WidthType.DXA },
      shading: { fill, type: ShadingType.CLEAR },
      margins: { top: 120, bottom: 120, left: 240, right: 240 },
      children: [
        new Paragraph({ spacing: { before: 40, after: 80 },
          children: [new TextRun({ text: title, font: "Arial", size: 22, bold: true, color: "404040" })] }),
        ...lines.map(line => new Paragraph({
          numbering: { reference: "cell-bullets", level: 0 },
          spacing: { before: 40, after: 40 },
          children: [new TextRun({ text: line, font: "Arial", size: 22, color: "404040" })]
        }))
      ]
    })})]
  });
}
// Usage: callout("What to ask:", ["Question one", "Question two"], "FFF2CC", "FFC000")

Single-Cell Table Helper Pattern

Single-cell tables (code blocks, callout boxes, prompt boxes) follow this structure. The closing sequence is the most common source of syntax errors — get it wrong and Node throws Unexpected token '}'.

return new Table({
  width: { size: CW, type: WidthType.DXA }, columnWidths: [CW],
  rows: [new TableRow({ children: [new TableCell({   // opens: rows[, TableRow{, children[, TableCell{
    borders, width: { size: CW, type: WidthType.DXA },
    shading: { fill: "F4F4F4", type: ShadingType.CLEAR },
    margins: { top: 120, bottom: 120, left: 200, right: 200 },
    children: [/* paragraphs */]
  })]})   // closes: TableCell{, TableCell(, children[, TableRow{, TableRow(
  ]        // closes: rows[
  });      // closes: Table{, Table(
}

Closing sequence: } ) ] } ) then ] on next line, then });. Never write })})] — it skips the ] that closes children:[ and crashes at parse time.

Common Mistakes

MistakeFix
require('docx') fails after npm install -gInstall locally: cd Desktop && npm init -y && npm install docx
Black table cell backgroundsUse ShadingType.CLEAR not SOLID
Table renders incorrectlySet columnWidths on table AND width on each cell, both in DXA
WidthType.PERCENTAGE usedSwitch to WidthType.DXA - percentage breaks in Google Docs
PageBreak causes invalid XMLWrap it: new Paragraph({ children: [new PageBreak()] })
Bullet shows as literal textNever new TextRun("• item") - use numbering config
Em dashes (--) appear in WordDo not use -- or in content - rephrase the sentence instead
Validator crashes on WindowsKnown encoding bug in validate.py - open in Word instead
node_modules left on DesktopAlways run cleanup step after generating
SyntaxError: Unexpected token } in table helperMissing ] to close children:[ of TableRow before closing } of TableRow args — use the single-cell table pattern above

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.