@wonderwhy-er/desktop-commander 0.2.37 → 0.2.39

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 (383) hide show
  1. package/README.md +290 -100
  2. package/dist/command-manager.js +6 -3
  3. package/dist/config-field-definitions.d.ts +41 -0
  4. package/dist/config-field-definitions.js +37 -0
  5. package/dist/config-manager.d.ts +2 -0
  6. package/dist/config-manager.js +22 -2
  7. package/dist/handlers/filesystem-handlers.d.ts +5 -0
  8. package/dist/handlers/filesystem-handlers.js +19 -12
  9. package/dist/remote-device/desktop-commander-integration.js +1 -1
  10. package/dist/remote-device/remote-channel.js +1 -1
  11. package/dist/search-manager.js +31 -38
  12. package/dist/server.js +11 -4
  13. package/dist/terminal-manager.js +4 -2
  14. package/dist/tools/config.d.ts +71 -0
  15. package/dist/tools/config.js +117 -2
  16. package/dist/tools/edit.js +34 -1
  17. package/dist/tools/filesystem.js +91 -3
  18. package/dist/tools/improved-process-tools.js +2 -1
  19. package/dist/tools/schemas.d.ts +3 -0
  20. package/dist/tools/schemas.js +1 -0
  21. package/dist/types.d.ts +0 -1
  22. package/dist/ui/config-editor/app.d.ts +43 -0
  23. package/dist/ui/config-editor/app.js +840 -0
  24. package/dist/ui/config-editor/array-modal.d.ts +19 -0
  25. package/dist/ui/config-editor/array-modal.js +185 -0
  26. package/dist/ui/config-editor/config-editor-runtime.js +150 -0
  27. package/dist/ui/config-editor/index.html +13 -0
  28. package/dist/ui/config-editor/main.js +2 -0
  29. package/dist/ui/config-editor/src/App.d.ts +43 -0
  30. package/dist/ui/config-editor/src/App.js +840 -0
  31. package/dist/ui/config-editor/src/array-modal.d.ts +19 -0
  32. package/dist/ui/config-editor/src/array-modal.js +185 -0
  33. package/dist/ui/config-editor/src/components/layout.d.ts +4 -0
  34. package/dist/ui/config-editor/src/components/layout.js +83 -0
  35. package/dist/ui/config-editor/src/components/toolbar.d.ts +1 -0
  36. package/dist/ui/config-editor/src/components/toolbar.js +21 -0
  37. package/dist/ui/config-editor/src/config-values.d.ts +6 -0
  38. package/dist/ui/config-editor/src/config-values.js +61 -0
  39. package/dist/ui/config-editor/src/contracts.d.ts +14 -0
  40. package/dist/ui/config-editor/src/contracts.js +3 -0
  41. package/dist/ui/config-editor/src/directory-browser.d.ts +6 -0
  42. package/dist/ui/config-editor/src/directory-browser.js +71 -0
  43. package/dist/ui/config-editor/src/layout.d.ts +5 -0
  44. package/dist/ui/config-editor/src/layout.js +90 -0
  45. package/dist/ui/config-editor/src/main.js +2 -0
  46. package/dist/ui/config-editor/src/parsing.d.ts +5 -0
  47. package/dist/ui/config-editor/src/parsing.js +50 -0
  48. package/dist/ui/config-editor/src/toolbar.d.ts +1 -0
  49. package/dist/ui/config-editor/src/toolbar.js +18 -0
  50. package/dist/ui/config-editor/src/types.d.ts +17 -0
  51. package/dist/ui/config-editor/src/types.js +3 -0
  52. package/dist/ui/config-editor/src/utils/config-values.d.ts +9 -0
  53. package/dist/ui/config-editor/src/utils/config-values.js +61 -0
  54. package/dist/ui/config-editor/src/utils/directory-browser.d.ts +31 -0
  55. package/dist/ui/config-editor/src/utils/directory-browser.js +201 -0
  56. package/dist/ui/config-editor/src/utils/parsing.d.ts +8 -0
  57. package/dist/ui/config-editor/src/utils/parsing.js +50 -0
  58. package/dist/ui/config-editor/styles.css +587 -0
  59. package/dist/ui/file-preview/app.d.ts +8 -0
  60. package/dist/ui/file-preview/app.js +2020 -0
  61. package/dist/ui/file-preview/components/code-viewer.d.ts +6 -0
  62. package/dist/ui/file-preview/components/code-viewer.js +73 -0
  63. package/dist/ui/file-preview/components/highlighting.d.ts +2 -0
  64. package/dist/ui/file-preview/components/highlighting.js +54 -0
  65. package/dist/ui/file-preview/components/html-renderer.d.ts +5 -0
  66. package/dist/ui/file-preview/components/html-renderer.js +47 -0
  67. package/dist/ui/file-preview/components/markdown-renderer.d.ts +1 -0
  68. package/dist/ui/file-preview/components/markdown-renderer.js +67 -0
  69. package/dist/ui/file-preview/components/toolbar.d.ts +6 -0
  70. package/dist/ui/file-preview/components/toolbar.js +75 -0
  71. package/dist/ui/file-preview/image-preview.d.ts +3 -0
  72. package/dist/ui/file-preview/image-preview.js +21 -0
  73. package/dist/ui/file-preview/main.js +5 -0
  74. package/dist/ui/file-preview/markdown/editor.d.ts +36 -0
  75. package/dist/ui/file-preview/markdown/editor.js +643 -0
  76. package/dist/ui/file-preview/markdown/linking.d.ts +9 -0
  77. package/dist/ui/file-preview/markdown/linking.js +210 -0
  78. package/dist/ui/file-preview/markdown/outline.d.ts +7 -0
  79. package/dist/ui/file-preview/markdown/outline.js +40 -0
  80. package/dist/ui/file-preview/markdown/preview.d.ts +8 -0
  81. package/dist/ui/file-preview/markdown/preview.js +33 -0
  82. package/dist/ui/file-preview/markdown/slugify.d.ts +3 -0
  83. package/dist/ui/file-preview/markdown/slugify.js +31 -0
  84. package/dist/ui/file-preview/markdown/toc.d.ts +11 -0
  85. package/dist/ui/file-preview/markdown/toc.js +75 -0
  86. package/dist/ui/file-preview/markdown/utils.d.ts +1 -0
  87. package/dist/ui/file-preview/markdown/utils.js +15 -0
  88. package/dist/ui/file-preview/markdown/workspace-controller.d.ts +25 -0
  89. package/dist/ui/file-preview/markdown/workspace-controller.js +40 -0
  90. package/dist/ui/file-preview/preview-runtime.js +399 -13969
  91. package/dist/ui/file-preview/shared/preview-file-types.d.ts +1 -1
  92. package/dist/ui/file-preview/shared/preview-file-types.js +3 -1
  93. package/dist/ui/file-preview/src/App.d.ts +4 -0
  94. package/dist/ui/file-preview/src/App.js +564 -0
  95. package/dist/ui/file-preview/src/components/CodeViewer.d.ts +6 -0
  96. package/dist/ui/file-preview/src/components/CodeViewer.js +60 -0
  97. package/dist/ui/file-preview/src/components/HtmlRenderer.d.ts +8 -0
  98. package/dist/ui/file-preview/src/components/HtmlRenderer.js +45 -0
  99. package/dist/ui/file-preview/src/components/MarkdownRenderer.d.ts +1 -0
  100. package/dist/ui/file-preview/src/components/MarkdownRenderer.js +15 -0
  101. package/dist/ui/file-preview/src/components/editor-toolbar.d.ts +15 -0
  102. package/dist/ui/file-preview/src/components/editor-toolbar.js +384 -0
  103. package/dist/ui/file-preview/src/components/html-renderer.d.ts +1 -5
  104. package/dist/ui/file-preview/src/components/html-renderer.js +11 -27
  105. package/dist/ui/file-preview/src/components/markdown-editor.d.ts +29 -0
  106. package/dist/ui/file-preview/src/components/markdown-editor.js +535 -0
  107. package/dist/ui/file-preview/src/components/markdown-renderer.js +47 -9
  108. package/dist/ui/file-preview/src/directory-controller.d.ts +8 -0
  109. package/dist/ui/file-preview/src/directory-controller.js +233 -0
  110. package/dist/ui/file-preview/src/document-layout.d.ts +20 -0
  111. package/dist/ui/file-preview/src/document-layout.js +109 -0
  112. package/dist/ui/file-preview/src/document-outline.d.ts +17 -0
  113. package/dist/ui/file-preview/src/document-outline.js +97 -0
  114. package/dist/ui/file-preview/src/document-workspace.d.ts +19 -0
  115. package/dist/ui/file-preview/src/document-workspace.js +33 -0
  116. package/dist/ui/file-preview/src/file-type-handlers.d.ts +10 -0
  117. package/dist/ui/file-preview/src/file-type-handlers.js +98 -0
  118. package/dist/ui/file-preview/src/host/external-actions.d.ts +19 -0
  119. package/dist/ui/file-preview/src/host/external-actions.js +94 -0
  120. package/dist/ui/file-preview/src/host/selection-context.d.ts +9 -0
  121. package/dist/ui/file-preview/src/host/selection-context.js +106 -0
  122. package/dist/ui/file-preview/src/markdown/block-merge.d.ts +25 -0
  123. package/dist/ui/file-preview/src/markdown/block-merge.js +86 -0
  124. package/dist/ui/file-preview/src/markdown/conflict-dialog.d.ts +40 -0
  125. package/dist/ui/file-preview/src/markdown/conflict-dialog.js +163 -0
  126. package/dist/ui/file-preview/src/markdown/controller.d.ts +38 -0
  127. package/dist/ui/file-preview/src/markdown/controller.js +921 -0
  128. package/dist/ui/file-preview/src/markdown/editor.d.ts +35 -0
  129. package/dist/ui/file-preview/src/markdown/editor.js +691 -0
  130. package/dist/ui/file-preview/src/markdown/link-modal.d.ts +13 -0
  131. package/dist/ui/file-preview/src/markdown/link-modal.js +213 -0
  132. package/dist/ui/file-preview/src/markdown/linking.d.ts +16 -0
  133. package/dist/ui/file-preview/src/markdown/linking.js +228 -0
  134. package/dist/ui/file-preview/src/markdown/outline.d.ts +2 -0
  135. package/dist/ui/file-preview/src/markdown/outline.js +16 -0
  136. package/dist/ui/file-preview/src/markdown/parser.d.ts +30 -0
  137. package/dist/ui/file-preview/src/markdown/parser.js +38 -0
  138. package/dist/ui/file-preview/src/markdown/preview.d.ts +1 -0
  139. package/dist/ui/file-preview/src/markdown/preview.js +20 -0
  140. package/dist/ui/file-preview/src/markdown/raw-editor.d.ts +8 -0
  141. package/dist/ui/file-preview/src/markdown/raw-editor.js +61 -0
  142. package/dist/ui/file-preview/src/markdown/selection-toolbar.d.ts +14 -0
  143. package/dist/ui/file-preview/src/markdown/selection-toolbar.js +128 -0
  144. package/dist/ui/file-preview/src/markdown/slugify.d.ts +3 -0
  145. package/dist/ui/file-preview/src/markdown/slugify.js +31 -0
  146. package/dist/ui/file-preview/src/markdown/toc.d.ts +11 -0
  147. package/dist/ui/file-preview/src/markdown/toc.js +75 -0
  148. package/dist/ui/file-preview/src/markdown/utils.d.ts +1 -0
  149. package/dist/ui/file-preview/src/markdown/utils.js +15 -0
  150. package/dist/ui/file-preview/src/markdown-workspace/editor.d.ts +36 -0
  151. package/dist/ui/file-preview/src/markdown-workspace/editor.js +643 -0
  152. package/dist/ui/file-preview/src/markdown-workspace/linking.d.ts +9 -0
  153. package/dist/ui/file-preview/src/markdown-workspace/linking.js +210 -0
  154. package/dist/ui/file-preview/src/markdown-workspace/outline.d.ts +7 -0
  155. package/dist/ui/file-preview/src/markdown-workspace/outline.js +40 -0
  156. package/dist/ui/file-preview/src/markdown-workspace/preview.d.ts +8 -0
  157. package/dist/ui/file-preview/src/markdown-workspace/preview.js +33 -0
  158. package/dist/ui/file-preview/src/markdown-workspace/slugify.d.ts +3 -0
  159. package/dist/ui/file-preview/src/markdown-workspace/slugify.js +31 -0
  160. package/dist/ui/file-preview/src/markdown-workspace/toc.d.ts +11 -0
  161. package/dist/ui/file-preview/src/markdown-workspace/toc.js +75 -0
  162. package/dist/ui/file-preview/src/markdown-workspace/utils.d.ts +1 -0
  163. package/dist/ui/file-preview/src/markdown-workspace/utils.js +15 -0
  164. package/dist/ui/file-preview/src/markdown-workspace/workspace-controller.d.ts +25 -0
  165. package/dist/ui/file-preview/src/markdown-workspace/workspace-controller.js +40 -0
  166. package/dist/ui/file-preview/src/model.d.ts +34 -0
  167. package/dist/ui/file-preview/src/panel-actions.d.ts +17 -0
  168. package/dist/ui/file-preview/src/panel-actions.js +182 -0
  169. package/dist/ui/file-preview/src/path-utils.d.ts +6 -0
  170. package/dist/ui/file-preview/src/path-utils.js +64 -0
  171. package/dist/ui/file-preview/src/payload-utils.d.ts +11 -0
  172. package/dist/ui/file-preview/src/payload-utils.js +94 -0
  173. package/dist/ui/file-preview/styles.css +1144 -277
  174. package/dist/ui/file-preview/types.d.ts +1 -0
  175. package/dist/ui/file-preview/types.js +1 -0
  176. package/dist/ui/resources.d.ts +7 -0
  177. package/dist/ui/resources.js +16 -2
  178. package/dist/ui/server-integration.d.ts +13 -0
  179. package/dist/ui/server-integration.js +31 -0
  180. package/dist/ui/shared/ToolHeader.d.ts +9 -0
  181. package/dist/ui/shared/ToolHeader.js +29 -0
  182. package/dist/ui/shared/app-bootstrap.d.ts +9 -0
  183. package/dist/ui/shared/app-bootstrap.js +15 -0
  184. package/dist/ui/shared/compact-row.d.ts +11 -0
  185. package/dist/ui/shared/compact-row.js +18 -0
  186. package/dist/ui/shared/guards.d.ts +1 -0
  187. package/dist/ui/shared/guards.js +3 -0
  188. package/dist/ui/shared/host-context.d.ts +15 -0
  189. package/dist/ui/shared/host-context.js +51 -0
  190. package/dist/ui/shared/host-lifecycle.d.ts +1 -0
  191. package/dist/ui/shared/host-lifecycle.js +8 -2
  192. package/dist/ui/shared/tool-bridge.d.ts +30 -0
  193. package/dist/ui/shared/tool-bridge.js +137 -0
  194. package/dist/ui/shared/tool-shell.d.ts +9 -0
  195. package/dist/ui/shared/tool-shell.js +46 -4
  196. package/dist/ui/shared/ui-event-tracker.d.ts +9 -0
  197. package/dist/ui/shared/ui-event-tracker.js +27 -0
  198. package/dist/ui/shared/widget-state.d.ts +6 -1
  199. package/dist/ui/shared/widget-state.js +102 -4
  200. package/dist/utils/capture.js +3 -3
  201. package/dist/utils/files/base.d.ts +2 -0
  202. package/dist/utils/open-browser.js +1 -1
  203. package/dist/utils/ui-call-context.d.ts +8 -0
  204. package/dist/utils/ui-call-context.js +72 -0
  205. package/dist/version.d.ts +1 -1
  206. package/dist/version.js +1 -1
  207. package/package.json +13 -4
  208. package/dist/data/spec-kit-prompts.json +0 -123
  209. package/dist/handlers/node-handlers.d.ts +0 -6
  210. package/dist/handlers/node-handlers.js +0 -73
  211. package/dist/handlers/test-crash-handler.d.ts +0 -11
  212. package/dist/handlers/test-crash-handler.js +0 -26
  213. package/dist/http-index.d.ts +0 -45
  214. package/dist/http-index.js +0 -51
  215. package/dist/http-server-auto-tunnel.js +0 -667
  216. package/dist/http-server-named-tunnel.d.ts +0 -2
  217. package/dist/http-server-named-tunnel.js +0 -167
  218. package/dist/http-server-tunnel.d.ts +0 -2
  219. package/dist/http-server-tunnel.js +0 -111
  220. package/dist/http-server.d.ts +0 -2
  221. package/dist/http-server.js +0 -270
  222. package/dist/index-oauth.d.ts +0 -2
  223. package/dist/index-oauth.js +0 -201
  224. package/dist/oauth/auth-middleware.d.ts +0 -20
  225. package/dist/oauth/auth-middleware.js +0 -62
  226. package/dist/oauth/index.d.ts +0 -3
  227. package/dist/oauth/index.js +0 -3
  228. package/dist/oauth/oauth-manager.d.ts +0 -80
  229. package/dist/oauth/oauth-manager.js +0 -179
  230. package/dist/oauth/oauth-routes.d.ts +0 -3
  231. package/dist/oauth/oauth-routes.js +0 -377
  232. package/dist/oauth/provider.d.ts +0 -22
  233. package/dist/oauth/provider.js +0 -124
  234. package/dist/oauth/server.d.ts +0 -18
  235. package/dist/oauth/server.js +0 -160
  236. package/dist/oauth/types.d.ts +0 -54
  237. package/dist/oauth/types.js +0 -2
  238. package/dist/remote-device/templates/auth-success.d.ts +0 -1
  239. package/dist/remote-device/templates/auth-success.js +0 -30
  240. package/dist/setup.log +0 -275
  241. package/dist/test-setup.js +0 -14
  242. package/dist/tools/docx/builders/html-builder.d.ts +0 -17
  243. package/dist/tools/docx/builders/html-builder.js +0 -92
  244. package/dist/tools/docx/builders/image.d.ts +0 -14
  245. package/dist/tools/docx/builders/image.js +0 -84
  246. package/dist/tools/docx/builders/index.d.ts +0 -11
  247. package/dist/tools/docx/builders/index.js +0 -11
  248. package/dist/tools/docx/builders/markdown-builder.d.ts +0 -2
  249. package/dist/tools/docx/builders/markdown-builder.js +0 -260
  250. package/dist/tools/docx/builders/paragraph.d.ts +0 -12
  251. package/dist/tools/docx/builders/paragraph.js +0 -29
  252. package/dist/tools/docx/builders/table.d.ts +0 -10
  253. package/dist/tools/docx/builders/table.js +0 -138
  254. package/dist/tools/docx/builders/utils.d.ts +0 -5
  255. package/dist/tools/docx/builders/utils.js +0 -18
  256. package/dist/tools/docx/constants.d.ts +0 -32
  257. package/dist/tools/docx/constants.js +0 -61
  258. package/dist/tools/docx/converters/markdown-to-html.d.ts +0 -17
  259. package/dist/tools/docx/converters/markdown-to-html.js +0 -111
  260. package/dist/tools/docx/create.d.ts +0 -21
  261. package/dist/tools/docx/create.js +0 -386
  262. package/dist/tools/docx/dom.d.ts +0 -139
  263. package/dist/tools/docx/dom.js +0 -448
  264. package/dist/tools/docx/errors.d.ts +0 -28
  265. package/dist/tools/docx/errors.js +0 -48
  266. package/dist/tools/docx/extractors/images.d.ts +0 -14
  267. package/dist/tools/docx/extractors/images.js +0 -40
  268. package/dist/tools/docx/extractors/metadata.d.ts +0 -14
  269. package/dist/tools/docx/extractors/metadata.js +0 -64
  270. package/dist/tools/docx/extractors/sections.d.ts +0 -14
  271. package/dist/tools/docx/extractors/sections.js +0 -61
  272. package/dist/tools/docx/html.d.ts +0 -17
  273. package/dist/tools/docx/html.js +0 -111
  274. package/dist/tools/docx/index.d.ts +0 -10
  275. package/dist/tools/docx/index.js +0 -10
  276. package/dist/tools/docx/markdown.d.ts +0 -84
  277. package/dist/tools/docx/markdown.js +0 -507
  278. package/dist/tools/docx/modify.d.ts +0 -28
  279. package/dist/tools/docx/modify.js +0 -271
  280. package/dist/tools/docx/operations/handlers/index.d.ts +0 -39
  281. package/dist/tools/docx/operations/handlers/index.js +0 -152
  282. package/dist/tools/docx/operations/html-manipulator.d.ts +0 -24
  283. package/dist/tools/docx/operations/html-manipulator.js +0 -352
  284. package/dist/tools/docx/operations/index.d.ts +0 -14
  285. package/dist/tools/docx/operations/index.js +0 -61
  286. package/dist/tools/docx/operations/operation-handlers.d.ts +0 -3
  287. package/dist/tools/docx/operations/operation-handlers.js +0 -67
  288. package/dist/tools/docx/operations/preprocessor.d.ts +0 -14
  289. package/dist/tools/docx/operations/preprocessor.js +0 -44
  290. package/dist/tools/docx/operations/xml-replacer.d.ts +0 -9
  291. package/dist/tools/docx/operations/xml-replacer.js +0 -35
  292. package/dist/tools/docx/operations.d.ts +0 -13
  293. package/dist/tools/docx/operations.js +0 -13
  294. package/dist/tools/docx/ops/delete-paragraph-at-body-index.d.ts +0 -11
  295. package/dist/tools/docx/ops/delete-paragraph-at-body-index.js +0 -23
  296. package/dist/tools/docx/ops/header-replace-text-exact.d.ts +0 -13
  297. package/dist/tools/docx/ops/header-replace-text-exact.js +0 -55
  298. package/dist/tools/docx/ops/index.d.ts +0 -17
  299. package/dist/tools/docx/ops/index.js +0 -70
  300. package/dist/tools/docx/ops/insert-image-after-text.d.ts +0 -24
  301. package/dist/tools/docx/ops/insert-image-after-text.js +0 -128
  302. package/dist/tools/docx/ops/insert-paragraph-after-text.d.ts +0 -12
  303. package/dist/tools/docx/ops/insert-paragraph-after-text.js +0 -74
  304. package/dist/tools/docx/ops/insert-table-after-text.d.ts +0 -19
  305. package/dist/tools/docx/ops/insert-table-after-text.js +0 -57
  306. package/dist/tools/docx/ops/replace-hyperlink-url.d.ts +0 -12
  307. package/dist/tools/docx/ops/replace-hyperlink-url.js +0 -37
  308. package/dist/tools/docx/ops/replace-paragraph-at-body-index.d.ts +0 -9
  309. package/dist/tools/docx/ops/replace-paragraph-at-body-index.js +0 -25
  310. package/dist/tools/docx/ops/replace-paragraph-text-exact.d.ts +0 -21
  311. package/dist/tools/docx/ops/replace-paragraph-text-exact.js +0 -36
  312. package/dist/tools/docx/ops/replace-table-cell-text.d.ts +0 -25
  313. package/dist/tools/docx/ops/replace-table-cell-text.js +0 -85
  314. package/dist/tools/docx/ops/set-color-for-paragraph-exact.d.ts +0 -9
  315. package/dist/tools/docx/ops/set-color-for-paragraph-exact.js +0 -24
  316. package/dist/tools/docx/ops/set-color-for-style.d.ts +0 -13
  317. package/dist/tools/docx/ops/set-color-for-style.js +0 -31
  318. package/dist/tools/docx/ops/set-paragraph-style-at-body-index.d.ts +0 -8
  319. package/dist/tools/docx/ops/set-paragraph-style-at-body-index.js +0 -57
  320. package/dist/tools/docx/ops/table-set-cell-text.d.ts +0 -9
  321. package/dist/tools/docx/ops/table-set-cell-text.js +0 -40
  322. package/dist/tools/docx/parsers/image-extractor.d.ts +0 -18
  323. package/dist/tools/docx/parsers/image-extractor.js +0 -61
  324. package/dist/tools/docx/parsers/index.d.ts +0 -9
  325. package/dist/tools/docx/parsers/index.js +0 -9
  326. package/dist/tools/docx/parsers/paragraph-parser.d.ts +0 -2
  327. package/dist/tools/docx/parsers/paragraph-parser.js +0 -88
  328. package/dist/tools/docx/parsers/table-parser.d.ts +0 -9
  329. package/dist/tools/docx/parsers/table-parser.js +0 -72
  330. package/dist/tools/docx/parsers/xml-parser.d.ts +0 -25
  331. package/dist/tools/docx/parsers/xml-parser.js +0 -71
  332. package/dist/tools/docx/parsers/zip-reader.d.ts +0 -23
  333. package/dist/tools/docx/parsers/zip-reader.js +0 -52
  334. package/dist/tools/docx/read.d.ts +0 -27
  335. package/dist/tools/docx/read.js +0 -308
  336. package/dist/tools/docx/relationships.d.ts +0 -22
  337. package/dist/tools/docx/relationships.js +0 -76
  338. package/dist/tools/docx/structure.d.ts +0 -25
  339. package/dist/tools/docx/structure.js +0 -102
  340. package/dist/tools/docx/styled-html-parser.d.ts +0 -23
  341. package/dist/tools/docx/styled-html-parser.js +0 -1262
  342. package/dist/tools/docx/types.d.ts +0 -213
  343. package/dist/tools/docx/types.js +0 -5
  344. package/dist/tools/docx/utils/escaping.d.ts +0 -13
  345. package/dist/tools/docx/utils/escaping.js +0 -26
  346. package/dist/tools/docx/utils/images.d.ts +0 -9
  347. package/dist/tools/docx/utils/images.js +0 -26
  348. package/dist/tools/docx/utils/index.d.ts +0 -12
  349. package/dist/tools/docx/utils/index.js +0 -17
  350. package/dist/tools/docx/utils/markdown.d.ts +0 -13
  351. package/dist/tools/docx/utils/markdown.js +0 -32
  352. package/dist/tools/docx/utils/paths.d.ts +0 -15
  353. package/dist/tools/docx/utils/paths.js +0 -27
  354. package/dist/tools/docx/utils/versioning.d.ts +0 -25
  355. package/dist/tools/docx/utils/versioning.js +0 -55
  356. package/dist/tools/docx/utils.d.ts +0 -101
  357. package/dist/tools/docx/utils.js +0 -299
  358. package/dist/tools/docx/validate.d.ts +0 -33
  359. package/dist/tools/docx/validate.js +0 -49
  360. package/dist/tools/docx/validators.d.ts +0 -13
  361. package/dist/tools/docx/validators.js +0 -40
  362. package/dist/tools/docx/write.d.ts +0 -17
  363. package/dist/tools/docx/write.js +0 -88
  364. package/dist/tools/docx/xml-view-test.js +0 -63
  365. package/dist/tools/docx/xml-view.d.ts +0 -56
  366. package/dist/tools/docx/xml-view.js +0 -169
  367. package/dist/tools/docx/zip.d.ts +0 -21
  368. package/dist/tools/docx/zip.js +0 -35
  369. package/dist/tools/pdf-processor.js +0 -3
  370. package/dist/tools/search.d.ts +0 -32
  371. package/dist/tools/search.js +0 -202
  372. package/dist/ui/file-preview/src/app.d.ts +0 -4
  373. package/dist/ui/file-preview/src/app.js +0 -800
  374. package/dist/utils/crash-logger.d.ts +0 -18
  375. package/dist/utils/crash-logger.js +0 -44
  376. package/dist/utils/dedent.d.ts +0 -8
  377. package/dist/utils/dedent.js +0 -38
  378. /package/dist/{http-server-auto-tunnel.d.ts → ui/config-editor/main.d.ts} +0 -0
  379. /package/dist/{test-docx.d.ts → ui/config-editor/src/main.d.ts} +0 -0
  380. /package/dist/{tools/docx/xml-view-test.d.ts → ui/file-preview/main.d.ts} +0 -0
  381. /package/dist/ui/file-preview/src/components/{toolbar.d.ts → Toolbar.d.ts} +0 -0
  382. /package/dist/ui/file-preview/src/components/{toolbar.js → Toolbar.js} +0 -0
  383. /package/dist/{tools/pdf-processor.d.ts → ui/file-preview/src/model.js} +0 -0
@@ -0,0 +1,45 @@
1
+ import { renderCodeViewer } from './CodeViewer.js';
2
+ import { escapeHtml } from './highlighting.js';
3
+ function sanitizeHtml(rawHtml) {
4
+ const blockedTagPattern = /<\/?(script|iframe|object|embed|link|meta|base|form)[^>]*>/gi;
5
+ let safe = rawHtml.replace(blockedTagPattern, '');
6
+ safe = safe.replace(/\son[a-z]+\s*=\s*(".*?"|'.*?'|[^\s>]+)/gi, '');
7
+ safe = safe.replace(/\s(href|src)\s*=\s*(".*?"|'.*?'|[^\s>]+)/gi, (match, attr, value) => {
8
+ const strippedValue = String(value).replace(/^['"]|['"]$/g, '').trim().toLowerCase();
9
+ if (strippedValue.startsWith('javascript:')) {
10
+ return ` ${attr}="#"`;
11
+ }
12
+ if (strippedValue.startsWith('data:text/html')) {
13
+ return ` ${attr}="#"`;
14
+ }
15
+ return match;
16
+ });
17
+ return safe;
18
+ }
19
+ function renderSandboxedHtmlFrame(content, allowUnsafeScripts) {
20
+ const htmlContent = allowUnsafeScripts ? content : sanitizeHtml(content);
21
+ const csp = allowUnsafeScripts
22
+ ? ''
23
+ : `<meta http-equiv="Content-Security-Policy" content="default-src 'none'; img-src https: http: data:; style-src 'unsafe-inline';">`;
24
+ const sandbox = allowUnsafeScripts ? 'allow-scripts allow-forms allow-popups' : '';
25
+ const frameDocument = `<!doctype html><html><head><meta charset="utf-8" />${csp}<style>body{font-family:"IBM Plex Sans","Segoe UI",sans-serif;color:#0f172a;padding:16px;margin:0;line-height:1.5;}img{max-width:100%;height:auto;}</style></head><body>${htmlContent}</body></html>`;
26
+ return `<iframe class="html-rendered-frame" title="Rendered HTML preview" sandbox="${sandbox}" referrerpolicy="no-referrer" srcdoc="${escapeHtml(frameDocument)}"></iframe>`;
27
+ }
28
+ export function renderHtmlPreview(content, mode, options = {}) {
29
+ if (mode === 'source') {
30
+ return {
31
+ html: `<div class="panel-content source-content">${renderCodeViewer(content, 'html')}</div>`
32
+ };
33
+ }
34
+ try {
35
+ return {
36
+ html: `<div class="panel-content html-content">${renderSandboxedHtmlFrame(content, options.allowUnsafeScripts === true)}</div>`
37
+ };
38
+ }
39
+ catch {
40
+ return {
41
+ html: `<div class="panel-content source-content">${renderCodeViewer(content, 'html')}</div>`,
42
+ notice: 'HTML renderer failed. Showing source instead.'
43
+ };
44
+ }
45
+ }
@@ -0,0 +1 @@
1
+ export declare function renderMarkdown(content: string): string;
@@ -0,0 +1,15 @@
1
+ import MarkdownIt from 'markdown-it';
2
+ import { highlightSource } from './highlighting.js';
3
+ const markdown = new MarkdownIt({
4
+ html: false,
5
+ linkify: true,
6
+ typographer: false,
7
+ highlight(code, language) {
8
+ const normalizedLanguage = (language || 'text').toLowerCase();
9
+ const highlighted = highlightSource(code, normalizedLanguage);
10
+ return `<pre class="code-viewer"><code class="hljs language-${normalizedLanguage}">${highlighted}</code></pre>`;
11
+ }
12
+ });
13
+ export function renderMarkdown(content) {
14
+ return markdown.render(content);
15
+ }
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Floating formatting toolbar for the WYSIWYG markdown editor. Appears above
3
+ * selected text and provides inline formatting: bold, italic, strikethrough,
4
+ * code, link, text color, and font size.
5
+ */
6
+ export interface EditorToolbar {
7
+ element: HTMLElement;
8
+ show: (anchorRect: DOMRect, containerRect: DOMRect) => void;
9
+ hide: () => void;
10
+ destroy: () => void;
11
+ readonly isVisible: boolean;
12
+ readonly hasOpenDropdown: boolean;
13
+ }
14
+ export declare function createEditorToolbar(onFormatApplied?: () => void): EditorToolbar;
15
+ export declare function handleFormatKeydown(e: KeyboardEvent): boolean;
@@ -0,0 +1,384 @@
1
+ /**
2
+ * Floating formatting toolbar for the WYSIWYG markdown editor. Appears above
3
+ * selected text and provides inline formatting: bold, italic, strikethrough,
4
+ * code, link, text color, and font size.
5
+ */
6
+ // ---------------------------------------------------------------------------
7
+ // Preset palettes
8
+ // ---------------------------------------------------------------------------
9
+ const COLORS = [
10
+ { label: 'Default', value: '' },
11
+ { label: 'Red', value: '#ef4444' },
12
+ { label: 'Orange', value: '#f97316' },
13
+ { label: 'Amber', value: '#f59e0b' },
14
+ { label: 'Green', value: '#22c55e' },
15
+ { label: 'Blue', value: '#3b82f6' },
16
+ { label: 'Purple', value: '#a855f7' },
17
+ { label: 'Pink', value: '#ec4899' },
18
+ { label: 'Gray', value: '#6b7280' },
19
+ ];
20
+ const FONT_SIZES = [
21
+ { label: 'Small', value: '0.85em' },
22
+ { label: 'Normal', value: '' },
23
+ { label: 'Large', value: '1.25em' },
24
+ { label: 'X-Large', value: '1.5em' },
25
+ ];
26
+ // ---------------------------------------------------------------------------
27
+ // SVG icons (inline, 16×16, matching project style)
28
+ // ---------------------------------------------------------------------------
29
+ const ICONS = {
30
+ bold: `<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M6 4h8a4 4 0 0 1 4 4 4 4 0 0 1-4 4H6z"/><path d="M6 12h9a4 4 0 0 1 4 4 4 4 0 0 1-4 4H6z"/></svg>`,
31
+ italic: `<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><line x1="19" y1="4" x2="10" y2="4"/><line x1="14" y1="20" x2="5" y2="20"/><line x1="15" y1="4" x2="9" y2="20"/></svg>`,
32
+ strike: `<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M17.3 4.9c-1.2-.9-2.7-1.4-4.3-1.4-3.3 0-5 2-5 4 0 .8.2 1.5.5 2"/><path d="M5 12h14"/><path d="M6.7 19.1c1.2.9 2.7 1.4 4.3 1.4 3.3 0 5-2 5-4 0-.8-.2-1.5-.5-2"/></svg>`,
33
+ code: `<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="16 18 22 12 16 6"/><polyline points="8 6 2 12 8 18"/></svg>`,
34
+ link: `<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg>`,
35
+ color: `<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M12 2l5.5 14H6.5z"/><line x1="4" y1="22" x2="20" y2="22" stroke-width="3"/></svg>`,
36
+ fontSize: `<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M4 7V4h16v3"/><path d="M12 4v16"/><path d="M8 20h8"/></svg>`,
37
+ chevron: `<svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9"/></svg>`,
38
+ };
39
+ // ---------------------------------------------------------------------------
40
+ // Selection save/restore (needed before opening dropdowns)
41
+ // ---------------------------------------------------------------------------
42
+ let savedRange = null;
43
+ function saveSelection() {
44
+ const sel = document.getSelection();
45
+ if (sel && sel.rangeCount > 0 && !sel.isCollapsed) {
46
+ savedRange = sel.getRangeAt(0).cloneRange();
47
+ }
48
+ }
49
+ function restoreSelection() {
50
+ if (!savedRange)
51
+ return false;
52
+ const sel = document.getSelection();
53
+ if (!sel)
54
+ return false;
55
+ sel.removeAllRanges();
56
+ sel.addRange(savedRange);
57
+ return !sel.isCollapsed;
58
+ }
59
+ // ---------------------------------------------------------------------------
60
+ // Format helpers
61
+ // ---------------------------------------------------------------------------
62
+ /**
63
+ * After a format command the browser typically collapses the selection.
64
+ * Force-restore the pre-command range so the user can chain operations.
65
+ */
66
+ function forceReselect() {
67
+ // The original savedRange still points at the right text — the browser
68
+ // mutated the DOM in-place (bold wraps in <b>, etc.) but the range
69
+ // endpoints stay valid. Re-add it.
70
+ restoreSelection();
71
+ }
72
+ function execFormat(command, value) {
73
+ if (!restoreSelection())
74
+ return;
75
+ document.execCommand(command, false, value);
76
+ forceReselect();
77
+ }
78
+ function wrapSelectionHtml(tag, attrs = '') {
79
+ if (!restoreSelection())
80
+ return;
81
+ const sel = document.getSelection();
82
+ if (!sel || sel.isCollapsed)
83
+ return;
84
+ const selectedText = sel.toString();
85
+ const html = `<${tag}${attrs ? ' ' + attrs : ''}>${escapeForInsert(selectedText)}</${tag}>`;
86
+ document.execCommand('insertHTML', false, html);
87
+ forceReselect();
88
+ }
89
+ function escapeForInsert(text) {
90
+ return text
91
+ .replace(/&/g, '&amp;')
92
+ .replace(/</g, '&lt;')
93
+ .replace(/>/g, '&gt;');
94
+ }
95
+ function applyColor(color) {
96
+ if (!color) {
97
+ execFormat('removeFormat');
98
+ return;
99
+ }
100
+ if (!restoreSelection())
101
+ return;
102
+ document.execCommand('foreColor', false, color);
103
+ forceReselect();
104
+ }
105
+ function applyFontSize(size) {
106
+ if (!size) {
107
+ execFormat('removeFormat');
108
+ return;
109
+ }
110
+ if (!restoreSelection())
111
+ return;
112
+ document.execCommand('fontSize', false, '7');
113
+ // Find the <font size="7"> the browser just created and swap it for a span
114
+ const editableRoot = document.getSelection()?.anchorNode?.parentElement?.closest('[contenteditable="true"]');
115
+ if (editableRoot) {
116
+ const fonts = editableRoot.querySelectorAll('font[size="7"]');
117
+ fonts.forEach(font => {
118
+ const span = document.createElement('span');
119
+ span.style.fontSize = size;
120
+ span.innerHTML = font.innerHTML;
121
+ font.replaceWith(span);
122
+ });
123
+ }
124
+ forceReselect();
125
+ }
126
+ function applyCode() {
127
+ wrapSelectionHtml('code');
128
+ }
129
+ /**
130
+ * Link insertion via inline input (prompt() is blocked in sandboxed iframes).
131
+ * The `linkInputContainer` ref is set by the factory below after the toolbar
132
+ * DOM is built.
133
+ */
134
+ let linkInputContainer = null;
135
+ let linkApplyCallback = null;
136
+ function applyLink() {
137
+ if (!linkInputContainer)
138
+ return;
139
+ saveSelection();
140
+ linkInputContainer.classList.add('md-tb-link-input--visible');
141
+ const input = linkInputContainer.querySelector('input');
142
+ if (input) {
143
+ input.value = 'https://';
144
+ input.focus();
145
+ input.select();
146
+ }
147
+ linkApplyCallback = (url) => {
148
+ if (!url)
149
+ return;
150
+ restoreSelection();
151
+ document.execCommand('createLink', false, url);
152
+ forceReselect();
153
+ };
154
+ }
155
+ // ---------------------------------------------------------------------------
156
+ // Toolbar DOM construction
157
+ // ---------------------------------------------------------------------------
158
+ function btn(icon, title, className = '') {
159
+ return `<button class="md-tb-btn ${className}" title="${title}" aria-label="${title}" type="button" tabindex="-1">${icon}</button>`;
160
+ }
161
+ function buildToolbarHTML() {
162
+ // Color swatches
163
+ const colorSwatches = COLORS.map(c => `<button class="md-tb-swatch${c.value === '' ? ' md-tb-swatch--default' : ''}" data-color="${c.value}" title="${c.label}" style="${c.value ? `background:${c.value}` : ''}" type="button" tabindex="-1">${c.value === '' ? '&times;' : ''}</button>`).join('');
164
+ // Font size options
165
+ const sizeOptions = FONT_SIZES.map(s => `<button class="md-tb-size-opt${s.value === '' ? ' md-tb-size-opt--active' : ''}" data-size="${s.value}" type="button" tabindex="-1">${s.label}</button>`).join('');
166
+ return `
167
+ <div class="md-tb-group">
168
+ ${btn(ICONS.bold, 'Bold (Ctrl+B)', 'md-tb-bold')}
169
+ ${btn(ICONS.italic, 'Italic (Ctrl+I)', 'md-tb-italic')}
170
+ ${btn(ICONS.strike, 'Strikethrough', 'md-tb-strike')}
171
+ ${btn(ICONS.code, 'Inline code', 'md-tb-code')}
172
+ ${btn(ICONS.link, 'Insert link (Ctrl+K)', 'md-tb-link')}
173
+ </div>
174
+ <div class="md-tb-sep"></div>
175
+ <div class="md-tb-group">
176
+ <div class="md-tb-dropdown">
177
+ <button class="md-tb-btn md-tb-color-trigger" title="Text color" aria-label="Text color" type="button" tabindex="-1">
178
+ ${ICONS.color}${ICONS.chevron}
179
+ </button>
180
+ <div class="md-tb-dropdown-panel md-tb-color-panel">${colorSwatches}</div>
181
+ </div>
182
+ <div class="md-tb-dropdown">
183
+ <button class="md-tb-btn md-tb-size-trigger" title="Font size" aria-label="Font size" type="button" tabindex="-1">
184
+ ${ICONS.fontSize}${ICONS.chevron}
185
+ </button>
186
+ <div class="md-tb-dropdown-panel md-tb-size-panel">${sizeOptions}</div>
187
+ </div>
188
+ </div>
189
+ <div class="md-tb-link-input">
190
+ <input type="text" class="md-tb-link-url" placeholder="https://" spellcheck="false" />
191
+ <button class="md-tb-link-apply" type="button" tabindex="-1">Go</button>
192
+ </div>
193
+ `;
194
+ }
195
+ export function createEditorToolbar(onFormatApplied) {
196
+ const el = document.createElement('div');
197
+ el.className = 'md-toolbar';
198
+ el.setAttribute('role', 'toolbar');
199
+ el.innerHTML = buildToolbarHTML();
200
+ // Wire up inline link input
201
+ linkInputContainer = el.querySelector('.md-tb-link-input');
202
+ const linkInput = el.querySelector('.md-tb-link-url');
203
+ const linkApplyBtn = el.querySelector('.md-tb-link-apply');
204
+ function commitLink() {
205
+ const url = linkInput?.value.trim();
206
+ linkInputContainer?.classList.remove('md-tb-link-input--visible');
207
+ if (url && linkApplyCallback) {
208
+ linkApplyCallback(url);
209
+ linkApplyCallback = null;
210
+ }
211
+ }
212
+ function cancelLink() {
213
+ linkInputContainer?.classList.remove('md-tb-link-input--visible');
214
+ linkApplyCallback = null;
215
+ restoreSelection();
216
+ }
217
+ linkApplyBtn?.addEventListener('click', commitLink);
218
+ linkInput?.addEventListener('keydown', (e) => {
219
+ if (e.key === 'Enter') {
220
+ e.preventDefault();
221
+ commitLink();
222
+ }
223
+ if (e.key === 'Escape') {
224
+ e.preventDefault();
225
+ cancelLink();
226
+ }
227
+ });
228
+ let visible = false;
229
+ let openDropdown = null;
230
+ // --- Positioning ---
231
+ function show(anchorRect, containerRect) {
232
+ if (!el.parentElement)
233
+ return;
234
+ visible = true;
235
+ el.classList.add('md-toolbar--visible');
236
+ // Measure toolbar
237
+ const tbWidth = el.offsetWidth || 320;
238
+ const tbHeight = el.offsetHeight || 40;
239
+ // Center above selection
240
+ let left = anchorRect.left + anchorRect.width / 2 - tbWidth / 2 - containerRect.left;
241
+ let top = anchorRect.top - tbHeight - 8 - containerRect.top + (el.parentElement?.scrollTop ?? 0);
242
+ // Clamp horizontal
243
+ left = Math.max(4, Math.min(left, containerRect.width - tbWidth - 4));
244
+ // If not enough space above, show below
245
+ if (anchorRect.top - containerRect.top < tbHeight + 12) {
246
+ top = anchorRect.bottom + 8 - containerRect.top + (el.parentElement?.scrollTop ?? 0);
247
+ }
248
+ el.style.left = `${left}px`;
249
+ el.style.top = `${top}px`;
250
+ }
251
+ function hide() {
252
+ visible = false;
253
+ el.classList.remove('md-toolbar--visible');
254
+ closeDropdown();
255
+ linkInputContainer?.classList.remove('md-tb-link-input--visible');
256
+ linkApplyCallback = null;
257
+ }
258
+ function closeDropdown() {
259
+ if (openDropdown) {
260
+ openDropdown.classList.remove('md-tb-dropdown--open');
261
+ openDropdown = null;
262
+ }
263
+ }
264
+ function toggleDropdown(dropdown) {
265
+ if (openDropdown === dropdown) {
266
+ closeDropdown();
267
+ return;
268
+ }
269
+ closeDropdown();
270
+ saveSelection();
271
+ openDropdown = dropdown;
272
+ dropdown.classList.add('md-tb-dropdown--open');
273
+ }
274
+ // --- Event handling ---
275
+ el.addEventListener('mousedown', (e) => {
276
+ const target = e.target;
277
+ // Let the link URL input receive focus normally
278
+ if (target.closest('.md-tb-link-input'))
279
+ return;
280
+ // Save the selection NOW — at mousedown time the browser hasn't
281
+ // cleared it yet. Every subsequent format operation will restore
282
+ // from this snapshot.
283
+ saveSelection();
284
+ // Prevent toolbar clicks from blurring the editable element
285
+ e.preventDefault();
286
+ });
287
+ el.addEventListener('click', (e) => {
288
+ const target = e.target;
289
+ const button = target.closest('button');
290
+ if (!button)
291
+ return;
292
+ // Dropdown triggers
293
+ const dropdown = button.closest('.md-tb-dropdown');
294
+ if (button.classList.contains('md-tb-color-trigger') || button.classList.contains('md-tb-size-trigger')) {
295
+ if (dropdown)
296
+ toggleDropdown(dropdown);
297
+ return;
298
+ }
299
+ // Color swatch
300
+ if (button.classList.contains('md-tb-swatch')) {
301
+ const color = button.dataset.color ?? '';
302
+ applyColor(color);
303
+ closeDropdown();
304
+ onFormatApplied?.();
305
+ return;
306
+ }
307
+ // Font size option
308
+ if (button.classList.contains('md-tb-size-opt')) {
309
+ const size = button.dataset.size ?? '';
310
+ applyFontSize(size);
311
+ closeDropdown();
312
+ onFormatApplied?.();
313
+ return;
314
+ }
315
+ // Inline format buttons
316
+ closeDropdown();
317
+ if (button.classList.contains('md-tb-bold')) {
318
+ execFormat('bold');
319
+ }
320
+ else if (button.classList.contains('md-tb-italic')) {
321
+ execFormat('italic');
322
+ }
323
+ else if (button.classList.contains('md-tb-strike')) {
324
+ execFormat('strikeThrough');
325
+ }
326
+ else if (button.classList.contains('md-tb-code')) {
327
+ applyCode();
328
+ }
329
+ else if (button.classList.contains('md-tb-link')) {
330
+ applyLink();
331
+ }
332
+ onFormatApplied?.();
333
+ });
334
+ // Close dropdown on outside click
335
+ function handleDocClick(e) {
336
+ if (openDropdown && !el.contains(e.target)) {
337
+ closeDropdown();
338
+ }
339
+ }
340
+ document.addEventListener('click', handleDocClick);
341
+ function destroy() {
342
+ document.removeEventListener('click', handleDocClick);
343
+ el.remove();
344
+ }
345
+ return {
346
+ element: el,
347
+ show,
348
+ hide,
349
+ destroy,
350
+ get isVisible() { return visible; },
351
+ get hasOpenDropdown() { return openDropdown !== null; },
352
+ };
353
+ }
354
+ // ---------------------------------------------------------------------------
355
+ // Keyboard shortcut handler (call from within contentEditable keydown)
356
+ // ---------------------------------------------------------------------------
357
+ export function handleFormatKeydown(e) {
358
+ const mod = e.metaKey || e.ctrlKey;
359
+ if (!mod)
360
+ return false;
361
+ switch (e.key.toLowerCase()) {
362
+ case 'b':
363
+ e.preventDefault();
364
+ saveSelection();
365
+ execFormat('bold');
366
+ return true;
367
+ case 'i':
368
+ e.preventDefault();
369
+ saveSelection();
370
+ execFormat('italic');
371
+ return true;
372
+ case 'k':
373
+ e.preventDefault();
374
+ applyLink();
375
+ return true;
376
+ case 'e':
377
+ e.preventDefault();
378
+ saveSelection();
379
+ applyCode();
380
+ return true;
381
+ default:
382
+ return false;
383
+ }
384
+ }
@@ -1,9 +1,5 @@
1
1
  import type { HtmlPreviewMode } from '../types.js';
2
- interface HtmlRenderOptions {
3
- allowUnsafeScripts?: boolean;
4
- }
5
- export declare function renderHtmlPreview(content: string, mode: HtmlPreviewMode, options?: HtmlRenderOptions): {
2
+ export declare function renderHtmlPreview(content: string, mode: HtmlPreviewMode): {
6
3
  html: string;
7
4
  notice?: string;
8
5
  };
9
- export {};
@@ -1,24 +1,13 @@
1
1
  /**
2
- * HTML preview renderer with guardrails for display modes. It controls when to show rendered HTML versus source text and ensures fallback behavior is predictable.
2
+ * HTML preview renderer with display mode control. It handles rendered HTML versus
3
+ * source text display and ensures fallback behavior is predictable.
4
+ *
5
+ * The rendered preview runs inside a nested sandboxed iframe, which is itself inside
6
+ * the MCP app's sandboxed iframe chain. Scripts and external resources (CDNs) are
7
+ * allowed since the sandbox isolation prevents any escape.
3
8
  */
4
9
  import { renderCodeViewer } from './code-viewer.js';
5
10
  import { escapeHtml } from './highlighting.js';
6
- function sanitizeHtml(rawHtml) {
7
- const blockedTagPattern = /<\/?(script|iframe|object|embed|link|meta|base|form)[^>]*>/gi;
8
- let safe = rawHtml.replace(blockedTagPattern, '');
9
- safe = safe.replace(/\son[a-z]+\s*=\s*(".*?"|'.*?'|[^\s>]+)/gi, '');
10
- safe = safe.replace(/\s(href|src)\s*=\s*(".*?"|'.*?'|[^\s>]+)/gi, (match, attr, value) => {
11
- const strippedValue = String(value).replace(/^['"]|['"]$/g, '').trim().toLowerCase();
12
- if (strippedValue.startsWith('javascript:')) {
13
- return ` ${attr}="#"`;
14
- }
15
- if (strippedValue.startsWith('data:text/html')) {
16
- return ` ${attr}="#"`;
17
- }
18
- return match;
19
- });
20
- return safe;
21
- }
22
11
  function resolveThemeFrameStyles() {
23
12
  if (typeof window === 'undefined' || typeof document === 'undefined') {
24
13
  return {
@@ -33,17 +22,12 @@ function resolveThemeFrameStyles() {
33
22
  const fontFamily = rootStyles.getPropertyValue('--font-sans').trim() || 'system-ui, sans-serif';
34
23
  return { background, text, fontFamily };
35
24
  }
36
- function renderSandboxedHtmlFrame(content, allowUnsafeScripts) {
37
- const htmlContent = allowUnsafeScripts ? content : sanitizeHtml(content);
38
- const csp = allowUnsafeScripts
39
- ? ''
40
- : `<meta http-equiv="Content-Security-Policy" content="default-src 'none'; img-src https: http: data:; style-src 'unsafe-inline';">`;
41
- const sandbox = allowUnsafeScripts ? 'allow-scripts allow-forms allow-popups' : '';
25
+ function renderSandboxedHtmlFrame(content) {
42
26
  const palette = resolveThemeFrameStyles();
43
- const frameDocument = `<!doctype html><html><head><meta charset="utf-8" />${csp}<style>html,body{margin:0;padding:0;background:${palette.background};color:${palette.text};}body{font-family:${palette.fontFamily};padding:16px;line-height:1.5;}img{max-width:100%;height:auto;}</style></head><body>${htmlContent}</body></html>`;
44
- return `<iframe class="html-rendered-frame" title="Rendered HTML preview" sandbox="${sandbox}" referrerpolicy="no-referrer" srcdoc="${escapeHtml(frameDocument)}"></iframe>`;
27
+ const frameDocument = `<!doctype html><html><head><meta charset="utf-8" /><style>html,body{margin:0;padding:0;background:${palette.background};color:${palette.text};}body{font-family:${palette.fontFamily};padding:16px;line-height:1.5;}img{max-width:100%;height:auto;}</style></head><body>${content}</body></html>`;
28
+ return `<iframe class="html-rendered-frame" title="Rendered HTML preview" sandbox="allow-scripts allow-forms allow-popups" referrerpolicy="no-referrer" srcdoc="${escapeHtml(frameDocument)}"></iframe>`;
45
29
  }
46
- export function renderHtmlPreview(content, mode, options = {}) {
30
+ export function renderHtmlPreview(content, mode) {
47
31
  if (mode === 'source') {
48
32
  return {
49
33
  html: `<div class="panel-content source-content">${renderCodeViewer(content, 'html')}</div>`
@@ -51,7 +35,7 @@ export function renderHtmlPreview(content, mode, options = {}) {
51
35
  }
52
36
  try {
53
37
  return {
54
- html: `<div class="panel-content html-content">${renderSandboxedHtmlFrame(content, options.allowUnsafeScripts === true)}</div>`
38
+ html: `<div class="panel-content html-content">${renderSandboxedHtmlFrame(content)}</div>`
55
39
  };
56
40
  }
57
41
  catch {
@@ -0,0 +1,29 @@
1
+ export interface MarkdownBlock {
2
+ type: 'heading' | 'paragraph' | 'list' | 'code' | 'blockquote' | 'hr' | 'table';
3
+ source: string;
4
+ startLine: number;
5
+ endLine: number;
6
+ level?: number;
7
+ listType?: 'ul' | 'ol';
8
+ editable: boolean;
9
+ }
10
+ export interface EditorCallbacks {
11
+ callTool: (name: string, args: Record<string, unknown>) => Promise<unknown>;
12
+ updateContext: (text: string) => void;
13
+ trackEvent?: (event: string, params?: Record<string, unknown>) => void;
14
+ }
15
+ export interface EditorHandle {
16
+ /** Remove all event listeners and toolbar DOM. */
17
+ cleanup: () => void;
18
+ /** True when a block is actively being edited (contentEditable is on). */
19
+ isEditing: () => boolean;
20
+ }
21
+ export declare function parseMarkdownBlocks(source: string): MarkdownBlock[];
22
+ export declare function renderEditableMarkdown(source: string): string;
23
+ /**
24
+ * Attach WYSIWYG editing handlers to editable markdown blocks inside
25
+ * the given container. All editable blocks are contentEditable from the
26
+ * start — users can select and type immediately without an activation
27
+ * click. Changes are committed when focus leaves the editor.
28
+ */
29
+ export declare function attachEditorHandlers(container: HTMLElement, source: string, filePath: string, callbacks: EditorCallbacks): EditorHandle;