bun-docx 0.1.1 → 0.3.0
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.
- package/README.md +27 -26
- package/dist/index.js +2370 -1477
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,13 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
A Bun-built CLI for AI agents (Claude, Codex) to read, edit, and comment on `.docx` files with full format fidelity. Outputs JSON-AST for precise locator-based editing; preserves anything it doesn't model by mutating XML in place.
|
|
4
4
|
|
|
5
|
-
## Stack
|
|
6
|
-
|
|
7
|
-
- **Runtime**: Bun (`node:util` parseArgs, JSX with custom factory, native zlib)
|
|
8
|
-
- **Parser**: [`jszip`](https://www.npmjs.com/package/jszip) + [`fast-xml-parser`](https://www.npmjs.com/package/fast-xml-parser) + [`fast-xml-builder`](https://www.npmjs.com/package/fast-xml-builder)
|
|
9
|
-
- **Quality**: Biome + Knip + tsc; LibreOffice headless for round-trip integration tests
|
|
10
|
-
- **Standard**: ECMA-376 Part 1 §17 (WordprocessingML), Transitional profile
|
|
11
|
-
|
|
12
5
|
## Install
|
|
13
6
|
|
|
14
7
|
**Standalone binary** (no Bun required):
|
|
@@ -44,11 +37,13 @@ docx insert FILE --after p3 --runs '[{"type":"text","text":"X","bold":true}]'
|
|
|
44
37
|
docx edit FILE --at p3 --text "..." | --runs '[...]'
|
|
45
38
|
docx delete FILE --at p3
|
|
46
39
|
|
|
40
|
+
docx find FILE QUERY [--regex] [--ignore-case] [--all] [--nth N]
|
|
41
|
+
docx replace FILE PATTERN REPLACEMENT [--regex] [--ignore-case] [--all] [--limit N] [--dry-run]
|
|
42
|
+
|
|
47
43
|
docx comments add FILE --range p3:5-20 --text "..." [--author NAME]
|
|
48
44
|
docx comments reply FILE --to c0 --text "..."
|
|
49
45
|
docx comments resolve FILE --id c0 [--unset]
|
|
50
46
|
docx comments delete FILE --id c0
|
|
51
|
-
docx comments restore FILE --id c0
|
|
52
47
|
docx comments list FILE [--include-resolved] [--thread c0]
|
|
53
48
|
|
|
54
49
|
docx images list FILE
|
|
@@ -56,11 +51,13 @@ docx images extract FILE --to ./media [--id imgN]
|
|
|
56
51
|
docx images replace FILE --at imgN --with ./new.png
|
|
57
52
|
|
|
58
53
|
docx track-changes FILE on|off
|
|
59
|
-
docx schema [--ts]
|
|
60
|
-
docx locators [--json]
|
|
54
|
+
docx info schema [--ts]
|
|
55
|
+
docx info locators [--json]
|
|
61
56
|
```
|
|
62
57
|
|
|
63
|
-
Every command has `--help`.
|
|
58
|
+
Every command has `--help`. Mutating commands accept `--dry-run` and `-o/--output PATH` (write to a parallel file instead of overwriting `FILE`). JSON output by default for `read` and `*.list`; structured `{ok, code, error, hint}` on failure.
|
|
59
|
+
|
|
60
|
+
When `<w:trackChanges/>` is set in the doc (toggle via `docx track-changes FILE on`), `insert`/`edit`/`delete`/`replace` automatically emit `<w:ins>`/`<w:del>` markers attributed to `$DOCX_AUTHOR` (default `docx-cli`). To make a one-off untracked edit, flip the flag off, edit, then flip it back on. `find` results inside tracked-change wrappers carry a `trackedChanges` array so agents can decide what to do with hits in pending insertions/deletions.
|
|
64
61
|
|
|
65
62
|
### Locators
|
|
66
63
|
|
|
@@ -72,7 +69,7 @@ tN table N; tN:rRcC for cell at row R, col C
|
|
|
72
69
|
cN, imgN comment / image ids
|
|
73
70
|
```
|
|
74
71
|
|
|
75
|
-
Run `docx locators` for the full reference.
|
|
72
|
+
Run `docx info locators` for the full reference.
|
|
76
73
|
|
|
77
74
|
## Development
|
|
78
75
|
|
|
@@ -106,11 +103,10 @@ src/
|
|
|
106
103
|
insert/ # insert FILE (uses ./emit Paragraph component)
|
|
107
104
|
edit/ # edit FILE
|
|
108
105
|
delete/ # delete FILE
|
|
109
|
-
comments/ # add | reply | resolve | delete |
|
|
106
|
+
comments/ # add | reply | resolve | delete | list
|
|
110
107
|
images/ # list | extract | replace
|
|
111
108
|
track-changes/ # FILE on|off
|
|
112
|
-
|
|
113
|
-
locators-cmd/ # grammar reference
|
|
109
|
+
info/ # schema | locators (reference output)
|
|
114
110
|
core/
|
|
115
111
|
package/ # JSZip open/close, named-part read/write
|
|
116
112
|
parser/ # XmlNode class + parse/serialize + JSX factory
|
|
@@ -118,13 +114,20 @@ src/
|
|
|
118
114
|
ast/ # types + DocView + XML→AST reader
|
|
119
115
|
locators/ # parse "p3:5-20" + resolve to refs
|
|
120
116
|
tests/
|
|
121
|
-
core/, cli/, integration/
|
|
122
|
-
fixtures/
|
|
117
|
+
core/, cli/, integration/
|
|
118
|
+
fixtures/
|
|
123
119
|
```
|
|
124
120
|
|
|
121
|
+
## Stack
|
|
122
|
+
|
|
123
|
+
- **Runtime**: Bun (`node:util` parseArgs, JSX with custom factory, native zlib)
|
|
124
|
+
- **Parser**: [`jszip`](https://www.npmjs.com/package/jszip) + [`fast-xml-parser`](https://www.npmjs.com/package/fast-xml-parser) + [`fast-xml-builder`](https://www.npmjs.com/package/fast-xml-builder)
|
|
125
|
+
- **Quality**: Biome + Knip + tsc; LibreOffice headless for round-trip integration tests
|
|
126
|
+
- **Standard**: ECMA-376 Part 1 §17 (WordprocessingML), Transitional profile
|
|
127
|
+
|
|
125
128
|
## How It Works
|
|
126
129
|
|
|
127
|
-
**In-place XML mutation.** The AST returned by `read` is a
|
|
130
|
+
**In-place XML mutation.** The AST returned by `read` is a _view_ over the parsed XML tree, not a separate model. When you `edit` or `comments add`, we mutate the underlying XML nodes directly and serialize back. Anything we don't model in the AST (custom styles, theme colors, schema extensions) survives because we never re-emit untouched regions.
|
|
128
131
|
|
|
129
132
|
**JSX for emitters.** Constructing OOXML fragments imperatively (`<w:rPr>` → `<w:b/>` → `<w:color w:val="800080"/>`) gets verbose. We write emitters in JSX with a custom factory: `<w.rPr><w.b/><w.color w-val="800080"/></w.rPr>` becomes the right `XmlNode` tree. Component names are PascalCase (`<Paragraph>`, `<RunProperties>`); they return `XmlNode | null` so empty wrappers get omitted automatically.
|
|
130
133
|
|
|
@@ -134,17 +137,15 @@ tests/
|
|
|
134
137
|
|
|
135
138
|
**Cross-format image replacement.** `images replace --at img0 --with new.png` detects the new MIME type via `Bun.file().type`, renames the part (`word/media/image1.jpeg` → `word/media/image1.png`), rewrites the relationship `Target`, and ensures `[Content_Types].xml` has a `<Default>` for the new extension.
|
|
136
139
|
|
|
137
|
-
**Trash for restore.** `comments delete` journals the removed comment XML + anchor info to `<dir>/.docx-cli/trash.json` so `comments restore --id cN` can re-anchor it at its original location.
|
|
138
|
-
|
|
139
140
|
## CI
|
|
140
141
|
|
|
141
142
|
GitHub Actions (`.github/workflows/ci.yml`) runs four jobs on push to `main` and on PRs:
|
|
142
143
|
|
|
143
|
-
| Job
|
|
144
|
-
|
|
145
|
-
| `check`
|
|
146
|
-
| `unit-tests`
|
|
147
|
-
| `integration-tests` | Installs LibreOffice, runs `bun run test:integration`
|
|
148
|
-
| `build-binary`
|
|
144
|
+
| Job | What |
|
|
145
|
+
| ------------------- | ----------------------------------------------------------- |
|
|
146
|
+
| `check` | `biome check . && knip-bun && tsc --noEmit` |
|
|
147
|
+
| `unit-tests` | `bun run test:unit` (core + cli, fast) |
|
|
148
|
+
| `integration-tests` | Installs LibreOffice, runs `bun run test:integration` |
|
|
149
|
+
| `build-binary` | Smoke-builds via `bun build --compile` and runs `--version` |
|
|
149
150
|
|
|
150
151
|
`.github/workflows/release.yml` triggers on `v*` tags, matrix-builds the five binaries, and uploads them to a GitHub Release via [`softprops/action-gh-release`](https://github.com/softprops/action-gh-release).
|