@eigenpal/docx-editor-core/headless
Headless aggregate for Node.js scripts, CLI tools, and server-side processing. Same surface as the default `.` entry, named to make the "no DOM" intent explicit. Prefer the smaller subpaths (`./docx`, `./agent`, `./utils`, etc.) for new code — they tree-shake better.
Functions(98)
attemptSelectiveSave
Attempt a selective save — patch only changed paragraphs in document.xml. Also updates comments, headers/footers, and core properties so that all document parts stay in sync even when only paragraphs are patched.
Returns the saved ArrayBuffer, or null if selective save is not possible (caller should fall back to full repack).
declare function attemptSelectiveSave(doc: Document, originalBuffer: ArrayBuffer, options: SelectiveSaveOptions): Promise<ArrayBuffer | null>;blendColors
Blend two colors together
declare function blendColors(color1: ColorValue | undefined | null, color2: ColorValue | undefined | null, ratio: number, theme: Theme | null | undefined): string;buildExtendedSelectionContext
Build extended selection context with additional details
declare function buildExtendedSelectionContext(doc: Document, range: Range, options?: SelectionContextOptions): ExtendedSelectionContext;buildPatchedDocumentXml
Build a patched document.xml by splicing new paragraph XML into the original at the correct offsets. Only changed paragraphs are replaced; everything else is preserved byte-for-byte.
Returns null if any step fails.
declare function buildPatchedDocumentXml(originalXml: string, serializedXml: string, changedIds: Set<string>): string | null;buildSelectionContext
Build selection context for AI operations
declare function buildSelectionContext(doc: Document, range: Range, options?: SelectionContextOptions): SelectionContext;buildSelectionContextFromContext
Build selection context for AI operations
declare function buildSelectionContext$1(doc: Document, range: Range, options?: SelectionContextOptions$1): SelectionContext;colorsEqual
Check if two colors are equal
declare function colorsEqual(color1: ColorValue | undefined | null, color2: ColorValue | undefined | null, theme: Theme | null | undefined): boolean;comparePositions
Compare two positions Returns: -1 if a b, 0 if equal, 1 if a b
declare function comparePositions(a: Position, b: Position): -1 | 0 | 1;countCharacters
Count characters in text
declare function countCharacters(text: string, includeSpaces?: boolean): number;countWords
Count words in text
declare function countWords(text: string): number;createAgent
Create a DocumentAgent from a DOCX buffer
declare function createAgent(buffer: ArrayBuffer): Promise<DocumentAgent>;createAgentFromDocument
Create a DocumentAgent from a parsed Document
declare function createAgentFromDocument(document: Document): DocumentAgent;createCollapsedRange
Create a collapsed range (cursor) at a position
declare function createCollapsedRange(position: Position): Range;createCommand
Create a command with generated ID
declare function createCommand<T extends AgentCommand>(command: Omit<T, 'id'>): T;createDocumentWithText
Create a document with a single paragraph containing the given text
declare function createDocumentWithText(text: string, options?: Omit<CreateEmptyDocumentOptions, 'initialText'>): Document;createDocx
Create a new DOCX from a Document (without requiring original buffer)
declare function createDocx(doc: Document): Promise<ArrayBuffer>;createEmptyDocument
Create an empty document with a single paragraph
declare function createEmptyDocument(options?: CreateEmptyDocumentOptions): Document;```ts
// Create a blank document
const doc = createEmptyDocument();
// Create with custom margins
const doc = createEmptyDocument({
marginTop: 720, // 0.5 inch
marginBottom: 720,
});
// Create with initial text
const doc = createEmptyDocument({
initialText: 'Hello, World!'
});
```createPluginRegistrar
Create a plugin registration helper with options pre-configured
declare function createPluginRegistrar(options: PluginOptions): (plugin: CorePlugin) => PluginRegistrationResult;createRange
Create a range from two positions
declare function createRange(start: Position, end: Position): Range;createRgbColor
Create a ColorValue from RGB hex
declare function createRgbColor(hex: string): ColorValue;createTemplateProcessor
Create a template processor with preset options
declare function createTemplateProcessor(defaultOptions?: ProcessTemplateOptions): (buffer: ArrayBuffer, variables: Record<string, string>) => ArrayBuffer;createThemeColor
Create a ColorValue from theme color reference
declare function createThemeColor(themeColor: ThemeColorSlot, tint?: number, shade?: number): ColorValue;darkenColor
Darken a color by a percentage
declare function darkenColor(color: ColorValue | undefined | null, theme: Theme | null | undefined, percent: number): string;detectVariables
Detect all template variables in a document
declare function detectVariables(doc: Document): string[];detectVariablesDetailed
Detect variables with detailed information
declare function detectVariablesDetailed(doc: Document): VariableDetectionResult;detectVariablesInBody
Detect variables in document body
declare function detectVariablesInBody(body: DocumentBody): string[];detectVariablesInParagraph
Detect variables in a paragraph
declare function detectVariablesInParagraph(paragraph: Paragraph): string[];documentHasVariables
Check if document has any template variables
declare function documentHasVariables(doc: Document): boolean;emuToPixels
Convert EMUs to pixels (at 96 DPI)
1 inch = 914400 EMUs = 96 pixels Returns 0 for null/undefined/NaN inputs.
declare function emuToPixels(emu: number | undefined | null): number;emuToTwips
Convert EMUs to twips
declare function emuToTwips(emu: number): number;executeCommand
Execute an agent command on a document Returns a new document with the command applied (immutable)
Dispatch order: 1. Try plugin handlers first (allows plugins to override built-in commands) 2. Fall back to built-in handlers
declare function executeCommand(doc: Document, command: AgentCommand): Document;executeCommands
Execute multiple commands in sequence
declare function executeCommands(doc: Document, commands: AgentCommand[]): Document;extractVariablesFromText
Extract variable names from text
declare function extractVariablesFromText(text: string): string[];formatPx
Format a pixel value as CSS string
declare function formatPx(px: number): string;formatVariable
Format a variable name with braces (standard docxtemplater syntax)
declare function formatVariable(name: string): string;getActionDescription
Get action description
declare function getActionDescription(action: AIAction): string;getActionLabel
Get action label
declare function getActionLabel(action: AIAction): string;getAgentContext
Build agent context from a document
declare function getAgentContext(doc: Document, options?: AgentContextOptions): AgentContext;getBlockIndexForParagraph
Get block index for a paragraph index
declare function getBlockIndexForParagraph(body: DocumentBody, paragraphIndex: number): number;getBodyCharacterCount
Get character count from document body
declare function getBodyCharacterCount(body: DocumentBody): number;getBodyText
Get plain text from document body
declare function getBodyText(body: DocumentBody): string;getBodyWordCount
Get word count from document body
declare function getBodyWordCount(body: DocumentBody): number;getContrastingColor
Get contrasting text color for a background
declare function getContrastingColor(backgroundColor: ColorValue | undefined | null, theme: Theme | null | undefined): string;getDocumentSummary
Get a simple document summary for quick context
declare function getDocumentSummary(doc: Document): string;getFormattingAtPosition
Get formatting at a specific position in a paragraph
declare function getFormattingAtPosition(paragraph: Paragraph, offset: number): Partial<TextFormatting>;getHyperlinkAtPosition
Get hyperlink at position
declare function getHyperlinkAtPosition(paragraph: Paragraph, offset: number): Hyperlink | undefined;getHyperlinkText
Get plain text from a hyperlink
declare function getHyperlinkText(hyperlink: Hyperlink): string;getMissingVariables
Check if all required variables have values
declare function getMissingVariables(tags: string[], variables: Record<string, string>): string[];getParagraphAtIndex
Get paragraph at index from document body
declare function getParagraphAtIndex(body: DocumentBody, index: number): Paragraph | undefined;getParagraphs
Get all paragraphs from document body
declare function getParagraphs(body: DocumentBody): Paragraph[];getParagraphText
Get plain text from a paragraph
declare function getParagraphText(paragraph: Paragraph): string;getRunText
Get plain text from a run
declare function getRunText(run: Run): string;getSelectionFormattingSummary
Get formatting summary for a selection
declare function getSelectionFormattingSummary(doc: Document, range: Range): FormattingSummary;getTableText
Get plain text from a table
declare function getTableText(table: Table): string;getTextAfter
Get text after a position
declare function getTextAfter(paragraphs: Paragraph[], position: Position, maxChars: number): string;getTextBefore
Get text before a position
declare function getTextBefore(paragraphs: Paragraph[], position: Position, maxChars: number): string;halfPointsToPixels
Convert half-points to pixels (at 96 DPI)
Half-points are commonly used for font sizes in OOXML (w:sz).
declare function halfPointsToPixels(halfPoints: number): number;hasHyperlinks
Check if document body has hyperlinks
declare function hasHyperlinks(body: DocumentBody): boolean;hasImages
Check if document body has images
declare function hasImages(body: DocumentBody): boolean;hasTables
Check if document body has tables
declare function hasTables(body: DocumentBody): boolean;hasTemplateVariables
Check if text contains template variables
declare function hasTemplateVariables(text: string): boolean;Check if a color is effectively black
declare function isBlack(color: ColorValue | undefined | null, theme: Theme | null | undefined): boolean;isHeadingStyle
Check if style ID represents a heading
declare function isHeadingStyle(styleId?: string): boolean;isPositionInHyperlink
Check if position is within a hyperlink
declare function isPositionInHyperlink(paragraph: Paragraph, offset: number): boolean;isPositionInRange
Check if a position is within a range
declare function isPositionInRange(position: Position, range: Range): boolean;isValidVariableName
Check if a variable name is valid
declare function isValidVariableName(name: string): boolean;Check if a color is effectively white
declare function isWhite(color: ColorValue | undefined | null, theme: Theme | null | undefined): boolean;isZodSchema
Check if a schema is Zod-like
declare function isZodSchema(schema: unknown): schema is ZodSchemaLike;lightenColor
Lighten a color by a percentage
declare function lightenColor(color: ColorValue | undefined | null, theme: Theme | null | undefined, percent: number): string;parseColorString
Parse a color string (various formats) to ColorValue
declare function parseColorString(colorString: string | undefined): ColorValue | undefined;parseDocx
Parse a DOCX file into a complete Document model
declare function parseDocx(input: DocxInput, options?: ParseOptions): Promise<Document>;parseHeadingLevel
Parse heading level from style ID
declare function parseHeadingLevel(styleId?: string): number | undefined;parseVariable
Parse a variable string to get the name
declare function parseVariable(variable: string): string | null;pixelsToEmu
Convert pixels to EMUs. EMU coordinates in OOXML are integer-typed (xs:long); rounding here keeps floating-point drift (e.g. 52 px → 495299.99999999994) out of the document.
declare function pixelsToEmu(px: number): number;pixelsToTwips
Convert pixels to twips
declare function pixelsToTwips(px: number): number;pointsToPixels
Convert points to pixels (at 96 DPI)
1 inch = 72 points = 96 pixels → 1 point = 96/72 pixels = 4/3 pixels
declare function pointsToPixels(points: number): number;previewTemplate
Preview what the document will look like after processing Returns the document text with variables replaced (for preview purposes)
declare function previewTemplate(buffer: ArrayBuffer, variables: Record<string, string>): string;processTemplate
Process a DOCX template with variable substitution
declare function processTemplate(buffer: ArrayBuffer, variables: Record<string, string>, options?: ProcessTemplateOptions): ArrayBuffer;processTemplateAdvanced
Process template with conditional sections Supports #if, #unless, #each loops
declare function processTemplateAdvanced(buffer: ArrayBuffer, data: Record<string, unknown>, options?: ProcessTemplateOptions): ArrayBuffer;processTemplateAsBlob
Process template and return as Blob
declare function processTemplateAsBlob(buffer: ArrayBuffer, variables: Record<string, string>, options?: ProcessTemplateOptions): Blob;processTemplateDetailed
Process template with detailed result
declare function processTemplateDetailed(buffer: ArrayBuffer, variables: Record<string, string>, options?: ProcessTemplateOptions): ProcessTemplateResult;registerPlugins
Register multiple plugins at once
declare function registerPlugins(plugins: CorePlugin[], options?: PluginOptions): PluginRegistrationResult[];removeVariables
Replace all variables in text with a placeholder
declare function removeVariables(text: string, placeholder?: string): string;repackDocx
Repack a Document into a valid DOCX file
declare function repackDocx(doc: Document, options?: RepackOptions): Promise<ArrayBuffer>;replaceVariables
Replace variables in text with values
declare function replaceVariables(text: string, values: Record<string, string>): string;resolveColor
Resolve a ColorValue to a CSS color string
declare function resolveColor(color: ColorValue | undefined | null, theme: Theme | null | undefined, defaultColor?: string): string;resolveHighlightColor
Resolve a highlight color name to CSS
declare function resolveHighlightColor(highlight: string | undefined): string;resolveShadingColor
Resolve a shading fill or pattern color to CSS
declare function resolveShadingColor(color: ColorValue | undefined | null, theme: Theme | null | undefined): string;sanitizeVariableName
Sanitize a variable name
declare function sanitizeVariableName(name: string): string;serializeDocumentBody
Serialize a DocumentBody to document.xml body content
declare function serializeDocumentBody(body: DocumentBody): string;serializeDocx
Serialize a complete Document to valid document.xml
declare function serializeDocument(doc: Document): string;serializeSectionProperties
Serialize section properties (w:sectPr)
declare function serializeSectionProperties(props: SectionProperties | undefined): string;twipsToEmu
Convert twips to EMUs
declare function twipsToEmu(twips: number): number;twipsToPixels
Convert twips to pixels (at 96 DPI)
1 inch = 1440 twips = 96 pixels → 1 twip = 96/1440 pixels = 1/15 pixels
declare function twipsToPixels(twips: number): number;updateMultipleFiles
Update multiple files in a DOCX buffer
declare function updateMultipleFiles(originalBuffer: ArrayBuffer, updates: Map<string, string | ArrayBuffer>, options?: RepackOptions): Promise<ArrayBuffer>;validatePatchSafety
Validate that a selective patch can be safely applied.
Checks: - All changed paraIds exist in original XML (exactly once) - All changed paraIds exist in serialized XML (exactly once) - Paragraph count matches between original and serialized
declare function validatePatchSafety(originalXml: string, serializedXml: string, changedIds: Set<string>): PatchValidationResult;validateTemplate
Validate that a document is a valid docxtemplater template
declare function validateTemplate(buffer: ArrayBuffer): {
valid: boolean;
errors: TemplateError[];
tags: string[];
};Classes(2)
DocumentAgent
DocumentAgent provides a fluent API for document manipulation
declare class DocumentAgent```ts
const agent = new DocumentAgent(buffer);
// Read operations
const text = agent.getText();
const wordCount = agent.getWordCount();
const variables = agent.getVariables();
// Write operations (returns new agent)
const newAgent = agent
.insertText({ paragraphIndex: 0, offset: 0 }, 'Hello ', { formatting: { bold: true } })
.applyStyle({ paragraphIndex: 0, offset: 0 }, { paragraphIndex: 0, offset: 5 }, 'Heading1');
// Export
const newBuffer = await newAgent.toBuffer();
```| Member | Type | Summary |
|---|---|---|
| (constructor) | — | Create a new DocumentAgent |
| applyFormatting | — | Apply text formatting to a range |
| applyParagraphFormatting | — | Apply paragraph formatting |
| applyStyle | — | Apply a named style to a paragraph |
| applyVariables | — | Apply all pending template variables |
| clearPendingVariables | — | Clear pending variables |
| deleteRange | — | Delete text in a range |
| executeCommands | — | Execute multiple commands in sequence |
| fromBuffer | — | Create a DocumentAgent from a DOCX buffer (async) |
| fromDocument | — | Create a DocumentAgent from a Document object |
| getAgentContext | — | Get document context for AI agents |
| getCharacterCount | — | Get character count |
| getDocument | — | Get the underlying document |
| getFormattedText | — | Get formatted text segments |
| getPageCount | — | Get approximate page count |
| getParagraphCount | — | Get paragraph count |
| getPendingVariables | — | Get pending variable values |
| getStyles | — | Get available styles from the document |
| getTableCount | — | Get table count |
| getText | — | Get plain text content of the document |
| getVariables | — | Get detected template variables |
| getWordCount | — | Get word count |
| insertHyperlink | — | Insert a hyperlink |
| insertImage | — | Insert an image at a position |
| insertParagraphBreak | — | Insert a paragraph break |
| insertTable | — | Insert a table at a position |
| insertText | — | Insert text at a position |
| mergeParagraphs | — | Merge consecutive paragraphs |
| removeHyperlink | — | Remove a hyperlink but keep the text |
| replaceRange | — | Replace text in a range |
| setVariable | — | Set a template variable value |
| setVariables | — | Set multiple template variables |
| toBlob | — | Export document to Blob |
| toBuffer | — | Export document to DOCX ArrayBuffer |
PluginRegistry
Plugin Registry - manages core plugins
declare class PluginRegistry```ts
import { pluginRegistry, docxtemplaterPlugin } from '@eigenpal/docx-editor/core-plugins';
// Register plugins
pluginRegistry.register(docxtemplaterPlugin);
// Get all MCP tools for MCP server
const tools = pluginRegistry.getMcpTools();
// Get command handler for executor
const handler = pluginRegistry.getCommandHandler('insertTemplateVariable');
```| Member | Type | Summary |
|---|---|---|
| addEventListener | — | Add an event listener |
| clear | — | Clear all registered plugins |
| get | — | Get a registered plugin by ID |
| getAll | — | Get all registered plugins |
| getCommandHandler | — | Get a command handler for a command type |
| getCommandTypes | — | Get all registered command types |
| getDebugInfo | — | Get registry state for debugging |
| getMcpTool | — | Get an MCP tool by name |
| getMcpTools | — | Get all MCP tools from all registered plugins |
| getMcpToolsForPlugin | — | Get MCP tools from a specific plugin |
| has | — | Check if a plugin is registered |
| hasCommandHandler | — | Check if a command type has a handler |
| register | — | Register a plugin |
| removeEventListener | — | Remove an event listener |
| size | number | Get number of registered plugins |
| unregister | — | Unregister a plugin |
Interfaces(81)
AgentContext
Document context for AI agents
interface AgentContext| Member | Type | Summary |
|---|---|---|
| availableStyles | StyleInfo[] | Available styles |
| characterCount | number | Total character count |
| hasHyperlinks | boolean | Has hyperlinks |
| hasImages | boolean | Has images |
| hasTables | boolean | Has tables |
| language? | string | Document language |
| outline | ParagraphOutline[] | Content outline (first N chars per paragraph) |
| paragraphCount | number | Total paragraph count |
| sections | SectionInfo[] | Document sections info |
| variableCount | number | Variable count |
| variables | string[] | Detected template variables |
| wordCount | number | Total word count (approximate) |
AgentContextOptions
Options for building agent context
interface AgentContextOptions| Member | Type | Summary |
|---|---|---|
| includeFormatting? | boolean | Include detailed formatting info (default: false) |
| includeTableContent? | boolean | Include table content in context (default: false) |
| maxOutlineParagraphs? | number | Maximum paragraphs to include in outline (default: 50) |
| outlineMaxChars? | number | Maximum characters per paragraph in outline (default: 100) |
AgentResponse
Response from an agent action
interface AgentResponse| Member | Type | Summary |
|---|---|---|
| commands? | AgentCommand[] | Commands to execute |
| error? | string | Error message if failed |
| metadata? | Record<string, unknown> | Metadata about the response |
| newContent? | AgentContent[] | New formatted content |
| newText? | string | New text to insert (for rewrite/expand/etc.) |
| success | boolean | Success status |
| warnings? | string[] | Warning messages |
AIActionRequest
AI action request
interface AIActionRequest| Member | Type | Summary |
|---|---|---|
| action | AIAction | Action type |
| context | SelectionContext | Selection context |
| customPrompt? | string | Custom prompt (for 'custom' action) |
| options? | Record<string, unknown> | Additional options |
| targetLanguage? | string | Target language (for 'translate' action) |
ApplyStyleCommand
Apply a named style to a paragraph
interface ApplyStyleCommand extends BaseCommand| Member | Type | Summary |
|---|---|---|
| paragraphIndex | number | Paragraph index |
| styleId | string | Style ID to apply |
| type | 'applyStyle' |
ApplyVariablesCommand
Apply all template variables
interface ApplyVariablesCommand extends BaseCommand| Member | Type | Summary |
|---|---|---|
| type | 'applyVariables' | |
| values | Record<string, string> | Variable values |
CommandResult
Result of command execution
interface CommandResult| Member | Type | Summary |
|---|---|---|
| document | Document | The modified document |
| error? | string | Error message if failed |
| metadata? | Record<string, unknown> | Metadata about the operation |
| success | boolean | Whether the command succeeded |
Comment_2
A comment from `comments.xml` — the top-level entity for review comments and replies. `id` matches the inline `CommentRangeStart` / `CommentRangeEnd` markers that anchor it inside a paragraph; `parentId` threads replies under their parent; `done` reflects Word's "Resolve" state (`w15:done`).
interface Comment| Member | Type | Summary |
|---|---|---|
| author | string | Author name |
| content | Paragraph[] | Comment content (paragraphs) |
| date? | string | Date |
| done? | boolean | Whether the comment is resolved/done |
| id | number | Comment ID (matches commentRangeStart/End) |
| initials? | string | Author initials |
| parentId? | number | Parent comment ID (for replies) |
CommentRangeEnd
Comment range end marker in paragraph content
interface CommentRangeEnd| Member | Type | Summary |
|---|---|---|
| id | number | |
| type | 'commentRangeEnd' |
CommentRangeStart
Comment range start marker in paragraph content
interface CommentRangeStart| Member | Type | Summary |
|---|---|---|
| id | number | |
| type | 'commentRangeStart' |
ContextSelectionOptions
Options for building selection context
interface SelectionContextOptions$1| Member | Type | Summary |
|---|---|---|
| contextChars? | number | Characters of context before/after selection (default: 200) |
| includeSuggestions? | boolean | Include suggested actions (default: true) |
CorePlugin
Core plugin interface - headless, works in Node.js
Plugins can: - Register command handlers that DocumentAgent dispatches to - Declare MCP tools that the MCP server exposes to AI clients - Have optional initialization logic - Declare dependencies on other plugins
interface CorePlugin| Member | Type | Summary |
|---|---|---|
| commandHandlers? | Record<string, CommandHandler> | Command handlers this plugin provides. DocumentAgent dispatches commands to these handlers. |
| dependencies? | string[] | Dependencies on other plugins (by ID). The registry ensures dependencies are loaded first. |
| description? | string | Plugin description |
| destroy? | () => void | Promise<void> | Optional cleanup when plugin is unregistered. |
| id | string | Unique plugin identifier |
| initialize? | () => void | Promise<void> | Optional setup when plugin is registered. Called once during plugin registration. |
| mcpTools? | McpToolDefinition[] | MCP tools this plugin exposes. MCP server collects these from all plugins. |
| name | string | Human-readable plugin name |
| version? | string | Plugin version (semver) |
CreateEmptyDocumentOptions
Options for creating an empty document
interface CreateEmptyDocumentOptions| Member | Type | Summary |
|---|---|---|
| initialText? | string | Initial text content (default: empty string) |
| marginBottom? | number | Bottom margin in twips (default: 1440 = 1 inch) |
| marginLeft? | number | Left margin in twips (default: 1440 = 1 inch) |
| marginRight? | number | Right margin in twips (default: 1440 = 1 inch) |
| marginTop? | number | Top margin in twips (default: 1440 = 1 inch) |
| orientation? | 'portrait' | 'landscape' | Page orientation (default: 'portrait') |
| pageHeight? | number | Page height in twips (default: 15840 = 11 inches) |
| pageWidth? | number | Page width in twips (default: 12240 = 8.5 inches) |
DeleteTextCommand
Delete text in a range
interface DeleteTextCommand extends BaseCommand| Member | Type | Summary |
|---|---|---|
| range | Range | Range to delete |
| type | 'deleteText' |
Deletion
Deletion wrapper (w:del) — runs deleted by tracked changes
interface Deletion| Member | Type | Summary |
|---|---|---|
| content | (Run | Hyperlink)[] | Deleted content |
| info | TrackedChangeInfo | Tracked change metadata |
| type | 'deletion' |
Document_2
Top-level parsed DOCX document — the result of `parseDocx(buffer)`.
Wraps the unzipped DOCX package (`document.xml`, `styles.xml`, etc.), the original buffer for round-trip saves, and any template variables / parse warnings detected during ingestion.
interface Document```ts
import { parseDocx } from '@eigenpal/docx-editor-core/headless';
const doc = await parseDocx(buffer);
console.log(doc.package.document.content.length);
```| Member | Type | Summary |
|---|---|---|
| originalBuffer? | ArrayBuffer | Original DOCX buffer. Kept for round-trip saves that preserve untouched parts. |
| package | DocxPackage | Parsed DOCX package — body, styles, numbering, theme, media, headers/footers. |
| templateVariables? | string[] | Detected docxtemplater variables (e.g. `{name}`, `{address}`). Populated when the document is recognized as a template. |
| warnings? | string[] | Non-fatal parser diagnostics — malformed parts, unsupported features, fallbacks. |
DocumentBody
Document body (`w:body`) — the editable content of the document.
Contains the ordered block content (paragraphs and tables), the section layout chain derived from inline `sectPr` markers, the final `sectPr`, and any document-level comments. This is what most edit operations mutate; headers/footers/styles live elsewhere in the package.
interface DocumentBody| Member | Type | Summary |
|---|---|---|
| comments? | Comment[] | Comments from comments.xml |
| content | BlockContent[] | All content (paragraphs, tables) |
| finalSectionProperties? | SectionProperties | Final section properties (from body's sectPr) |
| sections? | Section[] | Sections (derived from sectPr in paragraphs and final sectPr) |
DocxPackage
Complete DOCX package structure
interface DocxPackage| Member | Type | Summary |
|---|---|---|
| document | DocumentBody | Document body |
| endnotes? | Endnote[] | Endnotes |
| fontTable? | FontTable | Font table |
| footers? | Map<string, HeaderFooter> | Footers by relationship ID |
| footnotes? | Footnote[] | Footnotes |
| headers? | Map<string, HeaderFooter> | Headers by relationship ID |
| media? | Map<string, MediaFile> | Media files |
| numbering? | NumberingDefinitions | Numbering definitions |
| properties? | {
title?: string;
subject?: string;
creator?: string;
keywords?: string;
description?: string;
lastModifiedBy?: string;
revision?: number;
created?: Date;
modified?: Date;
} | Document properties |
| relationships? | RelationshipMap | Document relationships |
| styles? | StyleDefinitions | Style definitions |
| theme? | Theme | Theme |
Endnote
Endnote (w:endnote)
interface Endnote| Member | Type | Summary |
|---|---|---|
| content | (Paragraph | Table)[] | Content. Per ECMA-376 §17.11.4 endnotes can hold the same blocks as the body — paragraphs and tables. See note on `Footnote.content`. |
| id | number | Endnote ID |
| noteType? | 'normal' | 'separator' | 'continuationSeparator' | 'continuationNotice' | Special endnote type |
| type | 'endnote' |
ExtendedSelectionContext
Extended selection context with additional details
interface ExtendedSelectionContext extends SelectionContext| Member | Type | Summary |
|---|---|---|
| characterCount? | number | Selection character count |
| contentType? | 'prose' | 'list' | 'heading' | 'table' | 'mixed' | Content type hints |
| detectedLanguage? | string | Language detection hint |
| documentSummary? | string | Document summary for additional context |
| isMultiParagraph? | boolean | Is selection multi-paragraph |
| paragraphIndices? | number[] | Selected paragraph indices |
| wordCount? | number | Selection word count |
Footnote
Footnote (w:footnote)
interface Footnote| Member | Type | Summary |
|---|---|---|
| content | (Paragraph | Table)[] | Content. Per ECMA-376 §17.11.10 footnotes can hold the same blocks as the body — paragraphs and tables. The parser previously only collected w:p children which silently dropped any w:tbl inside a footnote; widened to match HeaderFooter / TableCell shape so the body pipeline (toProseDoc → toFlowBlocks) can render them uniformly. |
| id | number | Footnote ID |
| noteType? | 'normal' | 'separator' | 'continuationSeparator' | 'continuationNotice' | Special footnote type |
| type | 'footnote' |
FormatParagraphCommand
Apply paragraph formatting
interface FormatParagraphCommand extends BaseCommand| Member | Type | Summary |
|---|---|---|
| formatting | Partial<ParagraphFormatting> | Formatting to apply |
| paragraphIndex | number | Paragraph index |
| type | 'formatParagraph' |
FormattedTextSegment
Formatted text segment
interface FormattedTextSegment| Member | Type | Summary |
|---|---|---|
| formatting? | TextFormatting | Applied formatting |
| hyperlinkUrl? | string | Hyperlink URL if applicable |
| isHyperlink? | boolean | Is part of a hyperlink |
| text | string | Text content |
FormatTextCommand
Apply formatting to a range
interface FormatTextCommand extends BaseCommand| Member | Type | Summary |
|---|---|---|
| formatting | Partial<TextFormatting> | Formatting to apply |
| range | Range | Range to format |
| type | 'formatText' |
FormattingSummary
Selection formatting summary
interface FormattingSummary| Member | Type | Summary |
|---|---|---|
| allFormatting | Partial<TextFormatting>[] | All formatting found |
| isConsistent | boolean | Is formatting consistent across selection |
| predominant | Partial<TextFormatting> | Predominant formatting |
Hyperlink
Hyperlink (`w:hyperlink`) — wraps runs in a clickable link. External targets resolve through the relationships part (`rId` → `href`); internal targets reference a `BookmarkStart` anchor by name.
interface Hyperlink| Member | Type | Summary |
|---|---|---|
| anchor? | string | Internal bookmark anchor |
| children | (Run | BookmarkStart | BookmarkEnd)[] | Child runs |
| docLocation? | string | Document location |
| history? | boolean | Link history tracking |
| href? | string | Resolved URL (from relationships) |
| rId? | string | Relationship ID for external link |
| target? | string | Target frame |
| tooltip? | string | Tooltip text |
| type | 'hyperlink' |
Image_2
Embedded image (`w:drawing` with an inline or anchored picture). Carries the relationship-id pointer to the binary in `word/media/`, its resolved data URL (`src`), display dimensions, optional crop / transform / wrap behaviors, and anchor positioning for floating images.
See ECMA-376 §20.4 (DrawingML wordprocessingDrawing).
interface Image| Member | Type | Summary |
|---|---|---|
| allowOverlap? | boolean | `wp:anchor allowOverlap` — when true (default), anchored objects may overlap; when false, Word repositions them to avoid collisions. We don't currently reposition; we round-trip the flag so saving preserves the author's intent. |
| alt? | string | Alt text for accessibility |
| crop? | ImageCrop | Source-image crop (fractional, OOXML `a:srcRect`). |
| decorative? | boolean | Whether this is a decorative image |
| effects? | {
brightness?: number;
contrast?: number;
saturation?: number;
} | Image effects |
| filename? | string | Original filename |
| hlinkHref? | string | Hyperlink URL for clickable image |
| id? | string | Unique ID |
| layoutInCell? | boolean | `wp:anchor layoutInCell` — when true (default), an anchored image inside a table cell is constrained to the cell. When false, the image escapes the cell into the page area. Round-tripped on save. |
| mimeType? | string | Image MIME type |
| opacity? | number | Opacity in [0, 1] (OOXML `a:alphaModFix amt`). Undefined = fully opaque. |
| originalSize? | ImageSize | Original size before any transforms |
| outline? | ShapeOutline | Image outline/border |
| padding? | ImagePadding | Padding around image |
| position? | ImagePosition | Position for floating images |
| rId | string | Relationship ID for the image data |
| size | ImageSize | Image size |
| src? | string | Resolved image data (base64 or blob URL) |
| title? | string | Title/description |
| transform? | ImageTransform | Image transformations |
| type | 'image' | |
| wrap | ImageWrap | Wrap settings |
InsertHyperlinkCommand
Insert a hyperlink at a range
interface InsertHyperlinkCommand extends BaseCommand| Member | Type | Summary |
|---|---|---|
| displayText? | string | Display text (replaces range text if provided) |
| range | Range | Range to make into a hyperlink |
| tooltip? | string | Tooltip |
| type | 'insertHyperlink' | |
| url | string | URL of the hyperlink |
InsertHyperlinkOptions
Options for inserting hyperlink
interface InsertHyperlinkOptions| Member | Type | Summary |
|---|---|---|
| displayText? | string | Display text (overrides selected text) |
| tooltip? | string | Tooltip on hover |
InsertImageCommand
Insert an image at a position
interface InsertImageCommand extends BaseCommand| Member | Type | Summary |
|---|---|---|
| alt? | string | Alt text |
| height? | number | Image height in pixels |
| position | Position | Position to insert at |
| src | string | Image source (base64 or URL) |
| type | 'insertImage' | |
| width? | number | Image width in pixels |
InsertImageOptions
Options for inserting image
interface InsertImageOptions| Member | Type | Summary |
|---|---|---|
| alt? | string | Alt text for accessibility |
| height? | number | Image height in pixels |
| width? | number | Image width in pixels |
Insertion
Insertion wrapper (w:ins) — runs inserted by tracked changes
interface Insertion| Member | Type | Summary |
|---|---|---|
| content | (Run | Hyperlink)[] | Inserted content |
| info | TrackedChangeInfo | Tracked change metadata |
| type | 'insertion' |
InsertTableCommand
Insert a table at a position
interface InsertTableCommand extends BaseCommand| Member | Type | Summary |
|---|---|---|
| columns | number | Number of columns |
| data? | string[][] | Optional table data |
| hasHeader? | boolean | Optional header row |
| position | Position | Position to insert at |
| rows | number | Number of rows |
| type | 'insertTable' |
InsertTableOptions
Options for inserting table
interface InsertTableOptions| Member | Type | Summary |
|---|---|---|
| data? | string[][] | Table data (2D array of strings) |
| hasHeader? | boolean | Whether first row is a header |
InsertTextCommand
Insert text at a position
interface InsertTextCommand extends BaseCommand| Member | Type | Summary |
|---|---|---|
| formatting? | TextFormatting | Optional formatting for the inserted text |
| position | Position | Position to insert at |
| text | string | Text to insert |
| type | 'insertText' |
InsertTextOptions
Options for inserting text
interface InsertTextOptions| Member | Type | Summary |
|---|---|---|
| formatting? | TextFormatting | Text formatting |
JsonSchema
JSON Schema definition (subset)
interface JsonSchema| Member | Type | Summary |
|---|---|---|
| $ref? | string | |
| additionalProperties? | boolean | JsonSchema | |
| allOf? | JsonSchema[] | |
| anyOf? | JsonSchema[] | |
| default? | unknown | |
| description? | string | |
| enum? | unknown[] | |
| format? | string | |
| items? | JsonSchema | |
| maximum? | number | |
| maxLength? | number | |
| minimum? | number | |
| minLength? | number | |
| oneOf? | JsonSchema[] | |
| pattern? | string | |
| properties? | Record<string, JsonSchema> | |
| required? | string[] | |
| type? | string | string[] |
ListLevel
One indentation level of an abstract numbering definition (`w:lvl`). Carries the number format, the marker template (`lvlText` — e.g. `"%1.%2."`), the level's paragraph properties (indent, hanging) and character properties (font, size, color for the marker itself).
`ilvl` ranges 0-8 in standard Word documents.
interface ListLevel| Member | Type | Summary |
|---|---|---|
| ilvl | number | Level index (0-8) |
| isLgl? | boolean | Is legal numbering style |
| legacy? | {
legacy?: boolean;
legacySpace?: number;
legacyIndent?: number;
} | Legacy settings |
| lvlJc? | 'left' | 'center' | 'right' | Justification |
| lvlRestart? | number | Restart numbering from higher level |
| lvlText | string | Level text (e.g., "%1." or "•") |
| numFmt | NumberFormat | Number format |
| pPr? | ParagraphFormatting | Paragraph properties for this level |
| rPr? | TextFormatting | Run properties for the number/bullet |
| start? | number | Starting number |
| suffix? | LevelSuffix | Suffix after number |
LoadedDocument
A loaded document in the session
interface LoadedDocument| Member | Type | Summary |
|---|---|---|
| buffer? | ArrayBuffer | Original buffer (for repacking) |
| document | Document | Parsed document |
| id | string | Document ID |
| lastModified | number | Last modified timestamp |
| source? | string | Source filename or path |
McpSession
MCP session state
Maintains state across tool calls within a session.
interface McpSession| Member | Type | Summary |
|---|---|---|
| data | Map<string, unknown> | Custom session data |
| documents | Map<string, LoadedDocument> | Loaded documents by ID |
| id | string | Session ID |
McpToolAnnotations
MCP tool annotations
interface McpToolAnnotations| Member | Type | Summary |
|---|---|---|
| category? | string | Tool category for organization |
| complexity? | 'low' | 'medium' | 'high' | Estimated cost/complexity |
| examples? | McpToolExample[] | Example usage |
| readOnly? | boolean | Whether this tool modifies the document |
McpToolContext
Context passed to MCP tool handlers
interface McpToolContext| Member | Type | Summary |
|---|---|---|
| document? | Document | Current document (if loaded) |
| documentBuffer? | ArrayBuffer | Document buffer (if loaded) |
| log | (message: string, data?: unknown) => void | Logger for debugging |
| session | McpSession | Session state |
McpToolDefinition
MCP tool definition
Describes a tool that can be called by AI clients through the MCP server.
interface McpToolDefinition| Member | Type | Summary |
|---|---|---|
| annotations? | McpToolAnnotations | Optional annotations for the tool |
| description | string | Human-readable description for AI |
| handler | McpToolHandler | Handler function for the tool. Receives validated input and returns a result. |
| inputSchema | JsonSchema | ZodSchemaLike | JSON Schema for tool input validation. Can be a Zod schema or plain JSON Schema object. |
| name | string | Tool name (used in MCP protocol) |
McpToolResult
MCP tool result
interface McpToolResult| Member | Type | Summary |
|---|---|---|
| content | McpToolContent[] | Result content |
| isError? | boolean | Whether this is an error result |
MoveFrom
Move-from wrapper (w:moveFrom) — content moved away from this position
interface MoveFrom| Member | Type | Summary |
|---|---|---|
| content | (Run | Hyperlink)[] | Moved content |
| info | TrackedChangeInfo | Tracked change metadata |
| type | 'moveFrom' |
MoveTo
Move-to wrapper (w:moveTo) — content moved into this position
interface MoveTo| Member | Type | Summary |
|---|---|---|
| content | (Run | Hyperlink)[] | Moved content |
| info | TrackedChangeInfo | Tracked change metadata |
| type | 'moveTo' |
NumberingDefinitions
Top-level numbering data from `numbering.xml` — the set of abstract templates and the per-document `NumberingInstance`s that reference them. Paragraphs reference a `numId` (instance), not an `abstractNumId` directly.
interface NumberingDefinitions| Member | Type | Summary |
|---|---|---|
| abstractNums | AbstractNumbering[] | Abstract numbering definitions |
| nums | NumberingInstance[] | Numbering instances |
Paragraph
Paragraph (`w:p`) — the primary block-level container in a Word document.
Every paragraph carries direct formatting (`formatting`), tracked property changes (`propertyChanges`), inline content (`content`), and optional list rendering / section break metadata. `paraId` is Word's stable identifier (`w14:paraId`) and is what `EditorBridge` and the agent toolkit use to address paragraphs.
See ECMA-376 §17.3.1.
interface Paragraph| Member | Type | Summary |
|---|---|---|
| content | ParagraphContent[] | Paragraph content |
| formatting? | ParagraphFormatting | Paragraph formatting |
| listRendering? | ListRendering | Computed list rendering (if this is a list item) |
| paraId? | string | Unique paragraph ID |
| propertyChanges? | ParagraphPropertyChange[] | Paragraph-level tracked property changes (w:pPrChange) |
| renderedPageBreakBefore? | boolean | Word's cached layout says this paragraph started on a new rendered page. |
| sectionProperties? | SectionProperties | Section properties (if this paragraph ends a section) |
| textId? | string | Text ID |
| type | 'paragraph' |
ParagraphContext
Paragraph context for selection
interface ParagraphContext| Member | Type | Summary |
|---|---|---|
| fullText | string | Full paragraph text |
| index | number | Paragraph index |
| style? | string | Paragraph style |
| wordCount | number | Word count |
ParagraphFormatting
Paragraph-level formatting (`w:pPr`) — alignment, indentation, spacing (before/after, line height), pagination flags (keepNext, keepLines, pageBreakBefore, widowControl), tabs, borders, shading, numbering reference, style reference, and frame/anchored-text properties.
Most fields mirror their ECMA-376 element names (see §17.3.1). Inheritance: direct formatting beats the linked style which beats document defaults.
interface ParagraphFormatting| Member | Type | Summary |
|---|---|---|
| afterAutospacing? | boolean | Auto space after (w:spacing/w:afterAutospacing) |
| alignment? | ParagraphAlignment | Paragraph alignment (w:jc) |
| beforeAutospacing? | boolean | Auto space before (w:spacing/w:beforeAutospacing) |
| bidi? | boolean | Text direction (w:bidi) |
| borders? | {
top?: BorderSpec;
bottom?: BorderSpec;
left?: BorderSpec;
right?: BorderSpec;
between?: BorderSpec;
bar?: BorderSpec;
} | Paragraph borders (w:pBdr) |
| contextualSpacing? | boolean | Contextual spacing — suppress space between paragraphs of the same style (w:contextualSpacing) |
| frame? | {
width?: number;
height?: number;
hAnchor?: 'text' | 'margin' | 'page';
vAnchor?: 'text' | 'margin' | 'page';
x?: number;
y?: number;
xAlign?: 'left' | 'center' | 'right' | 'inside' | 'outside';
yAlign?: 'top' | 'center' | 'bottom' | 'inside' | 'outside' | 'inline';
wrap?: 'around' | 'auto' | 'none' | 'notBeside' | 'through' | 'tight';
} | Text frame properties (w:framePr) |
| hangingIndent? | boolean | Whether first line is hanging indent |
| indentFirstLine? | number | First line indent in twips - positive for indent, negative for hanging (w:ind/w:firstLine or w:hanging) |
| indentLeft? | number | Left indent in twips (w:ind/w:left) |
| indentRight? | number | Right indent in twips (w:ind/w:right) |
| keepLines? | boolean | Keep lines together (w:keepLines) |
| keepNext? | boolean | Keep with next paragraph (w:keepNext) |
| lineSpacing? | number | Line spacing value (w:spacing/w:line) |
| lineSpacingRule? | LineSpacingRule | Line spacing rule (w:spacing/w:lineRule) |
| numPr? | {
numId?: number;
ilvl?: number;
} | Numbering properties (w:numPr) |
| outlineLevel? | number | Outline level 0-9 (w:outlineLvl) |
| pageBreakBefore? | boolean | Page break before (w:pageBreakBefore) |
| runProperties? | TextFormatting | Run properties to apply to all runs (w:rPr) |
| shading? | ShadingProperties | Paragraph shading (w:shd) |
| spaceAfter? | number | Spacing after in twips (w:spacing/w:after) |
| spaceBefore? | number | Spacing before in twips (w:spacing/w:before) |
| spacingExplicit? | SpacingExplicit | Per-side flags marking which `<w:spacing>` attrs came from this paragraph's own pPr (vs inherited). Word collapses style-inherited spacing on empty paragraphs but honors the explicit values. |
| styleId? | string | Paragraph style ID (w:pStyle) |
| suppressAutoHyphens? | boolean | Suppress auto hyphens (w:suppressAutoHyphens) |
| suppressLineNumbers? | boolean | Suppress line numbers (w:suppressLineNumbers) |
| tabs? | TabStop[] | Custom tab stops (w:tabs) |
| widowControl? | boolean | Widow/orphan control (w:widowControl) |
ParagraphOutline
Paragraph outline for context
interface ParagraphOutline| Member | Type | Summary |
|---|---|---|
| headingLevel? | number | Heading level (1-9) |
| index | number | Paragraph index |
| isEmpty? | boolean | Is empty paragraph |
| isHeading? | boolean | Is heading |
| isListItem? | boolean | Is list item |
| preview | string | First N characters |
| style? | string | Paragraph style |
PluginCommand
Extended command type for plugins
Plugins can define custom command types beyond the built-in AgentCommand types.
interface PluginCommand| Member | Type | Summary |
|---|---|---|
| (member-0) | — | Additional command-specific data |
| id? | string | Unique command ID (for undo tracking) |
| position? | Position | Position for positional commands |
| range? | Range | Range for range-based commands |
| type | string | Command type identifier |
PluginOptions
Plugin configuration options
interface PluginOptions| Member | Type | Summary |
|---|---|---|
| config? | Record<string, unknown> | Custom configuration |
| debug? | boolean | Enable debug logging |
PluginRegistrationResult
Result of plugin registration
interface PluginRegistrationResult| Member | Type | Summary |
|---|---|---|
| error? | string | Error message (if failed) |
| plugin? | CorePlugin | Registered plugin (if successful) |
| success | boolean | Whether registration succeeded |
| warnings? | string[] | Warning messages |
Position_2
Position within a document
interface Position| Member | Type | Summary |
|---|---|---|
| contentIndex? | number | Optional: Content index within paragraph (run, hyperlink, etc.) |
| offset | number | Offset within the paragraph in characters |
| paragraphIndex | number | Index of the paragraph (0-indexed) |
| sectionIndex? | number | Optional: Section index |
ProcessTemplateOptions
Options for template processing
interface ProcessTemplateOptions| Member | Type | Summary |
|---|---|---|
| delimiters? | {
start?: string;
end?: string;
} | Delimiter settings |
| linebreaks? | boolean | Line breaks: keep raw n or convert to w:br |
| nullGetter? | 'keep' | 'empty' | 'error' | How to handle undefined variables |
| parser? | (tag: string) => {
get: (scope: Record<string, unknown>) => unknown;
} | Custom parser for variable names |
ProcessTemplateResult
Result of template processing
interface ProcessTemplateResult| Member | Type | Summary |
|---|---|---|
| buffer | ArrayBuffer | The processed document buffer |
| replacedVariables | string[] | Variables that were found and replaced |
| unreplacedVariables | string[] | Variables that were not replaced (no value provided) |
| warnings | string[] | Any warnings during processing |
Range_2
Range within a document
interface Range| Member | Type | Summary |
|---|---|---|
| collapsed? | boolean | Whether the range is collapsed (cursor position) |
| end | Position | End position |
| start | Position | Start position |
Relationship
Relationship entry
interface Relationship| Member | Type | Summary |
|---|---|---|
| id | string | Relationship ID (e.g., "rId1") |
| target | string | Target path or URL |
| targetMode? | 'External' | 'Internal' | Target mode |
| type | RelationshipType | Relationship type URI |
ReplaceTextCommand
Replace text in a range
interface ReplaceTextCommand extends BaseCommand| Member | Type | Summary |
|---|---|---|
| formatting? | TextFormatting | Optional formatting for the new text |
| range | Range | Range to replace |
| text | string | Replacement text |
| type | 'replaceText' |
Run
A run (`w:r`) — a contiguous span of inline content sharing one set of character properties (bold, italic, font, color, etc.). Runs are the atomic unit of character formatting; toggling bold on a selection that spans different formatting creates new runs.
See ECMA-376 §17.3.2.
interface Run```ts
const run: Run = {
type: 'run',
formatting: { bold: true },
content: [{ type: 'text', text: 'Hello' }],
};
```| Member | Type | Summary |
|---|---|---|
| content | RunContent[] | Run content (text, tabs, breaks, etc.) |
| formatting? | TextFormatting | Text formatting properties |
| propertyChanges? | RunPropertyChange[] | Run-level tracked property changes (w:rPrChange) |
| type | 'run' |
SectionInfo
Section information
interface SectionInfo| Member | Type | Summary |
|---|---|---|
| hasFooter? | boolean | Has footer |
| hasHeader? | boolean | Has header |
| index | number | Section index |
| isLandscape? | boolean | Is landscape |
| pageSize? | {
width: number;
height: number;
} | Page size |
| paragraphCount | number | Number of paragraphs |
SectionProperties
Section properties (`w:sectPr`) — page geometry, margins, columns, header/footer references, and page numbering for one section of the document. Sections are introduced by inline `sectPr` markers on the terminating paragraph (`Paragraph.sectionProperties`) and the body's final `sectPr`.
All distance units are twips (1/20 of a point) on the wire. The layout engine converts to pixels.
See ECMA-376 §17.6.
interface SectionProperties| Member | Type | Summary |
|---|---|---|
| background? | {
color?: ColorValue;
themeColor?: ThemeColorSlot;
themeTint?: string;
themeShade?: string;
} | Page background |
| bidi? | boolean | Right-to-left section |
| columnCount? | number | Number of columns |
| columns? | Column[] | Individual column definitions |
| columnSpace? | number | Space between columns in twips |
| docGrid? | {
type?: 'default' | 'lines' | 'linesAndChars' | 'snapToChars';
linePitch?: number;
charSpace?: number;
} | Document grid |
| endnotePr? | EndnoteProperties | Endnote properties for this section |
| equalWidth? | boolean | Equal width columns |
| evenAndOddHeaders? | boolean | Different odd/even page headers/footers |
| footerDistance? | number | Footer distance from bottom in twips |
| footerReferences? | FooterReference[] | Footer references |
| footnotePr? | FootnoteProperties | Footnote properties for this section |
| gutter? | number | Gutter margin in twips |
| headerDistance? | number | Header distance from top in twips |
| headerReferences? | HeaderReference[] | Header references |
| lineNumbers? | {
start?: number;
countBy?: number;
distance?: number;
restart?: LineNumberRestart;
} | Line numbering settings |
| marginBottom? | number | Bottom margin in twips |
| marginLeft? | number | Left margin in twips |
| marginRight? | number | Right margin in twips |
| marginTop? | number | Top margin in twips |
| orientation? | PageOrientation | Page orientation |
| pageBorders? | {
top?: BorderSpec;
bottom?: BorderSpec;
left?: BorderSpec;
right?: BorderSpec;
display?: 'allPages' | 'firstPage' | 'notFirstPage';
offsetFrom?: 'page' | 'text';
zOrder?: 'front' | 'back';
} | Page borders |
| pageHeight? | number | Page height in twips |
| pageWidth? | number | Page width in twips |
| paperSrcFirst? | number | First page paper source |
| paperSrcOther? | number | Other pages paper source |
| sectionStart? | SectionStart | Section start type |
| separator? | boolean | Separator line between columns |
| titlePg? | boolean | Different first page header/footer |
| verticalAlign? | VerticalAlign | Vertical alignment of text |
SelectionContext
Context about the current selection
interface SelectionContext| Member | Type | Summary |
|---|---|---|
| formatting | Partial<TextFormatting> | Current formatting of selection |
| inHyperlink? | boolean | Is selection within a hyperlink |
| inTable? | boolean | Is selection within a table |
| paragraph | ParagraphContext | Paragraph containing selection |
| paragraphFormatting | Partial<ParagraphFormatting> | Current paragraph formatting |
| range | Range | Selection range |
| selectedText | string | Selected text |
| suggestedActions? | SuggestedAction[] | Suggested actions based on selection |
| textAfter | string | Text after selection (context) |
| textBefore | string | Text before selection (context) |
SelectionContextOptions
Options for building selection context
interface SelectionContextOptions| Member | Type | Summary |
|---|---|---|
| contextCharsAfter? | number | Characters of context after selection (default: 200) |
| contextCharsBefore? | number | Characters of context before selection (default: 200) |
| includeDocumentSummary? | boolean | Include document summary (default: true) |
| includeSuggestions? | boolean | Include suggested actions (default: true) |
| maxSuggestions? | number | Maximum suggested actions (default: 8) |
SetVariableCommand
Set template variable value
interface SetVariableCommand extends BaseCommand| Member | Type | Summary |
|---|---|---|
| name | string | Variable name |
| type | 'setVariable' | |
| value | string | Variable value |
Style
Style definition from `styles.xml` — a named, reusable bundle of paragraph and/or character formatting. Word's "Heading 1", "Normal", "Title", and "List Bullet" are styles; user-defined styles look the same. `basedOn` chains styles for inheritance; `link` pairs a paragraph style with a matching character style.
See ECMA-376 §17.7.4.
interface Style| Member | Type | Summary |
|---|---|---|
| basedOn? | string | Based on style ID |
| default? | boolean | Is default style |
| link? | string | Linked style (paragraph/character pair) |
| name? | string | Display name |
| next? | string | Next style after Enter (for paragraph styles) |
| personal? | boolean | Personal style (custom) |
| pPr? | ParagraphFormatting | Paragraph properties (for paragraph/table styles) |
| qFormat? | boolean | Quick format in gallery |
| rPr? | TextFormatting | Run properties |
| styleId | string | Style ID |
| tblPr? | TableFormatting | Table properties (for table styles) |
| tblStylePr? | Array<{
type: 'band1Horz' | 'band1Vert' | 'band2Horz' | 'band2Vert' | 'firstCol' | 'firstRow' | 'lastCol' | 'lastRow' | 'neCell' | 'nwCell' | 'seCell' | 'swCell';
pPr?: ParagraphFormatting;
rPr?: TextFormatting;
tblPr?: TableFormatting;
trPr?: TableRowFormatting;
tcPr?: TableCellFormatting;
}> | Conditional table style parts |
| tcPr? | TableCellFormatting | Table cell properties |
| trPr? | TableRowFormatting | Table row properties |
| type | StyleType | Style type |
| uiPriority? | number | UI sort priority |
| unhideWhenUsed? | boolean | Unhide when used |
StyleDefinitions
Style definitions from styles.xml
interface StyleDefinitions| Member | Type | Summary |
|---|---|---|
| docDefaults? | DocDefaults | Document defaults |
| latentStyles? | {
defLockedState?: boolean;
defUIPriority?: number;
defSemiHidden?: boolean;
defUnhideWhenUsed?: boolean;
defQFormat?: boolean;
count?: number;
} | Latent styles |
| styles | Style[] | Style definitions |
StyleInfo
Style information for context
interface StyleInfo| Member | Type | Summary |
|---|---|---|
| builtIn? | boolean | Is built-in style |
| id | string | Style ID |
| name | string | Display name |
| type | 'paragraph' | 'character' | 'table' | Style type |
SuggestedAction
Suggested action for context menu
interface SuggestedAction| Member | Type | Summary |
|---|---|---|
| description? | string | Description |
| icon? | string | Icon name |
| id | string | Action ID |
| label | string | Display label |
| priority? | number | Priority (higher = more prominent) |
Table
Table (`w:tbl`) — a block-level grid of rows × cells. Tables carry their own formatting layer (borders, shading, alignment, indent, floating placement) and an explicit column-width grid in twips. Tables can nest arbitrarily through `TableCell.content`.
See ECMA-376 §17.4.
interface Table| Member | Type | Summary |
|---|---|---|
| columnWidths? | number[] | Column widths in twips |
| formatting? | TableFormatting | Table formatting |
| propertyChanges? | TablePropertyChange[] | Table-level tracked property changes (w:tblPrChange) |
| rows | TableRow[] | Table rows |
| type | 'table' |
TableCell
Table cell (`w:tc`). Holds nested block content (paragraphs and nested tables), cell-level formatting (borders, shading, vertical merge), tracked property changes, and tracked structural changes for cell insert/delete/merge operations.
interface TableCell| Member | Type | Summary |
|---|---|---|
| content | (Paragraph | Table)[] | Cell content (paragraphs, tables, etc.) |
| formatting? | TableCellFormatting | Cell formatting |
| propertyChanges? | TableCellPropertyChange[] | Cell-level tracked property changes (w:tcPrChange) |
| structuralChange? | TableStructuralChangeInfo | Tracked structural changes (cell insert/delete/merge) |
| type | 'tableCell' |
TableRow
Table row (`w:tr`) — an ordered list of `TableCell` plus row-level formatting (height, repeated header, cantSplit) and tracked changes for inserts/deletes.
interface TableRow| Member | Type | Summary |
|---|---|---|
| cells | TableCell[] | Cells in this row |
| formatting? | TableRowFormatting | Row formatting |
| propertyChanges? | TableRowPropertyChange[] | Row-level tracked property changes (w:trPrChange) |
| structuralChange? | TableStructuralChangeInfo | Tracked structural changes (row insert/delete) |
| type | 'tableRow' |
TemplateError
Error details from template processing
interface TemplateError| Member | Type | Summary |
|---|---|---|
| message | string | Error message |
| originalError? | Error | Original error |
| type | 'parse' | 'render' | 'undefined' | 'unknown' | Error type |
| variable? | string | Variable name that caused the error (if applicable) |
TextContent
Plain text run content (`w:t`). `preserveSpace` mirrors the `xml:space="preserve"` attribute and matters for runs that begin or end with whitespace — without it, Word collapses leading/trailing spaces.
interface TextContent| Member | Type | Summary |
|---|---|---|
| preserveSpace? | boolean | Preserve whitespace (xml:space="preserve") |
| text | string | The text string |
| type | 'text' |
TextFormatting
Character-level formatting (`w:rPr`) — the full set of run properties Word supports: weight, slant, font, size, color, highlight, underline, strikethrough, vertical position, language, complex-script variants, spacing/kerning, emphasis marks, and more.
Most fields mirror their ECMA-376 element names (see §17.3.2). Missing keys inherit from the run's paragraph style → linked style → document defaults chain.
interface TextFormatting| Member | Type | Summary |
|---|---|---|
| allCaps? | boolean | All caps (w:caps) |
| bold? | boolean | Bold (w:b) |
| boldCs? | boolean | Bold complex script (w:bCs) |
| color? | ColorValue | Text color (w:color) |
| cs? | boolean | Complex script formatting (w:cs) |
| doubleStrike? | boolean | Double strikethrough (w:dstrike) |
| effect? | TextEffect | Text effect animation (w:effect) |
| emboss? | boolean | Emboss effect (w:emboss) |
| emphasisMark? | EmphasisMark | Emphasis mark (w:em) |
| fontFamily? | {
ascii?: string;
hAnsi?: string;
eastAsia?: string;
cs?: string;
asciiTheme?: 'majorAscii' | 'majorHAnsi' | 'majorEastAsia' | 'majorBidi' | 'minorAscii' | 'minorHAnsi' | 'minorEastAsia' | 'minorBidi';
hAnsiTheme?: string;
eastAsiaTheme?: string;
csTheme?: string;
} | Font family (w:rFonts) |
| fontSize? | number | Font size in half-points (w:sz) - e.g., 24 = 12pt |
| fontSizeCs? | number | Font size complex script (w:szCs) |
| highlight? | 'black' | 'blue' | 'cyan' | 'darkBlue' | 'darkCyan' | 'darkGray' | 'darkGreen' | 'darkMagenta' | 'darkRed' | 'darkYellow' | 'green' | 'lightGray' | 'magenta' | 'none' | 'red' | 'white' | 'yellow' | Highlight/background color (w:highlight) |
| imprint? | boolean | Imprint/engrave effect (w:imprint) |
| italic? | boolean | Italic (w:i) |
| italicCs? | boolean | Italic complex script (w:iCs) |
| kerning? | number | Kerning threshold in half-points (w:kern) |
| outline? | boolean | Outline effect (w:outline) |
| position? | number | Raised/lowered text position in half-points (w:position) |
| rtl? | boolean | Right-to-left text (w:rtl) |
| scale? | number | Horizontal text scale percentage (w:w) |
| shading? | ShadingProperties | Character shading (w:shd) |
| shadow? | boolean | Shadow effect (w:shadow) |
| smallCaps? | boolean | Small caps (w:smallCaps) |
| spacing? | number | Character spacing in twips (w:spacing) |
| strike? | boolean | Strikethrough (w:strike) |
| styleId? | string | Character style ID (w:rStyle) |
| underline? | {
style: UnderlineStyle;
color?: ColorValue;
} | Underline style and color (w:u) |
| vertAlign? | 'baseline' | 'superscript' | 'subscript' | Superscript/subscript (w:vertAlign) |
Theme
Theme (from theme1.xml)
interface Theme| Member | Type | Summary |
|---|---|---|
| colorScheme? | ThemeColorScheme | Color scheme |
| fontScheme? | ThemeFontScheme | Font scheme |
| formatScheme? | {
name?: string;
} | Format scheme (fills, lines, effects) - simplified |
| name? | string | Theme name |
TrackedChangeInfo
Tracked change metadata (w:ins, w:del attributes)
interface TrackedChangeInfo| Member | Type | Summary |
|---|---|---|
| author | string | Author who made the change |
| date? | string | Date of the change |
| id | number | Revision ID |
VariableDetectionResult
Result of variable detection
interface VariableDetectionResult| Member | Type | Summary |
|---|---|---|
| byLocation | {
body: string[];
headers: string[];
footers: string[];
footnotes: string[];
endnotes: string[];
textBoxes: string[];
} | Variables by location |
| occurrences | VariableOccurrence[] | Variable occurrences with positions |
| totalOccurrences | number | Total count of variable occurrences |
| variables | string[] | Unique variable names sorted alphabetically |
VariableOccurrence
A single variable occurrence with location info
interface VariableOccurrence| Member | Type | Summary |
|---|---|---|
| location | 'body' | 'header' | 'footer' | 'footnote' | 'endnote' | 'textBox' | Location type |
| name | string | Variable name (without braces) |
| paragraphIndex? | number | Paragraph index within location |
| sectionIndex? | number | Section index (for headers/footers) |
ZodSchemaLike
Zod-like schema interface for compatibility
interface ZodSchemaLike| Member | Type | Summary |
|---|---|---|
| _def? | unknown | |
| parse? | (data: unknown) => unknown | |
| safeParse? | (data: unknown) => {
success: boolean;
data?: unknown;
error?: unknown;
} |
Type aliases(11)
AgentCommand
Union of all command types
type AgentCommand = InsertTextCommand | ReplaceTextCommand | DeleteTextCommand | FormatTextCommand | FormatParagraphCommand | ApplyStyleCommand | InsertTableCommand | InsertImageCommand | InsertHyperlinkCommand | RemoveHyperlinkCommand | InsertParagraphBreakCommand | MergeParagraphsCommand | SplitParagraphCommand | SetVariableCommand | ApplyVariablesCommand;AIAction
AI action types for context menu
type AIAction = 'askAI' | 'rewrite' | 'expand' | 'summarize' | 'translate' | 'explain' | 'fixGrammar' | 'makeFormal' | 'makeCasual' | 'custom';BlockContent
Block-level content types
type BlockContent = Paragraph | Table | BlockSdt;CommandHandler
Command handler function type
Receives a document and a command, returns a modified document. Must be pure/immutable - always return a new document.
type CommandHandler = (doc: Document, command: PluginCommand) => Document;McpToolContent
MCP tool content types
type McpToolContent = {
type: 'text';
text: string;
} | {
type: 'image';
data: string;
mimeType: string;
} | {
type: 'resource';
uri: string;
mimeType?: string;
text?: string;
};McpToolHandler
MCP tool handler function
type McpToolHandler = (input: unknown, context: McpToolContext) => Promise<McpToolResult> | McpToolResult;ParagraphContent
Inline content that can appear inside a paragraph. Covers runs (text), hyperlinks, bookmarks, fields, structured document tags, comment range markers, tracked-change wrappers, and math equations. Every node in this union carries a `type` discriminator so consumers can narrow at runtime.
type ParagraphContent = Run | Hyperlink | BookmarkStart | BookmarkEnd | SimpleField | ComplexField | InlineSdt | CommentRangeStart | CommentRangeEnd | Insertion | Deletion | MoveFrom | MoveTo | MoveFromRangeStart | MoveFromRangeEnd | MoveToRangeStart | MoveToRangeEnd | MathEquation;PluginEvent
Plugin lifecycle events
type PluginEvent = {
type: 'registered';
plugin: CorePlugin;
} | {
type: 'unregistered';
pluginId: string;
} | {
type: 'error';
pluginId: string;
error: Error;
};PluginEventListener
Plugin event listener
type PluginEventListener = (event: PluginEvent) => void;RunContent
All possible run content types
type RunContent = TextContent | TabContent | BreakContent | SymbolContent | NoteReferenceContent | FieldCharContent | InstrTextContent | SoftHyphenContent | NoBreakHyphenContent | DrawingContent | ShapeContent;TrackedRunChange
Run-level tracked wrappers represented in WordprocessingML.
type TrackedRunChange = Insertion | Deletion | MoveFrom | MoveTo;Variables(3)
DEFAULT_AI_ACTIONS
Default AI actions for context menu
DEFAULT_AI_ACTIONS: AIAction[]pluginRegistry
Global plugin registry instance
Use this for registering plugins and accessing their capabilities.
pluginRegistry: PluginRegistryVERSION
eigenpal/docx-editor-core/headless
Headless aggregate for Node.js scripts, CLI tools, and server-side processing. Same surface as the default `.` entry, named to make the "no DOM" intent explicit. Prefer the smaller subpaths (`./docx`, `./agent`, `./utils`, etc.) for new code — they tree-shake better.
VERSION = "0.0.2"```ts
import { DocumentAgent, parseDocx, pluginRegistry } from '@eigenpal/docx-editor-core/headless';
import { docxtemplaterPlugin } from '@eigenpal/docx-editor-core/core-plugins';
// Register plugins
pluginRegistry.register(docxtemplaterPlugin);
// Load and manipulate document
const buffer = fs.readFileSync('template.docx');
const agent = await DocumentAgent.fromBuffer(buffer);
// Get document info
console.log('Word count:', agent.getWordCount());
console.log('Variables:', agent.getVariables());
// Edit document
const newAgent = agent
.insertText({ paragraphIndex: 0, offset: 0 }, 'Hello ')
.applyStyle(0, 'Heading1');
// Apply template variables
const finalAgent = await newAgent.applyVariables({
customer_name: 'Jane Doe',
date: '2024-02-15',
});
// Export
const output = await finalAgent.toBuffer();
fs.writeFileSync('output.docx', Buffer.from(output));
```