AGENTS.md · git:20261015.1183c58 · 2026-10-15 · sha256 e53b60b153bf489b
AGENTS.md git:20261015.1183c58A
Immutable. This exact content never changes and is served at /api/v1/blob/e53b60b153bf489b.
# Document Skills Skills for creating, reading, and manipulating PDF, PPTX, XLSX, and DOCX files. > `CLAUDE.md` in this directory is a symlink to this file (`AGENTS.md`). ## Python - Always use `uv run` to execute Python scripts in these skills. - All directly-run scripts declare their dependencies via PEP 723 inline metadata — `uv run` resolves them automatically. (Library modules imported by those scripts inherit the runner's environment and need no header of their own.) No manual `pip install` needed. - When writing a new script, add a PEP 723 header: ```python # /// script # requires-python = ">=3.12" # dependencies = ["pypdf", "Pillow"] # /// ``` - Never run bare `pip install`. Never use the system Python (`/usr/bin/python3`). ### Python Packages | Package | PyPI name | Used by | Purpose | |---------|-----------|---------|---------| | pypdf | `pypdf` | pdf | PDF reading/writing, form fields, annotations | | pdf2image | `pdf2image` | pdf | PDF page to image conversion (requires poppler) | | Pillow | `Pillow` | pdf, pptx | Image processing, drawing, fonts | | pdfplumber | `pdfplumber` | pdf | Text and table extraction | | reportlab | `reportlab` | pdf | PDF creation from scratch | | pytesseract | `pytesseract` | pdf | OCR wrapper for Tesseract | | pypdfium2 | `pypdfium2` | pdf | PDF rendering using PDFium engine | | python-pptx | `python-pptx` | pptx | PowerPoint file manipulation | | markitdown | `markitdown[pptx]` | pptx | Extract PPTX text as Markdown | | openpyxl | `openpyxl` | xlsx | Excel file manipulation | | pandas | `pandas` | xlsx | Data analysis, table operations | | matplotlib | `matplotlib` | xlsx | Chart and visualization creation | | lxml | `lxml` | pptx, docx | XML processing and XSD schema validation | | defusedxml | `defusedxml` | pptx, docx | Secure XML parsing (XXE protection) | ## Node.js Each skill that needs Node packages has its own `package.json` and `node_modules/`. Run `npm install` in the skill directory once to set up. | Skill | Packages | |-------|----------| | pptx | `pptxgenjs` (pinned exactly: html2pptx repairs its XML output), `jszip`, `playwright-core` (drives the installed Google Chrome; it never downloads a browser), `sharp` (rasterizes SVG icons and gradients in agent-written scripts) | | docx | `docx` | pdf and xlsx do not use Node packages. ## System Tools (`brew` or `apt-get`) On macOS, `brew bundle` at the repo root installs everything below. The Brewfile keeps optional tools commented out and skips uv and node when they are already on the PATH. ### Required | Package | Install | Provides | Used by | |---------|---------|----------|---------| | poppler | `brew install poppler` | `pdftoppm`, `pdftotext`, `pdfimages` | pdf, pptx, docx | | LibreOffice | `brew install --cask libreoffice` | `soffice` | pptx, xlsx, docx | | pandoc | `brew install pandoc` | `pandoc` | docx | ### Optional | Package | Install | Provides | Used by | |---------|---------|----------|---------| | tesseract | `brew install tesseract` | `tesseract` | pdf | | tesseract-lang | `brew install tesseract-lang` | language packs | pdf | ## Skill Structure Each skill has: - `SKILL.md` — the prompt/instructions for the skill - `scripts/` — scripts the agent runs by absolute path (`uv run <skill>/scripts/...`) from the user's working directory - `package.json` — Node.js dependencies (docx, pptx only) - `ooxml/` — unpack, pack, validate and render tooling for Office XML (docx, pptx only) Each skill folder is the unit of distribution, so shared code is copied rather than linked. `docx/ooxml/` and `pptx/ooxml/` must stay identical, as must the three copies of `soffice.py` (in both `ooxml/scripts/` and `xlsx/scripts/`). Edit the docx copy, then sync: `rsync -a --delete --exclude __pycache__ docx/ooxml/ pptx/ooxml/ && cp docx/ooxml/scripts/soffice.py xlsx/scripts/`. A test enforces this. LibreOffice always runs through `soffice.py`, which gives every run a private, throwaway profile and a timeout. Never call `soffice` directly from a script: a shared profile collides with any LibreOffice window the user has open. ## Tests `tests/` runs every skill script through `uv run`, the way an agent does, against generated documents: ```bash uv run --with pytest --with openpyxl --with python-docx --with python-pptx --with Pillow --with pypdf --with reportlab pytest tests -q ``` Every bug fix comes with a test that fails on the old code. python-docx is used only to build test fixtures. GitHub runs the same suite on Ubuntu for every pull request and every push to master (`.github/workflows/tests.yml`).