zhongkaifu/tensorsharp/documents

Claude Code and agent skill by zhongkaifu/tensorsharp

Trust tier 3
  • community
Source check pending

Checking that the SKILL.md file is still in the repository.

Read and write real documents on the device - PDF, XLSX, DOCX, PPTX and CSV. Turn a photo or picture into a PDF, generate a PDF report or a slide deck from structured input, build a spreadsheet whose formulas carry computed values, extract text and tables out of a PDF or an Office file, and compute sums, means and groupings over a CSV or XLSX. Use whenever the user asks to convert an image to a PDF, to analyse a document or a table, or to produce a report, deck, spreadsheet or Word document.

Install

npx vskill@latest install zhongkaifu/tensorsharp/documents

SKILL.md

Documents

Six scripts. Every one runs under the interpreter bundled in this app, with the packages that are already there: reportlab, pypdf, openpyxl, Pillow and defusedxml, plus the standard library. Nothing here needs the network, a child process, or a package the user has to install. python-pptx, python-docx and lxml are bundled too (see Limits) for the things these writers do not do.

Read Limits before promising the user anything. Two of them change what you should say in your answer.

Choosing a script

The user wantsRun
A photo or a picture turned into a PDFmake_pdf.py --image
A report, a memo, anything to print or share as a PDFmake_pdf.py --spec
A CSV turned into a spreadsheet, as it standsmake_xlsx.py --csv
A spreadsheet built from figures you computedmake_xlsx.py --spec
A slide deckmake_pptx.py
A Word documentmake_docx.py
Numbers out of a CSV or spreadsheetanalyze_table.py
Text or tables out of a document they gave youread_document.py
To check a file you producedvalidate_document.py

A typical request — "analyse this spreadsheet and make me a deck" — is analyze_table.py to get the numbers, then make_pptx.py with those numbers in the spec. Do not put a number in a document that you did not compute.

Starting from a CSV. Three different requests, three different answers, and picking the wrong one wastes the turn:

  • "Turn this CSV into a spreadsheet" — one command:

make_xlsx.py --csv sales.csv --out sales.xlsx. Do not build a spec by hand for this, and do not reach for analyze_table.py: it profiles columns and refuses --out on a workbook without --group-by, because a profile is not a table.

  • "Total the revenue in this CSV" — analyze_table.py, which computes it.

Add --total revenue to the command above if you want the workbook to carry the sum as a live formula as well.

  • "Make a PDF/deck/Word report of this CSV" — there is no one-shot for this,

because a report is a document you design rather than a table you convert. Read the file (read_document.py, or the shell), then write a spec whose table block holds those rows, then run make_pdf.py / make_pptx.py / make_docx.py. Put the real rows in the spec; do not summarise them away.

make_pdf.py — a PDF report, or a picture

python3 scripts/make_pdf.py --image photo.jpg --out photo.pdf
python3 scripts/make_pdf.py --image a.png --image b.png --out album.pdf --title Album
python3 scripts/make_pdf.py --spec spec.json --out report.pdf
python3 scripts/make_pdf.py --spec - --out report.pdf # spec on stdin

"Turn this photo into a PDF" is `--image`, and it is one command. Do not write a spec for it. The user's attached files are already in your working directory under the names you were told — pass that name straight to --image. Each picture gets a page of its own, scaled to fit with its proportions kept; --title adds a title page. Pass either --image or --spec, never both.

An iPhone photo is HEIC, and the interpreter here has no HEIC decoder. The app stages a .png beside it for exactly this reason — if you were told about both IMG_0004.heic and IMG_0004.png, the .png is the one to pass.

Writes the PDF, reopens it with pypdf, and prints JSON: file, bytes, pages, blocks, extractable_characters. Non-zero exit means it failed.

json
{
"title": "Q3 Revenue Review",
"subtitle": "Prepared on device",
"author": "TensorAgent",
"page_size": "letter",
"landscape": false,
"margin_in": 0.9,
"blocks": [
{ "type": "heading", "level": 1, "text": "Summary" },
{ "type": "paragraph", "text": "Revenue rose 18%.", "mono": false },
{ "type": "bullets", "items": ["South overtook East", "Costs flat"] },
{ "type": "numbers", "items": ["Load the CSV", "Group by region"] },
{ "type": "table",
"columns": ["Region", "Units", "Revenue"],
"rows": [["West", 120, 420.0], ["East", 200, 700.0]],
"column_widths": [2, 1, 1],
"zebra": true },
{ "type": "image", "path": "chart.png", "width_in": 5.0, "caption": "Figure 1." },
{ "type": "pagebreak" },
{ "type": "spacer", "height": 12 }
]
}

page_size is letter or a4. level is 1-3. Numeric table cells are right-aligned and thousands-separated automatically; the header row repeats when a table crosses a page. column_widths are relative, not absolute. An unknown block type is an error, not a skipped block.

There is no chart type. Draw one with Pillow into a .png and add it as an image block — that is what the image block is for.

make_xlsx.py — a workbook whose formulas show their numbers

python3 scripts/make_xlsx.py --csv sales.csv --out sales.xlsx
python3 scripts/make_xlsx.py --csv sales.csv --out sales.xlsx --total revenue
python3 scripts/make_xlsx.py --spec spec.json --out book.xlsx

--csv writes the file as it stands: the header becomes the columns, and a cell that reads as a number is stored as one, so the column can be summed. --sheet-name names the sheet (default: the file's own name), and --total COL adds a SUM row for that column — a real formula with its value cached, like every other formula here. It is repeatable. Everything below is about --spec, which is what you use when the figures are ones you computed rather than ones already in a file.

Read this part. A formula in an .xlsx is only text; the number a reader sees is the cached value left behind by the last application that saved the file. There is no Excel and no LibreOffice on this device, so nothing will recalculate the sheet after you write it. This script therefore evaluates every formula in Python and writes the value into the cell alongside the formula. The file also carries fullCalcOnLoad, so a real Excel recomputes everything anyway the moment the user opens it.

If a formula cannot be evaluated here, the cell gets the formula and no cached value, the script lists it under uncomputable_formulas, and it exits non-zero. Tell the user which cells those are; do not present the file as finished.

json
{
"sheets": [
{
"name": "Sales",
"columns": ["Region", "Units", "Price", "Revenue"],
"rows": [["West", 120, 3.5, null], ["East", 200, 3.5, null]],
"formulas": [
{ "range": "D2:D3", "formula": "=B{r}*C{r}" },
{ "cell": "D4", "formula": "=SUM(D2:D3)" },
{ "cell": "D5", "formula": "=ROUND(AVERAGE(D2:D3),2)" }
],
"number_formats": { "C": "#,##0.00", "D": "#,##0.00" },
"column_widths": { "A": 18 },
"freeze_header": true,
"auto_filter": true
}
]
}

range fills a block of cells from one entry: {r} becomes the row number and {c} the column letter. Header cells are styled, columns are sized to content, and a formula may refer to another formula cell in any order.

Functions the evaluator implements: SUM AVERAGE AVG MEDIAN MIN MAX COUNT COUNTA STDEV PRODUCT ABS SQRT INT ROUND POWER LEN UPPER LOWER TRIM CONCAT CONCATENATE IF AND OR NOT, the operators + - * / ^ % &, comparisons, and A1 ranges. It does not implement lookups (VLOOKUP, INDEX/MATCH), whole-column ranges (A:B), cross-sheet references or dates. Compute those in Python and write the result as a value.

make_pptx.py — a slide deck

python3 scripts/make_pptx.py --spec spec.json --out deck.pptx

16:9. Five slide layouts; every slide may have a title.

json
{
"title": "Q3 Revenue Review",
"author": "TensorAgent",
"slides": [
{ "layout": "title", "title": "Q3 Revenue Review", "subtitle": "Prepared on device" },
{ "layout": "bullets", "title": "What happened",
"bullets": ["South overtook East", { "text": "since 2023", "level": 1 }] },
{ "layout": "table", "title": "By region",
"columns": ["Region", "Revenue"], "rows": [["West", 420.0]] },
{ "layout": "image", "title": "Revenue", "image": "chart.png", "caption": "Figure 1." },
{ "layout": "text", "title": "Next", "text": "Recheck the North price." }
]
}

Bullets nest to three levels via level. The common tree form { "text": "Heading", "bullets": ["Detail"] } is also accepted and flattened to those levels, so do not rewrite an otherwise-correct spec just to expand it. A citation bullet may add date and url beside text; the writer joins all three visibly on the slide. Images are scaled to fit and centred. A table slide holds about 12 rows before it runs off the bottom — split a longer one across slides. notes is refused rather than silently dropped: speaker notes need a notesMaster part this writer does not build.

Prefer the canonical fields in the example. For compatibility with common deck specs, a slide with no layout is a bullets slide and its content array is an alias for bullets (do not provide both). An optional top-level sources array accepts URL strings or { "title": "...", "date": "...", "url": "..." } objects and becomes a final Sources slide. For compatibility, the same sources array on an individual slide is collected into that one final Sources slide; a slide whose only body is sources acts as that final-slide placeholder instead of creating an additional empty slide. A text slide that also contains a bullets array is unambiguously normalized to a bullets slide, with its introductory text retained first. Unknown fields, ambiguous aliases, and layouts without visible required content fail before a .pptx is written; the diagnostic names the slide and the fields accepted by its layout.

make_docx.py — a Word document

python3 scripts/make_docx.py --spec spec.json --out report.docx

Same block vocabulary as make_pdf.py, minus spacer:

json
{
"title": "Q3 Revenue Review",
"subtitle": "Prepared on device",
"author": "TensorAgent",
"blocks": [
{ "type": "heading", "level": 2, "text": "By region" },
{ "type": "paragraph", "text": "Revenue rose 18%.", "bold": false, "italic": false, "align": "left" },
{ "type": "bullets", "items": ["Top level", { "text": "Nested", "level": 1 }] },
{ "type": "numbers", "items": ["First", "Second"] },
{ "type": "table", "columns": ["Region", "Revenue"], "rows": [["West", 420.0]] },
{ "type": "image", "path": "chart.png", "width_in": 5.0, "caption": "Figure 1." },
{ "type": "pagebreak" }
]
}

Real Word styles (Title, Heading 1-3, Caption, Table Grid) and real list numbering, so the document's outline and its lists behave as Word's own.

analyze_table.py — numbers out of a CSV or XLSX

python3 scripts/analyze_table.py sales.csv
python3 scripts/analyze_table.py sales.csv --group-by Region --sum Revenue --mean Price
python3 scripts/analyze_table.py book.xlsx --sheet Q3 --group-by Region --sum Revenue --out summary.xlsx
python3 scripts/analyze_table.py sales.csv --where "Units>=12" --where "Region=West" --sum Revenue --group-by Rep
OptionEffect
--sheet NAMEwhich sheet of an .xlsx (default: the first)
--delimiter CCSV delimiter (default: sniffed)
--where "Col=v"keep matching rows; = != > < >= <=; repeatable
--group-by COLaggregate per distinct value of this column
--sum COLtotal this column per group; repeatable
--mean COLaverage this column per group; repeatable
--out FILEalso write .json, .csv or .xlsx

With no --group-by it profiles every column: filled/empty counts, distinct values, and for numeric columns count, sum, mean, median, min, max and stdev; for text columns the five commonest values. JSON always goes to stdout.

$1,240.00, 1 240, 45% and (320) all read as numbers. A blank cell is not zero: it is left out of sums and means, and rows_dropped_not_a_number counts the rows an ordering filter could not judge. Say that number out loud if it is not zero — it usually is the finding.

This is the start of the file. Read the full SKILL.md on GitHub.

Security

  • Security scanPassed, 95 of 100Pattern checks on the skill's files.
  • Model reviewPassed

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

7-day trend score
5

Not refreshed yet.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/zhongkaifu/tensorsharp/documents/badge)](https://verified-skill.com/skills/zhongkaifu/tensorsharp/documents)

Something wrong with this skill or its page? Tell us.