[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6KN0AAPDB8J4FCMB99NN5KG":3,"skill-same:01M6KN0AAPDB8J4FCMB99NN5KG":125},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":34,"publishedAt":56,"linkOnly":57,"markdownContent":58,"markdownBody":59,"frontMatter":60,"refName":61,"commitSha":62,"skillDirectory":63,"forksCount":64,"repositoryHtmlUrl":65,"repositoryHomepageUrl":66,"ownerHtmlUrl":67,"ownerBlogUrl":66,"ownerDescription":6,"updatedAt":68,"install":69,"resources":82},"01M6KN0AAPDB8J4FCMB99NN5KG","documents",null,"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.","zhongkaifu\u002FTensorSharp","zhongkaifu","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F3347714?v=4","01M6KMY6F1P2PMX13BA17R8ZHE","Zhongkai Fu","01M6KMY6KB2CA5J6MW78KVWVNB",677,"BSD-3-Clause","https:\u002F\u002Fgithub.com\u002Fzhongkaifu\u002FTensorSharp\u002Fblob\u002Fmain\u002FTensorAgent\u002Fskills\u002Fdocuments\u002FSKILL.md",[18,23,26,29],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000002","文档处理","SCENARIO","使用场景",{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000003","演示文稿",{"categoryNo":27,"categoryName":28,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000004","电子表格",{"categoryNo":30,"categoryName":31,"taxonomyType":32,"taxonomyTypeDesc":33},"01JBSEEDCAT000000000000034","行政与办公人员","PROFESSION","适用职业",[5,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55],"table","analyse","pdf report","tables","formulas","input","document","deck","use","write","read","docx","text","Word","spreadsheet","produce","generate","image","xlsx","pptx","PDF","2026-11-10 10:12:30",false,"---\nname: documents\ndescription: 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.\n---\n\n# Documents\n\nSix scripts. Every one runs under the interpreter bundled in this app, with the\npackages that are already there: reportlab, pypdf, openpyxl, Pillow and\ndefusedxml, plus the standard library. Nothing here needs the network, a child\nprocess, or a package the user has to install. python-pptx, python-docx and\nlxml are bundled too (see **Limits**) for the things these writers do not do.\n\nRead **Limits** before promising the user anything. Two of them change what you\nshould say in your answer.\n\n## Choosing a script\n\n| The user wants | Run |\n| --- | --- |\n| A photo or a picture turned into a PDF | `make_pdf.py --image` |\n| A report, a memo, anything to print or share as a PDF | `make_pdf.py --spec` |\n| A CSV turned into a spreadsheet, as it stands | `make_xlsx.py --csv` |\n| A spreadsheet built from figures you computed | `make_xlsx.py --spec` |\n| A slide deck | `make_pptx.py` |\n| A Word document | `make_docx.py` |\n| Numbers out of a CSV or spreadsheet | `analyze_table.py` |\n| Text or tables out of a document they gave you | `read_document.py` |\n| To check a file you produced | `validate_document.py` |\n\nA typical request — \"analyse this spreadsheet and make me a deck\" — is\n`analyze_table.py` to get the numbers, then `make_pptx.py` with those numbers in\nthe spec. Do not put a number in a document that you did not compute.\n\n**Starting from a CSV.** Three different requests, three different answers, and\npicking the wrong one wastes the turn:\n\n* *\"Turn this CSV into a spreadsheet\"* — one command:\n  `make_xlsx.py --csv sales.csv --out sales.xlsx`. Do not build a spec by hand\n  for this, and do not reach for `analyze_table.py`: it profiles columns and\n  refuses `--out` on a workbook without `--group-by`, because a profile is not\n  a table.\n* *\"Total the revenue in this CSV\"* — `analyze_table.py`, which computes it.\n  Add `--total revenue` to the command above if you want the workbook to carry\n  the sum as a live formula as well.\n* *\"Make a PDF\u002Fdeck\u002FWord report of this CSV\"* — there is no one-shot for this,\n  because a report is a document you design rather than a table you convert.\n  Read the file (`read_document.py`, or the shell), then write a spec whose\n  `table` block holds those rows, then run `make_pdf.py` \u002F `make_pptx.py` \u002F\n  `make_docx.py`. Put the real rows in the spec; do not summarise them away.\n\n## make_pdf.py — a PDF report, or a picture\n\n```\npython3 scripts\u002Fmake_pdf.py --image photo.jpg --out photo.pdf\npython3 scripts\u002Fmake_pdf.py --image a.png --image b.png --out album.pdf --title Album\npython3 scripts\u002Fmake_pdf.py --spec spec.json --out report.pdf\npython3 scripts\u002Fmake_pdf.py --spec - --out report.pdf     # spec on stdin\n```\n\n**\"Turn this photo into a PDF\" is `--image`, and it is one command.** Do not write\na spec for it. The user's attached files are already in your working directory\nunder the names you were told — pass that name straight to `--image`. Each picture\ngets a page of its own, scaled to fit with its proportions kept; `--title` adds a\ntitle page. Pass either `--image` or `--spec`, never both.\n\nAn iPhone photo is HEIC, and the interpreter here has no HEIC decoder. The app\nstages a `.png` beside it for exactly this reason — if you were told about both\n`IMG_0004.heic` and `IMG_0004.png`, the `.png` is the one to pass.\n\nWrites the PDF, reopens it with pypdf, and prints JSON: `file`, `bytes`,\n`pages`, `blocks`, `extractable_characters`. Non-zero exit means it failed.\n\n```json\n{\n  \"title\": \"Q3 Revenue Review\",\n  \"subtitle\": \"Prepared on device\",\n  \"author\": \"TensorAgent\",\n  \"page_size\": \"letter\",\n  \"landscape\": false,\n  \"margin_in\": 0.9,\n  \"blocks\": [\n    { \"type\": \"heading\", \"level\": 1, \"text\": \"Summary\" },\n    { \"type\": \"paragraph\", \"text\": \"Revenue rose 18%.\", \"mono\": false },\n    { \"type\": \"bullets\", \"items\": [\"South overtook East\", \"Costs flat\"] },\n    { \"type\": \"numbers\", \"items\": [\"Load the CSV\", \"Group by region\"] },\n    { \"type\": \"table\",\n      \"columns\": [\"Region\", \"Units\", \"Revenue\"],\n      \"rows\": [[\"West\", 120, 420.0], [\"East\", 200, 700.0]],\n      \"column_widths\": [2, 1, 1],\n      \"zebra\": true },\n    { \"type\": \"image\", \"path\": \"chart.png\", \"width_in\": 5.0, \"caption\": \"Figure 1.\" },\n    { \"type\": \"pagebreak\" },\n    { \"type\": \"spacer\", \"height\": 12 }\n  ]\n}\n```\n\n`page_size` is `letter` or `a4`. `level` is 1-3. Numeric table cells are\nright-aligned and thousands-separated automatically; the header row repeats when\na table crosses a page. `column_widths` are relative, not absolute. An unknown\nblock type is an error, not a skipped block.\n\nThere is no chart type. Draw one with Pillow into a `.png` and add it as an\n`image` block — that is what the image block is for.\n\n## make_xlsx.py — a workbook whose formulas show their numbers\n\n```\npython3 scripts\u002Fmake_xlsx.py --csv sales.csv --out sales.xlsx\npython3 scripts\u002Fmake_xlsx.py --csv sales.csv --out sales.xlsx --total revenue\npython3 scripts\u002Fmake_xlsx.py --spec spec.json --out book.xlsx\n```\n\n`--csv` writes the file as it stands: the header becomes the columns, and a\ncell that reads as a number is stored as one, so the column can be summed.\n`--sheet-name` names the sheet (default: the file's own name), and `--total COL`\nadds a SUM row for that column — a real formula with its value cached, like\nevery other formula here. It is repeatable. Everything below is about `--spec`,\nwhich is what you use when the figures are ones you computed rather than ones\nalready in a file.\n\n**Read this part.** A formula in an .xlsx is only text; the number a reader sees\nis the *cached* value left behind by the last application that saved the file.\nThere is no Excel and no LibreOffice on this device, so nothing will recalculate\nthe sheet after you write it. This script therefore evaluates every formula in\nPython and writes the value into the cell **alongside** the formula. The file\nalso carries `fullCalcOnLoad`, so a real Excel recomputes everything anyway the\nmoment the user opens it.\n\nIf a formula cannot be evaluated here, the cell gets the formula and **no**\ncached value, the script lists it under `uncomputable_formulas`, and it exits\nnon-zero. Tell the user which cells those are; do not present the file as\nfinished.\n\n```json\n{\n  \"sheets\": [\n    {\n      \"name\": \"Sales\",\n      \"columns\": [\"Region\", \"Units\", \"Price\", \"Revenue\"],\n      \"rows\": [[\"West\", 120, 3.5, null], [\"East\", 200, 3.5, null]],\n      \"formulas\": [\n        { \"range\": \"D2:D3\", \"formula\": \"=B{r}*C{r}\" },\n        { \"cell\": \"D4\", \"formula\": \"=SUM(D2:D3)\" },\n        { \"cell\": \"D5\", \"formula\": \"=ROUND(AVERAGE(D2:D3),2)\" }\n      ],\n      \"number_formats\": { \"C\": \"#,##0.00\", \"D\": \"#,##0.00\" },\n      \"column_widths\": { \"A\": 18 },\n      \"freeze_header\": true,\n      \"auto_filter\": true\n    }\n  ]\n}\n```\n\n`range` fills a block of cells from one entry: `{r}` becomes the row number and\n`{c}` the column letter. Header cells are styled, columns are sized to content,\nand a formula may refer to another formula cell in any order.\n\nFunctions the evaluator implements: `SUM AVERAGE AVG MEDIAN MIN MAX COUNT COUNTA\nSTDEV PRODUCT ABS SQRT INT ROUND POWER LEN UPPER LOWER TRIM CONCAT CONCATENATE IF\nAND OR NOT`, the operators `+ - * \u002F ^ % &`, comparisons, and A1 ranges. It does\n**not** implement lookups (`VLOOKUP`, `INDEX`\u002F`MATCH`), whole-column ranges\n(`A:B`), cross-sheet references or dates. Compute those in Python and write the\nresult as a value.\n\n## make_pptx.py — a slide deck\n\n```\npython3 scripts\u002Fmake_pptx.py --spec spec.json --out deck.pptx\n```\n\n16:9. Five slide layouts; every slide may have a `title`.\n\n```json\n{\n  \"title\": \"Q3 Revenue Review\",\n  \"author\": \"TensorAgent\",\n  \"slides\": [\n    { \"layout\": \"title\", \"title\": \"Q3 Revenue Review\", \"subtitle\": \"Prepared on device\" },\n    { \"layout\": \"bullets\", \"title\": \"What happened\",\n      \"bullets\": [\"South overtook East\", { \"text\": \"since 2023\", \"level\": 1 }] },\n    { \"layout\": \"table\", \"title\": \"By region\",\n      \"columns\": [\"Region\", \"Revenue\"], \"rows\": [[\"West\", 420.0]] },\n    { \"layout\": \"image\", \"title\": \"Revenue\", \"image\": \"chart.png\", \"caption\": \"Figure 1.\" },\n    { \"layout\": \"text\", \"title\": \"Next\", \"text\": \"Recheck the North price.\" }\n  ]\n}\n```\n\nBullets nest to three levels via `level`. The common tree form\n`{ \"text\": \"Heading\", \"bullets\": [\"Detail\"] }` is also accepted and flattened\nto those levels, so do not rewrite an otherwise-correct spec just to expand it.\nA citation bullet may add `date` and `url` beside `text`; the writer joins all\nthree visibly on the slide. Images are scaled to fit and centred.\nA table slide holds about 12 rows before it runs off the bottom — split a longer\none across slides. `notes` is refused rather than silently dropped: speaker\nnotes need a notesMaster part this writer does not build.\n\nPrefer the canonical fields in the example. For compatibility with common deck\nspecs, a slide with no `layout` is a bullets slide and its `content` array is an\nalias for `bullets` (do not provide both). An optional top-level `sources` array\naccepts URL strings or `{ \"title\": \"...\", \"date\": \"...\", \"url\": \"...\" }`\nobjects and becomes a final Sources slide. For compatibility, the same\n`sources` array on an individual slide is collected into that one final Sources\nslide; a slide whose only body is `sources` acts as that final-slide placeholder\ninstead of creating an additional empty slide. A `text` slide that also contains a `bullets` array is unambiguously\nnormalized to a bullets slide, with its introductory `text` retained first.\nUnknown fields, ambiguous aliases, and layouts without visible required content\nfail before a `.pptx` is written; the diagnostic names the slide and the fields\naccepted by its layout.\n\n## make_docx.py — a Word document\n\n```\npython3 scripts\u002Fmake_docx.py --spec spec.json --out report.docx\n```\n\nSame block vocabulary as `make_pdf.py`, minus `spacer`:\n\n```json\n{\n  \"title\": \"Q3 Revenue Review\",\n  \"subtitle\": \"Prepared on device\",\n  \"author\": \"TensorAgent\",\n  \"blocks\": [\n    { \"type\": \"heading\", \"level\": 2, \"text\": \"By region\" },\n    { \"type\": \"paragraph\", \"text\": \"Revenue rose 18%.\", \"bold\": false, \"italic\": false, \"align\": \"left\" },\n    { \"type\": \"bullets\", \"items\": [\"Top level\", { \"text\": \"Nested\", \"level\": 1 }] },\n    { \"type\": \"numbers\", \"items\": [\"First\", \"Second\"] },\n    { \"type\": \"table\", \"columns\": [\"Region\", \"Revenue\"], \"rows\": [[\"West\", 420.0]] },\n    { \"type\": \"image\", \"path\": \"chart.png\", \"width_in\": 5.0, \"caption\": \"Figure 1.\" },\n    { \"type\": \"pagebreak\" }\n  ]\n}\n```\n\nReal Word styles (Title, Heading 1-3, Caption, Table Grid) and real list\nnumbering, so the document's outline and its lists behave as Word's own.\n\n## analyze_table.py — numbers out of a CSV or XLSX\n\n```\npython3 scripts\u002Fanalyze_table.py sales.csv\npython3 scripts\u002Fanalyze_table.py sales.csv --group-by Region --sum Revenue --mean Price\npython3 scripts\u002Fanalyze_table.py book.xlsx --sheet Q3 --group-by Region --sum Revenue --out summary.xlsx\npython3 scripts\u002Fanalyze_table.py sales.csv --where \"Units>=12\" --where \"Region=West\" --sum Revenue --group-by Rep\n```\n\n| Option | Effect |\n| --- | --- |\n| `--sheet NAME` | which sheet of an .xlsx (default: the first) |\n| `--delimiter C` | CSV delimiter (default: sniffed) |\n| `--where \"Col=v\"` | keep matching rows; `=` `!=` `>` `\u003C` `>=` `\u003C=`; repeatable |\n| `--group-by COL` | aggregate per distinct value of this column |\n| `--sum COL` | total this column per group; repeatable |\n| `--mean COL` | average this column per group; repeatable |\n| `--out FILE` | also write `.json`, `.csv` or `.xlsx` |\n\nWith no `--group-by` it profiles every column: filled\u002Fempty counts, distinct\nvalues, and for numeric columns count, sum, mean, median, min, max and stdev;\nfor text columns the five commonest values. JSON always goes to stdout.\n\n`$1,240.00`, `1 240`, `45%` and `(320)` all read as numbers. A blank cell is not\nzero: it is left out of sums and means, and `rows_dropped_not_a_number` counts\nthe rows an ordering filter could not judge. Say that number out loud if it is\nnot zero — it usually is the finding.\n\n`formula_cells_without_cached_values` is the other one to watch. Reading an\n.xlsx gives you the value the file has *cached*, so a workbook whose totals are\nformulas that nothing ever calculated reads as blank and counts as nothing. When\nthat number is not zero, say so rather than reporting a total built out of holes.\n\n## read_document.py — text and tables out of a document\n\n```\npython3 scripts\u002Fread_document.py report.pdf --tables --json extracted.json\npython3 scripts\u002Fread_document.py notes.docx\npython3 scripts\u002Fread_document.py deck.pptx --json deck.json\npython3 scripts\u002Fread_document.py book.xlsx --sheet Q3\n```\n\nReadable text on stdout; `--json` also writes the structured form, which is what\na follow-up script should consume.\n\n* **.pdf** — pypdf in *layout* mode, which keeps each glyph near its column\n  instead of reflowing the page. `--tables` then finds runs of lines whose\n  fields start at the same character positions. It is a heuristic: it finds the\n  tables a report lays out in aligned columns, misses ones drawn with borders\n  and no alignment, and sometimes calls a numbered list a table. Look at what it\n  returned before quoting it.\n* **.docx** — paragraphs (with their style names, so headings are identifiable)\n  and tables as rows of cells.\n* **.pptx** — text per slide, in slide order.\n* **.xlsx** — values via openpyxl. Formula cells hold whatever value was cached\n  in the file; a workbook written by a tool that caches none reads as empty\n  there. `make_xlsx.py` caches them, which is the point of it.\n\n## validate_document.py — check what you produced\n\n```\npython3 scripts\u002Fvalidate_document.py report.docx deck.pptx book.xlsx report.pdf\npython3 scripts\u002Fvalidate_document.py deck.pptx --json checks.json\n```\n\nPrints PASS\u002FFAIL per file and exits non-zero if any failed. `make_pdf.py`,\n`make_xlsx.py`, `make_docx.py` and `make_pptx.py` already run this on their own\noutput; use it on a file you assembled by hand or edited afterwards.\n\n## Limits\n\n**No Office application has opened these files.** There is no Word, PowerPoint\nor Excel on this device, and no headless converter — LibreOffice, which the\npublished document skills shell out to for exactly this check, cannot be bundled\nand could not be launched if it were, because iOS starts no subprocesses. What\n`validate_document.py` checks is that the package is internally consistent:\nevery part `[Content_Types].xml` names exists, every part has a content type,\nevery relationship resolves, every XML part parses, and the primary part has the\nroot element and children its kind requires. That is a real check and it catches\nthe mistakes that make a file unopenable — but a PASS means well formed, not\nopened. If the user reports that a file will not open, believe them.\n\n**python-docx and python-pptx ARE here, and so is lxml.** Both import\n`lxml.etree` at module scope, and lxml is a C extension that no index publishes\nfor iOS — so this app compiles it itself and ships it as signed frameworks,\nalongside `python-pptx`, `python-docx`, `XlsxWriter` and `typing_extensions`.\nImport them directly; `pip install` of any of them by name is a no-op. lxml is\ncompiled into the app and cannot be replaced by a download; the pure ones could\nbe shadowed by a pinned install, but nothing here needs that. The writers above\nstill build the OOXML\nthemselves with `zipfile` and `xml.etree` (they predate this, and they validate\ntheir own output), which is why their feature set is the list above and not\neverything Word can do. For what they lack — charts, speaker notes, headers and\nfooters, editing a document the user gave you — use python-pptx or python-docx\nand run `validate_document.py` on the result, which checks their output the\nsame way.\n\n**pdfplumber is not here.** It needs pdfminer.six, which imports\n`cryptography` at the top of `pdfminer\u002Fpdfdocument.py` in every release back to\n2022, and `cryptography` is a Rust extension with no pure wheel of any kind.\nThat is why PDF reading is pypdf's layout mode and the table finder is a\nheuristic rather than a ruling-line analysis. An encrypted PDF that needs a real\npassword cannot be opened here at all.\n\n**Spreadsheet formulas are evaluated by a subset.** See the function list under\n`make_xlsx.py`. Anything outside it is refused by name and reported, never\nguessed at.\n","# Documents\n\nSix scripts. Every one runs under the interpreter bundled in this app, with the\npackages that are already there: reportlab, pypdf, openpyxl, Pillow and\ndefusedxml, plus the standard library. Nothing here needs the network, a child\nprocess, or a package the user has to install. python-pptx, python-docx and\nlxml are bundled too (see **Limits**) for the things these writers do not do.\n\nRead **Limits** before promising the user anything. Two of them change what you\nshould say in your answer.\n\n## Choosing a script\n\n| The user wants | Run |\n| --- | --- |\n| A photo or a picture turned into a PDF | `make_pdf.py --image` |\n| A report, a memo, anything to print or share as a PDF | `make_pdf.py --spec` |\n| A CSV turned into a spreadsheet, as it stands | `make_xlsx.py --csv` |\n| A spreadsheet built from figures you computed | `make_xlsx.py --spec` |\n| A slide deck | `make_pptx.py` |\n| A Word document | `make_docx.py` |\n| Numbers out of a CSV or spreadsheet | `analyze_table.py` |\n| Text or tables out of a document they gave you | `read_document.py` |\n| To check a file you produced | `validate_document.py` |\n\nA typical request — \"analyse this spreadsheet and make me a deck\" — is\n`analyze_table.py` to get the numbers, then `make_pptx.py` with those numbers in\nthe spec. Do not put a number in a document that you did not compute.\n\n**Starting from a CSV.** Three different requests, three different answers, and\npicking the wrong one wastes the turn:\n\n* *\"Turn this CSV into a spreadsheet\"* — one command:\n  `make_xlsx.py --csv sales.csv --out sales.xlsx`. Do not build a spec by hand\n  for this, and do not reach for `analyze_table.py`: it profiles columns and\n  refuses `--out` on a workbook without `--group-by`, because a profile is not\n  a table.\n* *\"Total the revenue in this CSV\"* — `analyze_table.py`, which computes it.\n  Add `--total revenue` to the command above if you want the workbook to carry\n  the sum as a live formula as well.\n* *\"Make a PDF\u002Fdeck\u002FWord report of this CSV\"* — there is no one-shot for this,\n  because a report is a document you design rather than a table you convert.\n  Read the file (`read_document.py`, or the shell), then write a spec whose\n  `table` block holds those rows, then run `make_pdf.py` \u002F `make_pptx.py` \u002F\n  `make_docx.py`. Put the real rows in the spec; do not summarise them away.\n\n## make_pdf.py — a PDF report, or a picture\n\n```\npython3 scripts\u002Fmake_pdf.py --image photo.jpg --out photo.pdf\npython3 scripts\u002Fmake_pdf.py --image a.png --image b.png --out album.pdf --title Album\npython3 scripts\u002Fmake_pdf.py --spec spec.json --out report.pdf\npython3 scripts\u002Fmake_pdf.py --spec - --out report.pdf     # spec on stdin\n```\n\n**\"Turn this photo into a PDF\" is `--image`, and it is one command.** Do not write\na spec for it. The user's attached files are already in your working directory\nunder the names you were told — pass that name straight to `--image`. Each picture\ngets a page of its own, scaled to fit with its proportions kept; `--title` adds a\ntitle page. Pass either `--image` or `--spec`, never both.\n\nAn iPhone photo is HEIC, and the interpreter here has no HEIC decoder. The app\nstages a `.png` beside it for exactly this reason — if you were told about both\n`IMG_0004.heic` and `IMG_0004.png`, the `.png` is the one to pass.\n\nWrites the PDF, reopens it with pypdf, and prints JSON: `file`, `bytes`,\n`pages`, `blocks`, `extractable_characters`. Non-zero exit means it failed.\n\n```json\n{\n  \"title\": \"Q3 Revenue Review\",\n  \"subtitle\": \"Prepared on device\",\n  \"author\": \"TensorAgent\",\n  \"page_size\": \"letter\",\n  \"landscape\": false,\n  \"margin_in\": 0.9,\n  \"blocks\": [\n    { \"type\": \"heading\", \"level\": 1, \"text\": \"Summary\" },\n    { \"type\": \"paragraph\", \"text\": \"Revenue rose 18%.\", \"mono\": false },\n    { \"type\": \"bullets\", \"items\": [\"South overtook East\", \"Costs flat\"] },\n    { \"type\": \"numbers\", \"items\": [\"Load the CSV\", \"Group by region\"] },\n    { \"type\": \"table\",\n      \"columns\": [\"Region\", \"Units\", \"Revenue\"],\n      \"rows\": [[\"West\", 120, 420.0], [\"East\", 200, 700.0]],\n      \"column_widths\": [2, 1, 1],\n      \"zebra\": true },\n    { \"type\": \"image\", \"path\": \"chart.png\", \"width_in\": 5.0, \"caption\": \"Figure 1.\" },\n    { \"type\": \"pagebreak\" },\n    { \"type\": \"spacer\", \"height\": 12 }\n  ]\n}\n```\n\n`page_size` is `letter` or `a4`. `level` is 1-3. Numeric table cells are\nright-aligned and thousands-separated automatically; the header row repeats when\na table crosses a page. `column_widths` are relative, not absolute. An unknown\nblock type is an error, not a skipped block.\n\nThere is no chart type. Draw one with Pillow into a `.png` and add it as an\n`image` block — that is what the image block is for.\n\n## make_xlsx.py — a workbook whose formulas show their numbers\n\n```\npython3 scripts\u002Fmake_xlsx.py --csv sales.csv --out sales.xlsx\npython3 scripts\u002Fmake_xlsx.py --csv sales.csv --out sales.xlsx --total revenue\npython3 scripts\u002Fmake_xlsx.py --spec spec.json --out book.xlsx\n```\n\n`--csv` writes the file as it stands: the header becomes the columns, and a\ncell that reads as a number is stored as one, so the column can be summed.\n`--sheet-name` names the sheet (default: the file's own name), and `--total COL`\nadds a SUM row for that column — a real formula with its value cached, like\nevery other formula here. It is repeatable. Everything below is about `--spec`,\nwhich is what you use when the figures are ones you computed rather than ones\nalready in a file.\n\n**Read this part.** A formula in an .xlsx is only text; the number a reader sees\nis the *cached* value left behind by the last application that saved the file.\nThere is no Excel and no LibreOffice on this device, so nothing will recalculate\nthe sheet after you write it. This script therefore evaluates every formula in\nPython and writes the value into the cell **alongside** the formula. The file\nalso carries `fullCalcOnLoad`, so a real Excel recomputes everything anyway the\nmoment the user opens it.\n\nIf a formula cannot be evaluated here, the cell gets the formula and **no**\ncached value, the script lists it under `uncomputable_formulas`, and it exits\nnon-zero. Tell the user which cells those are; do not present the file as\nfinished.\n\n```json\n{\n  \"sheets\": [\n    {\n      \"name\": \"Sales\",\n      \"columns\": [\"Region\", \"Units\", \"Price\", \"Revenue\"],\n      \"rows\": [[\"West\", 120, 3.5, null], [\"East\", 200, 3.5, null]],\n      \"formulas\": [\n        { \"range\": \"D2:D3\", \"formula\": \"=B{r}*C{r}\" },\n        { \"cell\": \"D4\", \"formula\": \"=SUM(D2:D3)\" },\n        { \"cell\": \"D5\", \"formula\": \"=ROUND(AVERAGE(D2:D3),2)\" }\n      ],\n      \"number_formats\": { \"C\": \"#,##0.00\", \"D\": \"#,##0.00\" },\n      \"column_widths\": { \"A\": 18 },\n      \"freeze_header\": true,\n      \"auto_filter\": true\n    }\n  ]\n}\n```\n\n`range` fills a block of cells from one entry: `{r}` becomes the row number and\n`{c}` the column letter. Header cells are styled, columns are sized to content,\nand a formula may refer to another formula cell in any order.\n\nFunctions the evaluator implements: `SUM AVERAGE AVG MEDIAN MIN MAX COUNT COUNTA\nSTDEV PRODUCT ABS SQRT INT ROUND POWER LEN UPPER LOWER TRIM CONCAT CONCATENATE IF\nAND OR NOT`, the operators `+ - * \u002F ^ % &`, comparisons, and A1 ranges. It does\n**not** implement lookups (`VLOOKUP`, `INDEX`\u002F`MATCH`), whole-column ranges\n(`A:B`), cross-sheet references or dates. Compute those in Python and write the\nresult as a value.\n\n## make_pptx.py — a slide deck\n\n```\npython3 scripts\u002Fmake_pptx.py --spec spec.json --out deck.pptx\n```\n\n16:9. Five slide layouts; every slide may have a `title`.\n\n```json\n{\n  \"title\": \"Q3 Revenue Review\",\n  \"author\": \"TensorAgent\",\n  \"slides\": [\n    { \"layout\": \"title\", \"title\": \"Q3 Revenue Review\", \"subtitle\": \"Prepared on device\" },\n    { \"layout\": \"bullets\", \"title\": \"What happened\",\n      \"bullets\": [\"South overtook East\", { \"text\": \"since 2023\", \"level\": 1 }] },\n    { \"layout\": \"table\", \"title\": \"By region\",\n      \"columns\": [\"Region\", \"Revenue\"], \"rows\": [[\"West\", 420.0]] },\n    { \"layout\": \"image\", \"title\": \"Revenue\", \"image\": \"chart.png\", \"caption\": \"Figure 1.\" },\n    { \"layout\": \"text\", \"title\": \"Next\", \"text\": \"Recheck the North price.\" }\n  ]\n}\n```\n\nBullets nest to three levels via `level`. The common tree form\n`{ \"text\": \"Heading\", \"bullets\": [\"Detail\"] }` is also accepted and flattened\nto those levels, so do not rewrite an otherwise-correct spec just to expand it.\nA citation bullet may add `date` and `url` beside `text`; the writer joins all\nthree visibly on the slide. Images are scaled to fit and centred.\nA table slide holds about 12 rows before it runs off the bottom — split a longer\none across slides. `notes` is refused rather than silently dropped: speaker\nnotes need a notesMaster part this writer does not build.\n\nPrefer the canonical fields in the example. For compatibility with common deck\nspecs, a slide with no `layout` is a bullets slide and its `content` array is an\nalias for `bullets` (do not provide both). An optional top-level `sources` array\naccepts URL strings or `{ \"title\": \"...\", \"date\": \"...\", \"url\": \"...\" }`\nobjects and becomes a final Sources slide. For compatibility, the same\n`sources` array on an individual slide is collected into that one final Sources\nslide; a slide whose only body is `sources` acts as that final-slide placeholder\ninstead of creating an additional empty slide. A `text` slide that also contains a `bullets` array is unambiguously\nnormalized to a bullets slide, with its introductory `text` retained first.\nUnknown fields, ambiguous aliases, and layouts without visible required content\nfail before a `.pptx` is written; the diagnostic names the slide and the fields\naccepted by its layout.\n\n## make_docx.py — a Word document\n\n```\npython3 scripts\u002Fmake_docx.py --spec spec.json --out report.docx\n```\n\nSame block vocabulary as `make_pdf.py`, minus `spacer`:\n\n```json\n{\n  \"title\": \"Q3 Revenue Review\",\n  \"subtitle\": \"Prepared on device\",\n  \"author\": \"TensorAgent\",\n  \"blocks\": [\n    { \"type\": \"heading\", \"level\": 2, \"text\": \"By region\" },\n    { \"type\": \"paragraph\", \"text\": \"Revenue rose 18%.\", \"bold\": false, \"italic\": false, \"align\": \"left\" },\n    { \"type\": \"bullets\", \"items\": [\"Top level\", { \"text\": \"Nested\", \"level\": 1 }] },\n    { \"type\": \"numbers\", \"items\": [\"First\", \"Second\"] },\n    { \"type\": \"table\", \"columns\": [\"Region\", \"Revenue\"], \"rows\": [[\"West\", 420.0]] },\n    { \"type\": \"image\", \"path\": \"chart.png\", \"width_in\": 5.0, \"caption\": \"Figure 1.\" },\n    { \"type\": \"pagebreak\" }\n  ]\n}\n```\n\nReal Word styles (Title, Heading 1-3, Caption, Table Grid) and real list\nnumbering, so the document's outline and its lists behave as Word's own.\n\n## analyze_table.py — numbers out of a CSV or XLSX\n\n```\npython3 scripts\u002Fanalyze_table.py sales.csv\npython3 scripts\u002Fanalyze_table.py sales.csv --group-by Region --sum Revenue --mean Price\npython3 scripts\u002Fanalyze_table.py book.xlsx --sheet Q3 --group-by Region --sum Revenue --out summary.xlsx\npython3 scripts\u002Fanalyze_table.py sales.csv --where \"Units>=12\" --where \"Region=West\" --sum Revenue --group-by Rep\n```\n\n| Option | Effect |\n| --- | --- |\n| `--sheet NAME` | which sheet of an .xlsx (default: the first) |\n| `--delimiter C` | CSV delimiter (default: sniffed) |\n| `--where \"Col=v\"` | keep matching rows; `=` `!=` `>` `\u003C` `>=` `\u003C=`; repeatable |\n| `--group-by COL` | aggregate per distinct value of this column |\n| `--sum COL` | total this column per group; repeatable |\n| `--mean COL` | average this column per group; repeatable |\n| `--out FILE` | also write `.json`, `.csv` or `.xlsx` |\n\nWith no `--group-by` it profiles every column: filled\u002Fempty counts, distinct\nvalues, and for numeric columns count, sum, mean, median, min, max and stdev;\nfor text columns the five commonest values. JSON always goes to stdout.\n\n`$1,240.00`, `1 240`, `45%` and `(320)` all read as numbers. A blank cell is not\nzero: it is left out of sums and means, and `rows_dropped_not_a_number` counts\nthe rows an ordering filter could not judge. Say that number out loud if it is\nnot zero — it usually is the finding.\n\n`formula_cells_without_cached_values` is the other one to watch. Reading an\n.xlsx gives you the value the file has *cached*, so a workbook whose totals are\nformulas that nothing ever calculated reads as blank and counts as nothing. When\nthat number is not zero, say so rather than reporting a total built out of holes.\n\n## read_document.py — text and tables out of a document\n\n```\npython3 scripts\u002Fread_document.py report.pdf --tables --json extracted.json\npython3 scripts\u002Fread_document.py notes.docx\npython3 scripts\u002Fread_document.py deck.pptx --json deck.json\npython3 scripts\u002Fread_document.py book.xlsx --sheet Q3\n```\n\nReadable text on stdout; `--json` also writes the structured form, which is what\na follow-up script should consume.\n\n* **.pdf** — pypdf in *layout* mode, which keeps each glyph near its column\n  instead of reflowing the page. `--tables` then finds runs of lines whose\n  fields start at the same character positions. It is a heuristic: it finds the\n  tables a report lays out in aligned columns, misses ones drawn with borders\n  and no alignment, and sometimes calls a numbered list a table. Look at what it\n  returned before quoting it.\n* **.docx** — paragraphs (with their style names, so headings are identifiable)\n  and tables as rows of cells.\n* **.pptx** — text per slide, in slide order.\n* **.xlsx** — values via openpyxl. Formula cells hold whatever value was cached\n  in the file; a workbook written by a tool that caches none reads as empty\n  there. `make_xlsx.py` caches them, which is the point of it.\n\n## validate_document.py — check what you produced\n\n```\npython3 scripts\u002Fvalidate_document.py report.docx deck.pptx book.xlsx report.pdf\npython3 scripts\u002Fvalidate_document.py deck.pptx --json checks.json\n```\n\nPrints PASS\u002FFAIL per file and exits non-zero if any failed. `make_pdf.py`,\n`make_xlsx.py`, `make_docx.py` and `make_pptx.py` already run this on their own\noutput; use it on a file you assembled by hand or edited afterwards.\n\n## Limits\n\n**No Office application has opened these files.** There is no Word, PowerPoint\nor Excel on this device, and no headless converter — LibreOffice, which the\npublished document skills shell out to for exactly this check, cannot be bundled\nand could not be launched if it were, because iOS starts no subprocesses. What\n`validate_document.py` checks is that the package is internally consistent:\nevery part `[Content_Types].xml` names exists, every part has a content type,\nevery relationship resolves, every XML part parses, and the primary part has the\nroot element and children its kind requires. That is a real check and it catches\nthe mistakes that make a file unopenable — but a PASS means well formed, not\nopened. If the user reports that a file will not open, believe them.\n\n**python-docx and python-pptx ARE here, and so is lxml.** Both import\n`lxml.etree` at module scope, and lxml is a C extension that no index publishes\nfor iOS — so this app compiles it itself and ships it as signed frameworks,\nalongside `python-pptx`, `python-docx`, `XlsxWriter` and `typing_extensions`.\nImport them directly; `pip install` of any of them by name is a no-op. lxml is\ncompiled into the app and cannot be replaced by a download; the pure ones could\nbe shadowed by a pinned install, but nothing here needs that. The writers above\nstill build the OOXML\nthemselves with `zipfile` and `xml.etree` (they predate this, and they validate\ntheir own output), which is why their feature set is the list above and not\neverything Word can do. For what they lack — charts, speaker notes, headers and\nfooters, editing a document the user gave you — use python-pptx or python-docx\nand run `validate_document.py` on the result, which checks their output the\nsame way.\n\n**pdfplumber is not here.** It needs pdfminer.six, which imports\n`cryptography` at the top of `pdfminer\u002Fpdfdocument.py` in every release back to\n2022, and `cryptography` is a Rust extension with no pure wheel of any kind.\nThat is why PDF reading is pypdf's layout mode and the table finder is a\nheuristic rather than a ruling-line analysis. An encrypted PDF that needs a real\npassword cannot be opened here at all.\n\n**Spreadsheet formulas are evaluated by a subset.** See the function list under\n`make_xlsx.py`. Anything outside it is refused by name and reported, never\nguessed at.\n",{"name":5,"description":7},"main","2369f533b0a00861d0deee7739ec28671a1a7897","TensorAgent\u002Fskills\u002Fdocuments",73,"https:\u002F\u002Fgithub.com\u002Fzhongkaifu\u002FTensorSharp","https:\u002F\u002Ftensorsharp.ai","https:\u002F\u002Fgithub.com\u002Fzhongkaifu","2026-11-13 03:53:42",{"source":8,"skillName":5,"commands":70,"prompt":80,"zipAvailable":81},[71,74,77],{"tool":72,"command":73},"npx","npx skills add zhongkaifu\u002FTensorSharp --skill documents",{"tool":75,"command":76},"bunx","bunx skills add zhongkaifu\u002FTensorSharp --skill documents",{"tool":78,"command":79},"pnpm","pnpm dlx skills add zhongkaifu\u002FTensorSharp --skill documents","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fzhongkaifu\u002FTensorSharp\u002Fblob\u002Fmain\u002FTensorAgent\u002Fskills\u002Fdocuments\u002FSKILL.md",true,[83,89,93,97,101,105,109,113,117,121],{"path":84,"resourceType":85,"resourceTypeDesc":86,"sizeBytes":87,"sourceHtmlUrl":88},"scripts\u002Fanalyze_table.py","SCRIPT","脚本",16786,"https:\u002F\u002Fgithub.com\u002Fzhongkaifu\u002FTensorSharp\u002Fblob\u002Fmain\u002FTensorAgent\u002Fskills\u002Fdocuments\u002Fscripts\u002Fanalyze_table.py",{"path":90,"resourceType":85,"resourceTypeDesc":86,"sizeBytes":91,"sourceHtmlUrl":92},"scripts\u002Fmake_docx.py",15978,"https:\u002F\u002Fgithub.com\u002Fzhongkaifu\u002FTensorSharp\u002Fblob\u002Fmain\u002FTensorAgent\u002Fskills\u002Fdocuments\u002Fscripts\u002Fmake_docx.py",{"path":94,"resourceType":85,"resourceTypeDesc":86,"sizeBytes":95,"sourceHtmlUrl":96},"scripts\u002Fmake_pdf.py",13907,"https:\u002F\u002Fgithub.com\u002Fzhongkaifu\u002FTensorSharp\u002Fblob\u002Fmain\u002FTensorAgent\u002Fskills\u002Fdocuments\u002Fscripts\u002Fmake_pdf.py",{"path":98,"resourceType":85,"resourceTypeDesc":86,"sizeBytes":99,"sourceHtmlUrl":100},"scripts\u002Fmake_pptx.py",36875,"https:\u002F\u002Fgithub.com\u002Fzhongkaifu\u002FTensorSharp\u002Fblob\u002Fmain\u002FTensorAgent\u002Fskills\u002Fdocuments\u002Fscripts\u002Fmake_pptx.py",{"path":102,"resourceType":85,"resourceTypeDesc":86,"sizeBytes":103,"sourceHtmlUrl":104},"scripts\u002Fmake_xlsx.py",16002,"https:\u002F\u002Fgithub.com\u002Fzhongkaifu\u002FTensorSharp\u002Fblob\u002Fmain\u002FTensorAgent\u002Fskills\u002Fdocuments\u002Fscripts\u002Fmake_xlsx.py",{"path":106,"resourceType":85,"resourceTypeDesc":86,"sizeBytes":107,"sourceHtmlUrl":108},"scripts\u002Fooxml.py",19909,"https:\u002F\u002Fgithub.com\u002Fzhongkaifu\u002FTensorSharp\u002Fblob\u002Fmain\u002FTensorAgent\u002Fskills\u002Fdocuments\u002Fscripts\u002Fooxml.py",{"path":110,"resourceType":85,"resourceTypeDesc":86,"sizeBytes":111,"sourceHtmlUrl":112},"scripts\u002Fread_document.py",11056,"https:\u002F\u002Fgithub.com\u002Fzhongkaifu\u002FTensorSharp\u002Fblob\u002Fmain\u002FTensorAgent\u002Fskills\u002Fdocuments\u002Fscripts\u002Fread_document.py",{"path":114,"resourceType":85,"resourceTypeDesc":86,"sizeBytes":115,"sourceHtmlUrl":116},"scripts\u002Fsheetcalc.py",15662,"https:\u002F\u002Fgithub.com\u002Fzhongkaifu\u002FTensorSharp\u002Fblob\u002Fmain\u002FTensorAgent\u002Fskills\u002Fdocuments\u002Fscripts\u002Fsheetcalc.py",{"path":118,"resourceType":85,"resourceTypeDesc":86,"sizeBytes":119,"sourceHtmlUrl":120},"scripts\u002Fspecs.py",2685,"https:\u002F\u002Fgithub.com\u002Fzhongkaifu\u002FTensorSharp\u002Fblob\u002Fmain\u002FTensorAgent\u002Fskills\u002Fdocuments\u002Fscripts\u002Fspecs.py",{"path":122,"resourceType":85,"resourceTypeDesc":86,"sizeBytes":123,"sourceHtmlUrl":124},"scripts\u002Fvalidate_document.py",4675,"https:\u002F\u002Fgithub.com\u002Fzhongkaifu\u002FTensorSharp\u002Fblob\u002Fmain\u002FTensorAgent\u002Fskills\u002Fdocuments\u002Fscripts\u002Fvalidate_document.py",[126,158,186,215,240,265],{"skillNo":127,"name":128,"nameZh":6,"description":129,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":130,"licenseFileUrl":131,"sourceHtmlUrl":132,"categories":133,"keywords":137,"publishedAt":56},"01M6KN3TFVCZHZMDB6JYHSCFTT","web-artifacts-builder","Suite of tools for creating elaborate, multi-component claude.ai HTML artifacts using modern frontend web technologies (React, Tailwind CSS, shadcn\u002Fui). Use for complex artifacts requiring state management, routing, or shadcn\u002Fui components - not for simple single-file HTML\u002FJSX artifacts.","Apache-2.0","https:\u002F\u002Fgithub.com\u002Fzhongkaifu\u002FTensorSharp\u002Fblob\u002Fmain\u002FTensorAgent\u002Fskills\u002Fweb-artifacts-builder\u002FLICENSE.txt","https:\u002F\u002Fgithub.com\u002Fzhongkaifu\u002FTensorSharp\u002Fblob\u002Fmain\u002FTensorAgent\u002Fskills\u002Fweb-artifacts-builder\u002FSKILL.md",[134],{"categoryNo":135,"categoryName":136,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000009","前端开发",[138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157],"web artifacts builder","web","artifacts","artifacts builder","builder","frontend","css","components","react","component","shadcn","ui","Tools","Tailwind","html","single-file","ui components","for","jsx","suite",{"skillNo":159,"name":160,"nameZh":6,"description":161,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":130,"licenseFileUrl":162,"sourceHtmlUrl":163,"categories":164,"keywords":168,"publishedAt":56},"01M6KN3P30A9VG3459BQMD1QQB","theme-factory","Toolkit for styling artifacts with a theme. These artifacts can be slides, docs, reportings, HTML landing pages, etc. There are 10 pre-set themes with colors\u002Ffonts that you can apply to any artifact that has been creating, or can generate a new theme on-the-fly.","https:\u002F\u002Fgithub.com\u002Fzhongkaifu\u002FTensorSharp\u002Fblob\u002Fmain\u002FTensorAgent\u002Fskills\u002Ftheme-factory\u002FLICENSE.txt","https:\u002F\u002Fgithub.com\u002Fzhongkaifu\u002FTensorSharp\u002Fblob\u002Fmain\u002FTensorAgent\u002Fskills\u002Ftheme-factory\u002FSKILL.md",[165],{"categoryNo":166,"categoryName":167,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000015","视觉设计",[169,170,171,172,51,140,173,174,175,176,152,177,178,179,180,181,182,183,155,184,185],"theme factory","factory","theme","toolkit","SET","fly","slides","landing","styling","artifact","pages","themes","you","fonts","can","apply","new",{"skillNo":187,"name":188,"nameZh":6,"description":189,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":130,"licenseFileUrl":190,"sourceHtmlUrl":191,"categories":192,"keywords":199,"publishedAt":56},"01M6KN3AGP5G5KT8NY4WA7FHM1","slack-gif-creator","Knowledge and utilities for creating animated GIFs optimized for Slack. Provides constraints, validation tools, and animation concepts. Use when users request animated GIFs for Slack like \"make me a GIF of X doing Y for Slack.\"","https:\u002F\u002Fgithub.com\u002Fzhongkaifu\u002FTensorSharp\u002Fblob\u002Fmain\u002FTensorAgent\u002Fskills\u002Fslack-gif-creator\u002FLICENSE.txt","https:\u002F\u002Fgithub.com\u002Fzhongkaifu\u002FTensorSharp\u002Fblob\u002Fmain\u002FTensorAgent\u002Fskills\u002Fslack-gif-creator\u002FSKILL.md",[193,196],{"categoryNo":194,"categoryName":195,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000005","邮件与沟通",{"categoryNo":197,"categoryName":198,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000016","图像与多媒体",[200,201,202,203,204,150,205,206,207,43,208,209,210,211,212,155,213,214],"slack gif creator","slack","gif","creator","validation","constraints","Animation","knowledge","me","users","make","Utilities","concepts","request","when",{"skillNo":216,"name":217,"nameZh":6,"description":218,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":130,"licenseFileUrl":219,"sourceHtmlUrl":220,"categories":221,"keywords":223,"publishedAt":56},"01M6KN2RSKQ19P9SGZ5CGJCC7S","internal-comms","A set of resources to help me write all kinds of internal communications, using the formats that my company likes to use. Claude should use this skill whenever asked to write some sort of internal communications (status reports, leadership updates, 3P updates, company newsletters, FAQs, incident reports, project updates, etc.).","https:\u002F\u002Fgithub.com\u002Fzhongkaifu\u002FTensorSharp\u002Fblob\u002Fmain\u002FTensorAgent\u002Fskills\u002Finternal-comms\u002FLICENSE.txt","https:\u002F\u002Fgithub.com\u002Fzhongkaifu\u002FTensorSharp\u002Fblob\u002Fmain\u002FTensorAgent\u002Fskills\u002Finternal-comms\u002FSKILL.md",[222],{"categoryNo":194,"categoryName":195,"taxonomyType":21,"taxonomyTypeDesc":22},[224,225,226,227,173,44,43,228,208,229,230,231,232,233,234,235,236,237,238,239],"internal comms","comms","status","help","reports","incident","leadership","project","resources","communications","internal communications","formats","sort","my","updates","company",{"skillNo":241,"name":242,"nameZh":6,"description":243,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":130,"licenseFileUrl":244,"sourceHtmlUrl":245,"categories":246,"keywords":252,"publishedAt":56},"01M6KN13V1EK7HHG19QQDBW8QH","frontend-design","Design distinctive UI with intentional aesthetics and typography. Read the workflow first; save HTML with the offered file tool and return its download link.","https:\u002F\u002Fgithub.com\u002Fzhongkaifu\u002FTensorSharp\u002Fblob\u002Fmain\u002FTensorAgent\u002Fskills\u002Ffrontend-design\u002FLICENSE.txt","https:\u002F\u002Fgithub.com\u002Fzhongkaifu\u002FTensorSharp\u002Fblob\u002Fmain\u002FTensorAgent\u002Fskills\u002Ffrontend-design\u002FSKILL.md",[247,248,249],{"categoryNo":135,"categoryName":136,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":166,"categoryName":167,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":250,"categoryName":251,"taxonomyType":32,"taxonomyTypeDesc":33},"01JBSEEDCAT000000000000032","设计师",[143,253,254,255,256,149,257,258,259,260,45,261,152,262,263,264],"design","frontend design","workflow","file","first","save","tool","download","typography","link","aesthetics","with",{"skillNo":266,"name":267,"nameZh":6,"description":268,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":130,"licenseFileUrl":269,"sourceHtmlUrl":270,"categories":271,"keywords":275,"publishedAt":56},"01M6KMZF30TZEPM9ZMYMJKXBW6","canvas-design","Create beautiful visual art in .png and .pdf documents using design philosophy. You should use this skill when the user asks to create a poster, piece of art, design, or other static piece. Create original visual designs, never copying existing artists' work to avoid copyright violations.","https:\u002F\u002Fgithub.com\u002Fzhongkaifu\u002FTensorSharp\u002Fblob\u002Fmain\u002FTensorAgent\u002Fskills\u002Fcanvas-design\u002FLICENSE.txt","https:\u002F\u002Fgithub.com\u002Fzhongkaifu\u002FTensorSharp\u002Fblob\u002Fmain\u002FTensorAgent\u002Fskills\u002Fcanvas-design\u002FSKILL.md",[272,273,274],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":166,"categoryName":167,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":250,"categoryName":251,"taxonomyType":32,"taxonomyTypeDesc":33},[253,276,277,55,278,5,279,280,281,282,43,283,284,285,286,287,181,288,289,290,214],"canvas design","canvas","design philosophy","create","png","work","user","never","Art","philosophy","visual","poster","Existing","static","copyright"]