@bendyline/docblocks 1.1.2 → 2.0.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 (270) hide show
  1. package/README.md +76 -11
  2. package/dist/chunk-2D7Y4IR3.js +1293 -0
  3. package/dist/chunk-2D7Y4IR3.js.map +1 -0
  4. package/dist/chunk-5MYAICRE.js +957 -0
  5. package/dist/chunk-5MYAICRE.js.map +1 -0
  6. package/dist/chunk-75UUF6C4.js +802 -0
  7. package/dist/chunk-75UUF6C4.js.map +1 -0
  8. package/dist/chunk-AEHCVWU5.js +25 -0
  9. package/dist/chunk-AEHCVWU5.js.map +1 -0
  10. package/dist/chunk-AYZ4HN5M.js +20 -0
  11. package/dist/chunk-AYZ4HN5M.js.map +1 -0
  12. package/dist/chunk-EGNDADXB.js +111 -0
  13. package/dist/chunk-EGNDADXB.js.map +1 -0
  14. package/dist/chunk-EZKJZUNJ.js +13 -0
  15. package/dist/chunk-EZKJZUNJ.js.map +1 -0
  16. package/dist/chunk-FNW556FN.js +75 -0
  17. package/dist/chunk-FNW556FN.js.map +1 -0
  18. package/dist/chunk-GCPBEMMH.js +563 -0
  19. package/dist/chunk-GCPBEMMH.js.map +1 -0
  20. package/dist/chunk-J32GU3F3.js +1664 -0
  21. package/dist/chunk-J32GU3F3.js.map +1 -0
  22. package/dist/chunk-PGR7LK6D.js +1062 -0
  23. package/dist/chunk-PGR7LK6D.js.map +1 -0
  24. package/dist/chunk-RQJRQF46.js +787 -0
  25. package/dist/chunk-RQJRQF46.js.map +1 -0
  26. package/dist/{chunk-ME76RUMR.js → chunk-RVQHY3XU.js} +15 -1
  27. package/dist/chunk-RVQHY3XU.js.map +1 -0
  28. package/dist/chunk-SI2LU2RP.js +224 -0
  29. package/dist/chunk-SI2LU2RP.js.map +1 -0
  30. package/dist/chunk-W5UUUII5.js +142 -0
  31. package/dist/chunk-W5UUUII5.js.map +1 -0
  32. package/dist/document/document-session.d.ts +127 -0
  33. package/dist/document/document-session.d.ts.map +1 -0
  34. package/dist/document/document-session.js +749 -0
  35. package/dist/document/document-session.js.map +1 -0
  36. package/dist/document/filesystem-target.d.ts +17 -0
  37. package/dist/document/filesystem-target.d.ts.map +1 -0
  38. package/dist/document/filesystem-target.js +70 -0
  39. package/dist/document/filesystem-target.js.map +1 -0
  40. package/dist/document/index.d.ts +6 -0
  41. package/dist/document/index.d.ts.map +1 -0
  42. package/dist/document/index.js +4 -0
  43. package/dist/document/index.js.map +1 -0
  44. package/dist/document/recovery-journal.d.ts +125 -0
  45. package/dist/document/recovery-journal.d.ts.map +1 -0
  46. package/dist/document/recovery-journal.js +385 -0
  47. package/dist/document/recovery-journal.js.map +1 -0
  48. package/dist/document/types.d.ts +89 -0
  49. package/dist/document/types.d.ts.map +1 -0
  50. package/dist/document/types.js +9 -0
  51. package/dist/document/types.js.map +1 -0
  52. package/dist/filesystem/commit-lock.d.ts +3 -0
  53. package/dist/filesystem/commit-lock.d.ts.map +1 -0
  54. package/dist/filesystem/commit-lock.js +20 -0
  55. package/dist/filesystem/commit-lock.js.map +1 -0
  56. package/dist/filesystem/dbk-workspace.d.ts +34 -0
  57. package/dist/filesystem/dbk-workspace.d.ts.map +1 -0
  58. package/dist/filesystem/dbk-workspace.js +85 -0
  59. package/dist/filesystem/dbk-workspace.js.map +1 -0
  60. package/dist/filesystem/electron-provider-v2.d.ts +36 -0
  61. package/dist/filesystem/electron-provider-v2.d.ts.map +1 -0
  62. package/dist/filesystem/electron-provider-v2.js +503 -0
  63. package/dist/filesystem/electron-provider-v2.js.map +1 -0
  64. package/dist/filesystem/electron-provider.d.ts +6 -3
  65. package/dist/filesystem/electron-provider.d.ts.map +1 -1
  66. package/dist/filesystem/electron-provider.js +18 -13
  67. package/dist/filesystem/electron-provider.js.map +1 -1
  68. package/dist/filesystem/electron.d.ts +4 -0
  69. package/dist/filesystem/electron.d.ts.map +1 -0
  70. package/dist/filesystem/electron.js +4 -0
  71. package/dist/filesystem/electron.js.map +1 -0
  72. package/dist/filesystem/filesystem-content-container.d.ts +1 -1
  73. package/dist/filesystem/filesystem-content-container.d.ts.map +1 -1
  74. package/dist/filesystem/filesystem-content-container.js +50 -13
  75. package/dist/filesystem/filesystem-content-container.js.map +1 -1
  76. package/dist/filesystem/fs-error.d.ts +46 -0
  77. package/dist/filesystem/fs-error.d.ts.map +1 -0
  78. package/dist/filesystem/fs-error.js +170 -0
  79. package/dist/filesystem/fs-error.js.map +1 -0
  80. package/dist/filesystem/index.d.ts +15 -1
  81. package/dist/filesystem/index.d.ts.map +1 -1
  82. package/dist/filesystem/index.js +13 -0
  83. package/dist/filesystem/index.js.map +1 -1
  84. package/dist/filesystem/indexeddb-content-container.d.ts +3 -1
  85. package/dist/filesystem/indexeddb-content-container.d.ts.map +1 -1
  86. package/dist/filesystem/indexeddb-content-container.js +18 -11
  87. package/dist/filesystem/indexeddb-content-container.js.map +1 -1
  88. package/dist/filesystem/indexeddb-provider-v2.d.ts +96 -0
  89. package/dist/filesystem/indexeddb-provider-v2.d.ts.map +1 -0
  90. package/dist/filesystem/indexeddb-provider-v2.js +1241 -0
  91. package/dist/filesystem/indexeddb-provider-v2.js.map +1 -0
  92. package/dist/filesystem/indexeddb-provider.d.ts +21 -14
  93. package/dist/filesystem/indexeddb-provider.d.ts.map +1 -1
  94. package/dist/filesystem/indexeddb-provider.js +111 -261
  95. package/dist/filesystem/indexeddb-provider.js.map +1 -1
  96. package/dist/filesystem/indexeddb-store.d.ts +34 -0
  97. package/dist/filesystem/indexeddb-store.d.ts.map +1 -0
  98. package/dist/filesystem/indexeddb-store.js +165 -0
  99. package/dist/filesystem/indexeddb-store.js.map +1 -0
  100. package/dist/filesystem/indexeddb.d.ts +5 -0
  101. package/dist/filesystem/indexeddb.d.ts.map +1 -0
  102. package/dist/filesystem/indexeddb.js +5 -0
  103. package/dist/filesystem/indexeddb.js.map +1 -0
  104. package/dist/filesystem/legacy-v2-adapter.d.ts +62 -0
  105. package/dist/filesystem/legacy-v2-adapter.d.ts.map +1 -0
  106. package/dist/filesystem/legacy-v2-adapter.js +499 -0
  107. package/dist/filesystem/legacy-v2-adapter.js.map +1 -0
  108. package/dist/filesystem/memory-provider-v2.d.ts +92 -0
  109. package/dist/filesystem/memory-provider-v2.d.ts.map +1 -0
  110. package/dist/filesystem/memory-provider-v2.js +615 -0
  111. package/dist/filesystem/memory-provider-v2.js.map +1 -0
  112. package/dist/filesystem/memory-provider.d.ts +54 -0
  113. package/dist/filesystem/memory-provider.d.ts.map +1 -0
  114. package/dist/filesystem/memory-provider.js +132 -0
  115. package/dist/filesystem/memory-provider.js.map +1 -0
  116. package/dist/filesystem/memory.d.ts +4 -0
  117. package/dist/filesystem/memory.d.ts.map +1 -0
  118. package/dist/filesystem/memory.js +4 -0
  119. package/dist/filesystem/memory.js.map +1 -0
  120. package/dist/filesystem/move-entry.d.ts +9 -0
  121. package/dist/filesystem/move-entry.d.ts.map +1 -0
  122. package/dist/filesystem/move-entry.js +103 -0
  123. package/dist/filesystem/move-entry.js.map +1 -0
  124. package/dist/filesystem/move-error.d.ts +53 -0
  125. package/dist/filesystem/move-error.d.ts.map +1 -0
  126. package/dist/filesystem/move-error.js +99 -0
  127. package/dist/filesystem/move-error.js.map +1 -0
  128. package/dist/filesystem/native-provider-v2.d.ts +75 -0
  129. package/dist/filesystem/native-provider-v2.d.ts.map +1 -0
  130. package/dist/filesystem/native-provider-v2.js +849 -0
  131. package/dist/filesystem/native-provider-v2.js.map +1 -0
  132. package/dist/filesystem/native-provider.d.ts +9 -1
  133. package/dist/filesystem/native-provider.d.ts.map +1 -1
  134. package/dist/filesystem/native-provider.js +172 -37
  135. package/dist/filesystem/native-provider.js.map +1 -1
  136. package/dist/filesystem/native.d.ts +4 -0
  137. package/dist/filesystem/native.d.ts.map +1 -0
  138. package/dist/filesystem/native.js +4 -0
  139. package/dist/filesystem/native.js.map +1 -0
  140. package/dist/filesystem/types.d.ts +37 -4
  141. package/dist/filesystem/types.d.ts.map +1 -1
  142. package/dist/filesystem/types.js +11 -3
  143. package/dist/filesystem/types.js.map +1 -1
  144. package/dist/filesystem/v2.d.ts +172 -0
  145. package/dist/filesystem/v2.d.ts.map +1 -0
  146. package/dist/filesystem/v2.js +16 -0
  147. package/dist/filesystem/v2.js.map +1 -0
  148. package/dist/filesystem/workspace-path.d.ts +21 -0
  149. package/dist/filesystem/workspace-path.d.ts.map +1 -0
  150. package/dist/filesystem/workspace-path.js +80 -0
  151. package/dist/filesystem/workspace-path.js.map +1 -0
  152. package/dist/host/filesystem-v2.d.ts +45 -0
  153. package/dist/host/filesystem-v2.d.ts.map +1 -0
  154. package/dist/host/filesystem-v2.js +13 -0
  155. package/dist/host/filesystem-v2.js.map +1 -0
  156. package/dist/host/git.d.ts +200 -0
  157. package/dist/host/git.d.ts.map +1 -0
  158. package/dist/host/git.js +15 -0
  159. package/dist/host/git.js.map +1 -0
  160. package/dist/host/index.d.ts +4 -1
  161. package/dist/host/index.d.ts.map +1 -1
  162. package/dist/host/index.js +2 -0
  163. package/dist/host/index.js.map +1 -1
  164. package/dist/host/types.d.ts +114 -31
  165. package/dist/host/types.d.ts.map +1 -1
  166. package/dist/host/wire-policy.d.ts +22 -0
  167. package/dist/host/wire-policy.d.ts.map +1 -0
  168. package/dist/host/wire-policy.js +92 -0
  169. package/dist/host/wire-policy.js.map +1 -0
  170. package/dist/index.d.ts +2 -1
  171. package/dist/index.d.ts.map +1 -1
  172. package/dist/index.js +2 -1
  173. package/dist/index.js.map +1 -1
  174. package/dist/mcp/index.d.ts +4 -0
  175. package/dist/mcp/index.d.ts.map +1 -0
  176. package/dist/mcp/index.js +4 -0
  177. package/dist/mcp/index.js.map +1 -0
  178. package/dist/mcp/types.d.ts +466 -0
  179. package/dist/mcp/types.d.ts.map +1 -0
  180. package/dist/mcp/types.js +25 -0
  181. package/dist/mcp/types.js.map +1 -0
  182. package/dist/mcp/wire.d.ts +29 -0
  183. package/dist/mcp/wire.d.ts.map +1 -0
  184. package/dist/mcp/wire.js +1046 -0
  185. package/dist/mcp/wire.js.map +1 -0
  186. package/dist/mcp/zod.d.ts +5763 -0
  187. package/dist/mcp/zod.d.ts.map +1 -0
  188. package/dist/mcp/zod.js +908 -0
  189. package/dist/mcp/zod.js.map +1 -0
  190. package/dist/types-CX893hgH.d.ts +468 -0
  191. package/dist/types-CsX6EN2t.d.ts +301 -0
  192. package/dist/types-eOlt9J7n.d.ts +478 -0
  193. package/dist/vscode/index.d.ts +3 -0
  194. package/dist/vscode/index.d.ts.map +1 -0
  195. package/dist/vscode/index.js +3 -0
  196. package/dist/vscode/index.js.map +1 -0
  197. package/dist/vscode/messages.d.ts +204 -0
  198. package/dist/vscode/messages.d.ts.map +1 -0
  199. package/dist/vscode/messages.js +494 -0
  200. package/dist/vscode/messages.js.map +1 -0
  201. package/dist/workspace/index.d.ts +3 -2
  202. package/dist/workspace/index.d.ts.map +1 -1
  203. package/dist/workspace/index.js +2 -1
  204. package/dist/workspace/index.js.map +1 -1
  205. package/dist/workspace/reconcile-electron.d.ts +19 -0
  206. package/dist/workspace/reconcile-electron.d.ts.map +1 -0
  207. package/dist/workspace/reconcile-electron.js +42 -0
  208. package/dist/workspace/reconcile-electron.js.map +1 -0
  209. package/dist/workspace/types.d.ts +41 -1
  210. package/dist/workspace/types.d.ts.map +1 -1
  211. package/dist/workspace/types.js +0 -4
  212. package/dist/workspace/types.js.map +1 -1
  213. package/dist/workspace/workspace-manager.d.ts +17 -5
  214. package/dist/workspace/workspace-manager.d.ts.map +1 -1
  215. package/dist/workspace/workspace-manager.js +55 -11
  216. package/dist/workspace/workspace-manager.js.map +1 -1
  217. package/dist/workspace-path-CWVrcuPL.d.ts +21 -0
  218. package/package.json +43 -2
  219. package/src/document/document-session.ts +834 -0
  220. package/src/document/filesystem-target.ts +109 -0
  221. package/src/document/index.ts +41 -0
  222. package/src/document/recovery-journal.ts +536 -0
  223. package/src/document/types.ts +116 -0
  224. package/src/filesystem/commit-lock.ts +29 -0
  225. package/src/filesystem/dbk-workspace.ts +135 -0
  226. package/src/filesystem/electron-provider-v2.ts +630 -0
  227. package/src/filesystem/electron-provider.ts +25 -14
  228. package/src/filesystem/electron.ts +3 -0
  229. package/src/filesystem/filesystem-content-container.ts +53 -15
  230. package/src/filesystem/fs-error.ts +234 -0
  231. package/src/filesystem/index.ts +119 -0
  232. package/src/filesystem/indexeddb-content-container.ts +20 -12
  233. package/src/filesystem/indexeddb-provider-v2.ts +1740 -0
  234. package/src/filesystem/indexeddb-provider.ts +126 -300
  235. package/src/filesystem/indexeddb-store.ts +207 -0
  236. package/src/filesystem/indexeddb.ts +12 -0
  237. package/src/filesystem/legacy-v2-adapter.ts +779 -0
  238. package/src/filesystem/memory-provider-v2.ts +896 -0
  239. package/src/filesystem/memory-provider.ts +180 -0
  240. package/src/filesystem/memory.ts +15 -0
  241. package/src/filesystem/move-entry.ts +142 -0
  242. package/src/filesystem/move-error.ts +159 -0
  243. package/src/filesystem/native-provider-v2.ts +1165 -0
  244. package/src/filesystem/native-provider.ts +194 -41
  245. package/src/filesystem/native.ts +16 -0
  246. package/src/filesystem/types.ts +49 -4
  247. package/src/filesystem/v2.ts +231 -0
  248. package/src/filesystem/workspace-path.ts +92 -0
  249. package/src/host/filesystem-v2.ts +104 -0
  250. package/src/host/git.ts +246 -0
  251. package/src/host/index.ts +46 -0
  252. package/src/host/types.ts +155 -34
  253. package/src/host/wire-policy.ts +103 -0
  254. package/src/index.ts +2 -1
  255. package/src/mcp/index.ts +3 -0
  256. package/src/mcp/types.ts +594 -0
  257. package/src/mcp/wire.ts +1280 -0
  258. package/src/mcp/zod.ts +1000 -0
  259. package/src/vscode/index.ts +2 -0
  260. package/src/vscode/messages.ts +704 -0
  261. package/src/workspace/index.ts +8 -1
  262. package/src/workspace/reconcile-electron.ts +65 -0
  263. package/src/workspace/types.ts +39 -1
  264. package/src/workspace/workspace-manager.ts +71 -10
  265. package/dist/chunk-GUNM43XZ.js +0 -63
  266. package/dist/chunk-GUNM43XZ.js.map +0 -1
  267. package/dist/chunk-IM7LCQJ6.js +0 -850
  268. package/dist/chunk-IM7LCQJ6.js.map +0 -1
  269. package/dist/chunk-ME76RUMR.js.map +0 -1
  270. package/dist/index-pgBHBQ9G.d.ts +0 -213
@@ -0,0 +1,1046 @@
1
+ import { tryParseWorkspacePath } from '../filesystem/workspace-path.js';
2
+ import { DOCBLOCKS_MCP_WIRE_VERSION, } from './types.js';
3
+ /** Quantitative limits for untrusted MCP payloads. */
4
+ export const MCP_WIRE_LIMITS = Object.freeze({
5
+ identifierCharacters: 256,
6
+ formatCharacters: 64,
7
+ mimeTypeCharacters: 256,
8
+ labelCharacters: 1024,
9
+ pathCharacters: 4096,
10
+ uriCharacters: 8192,
11
+ messageCharacters: 4000,
12
+ excerptCharacters: 4096,
13
+ documentCharacters: 20 * 1024 * 1024,
14
+ artifactBytes: 500 * 1024 * 1024,
15
+ bundleAssets: 256,
16
+ arrayEntries: 10000,
17
+ previewItems: 1000,
18
+ imageDimension: 32768,
19
+ });
20
+ const IDENTIFIER_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._:-]*$/u;
21
+ const ENGINE_NAME_PATTERN = /^(?:[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;
22
+ const FORMAT_PATTERN = /^[a-z0-9][a-z0-9.+_-]*$/u;
23
+ const MIME_TYPE_PATTERN = /^[a-z0-9!#$&^_.+-]+\/[a-z0-9!#$&^_.+-]+$/iu;
24
+ const SHA256_PATTERN = /^[a-f0-9]{64}$/u;
25
+ const ISO_TIMESTAMP_PATTERN = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/u;
26
+ export function parseArtifactRef(value) {
27
+ if (!isRecord(value) ||
28
+ !hasExactKeys(value, [
29
+ 'id',
30
+ 'uri',
31
+ 'format',
32
+ 'mimeType',
33
+ 'size',
34
+ 'sha256',
35
+ 'sourceFormat',
36
+ 'sourceSha256',
37
+ 'suggestedFilename',
38
+ 'appliedOptions',
39
+ 'engineVersions',
40
+ 'createdAt',
41
+ 'expiresAt',
42
+ ])) {
43
+ return null;
44
+ }
45
+ const { id, uri, format, mimeType, size, sha256, sourceFormat, sourceSha256, suggestedFilename, createdAt, expiresAt, } = value;
46
+ const appliedOptions = parseArray(value.appliedOptions, parseAppliedOption);
47
+ const engineVersions = parseArray(value.engineVersions, parseEngineVersion);
48
+ if (!isIdentifier(id) ||
49
+ !isArtifactUri(uri, id) ||
50
+ !isFormat(format) ||
51
+ !isMimeType(mimeType) ||
52
+ !isBoundedInteger(size, 0, MCP_WIRE_LIMITS.artifactBytes) ||
53
+ !isSha256(sha256) ||
54
+ !(sourceFormat === null || isFormat(sourceFormat)) ||
55
+ !(sourceSha256 === null || isSha256(sourceSha256)) ||
56
+ !isSafeFilename(suggestedFilename) ||
57
+ appliedOptions === null ||
58
+ engineVersions === null ||
59
+ hasDuplicateNames(appliedOptions) ||
60
+ hasDuplicateNames(engineVersions) ||
61
+ !isIsoTimestamp(createdAt) ||
62
+ !(expiresAt === null || isIsoTimestamp(expiresAt)) ||
63
+ (expiresAt !== null && Date.parse(expiresAt) <= Date.parse(createdAt))) {
64
+ return null;
65
+ }
66
+ return {
67
+ id,
68
+ uri,
69
+ format,
70
+ mimeType,
71
+ size,
72
+ sha256,
73
+ sourceFormat,
74
+ sourceSha256,
75
+ suggestedFilename,
76
+ appliedOptions,
77
+ engineVersions,
78
+ createdAt,
79
+ expiresAt,
80
+ };
81
+ }
82
+ export function parseDocumentSource(value) {
83
+ if (!isRecord(value) || typeof value.kind !== 'string')
84
+ return null;
85
+ switch (value.kind) {
86
+ case 'markdown': {
87
+ if (!hasExactKeys(value, ['kind', 'markdown', 'name']))
88
+ return null;
89
+ const { markdown, name } = value;
90
+ if (!isBoundedString(markdown, MCP_WIRE_LIMITS.documentCharacters) ||
91
+ !isNullableBoundedString(name, MCP_WIRE_LIMITS.labelCharacters)) {
92
+ return null;
93
+ }
94
+ return { kind: 'markdown', markdown, name };
95
+ }
96
+ case 'file': {
97
+ if (!hasExactKeys(value, ['kind', 'rootId', 'path', 'format']))
98
+ return null;
99
+ const { rootId, path, format } = value;
100
+ const parsedPath = parseNonRootWorkspacePath(path);
101
+ if (!isIdentifier(rootId) || parsedPath === null || !(format === null || isFormat(format))) {
102
+ return null;
103
+ }
104
+ return { kind: 'file', rootId, path: parsedPath, format };
105
+ }
106
+ case 'artifact': {
107
+ if (!hasExactKeys(value, ['kind', 'uri']) || !isArtifactUri(value.uri))
108
+ return null;
109
+ return { kind: 'artifact', uri: value.uri };
110
+ }
111
+ case 'bundle': {
112
+ if (!hasExactKeys(value, ['kind', 'markdown', 'assets', 'name']))
113
+ return null;
114
+ const { markdown, name } = value;
115
+ if (!isBoundedString(markdown, MCP_WIRE_LIMITS.documentCharacters) ||
116
+ !isNullableBoundedString(name, MCP_WIRE_LIMITS.labelCharacters)) {
117
+ return null;
118
+ }
119
+ const assets = parseArray(value.assets, parseBundleAssetRef, MCP_WIRE_LIMITS.bundleAssets);
120
+ if (assets === null || hasDuplicatePaths(assets))
121
+ return null;
122
+ return { kind: 'bundle', markdown, assets, name };
123
+ }
124
+ default:
125
+ return null;
126
+ }
127
+ }
128
+ export function parseMcpDiagnostic(value) {
129
+ if (!isRecord(value) ||
130
+ !hasExactKeys(value, [
131
+ 'code',
132
+ 'severity',
133
+ 'stage',
134
+ 'format',
135
+ 'count',
136
+ 'message',
137
+ 'remediation',
138
+ 'retryable',
139
+ 'location',
140
+ ])) {
141
+ return null;
142
+ }
143
+ const { code, severity, stage, format, count, message, remediation, retryable } = value;
144
+ const location = parseNullable(value.location, parseDiagnosticLocation);
145
+ if (!isIdentifier(code) ||
146
+ !isDiagnosticSeverity(severity) ||
147
+ !isDiagnosticStage(stage) ||
148
+ !(format === null || isFormat(format)) ||
149
+ !isBoundedInteger(count, 1, Number.MAX_SAFE_INTEGER) ||
150
+ !isBoundedString(message, MCP_WIRE_LIMITS.messageCharacters, 1) ||
151
+ !isNullableBoundedString(remediation, MCP_WIRE_LIMITS.messageCharacters) ||
152
+ typeof retryable !== 'boolean' ||
153
+ location === undefined) {
154
+ return null;
155
+ }
156
+ return {
157
+ code,
158
+ severity,
159
+ stage,
160
+ format,
161
+ count,
162
+ message,
163
+ remediation,
164
+ retryable,
165
+ location,
166
+ };
167
+ }
168
+ export function parseMcpErrorResult(value) {
169
+ if (!isRecord(value) ||
170
+ !hasExactKeys(value, ['version', 'kind', 'result', 'error']) ||
171
+ value.version !== DOCBLOCKS_MCP_WIRE_VERSION ||
172
+ value.kind !== 'error' ||
173
+ value.result !== null ||
174
+ !isRecord(value.error) ||
175
+ !hasExactKeys(value.error, [
176
+ 'code',
177
+ 'message',
178
+ 'stage',
179
+ 'format',
180
+ 'hint',
181
+ 'retryable',
182
+ 'operationLoad',
183
+ ])) {
184
+ return null;
185
+ }
186
+ const { code, message, stage, format, hint, retryable, operationLoad } = value.error;
187
+ if (!isIdentifier(code) ||
188
+ !isBoundedString(message, MCP_WIRE_LIMITS.messageCharacters, 1) ||
189
+ !(stage === null || isDiagnosticStage(stage)) ||
190
+ !(format === null || isFormat(format)) ||
191
+ !isNullableBoundedString(hint, MCP_WIRE_LIMITS.messageCharacters) ||
192
+ typeof retryable !== 'boolean' ||
193
+ !(operationLoad === null ||
194
+ (isRecord(operationLoad) &&
195
+ hasExactKeys(operationLoad, ['active', 'capacity']) &&
196
+ isBoundedInteger(operationLoad.active, 0, 32) &&
197
+ isBoundedInteger(operationLoad.capacity, 1, 32) &&
198
+ operationLoad.active <= operationLoad.capacity))) {
199
+ return null;
200
+ }
201
+ return {
202
+ version: DOCBLOCKS_MCP_WIRE_VERSION,
203
+ kind: 'error',
204
+ result: null,
205
+ error: {
206
+ code,
207
+ message,
208
+ stage,
209
+ format,
210
+ hint,
211
+ retryable,
212
+ operationLoad: operationLoad === null
213
+ ? null
214
+ : {
215
+ active: operationLoad.active,
216
+ capacity: operationLoad.capacity,
217
+ },
218
+ },
219
+ };
220
+ }
221
+ export function parseConversionResult(value) {
222
+ if (!isRecord(value) ||
223
+ !hasExactKeys(value, [
224
+ 'version',
225
+ 'kind',
226
+ 'sourceFormat',
227
+ 'targetFormat',
228
+ 'artifact',
229
+ 'fidelity',
230
+ 'appliedThemeId',
231
+ 'appliedTransformId',
232
+ 'sourceAssets',
233
+ 'sourceAssetCount',
234
+ 'diagnostics',
235
+ ]) ||
236
+ value.version !== DOCBLOCKS_MCP_WIRE_VERSION ||
237
+ value.kind !== 'conversion' ||
238
+ !isFormat(value.sourceFormat) ||
239
+ !isFormat(value.targetFormat) ||
240
+ !isConversionFidelity(value.fidelity) ||
241
+ !isNullableIdentifier(value.appliedThemeId) ||
242
+ !isNullableIdentifier(value.appliedTransformId) ||
243
+ !isBoundedInteger(value.sourceAssetCount, 0, MCP_WIRE_LIMITS.arrayEntries)) {
244
+ return null;
245
+ }
246
+ const artifact = parseArtifactRef(value.artifact);
247
+ const sourceAssets = parseArray(value.sourceAssets, parseAssetSummary);
248
+ const diagnostics = parseArray(value.diagnostics, parseMcpDiagnostic);
249
+ if (artifact === null ||
250
+ sourceAssets === null ||
251
+ diagnostics === null ||
252
+ sourceAssets.length !== value.sourceAssetCount ||
253
+ hasDuplicatePaths(sourceAssets) ||
254
+ artifact.format !== value.targetFormat ||
255
+ (artifact.sourceFormat !== null && artifact.sourceFormat !== value.sourceFormat)) {
256
+ return null;
257
+ }
258
+ return {
259
+ version: DOCBLOCKS_MCP_WIRE_VERSION,
260
+ kind: 'conversion',
261
+ sourceFormat: value.sourceFormat,
262
+ targetFormat: value.targetFormat,
263
+ artifact,
264
+ fidelity: value.fidelity,
265
+ appliedThemeId: value.appliedThemeId,
266
+ appliedTransformId: value.appliedTransformId,
267
+ sourceAssets,
268
+ sourceAssetCount: value.sourceAssetCount,
269
+ diagnostics,
270
+ };
271
+ }
272
+ export function parseInspectionResult(value) {
273
+ if (!isRecord(value) ||
274
+ !hasExactKeys(value, [
275
+ 'version',
276
+ 'kind',
277
+ 'sourceFormat',
278
+ 'metadata',
279
+ 'statistics',
280
+ 'outline',
281
+ 'blocks',
282
+ 'blockOffset',
283
+ 'nextCursor',
284
+ 'tables',
285
+ 'links',
286
+ 'items',
287
+ 'assets',
288
+ 'theme',
289
+ 'truncated',
290
+ 'detailsTruncated',
291
+ 'diagnostics',
292
+ ]) ||
293
+ value.version !== DOCBLOCKS_MCP_WIRE_VERSION ||
294
+ value.kind !== 'inspection' ||
295
+ !isFormat(value.sourceFormat) ||
296
+ !isBoundedInteger(value.blockOffset, 0, MCP_WIRE_LIMITS.arrayEntries) ||
297
+ !isNullableBoundedString(value.nextCursor, MCP_WIRE_LIMITS.identifierCharacters) ||
298
+ typeof value.truncated !== 'boolean' ||
299
+ typeof value.detailsTruncated !== 'boolean') {
300
+ return null;
301
+ }
302
+ const metadata = parseDocumentMetadata(value.metadata);
303
+ const statistics = parseDocumentStatistics(value.statistics);
304
+ const outline = parseArray(value.outline, parseOutlineEntry);
305
+ const blocks = parseArray(value.blocks, parseBlockSummary);
306
+ const tables = parseArray(value.tables, parseTableSummary);
307
+ const links = parseArray(value.links, parseLinkSummary);
308
+ const items = parseArray(value.items, parseDocumentItemSummary);
309
+ const assets = parseArray(value.assets, parseAssetSummary);
310
+ const theme = parseNullable(value.theme, parseThemeSummary);
311
+ const diagnostics = parseArray(value.diagnostics, parseMcpDiagnostic);
312
+ if (metadata === null ||
313
+ statistics === null ||
314
+ outline === null ||
315
+ blocks === null ||
316
+ tables === null ||
317
+ links === null ||
318
+ items === null ||
319
+ assets === null ||
320
+ theme === undefined ||
321
+ diagnostics === null ||
322
+ statistics.blockCount < value.blockOffset + blocks.length ||
323
+ statistics.assetCount < assets.length ||
324
+ (!value.truncated && statistics.blockCount !== value.blockOffset + blocks.length) ||
325
+ value.truncated !== (value.nextCursor !== null) ||
326
+ statistics.tableCount < tables.length ||
327
+ statistics.linkCount < links.length ||
328
+ hasDuplicateIds(outline) ||
329
+ hasDuplicateIds(blocks) ||
330
+ hasDuplicateIndexes(tables) ||
331
+ hasDuplicateIndexes(links) ||
332
+ hasDuplicateItemIndexes(items) ||
333
+ hasDuplicatePaths(assets) ||
334
+ outline.some((entry) => entry.blockIndex >= statistics.blockCount) ||
335
+ blocks.some((block) => block.sourceRange !== null && block.sourceRange.end > statistics.characterCount)) {
336
+ return null;
337
+ }
338
+ return {
339
+ version: DOCBLOCKS_MCP_WIRE_VERSION,
340
+ kind: 'inspection',
341
+ sourceFormat: value.sourceFormat,
342
+ metadata,
343
+ statistics,
344
+ outline,
345
+ blocks,
346
+ blockOffset: value.blockOffset,
347
+ nextCursor: value.nextCursor,
348
+ tables,
349
+ links,
350
+ items,
351
+ assets,
352
+ theme,
353
+ truncated: value.truncated,
354
+ detailsTruncated: value.detailsTruncated,
355
+ diagnostics,
356
+ };
357
+ }
358
+ export function parseValidationResult(value) {
359
+ if (!isRecord(value) ||
360
+ !hasExactKeys(value, [
361
+ 'version',
362
+ 'kind',
363
+ 'sourceFormat',
364
+ 'targetFormat',
365
+ 'valid',
366
+ 'summary',
367
+ 'diagnostics',
368
+ ]) ||
369
+ value.version !== DOCBLOCKS_MCP_WIRE_VERSION ||
370
+ value.kind !== 'validation' ||
371
+ !isFormat(value.sourceFormat) ||
372
+ !(value.targetFormat === null || isFormat(value.targetFormat)) ||
373
+ typeof value.valid !== 'boolean') {
374
+ return null;
375
+ }
376
+ const summary = parseValidationSummary(value.summary);
377
+ const diagnostics = parseArray(value.diagnostics, parseMcpDiagnostic);
378
+ if (summary === null || diagnostics === null)
379
+ return null;
380
+ const actualSummary = summarizeDiagnostics(diagnostics);
381
+ if (summary.errorCount !== actualSummary.errorCount ||
382
+ summary.warningCount !== actualSummary.warningCount ||
383
+ summary.infoCount !== actualSummary.infoCount ||
384
+ value.valid !== (summary.errorCount === 0)) {
385
+ return null;
386
+ }
387
+ return {
388
+ version: DOCBLOCKS_MCP_WIRE_VERSION,
389
+ kind: 'validation',
390
+ sourceFormat: value.sourceFormat,
391
+ targetFormat: value.targetFormat,
392
+ valid: value.valid,
393
+ summary,
394
+ diagnostics,
395
+ };
396
+ }
397
+ export function parsePreviewResult(value) {
398
+ if (!isRecord(value) ||
399
+ !hasExactKeys(value, [
400
+ 'version',
401
+ 'kind',
402
+ 'sourceFormat',
403
+ 'previewBasis',
404
+ 'totalItems',
405
+ 'items',
406
+ 'truncated',
407
+ 'diagnostics',
408
+ ]) ||
409
+ value.version !== DOCBLOCKS_MCP_WIRE_VERSION ||
410
+ value.kind !== 'preview' ||
411
+ !isFormat(value.sourceFormat) ||
412
+ !(value.previewBasis === 'source-render' ||
413
+ value.previewBasis === 'reconstructed-import' ||
414
+ value.previewBasis === 'native-extracted') ||
415
+ !isBoundedInteger(value.totalItems, 0, Number.MAX_SAFE_INTEGER) ||
416
+ typeof value.truncated !== 'boolean') {
417
+ return null;
418
+ }
419
+ const items = parseArray(value.items, parsePreviewItem, MCP_WIRE_LIMITS.previewItems);
420
+ const diagnostics = parseArray(value.diagnostics, parseMcpDiagnostic);
421
+ if (items === null ||
422
+ diagnostics === null ||
423
+ value.totalItems < items.length ||
424
+ (!value.truncated && value.totalItems !== items.length) ||
425
+ hasDuplicatePreviewIndexes(items) ||
426
+ items.some((item) => item.artifact.sourceFormat !== null && item.artifact.sourceFormat !== value.sourceFormat)) {
427
+ return null;
428
+ }
429
+ return {
430
+ version: DOCBLOCKS_MCP_WIRE_VERSION,
431
+ kind: 'preview',
432
+ sourceFormat: value.sourceFormat,
433
+ previewBasis: value.previewBasis,
434
+ totalItems: value.totalItems,
435
+ items,
436
+ truncated: value.truncated,
437
+ diagnostics,
438
+ };
439
+ }
440
+ export function parseComparisonResult(value) {
441
+ if (!isRecord(value) ||
442
+ !hasExactKeys(value, [
443
+ 'version',
444
+ 'kind',
445
+ 'leftFormat',
446
+ 'rightFormat',
447
+ 'equivalent',
448
+ 'score',
449
+ 'changes',
450
+ 'metrics',
451
+ 'diagnostics',
452
+ ]) ||
453
+ value.version !== DOCBLOCKS_MCP_WIRE_VERSION ||
454
+ value.kind !== 'comparison' ||
455
+ !isFormat(value.leftFormat) ||
456
+ !isFormat(value.rightFormat) ||
457
+ typeof value.equivalent !== 'boolean' ||
458
+ !isBoundedNumber(value.score, 0, 1)) {
459
+ return null;
460
+ }
461
+ const changes = parseArray(value.changes, parseComparisonChange);
462
+ const metrics = parseArray(value.metrics, parseComparisonMetric);
463
+ const diagnostics = parseArray(value.diagnostics, parseMcpDiagnostic);
464
+ if (changes === null ||
465
+ metrics === null ||
466
+ diagnostics === null ||
467
+ hasDuplicateNames(metrics) ||
468
+ (value.equivalent &&
469
+ (value.score !== 1 || changes.some((change) => change.status !== 'retained')))) {
470
+ return null;
471
+ }
472
+ return {
473
+ version: DOCBLOCKS_MCP_WIRE_VERSION,
474
+ kind: 'comparison',
475
+ leftFormat: value.leftFormat,
476
+ rightFormat: value.rightFormat,
477
+ equivalent: value.equivalent,
478
+ score: value.score,
479
+ changes,
480
+ metrics,
481
+ diagnostics,
482
+ };
483
+ }
484
+ export function parseMaterializationOptions(value) {
485
+ if (!isRecord(value) ||
486
+ !hasExactKeys(value, ['rootId', 'path', 'ifExists', 'expectedSha256']) ||
487
+ !isIdentifier(value.rootId)) {
488
+ return null;
489
+ }
490
+ const path = parseNonRootWorkspacePath(value.path);
491
+ if (path === null)
492
+ return null;
493
+ if (value.ifExists === 'error' && value.expectedSha256 === null) {
494
+ return { rootId: value.rootId, path, ifExists: 'error', expectedSha256: null };
495
+ }
496
+ if (value.ifExists === 'replace' && isSha256(value.expectedSha256)) {
497
+ return {
498
+ rootId: value.rootId,
499
+ path,
500
+ ifExists: 'replace',
501
+ expectedSha256: value.expectedSha256,
502
+ };
503
+ }
504
+ return null;
505
+ }
506
+ function parseBundleAssetRef(value) {
507
+ if (!isRecord(value) ||
508
+ !hasExactKeys(value, ['path', 'source', 'mimeType', 'altText', 'credit', 'license'])) {
509
+ return null;
510
+ }
511
+ const path = parseNonRootWorkspacePath(value.path);
512
+ const source = parseBundleAssetContentSource(value.source);
513
+ if (path === null ||
514
+ source === null ||
515
+ !(value.mimeType === null || isMimeType(value.mimeType)) ||
516
+ !isNullableBoundedString(value.altText, MCP_WIRE_LIMITS.labelCharacters) ||
517
+ !isNullableBoundedString(value.credit, MCP_WIRE_LIMITS.labelCharacters) ||
518
+ !isNullableBoundedString(value.license, MCP_WIRE_LIMITS.labelCharacters)) {
519
+ return null;
520
+ }
521
+ return {
522
+ path,
523
+ source,
524
+ mimeType: value.mimeType,
525
+ altText: value.altText,
526
+ credit: value.credit,
527
+ license: value.license,
528
+ };
529
+ }
530
+ function parseBundleAssetContentSource(value) {
531
+ if (!isRecord(value) || typeof value.kind !== 'string')
532
+ return null;
533
+ if (value.kind === 'file') {
534
+ if (!hasExactKeys(value, ['kind', 'rootId', 'path']) || !isIdentifier(value.rootId)) {
535
+ return null;
536
+ }
537
+ const path = parseNonRootWorkspacePath(value.path);
538
+ return path === null ? null : { kind: 'file', rootId: value.rootId, path };
539
+ }
540
+ if (value.kind === 'artifact') {
541
+ return hasExactKeys(value, ['kind', 'uri']) && isArtifactUri(value.uri)
542
+ ? { kind: 'artifact', uri: value.uri }
543
+ : null;
544
+ }
545
+ return null;
546
+ }
547
+ function parseDiagnosticLocation(value) {
548
+ if (!isRecord(value) || typeof value.kind !== 'string')
549
+ return null;
550
+ switch (value.kind) {
551
+ case 'source':
552
+ return hasExactKeys(value, ['kind', 'line', 'column']) &&
553
+ isBoundedInteger(value.line, 1, Number.MAX_SAFE_INTEGER) &&
554
+ isBoundedInteger(value.column, 1, Number.MAX_SAFE_INTEGER)
555
+ ? { kind: 'source', line: value.line, column: value.column }
556
+ : null;
557
+ case 'block':
558
+ return hasExactKeys(value, ['kind', 'blockId', 'nodeType']) &&
559
+ isIdentifier(value.blockId) &&
560
+ isIdentifier(value.nodeType)
561
+ ? { kind: 'block', blockId: value.blockId, nodeType: value.nodeType }
562
+ : null;
563
+ case 'asset': {
564
+ if (!hasExactKeys(value, ['kind', 'path']))
565
+ return null;
566
+ const path = parseNonRootWorkspacePath(value.path);
567
+ return path === null ? null : { kind: 'asset', path };
568
+ }
569
+ case 'item':
570
+ return hasExactKeys(value, ['kind', 'itemKind', 'index']) &&
571
+ isPreviewItemKind(value.itemKind) &&
572
+ isBoundedInteger(value.index, 0, Number.MAX_SAFE_INTEGER)
573
+ ? { kind: 'item', itemKind: value.itemKind, index: value.index }
574
+ : null;
575
+ default:
576
+ return null;
577
+ }
578
+ }
579
+ function parseAppliedOption(value) {
580
+ if (!isRecord(value) ||
581
+ !hasExactKeys(value, ['name', 'value']) ||
582
+ !isIdentifier(value.name) ||
583
+ !isAppliedOptionValue(value.value)) {
584
+ return null;
585
+ }
586
+ return { name: value.name, value: value.value };
587
+ }
588
+ function parseEngineVersion(value) {
589
+ if (!isRecord(value) ||
590
+ !hasExactKeys(value, ['name', 'version']) ||
591
+ !isEngineName(value.name) ||
592
+ !isBoundedString(value.version, MCP_WIRE_LIMITS.identifierCharacters, 1)) {
593
+ return null;
594
+ }
595
+ return { name: value.name, version: value.version };
596
+ }
597
+ function parseDocumentMetadata(value) {
598
+ if (!isRecord(value) ||
599
+ !hasExactKeys(value, ['title', 'author', 'description']) ||
600
+ !isNullableBoundedString(value.title, MCP_WIRE_LIMITS.labelCharacters) ||
601
+ !isNullableBoundedString(value.author, MCP_WIRE_LIMITS.labelCharacters) ||
602
+ !isNullableBoundedString(value.description, MCP_WIRE_LIMITS.messageCharacters)) {
603
+ return null;
604
+ }
605
+ return { title: value.title, author: value.author, description: value.description };
606
+ }
607
+ function parseDocumentStatistics(value) {
608
+ if (!isRecord(value) ||
609
+ !hasExactKeys(value, [
610
+ 'blockCount',
611
+ 'wordCount',
612
+ 'characterCount',
613
+ 'tableCount',
614
+ 'linkCount',
615
+ 'assetCount',
616
+ 'pageCount',
617
+ 'slideCount',
618
+ 'sheetCount',
619
+ ]) ||
620
+ !isNonNegativeInteger(value.blockCount) ||
621
+ !isNonNegativeInteger(value.wordCount) ||
622
+ !isNonNegativeInteger(value.characterCount) ||
623
+ !isNonNegativeInteger(value.tableCount) ||
624
+ !isNonNegativeInteger(value.linkCount) ||
625
+ !isNonNegativeInteger(value.assetCount) ||
626
+ !isNullableNonNegativeInteger(value.pageCount) ||
627
+ !isNullableNonNegativeInteger(value.slideCount) ||
628
+ !isNullableNonNegativeInteger(value.sheetCount)) {
629
+ return null;
630
+ }
631
+ return {
632
+ blockCount: value.blockCount,
633
+ wordCount: value.wordCount,
634
+ characterCount: value.characterCount,
635
+ tableCount: value.tableCount,
636
+ linkCount: value.linkCount,
637
+ assetCount: value.assetCount,
638
+ pageCount: value.pageCount,
639
+ slideCount: value.slideCount,
640
+ sheetCount: value.sheetCount,
641
+ };
642
+ }
643
+ function parseOutlineEntry(value) {
644
+ if (!isRecord(value) ||
645
+ !hasExactKeys(value, ['id', 'title', 'level', 'blockIndex']) ||
646
+ !isIdentifier(value.id) ||
647
+ !isBoundedString(value.title, MCP_WIRE_LIMITS.labelCharacters, 1) ||
648
+ !isBoundedInteger(value.level, 1, 6) ||
649
+ !isNonNegativeInteger(value.blockIndex)) {
650
+ return null;
651
+ }
652
+ return { id: value.id, title: value.title, level: value.level, blockIndex: value.blockIndex };
653
+ }
654
+ function parseBlockSummary(value) {
655
+ if (!isRecord(value) ||
656
+ !hasExactKeys(value, ['id', 'type', 'text', 'wordCount', 'templateId', 'sourceRange']) ||
657
+ !isIdentifier(value.id) ||
658
+ !isIdentifier(value.type) ||
659
+ !isBoundedString(value.text, MCP_WIRE_LIMITS.excerptCharacters) ||
660
+ !isNonNegativeInteger(value.wordCount) ||
661
+ !isNullableIdentifier(value.templateId)) {
662
+ return null;
663
+ }
664
+ const sourceRange = parseNullable(value.sourceRange, parseSourceRange);
665
+ if (sourceRange === undefined)
666
+ return null;
667
+ return {
668
+ id: value.id,
669
+ type: value.type,
670
+ text: value.text,
671
+ wordCount: value.wordCount,
672
+ templateId: value.templateId,
673
+ sourceRange,
674
+ };
675
+ }
676
+ function parseSourceRange(value) {
677
+ if (!isRecord(value) ||
678
+ !hasExactKeys(value, ['start', 'end']) ||
679
+ !isNonNegativeInteger(value.start) ||
680
+ !isNonNegativeInteger(value.end) ||
681
+ value.end < value.start) {
682
+ return null;
683
+ }
684
+ return { start: value.start, end: value.end };
685
+ }
686
+ function parseTableSummary(value) {
687
+ if (!isRecord(value) ||
688
+ !hasExactKeys(value, ['index', 'rowCount', 'columnCount', 'headers']) ||
689
+ !isNonNegativeInteger(value.index) ||
690
+ !isNonNegativeInteger(value.rowCount) ||
691
+ !isNonNegativeInteger(value.columnCount)) {
692
+ return null;
693
+ }
694
+ const headers = parseArray(value.headers, (entry) => isBoundedString(entry, MCP_WIRE_LIMITS.labelCharacters) ? entry : null);
695
+ if (headers === null || headers.length > value.columnCount)
696
+ return null;
697
+ return {
698
+ index: value.index,
699
+ rowCount: value.rowCount,
700
+ columnCount: value.columnCount,
701
+ headers,
702
+ };
703
+ }
704
+ function parseLinkSummary(value) {
705
+ if (!isRecord(value) ||
706
+ !hasExactKeys(value, ['index', 'text', 'target']) ||
707
+ !isNonNegativeInteger(value.index) ||
708
+ !isBoundedString(value.text, MCP_WIRE_LIMITS.labelCharacters) ||
709
+ !isBoundedString(value.target, MCP_WIRE_LIMITS.uriCharacters, 1)) {
710
+ return null;
711
+ }
712
+ return { index: value.index, text: value.text, target: value.target };
713
+ }
714
+ function parseDocumentItemSummary(value) {
715
+ if (!isRecord(value) ||
716
+ !hasExactKeys(value, ['kind', 'index', 'label', 'blockIds']) ||
717
+ !isPreviewItemKind(value.kind) ||
718
+ !isNonNegativeInteger(value.index) ||
719
+ !isNullableBoundedString(value.label, MCP_WIRE_LIMITS.labelCharacters)) {
720
+ return null;
721
+ }
722
+ const blockIds = parseArray(value.blockIds, (entry) => (isIdentifier(entry) ? entry : null));
723
+ if (blockIds === null || new Set(blockIds).size !== blockIds.length)
724
+ return null;
725
+ return { kind: value.kind, index: value.index, label: value.label, blockIds };
726
+ }
727
+ function parseAssetSummary(value) {
728
+ if (!isRecord(value) ||
729
+ !hasExactKeys(value, ['path', 'mimeType', 'size', 'sha256', 'altText', 'credit', 'license'])) {
730
+ return null;
731
+ }
732
+ const path = parseNonRootWorkspacePath(value.path);
733
+ if (path === null ||
734
+ !isMimeType(value.mimeType) ||
735
+ !isBoundedInteger(value.size, 0, MCP_WIRE_LIMITS.artifactBytes) ||
736
+ !(value.sha256 === null || isSha256(value.sha256)) ||
737
+ !isNullableBoundedString(value.altText, MCP_WIRE_LIMITS.labelCharacters) ||
738
+ !isNullableBoundedString(value.credit, MCP_WIRE_LIMITS.labelCharacters) ||
739
+ !isNullableBoundedString(value.license, MCP_WIRE_LIMITS.labelCharacters)) {
740
+ return null;
741
+ }
742
+ return {
743
+ path,
744
+ mimeType: value.mimeType,
745
+ size: value.size,
746
+ sha256: value.sha256,
747
+ altText: value.altText,
748
+ credit: value.credit,
749
+ license: value.license,
750
+ };
751
+ }
752
+ function parseThemeSummary(value) {
753
+ if (!isRecord(value) ||
754
+ !hasExactKeys(value, ['id', 'name', 'source', 'layouts']) ||
755
+ !isIdentifier(value.id) ||
756
+ !isBoundedString(value.name, MCP_WIRE_LIMITS.labelCharacters, 1) ||
757
+ !(value.source === 'built-in' || value.source === 'document' || value.source === 'inferred')) {
758
+ return null;
759
+ }
760
+ const layouts = parseStringArray(value.layouts, MCP_WIRE_LIMITS.labelCharacters);
761
+ if (layouts === null || new Set(layouts).size !== layouts.length)
762
+ return null;
763
+ return { id: value.id, name: value.name, source: value.source, layouts };
764
+ }
765
+ function parseValidationSummary(value) {
766
+ if (!isRecord(value) ||
767
+ !hasExactKeys(value, ['errorCount', 'warningCount', 'infoCount']) ||
768
+ !isNonNegativeInteger(value.errorCount) ||
769
+ !isNonNegativeInteger(value.warningCount) ||
770
+ !isNonNegativeInteger(value.infoCount)) {
771
+ return null;
772
+ }
773
+ return {
774
+ errorCount: value.errorCount,
775
+ warningCount: value.warningCount,
776
+ infoCount: value.infoCount,
777
+ };
778
+ }
779
+ function parsePreviewItem(value) {
780
+ if (!isRecord(value) ||
781
+ !hasExactKeys(value, ['kind', 'index', 'label', 'artifact', 'width', 'height']) ||
782
+ !isPreviewItemKind(value.kind) ||
783
+ !isNonNegativeInteger(value.index) ||
784
+ !isNullableBoundedString(value.label, MCP_WIRE_LIMITS.labelCharacters) ||
785
+ !isBoundedInteger(value.width, 1, MCP_WIRE_LIMITS.imageDimension) ||
786
+ !isBoundedInteger(value.height, 1, MCP_WIRE_LIMITS.imageDimension)) {
787
+ return null;
788
+ }
789
+ const artifact = parseArtifactRef(value.artifact);
790
+ if (artifact === null || !artifact.mimeType.startsWith('image/'))
791
+ return null;
792
+ return {
793
+ kind: value.kind,
794
+ index: value.index,
795
+ label: value.label,
796
+ artifact,
797
+ width: value.width,
798
+ height: value.height,
799
+ };
800
+ }
801
+ function parseComparisonChange(value) {
802
+ if (!isRecord(value) ||
803
+ !hasExactKeys(value, ['category', 'status', 'path', 'message']) ||
804
+ !isComparisonCategory(value.category) ||
805
+ !isComparisonStatus(value.status) ||
806
+ !isNullableBoundedString(value.path, MCP_WIRE_LIMITS.pathCharacters) ||
807
+ !isBoundedString(value.message, MCP_WIRE_LIMITS.messageCharacters, 1)) {
808
+ return null;
809
+ }
810
+ return {
811
+ category: value.category,
812
+ status: value.status,
813
+ path: value.path,
814
+ message: value.message,
815
+ };
816
+ }
817
+ function parseComparisonMetric(value) {
818
+ if (!isRecord(value) ||
819
+ !hasExactKeys(value, ['name', 'leftValue', 'rightValue', 'similarity']) ||
820
+ !isIdentifier(value.name) ||
821
+ !isFiniteNumber(value.leftValue) ||
822
+ !isFiniteNumber(value.rightValue) ||
823
+ !isBoundedNumber(value.similarity, 0, 1)) {
824
+ return null;
825
+ }
826
+ return {
827
+ name: value.name,
828
+ leftValue: value.leftValue,
829
+ rightValue: value.rightValue,
830
+ similarity: value.similarity,
831
+ };
832
+ }
833
+ function summarizeDiagnostics(diagnostics) {
834
+ let errorCount = 0;
835
+ let warningCount = 0;
836
+ let infoCount = 0;
837
+ for (const diagnostic of diagnostics) {
838
+ if (diagnostic.severity === 'error')
839
+ errorCount += diagnostic.count;
840
+ else if (diagnostic.severity === 'warning')
841
+ warningCount += diagnostic.count;
842
+ else
843
+ infoCount += diagnostic.count;
844
+ }
845
+ return { errorCount, warningCount, infoCount };
846
+ }
847
+ function parseArray(value, parser, maximumEntries = MCP_WIRE_LIMITS.arrayEntries) {
848
+ if (!Array.isArray(value) || value.length > maximumEntries)
849
+ return null;
850
+ const parsed = [];
851
+ for (const entry of value) {
852
+ const result = parser(entry);
853
+ if (result === null)
854
+ return null;
855
+ parsed.push(result);
856
+ }
857
+ return parsed;
858
+ }
859
+ function parseStringArray(value, maximumCharacters) {
860
+ if (!Array.isArray(value) || value.length > MCP_WIRE_LIMITS.arrayEntries)
861
+ return null;
862
+ const parsed = [];
863
+ for (const entry of value) {
864
+ if (!isBoundedString(entry, maximumCharacters, 1))
865
+ return null;
866
+ parsed.push(entry);
867
+ }
868
+ return parsed;
869
+ }
870
+ function parseNullable(value, parser) {
871
+ if (value === null)
872
+ return null;
873
+ return parser(value) ?? undefined;
874
+ }
875
+ function parseNonRootWorkspacePath(value) {
876
+ if (!isBoundedString(value, MCP_WIRE_LIMITS.pathCharacters, 1) ||
877
+ value.includes('\\') ||
878
+ value.startsWith('/') ||
879
+ value.endsWith('/') ||
880
+ value.includes('//')) {
881
+ return null;
882
+ }
883
+ const parsed = tryParseWorkspacePath(value);
884
+ return parsed !== null && parsed !== '' && parsed === value ? parsed : null;
885
+ }
886
+ function isArtifactUri(value, expectedId) {
887
+ if (!isBoundedString(value, MCP_WIRE_LIMITS.uriCharacters, 1))
888
+ return false;
889
+ try {
890
+ const url = new URL(value);
891
+ if (url.protocol !== 'docblocks:' ||
892
+ url.hostname !== 'artifacts' ||
893
+ url.username !== '' ||
894
+ url.password !== '' ||
895
+ url.port !== '' ||
896
+ url.search !== '' ||
897
+ url.hash !== '') {
898
+ return false;
899
+ }
900
+ const id = url.pathname.slice(1);
901
+ return (!id.includes('/') &&
902
+ isIdentifier(id) &&
903
+ value === `docblocks://artifacts/${id}` &&
904
+ (expectedId === undefined || id === expectedId));
905
+ }
906
+ catch {
907
+ return false;
908
+ }
909
+ }
910
+ function isSafeFilename(value) {
911
+ return (isBoundedString(value, MCP_WIRE_LIMITS.labelCharacters, 1) &&
912
+ value !== '.' &&
913
+ value !== '..' &&
914
+ !value.includes('/') &&
915
+ !value.includes('\\'));
916
+ }
917
+ function isIsoTimestamp(value) {
918
+ if (typeof value !== 'string' || !ISO_TIMESTAMP_PATTERN.test(value))
919
+ return false;
920
+ const timestamp = Date.parse(value);
921
+ return Number.isFinite(timestamp) && new Date(timestamp).toISOString() === value;
922
+ }
923
+ function isIdentifier(value) {
924
+ return (isBoundedString(value, MCP_WIRE_LIMITS.identifierCharacters, 1) &&
925
+ IDENTIFIER_PATTERN.test(value));
926
+ }
927
+ function isEngineName(value) {
928
+ return (isBoundedString(value, MCP_WIRE_LIMITS.identifierCharacters, 1) &&
929
+ ENGINE_NAME_PATTERN.test(value));
930
+ }
931
+ function isNullableIdentifier(value) {
932
+ return value === null || isIdentifier(value);
933
+ }
934
+ function isFormat(value) {
935
+ return isBoundedString(value, MCP_WIRE_LIMITS.formatCharacters, 1) && FORMAT_PATTERN.test(value);
936
+ }
937
+ function isMimeType(value) {
938
+ return (isBoundedString(value, MCP_WIRE_LIMITS.mimeTypeCharacters, 3) && MIME_TYPE_PATTERN.test(value));
939
+ }
940
+ function isSha256(value) {
941
+ return typeof value === 'string' && SHA256_PATTERN.test(value);
942
+ }
943
+ function isAppliedOptionValue(value) {
944
+ return (value === null ||
945
+ typeof value === 'boolean' ||
946
+ isBoundedString(value, MCP_WIRE_LIMITS.messageCharacters) ||
947
+ isFiniteNumber(value));
948
+ }
949
+ function isDiagnosticSeverity(value) {
950
+ return value === 'info' || value === 'warning' || value === 'error';
951
+ }
952
+ function isDiagnosticStage(value) {
953
+ return (value === 'resolve' ||
954
+ value === 'import' ||
955
+ value === 'parse' ||
956
+ value === 'inspect' ||
957
+ value === 'validate' ||
958
+ value === 'transform' ||
959
+ value === 'convert' ||
960
+ value === 'render' ||
961
+ value === 'export' ||
962
+ value === 'materialize' ||
963
+ value === 'compare');
964
+ }
965
+ function isConversionFidelity(value) {
966
+ return (value === 'semantic' ||
967
+ value === 'editable-native' ||
968
+ value === 'rendered-fidelity' ||
969
+ value === 'hybrid');
970
+ }
971
+ function isPreviewItemKind(value) {
972
+ return value === 'page' || value === 'slide' || value === 'sheet' || value === 'frame';
973
+ }
974
+ function isComparisonCategory(value) {
975
+ return (value === 'text' ||
976
+ value === 'structure' ||
977
+ value === 'table' ||
978
+ value === 'media' ||
979
+ value === 'theme' ||
980
+ value === 'layout' ||
981
+ value === 'metadata' ||
982
+ value === 'timing' ||
983
+ value === 'accessibility');
984
+ }
985
+ function isComparisonStatus(value) {
986
+ return (value === 'retained' ||
987
+ value === 'changed' ||
988
+ value === 'degraded' ||
989
+ value === 'omitted' ||
990
+ value === 'added');
991
+ }
992
+ function hasDuplicateNames(values) {
993
+ return new Set(values.map((value) => value.name)).size !== values.length;
994
+ }
995
+ function hasDuplicateIds(values) {
996
+ return new Set(values.map((value) => value.id)).size !== values.length;
997
+ }
998
+ function hasDuplicatePaths(values) {
999
+ return new Set(values.map((value) => value.path)).size !== values.length;
1000
+ }
1001
+ function hasDuplicateIndexes(values) {
1002
+ return new Set(values.map((value) => value.index)).size !== values.length;
1003
+ }
1004
+ function hasDuplicateItemIndexes(values) {
1005
+ return new Set(values.map((value) => `${value.kind}:${value.index}`)).size !== values.length;
1006
+ }
1007
+ function hasDuplicatePreviewIndexes(values) {
1008
+ const keys = values.map((value) => `${value.kind}:${value.index}`);
1009
+ return new Set(keys).size !== keys.length;
1010
+ }
1011
+ function isRecord(value) {
1012
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
1013
+ }
1014
+ function hasExactKeys(value, keys) {
1015
+ const actual = Object.keys(value);
1016
+ return (actual.length === keys.length &&
1017
+ keys.every((key) => Object.prototype.hasOwnProperty.call(value, key)));
1018
+ }
1019
+ function isBoundedString(value, maximumCharacters, minimumCharacters = 0) {
1020
+ return (typeof value === 'string' &&
1021
+ value.length >= minimumCharacters &&
1022
+ value.length <= maximumCharacters &&
1023
+ ![...value].some((character) => {
1024
+ const codePoint = character.codePointAt(0) ?? 0;
1025
+ return codePoint === 0 || codePoint === 0x7f;
1026
+ }));
1027
+ }
1028
+ function isNullableBoundedString(value, maximumCharacters) {
1029
+ return value === null || isBoundedString(value, maximumCharacters);
1030
+ }
1031
+ function isFiniteNumber(value) {
1032
+ return typeof value === 'number' && Number.isFinite(value);
1033
+ }
1034
+ function isBoundedNumber(value, minimum, maximum) {
1035
+ return isFiniteNumber(value) && value >= minimum && value <= maximum;
1036
+ }
1037
+ function isBoundedInteger(value, minimum, maximum) {
1038
+ return (Number.isSafeInteger(value) && typeof value === 'number' && value >= minimum && value <= maximum);
1039
+ }
1040
+ function isNonNegativeInteger(value) {
1041
+ return isBoundedInteger(value, 0, Number.MAX_SAFE_INTEGER);
1042
+ }
1043
+ function isNullableNonNegativeInteger(value) {
1044
+ return value === null || isNonNegativeInteger(value);
1045
+ }
1046
+ //# sourceMappingURL=wire.js.map