agentleFS
sonichisonichi/sutando/skills/doc-ingest/SKILL.md

doc-ingest

Skill396 starsChanged 6 months agoMITView on GitHub

Extract readable text from document files — PDF, XLSX/CSV/TSV, DOCX, PPTX, and plain-text formats — so any task that arrives with an attachment can actually consume it. Prints the extracted text to stdout (default cap 200k chars per file, --max-chars 0 = uncapped). --json wraps each file's result in {"file", "kind", "ok", "text"|"error"} lines (JSONL) for programmatic callers. --csv switches tabular files to the compute-exact view (below). When the ask is quantitative over a tabular file — "how many …",…

1 other project uses a version of this.

Adopted by

Most recently taken up by

The file

We split this skill into the rules it gives an agent

2 rules. About 0 are common, 0 are distinctive, and 2 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈0

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 2

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    When the ask is quantitative over a tabular file — "how many …", "total …", "average …", "what percentage …", any filter/sum/count — do NOT …

    line 14
  2. Very specific:

    No caps does not mean no bounds — attachments are untrusted, so --csv carries a fail-closed compute budget: inputs over 32 MiB, renders …

    line 28

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

doc-ingest

Extract readable text from document files — PDF, XLSX/CSV/TSV, DOCX, PPTX, and plain-text formats — so any task that arrives with an attachment can actually consume it.

Usage:

python3 skills/doc-ingest/scripts/ingest.py <file> [<file> ...] [--json] [--csv] [--max-chars N]

Prints the extracted text to stdout (default cap 200k chars per file, --max-chars 0 = uncapped). --json wraps each file's result in {"file", "kind", "ok", "text"|"error"} lines (JSONL) for programmatic callers. --csv switches tabular files to the compute-exact view (below).

Quantitative questions: compute, don't read

When the ask is quantitative over a tabular file — "how many …", "total …", "average …", "what percentage …", any filter/sum/count — do NOT answer by reading the extracted markdown. Load the exact table and compute:

python3 skills/doc-ingest/scripts/ingest.py sheet.xlsx --csv   # exact, uncapped per-sheet CSV

then aggregate programmatically (pandas or stdlib csv), keeping a per-row breakdown so the result is auditable. Two exactness guarantees distinguish --csv from the reading view: no default row/char caps (a silently truncated table computes a silently wrong aggregate), and xlsx without openpyxl is refused with a clear error rather than served by the approximate zip-XML fallback (approximate cells are fine to read, not to compute with).

No caps does not mean no bounds — attachments are untrusted, so --csv carries a fail-closed compute budget: inputs over 32 MiB, renders over 64 MiB, or tables over the 1M-cell cap are refused with a loud error (never truncated). A caller that genuinely needs a bigger table passes the explicit --csv-no-budget override.

Why this is a rule and not a preference: on the GAIA file-attached benchmark subset (2026-07-30), switching solvers from reading extracted text to computing over the loaded table flipped 3/3 computable misses (multi-row Whyte-notation sums, filtered counts, parity logic) with no other change — 84.2% → 92.1%. The markdown view is for humans and summaries; numbers come from computation.

When to use

  • A bridge task carries [File attached: …] with a document the task needs read (report summarization, spreadsheet questions, contract review).
  • The agent-eval harness runs benchmark tasks that reference attached files.
  • Any script needs file-contents-as-text without caring about the format.

Not for:

  • Images — the agent reads images natively with the Read tool; the script says so and exits 3.
  • Audio — use skills/audio-transcribe (the script points there and exits 3).

Extraction matrix (best-available chain, graceful fallbacks)

FormatPrimaryFallback
.pdfpdftotext -layout (poppler)pypdf/fitz if importable, else a clear error naming the missing tool
.xlsx .xlsmopenpyxl (every sheet → markdown table, row-capped)dependency-free XML extraction from the zip
.csv .tsvstdlib csv → markdown table (row-capped)—
.docxpython-docx (paragraphs + tables)textutil -convert txt (macOS), else zip XML extraction
.pptxzip XML extraction (per-slide text, dependency-free)—
.zipmember manifest + recursive extraction of the first 20 supported members (flattened basenames — zip-slip safe)—
.txt .md .json .jsonl .xml .html code filesbounded streaming read (UTF-8, errors replaced)—
.rtf .doctextutil -convert txt (macOS)error naming the gap

Exit codes: 0 all files extracted · 1 at least one failed · 2 bad invocation · 3 file type is handled elsewhere (image/audio pointer printed).

Tabular rendering defaults to 500 rows per sheet (--max-rows). CSV and XLSX rows are consumed incrementally: only the rendered prefix is retained while the computed summary is updated over the stream. Hard shared safety budgets cap compressed/uncompressed table bytes, rows, cells, and cell text; exceeding one fails the file explicitly instead of risking unbounded attachment memory use. The dependency-free XLSX reader rejects sparse cell references before they can expand into a dense row beyond the remaining cell budget or Excel's column limit. Plain-text inputs are decoded in fixed-size chunks and retain only the --max-chars prefix (--max-chars 0 is the explicit uncapped mode). A display-truncation notice is appended whenever the rendered row cap fires, so a consumer never mistakes a prefix for the whole document.

Design notes

Pure stdlib + optional libraries probed at runtime — the skill works (with reduced format coverage) on a host with no extras installed, and never hard-depends on a library CI lacks. No network, no temp files, read-only on inputs.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.