@bendyline/docblocks 2.0.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (286) hide show
  1. package/dist/{chunk-J32GU3F3.js → chunk-6IYMTYMQ.js} +249 -221
  2. package/dist/chunk-6IYMTYMQ.js.map +1 -0
  3. package/dist/{chunk-75UUF6C4.js → chunk-B56KWCSE.js} +2 -2
  4. package/dist/{chunk-RVQHY3XU.js → chunk-BNKV7MTO.js} +1 -1
  5. package/dist/{chunk-RVQHY3XU.js.map → chunk-BNKV7MTO.js.map} +1 -1
  6. package/dist/chunk-BXMF5YQJ.js +149 -0
  7. package/dist/chunk-BXMF5YQJ.js.map +1 -0
  8. package/dist/{chunk-PGR7LK6D.js → chunk-COYQXQK3.js} +14 -5
  9. package/dist/chunk-COYQXQK3.js.map +1 -0
  10. package/dist/{chunk-RQJRQF46.js → chunk-DN7A33LL.js} +42 -49
  11. package/dist/chunk-DN7A33LL.js.map +1 -0
  12. package/dist/chunk-FA7UNOXK.js +20 -0
  13. package/dist/chunk-FA7UNOXK.js.map +1 -0
  14. package/dist/chunk-GM5YXU4L.js +29 -0
  15. package/dist/chunk-GM5YXU4L.js.map +1 -0
  16. package/dist/{chunk-SI2LU2RP.js → chunk-JS6XFWQK.js} +2 -1
  17. package/dist/chunk-JS6XFWQK.js.map +1 -0
  18. package/dist/{chunk-EGNDADXB.js → chunk-MNSZ7EZN.js} +2 -2
  19. package/dist/chunk-P3DVZQ6S.js +228 -0
  20. package/dist/chunk-P3DVZQ6S.js.map +1 -0
  21. package/dist/chunk-P4WATND4.js +52 -0
  22. package/dist/chunk-P4WATND4.js.map +1 -0
  23. package/dist/chunk-RVPGQBWR.js +169 -0
  24. package/dist/chunk-RVPGQBWR.js.map +1 -0
  25. package/dist/chunk-U722UUFN.js +9 -0
  26. package/dist/chunk-U722UUFN.js.map +1 -0
  27. package/dist/{chunk-GCPBEMMH.js → chunk-VTCSF7VS.js} +11 -21
  28. package/dist/chunk-VTCSF7VS.js.map +1 -0
  29. package/dist/{chunk-2D7Y4IR3.js → chunk-WJKYY5QR.js} +123 -66
  30. package/dist/chunk-WJKYY5QR.js.map +1 -0
  31. package/dist/{chunk-5MYAICRE.js → chunk-XUML3MKV.js} +44 -56
  32. package/dist/chunk-XUML3MKV.js.map +1 -0
  33. package/dist/document/index.d.ts +358 -6
  34. package/dist/document/index.js +24 -3
  35. package/dist/document/index.js.map +1 -1
  36. package/dist/filesystem/electron.d.ts +73 -4
  37. package/dist/filesystem/electron.js +16 -3
  38. package/dist/filesystem/electron.js.map +1 -1
  39. package/dist/filesystem/index.d.ts +228 -22
  40. package/dist/filesystem/index.js +133 -19
  41. package/dist/filesystem/index.js.map +1 -1
  42. package/dist/filesystem/indexeddb.d.ts +284 -5
  43. package/dist/filesystem/indexeddb.js +22 -4
  44. package/dist/filesystem/indexeddb.js.map +1 -1
  45. package/dist/filesystem/memory.d.ts +152 -4
  46. package/dist/filesystem/memory.js +12 -3
  47. package/dist/filesystem/memory.js.map +1 -1
  48. package/dist/filesystem/native.d.ts +136 -4
  49. package/dist/filesystem/native.js +27 -3
  50. package/dist/filesystem/native.js.map +1 -1
  51. package/dist/host/index.d.ts +32 -9
  52. package/dist/host/index.js +26 -29
  53. package/dist/host/index.js.map +1 -1
  54. package/dist/index.d.ts +14 -10
  55. package/dist/index.js +204 -9
  56. package/dist/index.js.map +1 -1
  57. package/dist/mcp/index.d.ts +33 -4
  58. package/dist/mcp/index.js +31 -3
  59. package/dist/mcp/index.js.map +1 -1
  60. package/dist/mcp/zod.d.ts +637 -635
  61. package/dist/mcp/zod.js +700 -884
  62. package/dist/mcp/zod.js.map +1 -1
  63. package/dist/share/index.d.ts +43 -0
  64. package/dist/share/index.js +13 -0
  65. package/dist/share/index.js.map +1 -0
  66. package/dist/{types-CsX6EN2t.d.ts → types-BEg5SQ1_.d.ts} +1 -1
  67. package/dist/{types-eOlt9J7n.d.ts → types-CueK0tvU.d.ts} +34 -11
  68. package/dist/vscode/index.d.ts +220 -3
  69. package/dist/vscode/index.js +382 -2
  70. package/dist/vscode/index.js.map +1 -1
  71. package/dist/workspace/index.d.ts +141 -4
  72. package/dist/workspace/index.js +28 -2
  73. package/dist/workspace/index.js.map +1 -1
  74. package/package.json +9 -5
  75. package/dist/chunk-2D7Y4IR3.js.map +0 -1
  76. package/dist/chunk-5MYAICRE.js.map +0 -1
  77. package/dist/chunk-AYZ4HN5M.js +0 -20
  78. package/dist/chunk-AYZ4HN5M.js.map +0 -1
  79. package/dist/chunk-GCPBEMMH.js.map +0 -1
  80. package/dist/chunk-J32GU3F3.js.map +0 -1
  81. package/dist/chunk-PGR7LK6D.js.map +0 -1
  82. package/dist/chunk-RQJRQF46.js.map +0 -1
  83. package/dist/chunk-SI2LU2RP.js.map +0 -1
  84. package/dist/chunk-W5UUUII5.js +0 -142
  85. package/dist/chunk-W5UUUII5.js.map +0 -1
  86. package/dist/document/document-session.d.ts +0 -127
  87. package/dist/document/document-session.d.ts.map +0 -1
  88. package/dist/document/document-session.js +0 -749
  89. package/dist/document/document-session.js.map +0 -1
  90. package/dist/document/filesystem-target.d.ts +0 -17
  91. package/dist/document/filesystem-target.d.ts.map +0 -1
  92. package/dist/document/filesystem-target.js +0 -70
  93. package/dist/document/filesystem-target.js.map +0 -1
  94. package/dist/document/index.d.ts.map +0 -1
  95. package/dist/document/recovery-journal.d.ts +0 -125
  96. package/dist/document/recovery-journal.d.ts.map +0 -1
  97. package/dist/document/recovery-journal.js +0 -385
  98. package/dist/document/recovery-journal.js.map +0 -1
  99. package/dist/document/types.d.ts +0 -89
  100. package/dist/document/types.d.ts.map +0 -1
  101. package/dist/document/types.js +0 -9
  102. package/dist/document/types.js.map +0 -1
  103. package/dist/filesystem/commit-lock.d.ts +0 -3
  104. package/dist/filesystem/commit-lock.d.ts.map +0 -1
  105. package/dist/filesystem/commit-lock.js +0 -20
  106. package/dist/filesystem/commit-lock.js.map +0 -1
  107. package/dist/filesystem/dbk-workspace.d.ts +0 -34
  108. package/dist/filesystem/dbk-workspace.d.ts.map +0 -1
  109. package/dist/filesystem/dbk-workspace.js +0 -85
  110. package/dist/filesystem/dbk-workspace.js.map +0 -1
  111. package/dist/filesystem/electron-provider-v2.d.ts +0 -36
  112. package/dist/filesystem/electron-provider-v2.d.ts.map +0 -1
  113. package/dist/filesystem/electron-provider-v2.js +0 -503
  114. package/dist/filesystem/electron-provider-v2.js.map +0 -1
  115. package/dist/filesystem/electron-provider.d.ts +0 -35
  116. package/dist/filesystem/electron-provider.d.ts.map +0 -1
  117. package/dist/filesystem/electron-provider.js +0 -69
  118. package/dist/filesystem/electron-provider.js.map +0 -1
  119. package/dist/filesystem/electron.d.ts.map +0 -1
  120. package/dist/filesystem/file-media-provider.d.ts +0 -23
  121. package/dist/filesystem/file-media-provider.d.ts.map +0 -1
  122. package/dist/filesystem/file-media-provider.js +0 -85
  123. package/dist/filesystem/file-media-provider.js.map +0 -1
  124. package/dist/filesystem/filesystem-content-container.d.ts +0 -24
  125. package/dist/filesystem/filesystem-content-container.d.ts.map +0 -1
  126. package/dist/filesystem/filesystem-content-container.js +0 -153
  127. package/dist/filesystem/filesystem-content-container.js.map +0 -1
  128. package/dist/filesystem/fs-error.d.ts +0 -46
  129. package/dist/filesystem/fs-error.d.ts.map +0 -1
  130. package/dist/filesystem/fs-error.js +0 -170
  131. package/dist/filesystem/fs-error.js.map +0 -1
  132. package/dist/filesystem/index.d.ts.map +0 -1
  133. package/dist/filesystem/indexeddb-content-container.d.ts +0 -22
  134. package/dist/filesystem/indexeddb-content-container.d.ts.map +0 -1
  135. package/dist/filesystem/indexeddb-content-container.js +0 -100
  136. package/dist/filesystem/indexeddb-content-container.js.map +0 -1
  137. package/dist/filesystem/indexeddb-provider-v2.d.ts +0 -96
  138. package/dist/filesystem/indexeddb-provider-v2.d.ts.map +0 -1
  139. package/dist/filesystem/indexeddb-provider-v2.js +0 -1241
  140. package/dist/filesystem/indexeddb-provider-v2.js.map +0 -1
  141. package/dist/filesystem/indexeddb-provider.d.ts +0 -39
  142. package/dist/filesystem/indexeddb-provider.d.ts.map +0 -1
  143. package/dist/filesystem/indexeddb-provider.js +0 -145
  144. package/dist/filesystem/indexeddb-provider.js.map +0 -1
  145. package/dist/filesystem/indexeddb-store.d.ts +0 -34
  146. package/dist/filesystem/indexeddb-store.d.ts.map +0 -1
  147. package/dist/filesystem/indexeddb-store.js +0 -165
  148. package/dist/filesystem/indexeddb-store.js.map +0 -1
  149. package/dist/filesystem/indexeddb.d.ts.map +0 -1
  150. package/dist/filesystem/legacy-v2-adapter.d.ts +0 -62
  151. package/dist/filesystem/legacy-v2-adapter.d.ts.map +0 -1
  152. package/dist/filesystem/legacy-v2-adapter.js +0 -499
  153. package/dist/filesystem/legacy-v2-adapter.js.map +0 -1
  154. package/dist/filesystem/memory-provider-v2.d.ts +0 -92
  155. package/dist/filesystem/memory-provider-v2.d.ts.map +0 -1
  156. package/dist/filesystem/memory-provider-v2.js +0 -615
  157. package/dist/filesystem/memory-provider-v2.js.map +0 -1
  158. package/dist/filesystem/memory-provider.d.ts +0 -54
  159. package/dist/filesystem/memory-provider.d.ts.map +0 -1
  160. package/dist/filesystem/memory-provider.js +0 -132
  161. package/dist/filesystem/memory-provider.js.map +0 -1
  162. package/dist/filesystem/memory.d.ts.map +0 -1
  163. package/dist/filesystem/move-entry.d.ts +0 -9
  164. package/dist/filesystem/move-entry.d.ts.map +0 -1
  165. package/dist/filesystem/move-entry.js +0 -103
  166. package/dist/filesystem/move-entry.js.map +0 -1
  167. package/dist/filesystem/move-error.d.ts +0 -53
  168. package/dist/filesystem/move-error.d.ts.map +0 -1
  169. package/dist/filesystem/move-error.js +0 -99
  170. package/dist/filesystem/move-error.js.map +0 -1
  171. package/dist/filesystem/native-provider-v2.d.ts +0 -75
  172. package/dist/filesystem/native-provider-v2.d.ts.map +0 -1
  173. package/dist/filesystem/native-provider-v2.js +0 -849
  174. package/dist/filesystem/native-provider-v2.js.map +0 -1
  175. package/dist/filesystem/native-provider.d.ts +0 -53
  176. package/dist/filesystem/native-provider.d.ts.map +0 -1
  177. package/dist/filesystem/native-provider.js +0 -471
  178. package/dist/filesystem/native-provider.js.map +0 -1
  179. package/dist/filesystem/native.d.ts.map +0 -1
  180. package/dist/filesystem/types.d.ts +0 -83
  181. package/dist/filesystem/types.d.ts.map +0 -1
  182. package/dist/filesystem/types.js +0 -16
  183. package/dist/filesystem/types.js.map +0 -1
  184. package/dist/filesystem/v2.d.ts +0 -172
  185. package/dist/filesystem/v2.d.ts.map +0 -1
  186. package/dist/filesystem/v2.js +0 -16
  187. package/dist/filesystem/v2.js.map +0 -1
  188. package/dist/filesystem/workspace-path.d.ts +0 -21
  189. package/dist/filesystem/workspace-path.d.ts.map +0 -1
  190. package/dist/filesystem/workspace-path.js +0 -80
  191. package/dist/filesystem/workspace-path.js.map +0 -1
  192. package/dist/host/filesystem-v2.d.ts +0 -45
  193. package/dist/host/filesystem-v2.d.ts.map +0 -1
  194. package/dist/host/filesystem-v2.js +0 -13
  195. package/dist/host/filesystem-v2.js.map +0 -1
  196. package/dist/host/git.d.ts +0 -200
  197. package/dist/host/git.d.ts.map +0 -1
  198. package/dist/host/git.js +0 -15
  199. package/dist/host/git.js.map +0 -1
  200. package/dist/host/index.d.ts.map +0 -1
  201. package/dist/host/types.d.ts +0 -232
  202. package/dist/host/types.d.ts.map +0 -1
  203. package/dist/host/types.js +0 -10
  204. package/dist/host/types.js.map +0 -1
  205. package/dist/host/wire-policy.d.ts +0 -22
  206. package/dist/host/wire-policy.d.ts.map +0 -1
  207. package/dist/host/wire-policy.js +0 -92
  208. package/dist/host/wire-policy.js.map +0 -1
  209. package/dist/index.d.ts.map +0 -1
  210. package/dist/mcp/index.d.ts.map +0 -1
  211. package/dist/mcp/types.d.ts +0 -466
  212. package/dist/mcp/types.d.ts.map +0 -1
  213. package/dist/mcp/types.js +0 -25
  214. package/dist/mcp/types.js.map +0 -1
  215. package/dist/mcp/wire.d.ts +0 -29
  216. package/dist/mcp/wire.d.ts.map +0 -1
  217. package/dist/mcp/wire.js +0 -1046
  218. package/dist/mcp/wire.js.map +0 -1
  219. package/dist/mcp/zod.d.ts.map +0 -1
  220. package/dist/vscode/index.d.ts.map +0 -1
  221. package/dist/vscode/messages.d.ts +0 -204
  222. package/dist/vscode/messages.d.ts.map +0 -1
  223. package/dist/vscode/messages.js +0 -494
  224. package/dist/vscode/messages.js.map +0 -1
  225. package/dist/workspace/index.d.ts.map +0 -1
  226. package/dist/workspace/reconcile-electron.d.ts +0 -19
  227. package/dist/workspace/reconcile-electron.d.ts.map +0 -1
  228. package/dist/workspace/reconcile-electron.js +0 -42
  229. package/dist/workspace/reconcile-electron.js.map +0 -1
  230. package/dist/workspace/types.d.ts +0 -69
  231. package/dist/workspace/types.d.ts.map +0 -1
  232. package/dist/workspace/types.js +0 -2
  233. package/dist/workspace/types.js.map +0 -1
  234. package/dist/workspace/workspace-manager.d.ts +0 -47
  235. package/dist/workspace/workspace-manager.d.ts.map +0 -1
  236. package/dist/workspace/workspace-manager.js +0 -126
  237. package/dist/workspace/workspace-manager.js.map +0 -1
  238. package/src/document/document-session.ts +0 -834
  239. package/src/document/filesystem-target.ts +0 -109
  240. package/src/document/index.ts +0 -41
  241. package/src/document/recovery-journal.ts +0 -536
  242. package/src/document/types.ts +0 -116
  243. package/src/filesystem/commit-lock.ts +0 -29
  244. package/src/filesystem/dbk-workspace.ts +0 -135
  245. package/src/filesystem/electron-provider-v2.ts +0 -630
  246. package/src/filesystem/electron-provider.ts +0 -99
  247. package/src/filesystem/electron.ts +0 -3
  248. package/src/filesystem/file-media-provider.ts +0 -103
  249. package/src/filesystem/filesystem-content-container.ts +0 -164
  250. package/src/filesystem/fs-error.ts +0 -234
  251. package/src/filesystem/index.ts +0 -143
  252. package/src/filesystem/indexeddb-content-container.ts +0 -112
  253. package/src/filesystem/indexeddb-provider-v2.ts +0 -1740
  254. package/src/filesystem/indexeddb-provider.ts +0 -171
  255. package/src/filesystem/indexeddb-store.ts +0 -207
  256. package/src/filesystem/indexeddb.ts +0 -12
  257. package/src/filesystem/legacy-v2-adapter.ts +0 -779
  258. package/src/filesystem/memory-provider-v2.ts +0 -896
  259. package/src/filesystem/memory-provider.ts +0 -180
  260. package/src/filesystem/memory.ts +0 -15
  261. package/src/filesystem/move-entry.ts +0 -142
  262. package/src/filesystem/move-error.ts +0 -159
  263. package/src/filesystem/native-provider-v2.ts +0 -1165
  264. package/src/filesystem/native-provider.ts +0 -537
  265. package/src/filesystem/native.ts +0 -16
  266. package/src/filesystem/types.ts +0 -114
  267. package/src/filesystem/v2.ts +0 -231
  268. package/src/filesystem/workspace-path.ts +0 -92
  269. package/src/host/filesystem-v2.ts +0 -104
  270. package/src/host/git.ts +0 -246
  271. package/src/host/index.ts +0 -93
  272. package/src/host/types.ts +0 -274
  273. package/src/host/wire-policy.ts +0 -103
  274. package/src/index.ts +0 -10
  275. package/src/mcp/index.ts +0 -3
  276. package/src/mcp/types.ts +0 -594
  277. package/src/mcp/wire.ts +0 -1280
  278. package/src/mcp/zod.ts +0 -1000
  279. package/src/vscode/index.ts +0 -2
  280. package/src/vscode/messages.ts +0 -704
  281. package/src/workspace/index.ts +0 -17
  282. package/src/workspace/reconcile-electron.ts +0 -65
  283. package/src/workspace/types.ts +0 -67
  284. package/src/workspace/workspace-manager.ts +0 -151
  285. /package/dist/{chunk-75UUF6C4.js.map → chunk-B56KWCSE.js.map} +0 -0
  286. /package/dist/{chunk-EGNDADXB.js.map → chunk-MNSZ7EZN.js.map} +0 -0
package/src/mcp/zod.ts DELETED
@@ -1,1000 +0,0 @@
1
- import { z } from 'zod';
2
- import { z as z4 } from 'zod/v4';
3
- import {
4
- MCP_WIRE_LIMITS,
5
- parseArtifactRef,
6
- parseComparisonResult,
7
- parseConversionResult,
8
- parseInspectionResult,
9
- parsePreviewResult,
10
- parseValidationResult,
11
- } from './wire.js';
12
- import type {
13
- DescribeTemplateResult,
14
- DescribeThemeResult,
15
- DocBlocksMcpToolName,
16
- FormatCapabilitySummary,
17
- FormatDirectionCapability,
18
- InferThemeResult,
19
- InspectPptxLayoutsResult,
20
- ListFormatsResult,
21
- ListRootsResult,
22
- ListTemplatesResult,
23
- ListThemesResult,
24
- ListTransformStylesResult,
25
- PptxLayoutSummary,
26
- RecommendTemplatesResult,
27
- RootGrantSummary,
28
- TemplateContentProfile,
29
- TemplateInputSummary,
30
- TemplateRecommendation,
31
- TemplateSummary,
32
- ThemeCatalogEntry,
33
- ThemeDescription,
34
- TransformStyleSummary,
35
- } from './types.js';
36
-
37
- /** Canonical Zod projection of the exact MCP wire contract for protocol SDKs. */
38
-
39
- export const MAX_MARKDOWN_CHARACTERS = 20 * 1024 * 1024;
40
- export const MAX_PATH_CHARACTERS = 4_096;
41
- const MAX_ID_CHARACTERS = 256;
42
-
43
- const IDENTIFIER_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._:-]*$/u;
44
- const FORMAT_PATTERN = /^[a-z0-9][a-z0-9.+_-]*$/u;
45
- const INPUT_FORMAT_PATTERN = /^[A-Za-z0-9][A-Za-z0-9.+_-]*$/u;
46
- const MIME_TYPE_PATTERN = /^[a-z0-9!#$&^_.+-]+\/[a-z0-9!#$&^_.+-]+$/iu;
47
- const ARTIFACT_URI_PATTERN = /^docblocks:\/\/artifacts\/[A-Za-z0-9][A-Za-z0-9._:-]*$/u;
48
- const ISO_TIMESTAMP_PATTERN = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/u;
49
- /* eslint-disable no-control-regex -- Wire contracts must publish explicit control-byte exclusions. */
50
- const WIRE_STRING_PATTERN = new RegExp('^[^\\u0000\\u007f]*$', 'u');
51
- const WORKSPACE_PATH_PATTERN = new RegExp(
52
- '^(?!/)(?![A-Za-z]:)(?!.*(?:^|/)(?:\\.{1,2})(?:/|$))(?!.*//)(?!.*[\\\\\\u0000-\\u001f\\u007f])(?!.*/$).+$',
53
- 'u',
54
- );
55
- const SAFE_FILENAME_PATTERN = new RegExp('^(?!\\.{1,2}$)[^/\\\\\\u0000\\u007f]+$', 'u');
56
- /* eslint-enable no-control-regex */
57
-
58
- const boundedString = z
59
- .string()
60
- .max(MCP_WIRE_LIMITS.messageCharacters)
61
- .regex(WIRE_STRING_PATTERN, 'NUL and DEL are not permitted on the MCP wire');
62
- const boundedNonEmptyString = z
63
- .string()
64
- .min(1)
65
- .max(MCP_WIRE_LIMITS.messageCharacters)
66
- .regex(WIRE_STRING_PATTERN, 'NUL and DEL are not permitted on the MCP wire');
67
- const labelSchema = z
68
- .string()
69
- .max(MCP_WIRE_LIMITS.labelCharacters)
70
- .regex(WIRE_STRING_PATTERN, 'NUL and DEL are not permitted on the MCP wire');
71
- const nonEmptyLabelSchema = labelSchema.min(1);
72
- const excerptSchema = z
73
- .string()
74
- .max(MCP_WIRE_LIMITS.excerptCharacters)
75
- .regex(WIRE_STRING_PATTERN, 'NUL and DEL are not permitted on the MCP wire');
76
- const uriTextSchema = z
77
- .string()
78
- .min(1)
79
- .max(MCP_WIRE_LIMITS.uriCharacters)
80
- .regex(WIRE_STRING_PATTERN, 'NUL and DEL are not permitted on the MCP wire');
81
- const nonNegativeSafeIntegerSchema = z.number().int().min(0).max(Number.MAX_SAFE_INTEGER);
82
- const idSchema = z.string().min(1).max(MAX_ID_CHARACTERS).regex(IDENTIFIER_PATTERN);
83
- export const formatSchema = z
84
- .string()
85
- .min(1)
86
- .max(MCP_WIRE_LIMITS.formatCharacters)
87
- .regex(FORMAT_PATTERN);
88
- /** Case-insensitive format input which handlers normalize before publishing it on the wire. */
89
- export const formatInputSchema = z
90
- .string()
91
- .min(1)
92
- .max(MCP_WIRE_LIMITS.formatCharacters)
93
- .regex(INPUT_FORMAT_PATTERN);
94
- const mimeTypeSchema = z
95
- .string()
96
- .min(3)
97
- .max(MCP_WIRE_LIMITS.mimeTypeCharacters)
98
- .regex(MIME_TYPE_PATTERN);
99
- const isoTimestampSchema = z
100
- .string()
101
- .regex(ISO_TIMESTAMP_PATTERN)
102
- .refine((value) => {
103
- const timestamp = Date.parse(value);
104
- return Number.isFinite(timestamp) && new Date(timestamp).toISOString() === value;
105
- }, 'Expected a canonical UTC timestamp with millisecond precision');
106
- const engineNameSchema = z
107
- .string()
108
- .min(1)
109
- .max(MAX_ID_CHARACTERS)
110
- .regex(
111
- /^(?:[A-Za-z0-9][A-Za-z0-9._:-]*|@[A-Za-z0-9][A-Za-z0-9._-]*\/[A-Za-z0-9][A-Za-z0-9._-]*)$/u,
112
- );
113
- const workspacePathSchema = z
114
- .string()
115
- .min(1)
116
- .max(MAX_PATH_CHARACTERS)
117
- .regex(WORKSPACE_PATH_PATTERN, 'Expected a canonical root-relative forward-slash path')
118
- .refine(
119
- (value) =>
120
- !value.includes('\\') &&
121
- !value.startsWith('/') &&
122
- !/^[a-zA-Z]:/u.test(value) &&
123
- !value.split('/').some((segment) => !segment || segment === '.' || segment === '..') &&
124
- ![...value].some((character) => {
125
- const codePoint = character.codePointAt(0) ?? 0;
126
- return codePoint <= 0x1f || codePoint === 0x7f;
127
- }),
128
- 'Expected a canonical root-relative forward-slash path',
129
- );
130
- export const artifactUriSchema = z
131
- .string()
132
- .max('docblocks://artifacts/'.length + MAX_ID_CHARACTERS)
133
- .regex(ARTIFACT_URI_PATTERN);
134
-
135
- const assetSourceSchema = z.discriminatedUnion('kind', [
136
- z.object({ kind: z.literal('file'), rootId: idSchema, path: workspacePathSchema }).strict(),
137
- z.object({ kind: z.literal('artifact'), uri: artifactUriSchema }).strict(),
138
- ]);
139
-
140
- export const bundleAssetSchema = z
141
- .object({
142
- path: workspacePathSchema,
143
- source: assetSourceSchema,
144
- mimeType: mimeTypeSchema.nullable(),
145
- altText: labelSchema.nullable(),
146
- credit: labelSchema.nullable(),
147
- license: labelSchema.nullable(),
148
- })
149
- .strict();
150
-
151
- export const bundleDocumentSourceSchema = z
152
- .object({
153
- kind: z.literal('bundle'),
154
- markdown: z
155
- .string()
156
- .max(MAX_MARKDOWN_CHARACTERS)
157
- .regex(WIRE_STRING_PATTERN, 'NUL and DEL are not permitted on the MCP wire'),
158
- assets: z.array(bundleAssetSchema).max(MCP_WIRE_LIMITS.bundleAssets),
159
- name: labelSchema.nullable(),
160
- })
161
- .strict();
162
-
163
- export const documentSourceSchema = z.discriminatedUnion('kind', [
164
- z
165
- .object({
166
- kind: z.literal('markdown'),
167
- markdown: z
168
- .string()
169
- .max(MAX_MARKDOWN_CHARACTERS)
170
- .regex(WIRE_STRING_PATTERN, 'NUL and DEL are not permitted on the MCP wire'),
171
- name: labelSchema.nullable(),
172
- })
173
- .strict(),
174
- z
175
- .object({
176
- kind: z.literal('file'),
177
- rootId: idSchema,
178
- path: workspacePathSchema,
179
- format: formatSchema.nullable(),
180
- })
181
- .strict(),
182
- z.object({ kind: z.literal('artifact'), uri: artifactUriSchema }).strict(),
183
- bundleDocumentSourceSchema,
184
- ]);
185
-
186
- const appliedOptionSchema = z
187
- .object({
188
- name: idSchema,
189
- value: z.union([boundedString, z.number().finite(), z.boolean(), z.null()]),
190
- })
191
- .strict();
192
- const engineVersionSchema = z
193
- .object({ name: engineNameSchema, version: boundedNonEmptyString })
194
- .strict();
195
-
196
- export const artifactRefSchema = z
197
- .object({
198
- id: idSchema,
199
- uri: artifactUriSchema,
200
- format: formatSchema,
201
- mimeType: mimeTypeSchema,
202
- size: z.number().int().nonnegative().max(MCP_WIRE_LIMITS.artifactBytes),
203
- sha256: z.string().regex(/^[a-f0-9]{64}$/u),
204
- sourceFormat: formatSchema.nullable(),
205
- sourceSha256: z
206
- .string()
207
- .regex(/^[a-f0-9]{64}$/u)
208
- .nullable(),
209
- suggestedFilename: z
210
- .string()
211
- .min(1)
212
- .max(MCP_WIRE_LIMITS.labelCharacters)
213
- .regex(SAFE_FILENAME_PATTERN),
214
- appliedOptions: z.array(appliedOptionSchema).max(MCP_WIRE_LIMITS.arrayEntries),
215
- engineVersions: z.array(engineVersionSchema).max(MCP_WIRE_LIMITS.arrayEntries),
216
- createdAt: isoTimestampSchema,
217
- expiresAt: isoTimestampSchema.nullable(),
218
- })
219
- .strict()
220
- .superRefine((value, context) => addExactWireIssue(parseArtifactRef(value), context));
221
-
222
- const diagnosticLocationSchema = z.discriminatedUnion('kind', [
223
- z
224
- .object({
225
- kind: z.literal('source'),
226
- line: z.number().int().min(1).max(Number.MAX_SAFE_INTEGER),
227
- column: z.number().int().min(1).max(Number.MAX_SAFE_INTEGER),
228
- })
229
- .strict(),
230
- z.object({ kind: z.literal('block'), blockId: idSchema, nodeType: idSchema }).strict(),
231
- z.object({ kind: z.literal('asset'), path: workspacePathSchema }).strict(),
232
- z
233
- .object({
234
- kind: z.literal('item'),
235
- itemKind: z.enum(['page', 'slide', 'sheet', 'frame']),
236
- index: nonNegativeSafeIntegerSchema,
237
- })
238
- .strict(),
239
- ]);
240
-
241
- export const diagnosticSchema = z
242
- .object({
243
- code: idSchema,
244
- severity: z.enum(['info', 'warning', 'error']),
245
- stage: z.enum([
246
- 'resolve',
247
- 'import',
248
- 'parse',
249
- 'inspect',
250
- 'validate',
251
- 'transform',
252
- 'convert',
253
- 'render',
254
- 'export',
255
- 'materialize',
256
- 'compare',
257
- ]),
258
- format: formatSchema.nullable(),
259
- count: z.number().int().min(1).max(Number.MAX_SAFE_INTEGER),
260
- message: boundedString,
261
- remediation: boundedString.nullable(),
262
- retryable: z.boolean(),
263
- location: diagnosticLocationSchema.nullable(),
264
- })
265
- .strict();
266
-
267
- export const mcpErrorDetailSchema = z
268
- .object({
269
- code: idSchema,
270
- message: boundedNonEmptyString,
271
- stage: z
272
- .enum([
273
- 'resolve',
274
- 'import',
275
- 'parse',
276
- 'inspect',
277
- 'validate',
278
- 'transform',
279
- 'convert',
280
- 'render',
281
- 'export',
282
- 'materialize',
283
- 'compare',
284
- ])
285
- .nullable(),
286
- format: formatSchema.nullable(),
287
- hint: boundedString.nullable(),
288
- retryable: z.boolean(),
289
- operationLoad: z
290
- .object({
291
- active: z.number().int().nonnegative().max(32),
292
- capacity: z.number().int().positive().max(32),
293
- })
294
- .strict()
295
- .nullable(),
296
- })
297
- .strict()
298
- .superRefine((value, context) => {
299
- if (value.operationLoad && value.operationLoad.active > value.operationLoad.capacity) {
300
- context.addIssue({
301
- code: z.ZodIssueCode.custom,
302
- path: ['operationLoad', 'active'],
303
- message: 'Active operation count cannot exceed capacity',
304
- });
305
- }
306
- });
307
-
308
- export const mcpErrorResultSchema = z
309
- .object({
310
- version: z.literal(1),
311
- kind: z.literal('error'),
312
- result: z.null(),
313
- error: mcpErrorDetailSchema,
314
- })
315
- .strict();
316
-
317
- /**
318
- * Root-object output schema compatible with MCP SDK 1.29's object normalizer.
319
- *
320
- * The SDK must see an object at the root, while clients must see the two exact
321
- * wire branches rather than independently-nullable fields. A Zod 4 object lets
322
- * us publish the branch schemas through standard JSON Schema `oneOf` metadata;
323
- * runtime validation still delegates to the original Zod 3 schemas so custom
324
- * exact-wire refinements remain authoritative.
325
- */
326
- export function toolOutputSchema<T extends z.ZodTypeAny>(success: T) {
327
- const successEnvelope = z
328
- .object({
329
- version: z.literal(1),
330
- kind: z.literal('success'),
331
- result: success,
332
- error: z.null(),
333
- })
334
- .strict();
335
- const errorEnvelope = z
336
- .object({
337
- version: z.literal(1),
338
- kind: z.literal('error'),
339
- result: z.null(),
340
- error: mcpErrorDetailSchema,
341
- })
342
- .strict();
343
- const publishedSuccess = z4
344
- .object({
345
- version: z4.literal(1),
346
- kind: z4.literal('success'),
347
- result: projectZod3Schema(success),
348
- error: z4.null(),
349
- })
350
- .strict();
351
- const publishedError = z4
352
- .object({
353
- version: z4.literal(1),
354
- kind: z4.literal('error'),
355
- result: z4.null(),
356
- error: projectZod3Schema(mcpErrorDetailSchema),
357
- })
358
- .strict();
359
- const oneOf = [
360
- jsonSchemaWithoutDialect(publishedSuccess),
361
- jsonSchemaWithoutDialect(publishedError),
362
- ];
363
-
364
- return z4
365
- .object({
366
- version: z4.literal(1),
367
- kind: z4.enum(['success', 'error']),
368
- result: z4.unknown(),
369
- error: z4.unknown(),
370
- })
371
- .strict()
372
- .superRefine((value, context) => {
373
- const branch = value.kind === 'success' ? successEnvelope : errorEnvelope;
374
- const parsed = branch.safeParse(value);
375
- if (parsed.success) return;
376
- for (const issue of parsed.error.issues) {
377
- context.addIssue({
378
- code: 'custom',
379
- path: issue.path,
380
- message: issue.message,
381
- });
382
- }
383
- })
384
- .meta({ oneOf });
385
- }
386
-
387
- const assetSummarySchema = z
388
- .object({
389
- path: workspacePathSchema,
390
- mimeType: mimeTypeSchema,
391
- size: z.number().int().nonnegative().max(MCP_WIRE_LIMITS.artifactBytes),
392
- sha256: z
393
- .string()
394
- .regex(/^[a-f0-9]{64}$/u)
395
- .nullable(),
396
- altText: labelSchema.nullable(),
397
- credit: labelSchema.nullable(),
398
- license: labelSchema.nullable(),
399
- })
400
- .strict();
401
-
402
- export const conversionResultSchema = z
403
- .object({
404
- version: z.literal(1),
405
- kind: z.literal('conversion'),
406
- sourceFormat: formatSchema,
407
- targetFormat: formatSchema,
408
- artifact: artifactRefSchema,
409
- fidelity: z.enum(['semantic', 'editable-native', 'rendered-fidelity', 'hybrid']),
410
- appliedThemeId: idSchema.nullable(),
411
- appliedTransformId: idSchema.nullable(),
412
- sourceAssets: z.array(assetSummarySchema).max(MCP_WIRE_LIMITS.arrayEntries),
413
- sourceAssetCount: z.number().int().min(0).max(MCP_WIRE_LIMITS.arrayEntries),
414
- diagnostics: z.array(diagnosticSchema).max(MCP_WIRE_LIMITS.arrayEntries),
415
- })
416
- .strict()
417
- .superRefine((value, context) => addExactWireIssue(parseConversionResult(value), context));
418
-
419
- const metadataSchema = z
420
- .object({
421
- title: labelSchema.nullable(),
422
- author: labelSchema.nullable(),
423
- description: boundedString.nullable(),
424
- })
425
- .strict();
426
- const statisticsSchema = z
427
- .object({
428
- blockCount: nonNegativeSafeIntegerSchema,
429
- wordCount: nonNegativeSafeIntegerSchema,
430
- characterCount: nonNegativeSafeIntegerSchema,
431
- tableCount: nonNegativeSafeIntegerSchema,
432
- linkCount: nonNegativeSafeIntegerSchema,
433
- assetCount: nonNegativeSafeIntegerSchema,
434
- pageCount: nonNegativeSafeIntegerSchema.nullable(),
435
- slideCount: nonNegativeSafeIntegerSchema.nullable(),
436
- sheetCount: nonNegativeSafeIntegerSchema.nullable(),
437
- })
438
- .strict();
439
- const outlineEntrySchema = z
440
- .object({
441
- id: idSchema,
442
- title: nonEmptyLabelSchema,
443
- level: z.number().int().min(1).max(6),
444
- blockIndex: nonNegativeSafeIntegerSchema,
445
- })
446
- .strict();
447
- const blockSummarySchema = z
448
- .object({
449
- id: idSchema,
450
- type: idSchema,
451
- text: excerptSchema,
452
- wordCount: nonNegativeSafeIntegerSchema,
453
- templateId: idSchema.nullable(),
454
- sourceRange: z
455
- .object({ start: nonNegativeSafeIntegerSchema, end: nonNegativeSafeIntegerSchema })
456
- .strict()
457
- .nullable(),
458
- })
459
- .strict();
460
- const tableSummarySchema = z
461
- .object({
462
- index: nonNegativeSafeIntegerSchema,
463
- rowCount: nonNegativeSafeIntegerSchema,
464
- columnCount: nonNegativeSafeIntegerSchema,
465
- headers: z.array(labelSchema).max(MCP_WIRE_LIMITS.arrayEntries),
466
- })
467
- .strict();
468
- const linkSummarySchema = z
469
- .object({
470
- index: nonNegativeSafeIntegerSchema,
471
- text: labelSchema,
472
- target: uriTextSchema,
473
- })
474
- .strict();
475
- const documentItemSummarySchema = z
476
- .object({
477
- kind: z.enum(['page', 'slide', 'sheet', 'frame']),
478
- index: nonNegativeSafeIntegerSchema,
479
- label: labelSchema.nullable(),
480
- blockIds: z.array(idSchema).max(MCP_WIRE_LIMITS.arrayEntries),
481
- })
482
- .strict();
483
- const themeSummarySchema = z
484
- .object({
485
- id: idSchema,
486
- name: nonEmptyLabelSchema,
487
- source: z.enum(['built-in', 'document', 'inferred']),
488
- layouts: z.array(nonEmptyLabelSchema).max(MCP_WIRE_LIMITS.arrayEntries),
489
- })
490
- .strict();
491
-
492
- export const inspectionResultSchema = z
493
- .object({
494
- version: z.literal(1),
495
- kind: z.literal('inspection'),
496
- sourceFormat: formatSchema,
497
- metadata: metadataSchema,
498
- statistics: statisticsSchema,
499
- outline: z.array(outlineEntrySchema).max(MCP_WIRE_LIMITS.arrayEntries),
500
- blocks: z.array(blockSummarySchema).max(MCP_WIRE_LIMITS.arrayEntries),
501
- blockOffset: z.number().int().min(0).max(MCP_WIRE_LIMITS.arrayEntries),
502
- nextCursor: z
503
- .string()
504
- .max(MCP_WIRE_LIMITS.identifierCharacters)
505
- .regex(WIRE_STRING_PATTERN)
506
- .nullable(),
507
- tables: z.array(tableSummarySchema).max(MCP_WIRE_LIMITS.arrayEntries),
508
- links: z.array(linkSummarySchema).max(MCP_WIRE_LIMITS.arrayEntries),
509
- items: z.array(documentItemSummarySchema).max(MCP_WIRE_LIMITS.arrayEntries),
510
- assets: z.array(assetSummarySchema).max(MCP_WIRE_LIMITS.arrayEntries),
511
- theme: themeSummarySchema.nullable(),
512
- truncated: z.boolean(),
513
- detailsTruncated: z.boolean(),
514
- diagnostics: z.array(diagnosticSchema).max(MCP_WIRE_LIMITS.arrayEntries),
515
- })
516
- .strict()
517
- .superRefine((value, context) => addExactWireIssue(parseInspectionResult(value), context));
518
-
519
- export const validationResultSchema = z
520
- .object({
521
- version: z.literal(1),
522
- kind: z.literal('validation'),
523
- sourceFormat: formatSchema,
524
- targetFormat: formatSchema.nullable(),
525
- valid: z.boolean(),
526
- summary: z
527
- .object({
528
- errorCount: nonNegativeSafeIntegerSchema,
529
- warningCount: nonNegativeSafeIntegerSchema,
530
- infoCount: nonNegativeSafeIntegerSchema,
531
- })
532
- .strict(),
533
- diagnostics: z.array(diagnosticSchema).max(MCP_WIRE_LIMITS.arrayEntries),
534
- })
535
- .strict()
536
- .superRefine((value, context) => addExactWireIssue(parseValidationResult(value), context));
537
-
538
- const previewItemSchema = z
539
- .object({
540
- kind: z.enum(['page', 'slide', 'sheet', 'frame']),
541
- index: nonNegativeSafeIntegerSchema,
542
- label: labelSchema.nullable(),
543
- artifact: artifactRefSchema,
544
- width: z.number().int().min(1).max(MCP_WIRE_LIMITS.imageDimension),
545
- height: z.number().int().min(1).max(MCP_WIRE_LIMITS.imageDimension),
546
- })
547
- .strict();
548
- export const previewResultSchema = z
549
- .object({
550
- version: z.literal(1),
551
- kind: z.literal('preview'),
552
- sourceFormat: formatSchema,
553
- previewBasis: z.enum(['source-render', 'reconstructed-import', 'native-extracted']),
554
- totalItems: nonNegativeSafeIntegerSchema,
555
- items: z.array(previewItemSchema).max(MCP_WIRE_LIMITS.previewItems),
556
- truncated: z.boolean(),
557
- diagnostics: z.array(diagnosticSchema).max(MCP_WIRE_LIMITS.arrayEntries),
558
- })
559
- .strict()
560
- .superRefine((value, context) => addExactWireIssue(parsePreviewResult(value), context));
561
-
562
- const comparisonChangeSchema = z
563
- .object({
564
- category: z.enum([
565
- 'text',
566
- 'structure',
567
- 'table',
568
- 'media',
569
- 'theme',
570
- 'layout',
571
- 'metadata',
572
- 'timing',
573
- 'accessibility',
574
- ]),
575
- status: z.enum(['retained', 'changed', 'degraded', 'omitted', 'added']),
576
- path: z.string().max(MCP_WIRE_LIMITS.pathCharacters).regex(WIRE_STRING_PATTERN).nullable(),
577
- message: boundedNonEmptyString,
578
- })
579
- .strict();
580
- const comparisonMetricSchema = z
581
- .object({
582
- name: idSchema,
583
- leftValue: z.number().finite(),
584
- rightValue: z.number().finite(),
585
- similarity: z.number().min(0).max(1),
586
- })
587
- .strict();
588
- export const comparisonResultSchema = z
589
- .object({
590
- version: z.literal(1),
591
- kind: z.literal('comparison'),
592
- leftFormat: formatSchema,
593
- rightFormat: formatSchema,
594
- equivalent: z.boolean(),
595
- score: z.number().min(0).max(1),
596
- changes: z.array(comparisonChangeSchema).max(MCP_WIRE_LIMITS.arrayEntries),
597
- metrics: z.array(comparisonMetricSchema).max(MCP_WIRE_LIMITS.arrayEntries),
598
- diagnostics: z.array(diagnosticSchema).max(MCP_WIRE_LIMITS.arrayEntries),
599
- })
600
- .strict()
601
- .superRefine((value, context) => addExactWireIssue(parseComparisonResult(value), context));
602
-
603
- const boundedPathTextSchema = z
604
- .string()
605
- .min(1)
606
- .max(MCP_WIRE_LIMITS.pathCharacters)
607
- .regex(WIRE_STRING_PATTERN, 'NUL and DEL are not permitted on the MCP wire');
608
- const sha256Schema = z.string().regex(/^[a-f0-9]{64}$/u);
609
-
610
- export const convertDocumentResultSchema = z
611
- .object({ results: z.array(conversionResultSchema).min(1).max(12) })
612
- .strict();
613
-
614
- export const rootGrantSummarySchema = z
615
- .object({
616
- id: idSchema,
617
- label: nonEmptyLabelSchema,
618
- read: z.boolean(),
619
- write: z.boolean(),
620
- })
621
- .strict() satisfies z.ZodType<RootGrantSummary>;
622
-
623
- export const listRootsResultSchema = z
624
- .object({ roots: z.array(rootGrantSummarySchema).max(64) })
625
- .strict() satisfies z.ZodType<ListRootsResult>;
626
-
627
- export const saveArtifactResultSchema = z
628
- .object({
629
- artifact: artifactRefSchema,
630
- destination: z.object({ rootId: idSchema, path: workspacePathSchema }).strict(),
631
- sha256: sha256Schema,
632
- })
633
- .strict();
634
-
635
- export const formatDirectionCapabilitySchema = z.discriminatedUnion('supported', [
636
- z
637
- .object({
638
- supported: z.literal(true),
639
- tool: z.enum(['inspect_document', 'convert_document']),
640
- })
641
- .strict(),
642
- z.object({ supported: z.literal(false), excludedReason: boundedString }).strict(),
643
- ]) satisfies z.ZodType<FormatDirectionCapability>;
644
-
645
- export const formatCapabilitySummarySchema = z
646
- .object({
647
- id: formatSchema,
648
- label: nonEmptyLabelSchema,
649
- mimeType: mimeTypeSchema,
650
- extensions: z.array(nonEmptyLabelSchema).max(64),
651
- import: formatDirectionCapabilitySchema,
652
- export: formatDirectionCapabilitySchema,
653
- })
654
- .strict() satisfies z.ZodType<FormatCapabilitySummary>;
655
-
656
- export const listFormatsResultSchema = z
657
- .object({ formats: z.array(formatCapabilitySummarySchema).max(64) })
658
- .strict() satisfies z.ZodType<ListFormatsResult>;
659
-
660
- export const themeCatalogEntrySchema = z
661
- .object({
662
- id: idSchema,
663
- name: nonEmptyLabelSchema,
664
- description: boundedString.optional(),
665
- })
666
- .strict() satisfies z.ZodType<ThemeCatalogEntry>;
667
-
668
- export const listThemesResultSchema = z
669
- .object({ themes: z.array(themeCatalogEntrySchema).max(MCP_WIRE_LIMITS.arrayEntries) })
670
- .strict() satisfies z.ZodType<ListThemesResult>;
671
-
672
- export const transformStyleSummarySchema = z
673
- .object({ id: idSchema, name: nonEmptyLabelSchema, description: boundedString })
674
- .strict() satisfies z.ZodType<TransformStyleSummary>;
675
-
676
- export const listTransformStylesResultSchema = z
677
- .object({
678
- styles: z.array(transformStyleSummarySchema).max(MCP_WIRE_LIMITS.arrayEntries),
679
- })
680
- .strict() satisfies z.ZodType<ListTransformStylesResult>;
681
-
682
- export const templateSummarySchema = z
683
- .object({ id: idSchema, label: nonEmptyLabelSchema, description: boundedString })
684
- .strict() satisfies z.ZodType<TemplateSummary>;
685
-
686
- export const listTemplatesResultSchema = z
687
- .object({ templates: z.array(templateSummarySchema).max(MCP_WIRE_LIMITS.arrayEntries) })
688
- .strict() satisfies z.ZodType<ListTemplatesResult>;
689
-
690
- export const templateInputSummarySchema = z
691
- .object({
692
- key: idSchema,
693
- description: boundedString,
694
- type: nonEmptyLabelSchema,
695
- required: z.boolean(),
696
- values: z.array(labelSchema).max(MCP_WIRE_LIMITS.arrayEntries),
697
- valueHint: labelSchema.nullable(),
698
- })
699
- .strict() satisfies z.ZodType<TemplateInputSummary>;
700
-
701
- export const describeTemplateResultSchema = z
702
- .object({
703
- template: templateSummarySchema
704
- .extend({ inputs: z.array(templateInputSummarySchema).max(MCP_WIRE_LIMITS.arrayEntries) })
705
- .strict(),
706
- annotationExample: boundedString,
707
- })
708
- .strict() satisfies z.ZodType<DescribeTemplateResult>;
709
-
710
- export const templateContentProfileSchema = z
711
- .object({
712
- hasImage: z.boolean(),
713
- imageCount: nonNegativeSafeIntegerSchema,
714
- hasVideo: z.boolean(),
715
- hasBlockquote: z.boolean(),
716
- hasList: z.boolean(),
717
- hasTable: z.boolean(),
718
- hasDate: z.boolean(),
719
- hasNumberHighlight: z.boolean(),
720
- wordCount: nonNegativeSafeIntegerSchema,
721
- hasAsciiDiagram: z.boolean(),
722
- hasTimeline: z.boolean(),
723
- hasTree: z.boolean(),
724
- })
725
- .strict() satisfies z.ZodType<TemplateContentProfile>;
726
-
727
- export const templateRecommendationSchema = z
728
- .object({
729
- blockId: idSchema,
730
- title: labelSchema.nullable(),
731
- profile: templateContentProfileSchema,
732
- recommendedTemplateIds: z.array(idSchema).max(256),
733
- })
734
- .strict() satisfies z.ZodType<TemplateRecommendation>;
735
-
736
- export const recommendTemplatesResultSchema = z
737
- .object({
738
- recommendations: z.array(templateRecommendationSchema).max(100),
739
- totalBlocks: nonNegativeSafeIntegerSchema,
740
- truncated: z.boolean(),
741
- })
742
- .strict() satisfies z.ZodType<RecommendTemplatesResult>;
743
-
744
- export const themeDescriptionSchema = z
745
- .object({
746
- id: idSchema,
747
- name: nonEmptyLabelSchema,
748
- description: boundedString,
749
- colors: z
750
- .object({
751
- primary: nonEmptyLabelSchema,
752
- secondary: nonEmptyLabelSchema,
753
- background: nonEmptyLabelSchema,
754
- text: nonEmptyLabelSchema,
755
- highlight: nonEmptyLabelSchema,
756
- })
757
- .strict(),
758
- bodyFont: boundedString,
759
- titleFont: boundedString,
760
- })
761
- .strict() satisfies z.ZodType<ThemeDescription>;
762
-
763
- export const describeThemeResultSchema = z
764
- .object({ theme: themeDescriptionSchema, source: z.enum(['built-in', 'document']) })
765
- .strict() satisfies z.ZodType<DescribeThemeResult>;
766
-
767
- export const inferredLayoutSummarySchema = z
768
- .object({ id: nonEmptyLabelSchema, name: nonEmptyLabelSchema, description: boundedString })
769
- .strict();
770
-
771
- export const inferThemeResultSchema = z
772
- .object({
773
- sourceFormat: formatSchema,
774
- sourceSha256: sha256Schema,
775
- theme: themeDescriptionSchema,
776
- layouts: z.array(inferredLayoutSummarySchema).max(1_000),
777
- warnings: z.array(boundedString).max(MCP_WIRE_LIMITS.arrayEntries),
778
- })
779
- .strict() satisfies z.ZodType<InferThemeResult>;
780
-
781
- export const pptxLayoutSummarySchema = z
782
- .object({
783
- layoutPath: boundedPathTextSchema,
784
- name: nonEmptyLabelSchema,
785
- masterName: labelSchema.nullable(),
786
- type: labelSchema.nullable(),
787
- slideCount: nonNegativeSafeIntegerSchema,
788
- verdict: z.enum(['builtin', 'custom', 'plain', 'skip']),
789
- templateId: labelSchema.nullable(),
790
- notes: z.array(boundedString).max(1_000),
791
- })
792
- .strict() satisfies z.ZodType<PptxLayoutSummary>;
793
-
794
- export const inspectPptxLayoutsResultSchema = z
795
- .object({
796
- slideSize: z
797
- .object({ cx: nonNegativeSafeIntegerSchema, cy: nonNegativeSafeIntegerSchema })
798
- .strict(),
799
- layouts: z.array(pptxLayoutSummarySchema).max(2_048),
800
- })
801
- .strict() satisfies z.ZodType<InspectPptxLayoutsResult>;
802
-
803
- export const applyInferredThemeResultSchema = z
804
- .object({
805
- result: conversionResultSchema,
806
- theme: themeDescriptionSchema,
807
- layoutIds: z.array(labelSchema).max(1_000),
808
- warnings: z.array(boundedString).max(MCP_WIRE_LIMITS.arrayEntries),
809
- })
810
- .strict();
811
-
812
- /** Core-owned success payload schemas for every advertised canonical MCP tool. */
813
- export const DOCBLOCKS_MCP_TOOL_RESULT_SCHEMAS: Readonly<
814
- Record<DocBlocksMcpToolName, z.ZodTypeAny>
815
- > = Object.freeze({
816
- list_roots: listRootsResultSchema,
817
- get_conversion_report: conversionResultSchema,
818
- convert_document: convertDocumentResultSchema,
819
- create_document_bundle: conversionResultSchema,
820
- save_artifact: saveArtifactResultSchema,
821
- inspect_document: inspectionResultSchema,
822
- validate_document: validationResultSchema,
823
- preview_document: previewResultSchema,
824
- compare_documents: comparisonResultSchema,
825
- list_templates: listTemplatesResultSchema,
826
- describe_template: describeTemplateResultSchema,
827
- recommend_templates: recommendTemplatesResultSchema,
828
- describe_theme: describeThemeResultSchema,
829
- infer_theme_from_file: inferThemeResultSchema,
830
- inspect_pptx_layouts: inspectPptxLayoutsResultSchema,
831
- apply_inferred_theme: applyInferredThemeResultSchema,
832
- list_formats: listFormatsResultSchema,
833
- list_themes: listThemesResultSchema,
834
- list_transform_styles: listTransformStylesResultSchema,
835
- });
836
-
837
- /** Exact success/error envelopes consumed directly by MCP tool registration. */
838
- type DocBlocksMcpToolOutputSchema = ReturnType<typeof toolOutputSchema>;
839
- export const DOCBLOCKS_MCP_TOOL_OUTPUT_SCHEMAS: Readonly<
840
- Record<DocBlocksMcpToolName, DocBlocksMcpToolOutputSchema>
841
- > = Object.freeze({
842
- list_roots: toolOutputSchema(DOCBLOCKS_MCP_TOOL_RESULT_SCHEMAS.list_roots),
843
- get_conversion_report: toolOutputSchema(DOCBLOCKS_MCP_TOOL_RESULT_SCHEMAS.get_conversion_report),
844
- convert_document: toolOutputSchema(DOCBLOCKS_MCP_TOOL_RESULT_SCHEMAS.convert_document),
845
- create_document_bundle: toolOutputSchema(
846
- DOCBLOCKS_MCP_TOOL_RESULT_SCHEMAS.create_document_bundle,
847
- ),
848
- save_artifact: toolOutputSchema(DOCBLOCKS_MCP_TOOL_RESULT_SCHEMAS.save_artifact),
849
- inspect_document: toolOutputSchema(DOCBLOCKS_MCP_TOOL_RESULT_SCHEMAS.inspect_document),
850
- validate_document: toolOutputSchema(DOCBLOCKS_MCP_TOOL_RESULT_SCHEMAS.validate_document),
851
- preview_document: toolOutputSchema(DOCBLOCKS_MCP_TOOL_RESULT_SCHEMAS.preview_document),
852
- compare_documents: toolOutputSchema(DOCBLOCKS_MCP_TOOL_RESULT_SCHEMAS.compare_documents),
853
- list_templates: toolOutputSchema(DOCBLOCKS_MCP_TOOL_RESULT_SCHEMAS.list_templates),
854
- describe_template: toolOutputSchema(DOCBLOCKS_MCP_TOOL_RESULT_SCHEMAS.describe_template),
855
- recommend_templates: toolOutputSchema(DOCBLOCKS_MCP_TOOL_RESULT_SCHEMAS.recommend_templates),
856
- describe_theme: toolOutputSchema(DOCBLOCKS_MCP_TOOL_RESULT_SCHEMAS.describe_theme),
857
- infer_theme_from_file: toolOutputSchema(DOCBLOCKS_MCP_TOOL_RESULT_SCHEMAS.infer_theme_from_file),
858
- inspect_pptx_layouts: toolOutputSchema(DOCBLOCKS_MCP_TOOL_RESULT_SCHEMAS.inspect_pptx_layouts),
859
- apply_inferred_theme: toolOutputSchema(DOCBLOCKS_MCP_TOOL_RESULT_SCHEMAS.apply_inferred_theme),
860
- list_formats: toolOutputSchema(DOCBLOCKS_MCP_TOOL_RESULT_SCHEMAS.list_formats),
861
- list_themes: toolOutputSchema(DOCBLOCKS_MCP_TOOL_RESULT_SCHEMAS.list_themes),
862
- list_transform_styles: toolOutputSchema(DOCBLOCKS_MCP_TOOL_RESULT_SCHEMAS.list_transform_styles),
863
- });
864
-
865
- export const materializationOptionsSchema = z.discriminatedUnion('ifExists', [
866
- z
867
- .object({
868
- rootId: idSchema,
869
- path: workspacePathSchema,
870
- ifExists: z.literal('error'),
871
- expectedSha256: z.null(),
872
- })
873
- .strict(),
874
- z
875
- .object({
876
- rootId: idSchema,
877
- path: workspacePathSchema,
878
- ifExists: z.literal('replace'),
879
- expectedSha256: z.string().regex(/^[a-f0-9]{64}$/u),
880
- })
881
- .strict(),
882
- ]);
883
-
884
- function addExactWireIssue<T>(parsed: T | null, context: z.RefinementCtx): void {
885
- if (parsed !== null) return;
886
- context.addIssue({
887
- code: z.ZodIssueCode.custom,
888
- message: 'Value does not satisfy the exact DocBlocks MCP wire invariants',
889
- });
890
- }
891
-
892
- /** Project the Zod 3 subset used by tool outputs into Zod 4 for SDK JSON Schema publication. */
893
- function projectZod3Schema(schema: z.ZodTypeAny): z4.ZodType {
894
- if (schema instanceof z.ZodEffects) return projectZod3Schema(schema.innerType());
895
- if (schema instanceof z.ZodOptional) return projectZod3Schema(schema.unwrap()).optional();
896
- if (schema instanceof z.ZodNullable) return projectZod3Schema(schema.unwrap()).nullable();
897
- if (schema instanceof z.ZodString) {
898
- let projected = z4.string();
899
- for (const check of schema._def.checks) {
900
- switch (check.kind) {
901
- case 'min':
902
- projected = projected.min(check.value);
903
- break;
904
- case 'max':
905
- projected = projected.max(check.value);
906
- break;
907
- case 'length':
908
- projected = projected.length(check.value);
909
- break;
910
- case 'regex':
911
- projected = projected.regex(check.regex);
912
- break;
913
- default:
914
- throw new Error(`Unsupported Zod string check in MCP output schema: ${check.kind}`);
915
- }
916
- }
917
- return projected;
918
- }
919
- if (schema instanceof z.ZodNumber) {
920
- let projected = z4.number();
921
- for (const check of schema._def.checks) {
922
- switch (check.kind) {
923
- case 'min':
924
- projected = check.inclusive ? projected.min(check.value) : projected.gt(check.value);
925
- break;
926
- case 'max':
927
- projected = check.inclusive ? projected.max(check.value) : projected.lt(check.value);
928
- break;
929
- case 'int':
930
- projected = projected.int();
931
- break;
932
- case 'multipleOf':
933
- projected = projected.multipleOf(check.value);
934
- break;
935
- case 'finite':
936
- // Zod 4 numbers reject infinities by default.
937
- break;
938
- }
939
- }
940
- return projected;
941
- }
942
- if (schema instanceof z.ZodBoolean) return z4.boolean();
943
- if (schema instanceof z.ZodNull) return z4.null();
944
- if (schema instanceof z.ZodAny) return z4.any();
945
- if (schema instanceof z.ZodUnknown) return z4.unknown();
946
- if (schema instanceof z.ZodNever) return z4.never();
947
- if (schema instanceof z.ZodLiteral) {
948
- const value: unknown = schema.value;
949
- if (
950
- typeof value === 'string' ||
951
- typeof value === 'number' ||
952
- typeof value === 'boolean' ||
953
- typeof value === 'bigint' ||
954
- value === null
955
- ) {
956
- return z4.literal(value);
957
- }
958
- throw new Error('Unsupported Zod literal in MCP output schema');
959
- }
960
- if (schema instanceof z.ZodEnum) {
961
- const [first, ...rest] = schema.options;
962
- if (first === undefined) throw new Error('Empty Zod enum in MCP output schema');
963
- return z4.enum([first, ...rest]);
964
- }
965
- if (schema instanceof z.ZodArray) {
966
- let projected = z4.array(projectZod3Schema(schema.element));
967
- if (schema._def.minLength) projected = projected.min(schema._def.minLength.value);
968
- if (schema._def.maxLength) projected = projected.max(schema._def.maxLength.value);
969
- if (schema._def.exactLength) projected = projected.length(schema._def.exactLength.value);
970
- return projected;
971
- }
972
- if (schema instanceof z.ZodObject) {
973
- const sourceShape = schema.shape as z.ZodRawShape;
974
- const shape = Object.fromEntries(
975
- Object.entries(sourceShape).map(([key, value]) => [key, projectZod3Schema(value)]),
976
- );
977
- if (schema._def.unknownKeys === 'passthrough') return z4.looseObject(shape);
978
- return z4.object(shape);
979
- }
980
- if (schema instanceof z.ZodDiscriminatedUnion) {
981
- const options = schema.options as readonly z.ZodTypeAny[];
982
- return projectUnion(options.map((option) => projectZod3Schema(option)));
983
- }
984
- if (schema instanceof z.ZodUnion) {
985
- const options = schema.options as readonly z.ZodTypeAny[];
986
- return projectUnion(options.map((option) => projectZod3Schema(option)));
987
- }
988
- throw new Error(`Unsupported Zod type in MCP output schema: ${schema._def.typeName}`);
989
- }
990
-
991
- function projectUnion(options: z4.ZodType[]): z4.ZodType {
992
- const [first, second, ...rest] = options;
993
- if (!first || !second) throw new Error('MCP output unions require at least two alternatives');
994
- return z4.union([first, second, ...rest]);
995
- }
996
-
997
- function jsonSchemaWithoutDialect(schema: z4.ZodType): Record<string, unknown> {
998
- const { $schema: _dialect, ...jsonSchema } = z4.toJSONSchema(schema, { target: 'draft-7' });
999
- return jsonSchema;
1000
- }