@qvac/skills 0.1.11 → 0.1.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,135 +1,155 @@
1
1
  ---
2
2
  name: word
3
- description: Create, edit, or read Word (.docx) documents with python-docx — deliver documents as chat attachments, or read an attached one to summarize it or answer questions in the chat. Can embed images generated in the chat. Opens in Pages and Google Docs too.
3
+ description: Create, edit, or read Word (.docx) documents — deliver documents as chat attachments, or read an attached one to summarize it or answer questions in the chat. Can embed images generated in the chat. Opens in Pages and Google Docs too.
4
4
  aliases: [docx, word-document, memo]
5
5
  preload_on_name: false
6
- tools: [exec(python)]
7
- platform: [darwin, linux, win32]
8
- metadata:
9
- {
10
- "openclaw":
11
- {
12
- "setup":
13
- {
14
- "summary": "Runs python-docx in the in-process Python runtime, from packages that ship with the app. The first use waits for the runtime to start."
15
- }
16
- }
17
- }
6
+ tools: [docx]
7
+ platform: [darwin, linux, win32, ios, android]
18
8
  ---
19
9
 
20
10
  # Word
21
11
 
22
- Build, change, or read `.docx` documents. This file holds no Python and no
23
- recipe: it only says which reference file to load. Load exactly one with the
24
- `skill` tool, then do what that file says.
25
-
26
- ## Which File to Load
27
-
28
- Pick the row by **what the user wants done**, then make that exact `skill`
29
- call. "Edit", "update", "modify", "change", "replace", "rewrite" and "fix" all
30
- mean the same thing here — the verb never picks the row, the change does.
31
-
32
- | The user wants | The `skill` call |
33
- | ------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------- |
34
- | A new document — "write a report", "make a doc with 30 fun facts about cats", "draft a letter" | `{"name": "word", "file": "references/create.md"}` |
35
- | Some paragraphs of an existing document changed — "replace the first 10 facts with dog facts", "change fact 3", "reword paragraph 7", "swap these bullets for those" | `{"name": "word", "file": "references/paragraphs.md"}` |
36
- | Anything else done to an existing document — add a section, remove or rewrite a whole section, make the text bigger, put an image in it | `{"name": "word", "file": "references/rework.md"}` |
37
- | An answer in the chat from an attached document — "summarize this", "what does it say about X" | `{"name": "word", "file": "references/read.md"}` |
38
-
39
- - A document that already exists in this chat is never rebuilt with
40
- `create.md` — that throws away everything the user has. Its `attachmentId`
41
- is in the `exec` result that produced it or on the `[Attached file …]` line.
42
- - A summary delivered as a file is `read.md` first, then `create.md`.
43
- - `paragraphs.md` runs two scripts bundled with this skill and contains no
44
- Python. `rework.md` and `create.md` carry the python-docx recipes to copy.
45
-
46
- Each load is a real `skill` tool call — printing the call as JSON or text in
47
- your reply loads nothing. Never write the Python from memory: the recipes carry
48
- rules (exact version pins, attachment staging, the only working removal idiom)
49
- that fail in non-obvious ways when improvised, and loading the file is one
50
- cheap read-only call.
51
-
52
- ## When to Use
53
-
54
- - The user asks for a document, report, letter, memo, `.docx`, or Word file.
55
- - The user attaches a `.docx` and wants its content changed, replaced in part,
56
- extended, trimmed, or reworked.
57
- - The user attaches a `.docx` and asks what it says — a summary, a question
58
- answered, or content pulled out into the chat.
59
- - The user wants a document that embeds images generated in this chat.
60
-
61
- ## When NOT to Use
62
-
63
- - The user wants text in the chat and no document is involved — just write it.
64
- Summarizing or answering from an attached `.docx` **is** this skill: load
65
- `references/read.md`.
66
- - The user wants slides or a deck — that is the presentations skill.
67
- - The user wants a spreadsheet or a PDF — python-docx writes only `.docx`.
68
-
69
- ## What This Skill Cannot Do
70
-
71
- Say so instead of faking these; a fake is worse than a clear "not supported":
72
-
73
- - **No table of contents.** A real TOC is a Word field that Word itself computes;
74
- python-docx cannot insert one. Do not fake a TOC by typing headings and page
75
- numbers — the page numbers would be wrong. Offer headings (`Heading 1..9`)
76
- instead; Word can generate a TOC from them later.
77
- - **No tracked changes or comments.** There is no revisions API. Edits land as
78
- plain content; say that when the user asks for a redline.
79
- - **No legacy `.doc`.** Only `.docx`. A `.doc` output name is rejected — name it
80
- `.docx`.
81
- - **No PDF export and no rendering.** The runtime cannot convert or preview the
82
- document; it can only write the file.
12
+ Every document job is one or two `docx` tool calls. A call with `ops` saves a
13
+ new file named `output` and attaches it to the chat; a call without `ops`
14
+ changes nothing and returns what the document holds.
15
+
16
+ ## Pick the Call
17
+
18
+ "Edit", "update", "change", "rewrite" and "fix" all mean the same thing here —
19
+ the change picks the row, never the verb.
20
+
21
+ | The user wants | The calls |
22
+ | ------------------------------------------------------------------------------- | -------------------------------------------------------------------- |
23
+ | A new document — "write a report", "30 fun facts about cats", "draft a letter" | one call: `create` + `ops` + `output` |
24
+ | A change whose words depend on the document — "replace the first 10 facts", "reword paragraph 7", "rewrite section 2" | read (`attachmentId` alone), then one edit call |
25
+ | A mechanical change — "make the text bigger", "add this image at the end" | one call: `attachmentId` + `ops` + `output` |
26
+ | An answer in the chat — "summarize this", "what does it say about X" | read (`attachmentId` alone), then reply in the chat — no second call |
27
+ | A summary of the document as a new file | read, then one `create` call written from what the read returned |
28
+
29
+ A document already in this chat is never rebuilt with `create` — that throws
30
+ away everything the user has. Its `attachmentId` is in the tool result that
31
+ produced it, or on the user's `[Attached file …]` line:
32
+
33
+ ```
34
+ [Attached file "report.docx" (application/vnd.openxmlformats-officedocument.wordprocessingml.document) — attachmentId: 4f9c2ab1]
35
+ ```
36
+
37
+ Copy the id verbatim. Never make one up.
38
+
39
+ ## A New Document
40
+
41
+ ```json
42
+ {
43
+ "create": { "title": "Cat Facts" },
44
+ "ops": [
45
+ { "op": "appendParagraphs", "paragraphs": [
46
+ { "text": "Cat Facts", "style": "Title" },
47
+ { "text": "Senses", "style": "Heading 1" },
48
+ { "text": "A cat's hearing reaches 64 kHz.", "style": "List Bullet" },
49
+ { "text": "Cats have about 200 million scent receptors.", "style": "List Bullet" },
50
+ { "text": "Sleep", "style": "Heading 1" },
51
+ { "runs": ["Cats sleep ", { "text": "12 to 16 hours", "bold": true }, " a day."] }
52
+ ] },
53
+ { "op": "addTable", "at": 6, "header": true, "rows": [["Breed", "Weight (kg)"], ["Siamese", 4], ["Maine Coon", 8]] }
54
+ ],
55
+ "output": "cat_facts.docx"
56
+ }
57
+ ```
58
+
59
+ A new document has the styles `Normal`, `Title`, `Subtitle`, `Heading 1`–`3`,
60
+ `List Bullet`, `List Number`, `Quote` and `Table Grid`. `create` also takes
61
+ `"page": "a4"` (the default is `letter`). Each bullet is its own paragraph —
62
+ never type `-`, `•` or `1.` in front of it; the style draws the bullet.
63
+
64
+ ## Reading a Document
65
+
66
+ ```json
67
+ { "attachmentId": "4f9c2ab1" }
68
+ ```
69
+
70
+ It returns the body as numbered **blocks** — paragraphs and tables in document
71
+ order, counted from 0 — each with its style, text, heading level, and whether
72
+ it is a list item; tables come back as rows of cell text. You cannot write a
73
+ summary or a replacement in the same call that reads, because the words are
74
+ fixed before the document is opened. Read, then write from what came back.
75
+
76
+ Only body paragraphs (`Normal`, `List Bullet`, `List Number`) are facts,
77
+ points or bullets. "The first 10 facts" are the first 10 body blocks after the
78
+ heading that introduces them — not blocks 0 to 9.
79
+
80
+ ## Editing a Document
81
+
82
+ ```json
83
+ {
84
+ "attachmentId": "4f9c2ab1",
85
+ "ops": [
86
+ { "op": "setText", "index": 3, "text": "Dogs have about 1,700 taste buds." },
87
+ { "op": "setText", "index": 4, "text": "A dog's nose print is unique, like a fingerprint." }
88
+ ],
89
+ "output": "report_revised.docx"
90
+ }
91
+ ```
92
+
93
+ "Replace the first 10 facts" is 10 `setText` ops, each a different sentence.
94
+ Every `index` is a block index from the read.
95
+
96
+ | The change | The op |
97
+ | ----------------------------------- | ----------------------------------------------------------------------------------------------- |
98
+ | Replace a paragraph's text | `{ "op": "setText", "index": 3, "text": "New sentence." }` |
99
+ | Bold part of a paragraph | `{ "op": "setText", "index": 3, "text": { "runs": ["Revenue grew ", { "text": "15%", "bold": true }] } }` |
100
+ | Insert paragraphs before a block | `{ "op": "insertParagraphs", "at": 6, "paragraphs": ["East opened", "West grew too"] }` |
101
+ | Add paragraphs at the end | `{ "op": "appendParagraphs", "paragraphs": [{ "text": "Appendix", "style": "Heading 1" }, "Notes."] }` |
102
+ | Rewrite a whole section | `{ "op": "replaceSection", "index": 8, "title": "Spending", "body": ["Spending fell.", "Contracts ended."] }` |
103
+ | Remove a whole section | `{ "op": "deleteSection", "index": 11 }` |
104
+ | Remove some blocks | `{ "op": "deleteBlocks", "index": 5, "count": 2 }` |
105
+ | Make all the text bigger | `{ "op": "formatStyle", "name": "Normal", "format": { "size": 12 } }` |
106
+ | Format one paragraph | `{ "op": "formatParagraph", "index": 2, "format": { "italic": true, "align": "center" } }` |
107
+ | Change a table cell | `{ "op": "setCell", "index": 10, "row": 1, "column": 2, "text": "38%" }` |
108
+ | Add a table row | `{ "op": "addRow", "index": 10, "values": ["Headcount", 120, 115] }` |
109
+ | Add a picture | `{ "op": "addImage", "at": 12, "image": { "attachmentId": "9be07c12" }, "width": 5.5, "align": "center" }` |
110
+ | Add a chart | `{ "op": "addChart", "at": 9, "type": "column", "categories": ["Q1", "Q2"], "series": [{ "name": "2026", "values": [11, 13] }] }` |
111
+
112
+ A section is a heading and everything under it up to the next heading of the
113
+ same or higher rank, tables included — `replaceSection` and `deleteSection`
114
+ take the heading's block index. A plain string paragraph takes the formatting
115
+ of the paragraph before it, so a new bullet after a bullet is a bullet. A
116
+ `style` must be one the document has; the error lists the ones it does.
117
+ `width` is inches; give it alone and the picture keeps its shape.
118
+
119
+ Name the output after the document you opened: `report.docx` →
120
+ `report_revised.docx`. Never the input's own name, and never a fresh name taken
121
+ from the new content.
122
+
123
+ ## Images
124
+
125
+ - An image this chat generated: `"image": { "attachmentId": "<id from the generate_image result>" }`.
126
+ - An image the user attached to their latest message: `"image": {}` — an
127
+ uploaded image shows no id, and the empty form picks it up.
128
+ - An image behind a URL cannot be downloaded. Say so, and ask the user to attach
129
+ it or offer `generate_image`.
83
130
 
84
131
  ## Rules for Every Job
85
132
 
86
- **You build it, not the user.** Deliver the document, never the recipe. Do NOT
87
- print the python source in chat, do NOT tell the user to install python-docx,
88
- run a script, or open a terminal — they have no terminal in this chat and the
89
- code would not run there. The document exists only if an `exec` call with
90
- `outputs` succeeds and returns the attachment; falling back to "here is the
91
- script, run it yourself" is a failed turn.
92
-
93
- **Success = stop.** When `exitCode` is `0` and the result's `attachments`
94
- lists the `.docx`, the document is done. Do not call `exec` again for the same
95
- request — not to "confirm", not to "improve", not to "add the image" after the
96
- fact. Exactly one successful _build_ `exec` per document request — a
97
- no-`outputs` read that precedes a build delivers nothing and is not one of
98
- them, but it belongs before the build, never after it. Reply with a single
99
- line: file name + the count line from stdout. If the result has
100
- `missingOutputs` instead, the file was never written: read stderr first — an
101
- `AssertionError` there means a guard stopped the save on purpose (see the
102
- rework recipe); only when stderr is clean check the `save()` name matches the
103
- declared output and rerun once.
104
-
105
- **Failures are fixed in the code, not around it.** An error in your code is
106
- never a fault in python-docx or in the runtime; fix the Python against the
107
- loaded reference file's recipes and Errors and call `exec` again. A bundled
108
- script that stops with a message is fixed by correcting its arguments and
109
- rerunning the same script — never by writing Python in its place. If two
110
- consecutive calls fail with the same error, re-read the traceback
111
- line-by-line before a third — retrying the identical `command`, or a version
112
- with only cosmetic changes, is a loop, not a fix. Do not switch package pins
113
- (keep `python-docx==1.2.0`), do not wrap source in `python -c` / `pip` /
114
- shell, do not "debug" with `os.listdir` or no-op scripts while `outputs`
115
- still lists the document, and do not write the document as markdown/chat text
116
- instead of a `.docx`. Never search the web about an error; the answer is
117
- always in the `exec` result you already have.
118
-
119
- **The runtime is sealed.** There is no shell — `ls`, `cat`, and `file` raise
120
- `SyntaxError` because `command` is Python source — and no network:
121
- `requests`, `urllib`, and `socket` all fail. The working directory starts
122
- empty on every call: a file from an earlier call is gone unless staged again,
123
- and a file you write but do not declare in `outputs` is discarded. The `exec`
124
- result is the only account of what happened — there is no filesystem to check
125
- and no shell to check it with.
126
-
127
- **Never overwrite a staged input.** Changes always save a new output name,
128
- derived from the document changed — `report.docx` becomes `report_revised.docx`,
129
- never a fresh name taken from the new content.
130
-
131
- **A change happens inside the document.** `add_paragraph` and `add_heading`
132
- append at the end and nowhere else, so replacing content that is already there
133
- means rewriting those paragraphs, not adding new ones. Delivering the original
134
- with the new version appended, or a fresh document holding only the new
135
- content, is a failed turn.
133
+ **You build it, not the user.** The document exists only when a `docx` call
134
+ with `ops` returns its attachment. Never write it as chat text instead, and
135
+ never tell the user to run anything.
136
+
137
+ **Success = stop.** When the result lists the attachment, reply with one line —
138
+ the file name and what changed — and call nothing else.
139
+
140
+ **A change happens inside the document.** Replacing text that is already there
141
+ is `setText` or `replaceSection` on those blocks, never new paragraphs appended
142
+ at the end.
143
+
144
+ **Errors name the fix.** A failed call returns a message that says what exists
145
+ — the block count, the styles, the sections. Correct that one op and call
146
+ again. Never repeat an identical call.
147
+
148
+ ## What This Cannot Do
149
+
150
+ Say so instead of faking it:
151
+
152
+ - **No table of contents.** Offer headings instead; Word can build one from them.
153
+ - **No tracked changes or comments.** Edits land as plain content.
154
+ - **No footnotes, and headers and footers can be read but not written.**
155
+ - **No legacy `.doc`, and no PDF export.**