bun-docx 0.20.0 → 0.20.2

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 +1 -1
  2. package/dist/index.js +26 -23
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -18,7 +18,7 @@ We measured it — a controlled A/B bake-off: **six real document tasks** (fill
18
18
  | :------------------------ | ------------------: | --------------------: | --------------: | --------------------: |
19
19
  | | **docx-cli** | default skill | **docx-cli** | default skill |
20
20
  | Tasks solved (of 6) | **4.3** (4–5) | 0.7 (0–1) | **6.0** (6–6) | 4.0 (4–4) |
21
- | Rendered correctly (of 6) | 5.7 | 3.7 | 6.0 | 4.7 |
21
+ | Rendered correctly (of 6) | 6 | 3.7 | 6.0 | 4.7 |
22
22
  | Outright-broken documents | **0** | ~1/run (up to 2) | **0** | 0 |
23
23
  | Input tokens | **2.4M** | 6.1M (2.6×) | **1.6M** | 3.6M (2.2×) |
24
24
  | Wall-clock | **924 s** | 1,882 s (2.0× slower) | **1,175 s** | 2,029 s (1.7× slower) |
package/dist/index.js CHANGED
@@ -82676,7 +82676,7 @@ async function resolveBlockOrFail(document4, locator) {
82676
82676
  return document4.body.resolveBlock(locator);
82677
82677
  } catch (err) {
82678
82678
  if (err instanceof LocatorResolveError) {
82679
- return await fail("BLOCK_NOT_FOUND", err.message);
82679
+ return await fail("BLOCK_NOT_FOUND", err.message, STALE_LOCATOR_HINT);
82680
82680
  }
82681
82681
  throw err;
82682
82682
  }
@@ -82726,7 +82726,7 @@ async function resolveBlockRangeOrFail(document4, locator) {
82726
82726
  return await fail("INVALID_LOCATOR", err.message);
82727
82727
  }
82728
82728
  if (err instanceof LocatorResolveError) {
82729
- return await fail("BLOCK_NOT_FOUND", err.message);
82729
+ return await fail("BLOCK_NOT_FOUND", err.message, STALE_LOCATOR_HINT);
82730
82730
  }
82731
82731
  throw err;
82732
82732
  }
@@ -82735,7 +82735,7 @@ var EXIT2, stdout = async (text6) => {
82735
82735
  await Bun.stdout.write(text6);
82736
82736
  }, stderr = async (text6) => {
82737
82737
  await Bun.stderr.write(text6);
82738
- }, sinks, verboseAck = false, SAVE_FLAGS;
82738
+ }, sinks, verboseAck = false, STALE_LOCATOR_HINT = "Locator ids are positional and shift after structural edits (insert/delete/section changes) \u2014 an id from an earlier read may now point elsewhere or be gone. Re-read the file to get current ids, then retry. Applying several changes? Do them from ONE read with --batch (edit/insert/delete/replace/comments) so ids never go stale mid-run.", SAVE_FLAGS;
82739
82739
  var init_respond = __esm(() => {
82740
82740
  init_core2();
82741
82741
  EXIT2 = {
@@ -82768,23 +82768,21 @@ function detectMarkdownInPlainText(text6) {
82768
82768
  return "a link ([text](url))";
82769
82769
  return null;
82770
82770
  }
82771
- async function rejectMarkdownInText(text6, help) {
82771
+ async function rejectMarkdownInText(text6) {
82772
82772
  const found = detectMarkdownInPlainText(text6);
82773
82773
  if (!found)
82774
82774
  return null;
82775
- return await fail("USAGE", `--text writes literal characters, but this value looks like markdown: ${found}. It would be baked in verbatim (e.g. literal ** around the word), not rendered.`, `Use --markdown to parse it (handles ${found}, headings, lists, links), --bold/--italic for a uniformly-emphasized run, or --runs for literal text that really contains these characters. Help:
82776
- ${help}`);
82775
+ return await fail("USAGE", `--text writes literal characters, but this value looks like markdown: ${found}. It would be baked in verbatim (e.g. literal ** around the word), not rendered.`, `Use --markdown to parse it (handles ${found}, headings, lists, links), --bold/--italic for a uniformly-emphasized run, or --runs for literal text that really contains these characters.`);
82777
82776
  }
82778
82777
  function detectShellMangledCurrency(text6) {
82779
82778
  const match = text6.match(/(?<![\d$])([.,]\d{2,})/);
82780
82779
  return match?.[1] ?? null;
82781
82780
  }
82782
- async function rejectShellMangledValue(text6, help, label = "this value") {
82781
+ async function rejectShellMangledValue(text6, label = "this value") {
82783
82782
  const fragment = detectShellMangledCurrency(text6);
82784
82783
  if (!fragment)
82785
82784
  return null;
82786
- return await fail("USAGE", `${label} contains "${fragment}" \u2014 a number with no integer part, the signature of a "$" amount gutted by the shell (bash turns double-quoted "$300.00" into ".00" and "$10,000" into ",000"). docx would write the corrupted value verbatim.`, `Wrap any "$"-bearing value in SINGLE quotes ('$300.00') so bash leaves it alone, or supply it via --batch FILE (JSONL never touches the shell). If you really mean "${fragment}", write its integer part (0${fragment}) or use --batch. Help:
82787
- ${help}`);
82785
+ return await fail("USAGE", `${label} contains "${fragment}" \u2014 a number with no integer part, the signature of a "$" amount gutted by the shell (bash turns double-quoted "$300.00" into ".00" and "$10,000" into ",000"). docx would write the corrupted value verbatim.`, `Wrap any "$"-bearing value in SINGLE quotes ('$300.00') so bash leaves it alone, or supply it via --batch FILE (JSONL never touches the shell). If you really mean "${fragment}", write its integer part (0${fragment}) or use --batch.`);
82788
82786
  }
82789
82787
  function decodeInlineEscapes(value) {
82790
82788
  if (value === undefined)
@@ -85930,10 +85928,10 @@ async function validateParagraphEdit(values2, paragraphOptions) {
85930
85928
  }
85931
85929
  return { kind: "removeLine" };
85932
85930
  }
85933
- const rejected = await rejectMarkdownInText(text6, HELP9);
85931
+ const rejected = await rejectMarkdownInText(text6);
85934
85932
  if (typeof rejected === "number")
85935
85933
  return rejected;
85936
- const mangled = await rejectShellMangledValue(text6, HELP9, "--text");
85934
+ const mangled = await rejectShellMangledValue(text6, "--text");
85937
85935
  if (typeof mangled === "number")
85938
85936
  return mangled;
85939
85937
  return {
@@ -86241,9 +86239,12 @@ General options:
86241
86239
  -h, --help Show this help
86242
86240
 
86243
86241
  Output:
86244
- Prints a one-line confirmation on success (exit 0) \u2014 the edited locator is unchanged, so there's
86245
- nothing to mint. --verbose prints {ok:true, operation, path, locator}.
86246
- Errors print {code, error, hint?} with a nonzero exit. Discover ids with
86242
+ Prints a one-line confirmation on success (exit 0) \u2014 an in-place edit shifts nothing, so the
86243
+ edited locator is unchanged and there's nothing to mint. --verbose prints {ok:true, operation,
86244
+ path, locator}. Errors print {code, error, hint?} with a nonzero exit.
86245
+ Heads up: a locator you hold from BEFORE a structural edit (an insert/delete elsewhere renumbers
86246
+ ids) is stale \u2014 it lands on the wrong block or errors BLOCK_NOT_FOUND. Re-read after any
86247
+ insert/delete, or apply the whole set from one read with --batch (above). Discover ids with
86247
86248
  \`docx read FILE --ast\` (equation ids appear on EquationRun nodes).
86248
86249
 
86249
86250
  Examples:
@@ -88872,10 +88873,10 @@ async function buildSingleShotOptions(filePath, values2) {
88872
88873
  if (typeof spec === "number")
88873
88874
  return spec;
88874
88875
  if (spec.kind === "text") {
88875
- const rejected = await rejectMarkdownInText(spec.text, HELP20);
88876
+ const rejected = await rejectMarkdownInText(spec.text);
88876
88877
  if (typeof rejected === "number")
88877
88878
  return rejected;
88878
- const mangled = await rejectShellMangledValue(spec.text, HELP20, "--text");
88879
+ const mangled = await rejectShellMangledValue(spec.text, "--text");
88879
88880
  if (typeof mangled === "number")
88880
88881
  return mangled;
88881
88882
  }
@@ -94849,7 +94850,7 @@ async function run43(args) {
94849
94850
  }
94850
94851
  const cellTexts = parsed.values.cells ? parsed.values.cells.split(",") : [];
94851
94852
  for (const cell of cellTexts) {
94852
- const mangled = await rejectShellMangledValue(cell, HELP39, "--cells");
94853
+ const mangled = await rejectShellMangledValue(cell, "--cells");
94853
94854
  if (typeof mangled === "number")
94854
94855
  return mangled;
94855
94856
  }
@@ -98014,7 +98015,7 @@ Examples:
98014
98015
  // package.json
98015
98016
  var package_default = {
98016
98017
  name: "bun-docx",
98017
- version: "0.20.0",
98018
+ version: "0.20.2",
98018
98019
  description: "Read, edit, redline, and comment on Microsoft Word .docx files from the command line \u2014 built for AI agents.",
98019
98020
  keywords: [
98020
98021
  "docx",
@@ -98137,11 +98138,13 @@ Commands (each one-liner names capabilities you'd otherwise miss; see <command>
98137
98138
  It is highly recommended to run "docx info locators" and "docx info schema" (neither needs a FILE) to understand the addressing model and AST.
98138
98139
  Run "docx <command> --help" for command-specific help.
98139
98140
 
98140
- BATCH MANY CHANGES IN ONE READ: filling a form or applying many edits? Don't go
98141
- one-at-a-time \u2014 edit / insert / replace / delete and comments (add/resolve/delete)
98142
- all take --batch FILE.jsonl (one JSON change per line; "-" reads stdin). Every locator
98143
- addresses the document AS READ, so ids stay valid across the whole batch \u2014 one
98144
- read, one write, no re-reading between changes. See "<command> --help".
98141
+ BATCH MANY CHANGES IN ONE READ: locator ids are positional and shift after structural
98142
+ edits (insert/delete/section changes), so going one-at-a-time forces a re-read to refresh
98143
+ ids after each. Miss the change and the next command lands on the wrong block or errors
98144
+ BLOCK_NOT_FOUND. Skip all that: edit / insert / replace / delete and comments
98145
+ (add/resolve/delete) all take --batch FILE.jsonl (one JSON change per line; "-" reads
98146
+ stdin). Every locator addresses the document AS READ, so ids stay valid across the whole
98147
+ batch \u2014 one read, one write, no re-reading between changes. See "<command> --help".
98145
98148
 
98146
98149
  FILL FORMATTED / TABBED LINES WITHOUT REBUILDING RUNS: to fill a template line that
98147
98150
  carries formatting (bold/font) or tab stops \u2014 e.g. "**Org Name**\u21E5Date" \u2014 replace just
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bun-docx",
3
- "version": "0.20.0",
3
+ "version": "0.20.2",
4
4
  "description": "Read, edit, redline, and comment on Microsoft Word .docx files from the command line — built for AI agents.",
5
5
  "keywords": [
6
6
  "docx",