@bendyline/docblocks-cli 2.3.1 → 2.3.3

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
@@ -69,12 +69,18 @@ For durable output, call `list_roots` before drafting. If no root is write-enabl
69
69
  restart the server with `--allow-write`; do not bypass MCP with the direct `convert`
70
70
  command. Plain text or ordinary Markdown can be passed directly to
71
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
72
+ and explicit Squisq annotations remain optional overrides. For PPTX, a level-one
73
+ heading creates each deliberate slide boundary by itself; do not add `---` between
74
+ slide headings unless a visible horizontal rule is intended. `get_authoring_context`
75
+ is optional discovery for exact annotation examples, safe defaults, and semantically
76
+ described theme/Summarize choices. MCP guidance tells agents to infer and choose a
77
+ style from the brief rather than presenting raw IDs, asking one compact high-level
78
+ question only when the choice is materially ambiguous. The complete catalog remains
74
79
  available at `docblocks://authoring-guide`.
75
80
 
76
81
  `convert` and `video` accept Markdown, Squisq JSON Doc, DBK/ZIP, folders, and
77
- import-capable linked-registry formats. `build` replaces generated HTML files;
82
+ import-capable linked-registry formats. `build`/`serve` standalone HTML includes
83
+ Copy controls for ordinary fenced code blocks; Mermaid fences remain diagrams. `build` replaces generated HTML files;
78
84
  `convert` and `video` refuse existing destinations unless `--allow-overwrite` is
79
85
  passed. Multi-target conversion stages the complete batch and rolls back replacements
80
86
  if publication fails. Build traversal, input bytes, and output bytes are bounded, as
@@ -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.4 | MIT | https://github.com/bendyline/squisq |
19
- | @bendyline/squisq-cli | 2.4.5 | MIT | https://github.com/bendyline/squisq |
20
- | @bendyline/squisq-formats | 2.3.9 | MIT | https://github.com/bendyline/squisq |
21
- | @bendyline/squisq-react | 2.4.7 | MIT | https://github.com/bendyline/squisq |
22
- | @bendyline/squisq-video | 2.2.8 | MIT | https://github.com/bendyline/squisq |
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 |
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 |
@@ -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.4.5, @bendyline/squisq-formats@2.3.9, @bendyline/squisq-react@2.4.7, @bendyline/squisq-video@2.2.8, @bendyline/squisq@2.4.4
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
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.4.5
676
+ Components: @bendyline/squisq-cli@2.5.2
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.4.5
696
+ Components: @bendyline/squisq-cli@2.5.2
697
697
  Source files: node_modules/@bendyline/squisq-cli/THIRD_PARTY_LICENSES.txt
698
698
  ==============================================================================
699
699
  THIRD-PARTY LICENSES FOR @bendyline/squisq-cli
@@ -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.3.9
5184
+ Components: @bendyline/squisq-formats@2.4.1
5185
5185
  Source files: node_modules/@bendyline/squisq-formats/NOTICE.md
5186
5186
  ==============================================================================
5187
5187
  # Third-Party Notices for @bendyline/squisq-formats
@@ -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.3.9
5209
+ Components: @bendyline/squisq-formats@2.4.1
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.4.7
5391
+ Components: @bendyline/squisq-react@2.7.0
5392
5392
  Source files: node_modules/@bendyline/squisq-react/NOTICE.md
5393
5393
  ==============================================================================
5394
5394
  # Third-Party Notices for @bendyline/squisq-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.4.7
5416
+ Components: @bendyline/squisq-react@2.7.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
@@ -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.8
9953
+ Components: @bendyline/squisq-video@2.2.11
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.8
9978
+ Components: @bendyline/squisq-video@2.2.11
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.4.4
9990
+ Components: @bendyline/squisq@2.7.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.4.4
10021
+ Components: @bendyline/squisq@2.7.0
10022
10022
  Source files: node_modules/@bendyline/squisq/THIRD_PARTY_LICENSES.txt
10023
10023
  ==============================================================================
10024
10024
  THIRD-PARTY LICENSES FOR @bendyline/squisq
package/dist/bin.js CHANGED
@@ -1398,6 +1398,13 @@ function warningDiagnostic(message, stage, format = null) {
1398
1398
  }
1399
1399
  function classifyWarning(message, format) {
1400
1400
  const normalized = message.toLowerCase();
1401
+ if (normalized.includes("redundant thematic break")) {
1402
+ return {
1403
+ code: "redundant-slide-separator",
1404
+ count: warningCount(message, /removed\s+(\d+)\s+redundant thematic break/iu),
1405
+ remediation: "Remove --- between slide headings because heading-based slide breaks already create the boundaries. Keep --- only for an intentional visible horizontal rule within a slide."
1406
+ };
1407
+ }
1401
1408
  if (normalized.includes("unsupported markdown node")) {
1402
1409
  return {
1403
1410
  code: "unsupported-markdown-node",
@@ -4037,6 +4044,17 @@ var init_progress = __esm({
4037
4044
  }
4038
4045
  });
4039
4046
 
4047
+ // src/mcp/style-guidance.ts
4048
+ var STYLE_SELECTION_GUIDANCE, TRANSFORM_SELECTION_GUIDANCE, MOTION_SELECTION_GUIDANCE;
4049
+ var init_style_guidance = __esm({
4050
+ "src/mcp/style-guidance.ts"() {
4051
+ "use strict";
4052
+ STYLE_SELECTION_GUIDANCE = 'Choose theme and Squisq Summarize/transform style automatically from the user brief, audience, tone, content shape, brand constraints, and accessibility needs. Do not present raw theme/transform ids to the user or ask separate theme, summarization, animation, and template questions. If the choice is materially ambiguous and interactive clarification is available, ask one concise high-level preference question with at most four semantic directions plus a "choose for me" option; otherwise use safe defaults and proceed.';
4053
+ TRANSFORM_SELECTION_GUIDANCE = "Treat transformId as the Squisq Summarize control: it can change content emphasis, density, pacing, and structure. For an existing source whose exact language or coverage matters, leave transformId unset unless the user requests or permits summarization or visual restructuring. When transformId is selected and the user did not request an exact theme, omit themeId so Squisq can apply that transform style's preferred compatible theme.";
4054
+ MOTION_SELECTION_GUIDANCE = "Treat motion as a high-level none, subtle, or dynamic preference instead of listing individual transitions. Themes provide motion defaults; use animationsEnabled only to honor an explicit MP4 or GIF motion preference.";
4055
+ }
4056
+ });
4057
+
4040
4058
  // src/mcp/agentic-tools.ts
4041
4059
  import { ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
4042
4060
  import { z } from "zod";
@@ -4099,12 +4117,16 @@ function registerAgenticTools(server, context) {
4099
4117
  server.registerTool(
4100
4118
  "convert_document",
4101
4119
  {
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.",
4120
+ 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.",
4103
4121
  inputSchema: z.object({
4104
4122
  source: documentSourceSchema,
4105
4123
  targets: z.array(conversionTargetSchema).min(1).max(12),
4106
- themeId: identifierSchema.optional(),
4107
- transformId: identifierSchema.optional(),
4124
+ themeId: identifierSchema.optional().describe(
4125
+ "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."
4126
+ ),
4127
+ transformId: identifierSchema.optional().describe(
4128
+ "Optional Squisq Summarize style id. It can change content emphasis, density, pacing, and structure; leave it unset for source-preserving work unless summarization or visual restructuring is requested or permitted."
4129
+ ),
4108
4130
  autoTemplates: z.boolean().optional().describe(
4109
4131
  "Enable content-aware automatic template selection. Defaults to true; explicit annotations still take precedence."
4110
4132
  ),
@@ -4135,8 +4157,10 @@ function registerAgenticTools(server, context) {
4135
4157
  );
4136
4158
  for (const result of results) requireWire(parseConversionResult2(result), "conversion");
4137
4159
  const payload = { results };
4160
+ const warningSummary = conversionWarningSummary(results);
4138
4161
  return {
4139
4162
  content: [
4163
+ ...warningSummary ? [{ type: "text", text: warningSummary }] : [],
4140
4164
  { type: "text", text: JSON.stringify(payload) },
4141
4165
  ...results.map((result) => artifactLink(result.artifact))
4142
4166
  ],
@@ -4410,11 +4434,14 @@ function registerAuthoringGuideResource(server) {
4410
4434
  import("@bendyline/squisq/transform")
4411
4435
  ]);
4412
4436
  const guide = {
4413
- version: 8,
4437
+ version: 10,
4414
4438
  workflow: [
4415
4439
  "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",
4440
+ "for deliberate PPTX slide boundaries, use one level-one Markdown heading per slide; headings alone create the boundaries, so do not add --- between them unless a visible horizontal rule is intended",
4417
4441
  "convert_document chooses compatible templates automatically; Squisq annotations on headings are optional layout hints that take precedence",
4442
+ STYLE_SELECTION_GUIDANCE,
4443
+ TRANSFORM_SELECTION_GUIDANCE,
4444
+ MOTION_SELECTION_GUIDANCE,
4418
4445
  "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
4446
  "use inspect_document or preview_document only when the user asks for document analysis or visual evidence",
4420
4447
  "convert_document creates immutable artifacts; save_artifact only when a durable file is required"
@@ -4458,7 +4485,7 @@ function registerTemplateTools(server, context) {
4458
4485
  server.registerTool(
4459
4486
  "get_authoring_context",
4460
4487
  {
4461
- description: "Optionally discover target capabilities, safe defaults, themes, transforms, and exact starter annotation examples. Plain Markdown can be converted without calling this tool.",
4488
+ description: "Optionally discover target capabilities, safe defaults, semantically described themes and Squisq Summarize styles, and exact starter annotation examples. Use these descriptions to choose for the user rather than presenting raw ids. Plain Markdown can be converted without calling this tool.",
4462
4489
  inputSchema: z.object({
4463
4490
  targetFormat: formatInputSchema.optional(),
4464
4491
  goal: z.enum(["content-first", "visual-polish"]).optional(),
@@ -4532,7 +4559,10 @@ function registerTemplateTools(server, context) {
4532
4559
  defaultFidelity: authoringDefaultFidelity(normalizedTarget),
4533
4560
  workflow: [
4534
4561
  "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.",
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.",
4562
+ normalizedTarget === "pptx" ? "Plain text and ordinary Markdown convert directly. Use one level-one Markdown heading (#) for each deliberate slide boundary. Headings alone create the boundaries, so do not add --- between them unless a visible horizontal rule is intended; unstructured text is still accepted." : "Plain text and ordinary Markdown convert directly without a preflight.",
4563
+ STYLE_SELECTION_GUIDANCE,
4564
+ TRANSFORM_SELECTION_GUIDANCE,
4565
+ ...normalizedTarget === "pptx" || normalizedTarget === "html" || normalizedTarget === "htmlzip" || normalizedTarget === "mp4" || normalizedTarget === "gif" ? [MOTION_SELECTION_GUIDANCE] : [],
4536
4566
  "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
4567
  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
4568
  "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.",
@@ -4982,6 +5012,29 @@ function artifactLink(artifact) {
4982
5012
  size: artifact.size
4983
5013
  };
4984
5014
  }
5015
+ function conversionWarningSummary(results) {
5016
+ const warnings = results.flatMap(
5017
+ (result) => result.diagnostics.filter((diagnostic) => diagnostic.severity === "warning").map((diagnostic) => ({ format: result.targetFormat, diagnostic }))
5018
+ );
5019
+ if (warnings.length === 0) return null;
5020
+ const totalOccurrences = warnings.reduce((total, { diagnostic }) => total + diagnostic.count, 0);
5021
+ const visible = warnings.slice(0, 10);
5022
+ const lines = [
5023
+ `Conversion warnings: ${totalOccurrences} occurrence(s) across ${warnings.length} diagnostic(s).`,
5024
+ ...visible.map(({ format, diagnostic }) => {
5025
+ const count = diagnostic.count > 1 ? ` x${diagnostic.count}` : "";
5026
+ const remediation = diagnostic.remediation ? ` Remediation: ${diagnostic.remediation}` : "";
5027
+ return `- [${diagnostic.code}] ${format}${count}: ${diagnostic.message}${remediation}`;
5028
+ })
5029
+ ];
5030
+ if (visible.length < warnings.length) {
5031
+ lines.push(
5032
+ `- ${warnings.length - visible.length} additional diagnostic(s) remain in structuredContent.`
5033
+ );
5034
+ }
5035
+ lines.push("The complete JSON result follows in the next text content item.");
5036
+ return lines.join("\n");
5037
+ }
4985
5038
  async function sendProgress(extra, progress, total, message) {
4986
5039
  await reportMcpProgress(extra, progress, total, message);
4987
5040
  }
@@ -5028,8 +5081,16 @@ function compactAuthoringContextText(context) {
5028
5081
  `Warning: ${context.syntax.standaloneWarning}`,
5029
5082
  `Templates (${context.templates.length}): ${context.templates.map(({ id }) => id).join(", ")}`,
5030
5083
  ...context.templates.filter(({ id }) => id !== "content").map(({ annotationExample }) => `Optional example: ${annotationExample}`),
5031
- `Themes (${context.themes.length}): ${context.themes.map(({ id }) => id).join(", ")}`,
5032
- `Transform styles (${context.transformStyles.length}): ${context.transformStyles.map(({ id }) => id).join(", ")}.`
5084
+ "",
5085
+ `Theme choices with descriptions (${context.themes.length}):`,
5086
+ ...context.themes.map(
5087
+ ({ id, name, description }) => `- ${id} (${name}): ${description ?? "No additional description."}`
5088
+ ),
5089
+ "",
5090
+ `Squisq Summarize choices for transformId (${context.transformStyles.length}):`,
5091
+ ...context.transformStyles.map(
5092
+ ({ id, name, description }) => `- ${id} (${name}): ${description}`
5093
+ )
5033
5094
  ];
5034
5095
  if (context.recommendations.length > 0) {
5035
5096
  lines.push(
@@ -5152,6 +5213,7 @@ var init_agentic_tools = __esm({
5152
5213
  init_error_result();
5153
5214
  init_progress();
5154
5215
  init_output_bounds();
5216
+ init_style_guidance();
5155
5217
  READ_ONLY = {
5156
5218
  readOnlyHint: true,
5157
5219
  destructiveHint: false,
@@ -5207,7 +5269,9 @@ var init_agentic_tools = __esm({
5207
5269
  format: z.literal("pptx"),
5208
5270
  fidelity: fidelitySchemas.pptx.optional(),
5209
5271
  ...metadataFields,
5210
- slideBreak: z.enum(["h1", "h2", "heading"]).optional(),
5272
+ slideBreak: z.enum(["h1", "h2", "heading"]).optional().describe(
5273
+ "Heading depths that start slides. Headings alone create slide boundaries; do not add --- between them unless a visible horizontal rule is intended."
5274
+ ),
5211
5275
  defaultFont: z.string().max(256).optional(),
5212
5276
  defaultFontSize: z.number().min(6).max(96).optional(),
5213
5277
  width: z.number().int().min(160).max(1920).optional(),
@@ -5257,7 +5321,9 @@ var init_agentic_tools = __esm({
5257
5321
  height: z.number().int().min(16).max(3840).optional(),
5258
5322
  captionStyle: z.enum(["standard", "social"]).optional(),
5259
5323
  coverPreRoll: z.number().min(0).max(60).optional(),
5260
- animationsEnabled: z.boolean().optional()
5324
+ animationsEnabled: z.boolean().optional().describe(
5325
+ "Explicit rendered-media motion switch. Use it only to honor a user preference such as no motion or dynamic motion; otherwise rely on the theme/target default. It does not select an individual transition."
5326
+ )
5261
5327
  }).strict(),
5262
5328
  z.object({
5263
5329
  format: z.literal("gif"),
@@ -5268,7 +5334,9 @@ var init_agentic_tools = __esm({
5268
5334
  height: z.number().int().min(16).max(1920).optional(),
5269
5335
  captionStyle: z.enum(["standard", "social"]).optional(),
5270
5336
  coverPreRoll: z.number().min(0).max(60).optional(),
5271
- animationsEnabled: z.boolean().optional(),
5337
+ animationsEnabled: z.boolean().optional().describe(
5338
+ "Explicit rendered-media motion switch. Use it only to honor a user preference such as no motion or dynamic motion; otherwise rely on the theme/target default. It does not select an individual transition."
5339
+ ),
5272
5340
  loop: z.number().int().min(-1).max(65535).optional(),
5273
5341
  maxColors: z.number().int().min(2).max(256).optional(),
5274
5342
  dither: z.enum(["none", "bayer", "heckbert", "floyd_steinberg", "sierra2", "sierra2_4a"]).optional(),
@@ -5416,14 +5484,18 @@ import { completable } from "@modelcontextprotocol/sdk/server/completable.js";
5416
5484
  import { z as z3 } from "zod";
5417
5485
  function registerAuthoringPrompts(server) {
5418
5486
  const style = completable(
5419
- z3.string().max(MAX_ID_CHARACTERS).optional().describe("Preferred transform style id."),
5487
+ z3.string().max(MAX_ID_CHARACTERS).optional().describe(
5488
+ "Optional exact Squisq Summarize/transform style id. Usually let the model infer this from the brief."
5489
+ ),
5420
5490
  async (prefix) => {
5421
5491
  const { getTransformStyleIds } = await import("@bendyline/squisq/transform");
5422
5492
  return complete(getTransformStyleIds(), prefix);
5423
5493
  }
5424
5494
  );
5425
5495
  const theme = completable(
5426
- z3.string().max(MAX_ID_CHARACTERS).optional().describe("Preferred Squisq theme id."),
5496
+ z3.string().max(MAX_ID_CHARACTERS).optional().describe(
5497
+ "Optional exact Squisq theme id. Usually let the model infer this from the brief or the selected transform."
5498
+ ),
5427
5499
  async (prefix) => {
5428
5500
  const { getAvailableThemes } = await import("@bendyline/squisq/schemas");
5429
5501
  return complete(getAvailableThemes(), prefix);
@@ -5516,13 +5588,15 @@ function presentationPrompt(topic, style, theme, template) {
5516
5588
  const templateHint = template ? ` Use the requested \`${template}\` annotation where appropriate.` : "";
5517
5589
  const themeHint = theme ? ` with themeId \`${theme}\`` : "";
5518
5590
  const styleHint = style ? ` and transformId \`${style}\`` : "";
5591
+ const selectionHint = style || theme ? `Honor the caller-supplied ${style ? `transform style \`${style}\`` : ""}${style && theme ? " and " : ""}${theme ? `theme \`${theme}\`` : ""}; do not ask for another style choice.${style && !theme ? " Because no exact theme was requested, omit themeId so Squisq can apply the transform style's preferred compatible theme." : ""}` : `${STYLE_SELECTION_GUIDANCE} ${TRANSFORM_SELECTION_GUIDANCE}`;
5519
5592
  return `Create a presentation about: ${topic}
5520
5593
 
5521
5594
  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.
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.`;
5595
+ 2. ${selectionHint} ${MOTION_SELECTION_GUIDANCE} Call get_authoring_context only when the linked theme and Summarize descriptions would materially improve the choice.
5596
+ 3. Author plain Markdown. One level-one heading (\`#\`) creates each deliberate slide boundary; headings alone create the boundaries, so do not add \`---\` between them unless a visible horizontal rule is intended. Unstructured text is also accepted. Squisq annotations are optional layout hints.${templateHint}
5597
+ 4. 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.
5598
+ 5. Use inspect_document or preview_document only when the user explicitly asks for document analysis or visual evidence.
5599
+ 6. Call save_artifact only when a durable file is required.`;
5526
5600
  }
5527
5601
  function videoPrompt(topic, orientation, theme, template) {
5528
5602
  const templateHint = template ? ` Use the requested \`${template}\` annotation where appropriate.` : "";
@@ -5555,6 +5629,7 @@ var MAX_ID_CHARACTERS, MAX_TOPIC_CHARACTERS;
5555
5629
  var init_prompts = __esm({
5556
5630
  "src/mcp/prompts.ts"() {
5557
5631
  "use strict";
5632
+ init_style_guidance();
5558
5633
  MAX_ID_CHARACTERS = 256;
5559
5634
  MAX_TOPIC_CHARACTERS = 1e4;
5560
5635
  }
@@ -5589,8 +5664,11 @@ function createMcpServer(options = {}) {
5589
5664
  {
5590
5665
  instructions: [
5591
5666
  "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.",
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.",
5667
+ "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. Headings alone create slide boundaries; do not add --- between them unless a visible horizontal rule is intended.",
5593
5668
  "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.",
5669
+ STYLE_SELECTION_GUIDANCE,
5670
+ TRANSFORM_SELECTION_GUIDANCE,
5671
+ MOTION_SELECTION_GUIDANCE,
5594
5672
  "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
5673
  "Use inspect_document or preview_document only when the user asks for document analysis or visual evidence.",
5596
5674
  "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."
@@ -5662,6 +5740,7 @@ var init_server = __esm({
5662
5740
  init_authority();
5663
5741
  init_discovery_tools();
5664
5742
  init_prompts();
5743
+ init_style_guidance();
5665
5744
  DEFAULT_MAX_CONCURRENT_OPERATIONS = 2;
5666
5745
  DEFAULT_OPERATION_TIMEOUT_MS = 2 * 60 * 1e3;
5667
5746
  DEFAULT_SHUTDOWN_DRAIN_TIMEOUT_MS = 5e3;
@@ -5877,7 +5956,8 @@ async function renderMarkdownHtml(markdown, options) {
5877
5956
  images,
5878
5957
  title: options.title,
5879
5958
  mode: options.mode ?? "static",
5880
- themeId: options.themeId
5959
+ themeId: options.themeId,
5960
+ showCodeCopyButton: true
5881
5961
  });
5882
5962
  }
5883
5963
  async function readReferencedImages(doc, sourcePath, assetRoot, maxAssetBytes, allowReferencedAsset, warn) {
package/dist/index.js CHANGED
@@ -138,7 +138,8 @@ async function renderMarkdownHtml(markdown, options) {
138
138
  images,
139
139
  title: options.title,
140
140
  mode: options.mode ?? "static",
141
- themeId: options.themeId
141
+ themeId: options.themeId,
142
+ showCodeCopyButton: true
142
143
  });
143
144
  }
144
145
  async function readReferencedImages(doc, sourcePath, assetRoot, maxAssetBytes, allowReferencedAsset, warn) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bendyline/docblocks-cli",
3
- "version": "2.3.1",
3
+ "version": "2.3.3",
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.1",
51
- "@bendyline/squisq": "2.4.4",
52
- "@bendyline/squisq-cli": "2.4.5",
53
- "@bendyline/squisq-formats": "2.3.9",
54
- "@bendyline/squisq-react": "2.4.7",
55
- "@bendyline/squisq-video": "2.2.8",
50
+ "@bendyline/docblocks": "2.3.3",
51
+ "@bendyline/squisq": "2.7.0",
52
+ "@bendyline/squisq-cli": "2.5.2",
53
+ "@bendyline/squisq-formats": "2.4.1",
54
+ "@bendyline/squisq-react": "2.7.0",
55
+ "@bendyline/squisq-video": "2.2.11",
56
56
  "@modelcontextprotocol/sdk": "1.29.0",
57
57
  "commander": "13.1.0",
58
58
  "jszip": "3.10.1",