@wonderwhy-er/desktop-commander 0.2.38 → 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 (364) hide show
  1. package/README.md +53 -2
  2. package/dist/handlers/filesystem-handlers.d.ts +5 -0
  3. package/dist/handlers/filesystem-handlers.js +14 -2
  4. package/dist/remote-device/desktop-commander-integration.js +1 -1
  5. package/dist/search-manager.js +31 -38
  6. package/dist/server.js +8 -3
  7. package/dist/terminal-manager.js +4 -2
  8. package/dist/tools/edit.js +34 -1
  9. package/dist/tools/filesystem.js +91 -3
  10. package/dist/tools/improved-process-tools.js +2 -1
  11. package/dist/ui/config-editor/app.js +840 -0
  12. package/dist/ui/config-editor/array-modal.d.ts +19 -0
  13. package/dist/ui/config-editor/array-modal.js +185 -0
  14. package/dist/ui/config-editor/config-editor-runtime.js +65 -14096
  15. package/dist/ui/config-editor/main.js +2 -0
  16. package/dist/ui/config-editor/src/App.d.ts +43 -0
  17. package/dist/ui/config-editor/src/components/layout.d.ts +4 -0
  18. package/dist/ui/config-editor/src/components/layout.js +83 -0
  19. package/dist/ui/config-editor/src/components/toolbar.d.ts +1 -0
  20. package/dist/ui/config-editor/src/components/toolbar.js +21 -0
  21. package/dist/ui/config-editor/src/config-values.d.ts +6 -0
  22. package/dist/ui/config-editor/src/config-values.js +61 -0
  23. package/dist/ui/config-editor/src/contracts.d.ts +14 -0
  24. package/dist/ui/config-editor/src/contracts.js +3 -0
  25. package/dist/ui/config-editor/src/directory-browser.d.ts +6 -0
  26. package/dist/ui/config-editor/src/directory-browser.js +71 -0
  27. package/dist/ui/config-editor/src/layout.d.ts +5 -0
  28. package/dist/ui/config-editor/src/layout.js +90 -0
  29. package/dist/ui/config-editor/src/parsing.d.ts +5 -0
  30. package/dist/ui/config-editor/src/parsing.js +50 -0
  31. package/dist/ui/config-editor/src/toolbar.d.ts +1 -0
  32. package/dist/ui/config-editor/src/toolbar.js +18 -0
  33. package/dist/ui/config-editor/src/types.d.ts +17 -0
  34. package/dist/ui/config-editor/src/types.js +3 -0
  35. package/dist/ui/config-editor/src/utils/config-values.d.ts +9 -0
  36. package/dist/ui/config-editor/src/utils/config-values.js +61 -0
  37. package/dist/ui/config-editor/src/utils/directory-browser.d.ts +31 -0
  38. package/dist/ui/config-editor/src/utils/directory-browser.js +201 -0
  39. package/dist/ui/config-editor/src/utils/parsing.d.ts +8 -0
  40. package/dist/ui/config-editor/src/utils/parsing.js +50 -0
  41. package/dist/ui/config-editor/styles.css +2 -1
  42. package/dist/ui/file-preview/{src/app.d.ts → app.d.ts} +1 -1
  43. package/dist/ui/file-preview/app.js +2020 -0
  44. package/dist/ui/file-preview/components/code-viewer.d.ts +6 -0
  45. package/dist/ui/file-preview/components/code-viewer.js +73 -0
  46. package/dist/ui/file-preview/components/highlighting.d.ts +2 -0
  47. package/dist/ui/file-preview/components/highlighting.js +54 -0
  48. package/dist/ui/file-preview/components/html-renderer.d.ts +5 -0
  49. package/dist/ui/file-preview/components/html-renderer.js +47 -0
  50. package/dist/ui/file-preview/components/markdown-renderer.d.ts +1 -0
  51. package/dist/ui/file-preview/components/markdown-renderer.js +67 -0
  52. package/dist/ui/file-preview/components/toolbar.d.ts +6 -0
  53. package/dist/ui/file-preview/components/toolbar.js +75 -0
  54. package/dist/ui/file-preview/image-preview.d.ts +3 -0
  55. package/dist/ui/file-preview/image-preview.js +21 -0
  56. package/dist/ui/file-preview/main.js +5 -0
  57. package/dist/ui/file-preview/markdown/editor.d.ts +36 -0
  58. package/dist/ui/file-preview/markdown/editor.js +643 -0
  59. package/dist/ui/file-preview/markdown/linking.d.ts +9 -0
  60. package/dist/ui/file-preview/markdown/linking.js +210 -0
  61. package/dist/ui/file-preview/markdown/outline.d.ts +7 -0
  62. package/dist/ui/file-preview/markdown/outline.js +40 -0
  63. package/dist/ui/file-preview/markdown/preview.d.ts +8 -0
  64. package/dist/ui/file-preview/markdown/preview.js +33 -0
  65. package/dist/ui/file-preview/markdown/slugify.d.ts +3 -0
  66. package/dist/ui/file-preview/markdown/slugify.js +31 -0
  67. package/dist/ui/file-preview/markdown/toc.d.ts +11 -0
  68. package/dist/ui/file-preview/markdown/toc.js +75 -0
  69. package/dist/ui/file-preview/markdown/utils.d.ts +1 -0
  70. package/dist/ui/file-preview/markdown/utils.js +15 -0
  71. package/dist/ui/file-preview/markdown/workspace-controller.d.ts +25 -0
  72. package/dist/ui/file-preview/markdown/workspace-controller.js +40 -0
  73. package/dist/ui/file-preview/preview-runtime.js +384 -26533
  74. package/dist/ui/file-preview/shared/preview-file-types.d.ts +1 -1
  75. package/dist/ui/file-preview/src/App.d.ts +4 -0
  76. package/dist/ui/file-preview/src/App.js +564 -0
  77. package/dist/ui/file-preview/src/components/CodeViewer.d.ts +6 -0
  78. package/dist/ui/file-preview/src/components/CodeViewer.js +60 -0
  79. package/dist/ui/file-preview/src/components/HtmlRenderer.d.ts +8 -0
  80. package/dist/ui/file-preview/src/components/HtmlRenderer.js +45 -0
  81. package/dist/ui/file-preview/src/components/MarkdownRenderer.d.ts +1 -0
  82. package/dist/ui/file-preview/src/components/MarkdownRenderer.js +15 -0
  83. package/dist/ui/file-preview/src/components/editor-toolbar.d.ts +15 -0
  84. package/dist/ui/file-preview/src/components/editor-toolbar.js +384 -0
  85. package/dist/ui/file-preview/src/components/markdown-editor.d.ts +29 -0
  86. package/dist/ui/file-preview/src/components/markdown-editor.js +535 -0
  87. package/dist/ui/file-preview/src/components/markdown-renderer.js +47 -9
  88. package/dist/ui/file-preview/src/directory-controller.d.ts +8 -0
  89. package/dist/ui/file-preview/src/directory-controller.js +233 -0
  90. package/dist/ui/file-preview/src/document-layout.d.ts +20 -0
  91. package/dist/ui/file-preview/src/document-layout.js +109 -0
  92. package/dist/ui/file-preview/src/document-outline.d.ts +17 -0
  93. package/dist/ui/file-preview/src/document-outline.js +97 -0
  94. package/dist/ui/file-preview/src/document-workspace.d.ts +19 -0
  95. package/dist/ui/file-preview/src/document-workspace.js +33 -0
  96. package/dist/ui/file-preview/src/file-type-handlers.d.ts +10 -0
  97. package/dist/ui/file-preview/src/file-type-handlers.js +98 -0
  98. package/dist/ui/file-preview/src/host/external-actions.d.ts +19 -0
  99. package/dist/ui/file-preview/src/host/external-actions.js +94 -0
  100. package/dist/ui/file-preview/src/host/selection-context.d.ts +9 -0
  101. package/dist/ui/file-preview/src/host/selection-context.js +106 -0
  102. package/dist/ui/file-preview/src/markdown/block-merge.d.ts +25 -0
  103. package/dist/ui/file-preview/src/markdown/block-merge.js +86 -0
  104. package/dist/ui/file-preview/src/markdown/conflict-dialog.d.ts +40 -0
  105. package/dist/ui/file-preview/src/markdown/conflict-dialog.js +163 -0
  106. package/dist/ui/file-preview/src/markdown/controller.d.ts +38 -0
  107. package/dist/ui/file-preview/src/markdown/controller.js +921 -0
  108. package/dist/ui/file-preview/src/markdown/editor.d.ts +35 -0
  109. package/dist/ui/file-preview/src/markdown/editor.js +691 -0
  110. package/dist/ui/file-preview/src/markdown/link-modal.d.ts +13 -0
  111. package/dist/ui/file-preview/src/markdown/link-modal.js +213 -0
  112. package/dist/ui/file-preview/src/markdown/linking.d.ts +16 -0
  113. package/dist/ui/file-preview/src/markdown/linking.js +228 -0
  114. package/dist/ui/file-preview/src/markdown/outline.d.ts +2 -0
  115. package/dist/ui/file-preview/src/markdown/outline.js +16 -0
  116. package/dist/ui/file-preview/src/markdown/parser.d.ts +30 -0
  117. package/dist/ui/file-preview/src/markdown/parser.js +38 -0
  118. package/dist/ui/file-preview/src/markdown/preview.d.ts +1 -0
  119. package/dist/ui/file-preview/src/markdown/preview.js +20 -0
  120. package/dist/ui/file-preview/src/markdown/raw-editor.d.ts +8 -0
  121. package/dist/ui/file-preview/src/markdown/raw-editor.js +61 -0
  122. package/dist/ui/file-preview/src/markdown/selection-toolbar.d.ts +14 -0
  123. package/dist/ui/file-preview/src/markdown/selection-toolbar.js +128 -0
  124. package/dist/ui/file-preview/src/markdown/slugify.d.ts +3 -0
  125. package/dist/ui/file-preview/src/markdown/slugify.js +31 -0
  126. package/dist/ui/file-preview/src/markdown/toc.d.ts +11 -0
  127. package/dist/ui/file-preview/src/markdown/toc.js +75 -0
  128. package/dist/ui/file-preview/src/markdown/utils.d.ts +1 -0
  129. package/dist/ui/file-preview/src/markdown/utils.js +15 -0
  130. package/dist/ui/file-preview/src/markdown-workspace/editor.d.ts +36 -0
  131. package/dist/ui/file-preview/src/markdown-workspace/editor.js +643 -0
  132. package/dist/ui/file-preview/src/markdown-workspace/linking.d.ts +9 -0
  133. package/dist/ui/file-preview/src/markdown-workspace/linking.js +210 -0
  134. package/dist/ui/file-preview/src/markdown-workspace/outline.d.ts +7 -0
  135. package/dist/ui/file-preview/src/markdown-workspace/outline.js +40 -0
  136. package/dist/ui/file-preview/src/markdown-workspace/preview.d.ts +8 -0
  137. package/dist/ui/file-preview/src/markdown-workspace/preview.js +33 -0
  138. package/dist/ui/file-preview/src/markdown-workspace/slugify.d.ts +3 -0
  139. package/dist/ui/file-preview/src/markdown-workspace/slugify.js +31 -0
  140. package/dist/ui/file-preview/src/markdown-workspace/toc.d.ts +11 -0
  141. package/dist/ui/file-preview/src/markdown-workspace/toc.js +75 -0
  142. package/dist/ui/file-preview/src/markdown-workspace/utils.d.ts +1 -0
  143. package/dist/ui/file-preview/src/markdown-workspace/utils.js +15 -0
  144. package/dist/ui/file-preview/src/markdown-workspace/workspace-controller.d.ts +25 -0
  145. package/dist/ui/file-preview/src/markdown-workspace/workspace-controller.js +40 -0
  146. package/dist/ui/file-preview/src/model.d.ts +34 -0
  147. package/dist/ui/file-preview/src/panel-actions.d.ts +17 -0
  148. package/dist/ui/file-preview/src/panel-actions.js +182 -0
  149. package/dist/ui/file-preview/src/path-utils.d.ts +6 -0
  150. package/dist/ui/file-preview/src/path-utils.js +64 -0
  151. package/dist/ui/file-preview/src/payload-utils.d.ts +11 -0
  152. package/dist/ui/file-preview/src/payload-utils.js +94 -0
  153. package/dist/ui/file-preview/styles.css +1066 -233
  154. package/dist/ui/file-preview/types.d.ts +1 -0
  155. package/dist/ui/server-integration.d.ts +13 -0
  156. package/dist/ui/server-integration.js +31 -0
  157. package/dist/ui/shared/ToolHeader.d.ts +9 -0
  158. package/dist/ui/shared/ToolHeader.js +29 -0
  159. package/dist/ui/shared/app-bootstrap.d.ts +9 -0
  160. package/dist/ui/shared/app-bootstrap.js +15 -0
  161. package/dist/ui/shared/guards.d.ts +1 -0
  162. package/dist/ui/shared/guards.js +3 -0
  163. package/dist/ui/shared/host-lifecycle.d.ts +1 -0
  164. package/dist/ui/shared/host-lifecycle.js +8 -2
  165. package/dist/ui/shared/widget-state.d.ts +6 -1
  166. package/dist/ui/shared/widget-state.js +102 -4
  167. package/dist/utils/files/base.d.ts +2 -0
  168. package/dist/utils/open-browser.js +1 -1
  169. package/dist/utils/ui-call-context.d.ts +8 -0
  170. package/dist/utils/ui-call-context.js +72 -0
  171. package/dist/version.d.ts +1 -1
  172. package/dist/version.js +1 -1
  173. package/package.json +6 -1
  174. package/dist/data/spec-kit-prompts.json +0 -123
  175. package/dist/handlers/macos-control-handlers.d.ts +0 -16
  176. package/dist/handlers/macos-control-handlers.js +0 -81
  177. package/dist/handlers/node-handlers.d.ts +0 -6
  178. package/dist/handlers/node-handlers.js +0 -73
  179. package/dist/handlers/test-crash-handler.d.ts +0 -11
  180. package/dist/handlers/test-crash-handler.js +0 -26
  181. package/dist/http-index.d.ts +0 -45
  182. package/dist/http-index.js +0 -51
  183. package/dist/http-server-auto-tunnel.js +0 -667
  184. package/dist/http-server-named-tunnel.d.ts +0 -2
  185. package/dist/http-server-named-tunnel.js +0 -167
  186. package/dist/http-server-tunnel.d.ts +0 -2
  187. package/dist/http-server-tunnel.js +0 -111
  188. package/dist/http-server.d.ts +0 -2
  189. package/dist/http-server.js +0 -270
  190. package/dist/index-oauth.d.ts +0 -2
  191. package/dist/index-oauth.js +0 -201
  192. package/dist/lib.d.ts +0 -10
  193. package/dist/lib.js +0 -10
  194. package/dist/oauth/auth-middleware.d.ts +0 -20
  195. package/dist/oauth/auth-middleware.js +0 -62
  196. package/dist/oauth/index.d.ts +0 -3
  197. package/dist/oauth/index.js +0 -3
  198. package/dist/oauth/oauth-manager.d.ts +0 -80
  199. package/dist/oauth/oauth-manager.js +0 -179
  200. package/dist/oauth/oauth-routes.d.ts +0 -3
  201. package/dist/oauth/oauth-routes.js +0 -377
  202. package/dist/oauth/provider.d.ts +0 -22
  203. package/dist/oauth/provider.js +0 -124
  204. package/dist/oauth/server.d.ts +0 -18
  205. package/dist/oauth/server.js +0 -160
  206. package/dist/oauth/types.d.ts +0 -54
  207. package/dist/oauth/types.js +0 -2
  208. package/dist/remote-device/templates/auth-success.d.ts +0 -1
  209. package/dist/remote-device/templates/auth-success.js +0 -30
  210. package/dist/setup.log +0 -275
  211. package/dist/test-setup.js +0 -14
  212. package/dist/tools/docx/builders/html-builder.d.ts +0 -17
  213. package/dist/tools/docx/builders/html-builder.js +0 -92
  214. package/dist/tools/docx/builders/image.d.ts +0 -14
  215. package/dist/tools/docx/builders/image.js +0 -84
  216. package/dist/tools/docx/builders/index.d.ts +0 -11
  217. package/dist/tools/docx/builders/index.js +0 -11
  218. package/dist/tools/docx/builders/markdown-builder.d.ts +0 -2
  219. package/dist/tools/docx/builders/markdown-builder.js +0 -260
  220. package/dist/tools/docx/builders/paragraph.d.ts +0 -12
  221. package/dist/tools/docx/builders/paragraph.js +0 -29
  222. package/dist/tools/docx/builders/table.d.ts +0 -10
  223. package/dist/tools/docx/builders/table.js +0 -138
  224. package/dist/tools/docx/builders/utils.d.ts +0 -5
  225. package/dist/tools/docx/builders/utils.js +0 -18
  226. package/dist/tools/docx/constants.d.ts +0 -32
  227. package/dist/tools/docx/constants.js +0 -61
  228. package/dist/tools/docx/converters/markdown-to-html.d.ts +0 -17
  229. package/dist/tools/docx/converters/markdown-to-html.js +0 -111
  230. package/dist/tools/docx/create.d.ts +0 -21
  231. package/dist/tools/docx/create.js +0 -386
  232. package/dist/tools/docx/dom.d.ts +0 -139
  233. package/dist/tools/docx/dom.js +0 -448
  234. package/dist/tools/docx/errors.d.ts +0 -28
  235. package/dist/tools/docx/errors.js +0 -48
  236. package/dist/tools/docx/extractors/images.d.ts +0 -14
  237. package/dist/tools/docx/extractors/images.js +0 -40
  238. package/dist/tools/docx/extractors/metadata.d.ts +0 -14
  239. package/dist/tools/docx/extractors/metadata.js +0 -64
  240. package/dist/tools/docx/extractors/sections.d.ts +0 -14
  241. package/dist/tools/docx/extractors/sections.js +0 -61
  242. package/dist/tools/docx/html.d.ts +0 -17
  243. package/dist/tools/docx/html.js +0 -111
  244. package/dist/tools/docx/index.d.ts +0 -10
  245. package/dist/tools/docx/index.js +0 -10
  246. package/dist/tools/docx/markdown.d.ts +0 -84
  247. package/dist/tools/docx/markdown.js +0 -507
  248. package/dist/tools/docx/modify.d.ts +0 -28
  249. package/dist/tools/docx/modify.js +0 -271
  250. package/dist/tools/docx/operations/handlers/index.d.ts +0 -39
  251. package/dist/tools/docx/operations/handlers/index.js +0 -152
  252. package/dist/tools/docx/operations/html-manipulator.d.ts +0 -24
  253. package/dist/tools/docx/operations/html-manipulator.js +0 -352
  254. package/dist/tools/docx/operations/index.d.ts +0 -14
  255. package/dist/tools/docx/operations/index.js +0 -61
  256. package/dist/tools/docx/operations/operation-handlers.d.ts +0 -3
  257. package/dist/tools/docx/operations/operation-handlers.js +0 -67
  258. package/dist/tools/docx/operations/preprocessor.d.ts +0 -14
  259. package/dist/tools/docx/operations/preprocessor.js +0 -44
  260. package/dist/tools/docx/operations/xml-replacer.d.ts +0 -9
  261. package/dist/tools/docx/operations/xml-replacer.js +0 -35
  262. package/dist/tools/docx/operations.d.ts +0 -13
  263. package/dist/tools/docx/operations.js +0 -13
  264. package/dist/tools/docx/ops/delete-paragraph-at-body-index.d.ts +0 -11
  265. package/dist/tools/docx/ops/delete-paragraph-at-body-index.js +0 -23
  266. package/dist/tools/docx/ops/header-replace-text-exact.d.ts +0 -13
  267. package/dist/tools/docx/ops/header-replace-text-exact.js +0 -55
  268. package/dist/tools/docx/ops/index.d.ts +0 -17
  269. package/dist/tools/docx/ops/index.js +0 -70
  270. package/dist/tools/docx/ops/insert-image-after-text.d.ts +0 -24
  271. package/dist/tools/docx/ops/insert-image-after-text.js +0 -128
  272. package/dist/tools/docx/ops/insert-paragraph-after-text.d.ts +0 -12
  273. package/dist/tools/docx/ops/insert-paragraph-after-text.js +0 -74
  274. package/dist/tools/docx/ops/insert-table-after-text.d.ts +0 -19
  275. package/dist/tools/docx/ops/insert-table-after-text.js +0 -57
  276. package/dist/tools/docx/ops/replace-hyperlink-url.d.ts +0 -12
  277. package/dist/tools/docx/ops/replace-hyperlink-url.js +0 -37
  278. package/dist/tools/docx/ops/replace-paragraph-at-body-index.d.ts +0 -9
  279. package/dist/tools/docx/ops/replace-paragraph-at-body-index.js +0 -25
  280. package/dist/tools/docx/ops/replace-paragraph-text-exact.d.ts +0 -21
  281. package/dist/tools/docx/ops/replace-paragraph-text-exact.js +0 -36
  282. package/dist/tools/docx/ops/replace-table-cell-text.d.ts +0 -25
  283. package/dist/tools/docx/ops/replace-table-cell-text.js +0 -85
  284. package/dist/tools/docx/ops/set-color-for-paragraph-exact.d.ts +0 -9
  285. package/dist/tools/docx/ops/set-color-for-paragraph-exact.js +0 -24
  286. package/dist/tools/docx/ops/set-color-for-style.d.ts +0 -13
  287. package/dist/tools/docx/ops/set-color-for-style.js +0 -31
  288. package/dist/tools/docx/ops/set-paragraph-style-at-body-index.d.ts +0 -8
  289. package/dist/tools/docx/ops/set-paragraph-style-at-body-index.js +0 -57
  290. package/dist/tools/docx/ops/table-set-cell-text.d.ts +0 -9
  291. package/dist/tools/docx/ops/table-set-cell-text.js +0 -40
  292. package/dist/tools/docx/parsers/image-extractor.d.ts +0 -18
  293. package/dist/tools/docx/parsers/image-extractor.js +0 -61
  294. package/dist/tools/docx/parsers/index.d.ts +0 -9
  295. package/dist/tools/docx/parsers/index.js +0 -9
  296. package/dist/tools/docx/parsers/paragraph-parser.d.ts +0 -2
  297. package/dist/tools/docx/parsers/paragraph-parser.js +0 -88
  298. package/dist/tools/docx/parsers/table-parser.d.ts +0 -9
  299. package/dist/tools/docx/parsers/table-parser.js +0 -72
  300. package/dist/tools/docx/parsers/xml-parser.d.ts +0 -25
  301. package/dist/tools/docx/parsers/xml-parser.js +0 -71
  302. package/dist/tools/docx/parsers/zip-reader.d.ts +0 -23
  303. package/dist/tools/docx/parsers/zip-reader.js +0 -52
  304. package/dist/tools/docx/read.d.ts +0 -27
  305. package/dist/tools/docx/read.js +0 -308
  306. package/dist/tools/docx/relationships.d.ts +0 -22
  307. package/dist/tools/docx/relationships.js +0 -76
  308. package/dist/tools/docx/structure.d.ts +0 -25
  309. package/dist/tools/docx/structure.js +0 -102
  310. package/dist/tools/docx/styled-html-parser.d.ts +0 -23
  311. package/dist/tools/docx/styled-html-parser.js +0 -1262
  312. package/dist/tools/docx/types.d.ts +0 -213
  313. package/dist/tools/docx/types.js +0 -5
  314. package/dist/tools/docx/utils/escaping.d.ts +0 -13
  315. package/dist/tools/docx/utils/escaping.js +0 -26
  316. package/dist/tools/docx/utils/images.d.ts +0 -9
  317. package/dist/tools/docx/utils/images.js +0 -26
  318. package/dist/tools/docx/utils/index.d.ts +0 -12
  319. package/dist/tools/docx/utils/index.js +0 -17
  320. package/dist/tools/docx/utils/markdown.d.ts +0 -13
  321. package/dist/tools/docx/utils/markdown.js +0 -32
  322. package/dist/tools/docx/utils/paths.d.ts +0 -15
  323. package/dist/tools/docx/utils/paths.js +0 -27
  324. package/dist/tools/docx/utils/versioning.d.ts +0 -25
  325. package/dist/tools/docx/utils/versioning.js +0 -55
  326. package/dist/tools/docx/utils.d.ts +0 -101
  327. package/dist/tools/docx/utils.js +0 -299
  328. package/dist/tools/docx/validate.d.ts +0 -33
  329. package/dist/tools/docx/validate.js +0 -49
  330. package/dist/tools/docx/validators.d.ts +0 -13
  331. package/dist/tools/docx/validators.js +0 -40
  332. package/dist/tools/docx/write.d.ts +0 -17
  333. package/dist/tools/docx/write.js +0 -88
  334. package/dist/tools/docx/xml-view-test.js +0 -63
  335. package/dist/tools/docx/xml-view.d.ts +0 -56
  336. package/dist/tools/docx/xml-view.js +0 -169
  337. package/dist/tools/docx/zip.d.ts +0 -21
  338. package/dist/tools/docx/zip.js +0 -35
  339. package/dist/tools/macos-control/ax-adapter.d.ts +0 -55
  340. package/dist/tools/macos-control/ax-adapter.js +0 -438
  341. package/dist/tools/macos-control/cdp-adapter.d.ts +0 -23
  342. package/dist/tools/macos-control/cdp-adapter.js +0 -402
  343. package/dist/tools/macos-control/orchestrator.d.ts +0 -77
  344. package/dist/tools/macos-control/orchestrator.js +0 -136
  345. package/dist/tools/macos-control/role-aliases.d.ts +0 -5
  346. package/dist/tools/macos-control/role-aliases.js +0 -34
  347. package/dist/tools/macos-control/types.d.ts +0 -129
  348. package/dist/tools/pdf-processor.d.ts +0 -1
  349. package/dist/tools/pdf-processor.js +0 -3
  350. package/dist/tools/search.d.ts +0 -32
  351. package/dist/tools/search.js +0 -202
  352. package/dist/ui/file-preview/src/app.js +0 -714
  353. package/dist/utils/crash-logger.d.ts +0 -18
  354. package/dist/utils/crash-logger.js +0 -44
  355. package/dist/utils/dedent.d.ts +0 -8
  356. package/dist/utils/dedent.js +0 -38
  357. /package/dist/ui/config-editor/{src/app.d.ts → app.d.ts} +0 -0
  358. /package/dist/{http-server-auto-tunnel.d.ts → ui/config-editor/main.d.ts} +0 -0
  359. /package/dist/ui/config-editor/src/{app.js → App.js} +0 -0
  360. /package/dist/{test-docx.d.ts → ui/file-preview/main.d.ts} +0 -0
  361. /package/dist/ui/file-preview/src/components/{toolbar.d.ts → Toolbar.d.ts} +0 -0
  362. /package/dist/ui/file-preview/src/components/{toolbar.js → Toolbar.js} +0 -0
  363. /package/dist/{tools/docx/xml-view-test.d.ts → ui/file-preview/src/model.js} +0 -0
  364. /package/dist/{tools/macos-control → ui/file-preview}/types.js +0 -0
@@ -1,4 +1,4 @@
1
- export type PreviewFileType = 'markdown' | 'text' | 'html' | 'image' | 'unsupported';
1
+ export type PreviewFileType = 'markdown' | 'text' | 'html' | 'image' | 'directory' | 'unsupported';
2
2
  export declare const MARKDOWN_PREVIEW_EXTENSIONS: Set<string>;
3
3
  export declare const HTML_PREVIEW_EXTENSIONS: Set<string>;
4
4
  export declare const TEXT_PREVIEW_EXTENSIONS: Set<string>;
@@ -0,0 +1,4 @@
1
+ import type { RenderPayload } from './model.js';
2
+ import type { HtmlPreviewMode } from './types.js';
3
+ export declare function renderApp(container: HTMLElement, payload?: RenderPayload, htmlMode?: HtmlPreviewMode, expandedState?: boolean): void;
4
+ export declare function bootstrapApp(): void;
@@ -0,0 +1,564 @@
1
+ /**
2
+ * Composition root for the File Preview app. It wires host services, file-type handlers, and specialized controllers together without owning feature logic inline.
3
+ */
4
+ import { App } from '@modelcontextprotocol/ext-apps';
5
+ import { createCompactRowShellController } from '../../shared/tool-shell.js';
6
+ import { createWidgetStateStorage } from '../../shared/widget-state.js';
7
+ import { renderCompactRow } from '../../shared/compact-row.js';
8
+ import { connectWithSharedHostContext } from '../../shared/host-context.js';
9
+ import { createUiEventTracker } from '../../shared/ui-event-tracker.js';
10
+ import { attachDirectoryHandlers } from './directory-controller.js';
11
+ import { buildDocumentLayout } from './document-layout.js';
12
+ import { getDocumentFullscreenAvailability, parseReadRange, stripReadStatusLine } from './document-workspace.js';
13
+ import { getFileTypeCapabilities, renderPayloadBody } from './file-type-handlers.js';
14
+ import { buildOpenInEditorCommand, buildOpenInFolderCommand, detectDefaultMarkdownEditor, renderMarkdownEditorAppIcon } from './host/external-actions.js';
15
+ import { attachSelectionContext } from './host/selection-context.js';
16
+ import { createMarkdownController } from './markdown/controller.js';
17
+ import { createConflictDialogController, renderConflictDialogMarkup, } from './markdown/conflict-dialog.js';
18
+ import { attachPanelActions } from './panel-actions.js';
19
+ import { extractRenderPayload, extractToolText, getFileExtensionForAnalytics, isLikelyUrl, isPreviewStructuredContent } from './payload-utils.js';
20
+ let isExpanded = false;
21
+ let hideSummaryRow = false;
22
+ let previewShownFired = false;
23
+ let onRender;
24
+ let trackUiEvent;
25
+ let conflictDialogController;
26
+ let rpcCallTool;
27
+ let rpcUpdateContext;
28
+ let openExternalLink;
29
+ let requestDisplayMode;
30
+ let shellController;
31
+ let currentPayload;
32
+ let currentHtmlMode = 'rendered';
33
+ let currentHostContext;
34
+ let rerenderCurrent;
35
+ let syncPayload;
36
+ let persistPayload;
37
+ let localPayloadOverride;
38
+ let hostPayload;
39
+ let inlinePayloadBeforeFullscreen;
40
+ let directoryBackPayload;
41
+ let selectionAbortController = null;
42
+ const markdownEditorAppCache = new Map();
43
+ const markdownEditorAppPending = new Set();
44
+ async function callToolIfReady(name, args) {
45
+ return rpcCallTool ? rpcCallTool(name, args) : undefined;
46
+ }
47
+ function getAvailableDisplayModes() {
48
+ const rawModes = currentHostContext?.availableDisplayModes;
49
+ if (!Array.isArray(rawModes)) {
50
+ return [];
51
+ }
52
+ return rawModes.filter((mode) => typeof mode === 'string');
53
+ }
54
+ function getCurrentDisplayMode() {
55
+ return typeof currentHostContext?.displayMode === 'string'
56
+ ? currentHostContext.displayMode
57
+ : null;
58
+ }
59
+ function storePayloadOverride(payload) {
60
+ localPayloadOverride = payload;
61
+ currentPayload = payload;
62
+ persistPayload?.(payload);
63
+ }
64
+ function getEffectiveIncomingPayload(payload) {
65
+ if (!localPayloadOverride) {
66
+ return payload;
67
+ }
68
+ if (localPayloadOverride.filePath !== payload.filePath) {
69
+ localPayloadOverride = undefined;
70
+ return payload;
71
+ }
72
+ const incomingContent = stripReadStatusLine(payload.content);
73
+ const overriddenContent = stripReadStatusLine(localPayloadOverride.content);
74
+ if (incomingContent === overriddenContent) {
75
+ return payload;
76
+ }
77
+ return localPayloadOverride;
78
+ }
79
+ function updateSaveStatusDOM(label, statusClass) {
80
+ const existing = document.querySelector('.panel-save-status');
81
+ if (label) {
82
+ if (existing) {
83
+ existing.textContent = label;
84
+ existing.className = `panel-save-status panel-save-status--${statusClass}`;
85
+ }
86
+ else {
87
+ const actions = document.querySelector('.panel-topbar-actions');
88
+ if (actions) {
89
+ const span = document.createElement('span');
90
+ span.className = `panel-save-status panel-save-status--${statusClass}`;
91
+ span.textContent = label;
92
+ actions.prepend(span);
93
+ }
94
+ }
95
+ }
96
+ else if (existing) {
97
+ existing.remove();
98
+ }
99
+ }
100
+ const markdownController = createMarkdownController({
101
+ callTool: callToolIfReady,
102
+ openExternalLink: async (url) => (openExternalLink ? openExternalLink(url) : undefined),
103
+ requestDisplayMode: async (mode) => (requestDisplayMode ? requestDisplayMode(mode) : undefined),
104
+ getAvailableDisplayModes,
105
+ getCurrentDisplayMode,
106
+ getCurrentPayload: () => currentPayload,
107
+ setExpanded: (expanded) => {
108
+ isExpanded = expanded;
109
+ },
110
+ syncPayload: (payload) => syncPayload?.(payload),
111
+ storePayloadOverride,
112
+ rerender: () => {
113
+ rerenderCurrent?.();
114
+ },
115
+ updateSaveStatus: updateSaveStatusDOM,
116
+ trackUiEvent: (event, params) => trackUiEvent?.(event, params),
117
+ showConflictDialog: (options) => {
118
+ if (conflictDialogController) {
119
+ conflictDialogController.open(options);
120
+ return;
121
+ }
122
+ // Dialog not yet initialized (would only happen if the save failure
123
+ // somehow fires before bootstrapApp). Fall back to the cancel callback
124
+ // so the editor still shows its inline note instead of silently no-op'ing.
125
+ console.warn('[file-preview] conflictDialogController not ready; firing onCancel fallback');
126
+ options.onCancel?.();
127
+ },
128
+ });
129
+ /**
130
+ * Check if a payload needs its file content to be read.
131
+ * Tool results from edit_block/write_file include structuredContent but
132
+ * their text is a success message, not file content. Detect this by
133
+ * checking for the absence of the read status line that read_file always includes.
134
+ * URL payloads are fetched remotely by read_file(isUrl:true); we can't
135
+ * re-fetch them from here (no isUrl flag on the refresh path), so skip.
136
+ */
137
+ function needsContentRead(payload) {
138
+ if (payload.fileType === 'directory' || payload.fileType === 'image' || payload.fileType === 'unsupported') {
139
+ return false;
140
+ }
141
+ if (/^https?:\/\//i.test(payload.filePath)) {
142
+ return false;
143
+ }
144
+ return !parseReadRange(payload.content);
145
+ }
146
+ async function readAndResolvePayload(payload, onReady) {
147
+ try {
148
+ const freshPayload = await markdownController.readPayload(payload.filePath);
149
+ if (freshPayload) {
150
+ onReady(freshPayload);
151
+ if (freshPayload.fileType === 'markdown') {
152
+ void markdownController.refreshFromDisk(freshPayload);
153
+ }
154
+ return;
155
+ }
156
+ }
157
+ catch {
158
+ // Fall through to original payload.
159
+ }
160
+ onReady(payload);
161
+ }
162
+ function renderStatusState(container, message) {
163
+ container.innerHTML = `
164
+ <main class="shell">
165
+ ${renderCompactRow({ label: message, variant: 'status', interactive: false })}
166
+ </main>
167
+ `;
168
+ document.body.classList.add('dc-ready');
169
+ }
170
+ function renderLoadingState(container) {
171
+ container.innerHTML = `
172
+ <main class="shell">
173
+ ${renderCompactRow({ label: 'Preparing preview…', variant: 'loading', interactive: false })}
174
+ </main>
175
+ `;
176
+ document.body.classList.add('dc-ready');
177
+ }
178
+ export function renderApp(container, payload, htmlMode = 'rendered', expandedState = false) {
179
+ isExpanded = expandedState;
180
+ currentHtmlMode = htmlMode;
181
+ shellController?.dispose();
182
+ shellController = undefined;
183
+ if (!payload || payload.fileType !== 'markdown') {
184
+ markdownController.clear();
185
+ }
186
+ else {
187
+ markdownController.disposeHandles();
188
+ }
189
+ if (!payload) {
190
+ selectionAbortController?.abort();
191
+ selectionAbortController = null;
192
+ currentPayload = undefined;
193
+ renderStatusState(container, 'No preview available for this response.');
194
+ onRender?.();
195
+ return;
196
+ }
197
+ currentPayload = payload;
198
+ const capabilities = getFileTypeCapabilities(payload);
199
+ if (!capabilities.supportsPreview && hideSummaryRow) {
200
+ isExpanded = false;
201
+ }
202
+ const range = parseReadRange(payload.content);
203
+ const body = renderPayloadBody({
204
+ payload,
205
+ htmlMode,
206
+ startLine: range?.fromLine ?? 1,
207
+ markdownController,
208
+ });
209
+ const markdownWorkspace = payload.fileType === 'markdown' ? markdownController.getState(payload) : undefined;
210
+ const fileExtension = getFileExtensionForAnalytics(payload.filePath);
211
+ const isFullscreen = getCurrentDisplayMode() === 'fullscreen';
212
+ const canGoFullscreen = !isFullscreen && getDocumentFullscreenAvailability({
213
+ availableDisplayModes: getAvailableDisplayModes(),
214
+ }).canFullscreen;
215
+ const defaultMarkdownEditor = payload.fileType === 'markdown'
216
+ ? markdownEditorAppCache.get(payload.filePath)
217
+ : undefined;
218
+ if (payload.fileType === 'markdown' && !defaultMarkdownEditor) {
219
+ void detectDefaultMarkdownEditor({
220
+ filePath: payload.filePath,
221
+ editorAppCache: markdownEditorAppCache,
222
+ editorAppPending: markdownEditorAppPending,
223
+ callTool: callToolIfReady,
224
+ extractToolText,
225
+ onDetected: () => {
226
+ rerenderCurrent?.();
227
+ },
228
+ });
229
+ }
230
+ const layout = buildDocumentLayout({
231
+ payload,
232
+ body,
233
+ capabilities,
234
+ fileExtension,
235
+ htmlMode,
236
+ currentDisplayMode: getCurrentDisplayMode(),
237
+ isExpanded,
238
+ hideSummaryRow,
239
+ markdownWorkspace,
240
+ canGoFullscreen,
241
+ isMarkdownUndoAvailable: markdownWorkspace ? markdownController.isUndoAvailable(markdownWorkspace) : false,
242
+ defaultMarkdownEditorName: defaultMarkdownEditor?.appName,
243
+ markdownEditorAppIcon: renderMarkdownEditorAppIcon(),
244
+ hasDirectoryBackButton: Boolean(directoryBackPayload),
245
+ });
246
+ container.innerHTML = layout.html;
247
+ document.body.classList.add('dc-ready');
248
+ attachPanelActions({
249
+ container,
250
+ payload,
251
+ htmlMode,
252
+ getIsExpanded: () => isExpanded,
253
+ callTool: callToolIfReady,
254
+ trackUiEvent,
255
+ getFileExtensionForAnalytics,
256
+ buildOpenInFolderCommand: (filePath) => buildOpenInFolderCommand(filePath, isLikelyUrl),
257
+ buildOpenInEditorCommand: (filePath) => buildOpenInEditorCommand(filePath, isLikelyUrl, markdownEditorAppCache),
258
+ render: (nextPayload, nextHtmlMode = 'rendered', nextExpanded = isExpanded) => {
259
+ renderApp(container, nextPayload, nextHtmlMode, nextExpanded);
260
+ },
261
+ updateSaveStatus: updateSaveStatusDOM,
262
+ markdownController,
263
+ });
264
+ if (payload.fileType === 'markdown') {
265
+ markdownController.attachHandlers(payload);
266
+ }
267
+ selectionAbortController = attachSelectionContext({
268
+ payload,
269
+ isMarkdownEditing: payload.fileType === 'markdown' && !!markdownWorkspace,
270
+ updateContext: rpcUpdateContext,
271
+ trackUiEvent,
272
+ getFileExtensionForAnalytics,
273
+ previousAbortController: selectionAbortController,
274
+ });
275
+ if (payload.fileType === 'directory') {
276
+ attachDirectoryHandlers({
277
+ container,
278
+ callTool: callToolIfReady,
279
+ buildOpenInFolderCommand: (filePath) => buildOpenInFolderCommand(filePath, isLikelyUrl),
280
+ onOpenPayload: (nextPayload) => {
281
+ directoryBackPayload = payload;
282
+ renderApp(container, nextPayload, 'rendered', true);
283
+ },
284
+ });
285
+ }
286
+ const backBtn = document.getElementById('dir-back');
287
+ if (backBtn && directoryBackPayload) {
288
+ const savedPayload = directoryBackPayload;
289
+ backBtn.addEventListener('click', () => {
290
+ directoryBackPayload = undefined;
291
+ renderApp(container, savedPayload, 'rendered', true);
292
+ });
293
+ }
294
+ if (payload.fileType === 'directory') {
295
+ directoryBackPayload = undefined;
296
+ }
297
+ const compactRow = document.getElementById('compact-toggle');
298
+ shellController = createCompactRowShellController({
299
+ shell: document.getElementById('tool-shell'),
300
+ compactRow,
301
+ initialExpanded: layout.effectiveExpanded,
302
+ onToggle: (expanded) => {
303
+ isExpanded = expanded;
304
+ trackUiEvent?.(expanded ? 'expand' : 'collapse', {
305
+ file_type: payload.fileType,
306
+ file_extension: fileExtension,
307
+ });
308
+ },
309
+ onScrollAfterExpand: () => {
310
+ trackUiEvent?.('scroll_after_expand', {
311
+ file_type: payload.fileType,
312
+ file_extension: fileExtension,
313
+ });
314
+ },
315
+ onRender,
316
+ });
317
+ onRender?.();
318
+ if (!previewShownFired) {
319
+ previewShownFired = true;
320
+ trackUiEvent?.('preview_shown', {
321
+ file_type: payload.fileType,
322
+ file_extension: fileExtension,
323
+ });
324
+ }
325
+ }
326
+ export function bootstrapApp() {
327
+ const container = document.getElementById('app');
328
+ if (!container) {
329
+ return;
330
+ }
331
+ renderLoadingState(container);
332
+ // Mount the conflict dialog once at body level. It's position: fixed and
333
+ // must live outside the app container so that re-renders of the document
334
+ // body never wipe it while it's open.
335
+ if (!document.getElementById('md-conflict-modal')) {
336
+ const dialogHost = document.createElement('div');
337
+ dialogHost.innerHTML = renderConflictDialogMarkup();
338
+ const dialogRoot = dialogHost.firstElementChild;
339
+ if (dialogRoot) {
340
+ document.body.appendChild(dialogRoot);
341
+ }
342
+ }
343
+ conflictDialogController = createConflictDialogController({ container: document });
344
+ const app = new App({ name: 'Desktop Commander File Preview', version: '1.0.0' }, { updateModelContext: { text: {} } }, { autoResize: true });
345
+ const chrome = {
346
+ expanded: isExpanded,
347
+ hideSummaryRow,
348
+ };
349
+ const syncChromeState = () => {
350
+ isExpanded = chrome.expanded;
351
+ hideSummaryRow = chrome.hideSummaryRow;
352
+ };
353
+ const widgetState = createWidgetStateStorage((value) => isPreviewStructuredContent(value) && typeof value.content === 'string');
354
+ const renderAndSync = (payload) => {
355
+ if (payload) {
356
+ widgetState.write(payload);
357
+ }
358
+ renderApp(container, payload, 'rendered', isExpanded);
359
+ };
360
+ const syncFromPersistedWidgetState = () => {
361
+ const persistedPayload = widgetState.read();
362
+ if (!persistedPayload) {
363
+ return;
364
+ }
365
+ if (currentPayload
366
+ && currentPayload.filePath === persistedPayload.filePath
367
+ && stripReadStatusLine(currentPayload.content) === stripReadStatusLine(persistedPayload.content)) {
368
+ return;
369
+ }
370
+ renderAndSync(persistedPayload);
371
+ };
372
+ syncPayload = renderAndSync;
373
+ persistPayload = (payload) => {
374
+ widgetState.write(payload);
375
+ };
376
+ rerenderCurrent = () => {
377
+ renderApp(container, currentPayload, currentHtmlMode, isExpanded);
378
+ };
379
+ let pendingCachedPayload;
380
+ let initialStateResolved = false;
381
+ const resolveInitialState = (payload, message) => {
382
+ if (initialStateResolved) {
383
+ return;
384
+ }
385
+ initialStateResolved = true;
386
+ if (payload) {
387
+ hostPayload = payload;
388
+ renderAndSync(payload);
389
+ if (payload.fileType === 'markdown' && getCurrentDisplayMode() === 'fullscreen') {
390
+ void markdownController.requestEditMode(payload);
391
+ }
392
+ if (payload.fileType === 'markdown') {
393
+ void markdownController.refreshFromDisk(payload);
394
+ }
395
+ return;
396
+ }
397
+ renderStatusState(container, message ?? 'No preview available for this response.');
398
+ onRender?.();
399
+ };
400
+ onRender = () => { };
401
+ rpcCallTool = (name, args) => (app.callServerTool({ name, arguments: args }));
402
+ rpcUpdateContext = (text) => {
403
+ const params = text
404
+ ? { content: [{ type: 'text', text }] }
405
+ : { content: [] };
406
+ app.updateModelContext(params).catch(() => {
407
+ // Host may not support updateModelContext.
408
+ });
409
+ };
410
+ openExternalLink = async (url) => {
411
+ const result = await app.openLink({ url });
412
+ return result.isError !== true;
413
+ };
414
+ requestDisplayMode = async (mode) => {
415
+ const result = await app.requestDisplayMode({ mode });
416
+ return typeof result.mode === 'string' ? result.mode : null;
417
+ };
418
+ trackUiEvent = createUiEventTracker((name, args) => app.callServerTool({ name, arguments: args }), {
419
+ component: 'file_preview',
420
+ baseParams: { tool_name: 'read_file' },
421
+ });
422
+ app.ontoolinput = (params) => {
423
+ const requestedPath = typeof params.arguments?.path === 'string' ? params.arguments.path : undefined;
424
+ if (!initialStateResolved
425
+ && pendingCachedPayload
426
+ && requestedPath
427
+ && pendingCachedPayload.filePath === requestedPath) {
428
+ const cached = pendingCachedPayload;
429
+ pendingCachedPayload = undefined;
430
+ resolveInitialState(cached);
431
+ return;
432
+ }
433
+ renderLoadingState(container);
434
+ onRender?.();
435
+ };
436
+ app.ontoolresult = (result) => {
437
+ pendingCachedPayload = undefined;
438
+ const payload = extractRenderPayload(result);
439
+ const message = extractToolText(result);
440
+ if (!initialStateResolved) {
441
+ if (payload) {
442
+ if (needsContentRead(payload)) {
443
+ void readAndResolvePayload(payload, (p) => resolveInitialState(getEffectiveIncomingPayload(p)));
444
+ return;
445
+ }
446
+ resolveInitialState(getEffectiveIncomingPayload(payload));
447
+ return;
448
+ }
449
+ if (message) {
450
+ resolveInitialState(undefined, message);
451
+ }
452
+ return;
453
+ }
454
+ if (payload) {
455
+ if (needsContentRead(payload)) {
456
+ renderLoadingState(container);
457
+ void readAndResolvePayload(payload, (p) => renderAndSync(getEffectiveIncomingPayload(p)));
458
+ }
459
+ else {
460
+ renderAndSync(getEffectiveIncomingPayload(payload));
461
+ }
462
+ }
463
+ else if (message) {
464
+ renderStatusState(container, message);
465
+ onRender?.();
466
+ }
467
+ };
468
+ app.ontoolcancelled = (params) => {
469
+ resolveInitialState(undefined, params.reason ?? 'Tool was cancelled.');
470
+ };
471
+ const handleVisibilitySync = () => {
472
+ if (document.visibilityState === 'visible') {
473
+ syncFromPersistedWidgetState();
474
+ }
475
+ };
476
+ const handleFocusSync = () => {
477
+ // Only sync cross-tab state if the page was hidden (tab switch).
478
+ // Simple focus changes within the same page should not trigger a re-render
479
+ // as it destroys the active editor.
480
+ if (document.visibilityState !== 'visible') {
481
+ syncFromPersistedWidgetState();
482
+ }
483
+ };
484
+ const teardown = () => {
485
+ shellController?.dispose();
486
+ shellController = undefined;
487
+ markdownController.disposeHandles();
488
+ selectionAbortController?.abort();
489
+ selectionAbortController = null;
490
+ document.removeEventListener('visibilitychange', handleVisibilitySync);
491
+ window.removeEventListener('focus', handleFocusSync);
492
+ };
493
+ document.addEventListener('visibilitychange', handleVisibilitySync);
494
+ window.addEventListener('focus', handleFocusSync);
495
+ app.onteardown = async () => {
496
+ teardown();
497
+ return {};
498
+ };
499
+ void connectWithSharedHostContext({
500
+ app,
501
+ chrome,
502
+ onContextApplied: () => {
503
+ const previousDisplayMode = getCurrentDisplayMode();
504
+ syncChromeState();
505
+ currentHostContext = app.getHostContext();
506
+ const nextDisplayMode = getCurrentDisplayMode();
507
+ const displayModeChanged = previousDisplayMode !== nextDisplayMode;
508
+ // Clicking a display-mode button blurs the editor first, and the
509
+ // editor's onBlur handler already persists dirty drafts, so there
510
+ // is nothing additional to save here.
511
+ if (previousDisplayMode === 'fullscreen'
512
+ && nextDisplayMode === 'inline'
513
+ && currentPayload?.fileType === 'markdown') {
514
+ isExpanded = true;
515
+ chrome.expanded = true;
516
+ const restorePayload = inlinePayloadBeforeFullscreen ?? hostPayload;
517
+ const restoreWasPartial = restorePayload ? parseReadRange(restorePayload.content)?.isPartial === true : false;
518
+ if (restoreWasPartial && restorePayload) {
519
+ localPayloadOverride = restorePayload;
520
+ currentPayload = restorePayload;
521
+ widgetState.write(restorePayload);
522
+ void markdownController.handleInlineExitFromFullscreen(restorePayload).then((freshPayload) => {
523
+ if (freshPayload) {
524
+ currentPayload = freshPayload;
525
+ localPayloadOverride = freshPayload;
526
+ widgetState.write(freshPayload);
527
+ rerenderCurrent?.();
528
+ }
529
+ });
530
+ }
531
+ else {
532
+ void markdownController.handleInlineExitFromFullscreen();
533
+ }
534
+ inlinePayloadBeforeFullscreen = undefined;
535
+ }
536
+ if (previousDisplayMode !== 'fullscreen'
537
+ && nextDisplayMode === 'fullscreen'
538
+ && currentPayload?.fileType === 'markdown') {
539
+ inlinePayloadBeforeFullscreen = currentPayload;
540
+ if (parseReadRange(currentPayload.content)?.isPartial) {
541
+ void markdownController.requestEditMode(currentPayload);
542
+ }
543
+ }
544
+ if (initialStateResolved && displayModeChanged) {
545
+ rerenderCurrent?.();
546
+ }
547
+ },
548
+ onConnected: () => {
549
+ currentHostContext = app.getHostContext();
550
+ pendingCachedPayload = widgetState.read() ?? undefined;
551
+ window.setTimeout(() => {
552
+ if (!initialStateResolved) {
553
+ resolveInitialState(undefined, 'Preview unavailable after page refresh. Switch threads or re-run the tool.');
554
+ }
555
+ }, 8000);
556
+ },
557
+ }).catch(() => {
558
+ renderStatusState(container, 'Failed to connect to host.');
559
+ onRender?.();
560
+ });
561
+ window.addEventListener('beforeunload', () => {
562
+ teardown();
563
+ }, { once: true });
564
+ }
@@ -0,0 +1,6 @@
1
+ export declare function inferLanguageFromPath(filePath: string): string;
2
+ export declare function formatJsonIfPossible(content: string, filePath: string): {
3
+ content: string;
4
+ notice?: string;
5
+ };
6
+ export declare function renderCodeViewer(code: string, language?: string): string;
@@ -0,0 +1,60 @@
1
+ import { highlightSource } from './highlighting.js';
2
+ const EXTENSION_LANGUAGE_MAP = {
3
+ js: 'javascript',
4
+ cjs: 'javascript',
5
+ mjs: 'javascript',
6
+ ts: 'typescript',
7
+ jsx: 'javascript',
8
+ tsx: 'typescript',
9
+ json: 'json',
10
+ yaml: 'yaml',
11
+ yml: 'yaml',
12
+ toml: 'toml',
13
+ ini: 'ini',
14
+ xml: 'xml',
15
+ html: 'html',
16
+ htm: 'html',
17
+ css: 'css',
18
+ scss: 'css',
19
+ less: 'css',
20
+ sh: 'bash',
21
+ bash: 'bash',
22
+ zsh: 'bash',
23
+ py: 'python',
24
+ rb: 'ruby',
25
+ java: 'java',
26
+ go: 'go',
27
+ rs: 'rust',
28
+ sql: 'sql',
29
+ md: 'markdown',
30
+ markdown: 'markdown'
31
+ };
32
+ function getFileExtension(filePath) {
33
+ const match = filePath.toLowerCase().match(/\.([a-z0-9]+)$/);
34
+ return match ? match[1] : '';
35
+ }
36
+ export function inferLanguageFromPath(filePath) {
37
+ const extension = getFileExtension(filePath);
38
+ return EXTENSION_LANGUAGE_MAP[extension] ?? 'text';
39
+ }
40
+ export function formatJsonIfPossible(content, filePath) {
41
+ if (inferLanguageFromPath(filePath) !== 'json') {
42
+ return { content };
43
+ }
44
+ try {
45
+ return {
46
+ content: `${JSON.stringify(JSON.parse(content), null, 2)}\n`
47
+ };
48
+ }
49
+ catch {
50
+ return {
51
+ content,
52
+ notice: 'Invalid JSON. Showing raw source.'
53
+ };
54
+ }
55
+ }
56
+ export function renderCodeViewer(code, language = 'text') {
57
+ const normalizedLanguage = language || 'text';
58
+ const highlighted = highlightSource(code, normalizedLanguage);
59
+ return `<pre class="code-viewer"><code class="hljs language-${normalizedLanguage}">${highlighted}</code></pre>`;
60
+ }
@@ -0,0 +1,8 @@
1
+ export type HtmlPreviewMode = 'rendered' | 'source';
2
+ export interface HtmlRenderOptions {
3
+ allowUnsafeScripts?: boolean;
4
+ }
5
+ export declare function renderHtmlPreview(content: string, mode: HtmlPreviewMode, options?: HtmlRenderOptions): {
6
+ html: string;
7
+ notice?: string;
8
+ };