@bendyline/docblocks-cli 2.2.2 → 2.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 CHANGED
@@ -8,7 +8,7 @@ agents.
8
8
 
9
9
  ## Installation
10
10
 
11
- Node.js 22.14 or newer is required.
11
+ Node.js 22.22.2+, 24.15.0+, or 26+ is required.
12
12
 
13
13
  ```bash
14
14
  npm install -g @bendyline/docblocks-cli
@@ -67,8 +67,11 @@ docblocks mcp --allow-read ./documents --allow-write ./exports
67
67
 
68
68
  For durable output, call `list_roots` before drafting. If no root is write-enabled,
69
69
  restart the server with `--allow-write`; do not bypass MCP with the direct `convert`
70
- command. `get_authoring_context` returns a focused contract and safe defaults, while
71
- the complete catalog remains available at `docblocks://authoring-guide`.
70
+ command. Plain text or ordinary Markdown can be passed directly to
71
+ `convert_document` without a preflight; compatible templates are chosen automatically,
72
+ and explicit Squisq annotations remain optional overrides. `get_authoring_context` is
73
+ optional discovery for exact annotation examples and safe defaults; the complete catalog remains
74
+ available at `docblocks://authoring-guide`.
72
75
 
73
76
  `convert` and `video` accept Markdown, Squisq JSON Doc, DBK/ZIP, folders, and
74
77
  import-capable linked-registry formats. `build` replaces generated HTML files;
@@ -6,7 +6,7 @@ Run `npm run generate:notices` from the repository root.
6
6
  Resolved runtime and optional dependency closure declared by packages/cli/package.json.
7
7
 
8
8
  Inventory source: package-lock.json.
9
- Components: 347.
9
+ Components: 348.
10
10
 
11
11
  This notice is included in the published npm tarball. Transitive packages installed by npm also retain their package-local license files.
12
12
 
@@ -15,11 +15,11 @@ This notice is included in the published npm tarball. Transitive packages instal
15
15
  | Package | Version | License | Source |
16
16
  | --- | --- | --- | --- |
17
17
  | @antfu/install-pkg | 1.1.0 | MIT | https://github.com/antfu/install-pkg |
18
- | @bendyline/squisq | 2.4.1 | MIT | https://github.com/bendyline/squisq |
19
- | @bendyline/squisq-cli | 2.4.1 | MIT | https://github.com/bendyline/squisq |
20
- | @bendyline/squisq-formats | 2.3.5 | MIT | https://github.com/bendyline/squisq |
21
- | @bendyline/squisq-react | 2.4.1 | MIT | https://github.com/bendyline/squisq |
22
- | @bendyline/squisq-video | 2.2.5 | MIT | https://github.com/bendyline/squisq |
18
+ | @bendyline/squisq | 2.4.3 | MIT | https://github.com/bendyline/squisq |
19
+ | @bendyline/squisq-cli | 2.4.3 | MIT | https://github.com/bendyline/squisq |
20
+ | @bendyline/squisq-formats | 2.3.7 | MIT | https://github.com/bendyline/squisq |
21
+ | @bendyline/squisq-react | 2.4.5 | MIT | https://github.com/bendyline/squisq |
22
+ | @bendyline/squisq-video | 2.2.7 | MIT | https://github.com/bendyline/squisq |
23
23
  | @braintree/sanitize-url | 7.1.2 | MIT | https://github.com/braintree/sanitize-url |
24
24
  | @chevrotain/types | 11.1.2 | Apache-2.0 | https://github.com/Chevrotain/chevrotain |
25
25
  | @ffmpeg/ffmpeg | 0.12.15 | MIT | https://github.com/ffmpegwasm/ffmpeg.wasm |
@@ -42,6 +42,7 @@ This notice is included in the published npm tarball. Transitive packages instal
42
42
  | @napi-rs/canvas-linux-x64-musl | 0.1.100 | MIT | https://www.npmjs.com/package/@napi-rs/canvas-linux-x64-musl |
43
43
  | @napi-rs/canvas-win32-arm64-msvc | 0.1.100 | MIT | https://www.npmjs.com/package/@napi-rs/canvas-win32-arm64-msvc |
44
44
  | @napi-rs/canvas-win32-x64-msvc | 0.1.100 | MIT | https://github.com/Brooooooklyn/canvas |
45
+ | @pdf-lib/fontkit | 1.1.1 | MIT | https://github.com/Hopding/fontkit |
45
46
  | @pdf-lib/standard-fonts | 1.0.0 | MIT | https://github.com/Hopding/standard-fonts |
46
47
  | @pdf-lib/upng | 1.0.1 | MIT | https://github.com/Hopding/upng |
47
48
  | @types/d3 | 7.4.3 | MIT | https://github.com/DefinitelyTyped/DefinitelyTyped |
@@ -366,6 +367,14 @@ This notice is included in the published npm tarball. Transitive packages instal
366
367
 
367
368
  Package-local license, copying, and notice files are reproduced below. Where a published package omits its repository license, the reviewed aggregate or README identified in `Source files` supplies the retained material.
368
369
 
370
+ ### Packages whose npm archive omits license text
371
+
372
+ The following locked packages declare a license identifier but publish no package-local license/copying/notice file. Their identifiers and source locations are retained here for distribution review:
373
+
374
+ | Package | Version | Declared license | Source |
375
+ | --- | --- | --- | --- |
376
+ | @pdf-lib/fontkit | 1.1.1 | MIT | https://github.com/Hopding/fontkit |
377
+
369
378
  ==============================================================================
370
379
  Components: @antfu/install-pkg@1.1.0
371
380
  Source files: node_modules/@antfu/install-pkg/LICENSE
@@ -393,7 +402,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
393
402
  SOFTWARE.
394
403
 
395
404
  ==============================================================================
396
- Components: @bendyline/squisq-cli@2.4.1, @bendyline/squisq-formats@2.3.5, @bendyline/squisq-react@2.4.1, @bendyline/squisq-video@2.2.5, @bendyline/squisq@2.4.1
405
+ Components: @bendyline/squisq-cli@2.4.3, @bendyline/squisq-formats@2.3.7, @bendyline/squisq-react@2.4.5, @bendyline/squisq-video@2.2.7, @bendyline/squisq@2.4.3
397
406
  Source files: node_modules/@bendyline/squisq-cli/LICENSE, node_modules/@bendyline/squisq-formats/LICENSE, node_modules/@bendyline/squisq-react/LICENSE, node_modules/@bendyline/squisq-video/LICENSE, node_modules/@bendyline/squisq/LICENSE
398
407
  ==============================================================================
399
408
  MIT License
@@ -663,7 +672,7 @@ This software contains code derived from the Puppeteer project (https://github.c
663
672
  available under the Apache 2.0 license (https://github.com/puppeteer/puppeteer/blob/master/LICENSE).
664
673
 
665
674
  ==============================================================================
666
- Components: @bendyline/squisq-cli@2.4.1
675
+ Components: @bendyline/squisq-cli@2.4.3
667
676
  Source files: node_modules/@bendyline/squisq-cli/NOTICE.md
668
677
  ==============================================================================
669
678
  # Third-Party Notices for @bendyline/squisq-cli
@@ -683,12 +692,12 @@ Copyright and complete license texts for these dependencies are included in
683
692
  their respective npm distributions and source repositories.
684
693
 
685
694
  ==============================================================================
686
- Components: @bendyline/squisq-cli@2.4.1
695
+ Components: @bendyline/squisq-cli@2.4.3
687
696
  Source files: node_modules/@bendyline/squisq-cli/THIRD_PARTY_LICENSES.txt
688
697
  ==============================================================================
689
698
  THIRD-PARTY LICENSES FOR @bendyline/squisq-cli
690
699
 
691
- The inventory below covers the bundled light standalone player artifact.
700
+ The inventory below covers the bundled light and full standalone player artifacts.
692
701
 
693
702
  Generated from the actual esbuild input graph. Package-local license, copying,
694
703
  and notice files are reproduced verbatim. When an npm tarball omits its
@@ -5171,7 +5180,7 @@ The above copyright notice and this permission notice shall be included in all c
5171
5180
  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
5172
5181
 
5173
5182
  ==============================================================================
5174
- Components: @bendyline/squisq-formats@2.3.5
5183
+ Components: @bendyline/squisq-formats@2.3.7
5175
5184
  Source files: node_modules/@bendyline/squisq-formats/NOTICE.md
5176
5185
  ==============================================================================
5177
5186
  # Third-Party Notices for @bendyline/squisq-formats
@@ -5182,20 +5191,21 @@ Third-party components remain under their respective license terms.
5182
5191
 
5183
5192
  ## Runtime dependencies
5184
5193
 
5185
- | Package | Version | License | Repository |
5186
- | -------------- | ------- | ----------------------- | -------------------------------- |
5187
- | @pdf-lib/upng | 1.0.1 | MIT | https://github.com/Hopding/upng |
5188
- | @xmldom/xmldom | 0.9.10 | MIT | https://github.com/xmldom/xmldom |
5189
- | jszip | 3.10.1 | MIT OR GPL-3.0-or-later | https://github.com/Stuk/jszip |
5190
- | pdf-lib | 1.17.1 | MIT | https://pdf-lib.js.org |
5191
- | pdfjs-dist | 4.10.38 | Apache-2.0 | https://mozilla.github.io/pdf.js |
5194
+ | Package | Version | License | Repository |
5195
+ | ---------------- | ------- | ----------------------- | ---------------------------------- |
5196
+ | @pdf-lib/fontkit | 1.1.1 | MIT | https://github.com/Hopding/fontkit |
5197
+ | @pdf-lib/upng | 1.0.1 | MIT | https://github.com/Hopding/upng |
5198
+ | @xmldom/xmldom | 0.9.10 | MIT | https://github.com/xmldom/xmldom |
5199
+ | jszip | 3.10.1 | MIT OR GPL-3.0-or-later | https://github.com/Stuk/jszip |
5200
+ | pdf-lib | 1.17.1 | MIT | https://pdf-lib.js.org |
5201
+ | pdfjs-dist | 4.10.38 | Apache-2.0 | https://mozilla.github.io/pdf.js |
5192
5202
 
5193
5203
  Squisq uses jszip under its MIT license option. Copyright and complete license
5194
5204
  texts for these dependencies are included in their respective npm
5195
5205
  distributions and source repositories.
5196
5206
 
5197
5207
  ==============================================================================
5198
- Components: @bendyline/squisq-formats@2.3.5
5208
+ Components: @bendyline/squisq-formats@2.3.7
5199
5209
  Source files: node_modules/@bendyline/squisq-formats/THIRD_PARTY_LICENSES.txt
5200
5210
  ==============================================================================
5201
5211
  THIRD-PARTY LICENSES FOR @bendyline/squisq-formats
@@ -5205,9 +5215,179 @@ and notice files are reproduced verbatim. When an npm tarball omits its
5205
5215
  repository license, the pinned upstream copy is vendored and identified below.
5206
5216
 
5207
5217
  COMPONENTS
5218
+ - @fortawesome/fontawesome-free@7.2.0 ((CC-BY-4.0 AND OFL-1.1 AND MIT)); files: LICENSE.txt
5219
+
5220
+ ==============================================================================
5221
+ @fortawesome/fontawesome-free@7.2.0 - LICENSE.txt
5222
+ ==============================================================================
5223
+ Fonticons, Inc. (https://fontawesome.com)
5224
+
5225
+ --------------------------------------------------------------------------------
5226
+
5227
+ Font Awesome Free License
5228
+
5229
+ Font Awesome Free is free, open source, and GPL friendly. You can use it for
5230
+ commercial projects, open source projects, or really almost whatever you want.
5231
+ Full Font Awesome Free license: https://fontawesome.com/license/free.
5232
+
5233
+ --------------------------------------------------------------------------------
5234
+
5235
+ # Icons: CC BY 4.0 License (https://creativecommons.org/licenses/by/4.0/)
5236
+
5237
+ The Font Awesome Free download is licensed under a Creative Commons
5238
+ Attribution 4.0 International License and applies to all icons packaged
5239
+ as SVG and JS file types.
5240
+
5241
+ --------------------------------------------------------------------------------
5242
+
5243
+ # Fonts: SIL OFL 1.1 License
5244
+
5245
+ In the Font Awesome Free download, the SIL OFL license applies to all icons
5246
+ packaged as web and desktop font files.
5247
+
5248
+ Copyright (c) 2026 Fonticons, Inc. (https://fontawesome.com)
5249
+ with Reserved Font Name: "Font Awesome".
5250
+
5251
+ This Font Software is licensed under the SIL Open Font License, Version 1.1.
5252
+ This license is copied below, and is also available with a FAQ at:
5253
+ http://scripts.sil.org/OFL
5254
+
5255
+ SIL OPEN FONT LICENSE
5256
+ Version 1.1 - 26 February 2007
5257
+
5258
+ PREAMBLE
5259
+ The goals of the Open Font License (OFL) are to stimulate worldwide
5260
+ development of collaborative font projects, to support the font creation
5261
+ efforts of academic and linguistic communities, and to provide a free and
5262
+ open framework in which fonts may be shared and improved in partnership
5263
+ with others.
5264
+
5265
+ The OFL allows the licensed fonts to be used, studied, modified and
5266
+ redistributed freely as long as they are not sold by themselves. The
5267
+ fonts, including any derivative works, can be bundled, embedded,
5268
+ redistributed and/or sold with any software provided that any reserved
5269
+ names are not used by derivative works. The fonts and derivatives,
5270
+ however, cannot be released under any other type of license. The
5271
+ requirement for fonts to remain under this license does not apply
5272
+ to any document created using the fonts or their derivatives.
5273
+
5274
+ DEFINITIONS
5275
+ "Font Software" refers to the set of files released by the Copyright
5276
+ Holder(s) under this license and clearly marked as such. This may
5277
+ include source files, build scripts and documentation.
5278
+
5279
+ "Reserved Font Name" refers to any names specified as such after the
5280
+ copyright statement(s).
5281
+
5282
+ "Original Version" refers to the collection of Font Software components as
5283
+ distributed by the Copyright Holder(s).
5284
+
5285
+ "Modified Version" refers to any derivative made by adding to, deleting,
5286
+ or substituting — in part or in whole — any of the components of the
5287
+ Original Version, by changing formats or by porting the Font Software to a
5288
+ new environment.
5289
+
5290
+ "Author" refers to any designer, engineer, programmer, technical
5291
+ writer or other person who contributed to the Font Software.
5292
+
5293
+ PERMISSION & CONDITIONS
5294
+ Permission is hereby granted, free of charge, to any person obtaining
5295
+ a copy of the Font Software, to use, study, copy, merge, embed, modify,
5296
+ redistribute, and sell modified and unmodified copies of the Font
5297
+ Software, subject to the following conditions:
5298
+
5299
+ 1) Neither the Font Software nor any of its individual components,
5300
+ in Original or Modified Versions, may be sold by itself.
5301
+
5302
+ 2) Original or Modified Versions of the Font Software may be bundled,
5303
+ redistributed and/or sold with any software, provided that each copy
5304
+ contains the above copyright notice and this license. These can be
5305
+ included either as stand-alone text files, human-readable headers or
5306
+ in the appropriate machine-readable metadata fields within text or
5307
+ binary files as long as those fields can be easily viewed by the user.
5308
+
5309
+ 3) No Modified Version of the Font Software may use the Reserved Font
5310
+ Name(s) unless explicit written permission is granted by the corresponding
5311
+ Copyright Holder. This restriction only applies to the primary font name as
5312
+ presented to the users.
5313
+
5314
+ 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
5315
+ Software shall not be used to promote, endorse or advertise any
5316
+ Modified Version, except to acknowledge the contribution(s) of the
5317
+ Copyright Holder(s) and the Author(s) or with their explicit written
5318
+ permission.
5319
+
5320
+ 5) The Font Software, modified or unmodified, in part or in whole,
5321
+ must be distributed entirely under this license, and must not be
5322
+ distributed under any other license. The requirement for fonts to
5323
+ remain under this license does not apply to any document created
5324
+ using the Font Software.
5325
+
5326
+ TERMINATION
5327
+ This license becomes null and void if any of the above conditions are
5328
+ not met.
5329
+
5330
+ DISCLAIMER
5331
+ THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
5332
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
5333
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
5334
+ OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
5335
+ COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
5336
+ INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
5337
+ DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
5338
+ FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
5339
+ OTHER DEALINGS IN THE FONT SOFTWARE.
5340
+
5341
+ --------------------------------------------------------------------------------
5342
+
5343
+ # Code: MIT License (https://opensource.org/licenses/MIT)
5344
+
5345
+ In the Font Awesome Free download, the MIT license applies to all non-font and
5346
+ non-icon files.
5347
+
5348
+ Copyright 2026 Fonticons, Inc.
5349
+
5350
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
5351
+ this software and associated documentation files (the "Software"), to deal in the
5352
+ Software without restriction, including without limitation the rights to use, copy,
5353
+ modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
5354
+ and to permit persons to whom the Software is furnished to do so, subject to the
5355
+ following conditions:
5356
+
5357
+ The above copyright notice and this permission notice shall be included in all
5358
+ copies or substantial portions of the Software.
5359
+
5360
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
5361
+ INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
5362
+ PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
5363
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
5364
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
5365
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
5366
+
5367
+ --------------------------------------------------------------------------------
5368
+
5369
+ # Attribution
5370
+
5371
+ Attribution is required by MIT, SIL OFL, and CC BY licenses. Downloaded Font
5372
+ Awesome Free files already contain embedded comments with sufficient
5373
+ attribution, so you shouldn't need to do anything additional when using these
5374
+ files normally.
5375
+
5376
+ We've kept attribution comments terse, so we ask that you do not actively work
5377
+ to remove them from files, especially code. They're a great way for folks to
5378
+ learn about Font Awesome.
5379
+
5380
+ --------------------------------------------------------------------------------
5381
+
5382
+ # Brand Icons
5383
+
5384
+ All brand icons are trademarks of their respective owners. The use of these
5385
+ trademarks does not indicate endorsement of the trademark holder by Font
5386
+ Awesome, nor vice versa. **Please do not use brand logos for any purpose except
5387
+ to represent the company, product, or service to which they refer.**
5208
5388
 
5209
5389
  ==============================================================================
5210
- Components: @bendyline/squisq-react@2.4.1
5390
+ Components: @bendyline/squisq-react@2.4.5
5211
5391
  Source files: node_modules/@bendyline/squisq-react/NOTICE.md
5212
5392
  ==============================================================================
5213
5393
  # Third-Party Notices for @bendyline/squisq-react
@@ -5231,7 +5411,7 @@ third-party license texts for the complete standalone bundle graph are shipped
5231
5411
  in THIRD_PARTY_LICENSES.txt.
5232
5412
 
5233
5413
  ==============================================================================
5234
- Components: @bendyline/squisq-react@2.4.1
5414
+ Components: @bendyline/squisq-react@2.4.5
5235
5415
  Source files: node_modules/@bendyline/squisq-react/THIRD_PARTY_LICENSES.txt
5236
5416
  ==============================================================================
5237
5417
  THIRD-PARTY LICENSES FOR @bendyline/squisq-react
@@ -9768,7 +9948,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
9768
9948
  SOFTWARE.
9769
9949
 
9770
9950
  ==============================================================================
9771
- Components: @bendyline/squisq-video@2.2.5
9951
+ Components: @bendyline/squisq-video@2.2.7
9772
9952
  Source files: node_modules/@bendyline/squisq-video/NOTICE.md
9773
9953
  ==============================================================================
9774
9954
  # Third-Party Notices for @bendyline/squisq-video
@@ -9793,7 +9973,7 @@ Copyright and complete license texts for the listed dependencies are included
9793
9973
  in their respective npm distributions and source repositories.
9794
9974
 
9795
9975
  ==============================================================================
9796
- Components: @bendyline/squisq-video@2.2.5
9976
+ Components: @bendyline/squisq-video@2.2.7
9797
9977
  Source files: node_modules/@bendyline/squisq-video/THIRD_PARTY_LICENSES.txt
9798
9978
  ==============================================================================
9799
9979
  THIRD-PARTY LICENSES FOR @bendyline/squisq-video
@@ -9805,7 +9985,7 @@ repository license, the pinned upstream copy is vendored and identified below.
9805
9985
  COMPONENTS
9806
9986
 
9807
9987
  ==============================================================================
9808
- Components: @bendyline/squisq@2.4.1
9988
+ Components: @bendyline/squisq@2.4.3
9809
9989
  Source files: node_modules/@bendyline/squisq/NOTICE.md
9810
9990
  ==============================================================================
9811
9991
  # Third-Party Notices for @bendyline/squisq
@@ -9836,7 +10016,7 @@ third-party license texts for bundled code and data are shipped in
9836
10016
  THIRD_PARTY_LICENSES.txt.
9837
10017
 
9838
10018
  ==============================================================================
9839
- Components: @bendyline/squisq@2.4.1
10019
+ Components: @bendyline/squisq@2.4.3
9840
10020
  Source files: node_modules/@bendyline/squisq/THIRD_PARTY_LICENSES.txt
9841
10021
  ==============================================================================
9842
10022
  THIRD-PARTY LICENSES FOR @bendyline/squisq
package/dist/bin.js CHANGED
@@ -1831,47 +1831,6 @@ async function inspectPreparedDocument(_documents, prepared, maximumBlocks = DEF
1831
1831
  diagnostics: boundDiagnostics(diagnostics, "inspect")
1832
1832
  };
1833
1833
  }
1834
- async function validatePreparedDocument(_documents, prepared, targetFormat, signal) {
1835
- throwIfAborted5(signal);
1836
- const normalizedTargetFormat = normalizeTargetFormat(targetFormat);
1837
- const { validateMarkdownSource } = await import("@bendyline/squisq/doc");
1838
- await yieldForCancellation(signal);
1839
- const assets = prepared.assets;
1840
- const validation = validateMarkdownSource(prepared.markdown, {
1841
- assets: new Set(assets.map((asset) => asset.path))
1842
- });
1843
- throwIfAborted5(signal);
1844
- const diagnostics = [
1845
- ...prepared.diagnostics,
1846
- ...validation.diagnostics.map(
1847
- (diagnostic) => mapDocDiagnostic(diagnostic, prepared.sourceFormat)
1848
- ),
1849
- ...missingAltTextDiagnostics(
1850
- prepared.markdownDoc,
1851
- normalizedTargetFormat ?? prepared.sourceFormat
1852
- ),
1853
- ...await authoringDiagnostics(
1854
- prepared,
1855
- "validate",
1856
- normalizedTargetFormat ?? prepared.sourceFormat,
1857
- signal
1858
- ),
1859
- ...normalizedTargetFormat ? await targetPreflight(prepared, normalizedTargetFormat, signal) : []
1860
- ];
1861
- await yieldForCancellation(signal);
1862
- const unique = boundDiagnostics(diagnostics, "validate");
1863
- throwIfAborted5(signal);
1864
- const summary = summarizeDiagnostics(unique);
1865
- return {
1866
- version: DOCBLOCKS_MCP_WIRE_VERSION,
1867
- kind: "validation",
1868
- sourceFormat: prepared.sourceFormat,
1869
- targetFormat: normalizedTargetFormat,
1870
- valid: summary.errorCount === 0,
1871
- summary,
1872
- diagnostics: unique
1873
- };
1874
- }
1875
1834
  function annotationSyntaxDiagnostics(markdown, stage, format) {
1876
1835
  const diagnostics = [];
1877
1836
  const lines = markdown.split(/\r?\n/);
@@ -1927,7 +1886,7 @@ function malformedAnnotationDiagnostic(stage, format, line, column, message) {
1927
1886
  format,
1928
1887
  count: 1,
1929
1888
  message,
1930
- remediation: 'Repair the annotation so it reads exactly `{[templateId key="value"]}` with no extra braces or brackets, then validate again.',
1889
+ remediation: 'Repair the annotation so it reads exactly `{[templateId key="value"]}` with no extra braces or brackets.',
1931
1890
  retryable: false,
1932
1891
  location: { kind: "source", line, column }
1933
1892
  };
@@ -2013,7 +1972,7 @@ async function authoringDiagnostics(prepared, stage, format, signal) {
2013
1972
  format,
2014
1973
  count: 1,
2015
1974
  message: `The complete body of block "${block.title ?? block.id}" is not present in its rendered text layers.`,
2016
- remediation: "Keep the content template and repair its inputs, then validate and preview again before conversion.",
1975
+ remediation: "Keep the content template or repair its inputs; request a preview only when visual evidence is useful.",
2017
1976
  retryable: false,
2018
1977
  location: {
2019
1978
  kind: "block",
@@ -2400,7 +2359,7 @@ function mapDocDiagnostic(diagnostic, format) {
2400
2359
  return {
2401
2360
  code: diagnostic.code,
2402
2361
  severity: diagnostic.severity,
2403
- stage: "validate",
2362
+ stage: "inspect",
2404
2363
  format,
2405
2364
  count: 1,
2406
2365
  message: diagnostic.message,
@@ -2429,7 +2388,7 @@ function missingAltTextDiagnostics(markdownDoc, format) {
2429
2388
  {
2430
2389
  code: "missing-alt-text",
2431
2390
  severity: "warning",
2432
- stage: "validate",
2391
+ stage: "inspect",
2433
2392
  format,
2434
2393
  count: missingCount,
2435
2394
  message: missingCount === 1 ? "One image has no alternative text." : `${missingCount} images have no alternative text.`,
@@ -2439,130 +2398,6 @@ function missingAltTextDiagnostics(markdownDoc, format) {
2439
2398
  }
2440
2399
  ];
2441
2400
  }
2442
- async function targetPreflight(prepared, targetFormat, signal) {
2443
- throwIfAborted5(signal);
2444
- const normalized = targetFormat.toLowerCase();
2445
- const { createCliRegistry: createCliRegistry2 } = await import("@bendyline/squisq-cli/api");
2446
- throwIfAborted5(signal);
2447
- const target = createCliRegistry2().get(normalized);
2448
- if (!target?.exportDoc) {
2449
- return [
2450
- {
2451
- code: target ? "unsupported-output" : "unknown-format",
2452
- severity: "error",
2453
- stage: "validate",
2454
- format: normalized,
2455
- count: 1,
2456
- message: target ? `${target.label} cannot be used as a conversion target.` : `Unknown target format "${normalized}".`,
2457
- remediation: "Choose an export-capable format from list_formats.",
2458
- retryable: false,
2459
- location: null
2460
- }
2461
- ];
2462
- }
2463
- const diagnostics = [];
2464
- const details = summarizeMarkdownNodes(prepared.markdownDoc);
2465
- const { flattenBlocks } = await import("@bendyline/squisq/doc");
2466
- const flatBlocks = flattenBlocks(prepared.doc.blocks);
2467
- await yieldForCancellation(signal);
2468
- if (["pptx", "pdf", "mp4", "gif"].includes(normalized)) {
2469
- let denseBlockCount = 0;
2470
- let firstDenseBlock = null;
2471
- let analyzedIndex = 0;
2472
- for (const entry of await analyzeDocumentBlocks(prepared.doc.blocks)) {
2473
- const checkpoint = cancellationCheckpoint(signal, analyzedIndex);
2474
- if (checkpoint) await checkpoint;
2475
- analyzedIndex += 1;
2476
- if (entry.bodyWordCount <= 120 && entry.plainText.length <= 900) continue;
2477
- denseBlockCount += 1;
2478
- firstDenseBlock ?? (firstDenseBlock = entry.block);
2479
- }
2480
- if (denseBlockCount > 0) {
2481
- diagnostics.push({
2482
- code: "content-density-high",
2483
- severity: "warning",
2484
- stage: "validate",
2485
- format: normalized,
2486
- count: denseBlockCount,
2487
- message: denseBlockCount === 1 ? `Block "${firstDenseBlock?.title ?? firstDenseBlock?.id ?? "unknown"}" may be too dense for a single rendered item.` : `${denseBlockCount} blocks may be too dense for a single rendered item.`,
2488
- remediation: "Split the block, shorten prose, or confirm the result with preview_document overflow diagnostics.",
2489
- retryable: false,
2490
- location: denseBlockCount === 1 && firstDenseBlock ? {
2491
- kind: "block",
2492
- blockId: toWireIdentifier(firstDenseBlock.id, "block"),
2493
- nodeType: "block"
2494
- } : null
2495
- });
2496
- }
2497
- const denseTables = details.tables.filter(
2498
- (table) => table.columnCount > 8 || table.rowCount > 30
2499
- );
2500
- if (denseTables.length > 0) {
2501
- const firstDenseTable = denseTables[0];
2502
- diagnostics.push({
2503
- code: "table-density-high",
2504
- severity: "warning",
2505
- stage: "validate",
2506
- format: normalized,
2507
- count: denseTables.length,
2508
- message: denseTables.length === 1 && firstDenseTable ? `Table ${firstDenseTable.index + 1} has ${firstDenseTable.rowCount} rows and ${firstDenseTable.columnCount} columns and may overflow.` : `${denseTables.length} tables may overflow the rendered output.`,
2509
- remediation: "Split the table or use a spreadsheet target; verify visual clipping with preview_document.",
2510
- retryable: false,
2511
- location: null
2512
- });
2513
- }
2514
- }
2515
- if (normalized === "pptx" && flatBlocks.some((block) => block.template)) {
2516
- diagnostics.push(
2517
- warningDiagnostic(
2518
- "Editable-native PPTX export preserves semantic content and theme but does not reproduce arbitrary Squisq template geometry.",
2519
- "validate",
2520
- normalized
2521
- )
2522
- );
2523
- }
2524
- if (normalized === "pdf" && await hasImages(prepared.markdownDoc, signal)) {
2525
- diagnostics.push(
2526
- warningDiagnostic(
2527
- "Native PDF export currently represents Markdown images as labeled placeholders.",
2528
- "validate",
2529
- normalized
2530
- )
2531
- );
2532
- }
2533
- if ((normalized === "csv" || normalized === "xlsx") && details.tableCount === 0) {
2534
- diagnostics.push(
2535
- warningDiagnostic(
2536
- `${normalized.toUpperCase()} export is table-oriented; this document contains no Markdown tables.`,
2537
- "validate",
2538
- normalized
2539
- )
2540
- );
2541
- }
2542
- if (normalized === "gif" && (prepared.doc.audio?.segments?.length ?? 0) > 0) {
2543
- diagnostics.push(
2544
- warningDiagnostic(
2545
- "Animated GIF does not support audio; audio will be omitted.",
2546
- "validate",
2547
- normalized
2548
- )
2549
- );
2550
- }
2551
- return diagnostics;
2552
- }
2553
- async function hasImages(markdownDoc, signal) {
2554
- throwIfAborted5(signal);
2555
- let found = false;
2556
- const visit = (node) => {
2557
- if (found || !node || typeof node !== "object") return;
2558
- const candidate = node;
2559
- if (candidate.type === "image" || candidate.type === "imageReference") found = true;
2560
- if (Array.isArray(candidate.children)) candidate.children.forEach(visit);
2561
- };
2562
- visit(markdownDoc);
2563
- await yieldForCancellation(signal);
2564
- return found;
2565
- }
2566
2401
  function boundDiagnostics(diagnostics, stage) {
2567
2402
  const aggregated = aggregateDiagnostics(diagnostics);
2568
2403
  if (aggregated.length <= MAX_DIAGNOSTICS) return aggregated;
@@ -2643,29 +2478,6 @@ function sameLocation(left, right) {
2643
2478
  function safeDiagnosticCountSum(left, right) {
2644
2479
  return Math.min(Number.MAX_SAFE_INTEGER, left + right);
2645
2480
  }
2646
- function summarizeDiagnostics(diagnostics) {
2647
- let errorCount = 0;
2648
- let warningCount2 = 0;
2649
- let infoCount = 0;
2650
- for (const diagnostic of diagnostics) {
2651
- if (diagnostic.severity === "error") {
2652
- errorCount = safeDiagnosticCountSum(errorCount, diagnostic.count);
2653
- } else if (diagnostic.severity === "warning") {
2654
- warningCount2 = safeDiagnosticCountSum(warningCount2, diagnostic.count);
2655
- } else {
2656
- infoCount = safeDiagnosticCountSum(infoCount, diagnostic.count);
2657
- }
2658
- }
2659
- return { errorCount, warningCount: warningCount2, infoCount };
2660
- }
2661
- function normalizeTargetFormat(targetFormat) {
2662
- if (targetFormat === null) return null;
2663
- const normalized = targetFormat.toLowerCase();
2664
- if (!FORMAT_PATTERN.test(normalized)) {
2665
- throw new Error(`Invalid target format "${targetFormat.slice(0, 64)}"`);
2666
- }
2667
- return normalized;
2668
- }
2669
2481
  function words(text) {
2670
2482
  return text.toLowerCase().match(/[\p{L}\p{N}]+/gu) ?? [];
2671
2483
  }
@@ -4235,8 +4047,7 @@ import {
4235
4047
  parseDocumentSource,
4236
4048
  parseInspectionResult,
4237
4049
  parseMaterializationOptions,
4238
- parsePreviewResult,
4239
- parseValidationResult
4050
+ parsePreviewResult
4240
4051
  } from "@bendyline/docblocks/mcp";
4241
4052
  import {
4242
4053
  artifactUriSchema,
@@ -4288,13 +4099,15 @@ function registerAgenticTools(server, context) {
4288
4099
  server.registerTool(
4289
4100
  "convert_document",
4290
4101
  {
4291
- description: "Convert any linked-registry input into one or more immutable artifacts. Use save_artifact only when a durable filesystem file is required.",
4102
+ description: "Convert plain text, Markdown, bundles, or linked-registry inputs directly into one or more immutable artifacts. Plain Markdown needs no preflight or annotations; valid Squisq annotations are optional layout hints. Use save_artifact only for durable filesystem output.",
4292
4103
  inputSchema: z.object({
4293
4104
  source: documentSourceSchema,
4294
4105
  targets: z.array(conversionTargetSchema).min(1).max(12),
4295
4106
  themeId: identifierSchema.optional(),
4296
4107
  transformId: identifierSchema.optional(),
4297
- autoTemplates: z.boolean().optional(),
4108
+ autoTemplates: z.boolean().optional().describe(
4109
+ "Enable content-aware automatic template selection. Defaults to true; explicit annotations still take precedence."
4110
+ ),
4298
4111
  title: z.string().max(4e3).optional()
4299
4112
  }).strict(),
4300
4113
  outputSchema: DOCBLOCKS_MCP_TOOL_OUTPUT_SCHEMAS.convert_document,
@@ -4314,7 +4127,7 @@ function registerAgenticTools(server, context) {
4314
4127
  targets: targets.map(toConversionTarget),
4315
4128
  themeId,
4316
4129
  transformId,
4317
- autoTemplates,
4130
+ autoTemplates: autoTemplates ?? true,
4318
4131
  title
4319
4132
  },
4320
4133
  operationSignal,
@@ -4338,7 +4151,7 @@ function registerAgenticTools(server, context) {
4338
4151
  server.registerTool(
4339
4152
  "create_document_bundle",
4340
4153
  {
4341
- description: "Stage Markdown plus authority-scoped assets as a reusable immutable DBK artifact when the same complete draft will be passed to two or more validate, inspect, preview, or convert calls. Pass its artifact URI instead of repeating the Markdown.",
4154
+ description: "Stage Markdown plus authority-scoped assets as a reusable immutable DBK artifact when assets must travel with the document or the same draft will be passed to two or more inspect, preview, or convert calls. Pass its artifact URI instead of repeating the Markdown.",
4342
4155
  inputSchema: z.object({ source: bundleDocumentSourceSchema }).strict(),
4343
4156
  outputSchema: DOCBLOCKS_MCP_TOOL_OUTPUT_SCHEMAS.create_document_bundle,
4344
4157
  annotations: ARTIFACT_CREATING
@@ -4412,7 +4225,7 @@ function registerAgenticTools(server, context) {
4412
4225
  server.registerTool(
4413
4226
  "inspect_document",
4414
4227
  {
4415
- description: "Inspect bounded semantic structure, block provenance, assets, metadata, theme, and diagnostics. Use for those details; do not pair it with validate_document for a routine export preflight.",
4228
+ description: "Inspect bounded semantic structure, block provenance, assets, metadata, theme, and diagnostics when the user asks for document analysis. Inspection is never required before conversion.",
4416
4229
  inputSchema: z.object({
4417
4230
  source: documentSourceSchema,
4418
4231
  maxBlocks: z.number().int().min(1).max(2e3).optional(),
@@ -4441,37 +4254,6 @@ function registerAgenticTools(server, context) {
4441
4254
  }
4442
4255
  }
4443
4256
  );
4444
- server.registerTool(
4445
- "validate_document",
4446
- {
4447
- description: "Primary pre-export review for structure, template content retention, annotations, assets, accessibility, and target fidelity. Diagnostics include repairs; normally do not also call inspect_document.",
4448
- inputSchema: z.object({
4449
- source: documentSourceSchema,
4450
- targetFormat: formatInputSchema.nullable().optional()
4451
- }).strict(),
4452
- outputSchema: DOCBLOCKS_MCP_TOOL_OUTPUT_SCHEMAS.validate_document,
4453
- annotations: READ_ONLY
4454
- },
4455
- async ({ source, targetFormat }, extra) => {
4456
- try {
4457
- return await context.runOperation(extra.signal, async (operationSignal) => {
4458
- const documents = new DocumentService(await context.authority, context.artifacts);
4459
- const prepared = await documents.prepare(requireDocumentSource(source), operationSignal);
4460
- const normalizedTargetFormat = targetFormat?.toLowerCase() ?? null;
4461
- const result = await validatePreparedDocument(
4462
- documents,
4463
- prepared,
4464
- normalizedTargetFormat,
4465
- operationSignal
4466
- );
4467
- requireWire(parseValidationResult(result), "validation");
4468
- return textAndStructured(result);
4469
- });
4470
- } catch (caught) {
4471
- return errorResult(caught, "validate", null, extra.signal);
4472
- }
4473
- }
4474
- );
4475
4257
  server.registerTool(
4476
4258
  "compare_documents",
4477
4259
  {
@@ -4628,18 +4410,14 @@ function registerAuthoringGuideResource(server) {
4628
4410
  import("@bendyline/squisq/transform")
4629
4411
  ]);
4630
4412
  const guide = {
4631
- version: 7,
4413
+ version: 8,
4632
4414
  workflow: [
4633
- "treat supplied facts as a closed evidence set; label calculations, assumptions, hypotheses, recommendations, and examples; do not present causal links, rhetorical performance labels, superlatives, sole causes, targets, capabilities, owners, dates, channels, or operational details as established facts unless supplied",
4634
- "when the requested genre needs unsupplied roles, gates, timelines, channels, or procedures, add one explicit proposed operating model scope note that applies to those details, then complete the requested element",
4635
- "author complete Squisq-compatible Markdown with annotations bound to headings; ordinary headings default to the loss-averse content template",
4636
- "for PPTX, use exactly one level-one Markdown heading per slide and no level-two through level-six headings because every heading becomes a slide by default",
4637
- "by default, pass the complete Markdown\u2014or a bundle source when assets are needed\u2014directly to convert_document; revise by editing the complete Markdown and converting again",
4638
- "use create_document_bundle when the same complete draft will be passed to two or more validate, inspect, preview, or convert calls, then pass its artifact URI instead of repeating Markdown",
4639
- "use validate_document as the routine export preflight; use inspect_document only for semantic structure, provenance, assets, metadata, or theme details; use preview_document only when visual evidence is useful",
4640
- "for visual polish, replace selected content blocks with compatible visual templates while preserving required content",
4641
- "convert_document creates one or more immutable artifacts from the authoritative complete source",
4642
- "save_artifact only when a durable file is required"
4415
+ "plain text and ordinary Markdown can be passed directly to convert_document without a preflight or template annotations",
4416
+ "for deliberate PPTX slide boundaries, use one level-one Markdown heading per slide; unstructured text is still accepted",
4417
+ "convert_document chooses compatible templates automatically; Squisq annotations on headings are optional layout hints that take precedence",
4418
+ "use a bundle source when assets must travel with the document, or create_document_bundle when one draft will be reused by two or more inspect, preview, or convert calls",
4419
+ "use inspect_document or preview_document only when the user asks for document analysis or visual evidence",
4420
+ "convert_document creates immutable artifacts; save_artifact only when a durable file is required"
4643
4421
  ],
4644
4422
  markdownAnnotation: '# Heading {[templateId key="value"]}',
4645
4423
  standaloneAnnotation: '{[templateId key="value"]}',
@@ -4680,7 +4458,7 @@ function registerTemplateTools(server, context) {
4680
4458
  server.registerTool(
4681
4459
  "get_authoring_context",
4682
4460
  {
4683
- description: "Get a focused authoring contract, target capability, safe default template, themes, transforms, and optional source-based recommendations. Exact full template inputs remain on demand through describe_template or docblocks://authoring-guide.",
4461
+ description: "Optionally discover target capabilities, safe defaults, themes, transforms, and exact starter annotation examples. Plain Markdown can be converted without calling this tool.",
4684
4462
  inputSchema: z.object({
4685
4463
  targetFormat: formatInputSchema.optional(),
4686
4464
  goal: z.enum(["content-first", "visual-polish"]).optional(),
@@ -4751,17 +4529,14 @@ function registerTemplateTools(server, context) {
4751
4529
  goal,
4752
4530
  targetFormat: normalizedTarget,
4753
4531
  defaultTemplateId: "content",
4754
- defaultFidelity: authoringDefaultFidelity(normalizedTarget, goal),
4532
+ defaultFidelity: authoringDefaultFidelity(normalizedTarget),
4755
4533
  workflow: [
4756
4534
  "For durable local output, call list_roots before drafting. If no returned root is write-enabled, stop and explain that the MCP server must restart with --allow-write; do not fall back to a shell or CLI converter. A transient artifact is acceptable only when the user did not require a file.",
4757
- "Treat supplied facts as a closed evidence set. Preserve them exactly; label calculations, assumptions, hypotheses, recommendations, causal claims, capabilities, owners, dates, and unsupplied operating details. When a requested policy or playbook needs invented procedures, introduce one proposed operating model scope note before those details.",
4758
- normalizedTarget === "pptx" ? "Match every explicitly requested slide count exactly. Use exactly one level-one Markdown heading (#) per slide and no level-two through level-six headings because every heading becomes a slide by default. Target at most 80 words per slide, and use lists, tables, or bold labels for within-slide structure." : "Honor the requested word range and document genre. Prefer connected memo prose for executive decisions and native headings, tables, and checklists for operational documents.",
4759
- "Author the complete Squisq-compatible Markdown with annotations bound to headings. Ordinary headings default to the loss-averse content template; keep that default until the complete content is sound.",
4760
- "Before conversion, count slide sections or document words, verify every requested element, and rewrite or label unsupported claims. For decisions, ground tradeoffs in supplied alternatives and label unsupplied accountability, capacity, outcomes, and review cadences as proposed or assumed.",
4761
- "Use validate_document as the routine export preflight and follow its repair diagnostics. Call inspect_document only when semantic structure, provenance, assets, metadata, or theme details are needed.",
4762
- "When the same complete draft will feed two or more validate, inspect, preview, or convert calls, stage it once with create_document_bundle and reuse its artifact URI; after edits, stage the revised draft again.",
4763
- normalizedTarget === "pptx" ? "For visual polish, call recommend_templates on the complete draft, then describe_template only for selected candidates before replacing content blocks. Preserve required content and use preview_document only when visual evidence is needed." : annotationHandling === "ignored" ? "This target flattens template annotations to semantic content, so visual templates have no effect on the exported file: rely on native headings, tables, and checklists for structure and scanning." : "For visual polish, use native headings, tables, and checklists where they improve scanning; describe a selected visual template before use and keep complete-body content when it would discard detail.",
4764
- "Pass the authoritative Markdown or bundle source directly to convert_document. It returns immutable artifacts; call save_artifact only for final durable outputs and never switch to a shell or CLI converter."
4535
+ normalizedTarget === "pptx" ? "Plain text and ordinary Markdown convert directly. Use one level-one Markdown heading (#) for each deliberate slide boundary; unstructured text is still accepted." : "Plain text and ordinary Markdown convert directly without a preflight.",
4536
+ "convert_document chooses compatible templates automatically. Annotations on headings are optional layout hints that take precedence; use the returned exact starter examples when useful.",
4537
+ annotationHandling === "ignored" ? "This target flattens template annotations to semantic content, so annotations are unnecessary for the exported file." : "Explicit valid annotations override automatic layout choices; invalid or unnecessary annotations should be omitted rather than repaired through a separate workflow.",
4538
+ "Pass Markdown directly to convert_document. Use a bundle source for assets, or create_document_bundle only when one draft will be reused by two or more inspect, preview, or convert calls.",
4539
+ "Use inspect_document or preview_document only when the user asks for document analysis or visual evidence. Save only final durable artifacts with save_artifact."
4765
4540
  ],
4766
4541
  syntax: {
4767
4542
  headingAnnotation: "# Heading {[content]}",
@@ -4769,7 +4544,11 @@ function registerTemplateTools(server, context) {
4769
4544
  standaloneWarning: "A standalone annotation creates an additional heading-less block. Bind it to a heading unless that extra block is deliberate."
4770
4545
  },
4771
4546
  formats: normalizedTarget ? formats.filter((format) => format.id === normalizedTarget) : formats,
4772
- templates: focusedAuthoringTemplates(candidateTemplates, recommendations),
4547
+ templates: focusedAuthoringTemplates(
4548
+ candidateTemplates,
4549
+ recommendations,
4550
+ normalizedTarget
4551
+ ),
4773
4552
  themes: schemaModule.getThemeSummaries().slice(0, MCP_WIRE_LIMITS7.arrayEntries).map((theme) => ({
4774
4553
  id: requireWireIdentifier(theme.id, "theme id"),
4775
4554
  name: boundWireText(theme.name, MCP_WIRE_LIMITS7.labelCharacters, theme.id),
@@ -4838,7 +4617,7 @@ function registerTemplateTools(server, context) {
4838
4617
  (template2) => template2.id === templateId
4839
4618
  );
4840
4619
  if (!described) {
4841
- return errorResult(new Error(`Unknown template "${templateId}"`), "validate");
4620
+ return errorResult(new Error(`Unknown template "${templateId}"`), "inspect");
4842
4621
  }
4843
4622
  const template = {
4844
4623
  id: described.id,
@@ -4935,7 +4714,7 @@ function registerThemeTools(server, context) {
4935
4714
  const documentTheme = prepared?.doc.customThemes?.find((theme2) => theme2.id === themeId);
4936
4715
  const builtIn = Object.prototype.hasOwnProperty.call(schemaModule.THEMES, themeId);
4937
4716
  if (!documentTheme && !builtIn) {
4938
- return errorResult(new Error(`Unknown theme "${themeId}"`), "validate");
4717
+ return errorResult(new Error(`Unknown theme "${themeId}"`), "inspect");
4939
4718
  }
4940
4719
  const theme = docModule.resolveThemeForDoc(prepared?.doc, themeId);
4941
4720
  return textAndStructured({
@@ -5222,8 +5001,13 @@ function rootDiscoveryText(roots) {
5222
5001
 
5223
5002
  No returned root is write-enabled. Durable file output is unavailable: restart the server with --allow-write <directory>. Do not fall back to a shell or CLI converter.`;
5224
5003
  }
5225
- function focusedAuthoringTemplates(candidates, recommendations) {
5004
+ function focusedAuthoringTemplates(candidates, recommendations, targetFormat) {
5226
5005
  const selectedIds = /* @__PURE__ */ new Set(["content"]);
5006
+ if (targetFormat === "pptx") {
5007
+ for (const templateId of ["title", "sectionHeader", "statHighlight", "quote"]) {
5008
+ selectedIds.add(templateId);
5009
+ }
5010
+ }
5227
5011
  for (const recommendation of recommendations) {
5228
5012
  for (const templateId of recommendation.recommendedTemplateIds) {
5229
5013
  selectedIds.add(templateId);
@@ -5237,14 +5021,15 @@ function compactAuthoringContextText(context) {
5237
5021
  `DocBlocks authoring contract: ${target}, ${context.goal}.`,
5238
5022
  `Default template: ${context.defaultTemplateId}. Default fidelity: ${context.defaultFidelity ?? "select for target"}.`,
5239
5023
  "",
5240
- "Required workflow:",
5024
+ "Optional guidance:",
5241
5025
  ...context.workflow.map((step, index) => `${index + 1}. ${step}`),
5242
5026
  "",
5243
5027
  `Heading annotation: ${context.syntax.headingAnnotation}`,
5244
5028
  `Warning: ${context.syntax.standaloneWarning}`,
5245
5029
  `Templates (${context.templates.length}): ${context.templates.map(({ id }) => id).join(", ")}`,
5030
+ ...context.templates.filter(({ id }) => id !== "content").map(({ annotationExample }) => `Optional example: ${annotationExample}`),
5246
5031
  `Themes (${context.themes.length}): ${context.themes.map(({ id }) => id).join(", ")}`,
5247
- `Transform styles (${context.transformStyles.length}): ${context.transformStyles.map(({ id }) => id).join(", ")} \u2014 transforms re-compose blocks and can change section count; avoid on exact-count briefs.`
5032
+ `Transform styles (${context.transformStyles.length}): ${context.transformStyles.map(({ id }) => id).join(", ")}.`
5248
5033
  ];
5249
5034
  if (context.recommendations.length > 0) {
5250
5035
  lines.push(
@@ -5332,12 +5117,9 @@ async function targetTemplateAnnotationHandling(targetFormat) {
5332
5117
  }
5333
5118
  return null;
5334
5119
  }
5335
- function authoringDefaultFidelity(targetFormat, goal) {
5120
+ function authoringDefaultFidelity(targetFormat) {
5336
5121
  if (!targetFormat) return null;
5337
5122
  if (targetFormat === "mp4" || targetFormat === "gif") return "rendered-fidelity";
5338
- if (goal === "visual-polish" && (targetFormat === "pptx" || targetFormat === "pdf")) {
5339
- return "rendered-fidelity";
5340
- }
5341
5123
  if (targetFormat === "docx" || targetFormat === "pptx" || targetFormat === "xlsx") {
5342
5124
  return "editable-native";
5343
5125
  }
@@ -5663,7 +5445,7 @@ function registerAuthoringPrompts(server) {
5663
5445
  const presentation = server.registerPrompt(
5664
5446
  "create-presentation",
5665
5447
  {
5666
- description: "Create, validate, preview, and export an artifact-first presentation.",
5448
+ description: "Convert model-authored Markdown into an artifact-first presentation.",
5667
5449
  argsSchema: presentationArgs.shape
5668
5450
  },
5669
5451
  async (args) => ({
@@ -5688,7 +5470,7 @@ function registerAuthoringPrompts(server) {
5688
5470
  const video = server.registerPrompt(
5689
5471
  "create-video",
5690
5472
  {
5691
- description: "Create, validate, preview, and export an artifact-first MP4 video.",
5473
+ description: "Convert model-authored Markdown into an artifact-first MP4 video.",
5692
5474
  argsSchema: videoArgs.shape
5693
5475
  },
5694
5476
  async (args) => ({
@@ -5713,7 +5495,7 @@ function registerAuthoringPrompts(server) {
5713
5495
  const document2 = server.registerPrompt(
5714
5496
  "create-document",
5715
5497
  {
5716
- description: "Create, validate, preview, and export an artifact-first document.",
5498
+ description: "Convert model-authored Markdown into an artifact-first document.",
5717
5499
  argsSchema: documentArgs.shape
5718
5500
  },
5719
5501
  async (args) => ({
@@ -5731,39 +5513,39 @@ function registerAuthoringPrompts(server) {
5731
5513
  document2.argsSchema = documentArgs;
5732
5514
  }
5733
5515
  function presentationPrompt(topic, style, theme, template) {
5516
+ const templateHint = template ? ` Use the requested \`${template}\` annotation where appropriate.` : "";
5517
+ const themeHint = theme ? ` with themeId \`${theme}\`` : "";
5518
+ const styleHint = style ? ` and transformId \`${style}\`` : "";
5734
5519
  return `Create a presentation about: ${topic}
5735
5520
 
5736
5521
  1. For durable output, call list_roots before drafting. If no returned root is write-enabled, stop and explain that the MCP server must restart with --allow-write; do not use a shell or CLI converter.
5737
- 2. Call get_authoring_context with targetFormat "pptx" and goal "content-first" for the focused linked-Squisq workflow and safe default. Read the full authoring-guide resource only if focused follow-up tools are insufficient.
5738
- 3. Treat the topic facts as a closed evidence set. Preserve them exactly, use temporal or correlational wording unless causality is supplied, and label calculations, assumptions, hypotheses, recommendations, and examples. Causal links, rhetorical performance labels, superlatives, sole causes, capabilities, owners, dates, channels, and operational details must be supplied or explicitly framed. Do not connect separate metrics, audiences, segments, or workflows unless the relationship is supplied. Prefer observed, coincided with, intended to, or proposed over drove, addresses, protects, or proves. Add decision value through supplied baselines, goals, targets, rankings, and transparent calculations. Do not call choices a sequence or capacity allocation unless order, timing, or resources were supplied. When the requested content needs unsupplied operating details, add one proposed operating model scope note that applies to them.
5739
- 4. Match every explicitly requested slide count exactly. Use exactly one level-one Markdown heading (\`#\`) per slide and no level-two through level-six headings because every heading becomes a slide by default; use lists, tables, or bold labels within a slide. Target at most 80 words per slide. Make slide one a supported point-of-view thesis, not a generic title or unsupported flourish. For requested choices, state concrete opportunity costs grounded in supplied alternatives and one clearly labeled proposed accountable role per choice. Label any unsupplied capacity or outcome assumption as \`Assumption:\` or \`Potential tradeoff:\`. Author complete Markdown sections with accessible alt text. Put annotations on headings, for example \`# Heading {[content]}\`; a standalone \`{[template]}\` creates an extra block. Prefer style "${style ?? "choose from the returned transform styles"}", theme "${theme ?? "choose from the returned themes"}", and template "${template ?? "content until visual optimization"}".
5740
- 5. Keep the complete Markdown as the authoritative draft. If it will feed two or more validate, inspect, preview, or convert calls, stage it once with create_document_bundle and reuse the artifact URI. Otherwise pass it\u2014or a bundle source when assets are needed\u2014directly to convert_document. Do not write a temporary local Markdown file or invent a root id.
5741
- 6. Before conversion, count slide sections, verify every requested element, and rewrite or label every unsupported claim. Use validate_document as the routine export preflight; use inspect_document only for semantic or metadata detail and preview_document only for visual evidence such as overflow. Repair findings in the complete Markdown.
5742
- 7. Only after content coverage is acceptable, call recommend_templates, describe only selected candidates, and replace compatible \`content\` blocks when their semantic inputs fit. Preserve required content.
5743
- 8. Call convert_document with the complete source and a pptx target. Choose editable-native for editable Office structures, rendered-fidelity for exact Squisq visuals, or hybrid for rendered visuals plus semantic retention. Revise by editing the complete Markdown and converting again.
5744
- 9. Use get_conversion_report for provenance and save_artifact only when a durable file is required.`;
5522
+ 2. Author plain Markdown. One level-one heading (\`#\`) creates each deliberate slide boundary; unstructured text is also accepted. Squisq annotations are optional layout hints.${templateHint} Call get_authoring_context only when exact annotation examples or theme details would help.
5523
+ 3. Pass the Markdown directly to convert_document with a pptx target${themeHint}${styleHint}. Use a bundle source only when assets must travel with the document. No validation, inspection, or preview is required.
5524
+ 4. Use inspect_document or preview_document only when the user explicitly asks for document analysis or visual evidence.
5525
+ 5. Call save_artifact only when a durable file is required.`;
5745
5526
  }
5746
5527
  function videoPrompt(topic, orientation, theme, template) {
5528
+ const templateHint = template ? ` Use the requested \`${template}\` annotation where appropriate.` : "";
5529
+ const themeHint = theme ? ` and themeId \`${theme}\`` : "";
5747
5530
  return `Create a video about: ${topic}
5748
5531
 
5749
5532
  1. For durable output, call list_roots before drafting and stop if no root is write-enabled; do not use a shell or CLI converter.
5750
- 2. Call get_authoring_context with targetFormat "mp4" for the focused linked-Squisq workflow.
5751
- 3. Author concise Markdown for a ${orientation ?? "landscape"} animated sequence using theme "${theme ?? "choose from the returned themes"}" and template "${template ?? "content until visual optimization"}". Bind annotations to headings.
5752
- 4. Keep the complete Markdown as the authoritative draft and pass it\u2014or a bundle source when assets are needed\u2014directly to convert_document. Use validate_document for uncertain target constraints and preview_document when representative-frame evidence is useful; repair findings in the complete Markdown.
5753
- 5. Call convert_document with the complete source, an mp4 target, and orientation "${orientation ?? "landscape"}"; monitor progress and honor cancellation. Revise by editing the complete Markdown and converting again.
5754
- 6. Use get_conversion_report for provenance and save_artifact only when a durable file is required.`;
5533
+ 2. Author plain Markdown. Squisq annotations are optional layout hints.${templateHint} Call get_authoring_context only when exact annotation examples or theme details would help.
5534
+ 3. Pass the Markdown directly to convert_document with an mp4 target, orientation "${orientation ?? "landscape"}"${themeHint}. Use a bundle source only when assets must travel with the document. No validation, inspection, or preview is required.
5535
+ 4. Use preview_document only when the user explicitly asks for visual evidence.
5536
+ 5. Call save_artifact only when a durable file is required.`;
5755
5537
  }
5756
5538
  function documentPrompt(topic, format, theme, template) {
5757
5539
  const target = format ?? "pdf";
5758
- return `Create a professional document about: ${topic}
5540
+ const templateHint = template ? ` Use the requested \`${template}\` annotation where appropriate.` : "";
5541
+ const themeHint = theme ? ` and themeId \`${theme}\`` : "";
5542
+ return `Create a document about: ${topic}
5759
5543
 
5760
5544
  1. For durable output, call list_roots before drafting and stop if no root is write-enabled; do not use a shell or CLI converter.
5761
- 2. Call get_authoring_context with targetFormat "${target}" for the focused linked-Squisq workflow.
5762
- 3. Treat the topic facts as a closed evidence set. Preserve them exactly, use temporal or correlational wording unless causality is supplied, and label calculations, assumptions, hypotheses, recommendations, and examples. Causal links, superlatives, sole causes, capabilities, owners, dates, channels, and operational details must be supplied or explicitly framed. When the requested genre needs unsupplied roles, gates, timelines, channels, or procedures, add one proposed operating model scope note that applies to those details.
5763
- 4. Honor the requested word range and document genre. Author structured Markdown using theme "${theme ?? "choose from the returned themes"}" and template "${template ?? "content until visual optimization"}". Bind annotations to headings. Use connected memo prose for executive decisions and native headings, tables, and checklists for operational documents; retain complete-body content when a visual template would discard detail.
5764
- 5. Before conversion, count document words, verify every requested element, and rewrite or label every unsupported claim. If the complete draft will feed two or more review or conversion calls, stage it with create_document_bundle and reuse the artifact URI. Use validate_document as the routine export preflight and preview_document only when page-layout evidence is useful; repair findings in the complete Markdown.
5765
- 6. Call convert_document with the complete source and a ${target} target to create an immutable artifact. Revise by editing the complete Markdown and converting again.
5766
- 7. Use get_conversion_report for provenance and save_artifact only when a durable file is required.`;
5545
+ 2. Author plain Markdown. Squisq annotations are optional layout hints.${templateHint} Call get_authoring_context only when exact annotation examples or theme details would help.
5546
+ 3. Pass the Markdown directly to convert_document with a ${target} target${themeHint}. Use a bundle source only when assets must travel with the document. No validation, inspection, or preview is required.
5547
+ 4. Use inspect_document or preview_document only when the user explicitly asks for document analysis or visual evidence.
5548
+ 5. Call save_artifact only when a durable file is required.`;
5767
5549
  }
5768
5550
  function complete(values, prefix) {
5769
5551
  const value = prefix ?? "";
@@ -5807,13 +5589,11 @@ function createMcpServer(options = {}) {
5807
5589
  {
5808
5590
  instructions: [
5809
5591
  "For durable local output, call list_roots before drafting and use a returned write-enabled root id exactly as given. If none is writable, stop and explain that the server must restart with --allow-write; do not fall back to a shell or CLI converter.",
5810
- "Call get_authoring_context once for the focused linked-Squisq contract. Read the full authoring-guide resource or call describe_template only when exact additional catalog detail is needed; do not also enumerate catalogs by default.",
5811
- "Treat supplied facts as a closed evidence set: preserve them exactly, use temporal or correlational wording unless causality is supplied, and label calculations, assumptions, hypotheses, recommendations, capabilities, owners, dates, and unsupplied operating details. For a policy or playbook, introduce one proposed operating model scope note before invented procedures.",
5812
- "Honor explicit slide/page counts and word ranges. For PPTX use one level-one heading per slide, no lower-level headings, and at most 80 words per slide. Ground decision tradeoffs in supplied alternatives and label unsupplied accountability, capacity, outcomes, or review cadences as proposed or assumed.",
5813
- "Author complete Squisq-compatible Markdown with annotations on headings, for example `# Heading {[content]}`. Ordinary headings default to the loss-averse content template; standalone annotations create an extra heading-less block.",
5814
- "Use validate_document as the routine export preflight and repair its diagnostics. Use inspect_document only for semantic structure, provenance, assets, metadata, or theme details, and preview_document only when visual evidence is useful.",
5815
- "When the same complete draft will feed two or more validate, inspect, preview, or convert calls, stage it once with create_document_bundle and reuse its artifact URI instead of resending Markdown.",
5816
- "Pass the complete Markdown or bundle source directly into convert_document. Save only the final durable artifact with save_artifact; never invent root ids or switch conversion to a shell or CLI."
5592
+ "Pass plain text or ordinary Markdown directly to convert_document; no preflight, inspection, preview, or template annotation is required. For deliberate PPTX slide boundaries, use one level-one heading per slide; unstructured text is still accepted.",
5593
+ "convert_document chooses compatible templates automatically. Squisq annotations on headings are optional layout hints that take precedence. Call get_authoring_context only when exact starter examples, themes, transforms, or target details are useful; read the full authoring-guide or call describe_template only for advanced author control.",
5594
+ "Use a bundle source when assets must travel with the document. Use create_document_bundle only when one complete draft will be reused by two or more inspect, preview, or convert calls.",
5595
+ "Use inspect_document or preview_document only when the user asks for document analysis or visual evidence.",
5596
+ "convert_document returns immutable artifacts and diagnostics. Save only final durable output with save_artifact; never invent root ids or switch conversion to a shell or CLI."
5817
5597
  ].join(" ")
5818
5598
  }
5819
5599
  );
package/dist/eval/cli.js CHANGED
@@ -4,8 +4,8 @@ import { Command } from "commander";
4
4
 
5
5
  // src/eval/cases.ts
6
6
  var EVAL_PROMPT_PROFILES = Object.freeze({
7
- baseline: `Use the DocBlocks MCP server for authoring, validation, conversion, and saving. Do not create the Office artifact with shell commands or another document library. Return the exact Squisq-flavored Markdown supplied to the final convert_document call.`,
8
- "content-first": `Use the DocBlocks MCP server for the complete workflow. Start with get_authoring_context, author a lossless content-first draft, validate it, then use compatible visual templates selectively and preview before the final conversion. Repair actionable diagnostics. Do not create the Office artifact with shell commands or another document library. Return the exact Squisq-flavored Markdown supplied to the final convert_document call.`
7
+ baseline: `Use the DocBlocks MCP server for conversion and saving. Author Markdown and pass it directly to convert_document; no validation, inspection, preview, or authoring-context call is required. Do not create the Office artifact with shell commands or another document library. Return the exact Squisq-flavored Markdown supplied to the final convert_document call.`,
8
+ "content-first": `Use the DocBlocks MCP server for the complete workflow. Author the complete Markdown first and pass it directly to convert_document. Squisq annotations are optional layout hints; use get_authoring_context only when exact examples help, and use inspection or preview only when the brief explicitly requires that evidence. Do not create the Office artifact with shell commands or another document library. Return the exact Squisq-flavored Markdown supplied to the final convert_document call.`
9
9
  });
10
10
  var MCP_CONTENT_EVAL_CASES = Object.freeze([
11
11
  {
@@ -1190,7 +1190,7 @@ function collectToolMarkdown(value, candidates) {
1190
1190
  if (!isRecord2(value)) return;
1191
1191
  const toolName = [value.tool, value.name, value.tool_name].find((candidate) => typeof candidate === "string")?.toString();
1192
1192
  if (toolName) {
1193
- const priority = toolName.endsWith("convert_document") ? 3 : toolName.endsWith("create_document_bundle") ? 2 : toolName.endsWith("validate_document") ? 1 : 0;
1193
+ const priority = toolName.endsWith("convert_document") ? 3 : toolName.endsWith("create_document_bundle") ? 2 : 0;
1194
1194
  if (priority > 0) {
1195
1195
  for (const args of [value.arguments, value.args, value.input]) {
1196
1196
  const parsed = parsePossibleJson(args);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bendyline/docblocks-cli",
3
- "version": "2.2.2",
3
+ "version": "2.3.0",
4
4
  "description": "Build, preview, convert, render, inspect, and automate documents",
5
5
  "license": "MIT",
6
6
  "author": "Bendyline",
@@ -36,7 +36,7 @@
36
36
  "docblocks": "./dist/bin.js"
37
37
  },
38
38
  "engines": {
39
- "node": ">=22.14.0"
39
+ "node": "^22.22.2 || ^24.15.0 || >=26.0.0"
40
40
  },
41
41
  "files": [
42
42
  "dist",
@@ -47,12 +47,12 @@
47
47
  "typecheck": "tsc --noEmit"
48
48
  },
49
49
  "dependencies": {
50
- "@bendyline/docblocks": "2.2.2",
51
- "@bendyline/squisq": "2.4.1",
52
- "@bendyline/squisq-cli": "2.4.1",
53
- "@bendyline/squisq-formats": "2.3.5",
54
- "@bendyline/squisq-react": "2.4.1",
55
- "@bendyline/squisq-video": "2.2.5",
50
+ "@bendyline/docblocks": "2.3.0",
51
+ "@bendyline/squisq": "2.4.3",
52
+ "@bendyline/squisq-cli": "2.4.3",
53
+ "@bendyline/squisq-formats": "2.3.7",
54
+ "@bendyline/squisq-react": "2.4.5",
55
+ "@bendyline/squisq-video": "2.2.7",
56
56
  "@modelcontextprotocol/sdk": "1.29.0",
57
57
  "commander": "13.1.0",
58
58
  "jszip": "3.10.1",