Self-contained C# script runner for editing Office documents. Embeds Roslyn compiler + OpenXML SDK in a single executable — no .NET SDK required.
130 lines of code. 43 MB single file. Full OpenXML SDK access.
"AI can't reliably edit Office documents" is a tooling problem, not a capability problem.
| Tool | Problem |
|---|---|
| python-docx / openpyxl | Incomplete OpenXML spec coverage. Complex documents (multi-level lists, field codes, cross-references) always break. |
| officecli / CLI wrappers | Designers must anticipate every need. Miss something? You're stuck. (80K lines of C# to wrap what the SDK already exposes.) |
OpenXML SDK + dotnet run |
The SDK works perfectly — but requires a ~500 MB .NET SDK install. |
office-eval solves this by packaging the Roslyn compiler + OpenXML SDK into a single zero-dependency binary. Download, run, done.
Give agents a VM + API docs, not wrapped commands.
CLI wrappers try to predict what users need: --prop fill=FF0000, --type shape, --prop bold=true. But agents don't need human-friendly CLI syntax. Agents read API docs and write code — that's what they're best at.
CLI wrapper: human predicts commands → agent picks commands → execute
office-eval: agent reads API docs → agent writes code → VM executes
One approach scales linearly with the designer's imagination. The other scales with the SDK.
Download office-eval.exe from Releases (~43 MB, Windows x64).
Or build from source:
cd src/office-eval
dotnet publish -r win-x64 --self-contained \
-p:PublishSingleFile=true \
-p:IncludeAllContentForSelfExtract=true \
-p:EnableCompressionInSingleFile=true \
-o bin/publishGive your agent these instructions to set up office-eval:
git clone --recursive https://github.com/corvo007/officedit.git--recursive pulls the OpenXML SDK docs submodule.
Download the correct binary for the current platform from the latest release. Available builds:
| Platform | File |
|---|---|
| Windows x64 | office-eval-win-x64.exe |
| Windows ARM64 | office-eval-win-arm64.exe |
| Linux x64 | office-eval-linux-x64 |
| Linux ARM64 | office-eval-linux-arm64 |
| macOS x64 | office-eval-mac-x64 |
| macOS ARM64 | office-eval-mac-arm64 |
Use whatever download tool is available in the environment (curl, wget, gh, Invoke-WebRequest, browser, etc.). Place the binary somewhere on PATH or reference it by full path.
The agent should read docs/skill.md first — it contains:
- 3 inviolable rules (edit copies only, locate by paraId, verify after edit)
- Script templates for Word / Excel / PPT
- Navigation table pointing to examples, advanced operations, and pitfalls
docs/
├── skill.md ← Start here (~150 lines)
├── examples-basic.md ← 14 basic operation examples
├── examples-advanced.md ← 7 advanced examples (borders, SEQ fields, numbering...)
├── pitfalls.md ← Checklist + known pitfalls + compile errors
├── open-xml-docs/ ← Microsoft's official how-to guides
└── api-doc/ ← Full API reference (grep for class/property names)
office-eval -e "Console.WriteLine(\"office-eval is ready\");"# Run a script
office-eval script.csx -- document.docx arg2 arg3
# Inline execution
office-eval -e "Console.WriteLine(Args[0]);" -- document.docxScripts access arguments via Args (IList<string>), separated by --.
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
// List paragraphs with their IDs
var doc = WordprocessingDocument.Open(Args[0], false);
var body = doc.MainDocumentPart!.Document.Body!;
foreach (var para in body.Descendants<Paragraph>())
{
var id = para.ParagraphId?.Value ?? "(none)";
var text = string.Concat(para.Descendants<Text>().Select(t => t.Text));
if (!string.IsNullOrWhiteSpace(text))
Console.WriteLine($"[{id}] {text}");
}
doc.Dispose();More examples in examples/.
- System namespaces auto-imported:
System,System.IO,System.Linq,System.Collections.Generic,System.Text.RegularExpressions - OpenXML SDK assemblies pre-loaded. Add
usingfor the namespace you need:- Word:
using DocumentFormat.OpenXml.Wordprocessing; - Excel:
using DocumentFormat.OpenXml.Spreadsheet; - PPT:
using DocumentFormat.OpenXml.Presentation;+using Drawing = DocumentFormat.OpenXml.Drawing;
- Word:
#r "path/to/local.dll"for additional assemblies- Full .NET Runtime standard library available
- No
using var— Roslyn scripting mode parsesusingat line start as a namespace import directive. Usevar doc = ...; doc.Dispose();instead. - No runtime NuGet — packages can't be installed at runtime. The SDK and standard library cover all Office editing needs.
officedit/
├── src/office-eval/ # Source code (Program.cs + .csproj, ~130 lines)
├── examples/ # Example .csx scripts
├── docs/
│ ├── skill.md # Agent entry point (~150 lines): rules, templates, navigation
│ ├── examples-basic.md # 14 basic operation examples
│ ├── examples-advanced.md # 7 advanced operation examples (borders, subscript, SEQ fields, numbering)
│ ├── pitfalls.md # Workflow checklist + pitfall records + common errors
│ ├── open-xml-docs/ # Microsoft's official OpenXML SDK how-to guides (git clone)
│ ├── api-doc/ # XML API reference extracted from NuGet package
│ └── plans/ # Design documents
└── README.md
The doc system is layered — agents read only what they need:
| File | Lines | When to read |
|---|---|---|
skill.md |
~150 | Always — rules, templates, key concepts |
examples-basic.md |
~400 | Basic operations (replace, query, delete, read table/comments) |
examples-advanced.md |
~500 | Complex operations (borders, subscript, cross-Run, SEQ fields, numbering) |
pitfalls.md |
~170 | Before editing — checklist, known pitfalls, compile errors |
open-xml-docs/ |
— | On demand — Microsoft's how-to guides for operations not in examples |
api-doc/ |
— | On demand — grep for class/property names |
MIT