@wonderwhy-er/desktop-commander 0.2.39 → 0.2.40

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 (137) hide show
  1. package/dist/server.js +1 -1
  2. package/dist/ui/file-preview/preview-runtime.js +204 -153
  3. package/dist/ui/file-preview/src/markdown/controller.d.ts +7 -1
  4. package/dist/ui/file-preview/src/markdown/controller.js +135 -16
  5. package/dist/ui/file-preview/src/markdown/editor.d.ts +97 -1
  6. package/dist/ui/file-preview/src/markdown/editor.js +814 -26
  7. package/dist/ui/file-preview/src/model.d.ts +2 -1
  8. package/dist/utils/capture.js +1 -1
  9. package/dist/utils/toolHistory.d.ts +13 -0
  10. package/dist/utils/toolHistory.js +65 -0
  11. package/dist/version.d.ts +1 -1
  12. package/dist/version.js +1 -1
  13. package/package.json +7 -1
  14. package/dist/ui/config-editor/app.js +0 -840
  15. package/dist/ui/config-editor/array-modal.d.ts +0 -19
  16. package/dist/ui/config-editor/array-modal.js +0 -185
  17. package/dist/ui/config-editor/main.d.ts +0 -1
  18. package/dist/ui/config-editor/main.js +0 -2
  19. package/dist/ui/config-editor/src/App.d.ts +0 -43
  20. package/dist/ui/config-editor/src/components/layout.d.ts +0 -4
  21. package/dist/ui/config-editor/src/components/layout.js +0 -83
  22. package/dist/ui/config-editor/src/components/toolbar.d.ts +0 -1
  23. package/dist/ui/config-editor/src/components/toolbar.js +0 -21
  24. package/dist/ui/config-editor/src/config-values.d.ts +0 -6
  25. package/dist/ui/config-editor/src/config-values.js +0 -61
  26. package/dist/ui/config-editor/src/contracts.d.ts +0 -14
  27. package/dist/ui/config-editor/src/contracts.js +0 -3
  28. package/dist/ui/config-editor/src/directory-browser.d.ts +0 -6
  29. package/dist/ui/config-editor/src/directory-browser.js +0 -71
  30. package/dist/ui/config-editor/src/layout.d.ts +0 -5
  31. package/dist/ui/config-editor/src/layout.js +0 -90
  32. package/dist/ui/config-editor/src/parsing.d.ts +0 -5
  33. package/dist/ui/config-editor/src/parsing.js +0 -50
  34. package/dist/ui/config-editor/src/toolbar.d.ts +0 -1
  35. package/dist/ui/config-editor/src/toolbar.js +0 -18
  36. package/dist/ui/config-editor/src/types.d.ts +0 -17
  37. package/dist/ui/config-editor/src/types.js +0 -3
  38. package/dist/ui/config-editor/src/utils/config-values.d.ts +0 -9
  39. package/dist/ui/config-editor/src/utils/config-values.js +0 -61
  40. package/dist/ui/config-editor/src/utils/directory-browser.d.ts +0 -31
  41. package/dist/ui/config-editor/src/utils/directory-browser.js +0 -201
  42. package/dist/ui/config-editor/src/utils/parsing.d.ts +0 -8
  43. package/dist/ui/config-editor/src/utils/parsing.js +0 -50
  44. package/dist/ui/file-preview/app.d.ts +0 -8
  45. package/dist/ui/file-preview/app.js +0 -2020
  46. package/dist/ui/file-preview/components/code-viewer.d.ts +0 -6
  47. package/dist/ui/file-preview/components/code-viewer.js +0 -73
  48. package/dist/ui/file-preview/components/highlighting.d.ts +0 -2
  49. package/dist/ui/file-preview/components/highlighting.js +0 -54
  50. package/dist/ui/file-preview/components/html-renderer.d.ts +0 -5
  51. package/dist/ui/file-preview/components/html-renderer.js +0 -47
  52. package/dist/ui/file-preview/components/markdown-renderer.d.ts +0 -1
  53. package/dist/ui/file-preview/components/markdown-renderer.js +0 -67
  54. package/dist/ui/file-preview/components/toolbar.d.ts +0 -6
  55. package/dist/ui/file-preview/components/toolbar.js +0 -75
  56. package/dist/ui/file-preview/image-preview.d.ts +0 -3
  57. package/dist/ui/file-preview/image-preview.js +0 -21
  58. package/dist/ui/file-preview/main.d.ts +0 -1
  59. package/dist/ui/file-preview/main.js +0 -5
  60. package/dist/ui/file-preview/markdown/editor.d.ts +0 -36
  61. package/dist/ui/file-preview/markdown/editor.js +0 -643
  62. package/dist/ui/file-preview/markdown/linking.d.ts +0 -9
  63. package/dist/ui/file-preview/markdown/linking.js +0 -210
  64. package/dist/ui/file-preview/markdown/outline.d.ts +0 -7
  65. package/dist/ui/file-preview/markdown/outline.js +0 -40
  66. package/dist/ui/file-preview/markdown/preview.d.ts +0 -8
  67. package/dist/ui/file-preview/markdown/preview.js +0 -33
  68. package/dist/ui/file-preview/markdown/slugify.d.ts +0 -3
  69. package/dist/ui/file-preview/markdown/slugify.js +0 -31
  70. package/dist/ui/file-preview/markdown/toc.d.ts +0 -11
  71. package/dist/ui/file-preview/markdown/toc.js +0 -75
  72. package/dist/ui/file-preview/markdown/utils.d.ts +0 -1
  73. package/dist/ui/file-preview/markdown/utils.js +0 -15
  74. package/dist/ui/file-preview/markdown/workspace-controller.d.ts +0 -25
  75. package/dist/ui/file-preview/markdown/workspace-controller.js +0 -40
  76. package/dist/ui/file-preview/src/components/CodeViewer.d.ts +0 -6
  77. package/dist/ui/file-preview/src/components/CodeViewer.js +0 -60
  78. package/dist/ui/file-preview/src/components/HtmlRenderer.d.ts +0 -8
  79. package/dist/ui/file-preview/src/components/HtmlRenderer.js +0 -45
  80. package/dist/ui/file-preview/src/components/MarkdownRenderer.d.ts +0 -1
  81. package/dist/ui/file-preview/src/components/MarkdownRenderer.js +0 -15
  82. package/dist/ui/file-preview/src/components/Toolbar.d.ts +0 -6
  83. package/dist/ui/file-preview/src/components/Toolbar.js +0 -75
  84. package/dist/ui/file-preview/src/components/editor-toolbar.d.ts +0 -15
  85. package/dist/ui/file-preview/src/components/editor-toolbar.js +0 -384
  86. package/dist/ui/file-preview/src/components/markdown-editor.d.ts +0 -29
  87. package/dist/ui/file-preview/src/components/markdown-editor.js +0 -535
  88. package/dist/ui/file-preview/src/markdown/block-merge.d.ts +0 -25
  89. package/dist/ui/file-preview/src/markdown/block-merge.js +0 -86
  90. package/dist/ui/file-preview/src/markdown/link-modal.d.ts +0 -13
  91. package/dist/ui/file-preview/src/markdown/link-modal.js +0 -213
  92. package/dist/ui/file-preview/src/markdown/raw-editor.d.ts +0 -8
  93. package/dist/ui/file-preview/src/markdown/raw-editor.js +0 -61
  94. package/dist/ui/file-preview/src/markdown/selection-toolbar.d.ts +0 -14
  95. package/dist/ui/file-preview/src/markdown/selection-toolbar.js +0 -128
  96. package/dist/ui/file-preview/src/markdown/toc.d.ts +0 -11
  97. package/dist/ui/file-preview/src/markdown/toc.js +0 -75
  98. package/dist/ui/file-preview/src/markdown-workspace/editor.d.ts +0 -36
  99. package/dist/ui/file-preview/src/markdown-workspace/editor.js +0 -643
  100. package/dist/ui/file-preview/src/markdown-workspace/linking.d.ts +0 -9
  101. package/dist/ui/file-preview/src/markdown-workspace/linking.js +0 -210
  102. package/dist/ui/file-preview/src/markdown-workspace/outline.d.ts +0 -7
  103. package/dist/ui/file-preview/src/markdown-workspace/outline.js +0 -40
  104. package/dist/ui/file-preview/src/markdown-workspace/preview.d.ts +0 -8
  105. package/dist/ui/file-preview/src/markdown-workspace/preview.js +0 -33
  106. package/dist/ui/file-preview/src/markdown-workspace/slugify.d.ts +0 -3
  107. package/dist/ui/file-preview/src/markdown-workspace/slugify.js +0 -31
  108. package/dist/ui/file-preview/src/markdown-workspace/toc.d.ts +0 -11
  109. package/dist/ui/file-preview/src/markdown-workspace/toc.js +0 -75
  110. package/dist/ui/file-preview/src/markdown-workspace/utils.d.ts +0 -1
  111. package/dist/ui/file-preview/src/markdown-workspace/utils.js +0 -15
  112. package/dist/ui/file-preview/src/markdown-workspace/workspace-controller.d.ts +0 -25
  113. package/dist/ui/file-preview/src/markdown-workspace/workspace-controller.js +0 -40
  114. package/dist/ui/file-preview/types.d.ts +0 -1
  115. package/dist/ui/file-preview/types.js +0 -1
  116. package/dist/ui/server-integration.d.ts +0 -13
  117. package/dist/ui/server-integration.js +0 -31
  118. package/dist/ui/shared/ToolHeader.d.ts +0 -9
  119. package/dist/ui/shared/ToolHeader.js +0 -29
  120. package/dist/ui/shared/app-bootstrap.d.ts +0 -9
  121. package/dist/ui/shared/app-bootstrap.js +0 -15
  122. package/dist/ui/shared/guards.d.ts +0 -1
  123. package/dist/ui/shared/guards.js +0 -3
  124. package/dist/ui/shared/host-lifecycle.d.ts +0 -17
  125. package/dist/ui/shared/host-lifecycle.js +0 -41
  126. package/dist/ui/shared/rpc-client.d.ts +0 -14
  127. package/dist/ui/shared/rpc-client.js +0 -72
  128. package/dist/ui/shared/theme-adaptation.d.ts +0 -10
  129. package/dist/ui/shared/theme-adaptation.js +0 -118
  130. package/dist/ui/shared/tool-header.d.ts +0 -9
  131. package/dist/ui/shared/tool-header.js +0 -25
  132. package/dist/utils/ui-call-context.d.ts +0 -8
  133. package/dist/utils/ui-call-context.js +0 -72
  134. /package/dist/ui/config-editor/{app.d.ts → src/app.d.ts} +0 -0
  135. /package/dist/ui/config-editor/src/{App.js → app.js} +0 -0
  136. /package/dist/ui/file-preview/src/{App.d.ts → app.d.ts} +0 -0
  137. /package/dist/ui/file-preview/src/{App.js → app.js} +0 -0
@@ -1,6 +0,0 @@
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, startLine?: number): string;
@@ -1,73 +0,0 @@
1
- /**
2
- * Code/text viewer renderer responsible for escaping, optional formatting, and syntax-highlight output wrappers. It provides a safe default for non-rich preview content.
3
- */
4
- import { highlightSource } from './highlighting.js';
5
- const EXTENSION_LANGUAGE_MAP = {
6
- js: 'javascript',
7
- cjs: 'javascript',
8
- mjs: 'javascript',
9
- ts: 'typescript',
10
- jsx: 'javascript',
11
- tsx: 'typescript',
12
- json: 'json',
13
- yaml: 'yaml',
14
- yml: 'yaml',
15
- toml: 'toml',
16
- ini: 'ini',
17
- xml: 'xml',
18
- html: 'html',
19
- htm: 'html',
20
- css: 'css',
21
- scss: 'css',
22
- less: 'css',
23
- sh: 'bash',
24
- bash: 'bash',
25
- zsh: 'bash',
26
- py: 'python',
27
- rb: 'ruby',
28
- java: 'java',
29
- go: 'go',
30
- rs: 'rust',
31
- sql: 'sql',
32
- md: 'markdown',
33
- markdown: 'markdown'
34
- };
35
- function getFileExtension(filePath) {
36
- const match = filePath.toLowerCase().match(/\.([a-z0-9]+)$/);
37
- return match ? match[1] : '';
38
- }
39
- export function inferLanguageFromPath(filePath) {
40
- const extension = getFileExtension(filePath);
41
- return EXTENSION_LANGUAGE_MAP[extension] ?? 'text';
42
- }
43
- export function formatJsonIfPossible(content, filePath) {
44
- if (inferLanguageFromPath(filePath) !== 'json') {
45
- return { content };
46
- }
47
- try {
48
- return {
49
- content: `${JSON.stringify(JSON.parse(content), null, 2)}\n`
50
- };
51
- }
52
- catch {
53
- return {
54
- content,
55
- notice: 'Invalid JSON. Showing raw source.'
56
- };
57
- }
58
- }
59
- export function renderCodeViewer(code, language = 'text', startLine = 1) {
60
- const normalizedLanguage = language || 'text';
61
- const highlighted = highlightSource(code, normalizedLanguage);
62
- // Wrap each line with line number gutter
63
- const lines = highlighted.split('\n');
64
- // Remove trailing empty line from trailing newline
65
- if (lines.length > 0 && lines[lines.length - 1] === '') {
66
- lines.pop();
67
- }
68
- const lineHtml = lines.map((line, i) => {
69
- const lineNum = startLine + i;
70
- return `<tr class="code-line" data-line="${lineNum}"><td class="line-num" data-line="${lineNum}">${lineNum}</td><td class="line-content">${line || ' '}</td></tr>`;
71
- }).join('\n');
72
- return `<pre class="code-viewer"><table class="code-table"><tbody>${lineHtml}</tbody></table></pre>`;
73
- }
@@ -1,2 +0,0 @@
1
- export declare function escapeHtml(input: string): string;
2
- export declare function highlightSource(code: string, language: string): string;
@@ -1,54 +0,0 @@
1
- /**
2
- * Syntax highlighting integration layer around highlight.js. It registers supported languages and provides safe helpers for highlighted or plain escaped output.
3
- */
4
- import { escapeHtml as sharedEscapeHtml } from '../../shared/escape-html.js';
5
- import hljs from 'highlight.js/lib/core';
6
- import bash from 'highlight.js/lib/languages/bash';
7
- import css from 'highlight.js/lib/languages/css';
8
- import go from 'highlight.js/lib/languages/go';
9
- import java from 'highlight.js/lib/languages/java';
10
- import javascript from 'highlight.js/lib/languages/javascript';
11
- import json from 'highlight.js/lib/languages/json';
12
- import markdown from 'highlight.js/lib/languages/markdown';
13
- import python from 'highlight.js/lib/languages/python';
14
- import ruby from 'highlight.js/lib/languages/ruby';
15
- import rust from 'highlight.js/lib/languages/rust';
16
- import sql from 'highlight.js/lib/languages/sql';
17
- import typescript from 'highlight.js/lib/languages/typescript';
18
- import xml from 'highlight.js/lib/languages/xml';
19
- import yaml from 'highlight.js/lib/languages/yaml';
20
- hljs.registerLanguage('bash', bash);
21
- hljs.registerLanguage('css', css);
22
- hljs.registerLanguage('go', go);
23
- hljs.registerLanguage('java', java);
24
- hljs.registerLanguage('javascript', javascript);
25
- hljs.registerLanguage('json', json);
26
- hljs.registerLanguage('markdown', markdown);
27
- hljs.registerLanguage('python', python);
28
- hljs.registerLanguage('ruby', ruby);
29
- hljs.registerLanguage('rust', rust);
30
- hljs.registerLanguage('sql', sql);
31
- hljs.registerLanguage('typescript', typescript);
32
- hljs.registerLanguage('xml', xml);
33
- hljs.registerLanguage('html', xml);
34
- hljs.registerLanguage('yaml', yaml);
35
- hljs.registerLanguage('toml', yaml);
36
- hljs.registerLanguage('ini', yaml);
37
- export function escapeHtml(input) {
38
- return sharedEscapeHtml(input);
39
- }
40
- export function highlightSource(code, language) {
41
- const normalizedLanguage = (language || '').toLowerCase();
42
- if (!normalizedLanguage || normalizedLanguage === 'text') {
43
- return escapeHtml(code);
44
- }
45
- try {
46
- if (hljs.getLanguage(normalizedLanguage)) {
47
- return hljs.highlight(code, { language: normalizedLanguage, ignoreIllegals: true }).value;
48
- }
49
- return hljs.highlightAuto(code).value;
50
- }
51
- catch {
52
- return escapeHtml(code);
53
- }
54
- }
@@ -1,5 +0,0 @@
1
- import type { HtmlPreviewMode } from '../types.js';
2
- export declare function renderHtmlPreview(content: string, mode: HtmlPreviewMode): {
3
- html: string;
4
- notice?: string;
5
- };
@@ -1,47 +0,0 @@
1
- /**
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.
8
- */
9
- import { renderCodeViewer } from './code-viewer.js';
10
- import { escapeHtml } from './highlighting.js';
11
- function resolveThemeFrameStyles() {
12
- if (typeof window === 'undefined' || typeof document === 'undefined') {
13
- return {
14
- background: 'Canvas',
15
- text: 'CanvasText',
16
- fontFamily: 'system-ui, sans-serif',
17
- };
18
- }
19
- const rootStyles = window.getComputedStyle(document.documentElement);
20
- const background = rootStyles.getPropertyValue('--panel').trim() || 'Canvas';
21
- const text = rootStyles.getPropertyValue('--text').trim() || 'CanvasText';
22
- const fontFamily = rootStyles.getPropertyValue('--font-sans').trim() || 'system-ui, sans-serif';
23
- return { background, text, fontFamily };
24
- }
25
- function renderSandboxedHtmlFrame(content) {
26
- const palette = resolveThemeFrameStyles();
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>`;
29
- }
30
- export function renderHtmlPreview(content, mode) {
31
- if (mode === 'source') {
32
- return {
33
- html: `<div class="panel-content source-content">${renderCodeViewer(content, 'html')}</div>`
34
- };
35
- }
36
- try {
37
- return {
38
- html: `<div class="panel-content html-content">${renderSandboxedHtmlFrame(content)}</div>`
39
- };
40
- }
41
- catch {
42
- return {
43
- html: `<div class="panel-content source-content">${renderCodeViewer(content, 'html')}</div>`,
44
- notice: 'HTML renderer failed. Showing source instead.'
45
- };
46
- }
47
- }
@@ -1 +0,0 @@
1
- export declare function renderMarkdown(content: string): string;
@@ -1,67 +0,0 @@
1
- /**
2
- * Markdown rendering pipeline for preview mode. It configures markdown-it and highlighting so markdown content is rendered consistently with code block support.
3
- */
4
- // markdown-it is intentionally typed locally here to avoid maintaining global ambient module declarations.
5
- // @ts-expect-error markdown-it does not provide local TypeScript typings in this setup.
6
- import MarkdownIt from 'markdown-it';
7
- import { highlightSource } from './highlighting.js';
8
- import { rewriteWikiLinks } from '../markdown/linking.js';
9
- import { createSlugTracker } from '../markdown/slugify.js';
10
- import { extractInlineText } from '../markdown/utils.js';
11
- const MarkdownItCtor = MarkdownIt;
12
- const markdown = new MarkdownItCtor({
13
- html: false,
14
- linkify: true,
15
- typographer: false,
16
- highlight(code, language) {
17
- const normalizedLanguage = (language || 'text').toLowerCase();
18
- const highlighted = highlightSource(code, normalizedLanguage);
19
- return `<pre class="code-viewer"><code class="hljs language-${normalizedLanguage}">${highlighted}</code></pre>`;
20
- }
21
- });
22
- const renderHeadingOpen = markdown.renderer.rules.heading_open;
23
- markdown.renderer.rules.heading_open = (...args) => {
24
- const tokens = args[0];
25
- const index = args[1];
26
- const options = args[2];
27
- const environment = args[3] ?? {};
28
- const self = args[4];
29
- const nextSlug = typeof environment.nextSlug === 'function'
30
- ? environment.nextSlug
31
- : createSlugTracker();
32
- environment.nextSlug = nextSlug;
33
- const inlineToken = tokens[index + 1];
34
- const headingText = extractInlineText(inlineToken).trim();
35
- const headingId = nextSlug(headingText || 'section');
36
- const token = tokens[index];
37
- token.attrSet?.('id', headingId);
38
- token.attrSet?.('data-heading-id', headingId);
39
- if (typeof renderHeadingOpen === 'function') {
40
- return renderHeadingOpen(...args);
41
- }
42
- return self.renderToken(tokens, index, options);
43
- };
44
- const renderLinkOpen = markdown.renderer.rules.link_open;
45
- markdown.renderer.rules.link_open = (...args) => {
46
- const tokens = args[0];
47
- const index = args[1];
48
- const options = args[2];
49
- const self = args[4];
50
- const token = tokens[index];
51
- token.attrSet?.('data-markdown-link', 'true');
52
- const title = token.attrGet?.('title');
53
- if (title?.startsWith('mcp-wiki:')) {
54
- const rawWikiLink = decodeURIComponent(title.slice('mcp-wiki:'.length));
55
- token.attrSet?.('data-wiki-link', rawWikiLink);
56
- if (Array.isArray(token.attrs)) {
57
- token.attrs = token.attrs.filter(([name]) => name !== 'title');
58
- }
59
- }
60
- if (typeof renderLinkOpen === 'function') {
61
- return renderLinkOpen(...args);
62
- }
63
- return self.renderToken(tokens, index, options);
64
- };
65
- export function renderMarkdown(content) {
66
- return markdown.render(rewriteWikiLinks(content), { nextSlug: createSlugTracker() });
67
- }
@@ -1,6 +0,0 @@
1
- /**
2
- * Toolbar component for preview controls (view mode, metadata, actions). It isolates UI control rendering and event plumbing from core preview orchestration.
3
- */
4
- import type { FilePreviewStructuredContent } from '../../../types.js';
5
- import type { HtmlPreviewMode } from '../types.js';
6
- export declare function renderToolbar(payload: FilePreviewStructuredContent, canCopy: boolean, htmlMode: HtmlPreviewMode, isExpanded: boolean, canOpenInFolder: boolean): string;
@@ -1,75 +0,0 @@
1
- import { renderToolHeader } from '../../shared/tool-header.js';
2
- function inferFilePill(payload) {
3
- if (payload.fileType === 'markdown') {
4
- return { label: 'MD', className: 'file-pill--md' };
5
- }
6
- if (payload.fileType === 'html') {
7
- return { label: 'HTML', className: 'file-pill--html' };
8
- }
9
- const extensionMatch = payload.filePath.toLowerCase().match(/\.([a-z0-9]+)$/);
10
- const extension = extensionMatch ? extensionMatch[1] : 'txt';
11
- if (extension === 'json') {
12
- return { label: 'JSON', className: 'file-pill--json' };
13
- }
14
- return { label: extension.slice(0, 4).toUpperCase(), className: 'file-pill--text' };
15
- }
16
- export function renderToolbar(payload, canCopy, htmlMode, isExpanded, canOpenInFolder) {
17
- const supportsPreview = payload.fileType !== 'unsupported';
18
- const copyDisabled = canCopy ? '' : 'disabled';
19
- const copyTitle = canCopy ? 'Copy source' : 'Copy unavailable';
20
- const copyIcon = `
21
- <svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
22
- <path d="M8 8h10v12H8z"></path>
23
- <path d="M6 4h10v2H8v10H6z"></path>
24
- </svg>
25
- `;
26
- const folderDisabled = canOpenInFolder ? '' : 'disabled';
27
- const folderTitle = canOpenInFolder ? 'Open in folder' : 'Open in folder unavailable';
28
- const folderIcon = `
29
- <svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
30
- <path d="M10 4l2 2h8v12H4V4z"></path>
31
- </svg>
32
- `;
33
- const previewIcon = isExpanded
34
- ? `<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M7 14l5-5 5 5z"></path></svg>`
35
- : `<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M7 10l5 5 5-5z"></path></svg>`;
36
- const htmlModeButton = payload.fileType === 'html'
37
- ? `
38
- <button class="icon-button icon-button--secondary" id="toggle-html-mode" title="${htmlMode === 'rendered' ? 'Show source' : 'Show rendered'}" aria-label="${htmlMode === 'rendered' ? 'Show source' : 'Show rendered'}">
39
- ${htmlMode === 'rendered'
40
- ? `<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M12 5c5.2 0 9.3 4.4 10.6 6-1.3 1.6-5.4 6-10.6 6S2.7 12.6 1.4 11C2.7 9.4 6.8 5 12 5zm0 2.2A3.8 3.8 0 1 0 12 14.8a3.8 3.8 0 0 0 0-7.6z"></path></svg>`
41
- : `<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M9.4 16.6L4.8 12l4.6-4.6L8 6 2 12l6 6 1.4-1.4zm5.2 0l4.6-4.6-4.6-4.6L16 6l6 6-6 6-1.4-1.4z"></path></svg>`}
42
- </button>
43
- `
44
- : '';
45
- const filePill = inferFilePill(payload);
46
- const leadingActions = supportsPreview
47
- ? `
48
- <button class="icon-button" id="toggle-expand" title="${isExpanded ? 'Hide preview' : 'Show preview'}" aria-label="${isExpanded ? 'Hide preview' : 'Show preview'}">
49
- ${previewIcon}
50
- </button>
51
- `
52
- : '';
53
- const trailingActions = supportsPreview
54
- ? `
55
- ${htmlModeButton}
56
- <button class="icon-button" id="copy-source" ${copyDisabled} title="${copyTitle}" aria-label="${copyTitle}">
57
- ${copyIcon}
58
- </button>
59
- `
60
- : '';
61
- return renderToolHeader({
62
- pillLabel: filePill.label,
63
- pillClassName: filePill.className,
64
- title: payload.fileName,
65
- subtitle: payload.filePath,
66
- badges: [],
67
- actionsHtml: `
68
- ${leadingActions}
69
- <button class="icon-button" id="open-in-folder" ${folderDisabled} title="${folderTitle}" aria-label="${folderTitle}">
70
- ${folderIcon}
71
- </button>
72
- ${trailingActions}
73
- `
74
- });
75
- }
@@ -1,3 +0,0 @@
1
- export declare const ALLOWED_IMAGE_MIME_TYPES: Set<string>;
2
- export declare function normalizeImageMimeType(mimeType: string | undefined): string;
3
- export declare function isAllowedImageMimeType(mimeType: string | undefined): boolean;
@@ -1,21 +0,0 @@
1
- export const ALLOWED_IMAGE_MIME_TYPES = new Set([
2
- 'image/png',
3
- 'image/jpeg',
4
- 'image/gif',
5
- 'image/webp',
6
- 'image/bmp',
7
- // Intentional product decision: allow SVG rendering in preview UI.
8
- // This is currently unsanitized and should be revisited if threat model changes.
9
- 'image/svg',
10
- 'image/svg+xml'
11
- ]);
12
- export function normalizeImageMimeType(mimeType) {
13
- if (!mimeType) {
14
- return '';
15
- }
16
- return mimeType.toLowerCase().split(';', 1)[0].trim();
17
- }
18
- export function isAllowedImageMimeType(mimeType) {
19
- const normalizedMimeType = normalizeImageMimeType(mimeType);
20
- return normalizedMimeType.length > 0 && ALLOWED_IMAGE_MIME_TYPES.has(normalizedMimeType);
21
- }
@@ -1 +0,0 @@
1
- export {};
@@ -1,5 +0,0 @@
1
- /**
2
- * Browser bootstrap entrypoint for File Preview UI. It starts the app lifecycle and keeps initialization logic separate from runtime feature code.
3
- */
4
- import { bootstrapApp } from './app.js';
5
- bootstrapApp();
@@ -1,36 +0,0 @@
1
- export type MarkdownEditorView = 'raw' | 'markdown';
2
- export interface MarkdownLinkSearchItem {
3
- path: string;
4
- title: string;
5
- wikiPath: string;
6
- relativePath: string;
7
- }
8
- export interface MarkdownLinkHeading {
9
- id: string;
10
- text: string;
11
- }
12
- export interface MarkdownEditorHandle {
13
- destroy: () => void;
14
- focus: () => void;
15
- getValue: () => string;
16
- setValue: (value: string) => void;
17
- revealLine: (lineNumber: number, headingId?: string) => void;
18
- setScrollTop: (scrollTop: number) => void;
19
- }
20
- export declare function renderMarkdownCopyButton(): string;
21
- export declare function renderMarkdownModeToggle(view: MarkdownEditorView): string;
22
- export declare function renderMarkdownEditorShell(options: {
23
- content: string;
24
- view: MarkdownEditorView;
25
- }): string;
26
- export declare function mountMarkdownEditor(options: {
27
- target: HTMLElement;
28
- value: string;
29
- view: MarkdownEditorView;
30
- initialScrollTop?: number;
31
- currentFilePath: string;
32
- searchLinks?: (query: string) => Promise<MarkdownLinkSearchItem[]>;
33
- loadHeadings?: (filePath: string) => Promise<MarkdownLinkHeading[]>;
34
- onChange: (value: string) => void;
35
- onBlur?: () => void;
36
- }): MarkdownEditorHandle;