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.
Files changed (3) hide show
  1. package/README.md +27 -26
  2. package/dist/index.js +2370 -1477
  3. 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`. All mutating commands accept `--dry-run`. JSON output by default for `read` and `*.list`; structured `{ok, code, error, hint}` on failure.
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 | restore | list
106
+ comments/ # add | reply | resolve | delete | list
110
107
  images/ # list | extract | replace
111
108
  track-changes/ # FILE on|off
112
- schema/ # AST JSON Schema + TS source
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/ # 51 tests, 9 files
122
- fixtures/ # 11 .docx fixtures across producers
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 *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.
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 | What |
144
- |---|---|
145
- | `check` | `biome check . && knip-bun && tsc --noEmit` |
146
- | `unit-tests` | `bun run test:unit` (core + cli, fast) |
147
- | `integration-tests` | Installs LibreOffice, runs `bun run test:integration` |
148
- | `build-binary` | Smoke-builds via `bun build --compile` and runs `--version` |
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).