@bendyline/docblocks-cli 2.3.4 → 2.5.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
@@ -54,6 +54,9 @@ docblocks convert report.docx --formats md,pdf,pptx --output-dir ./exports
54
54
  # Render MP4 with explicit media controls
55
55
  docblocks video story.md --quality high --orientation portrait
56
56
 
57
+ # Render the Dashboard rendition to a square image with accent cards
58
+ docblocks convert report.md --formats png --image-resolution square --image-style accent
59
+
57
60
  # Discover authoring vocabulary from linked Squisq
58
61
  docblocks themes
59
62
  docblocks transforms
@@ -93,9 +96,10 @@ The package root is a side-effect-free programmatic API for `runBuild`, `runConv
93
96
  the separate `docblocks` bin entry.
94
97
 
95
98
  The live linked registry currently covers Markdown, DOCX, PDF, PPTX, XLSX, CSV,
96
- HTML, HTML ZIP, EPUB, DBK, MP4, and GIF. Direction varies by format, so use the
97
- CLI reference or MCP `list_formats` rather than assuming every format imports.
99
+ HTML, HTML ZIP, EPUB, DBK, MP4, GIF, and PNG. Direction varies by format, so use
100
+ the CLI reference or MCP `list_formats` rather than assuming every format imports.
98
101
 
99
102
  MP4/GIF rendering requires Chromium and FFmpeg. Install Chromium with
100
103
  `npx playwright install chromium`; Squisq resolves FFmpeg from `SQUISQ_FFMPEG`,
101
- `PATH`, or `ffmpeg-static`, in that order.
104
+ `PATH`, or `ffmpeg-static`, in that order. PNG renders the document's Dashboard
105
+ rendition to a single image and needs Chromium only.
@@ -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.7.0 | MIT | https://github.com/bendyline/squisq |
19
- | @bendyline/squisq-cli | 2.5.2 | MIT | https://github.com/bendyline/squisq |
20
- | @bendyline/squisq-formats | 2.4.1 | MIT | https://github.com/bendyline/squisq |
21
- | @bendyline/squisq-react | 2.7.0 | MIT | https://github.com/bendyline/squisq |
22
- | @bendyline/squisq-video | 2.2.11 | MIT | https://github.com/bendyline/squisq |
18
+ | @bendyline/squisq | 2.8.0 | MIT | https://github.com/bendyline/squisq |
19
+ | @bendyline/squisq-cli | 2.6.0 | MIT | https://github.com/bendyline/squisq |
20
+ | @bendyline/squisq-formats | 2.4.5 | MIT | https://github.com/bendyline/squisq |
21
+ | @bendyline/squisq-react | 2.8.0 | MIT | https://github.com/bendyline/squisq |
22
+ | @bendyline/squisq-video | 2.3.0 | 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 |
@@ -61,7 +61,7 @@ This notice is included in the published npm tarball. Transitive packages instal
61
61
  | @types/d3-fetch | 3.0.7 | MIT | https://github.com/DefinitelyTyped/DefinitelyTyped |
62
62
  | @types/d3-force | 3.0.10 | MIT | https://github.com/DefinitelyTyped/DefinitelyTyped |
63
63
  | @types/d3-format | 3.0.4 | MIT | https://github.com/DefinitelyTyped/DefinitelyTyped |
64
- | @types/d3-geo | 3.1.0 | MIT | https://github.com/DefinitelyTyped/DefinitelyTyped |
64
+ | @types/d3-geo | 3.1.1 | MIT | https://github.com/DefinitelyTyped/DefinitelyTyped |
65
65
  | @types/d3-hierarchy | 3.1.7 | MIT | https://github.com/DefinitelyTyped/DefinitelyTyped |
66
66
  | @types/d3-interpolate | 3.0.4 | MIT | https://github.com/DefinitelyTyped/DefinitelyTyped |
67
67
  | @types/d3-path | 3.1.1 | MIT | https://github.com/DefinitelyTyped/DefinitelyTyped |
@@ -87,7 +87,7 @@ This notice is included in the published npm tarball. Transitive packages instal
87
87
  | @types/unist | 2.0.11 | MIT | https://github.com/DefinitelyTyped/DefinitelyTyped |
88
88
  | @types/unist | 3.0.3 | MIT | https://github.com/DefinitelyTyped/DefinitelyTyped |
89
89
  | @upsetjs/venn.js | 2.0.0 | MIT | https://github.com/upsetjs/venn.js |
90
- | @xmldom/xmldom | 0.9.10 | MIT | https://github.com/xmldom/xmldom |
90
+ | @xmldom/xmldom | 0.9.11 | MIT | https://github.com/xmldom/xmldom |
91
91
  | accepts | 2.0.0 | MIT | https://github.com/jshttp/accepts |
92
92
  | ajv | 8.20.0 | MIT | https://github.com/ajv-validator/ajv |
93
93
  | ajv-formats | 3.0.1 | MIT | https://github.com/ajv-validator/ajv-formats |
@@ -115,7 +115,7 @@ This notice is included in the published npm tarball. Transitive packages instal
115
115
  | cose-base | 1.0.3 | MIT | https://github.com/iVis-at-Bilkent/cose-base |
116
116
  | cose-base | 2.2.0 | MIT | https://github.com/iVis-at-Bilkent/cose-base |
117
117
  | cross-spawn | 7.0.6 | MIT | git@github.com:moxystudio/node-cross-spawn |
118
- | cytoscape | 3.34.0 | MIT | https://github.com/cytoscape/cytoscape.js |
118
+ | cytoscape | 3.34.1 | MIT | https://github.com/cytoscape/cytoscape.js |
119
119
  | cytoscape-cose-bilkent | 4.1.0 | MIT | https://github.com/cytoscape/cytoscape.js-cose-bilkent |
120
120
  | cytoscape-fcose | 2.2.0 | MIT | https://github.com/iVis-at-Bilkent/cytoscape.js-fcose |
121
121
  | d3 | 7.9.0 | ISC | https://github.com/d3/d3 |
@@ -161,7 +161,7 @@ This notice is included in the published npm tarball. Transitive packages instal
161
161
  | depd | 2.0.0 | MIT | https://github.com/dougwilson/nodejs-depd |
162
162
  | dequal | 2.0.3 | MIT | https://github.com/lukeed/dequal |
163
163
  | devlop | 1.1.0 | MIT | https://github.com/wooorm/devlop |
164
- | dompurify | 3.4.12 | (MPL-2.0 OR Apache-2.0) | https://github.com/cure53/DOMPurify |
164
+ | dompurify | 3.4.13 | (MPL-2.0 OR Apache-2.0) | https://github.com/cure53/DOMPurify |
165
165
  | dunder-proto | 1.0.1 | MIT | https://github.com/es-shims/dunder-proto |
166
166
  | ee-first | 1.1.1 | MIT | https://github.com/jonathanong/ee-first |
167
167
  | encodeurl | 2.0.0 | MIT | https://github.com/pillarjs/encodeurl |
@@ -169,7 +169,7 @@ This notice is included in the published npm tarball. Transitive packages instal
169
169
  | es-define-property | 1.0.1 | MIT | https://github.com/ljharb/es-define-property |
170
170
  | es-errors | 1.3.0 | MIT | https://github.com/ljharb/es-errors |
171
171
  | es-object-atoms | 1.1.2 | MIT | https://github.com/ljharb/es-object-atoms |
172
- | es-toolkit | 1.49.0 | MIT | https://github.com/toss/es-toolkit |
172
+ | es-toolkit | 1.50.0 | MIT | https://github.com/toss/es-toolkit |
173
173
  | escape-html | 1.0.3 | MIT | https://github.com/component/escape-html |
174
174
  | escape-string-regexp | 5.0.0 | MIT | https://github.com/sindresorhus/escape-string-regexp |
175
175
  | etag | 1.8.1 | MIT | https://github.com/jshttp/etag |
@@ -248,7 +248,7 @@ This notice is included in the published npm tarball. Transitive packages instal
248
248
  | mdast-util-to-string | 4.0.0 | MIT | https://github.com/syntax-tree/mdast-util-to-string |
249
249
  | media-typer | 1.1.0 | MIT | https://github.com/jshttp/media-typer |
250
250
  | merge-descriptors | 2.0.0 | MIT | https://github.com/sindresorhus/merge-descriptors |
251
- | mermaid | 11.16.0 | MIT | https://github.com/mermaid-js/mermaid |
251
+ | mermaid | 11.16.1 | MIT | https://github.com/mermaid-js/mermaid |
252
252
  | micromark | 4.0.2 | MIT | https://github.com/micromark/micromark/tree/main/packages/micromark |
253
253
  | micromark-core-commonmark | 2.0.3 | MIT | https://github.com/micromark/micromark/tree/main/packages/micromark-core-commonmark |
254
254
  | micromark-extension-directive | 3.0.2 | MIT | https://github.com/micromark/micromark-extension-directive |
@@ -289,7 +289,7 @@ This notice is included in the published npm tarball. Transitive packages instal
289
289
  | object-inspect | 1.13.4 | MIT | https://github.com/inspect-js/object-inspect |
290
290
  | on-finished | 2.4.1 | MIT | https://github.com/jshttp/on-finished |
291
291
  | once | 1.4.0 | ISC | https://github.com/isaacs/once |
292
- | package-manager-detector | 1.7.0 | MIT | https://github.com/antfu-collective/package-manager-detector |
292
+ | package-manager-detector | 1.8.0 | MIT | https://github.com/antfu-collective/package-manager-detector |
293
293
  | pako | 1.0.11 | (MIT AND Zlib) | https://github.com/nodeca/pako |
294
294
  | parse-entities | 4.0.2 | MIT | https://github.com/wooorm/parse-entities |
295
295
  | parse5 | 7.3.0 | MIT | https://github.com/inikulin/parse5 |
@@ -403,7 +403,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
403
403
  SOFTWARE.
404
404
 
405
405
  ==============================================================================
406
- Components: @bendyline/squisq-cli@2.5.2, @bendyline/squisq-formats@2.4.1, @bendyline/squisq-react@2.7.0, @bendyline/squisq-video@2.2.11, @bendyline/squisq@2.7.0
406
+ Components: @bendyline/squisq-cli@2.6.0, @bendyline/squisq-formats@2.4.5, @bendyline/squisq-react@2.8.0, @bendyline/squisq-video@2.3.0, @bendyline/squisq@2.8.0
407
407
  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
408
408
  ==============================================================================
409
409
  MIT License
@@ -673,7 +673,7 @@ This software contains code derived from the Puppeteer project (https://github.c
673
673
  available under the Apache 2.0 license (https://github.com/puppeteer/puppeteer/blob/master/LICENSE).
674
674
 
675
675
  ==============================================================================
676
- Components: @bendyline/squisq-cli@2.5.2
676
+ Components: @bendyline/squisq-cli@2.6.0
677
677
  Source files: node_modules/@bendyline/squisq-cli/NOTICE.md
678
678
  ==============================================================================
679
679
  # Third-Party Notices for @bendyline/squisq-cli
@@ -693,7 +693,7 @@ Copyright and complete license texts for these dependencies are included in
693
693
  their respective npm distributions and source repositories.
694
694
 
695
695
  ==============================================================================
696
- Components: @bendyline/squisq-cli@2.5.2
696
+ Components: @bendyline/squisq-cli@2.6.0
697
697
  Source files: node_modules/@bendyline/squisq-cli/THIRD_PARTY_LICENSES.txt
698
698
  ==============================================================================
699
699
  THIRD-PARTY LICENSES FOR @bendyline/squisq-cli
@@ -800,7 +800,7 @@ COMPONENTS
800
800
  - mdast-util-phrasing@4.1.0 (MIT); files: license
801
801
  - mdast-util-to-markdown@2.1.2 (MIT); files: license
802
802
  - mdast-util-to-string@4.0.0 (MIT); files: license
803
- - mermaid@11.16.0 (MIT); files: LICENSE
803
+ - mermaid@11.16.1 (MIT); files: LICENSE
804
804
  - micromark-core-commonmark@2.0.3 (MIT); files: license
805
805
  - micromark-extension-directive@3.0.2 (MIT); files: license
806
806
  - micromark-extension-frontmatter@2.0.0 (MIT); files: license
@@ -3685,7 +3685,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
3685
3685
  SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
3686
3686
 
3687
3687
  ==============================================================================
3688
- mermaid@11.16.0 - LICENSE
3688
+ mermaid@11.16.1 - LICENSE
3689
3689
  ==============================================================================
3690
3690
  The MIT License (MIT)
3691
3691
 
@@ -5168,7 +5168,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
5168
5168
  SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
5169
5169
 
5170
5170
  ==============================================================================
5171
- Components: @xmldom/xmldom@0.9.10
5171
+ Components: @xmldom/xmldom@0.9.11
5172
5172
  Source files: node_modules/@bendyline/squisq-formats/node_modules/@xmldom/xmldom/LICENSE
5173
5173
  ==============================================================================
5174
5174
  Copyright 2019 - present Christopher J. Brody and other contributors, as listed in: https://github.com/xmldom/xmldom/graphs/contributors
@@ -5181,7 +5181,7 @@ The above copyright notice and this permission notice shall be included in all c
5181
5181
  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.
5182
5182
 
5183
5183
  ==============================================================================
5184
- Components: @bendyline/squisq-formats@2.4.1
5184
+ Components: @bendyline/squisq-formats@2.4.5
5185
5185
  Source files: node_modules/@bendyline/squisq-formats/NOTICE.md
5186
5186
  ==============================================================================
5187
5187
  # Third-Party Notices for @bendyline/squisq-formats
@@ -5196,7 +5196,7 @@ Third-party components remain under their respective license terms.
5196
5196
  | ---------------- | ------- | ----------------------- | ---------------------------------- |
5197
5197
  | @pdf-lib/fontkit | 1.1.1 | MIT | https://github.com/Hopding/fontkit |
5198
5198
  | @pdf-lib/upng | 1.0.1 | MIT | https://github.com/Hopding/upng |
5199
- | @xmldom/xmldom | 0.9.10 | MIT | https://github.com/xmldom/xmldom |
5199
+ | @xmldom/xmldom | 0.9.11 | MIT | https://github.com/xmldom/xmldom |
5200
5200
  | jszip | 3.10.1 | MIT OR GPL-3.0-or-later | https://github.com/Stuk/jszip |
5201
5201
  | pdf-lib | 1.17.1 | MIT | https://pdf-lib.js.org |
5202
5202
  | pdfjs-dist | 4.10.38 | Apache-2.0 | https://mozilla.github.io/pdf.js |
@@ -5206,7 +5206,7 @@ texts for these dependencies are included in their respective npm
5206
5206
  distributions and source repositories.
5207
5207
 
5208
5208
  ==============================================================================
5209
- Components: @bendyline/squisq-formats@2.4.1
5209
+ Components: @bendyline/squisq-formats@2.4.5
5210
5210
  Source files: node_modules/@bendyline/squisq-formats/THIRD_PARTY_LICENSES.txt
5211
5211
  ==============================================================================
5212
5212
  THIRD-PARTY LICENSES FOR @bendyline/squisq-formats
@@ -5388,7 +5388,7 @@ Awesome, nor vice versa. **Please do not use brand logos for any purpose except
5388
5388
  to represent the company, product, or service to which they refer.**
5389
5389
 
5390
5390
  ==============================================================================
5391
- Components: @bendyline/squisq-react@2.7.0
5391
+ Components: @bendyline/squisq-react@2.8.0
5392
5392
  Source files: node_modules/@bendyline/squisq-react/NOTICE.md
5393
5393
  ==============================================================================
5394
5394
  # Third-Party Notices for @bendyline/squisq-react
@@ -5402,7 +5402,7 @@ Third-party components remain under their respective license terms.
5402
5402
  | Package | Version | License | Repository |
5403
5403
  | ----------------------------- | -------------------- | ----------------------------- | ------------------------------------------- |
5404
5404
  | @fortawesome/fontawesome-free | 7.2.0 | CC-BY-4.0 AND OFL-1.1 AND MIT | https://github.com/FortAwesome/Font-Awesome |
5405
- | mermaid | 11.16.0 | MIT | https://github.com/mermaid-js/mermaid |
5405
+ | mermaid | 11.16.1 | MIT | https://github.com/mermaid-js/mermaid |
5406
5406
  | preact _(bundled)_ | 10.29.0 | MIT | https://github.com/preactjs/preact |
5407
5407
  | react _(peer)_ | ^18.0.0 \|\| ^19.0.0 | MIT | https://github.com/facebook/react |
5408
5408
  | react-dom _(peer)_ | ^18.0.0 \|\| ^19.0.0 | MIT | https://github.com/facebook/react |
@@ -5413,7 +5413,7 @@ third-party license texts for the complete standalone bundle graph are shipped
5413
5413
  in THIRD_PARTY_LICENSES.txt.
5414
5414
 
5415
5415
  ==============================================================================
5416
- Components: @bendyline/squisq-react@2.7.0
5416
+ Components: @bendyline/squisq-react@2.8.0
5417
5417
  Source files: node_modules/@bendyline/squisq-react/THIRD_PARTY_LICENSES.txt
5418
5418
  ==============================================================================
5419
5419
  THIRD-PARTY LICENSES FOR @bendyline/squisq-react
@@ -5518,7 +5518,7 @@ COMPONENTS
5518
5518
  - mdast-util-phrasing@4.1.0 (MIT); files: license
5519
5519
  - mdast-util-to-markdown@2.1.2 (MIT); files: license
5520
5520
  - mdast-util-to-string@4.0.0 (MIT); files: license
5521
- - mermaid@11.16.0 (MIT); files: LICENSE
5521
+ - mermaid@11.16.1 (MIT); files: LICENSE
5522
5522
  - micromark-core-commonmark@2.0.3 (MIT); files: license
5523
5523
  - micromark-extension-directive@3.0.2 (MIT); files: license
5524
5524
  - micromark-extension-frontmatter@2.0.0 (MIT); files: license
@@ -8403,7 +8403,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
8403
8403
  SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
8404
8404
 
8405
8405
  ==============================================================================
8406
- mermaid@11.16.0 - LICENSE
8406
+ mermaid@11.16.1 - LICENSE
8407
8407
  ==============================================================================
8408
8408
  The MIT License (MIT)
8409
8409
 
@@ -9950,7 +9950,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
9950
9950
  SOFTWARE.
9951
9951
 
9952
9952
  ==============================================================================
9953
- Components: @bendyline/squisq-video@2.2.11
9953
+ Components: @bendyline/squisq-video@2.3.0
9954
9954
  Source files: node_modules/@bendyline/squisq-video/NOTICE.md
9955
9955
  ==============================================================================
9956
9956
  # Third-Party Notices for @bendyline/squisq-video
@@ -9975,7 +9975,7 @@ Copyright and complete license texts for the listed dependencies are included
9975
9975
  in their respective npm distributions and source repositories.
9976
9976
 
9977
9977
  ==============================================================================
9978
- Components: @bendyline/squisq-video@2.2.11
9978
+ Components: @bendyline/squisq-video@2.3.0
9979
9979
  Source files: node_modules/@bendyline/squisq-video/THIRD_PARTY_LICENSES.txt
9980
9980
  ==============================================================================
9981
9981
  THIRD-PARTY LICENSES FOR @bendyline/squisq-video
@@ -9987,7 +9987,7 @@ repository license, the pinned upstream copy is vendored and identified below.
9987
9987
  COMPONENTS
9988
9988
 
9989
9989
  ==============================================================================
9990
- Components: @bendyline/squisq@2.7.0
9990
+ Components: @bendyline/squisq@2.8.0
9991
9991
  Source files: node_modules/@bendyline/squisq/NOTICE.md
9992
9992
  ==============================================================================
9993
9993
  # Third-Party Notices for @bendyline/squisq
@@ -10018,7 +10018,7 @@ third-party license texts for bundled code and data are shipped in
10018
10018
  THIRD_PARTY_LICENSES.txt.
10019
10019
 
10020
10020
  ==============================================================================
10021
- Components: @bendyline/squisq@2.7.0
10021
+ Components: @bendyline/squisq@2.8.0
10022
10022
  Source files: node_modules/@bendyline/squisq/THIRD_PARTY_LICENSES.txt
10023
10023
  ==============================================================================
10024
10024
  THIRD-PARTY LICENSES FOR @bendyline/squisq
@@ -10226,7 +10226,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
10226
10226
  SOFTWARE.
10227
10227
 
10228
10228
  ==============================================================================
10229
- Components: @chevrotain/types@11.1.2, dompurify@3.4.12
10229
+ Components: @chevrotain/types@11.1.2, dompurify@3.4.13
10230
10230
  Source files: node_modules/@chevrotain/types/LICENSE.txt, node_modules/dompurify/LICENSE
10231
10231
  ==============================================================================
10232
10232
 
@@ -10811,8 +10811,8 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
10811
10811
  SOFTWARE.
10812
10812
 
10813
10813
  ==============================================================================
10814
- Components: @types/d3-array@3.2.2, @types/d3-axis@3.0.6, @types/d3-brush@3.0.6, @types/d3-chord@3.0.6, @types/d3-color@3.1.3, @types/d3-contour@3.0.6, @types/d3-delaunay@6.0.4, @types/d3-dispatch@3.0.7, @types/d3-drag@3.0.7, @types/d3-dsv@3.0.7, @types/d3-ease@3.0.2, @types/d3-fetch@3.0.7, @types/d3-force@3.0.10, @types/d3-format@3.0.4, @types/d3-geo@3.1.0, @types/d3-hierarchy@3.1.7, @types/d3-interpolate@3.0.4, @types/d3-path@3.1.1, @types/d3-polygon@3.0.2, @types/d3-quadtree@3.0.6, @types/d3-random@3.0.4, @types/d3-scale-chromatic@3.1.0, @types/d3-scale@4.0.9, @types/d3-selection@3.0.11, @types/d3-shape@3.1.8, @types/d3-time-format@4.0.3, @types/d3-time@3.0.4, @types/d3-timer@3.0.2, @types/d3-transition@3.0.9, @types/d3-zoom@3.0.8, @types/d3@7.4.3, @types/debug@4.1.12, @types/geojson@7946.0.16, @types/hast@3.0.4, @types/katex@0.16.8, @types/mdast@4.0.4, @types/ms@2.1.0, @types/trusted-types@2.0.7, @types/unist@2.0.11, @types/unist@3.0.3
10815
- Source files: node_modules/@types/d3-array/LICENSE, node_modules/@types/d3-axis/LICENSE, node_modules/@types/d3-brush/LICENSE, node_modules/@types/d3-chord/LICENSE, node_modules/@types/d3-color/LICENSE, node_modules/@types/d3-contour/LICENSE, node_modules/@types/d3-delaunay/LICENSE, node_modules/@types/d3-dispatch/LICENSE, node_modules/@types/d3-drag/LICENSE, node_modules/@types/d3-dsv/LICENSE, node_modules/@types/d3-ease/LICENSE, node_modules/@types/d3-fetch/LICENSE, node_modules/@types/d3-force/LICENSE, node_modules/@types/d3-format/LICENSE, node_modules/@types/d3-geo/LICENSE, node_modules/@types/d3-hierarchy/LICENSE, node_modules/@types/d3-interpolate/LICENSE, node_modules/@types/d3-path/LICENSE, node_modules/@types/d3-polygon/LICENSE, node_modules/@types/d3-quadtree/LICENSE, node_modules/@types/d3-random/LICENSE, node_modules/@types/d3-scale-chromatic/LICENSE, node_modules/@types/d3-scale/LICENSE, node_modules/@types/d3-selection/LICENSE, node_modules/@types/d3-shape/LICENSE, node_modules/@types/d3-time-format/LICENSE, node_modules/@types/d3-time/LICENSE, node_modules/@types/d3-timer/LICENSE, node_modules/@types/d3-transition/LICENSE, node_modules/@types/d3-zoom/LICENSE, node_modules/@types/d3/LICENSE, node_modules/@types/debug/LICENSE, node_modules/@types/geojson/LICENSE, node_modules/@types/hast/LICENSE, node_modules/@types/katex/LICENSE, node_modules/@types/mdast/LICENSE, node_modules/@types/ms/LICENSE, node_modules/@types/unist/LICENSE, node_modules/dompurify/node_modules/@types/trusted-types/LICENSE, node_modules/parse-entities/node_modules/@types/unist/LICENSE
10814
+ Components: @types/d3-array@3.2.2, @types/d3-axis@3.0.6, @types/d3-brush@3.0.6, @types/d3-chord@3.0.6, @types/d3-color@3.1.3, @types/d3-contour@3.0.6, @types/d3-delaunay@6.0.4, @types/d3-dispatch@3.0.7, @types/d3-drag@3.0.7, @types/d3-dsv@3.0.7, @types/d3-ease@3.0.2, @types/d3-fetch@3.0.7, @types/d3-force@3.0.10, @types/d3-format@3.0.4, @types/d3-geo@3.1.1, @types/d3-hierarchy@3.1.7, @types/d3-interpolate@3.0.4, @types/d3-path@3.1.1, @types/d3-polygon@3.0.2, @types/d3-quadtree@3.0.6, @types/d3-random@3.0.4, @types/d3-scale-chromatic@3.1.0, @types/d3-scale@4.0.9, @types/d3-selection@3.0.11, @types/d3-shape@3.1.8, @types/d3-time-format@4.0.3, @types/d3-time@3.0.4, @types/d3-timer@3.0.2, @types/d3-transition@3.0.9, @types/d3-zoom@3.0.8, @types/d3@7.4.3, @types/debug@4.1.12, @types/geojson@7946.0.16, @types/hast@3.0.4, @types/katex@0.16.8, @types/mdast@4.0.4, @types/ms@2.1.0, @types/trusted-types@2.0.7, @types/unist@2.0.11, @types/unist@3.0.3
10815
+ Source files: node_modules/@types/d3-array/LICENSE, node_modules/@types/d3-axis/LICENSE, node_modules/@types/d3-brush/LICENSE, node_modules/@types/d3-chord/LICENSE, node_modules/@types/d3-color/LICENSE, node_modules/@types/d3-contour/LICENSE, node_modules/@types/d3-delaunay/LICENSE, node_modules/@types/d3-dispatch/LICENSE, node_modules/@types/d3-drag/LICENSE, node_modules/@types/d3-dsv/LICENSE, node_modules/@types/d3-ease/LICENSE, node_modules/@types/d3-fetch/LICENSE, node_modules/@types/d3-force/LICENSE, node_modules/@types/d3-format/LICENSE, node_modules/@types/d3-geo/LICENSE, node_modules/@types/d3-hierarchy/LICENSE, node_modules/@types/d3-interpolate/LICENSE, node_modules/@types/d3-path/LICENSE, node_modules/@types/d3-polygon/LICENSE, node_modules/@types/d3-quadtree/LICENSE, node_modules/@types/d3-random/LICENSE, node_modules/@types/d3-scale-chromatic/LICENSE, node_modules/@types/d3-scale/LICENSE, node_modules/@types/d3-selection/LICENSE, node_modules/@types/d3-shape/LICENSE, node_modules/@types/d3-time-format/LICENSE, node_modules/@types/d3-time/LICENSE, node_modules/@types/d3-timer/LICENSE, node_modules/@types/d3-transition/LICENSE, node_modules/@types/d3-zoom/LICENSE, node_modules/@types/d3/LICENSE, node_modules/@types/debug/LICENSE, node_modules/@types/geojson/LICENSE, node_modules/@types/hast/LICENSE, node_modules/@types/katex/LICENSE, node_modules/@types/mdast/LICENSE, node_modules/@types/ms/LICENSE, node_modules/@types/trusted-types/LICENSE, node_modules/@types/unist/LICENSE, node_modules/parse-entities/node_modules/@types/unist/LICENSE
10816
10816
  ==============================================================================
10817
10817
  MIT License
10818
10818
 
@@ -11368,7 +11368,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
11368
11368
  SOFTWARE.
11369
11369
 
11370
11370
  ==============================================================================
11371
- Components: cytoscape@3.34.0
11371
+ Components: cytoscape@3.34.1
11372
11372
  Source files: node_modules/cytoscape/LICENSE
11373
11373
  ==============================================================================
11374
11374
  Copyright (c) 2016-2026, The Cytoscape Consortium.
@@ -11392,7 +11392,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
11392
11392
  SOFTWARE.
11393
11393
 
11394
11394
  ==============================================================================
11395
- Components: cytoscape@3.34.0
11395
+ Components: cytoscape@3.34.1
11396
11396
  Source files: node_modules/cytoscape/license-update.mjs
11397
11397
  ==============================================================================
11398
11398
  import fs from 'fs';
@@ -12073,7 +12073,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
12073
12073
  SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
12074
12074
 
12075
12075
  ==============================================================================
12076
- Components: dompurify@3.4.12
12076
+ Components: dompurify@3.4.13
12077
12077
  Source files: node_modules/dompurify/LICENSE-MPL
12078
12078
  ==============================================================================
12079
12079
  Mozilla Public License Version 2.0
@@ -12547,7 +12547,7 @@ THIS IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRE
12547
12547
  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
12548
12548
 
12549
12549
  ==============================================================================
12550
- Components: es-toolkit@1.49.0
12550
+ Components: es-toolkit@1.50.0
12551
12551
  Source files: node_modules/es-toolkit/LICENSE
12552
12552
  ==============================================================================
12553
12553
  MIT License
@@ -14867,7 +14867,7 @@ The above copyright notice and this permission notice shall be included in all c
14867
14867
  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.
14868
14868
 
14869
14869
  ==============================================================================
14870
- Components: mermaid@11.16.0
14870
+ Components: mermaid@11.16.1
14871
14871
  Source files: node_modules/mermaid/LICENSE
14872
14872
  ==============================================================================
14873
14873
  The MIT License (MIT)
@@ -15156,7 +15156,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
15156
15156
  SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
15157
15157
 
15158
15158
  ==============================================================================
15159
- Components: package-manager-detector@1.7.0
15159
+ Components: package-manager-detector@1.8.0
15160
15160
  Source files: node_modules/package-manager-detector/LICENSE
15161
15161
  ==============================================================================
15162
15162
  MIT License
package/dist/bin.js CHANGED
@@ -947,10 +947,22 @@ var init_authority = __esm({
947
947
  }
948
948
  return [...roots.values()].sort((left, right) => left.id.localeCompare(right.id));
949
949
  }
950
- /** Resolve a root-relative read without ever treating the alias as new authority. */
950
+ /**
951
+ * Resolve a root-relative read without ever treating the alias as new
952
+ * authority. A null rootId (the wire schema's flat-string and
953
+ * omitted-rootId convenience forms) selects the SOLE read root; with
954
+ * several roots configured the ambiguity is an error naming the
955
+ * candidates, never a guess — defaulting must not widen authority.
956
+ */
951
957
  async authorizeRootRead(rootId, workspacePath) {
952
- const root = this.readRoots.find((candidate2) => candidate2.id === rootId);
958
+ const root = rootId === null ? this.readRoots.length === 1 ? this.readRoots[0] : void 0 : this.readRoots.find((candidate2) => candidate2.id === rootId);
953
959
  if (!root) {
960
+ if (rootId === null && this.readRoots.length > 1) {
961
+ throw authorityError(
962
+ "Ambiguous MCP root \u2014 several read roots are configured",
963
+ `Pass source.rootId explicitly. Configured read roots: ${this.readRoots.map((candidate2) => candidate2.id).join(", ")}.`
964
+ );
965
+ }
954
966
  throw authorityError(
955
967
  "Unknown or unreadable MCP root",
956
968
  "Call list_roots and copy a returned read-enabled root id. If no roots are listed, use an inline markdown or bundle source, or restart the server with --allow-read."
@@ -3460,6 +3472,7 @@ import {
3460
3472
  createCliRegistry,
3461
3473
  prepareConversion as prepareLinkedConversion
3462
3474
  } from "@bendyline/squisq-cli/api";
3475
+ import { DASHBOARD_STYLE_IDS } from "@bendyline/squisq/doc";
3463
3476
  import { getDocPlaybackDuration } from "@bendyline/squisq/schemas";
3464
3477
  async function convertPreparedDocument(artifacts, prepared, request, signal, progress, dependencies = DEFAULT_CONVERSION_SERVICE_DEPENDENCIES) {
3465
3478
  if (request.targets.length < 1 || request.targets.length > 12) {
@@ -3722,13 +3735,17 @@ function canonicalJson(value) {
3722
3735
  return `{${entries.map(([key, entry]) => `${JSON.stringify(key)}:${canonicalJson(entry)}`).join(",")}}`;
3723
3736
  }
3724
3737
  function defaultFidelity(format) {
3725
- if (format === "mp4" || format === "gif") return "rendered-fidelity";
3738
+ if (format === "mp4" || format === "gif" || format === "png") return "rendered-fidelity";
3726
3739
  return format === "docx" || format === "pptx" ? "editable-native" : "semantic";
3727
3740
  }
3728
3741
  function usesDocumentRasterizer(format, fidelity) {
3729
3742
  return (format === "pdf" || format === "pptx") && (fidelity === "rendered-fidelity" || fidelity === "hybrid");
3730
3743
  }
3731
3744
  function assertMediaRenderBudget(prepared, target) {
3745
+ if (target.format === "png") {
3746
+ assertDashboardImageBudget(target);
3747
+ return;
3748
+ }
3732
3749
  if (target.format !== "mp4" && target.format !== "gif") return;
3733
3750
  const format = target.format;
3734
3751
  const limits = MCP_MEDIA_RENDER_LIMITS[format];
@@ -3763,6 +3780,35 @@ function assertMediaRenderBudget(prepared, target) {
3763
3780
  }
3764
3781
  if (violations.length > 0) throw new MediaRenderBudgetError(format, violations, limits);
3765
3782
  }
3783
+ function assertDashboardImageBudget(target) {
3784
+ const options = target.options ?? {};
3785
+ const hasCustom = options.width !== void 0 || options.height !== void 0;
3786
+ if (!hasCustom) return;
3787
+ if (options.resolution !== void 0) {
3788
+ throw new DashboardImageBudgetError(
3789
+ "Pass either a resolution preset or custom width and height, not both."
3790
+ );
3791
+ }
3792
+ if (options.width === void 0 || options.height === void 0) {
3793
+ throw new DashboardImageBudgetError("Custom dimensions require both width and height.");
3794
+ }
3795
+ const width = numericOption2(options.width, 0);
3796
+ const height = numericOption2(options.height, 0);
3797
+ const limits = MCP_DASHBOARD_IMAGE_LIMITS;
3798
+ if (!Number.isSafeInteger(width) || !Number.isSafeInteger(height)) {
3799
+ throw new DashboardImageBudgetError("Width and height must be whole pixel counts.");
3800
+ }
3801
+ if (width < limits.minimumDimension || height < limits.minimumDimension || width > limits.maximumDimension || height > limits.maximumDimension) {
3802
+ throw new DashboardImageBudgetError(
3803
+ `Each dimension must be between ${limits.minimumDimension} and ${limits.maximumDimension} pixels; received ${width}x${height}.`
3804
+ );
3805
+ }
3806
+ if (width * height > limits.maximumPixels) {
3807
+ throw new DashboardImageBudgetError(
3808
+ `The image may not exceed ${limits.maximumPixels} total pixels; ${width}x${height} is ${width * height}.`
3809
+ );
3810
+ }
3811
+ }
3766
3812
  function numericOption2(value, fallback) {
3767
3813
  return typeof value === "number" && Number.isFinite(value) ? value : fallback;
3768
3814
  }
@@ -3829,7 +3875,7 @@ function firstDuplicate2(values) {
3829
3875
  }
3830
3876
  return void 0;
3831
3877
  }
3832
- var MCP_FORMAT_FIDELITIES, MCP_MEDIA_RENDER_LIMITS, COMPLETED_CONVERSION_CACHE_LIMIT, completedConversionCaches, linkedRegistry, DEFAULT_CONVERSION_SERVICE_DEPENDENCIES, MCP_FORMAT_CAPABILITIES, CompletedConversionCache, MediaRenderBudgetError, UnsupportedFidelityError, UnknownTransformError, UnknownThemeError;
3878
+ var MCP_FORMAT_FIDELITIES, MCP_DASHBOARD_IMAGE_LIMITS, MCP_DASHBOARD_STYLE_IDS, MCP_DASHBOARD_RESOLUTION_IDS, MCP_MEDIA_RENDER_LIMITS, COMPLETED_CONVERSION_CACHE_LIMIT, completedConversionCaches, linkedRegistry, DEFAULT_CONVERSION_SERVICE_DEPENDENCIES, MCP_FORMAT_CAPABILITIES, CompletedConversionCache, MediaRenderBudgetError, DashboardImageBudgetError, UnsupportedFidelityError, UnknownTransformError, UnknownThemeError;
3833
3879
  var init_conversion_service = __esm({
3834
3880
  "src/mcp/conversion-service.ts"() {
3835
3881
  "use strict";
@@ -3849,8 +3895,25 @@ var init_conversion_service = __esm({
3849
3895
  epub: ["semantic"],
3850
3896
  dbk: ["semantic", "editable-native"],
3851
3897
  mp4: ["rendered-fidelity"],
3852
- gif: ["rendered-fidelity"]
3898
+ gif: ["rendered-fidelity"],
3899
+ png: ["rendered-fidelity"]
3853
3900
  };
3901
+ MCP_DASHBOARD_IMAGE_LIMITS = Object.freeze({
3902
+ minimumDimension: 64,
3903
+ maximumDimension: 7680,
3904
+ maximumPixels: 33177600
3905
+ });
3906
+ MCP_DASHBOARD_STYLE_IDS = DASHBOARD_STYLE_IDS;
3907
+ MCP_DASHBOARD_RESOLUTION_IDS = [
3908
+ "hd",
3909
+ "fhd",
3910
+ "4k",
3911
+ "square",
3912
+ "square-2k",
3913
+ "portrait",
3914
+ "portrait-4k",
3915
+ "standard"
3916
+ ];
3854
3917
  MCP_MEDIA_RENDER_LIMITS = Object.freeze({
3855
3918
  mp4: Object.freeze({
3856
3919
  maximumFps: 60,
@@ -3933,6 +3996,16 @@ var init_conversion_service = __esm({
3933
3996
  this.hint = `Reduce duration, FPS, or dimensions. ${format.toUpperCase()} permits at most ${limits.maximumDurationSeconds}s, ${limits.maximumFps} fps, ${limits.maximumPixelsPerFrame} pixels/frame, ${limits.maximumPixelFrames} frame-pixels, and ${limits.maximumCapturedFrameBytes} retained captured-PNG bytes.`;
3934
3997
  }
3935
3998
  };
3999
+ DashboardImageBudgetError = class extends Error {
4000
+ constructor(message) {
4001
+ super(`The Dashboard image render exceeds MCP raster budgets: ${message}`);
4002
+ this.code = "media-budget-exceeded";
4003
+ this.retryable = false;
4004
+ this.format = "png";
4005
+ this.name = "DashboardImageBudgetError";
4006
+ this.hint = `Use a named resolution preset, or custom dimensions between ${MCP_DASHBOARD_IMAGE_LIMITS.minimumDimension} and ${MCP_DASHBOARD_IMAGE_LIMITS.maximumDimension} pixels per edge totaling at most ${MCP_DASHBOARD_IMAGE_LIMITS.maximumPixels} pixels.`;
4007
+ }
4008
+ };
3936
4009
  UnsupportedFidelityError = class extends Error {
3937
4010
  constructor(format, fidelity, supported) {
3938
4011
  const choices = supported.length > 0 ? supported.join(", ") : "none";
@@ -4129,7 +4202,7 @@ function registerAgenticTools(server, context) {
4129
4202
  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. For PPTX, heading-based slide boundaries do not need --- separators. Use save_artifact only for durable filesystem output.",
4130
4203
  inputSchema: z.object({
4131
4204
  source: documentSourceSchema,
4132
- targets: z.array(conversionTargetSchema).min(1).max(12),
4205
+ targets: conversionTargetsSchema,
4133
4206
  themeId: identifierSchema.optional().describe(
4134
4207
  "Exact Squisq theme id. Infer it from the brief when the visual direction is clear. If transformId is set and no exact theme was requested, omit themeId so the transform can apply its preferred compatible theme."
4135
4208
  ),
@@ -5211,7 +5284,7 @@ function boundedFormatCapabilities() {
5211
5284
  };
5212
5285
  });
5213
5286
  }
5214
- var READ_ONLY, ARTIFACT_CREATING, MATERIALIZING, identifierSchema, fidelitySchemas, metadataFields, simpleTarget, conversionTargetSchema, MCP_CONVERSION_TARGET_FORMATS;
5287
+ var READ_ONLY, ARTIFACT_CREATING, MATERIALIZING, identifierSchema, fidelitySchemas, metadataFields, simpleTarget, conversionTargetSchema, MCP_CONVERSION_TARGET_FORMATS, conversionTargetsSchema;
5215
5288
  var init_agentic_tools = __esm({
5216
5289
  "src/mcp/agentic-tools.ts"() {
5217
5290
  "use strict";
@@ -5350,11 +5423,49 @@ var init_agentic_tools = __esm({
5350
5423
  maxColors: z.number().int().min(2).max(256).optional(),
5351
5424
  dither: z.enum(["none", "bayer", "heckbert", "floyd_steinberg", "sierra2", "sierra2_4a"]).optional(),
5352
5425
  bayerScale: z.number().int().min(0).max(5).optional()
5426
+ }).strict(),
5427
+ z.object({
5428
+ format: z.literal("png"),
5429
+ fidelity: z.enum(MCP_FORMAT_FIDELITIES.png).optional(),
5430
+ resolution: z.enum(MCP_DASHBOARD_RESOLUTION_IDS).optional().describe(
5431
+ "Named output size for the Dashboard image. Mutually exclusive with width/height."
5432
+ ),
5433
+ width: z.number().int().min(64).max(7680).optional().describe("Custom pixel width. Requires height and excludes resolution."),
5434
+ height: z.number().int().min(64).max(7680).optional().describe("Custom pixel height. Requires width and excludes resolution."),
5435
+ layout: z.string().max(64).optional().describe(
5436
+ `Dashboard layout id, or "auto" to pick by block count. Omit to honor the document's own squisq-dashboard-layout frontmatter.`
5437
+ ),
5438
+ style: z.enum(MCP_DASHBOARD_STYLE_IDS).optional().describe(
5439
+ "Cell dressing around each block. Omit to honor the document's own squisq-dashboard-style frontmatter."
5440
+ ),
5441
+ title: z.boolean().optional().describe("Render the document-title band. Omit to honor the document\u2019s own setting.")
5353
5442
  }).strict()
5354
5443
  ]);
5355
5444
  MCP_CONVERSION_TARGET_FORMATS = Object.freeze(
5356
5445
  conversionTargetSchema.options.map((schema) => schema.shape.format.value)
5357
5446
  );
5447
+ conversionTargetsSchema = z.preprocess((value) => {
5448
+ const normalizeEntry = (entry) => typeof entry === "string" && !entry.trim().startsWith("{") ? { format: entry.trim().toLowerCase().replace(/^\./u, "") } : typeof entry === "string" ? (() => {
5449
+ try {
5450
+ return JSON.parse(entry);
5451
+ } catch {
5452
+ return entry;
5453
+ }
5454
+ })() : entry;
5455
+ if (typeof value === "string") {
5456
+ const text = value.trim();
5457
+ if (text.startsWith("[")) {
5458
+ try {
5459
+ return JSON.parse(text).map(normalizeEntry);
5460
+ } catch {
5461
+ return value;
5462
+ }
5463
+ }
5464
+ return [normalizeEntry(text)];
5465
+ }
5466
+ if (Array.isArray(value)) return value.map(normalizeEntry);
5467
+ return value;
5468
+ }, z.array(conversionTargetSchema).min(1).max(12));
5358
5469
  }
5359
5470
  });
5360
5471
 
@@ -5567,6 +5678,38 @@ function registerAuthoringPrompts(server) {
5567
5678
  })
5568
5679
  );
5569
5680
  video.argsSchema = videoArgs;
5681
+ const dashboardArgs = z3.object({
5682
+ topic: z3.string().max(MAX_TOPIC_CHARACTERS).describe("Dashboard topic or subject."),
5683
+ resolution: z3.enum(MCP_DASHBOARD_RESOLUTION_IDS).optional().describe("Named output size for the image."),
5684
+ style: z3.enum(MCP_DASHBOARD_STYLE_IDS).optional().describe("Cell dressing around each block."),
5685
+ theme,
5686
+ template
5687
+ }).strict();
5688
+ const dashboard = server.registerPrompt(
5689
+ "create-dashboard",
5690
+ {
5691
+ description: "Convert model-authored Markdown into an artifact-first dashboard image.",
5692
+ argsSchema: dashboardArgs.shape
5693
+ },
5694
+ async (args) => ({
5695
+ messages: [
5696
+ {
5697
+ role: "user",
5698
+ content: {
5699
+ type: "text",
5700
+ text: dashboardPrompt(
5701
+ args.topic,
5702
+ args.resolution,
5703
+ args.style,
5704
+ args.theme,
5705
+ args.template
5706
+ )
5707
+ }
5708
+ }
5709
+ ]
5710
+ })
5711
+ );
5712
+ dashboard.argsSchema = dashboardArgs;
5570
5713
  const documentArgs = z3.object({
5571
5714
  topic: z3.string().max(MAX_TOPIC_CHARACTERS).describe("Document topic or subject."),
5572
5715
  format: z3.enum(["docx", "pdf"]).optional(),
@@ -5618,6 +5761,19 @@ function videoPrompt(topic, orientation, theme, template) {
5618
5761
  4. Use preview_document only when the user explicitly asks for visual evidence.
5619
5762
  5. Call save_artifact only when a durable file is required.`;
5620
5763
  }
5764
+ function dashboardPrompt(topic, resolution, style, theme, template) {
5765
+ const templateHint = template ? ` Use the requested \`${template}\` annotation where appropriate.` : "";
5766
+ const themeHint = theme ? ` and themeId \`${theme}\`` : "";
5767
+ const sizeHint = resolution ? `, resolution "${resolution}"` : "";
5768
+ const styleHint = style ? `, style "${style}"` : "";
5769
+ return `Create a dashboard image about: ${topic}
5770
+
5771
+ 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.
5772
+ 2. A dashboard renders the WHOLE document onto one canvas, one block per cell, so write for a single screen. Aim for four to eight short, self-contained blocks \u2014 a lead statement, a table or metric, a short list, a closing note. Long prose does not fit a cell and will be clipped.${templateHint} Call get_authoring_context only when exact annotation examples or theme details would help.
5773
+ 3. Pass the Markdown directly to convert_document with a png target${sizeHint}${styleHint}${themeHint}. Omit layout to let the block count pick one. Use a bundle source only when assets must travel with the document. No validation, inspection, or preview is required.
5774
+ 4. Use preview_document only when the user explicitly asks for visual evidence.
5775
+ 5. Call save_artifact only when a durable file is required.`;
5776
+ }
5621
5777
  function documentPrompt(topic, format, theme, template) {
5622
5778
  const target = format ?? "pdf";
5623
5779
  const templateHint = template ? ` Use the requested \`${template}\` annotation where appropriate.` : "";
@@ -5638,6 +5794,7 @@ var MAX_ID_CHARACTERS, MAX_TOPIC_CHARACTERS;
5638
5794
  var init_prompts = __esm({
5639
5795
  "src/mcp/prompts.ts"() {
5640
5796
  "use strict";
5797
+ init_conversion_service();
5641
5798
  init_style_guidance();
5642
5799
  MAX_ID_CHARACTERS = 256;
5643
5800
  MAX_TOPIC_CHARACTERS = 1e4;
@@ -6741,7 +6898,70 @@ import { Command as Command3 } from "commander";
6741
6898
  init_link_support();
6742
6899
  init_node_error();
6743
6900
  init_cancellation();
6901
+
6902
+ // src/internal/dashboard-image.ts
6903
+ function hasDashboardImageInput(input) {
6904
+ return input.resolution !== void 0 || input.width !== void 0 || input.height !== void 0 || input.layout !== void 0 || input.style !== void 0 || input.title !== void 0;
6905
+ }
6906
+ function pixelCount(value, flag) {
6907
+ if (value === void 0) return void 0;
6908
+ const parsed = typeof value === "number" ? value : Number(value.trim());
6909
+ if (!Number.isFinite(parsed)) {
6910
+ throw new Error(`The ${flag} must be a whole number of pixels.`);
6911
+ }
6912
+ return parsed;
6913
+ }
6914
+ async function resolveDashboardImageOptions(input) {
6915
+ const [{ resolveDashboardStyleId, DASHBOARD_STYLE_IDS: DASHBOARD_STYLE_IDS2 }, video] = await Promise.all([
6916
+ import("@bendyline/squisq/doc"),
6917
+ import("@bendyline/squisq-video")
6918
+ ]);
6919
+ const width = pixelCount(input.width, "--image-width");
6920
+ const height = pixelCount(input.height, "--image-height");
6921
+ const dimensions = video.resolveDashboardDimensions({
6922
+ resolution: input.resolution,
6923
+ width,
6924
+ height
6925
+ });
6926
+ const options = {};
6927
+ if (input.resolution !== void 0) {
6928
+ options.resolution = input.resolution;
6929
+ } else if (width !== void 0 && height !== void 0) {
6930
+ options.width = dimensions.width;
6931
+ options.height = dimensions.height;
6932
+ }
6933
+ if (input.layout !== void 0) {
6934
+ const layout = input.layout.trim().toLowerCase();
6935
+ if (!layout) throw new Error("The --image-layout id must be a non-empty string.");
6936
+ options.layout = layout;
6937
+ }
6938
+ if (input.style !== void 0) {
6939
+ const style = resolveDashboardStyleId(input.style);
6940
+ if (!style) {
6941
+ throw new Error(
6942
+ `Unknown dashboard style "${input.style}". Valid: ${DASHBOARD_STYLE_IDS2.join(", ")}`
6943
+ );
6944
+ }
6945
+ options.style = style;
6946
+ }
6947
+ if (input.title !== void 0) options.title = input.title;
6948
+ return options;
6949
+ }
6950
+ async function assertKnownDashboardLayout(layout, doc) {
6951
+ if (!layout) return;
6952
+ const { DASHBOARD_AUTO_LAYOUT_ID, listDashboardLayouts } = await import("@bendyline/squisq/doc");
6953
+ if (layout === DASHBOARD_AUTO_LAYOUT_ID) return;
6954
+ const available = listDashboardLayouts(doc);
6955
+ if (available.some((entry) => entry.id === layout)) return;
6956
+ const known = available.map((entry) => entry.id).join(", ");
6957
+ throw new Error(
6958
+ `Unknown dashboard layout "${layout}". Valid: ${DASHBOARD_AUTO_LAYOUT_ID}, ${known}`
6959
+ );
6960
+ }
6961
+
6962
+ // src/commands/convert.ts
6744
6963
  var DEFAULT_FORMATS = ["docx", "pptx", "pdf", "html", "dbk"];
6964
+ var DASHBOARD_IMAGE_FORMAT = "png";
6745
6965
  var DEFAULT_MAX_CONVERT_INPUT_BYTES = 1024 * 1024 * 1024;
6746
6966
  var DEFAULT_MAX_CONVERT_INPUT_ENTRIES = 2e4;
6747
6967
  var DEFAULT_MAX_CONVERT_OUTPUT_BYTES = 512 * 1024 * 1024;
@@ -6814,6 +7034,24 @@ async function runConvert(inputPath, opts) {
6814
7034
  { format: requested[0], hint: registryHint }
6815
7035
  );
6816
7036
  }
7037
+ const dashboardImageInput = {
7038
+ resolution: opts.imageResolution,
7039
+ width: opts.imageWidth,
7040
+ height: opts.imageHeight,
7041
+ layout: opts.imageLayout,
7042
+ style: opts.imageStyle,
7043
+ title: opts.imageTitle
7044
+ };
7045
+ const wantsDashboardImage = formats.includes(DASHBOARD_IMAGE_FORMAT);
7046
+ if (hasDashboardImageInput(dashboardImageInput) && !wantsDashboardImage) {
7047
+ throw new squisq.ConversionError(
7048
+ "unknown-format",
7049
+ `The --image-* options only apply to the "${DASHBOARD_IMAGE_FORMAT}" target. Add it to --formats.`,
7050
+ { format: DASHBOARD_IMAGE_FORMAT, hint: registryHint }
7051
+ );
7052
+ }
7053
+ const dashboardImageOptions = wantsDashboardImage ? await resolveDashboardImageOptions(dashboardImageInput) : void 0;
7054
+ throwIfAborted2(opts.signal);
6817
7055
  if (opts.transform) {
6818
7056
  const { getTransformStyleIds } = await import("@bendyline/squisq/transform");
6819
7057
  throwIfAborted2(opts.signal);
@@ -6839,6 +7077,7 @@ async function runConvert(inputPath, opts) {
6839
7077
  opts.theme,
6840
7078
  result.doc.customThemes?.map((theme) => theme.id)
6841
7079
  );
7080
+ await assertKnownDashboardLayout(dashboardImageOptions?.layout, result.doc);
6842
7081
  throwIfAborted2(opts.signal);
6843
7082
  let exportMarkdownDoc = result.markdownDoc;
6844
7083
  if (opts.transform && exportMarkdownDoc) {
@@ -6862,7 +7101,8 @@ async function runConvert(inputPath, opts) {
6862
7101
  registry,
6863
7102
  title: baseName,
6864
7103
  themeId: opts.theme,
6865
- ...!exportMarkdownDoc && opts.transform ? { transformStyle: opts.transform } : {}
7104
+ ...!exportMarkdownDoc && opts.transform ? { transformStyle: opts.transform } : {},
7105
+ ...format === DASHBOARD_IMAGE_FORMAT && dashboardImageOptions ? { formatOptions: { [DASHBOARD_IMAGE_FORMAT]: dashboardImageOptions } } : {}
6866
7106
  });
6867
7107
  throwIfAborted2(opts.signal);
6868
7108
  if (conversion.bytes.byteLength > maxOutputBytes) {
@@ -7287,7 +7527,16 @@ var convertCommand = new Command3("convert").description("Convert a document thr
7287
7527
  ).option("-t, --theme <id>", "Squisq theme ID to apply (e.g., documentary, cinematic, bold)").option(
7288
7528
  "--transform <style>",
7289
7529
  "Transform style to apply before export (e.g., documentary, magazine, minimal)"
7290
- ).option("--allow-overwrite", "replace existing output files instead of refusing the run").action(async (inputPath, opts) => {
7530
+ ).option(
7531
+ "--image-resolution <preset>",
7532
+ "Dashboard image size preset for the png target (hd, fhd, 4k, square, square-2k, portrait, portrait-4k, standard)"
7533
+ ).option("--image-width <pixels>", "Custom dashboard image width (requires --image-height)").option("--image-height <pixels>", "Custom dashboard image height (requires --image-width)").option(
7534
+ "--image-layout <id>",
7535
+ `Dashboard layout id, or "auto" to pick by block count (default: the document's own setting)`
7536
+ ).option(
7537
+ "--image-style <variant>",
7538
+ "Dashboard cell style: basic, card, panel, accent (default: the document's own setting)"
7539
+ ).option("--image-title", "Include the dashboard document-title band").option("--no-image-title", "Hide the dashboard document-title band").option("--allow-overwrite", "replace existing output files instead of refusing the run").action(async (inputPath, opts) => {
7291
7540
  try {
7292
7541
  await runConvert(inputPath, opts);
7293
7542
  } catch (err) {
package/dist/index.d.ts CHANGED
@@ -52,6 +52,18 @@ interface ConvertOptions {
52
52
  * before any conversion work when a destination already exists.
53
53
  */
54
54
  allowOverwrite?: boolean;
55
+ /** Named dashboard-image resolution preset for the `png` target. */
56
+ imageResolution?: string;
57
+ /** Custom dashboard-image width; requires `imageHeight`. */
58
+ imageWidth?: string | number;
59
+ /** Custom dashboard-image height; requires `imageWidth`. */
60
+ imageHeight?: string | number;
61
+ /** Dashboard layout id, or `auto` to pick by block count. */
62
+ imageLayout?: string;
63
+ /** Dashboard cell style variant (`basic`, `card`, `panel`, `accent`). */
64
+ imageStyle?: string;
65
+ /** Render the dashboard's document-title band. */
66
+ imageTitle?: boolean;
55
67
  /** Cancel reading, transformation, conversion, or publication at a bounded boundary. */
56
68
  signal?: AbortSignal;
57
69
  /** Programmatic registry override; the CLI defaults to the linked Squisq registry. */
package/dist/index.js CHANGED
@@ -465,8 +465,69 @@ function throwIfAborted(signal, message) {
465
465
  throw signal.reason ?? cancellationError(message);
466
466
  }
467
467
 
468
+ // src/internal/dashboard-image.ts
469
+ function hasDashboardImageInput(input) {
470
+ return input.resolution !== void 0 || input.width !== void 0 || input.height !== void 0 || input.layout !== void 0 || input.style !== void 0 || input.title !== void 0;
471
+ }
472
+ function pixelCount(value, flag) {
473
+ if (value === void 0) return void 0;
474
+ const parsed = typeof value === "number" ? value : Number(value.trim());
475
+ if (!Number.isFinite(parsed)) {
476
+ throw new Error(`The ${flag} must be a whole number of pixels.`);
477
+ }
478
+ return parsed;
479
+ }
480
+ async function resolveDashboardImageOptions(input) {
481
+ const [{ resolveDashboardStyleId, DASHBOARD_STYLE_IDS }, video] = await Promise.all([
482
+ import("@bendyline/squisq/doc"),
483
+ import("@bendyline/squisq-video")
484
+ ]);
485
+ const width = pixelCount(input.width, "--image-width");
486
+ const height = pixelCount(input.height, "--image-height");
487
+ const dimensions = video.resolveDashboardDimensions({
488
+ resolution: input.resolution,
489
+ width,
490
+ height
491
+ });
492
+ const options = {};
493
+ if (input.resolution !== void 0) {
494
+ options.resolution = input.resolution;
495
+ } else if (width !== void 0 && height !== void 0) {
496
+ options.width = dimensions.width;
497
+ options.height = dimensions.height;
498
+ }
499
+ if (input.layout !== void 0) {
500
+ const layout = input.layout.trim().toLowerCase();
501
+ if (!layout) throw new Error("The --image-layout id must be a non-empty string.");
502
+ options.layout = layout;
503
+ }
504
+ if (input.style !== void 0) {
505
+ const style = resolveDashboardStyleId(input.style);
506
+ if (!style) {
507
+ throw new Error(
508
+ `Unknown dashboard style "${input.style}". Valid: ${DASHBOARD_STYLE_IDS.join(", ")}`
509
+ );
510
+ }
511
+ options.style = style;
512
+ }
513
+ if (input.title !== void 0) options.title = input.title;
514
+ return options;
515
+ }
516
+ async function assertKnownDashboardLayout(layout, doc) {
517
+ if (!layout) return;
518
+ const { DASHBOARD_AUTO_LAYOUT_ID, listDashboardLayouts } = await import("@bendyline/squisq/doc");
519
+ if (layout === DASHBOARD_AUTO_LAYOUT_ID) return;
520
+ const available = listDashboardLayouts(doc);
521
+ if (available.some((entry) => entry.id === layout)) return;
522
+ const known = available.map((entry) => entry.id).join(", ");
523
+ throw new Error(
524
+ `Unknown dashboard layout "${layout}". Valid: ${DASHBOARD_AUTO_LAYOUT_ID}, ${known}`
525
+ );
526
+ }
527
+
468
528
  // src/commands/convert.ts
469
529
  var DEFAULT_FORMATS = ["docx", "pptx", "pdf", "html", "dbk"];
530
+ var DASHBOARD_IMAGE_FORMAT = "png";
470
531
  var DEFAULT_MAX_CONVERT_INPUT_BYTES = 1024 * 1024 * 1024;
471
532
  var DEFAULT_MAX_CONVERT_INPUT_ENTRIES = 2e4;
472
533
  var DEFAULT_MAX_CONVERT_OUTPUT_BYTES = 512 * 1024 * 1024;
@@ -539,6 +600,24 @@ async function runConvert(inputPath, opts) {
539
600
  { format: requested[0], hint: registryHint }
540
601
  );
541
602
  }
603
+ const dashboardImageInput = {
604
+ resolution: opts.imageResolution,
605
+ width: opts.imageWidth,
606
+ height: opts.imageHeight,
607
+ layout: opts.imageLayout,
608
+ style: opts.imageStyle,
609
+ title: opts.imageTitle
610
+ };
611
+ const wantsDashboardImage = formats.includes(DASHBOARD_IMAGE_FORMAT);
612
+ if (hasDashboardImageInput(dashboardImageInput) && !wantsDashboardImage) {
613
+ throw new squisq.ConversionError(
614
+ "unknown-format",
615
+ `The --image-* options only apply to the "${DASHBOARD_IMAGE_FORMAT}" target. Add it to --formats.`,
616
+ { format: DASHBOARD_IMAGE_FORMAT, hint: registryHint }
617
+ );
618
+ }
619
+ const dashboardImageOptions = wantsDashboardImage ? await resolveDashboardImageOptions(dashboardImageInput) : void 0;
620
+ throwIfAborted2(opts.signal);
542
621
  if (opts.transform) {
543
622
  const { getTransformStyleIds } = await import("@bendyline/squisq/transform");
544
623
  throwIfAborted2(opts.signal);
@@ -564,6 +643,7 @@ async function runConvert(inputPath, opts) {
564
643
  opts.theme,
565
644
  result.doc.customThemes?.map((theme) => theme.id)
566
645
  );
646
+ await assertKnownDashboardLayout(dashboardImageOptions?.layout, result.doc);
567
647
  throwIfAborted2(opts.signal);
568
648
  let exportMarkdownDoc = result.markdownDoc;
569
649
  if (opts.transform && exportMarkdownDoc) {
@@ -587,7 +667,8 @@ async function runConvert(inputPath, opts) {
587
667
  registry,
588
668
  title: baseName,
589
669
  themeId: opts.theme,
590
- ...!exportMarkdownDoc && opts.transform ? { transformStyle: opts.transform } : {}
670
+ ...!exportMarkdownDoc && opts.transform ? { transformStyle: opts.transform } : {},
671
+ ...format === DASHBOARD_IMAGE_FORMAT && dashboardImageOptions ? { formatOptions: { [DASHBOARD_IMAGE_FORMAT]: dashboardImageOptions } } : {}
591
672
  });
592
673
  throwIfAborted2(opts.signal);
593
674
  if (conversion.bytes.byteLength > maxOutputBytes) {
@@ -1012,7 +1093,16 @@ var convertCommand = new Command2("convert").description("Convert a document thr
1012
1093
  ).option("-t, --theme <id>", "Squisq theme ID to apply (e.g., documentary, cinematic, bold)").option(
1013
1094
  "--transform <style>",
1014
1095
  "Transform style to apply before export (e.g., documentary, magazine, minimal)"
1015
- ).option("--allow-overwrite", "replace existing output files instead of refusing the run").action(async (inputPath, opts) => {
1096
+ ).option(
1097
+ "--image-resolution <preset>",
1098
+ "Dashboard image size preset for the png target (hd, fhd, 4k, square, square-2k, portrait, portrait-4k, standard)"
1099
+ ).option("--image-width <pixels>", "Custom dashboard image width (requires --image-height)").option("--image-height <pixels>", "Custom dashboard image height (requires --image-width)").option(
1100
+ "--image-layout <id>",
1101
+ `Dashboard layout id, or "auto" to pick by block count (default: the document's own setting)`
1102
+ ).option(
1103
+ "--image-style <variant>",
1104
+ "Dashboard cell style: basic, card, panel, accent (default: the document's own setting)"
1105
+ ).option("--image-title", "Include the dashboard document-title band").option("--no-image-title", "Hide the dashboard document-title band").option("--allow-overwrite", "replace existing output files instead of refusing the run").action(async (inputPath, opts) => {
1016
1106
  try {
1017
1107
  await runConvert(inputPath, opts);
1018
1108
  } catch (err) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bendyline/docblocks-cli",
3
- "version": "2.3.4",
3
+ "version": "2.5.0",
4
4
  "description": "Build, preview, convert, render, inspect, and automate documents",
5
5
  "license": "MIT",
6
6
  "author": "Bendyline",
@@ -47,12 +47,12 @@
47
47
  "typecheck": "tsc --noEmit"
48
48
  },
49
49
  "dependencies": {
50
- "@bendyline/docblocks": "2.3.4",
51
- "@bendyline/squisq": "2.7.1",
52
- "@bendyline/squisq-cli": "2.5.3",
53
- "@bendyline/squisq-formats": "2.4.2",
54
- "@bendyline/squisq-react": "2.7.1",
55
- "@bendyline/squisq-video": "2.2.12",
50
+ "@bendyline/docblocks": "2.5.0",
51
+ "@bendyline/squisq": "2.9.0",
52
+ "@bendyline/squisq-cli": "2.6.1",
53
+ "@bendyline/squisq-formats": "2.4.6",
54
+ "@bendyline/squisq-react": "2.9.0",
55
+ "@bendyline/squisq-video": "2.3.1",
56
56
  "@modelcontextprotocol/sdk": "1.29.0",
57
57
  "commander": "13.1.0",
58
58
  "jszip": "3.10.1",