@lemoncat7/dsh-ssh 1.5.2 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/ARCHITECTURE.md +3 -0
  2. package/README.md +14 -1
  3. package/docs/dsh-015-compatibility.md +21 -0
  4. package/docs/releases/1.4.3.md +24 -0
  5. package/docs/releases/1.5.0.md +15 -0
  6. package/docs/releases/1.5.3.md +11 -0
  7. package/docs/releases/1.6.0.md +12 -0
  8. package/lib/api.d.ts.map +1 -1
  9. package/lib/api.js +24 -2
  10. package/lib/api.js.map +1 -1
  11. package/lib/client-api.d.ts +21 -6
  12. package/lib/client-api.d.ts.map +1 -1
  13. package/lib/client-api.js +21 -12
  14. package/lib/client-api.js.map +1 -1
  15. package/lib/client.d.ts.map +1 -1
  16. package/lib/client.js +430 -72
  17. package/lib/client.js.map +4 -4
  18. package/lib/docked-panel-compat.d.ts +13 -0
  19. package/lib/docked-panel-compat.d.ts.map +1 -0
  20. package/lib/docked-panel-compat.js +116 -0
  21. package/lib/docked-panel-compat.js.map +1 -0
  22. package/lib/html-file-preview.d.ts +8 -0
  23. package/lib/html-file-preview.d.ts.map +1 -0
  24. package/lib/html-file-preview.js +55 -0
  25. package/lib/html-file-preview.js.map +1 -0
  26. package/lib/local-markdown-file.d.ts +5 -0
  27. package/lib/local-markdown-file.d.ts.map +1 -0
  28. package/lib/local-markdown-file.js +63 -0
  29. package/lib/local-markdown-file.js.map +1 -0
  30. package/lib/local-workspace.d.ts +1 -0
  31. package/lib/local-workspace.d.ts.map +1 -1
  32. package/lib/local-workspace.js +3 -2
  33. package/lib/local-workspace.js.map +1 -1
  34. package/lib/main-panel-compat.d.ts +5 -0
  35. package/lib/main-panel-compat.d.ts.map +1 -0
  36. package/lib/main-panel-compat.js +38 -0
  37. package/lib/main-panel-compat.js.map +1 -0
  38. package/lib/markdown-file.d.ts +19 -0
  39. package/lib/markdown-file.d.ts.map +1 -0
  40. package/lib/markdown-file.js +52 -0
  41. package/lib/markdown-file.js.map +1 -0
  42. package/lib/markdown-preview-editor.d.ts +8 -0
  43. package/lib/markdown-preview-editor.d.ts.map +1 -0
  44. package/lib/markdown-preview-editor.js +56 -0
  45. package/lib/markdown-preview-editor.js.map +1 -0
  46. package/lib/preview-refresh-control.d.ts +9 -0
  47. package/lib/preview-refresh-control.d.ts.map +1 -0
  48. package/lib/preview-refresh-control.js +6 -0
  49. package/lib/preview-refresh-control.js.map +1 -0
  50. package/lib/sftp-client.d.ts +11 -1
  51. package/lib/sftp-client.d.ts.map +1 -1
  52. package/lib/sftp-client.js +57 -28
  53. package/lib/sftp-client.js.map +1 -1
  54. package/lib/sftp-markdown-file.d.ts +6 -0
  55. package/lib/sftp-markdown-file.d.ts.map +1 -0
  56. package/lib/sftp-markdown-file.js +72 -0
  57. package/lib/sftp-markdown-file.js.map +1 -0
  58. package/lib/sftp.d.ts +1 -0
  59. package/lib/sftp.d.ts.map +1 -1
  60. package/lib/sftp.js +3 -1
  61. package/lib/sftp.js.map +1 -1
  62. package/lib/use-file-preview.d.ts +13 -0
  63. package/lib/use-file-preview.d.ts.map +1 -0
  64. package/lib/use-file-preview.js +100 -0
  65. package/lib/use-file-preview.js.map +1 -0
  66. package/lib/use-markdown-draft.d.ts +23 -0
  67. package/lib/use-markdown-draft.d.ts.map +1 -0
  68. package/lib/use-markdown-draft.js +114 -0
  69. package/lib/use-markdown-draft.js.map +1 -0
  70. package/package.json +15 -7
@@ -0,0 +1,13 @@
1
+ import type { Context } from '@deepseek-ai/cordis';
2
+ import type { PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots';
3
+ type PanelProps = PropsRuntime<'details'>;
4
+ /** The new host owns session persistence, docking and tab closure. */
5
+ export declare function supportsDockedPanels(ctx: Context): boolean;
6
+ export declare function createDockedPanel(ctx: Context, id: string, title: string, render: (props: PanelProps) => JSX.Element, notify: () => void): {
7
+ open(sessionId: string): void;
8
+ close(sessionId: string): void;
9
+ isOpen(sessionId: string): boolean;
10
+ dispose(): void;
11
+ };
12
+ export {};
13
+ //# sourceMappingURL=docked-panel-compat.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"docked-panel-compat.d.ts","sourceRoot":"","sources":["../src/docked-panel-compat.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAClD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAA;AAGpE,KAAK,UAAU,GAAG,YAAY,CAAC,SAAS,CAAC,CAAA;AAMzC,sEAAsE;AACtE,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAE1D;AAED,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,OAAO,EACZ,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,GAAG,CAAC,OAAO,EAC1C,MAAM,EAAE,MAAM,IAAI;oBAkDA,MAAM,GAAG,IAAI;qBAwBZ,MAAM,GAAG,IAAI;sBAMZ,MAAM,GAAG,OAAO;eAGvB,IAAI;EAQlB"}
@@ -0,0 +1,116 @@
1
+ import { useEffect } from 'react';
2
+ /** The new host owns session persistence, docking and tab closure. */
3
+ export function supportsDockedPanels(ctx) {
4
+ return typeof ctx.layout.selectPanel === 'function';
5
+ }
6
+ export function createDockedPanel(ctx, id, title, render, notify) {
7
+ const records = new Map();
8
+ let pending;
9
+ let frame;
10
+ let disposed = false;
11
+ let sidebar;
12
+ const cancel = () => {
13
+ if (frame !== undefined)
14
+ window.cancelAnimationFrame(frame);
15
+ frame = undefined;
16
+ pending = undefined;
17
+ };
18
+ function Body(props) {
19
+ const { tab } = props.useTabInfo();
20
+ const sessionId = String(props.sessionId);
21
+ useEffect(() => {
22
+ let entries = records.get(sessionId);
23
+ if (entries === undefined) {
24
+ entries = new Map();
25
+ records.set(sessionId, entries);
26
+ }
27
+ const entry = { visible: tab.visible, close: () => tab.actions.close() };
28
+ entries.set(tab.id, entry);
29
+ const remove = () => {
30
+ if (entries?.get(tab.id) !== entry)
31
+ return;
32
+ entries.delete(tab.id);
33
+ if (entries.size === 0)
34
+ records.delete(sessionId);
35
+ notify();
36
+ };
37
+ tab.signal.addEventListener('abort', remove, { once: true });
38
+ notify();
39
+ return () => {
40
+ tab.signal.removeEventListener('abort', remove);
41
+ remove();
42
+ };
43
+ }, [sessionId, tab.id, tab.visible, tab.signal]);
44
+ // Hidden tabs must not keep terminal polling and document fetching alive.
45
+ return tab.visible ? render(props) : null;
46
+ }
47
+ const fiber = ctx.inject(['sidebarRight', 'sidebarRightTabs'], child => {
48
+ sidebar = child.get('sidebarRight');
49
+ const registry = child.get('sidebarRightTabs');
50
+ const slots = child.slots;
51
+ child.effect(() => registry.register({ id, kind: id, title: () => title }), id + ': tab type');
52
+ child.effect(() => slots.inject('sidebar.right.pane.tab', () => slots.register({
53
+ name: 'sidebar.right.pane.tab', key: id,
54
+ }, Body)), id + ': tab body');
55
+ child.effect(() => () => { sidebar = undefined; }, id + ': tab service');
56
+ });
57
+ return {
58
+ open(sessionId) {
59
+ cancel();
60
+ pending = sessionId;
61
+ // Closing a main panel remounts the conversation seat on the next commit.
62
+ // Do not issue a right-tab command against a stale/unmounted seat.
63
+ let attempts = 0;
64
+ const reveal = () => {
65
+ frame = undefined;
66
+ if (disposed || pending !== sessionId)
67
+ return;
68
+ const sessions = ctx.get('sessions');
69
+ if (String(sessions.list.getSnapshot().current) !== sessionId) {
70
+ cancel();
71
+ notify();
72
+ return;
73
+ }
74
+ try {
75
+ if (sidebar === undefined)
76
+ throw new Error('Right sidebar is not ready');
77
+ sidebar.openTab(id);
78
+ pending = undefined;
79
+ notify();
80
+ }
81
+ catch (error) {
82
+ if (++attempts < 30)
83
+ frame = window.requestAnimationFrame(reveal);
84
+ else {
85
+ cancel();
86
+ notify();
87
+ console.error(title + ': could not open sidebar', error);
88
+ }
89
+ }
90
+ };
91
+ frame = window.requestAnimationFrame(reveal);
92
+ notify();
93
+ },
94
+ close(sessionId) {
95
+ if (pending === sessionId)
96
+ cancel();
97
+ for (const entry of [...(records.get(sessionId)?.values() ?? [])])
98
+ entry.close();
99
+ records.delete(sessionId);
100
+ notify();
101
+ },
102
+ isOpen(sessionId) {
103
+ return pending === sessionId || [...(records.get(sessionId)?.values() ?? [])].some(entry => entry.visible);
104
+ },
105
+ dispose() {
106
+ disposed = true;
107
+ cancel();
108
+ for (const entries of records.values())
109
+ for (const entry of [...entries.values()])
110
+ entry.close();
111
+ records.clear();
112
+ void fiber.dispose();
113
+ },
114
+ };
115
+ }
116
+ //# sourceMappingURL=docked-panel-compat.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"docked-panel-compat.js","sourceRoot":"","sources":["../src/docked-panel-compat.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /** Static, offline HTML only. The iframe additionally disables script execution. */
2
+ export declare function staticHtmlDocument(source: string): string;
3
+ export declare function HtmlFilePreview({ text, name, truncated }: {
4
+ text: string;
5
+ name: string;
6
+ truncated: boolean;
7
+ }): JSX.Element;
8
+ //# sourceMappingURL=html-file-preview.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"html-file-preview.d.ts","sourceRoot":"","sources":["../src/html-file-preview.tsx"],"names":[],"mappings":"AAEA,oFAAoF;AACpF,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAezD;AAED,wBAAgB,eAAe,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,GAAG,GAAG,CAAC,OAAO,CAiC1H"}
@@ -0,0 +1,55 @@
1
+ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
+ import { useLayoutEffect, useRef, useState } from 'react';
3
+ /** Static, offline HTML only. The iframe additionally disables script execution. */
4
+ export function staticHtmlDocument(source) {
5
+ const doc = new DOMParser().parseFromString(source, 'text/html');
6
+ doc.querySelectorAll('script, noscript, template, meta, base, link, iframe, frame, frameset, object, embed, portal, animate, animateMotion, animateTransform, set').forEach(node => node.remove());
7
+ for (const node of doc.querySelectorAll('*')) {
8
+ for (const attribute of [...node.attributes]) {
9
+ const name = attribute.name.toLowerCase();
10
+ if (name.startsWith('on') || ['autofocus', 'target', 'formaction', 'action', 'srcdoc', 'nonce', 'is'].includes(name)
11
+ || (['href', 'xlink:href'].includes(name) && !attribute.value.trim().startsWith('#')))
12
+ node.removeAttribute(attribute.name);
13
+ }
14
+ }
15
+ const policy = doc.createElement('meta');
16
+ policy.httpEquiv = 'Content-Security-Policy';
17
+ policy.content = "default-src 'none'; script-src 'none'; style-src 'unsafe-inline'; img-src data:; font-src data:; connect-src 'none'; frame-src 'none'; object-src 'none'; base-uri 'none'; form-action 'none'";
18
+ doc.head.prepend(policy);
19
+ return '<!doctype html>\n' + doc.documentElement.outerHTML;
20
+ }
21
+ export function HtmlFilePreview({ text, name, truncated }) {
22
+ const [source, setSource] = useState(false);
23
+ const frame = useRef(null);
24
+ const code = useRef(null);
25
+ const position = useRef({ x: 0, y: 0 });
26
+ const codePosition = useRef({ x: 0, y: 0 });
27
+ const lastDocument = useRef();
28
+ useLayoutEffect(() => {
29
+ const iframe = frame.current;
30
+ if (!iframe || lastDocument.current === text)
31
+ return;
32
+ const view = iframe.contentWindow;
33
+ if (!source && lastDocument.current !== undefined && view)
34
+ position.current = { x: view.scrollX, y: view.scrollY };
35
+ lastDocument.current = text;
36
+ iframe.srcdoc = staticHtmlDocument(text);
37
+ }, [text, source]);
38
+ useLayoutEffect(() => {
39
+ if (code.current) {
40
+ code.current.scrollTop = codePosition.current.y;
41
+ code.current.scrollLeft = codePosition.current.x;
42
+ }
43
+ if (!source)
44
+ frame.current?.contentWindow?.scrollTo(position.current.x, position.current.y);
45
+ }, [source, text]);
46
+ function toggle() {
47
+ if (source && code.current)
48
+ codePosition.current = { x: code.current.scrollLeft, y: code.current.scrollTop };
49
+ if (!source && frame.current?.contentWindow)
50
+ position.current = { x: frame.current.contentWindow.scrollX, y: frame.current.contentWindow.scrollY };
51
+ setSource(value => !value);
52
+ }
53
+ return _jsxs("section", { className: "dsh-ssh-html-preview", children: [_jsxs("div", { className: "dsh-ssh-html-preview-toolbar", children: [_jsxs("small", { title: "\u9759\u6001\u9694\u79BB\u9884\u89C8\uFF1A\u4E0D\u6267\u884C\u811A\u672C\uFF0C\u4E0D\u52A0\u8F7D\u5916\u90E8\u6216\u76F8\u5BF9\u8DEF\u5F84\u8D44\u6E90", children: ["HTML \u00B7 ", truncated ? '内容已截断' : '静态预览'] }), _jsx("button", { type: "button", onClick: toggle, "aria-pressed": source, "aria-label": "\u67E5\u770B HTML \u6E90\u7801", children: source ? '页面' : '源码' })] }), _jsx("iframe", { ref: frame, hidden: source, title: `HTML 预览:${name}`, sandbox: "allow-same-origin", referrerPolicy: "no-referrer", onLoad: () => frame.current?.contentWindow?.scrollTo(position.current.x, position.current.y) }), source && _jsx("pre", { ref: code, onScroll: event => { codePosition.current = { x: event.currentTarget.scrollLeft, y: event.currentTarget.scrollTop }; }, children: text })] });
54
+ }
55
+ //# sourceMappingURL=html-file-preview.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"html-file-preview.js","sourceRoot":"","sources":["../src/html-file-preview.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAEzD,oFAAoF;AACpF,MAAM,UAAU,kBAAkB,CAAC,MAAc;IAC/C,MAAM,GAAG,GAAG,IAAI,SAAS,EAAE,CAAC,eAAe,CAAC,MAAM,EAAE,WAAW,CAAC,CAAA;IAChE,GAAG,CAAC,gBAAgB,CAAC,6IAA6I,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAA;IAClM,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,gBAAgB,CAAC,GAAG,CAAC,EAAE,CAAC;QAC7C,KAAK,MAAM,SAAS,IAAI,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;YAC7C,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC,WAAW,EAAE,CAAA;YACzC,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,QAAQ,EAAE,YAAY,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC;mBAC/G,CAAC,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;gBAAE,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;QAC/H,CAAC;IACH,CAAC;IACD,MAAM,MAAM,GAAG,GAAG,CAAC,aAAa,CAAC,MAAM,CAAC,CAAA;IACxC,MAAM,CAAC,SAAS,GAAG,yBAAyB,CAAA;IAC5C,MAAM,CAAC,OAAO,GAAG,+LAA+L,CAAA;IAChN,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;IACxB,OAAO,mBAAmB,GAAG,GAAG,CAAC,eAAe,CAAC,SAAS,CAAA;AAC5D,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAsD;IAC3G,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAA;IAC3C,MAAM,KAAK,GAAG,MAAM,CAAoB,IAAI,CAAC,CAAA;IAC7C,MAAM,IAAI,GAAG,MAAM,CAAiB,IAAI,CAAC,CAAA;IACzC,MAAM,QAAQ,GAAG,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAA;IACvC,MAAM,YAAY,GAAG,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAA;IAC3C,MAAM,YAAY,GAAG,MAAM,EAAU,CAAA;IAErC,eAAe,CAAC,GAAG,EAAE;QACnB,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAA;QAC5B,IAAI,CAAC,MAAM,IAAI,YAAY,CAAC,OAAO,KAAK,IAAI;YAAE,OAAM;QACpD,MAAM,IAAI,GAAG,MAAM,CAAC,aAAa,CAAA;QACjC,IAAI,CAAC,MAAM,IAAI,YAAY,CAAC,OAAO,KAAK,SAAS,IAAI,IAAI;YAAE,QAAQ,CAAC,OAAO,GAAG,EAAE,CAAC,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE,IAAI,CAAC,OAAO,EAAE,CAAA;QAClH,YAAY,CAAC,OAAO,GAAG,IAAI,CAAA;QAC3B,MAAM,CAAC,MAAM,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAA;IAC1C,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAA;IAElB,eAAe,CAAC,GAAG,EAAE;QACnB,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YAAC,IAAI,CAAC,OAAO,CAAC,SAAS,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC;YAAC,IAAI,CAAC,OAAO,CAAC,UAAU,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC,CAAA;QAAC,CAAC;QACvH,IAAI,CAAC,MAAM;YAAE,KAAK,CAAC,OAAO,EAAE,aAAa,EAAE,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;IAC7F,CAAC,EAAE,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAA;IAElB,SAAS,MAAM;QACb,IAAI,MAAM,IAAI,IAAI,CAAC,OAAO;YAAE,YAAY,CAAC,OAAO,GAAG,EAAE,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,CAAA;QAC5G,IAAI,CAAC,MAAM,IAAI,KAAK,CAAC,OAAO,EAAE,aAAa;YAAE,QAAQ,CAAC,OAAO,GAAG,EAAE,CAAC,EAAE,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC,OAAO,EAAE,CAAC,EAAE,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC,OAAO,EAAE,CAAA;QAClJ,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAA;IAC5B,CAAC;IAED,OAAO,mBAAS,SAAS,EAAC,sBAAsB,aAC9C,eAAK,SAAS,EAAC,8BAA8B,aAAC,iBAAO,KAAK,EAAC,wJAA2B,6BAAS,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,IAAS,EAAA,iBAAQ,IAAI,EAAC,QAAQ,EAAC,OAAO,EAAE,MAAM,kBAAgB,MAAM,gBAAa,gCAAY,YAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,GAAU,IAAM,EAC9P,iBAAQ,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,IAAI,EAAE,EAAE,OAAO,EAAC,mBAAmB,EAAC,cAAc,EAAC,aAAa,EAAC,MAAM,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,aAAa,EAAE,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,GAAI,EACtN,MAAM,IAAI,cAAK,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,CAAC,EAAE,GAAG,YAAY,CAAC,OAAO,GAAG,EAAE,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC,UAAU,EAAE,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC,SAAS,EAAE,CAAA,CAAC,CAAC,YAAG,IAAI,GAAO,IACtJ,CAAA;AACZ,CAAC"}
@@ -0,0 +1,5 @@
1
+ import { type MarkdownSaveRequest } from './markdown-file.js';
2
+ export declare function saveLocalMarkdown(root: string, input: MarkdownSaveRequest): Promise<{
3
+ contentHash: string;
4
+ }>;
5
+ //# sourceMappingURL=local-markdown-file.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-markdown-file.d.ts","sourceRoot":"","sources":["../src/local-markdown-file.ts"],"names":[],"mappings":"AAIA,OAAO,EAAmE,KAAK,mBAAmB,EAAE,MAAM,oBAAoB,CAAA;AAE9H,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAAC;IAAE,WAAW,EAAE,MAAM,CAAA;CAAE,CAAC,CAqClH"}
@@ -0,0 +1,63 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { open, realpath, rename, unlink } from 'node:fs/promises';
3
+ import path from 'node:path';
4
+ import { resolveInside } from './local-workspace.js';
5
+ import { MAX_MARKDOWN_EDIT_BYTES, markdownError, saveMarkdownWithAdapter } from './markdown-file.js';
6
+ export async function saveLocalMarkdown(root, input) {
7
+ const boundary = await realpath(root);
8
+ const target = await resolveInside(boundary, input.path);
9
+ if (!/\.md$/i.test(target))
10
+ throw markdownError(400, '目标不是 Markdown 文件');
11
+ const temporary = path.join(path.dirname(target), `.${path.basename(target)}.dsh-save-${randomUUID()}`);
12
+ let staged = false;
13
+ let mode = 0, uid = 0, gid = 0;
14
+ let identity;
15
+ return saveMarkdownWithAdapter(`local:${target}`, input, {
16
+ read: async () => {
17
+ if (await resolveInside(boundary, input.path) !== target)
18
+ throw markdownError(409, '文件路径发生变化');
19
+ const file = await open(target, 'r+'); // Require file write permission, not only parent-directory permission.
20
+ try {
21
+ const info = await file.stat();
22
+ const nextIdentity = `${info.dev}:${info.ino}:${info.mode}:${info.uid}:${info.gid}:${info.size}:${info.mtimeMs}`;
23
+ if (identity !== undefined && identity !== nextIdentity)
24
+ throw markdownError(409, '保存期间文件或权限发生变化');
25
+ identity = nextIdentity;
26
+ if (!info.isFile() || info.nlink > 1)
27
+ throw markdownError(400, '不支持编辑非普通文件或硬链接文件');
28
+ if (info.size > MAX_MARKDOWN_EDIT_BYTES)
29
+ throw markdownError(413, '文件超过编辑大小限制');
30
+ mode = info.mode & 0o777;
31
+ uid = info.uid;
32
+ gid = info.gid;
33
+ const buffer = Buffer.alloc(MAX_MARKDOWN_EDIT_BYTES + 1);
34
+ const { bytesRead } = await file.read(buffer, 0, buffer.length, 0);
35
+ if (bytesRead > MAX_MARKDOWN_EDIT_BYTES)
36
+ throw markdownError(413, '文件超过编辑大小限制');
37
+ return buffer.subarray(0, bytesRead);
38
+ }
39
+ finally {
40
+ await file.close();
41
+ }
42
+ },
43
+ stage: async (text) => {
44
+ const file = await open(temporary, 'wx', 0o600);
45
+ staged = true;
46
+ try {
47
+ await file.writeFile(text, 'utf8');
48
+ if (process.platform !== 'win32') {
49
+ await file.chown(uid, gid);
50
+ await file.chmod(mode);
51
+ }
52
+ await file.sync();
53
+ }
54
+ finally {
55
+ await file.close();
56
+ }
57
+ },
58
+ commit: async () => { await rename(temporary, target); staged = false; },
59
+ cleanup: async () => { if (staged)
60
+ await unlink(temporary); },
61
+ });
62
+ }
63
+ //# sourceMappingURL=local-markdown-file.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-markdown-file.js","sourceRoot":"","sources":["../src/local-markdown-file.ts"],"names":[],"mappings":"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"}
@@ -10,4 +10,5 @@ export declare function openLocalWorkspaceFile(root: string, requestedPath: stri
10
10
  stream: Readable;
11
11
  }>;
12
12
  export declare function deleteLocalWorkspaceEntries(root: string, directory: string, requestedPaths: string[]): Promise<void>;
13
+ export declare function resolveInside(boundary: string, requestedPath: string): Promise<string>;
13
14
  //# sourceMappingURL=local-workspace.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"local-workspace.d.ts","sourceRoot":"","sources":["../src/local-workspace.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAC3C,OAAO,EAA4B,KAAK,kBAAkB,EAAE,KAAK,iBAAiB,EAAE,KAAK,eAAe,EAAE,MAAM,WAAW,CAAA;AAI3H,wBAAsB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAK7G;AAED,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAsBzG;AAED,wBAAsB,yBAAyB,CAAC,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAgB7G;AAED,wBAAsB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,QAAQ,CAAA;CAAE,CAAC,CAM7J;AAED,wBAAsB,2BAA2B,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAoB1H"}
1
+ {"version":3,"file":"local-workspace.d.ts","sourceRoot":"","sources":["../src/local-workspace.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAE3C,OAAO,EAA4B,KAAK,kBAAkB,EAAE,KAAK,iBAAiB,EAAE,KAAK,eAAe,EAAE,MAAM,WAAW,CAAA;AAI3H,wBAAsB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAK7G;AAED,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAsBzG;AAED,wBAAsB,yBAAyB,CAAC,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAgB7G;AAED,wBAAsB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,QAAQ,CAAA;CAAE,CAAC,CAM7J;AAED,wBAAsB,2BAA2B,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAoB1H;AAED,wBAAsB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAQ5F"}
@@ -1,6 +1,7 @@
1
1
  import { createReadStream } from 'node:fs';
2
2
  import { lstat, open, readdir, realpath, rm, stat } from 'node:fs/promises';
3
3
  import path from 'node:path';
4
+ import { markdownHash } from './markdown-file.js';
4
5
  import { mimeTypeFor, previewKind } from './sftp.js';
5
6
  const MAX_PREVIEW_BYTES = 1_048_576;
6
7
  export async function statLocalWorkspacePath(root, requestedPath) {
@@ -51,7 +52,7 @@ export async function readLocalWorkspacePreview(root, requestedPath) {
51
52
  const handle = await open(target, 'r');
52
53
  try {
53
54
  const { bytesRead } = await handle.read(buffer, 0, length, 0);
54
- return { ...base, text: buffer.subarray(0, bytesRead).toString('utf8'), truncated: attributes.size > bytesRead };
55
+ return { ...base, text: buffer.subarray(0, bytesRead).toString('utf8'), contentHash: markdownHash(buffer.subarray(0, bytesRead)), truncated: attributes.size > bytesRead };
55
56
  }
56
57
  finally {
57
58
  await handle.close();
@@ -86,7 +87,7 @@ export async function deleteLocalWorkspaceEntries(root, directory, requestedPath
86
87
  for (const target of targets)
87
88
  await rm(target.path, { recursive: target.recursive, force: false });
88
89
  }
89
- async function resolveInside(boundary, requestedPath) {
90
+ export async function resolveInside(boundary, requestedPath) {
90
91
  const candidate = path.isAbsolute(requestedPath) ? requestedPath : path.join(boundary, requestedPath);
91
92
  let resolved;
92
93
  try {
@@ -1 +1 @@
1
- {"version":3,"file":"local-workspace.js","sourceRoot":"","sources":["../src/local-workspace.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"local-workspace.js","sourceRoot":"","sources":["../src/local-workspace.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import type { Context } from '@deepseek-ai/cordis';
2
+ import type { PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots';
3
+ /** Keep host-version differences at the navigation boundary, not in pages. */
4
+ export declare function registerMainPanel(ctx: Context, id: string, priority: number, render: (props: PropsRuntime<'conversation'>) => JSX.Element, onHidden?: () => void): () => void;
5
+ //# sourceMappingURL=main-panel-compat.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main-panel-compat.d.ts","sourceRoot":"","sources":["../src/main-panel-compat.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAClD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAA;AAIpE,8EAA8E;AAC9E,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,OAAO,EACZ,EAAE,EAAE,MAAM,EACV,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,CAAC,KAAK,EAAE,YAAY,CAAC,cAAc,CAAC,KAAK,GAAG,CAAC,OAAO,EAC5D,QAAQ,GAAE,MAAM,IAAe,GAC9B,MAAM,IAAI,CA4BZ"}
@@ -0,0 +1,38 @@
1
+ import { useEffect } from 'react';
2
+ /** Keep host-version differences at the navigation boundary, not in pages. */
3
+ export function registerMainPanel(ctx, id, priority, render, onHidden = () => { }) {
4
+ const layout = ctx.layout;
5
+ if (typeof layout.selectPanel !== 'function') {
6
+ return ctx.slots.register({ name: 'conversation', priority }, render);
7
+ }
8
+ // 0.1.5 moves global panels from the session-scoped conversation seat to
9
+ // root-scoped keyed main entries. This cast is confined to the version bridge.
10
+ const slots = ctx.slots;
11
+ let disposed = false;
12
+ let generation = 0;
13
+ const Body = (props) => {
14
+ useEffect(() => {
15
+ const current = ++generation;
16
+ return () => {
17
+ // Ignore StrictMode's effect replay and our own explicit removal.
18
+ queueMicrotask(() => { if (!disposed && generation === current)
19
+ onHidden(); });
20
+ };
21
+ }, []);
22
+ return render(props);
23
+ };
24
+ const remove = slots.register({ name: 'main', key: id }, Body);
25
+ const dispose = () => { if (disposed)
26
+ return; disposed = true; remove(); };
27
+ try {
28
+ layout.selectPanel(id);
29
+ }
30
+ catch (error) {
31
+ dispose();
32
+ throw error;
33
+ }
34
+ // The host retains registered keys and resets only a removed active key;
35
+ // never select null here, which could close another plugin's newer panel.
36
+ return dispose;
37
+ }
38
+ //# sourceMappingURL=main-panel-compat.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main-panel-compat.js","sourceRoot":"","sources":["../src/main-panel-compat.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAMjC,8EAA8E;AAC9E,MAAM,UAAU,iBAAiB,CAC/B,GAAY,EACZ,EAAU,EACV,QAAgB,EAChB,MAA4D,EAC5D,WAAuB,GAAG,EAAE,GAAE,CAAC;IAE/B,MAAM,MAAM,GAAG,GAAG,CAAC,MAAkE,CAAA;IACrF,IAAI,OAAO,MAAM,CAAC,WAAW,KAAK,UAAU,EAAE,CAAC;QAC7C,OAAO,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,QAAQ,EAAE,EAAE,MAAM,CAAC,CAAA;IACvE,CAAC;IACD,yEAAyE;IACzE,+EAA+E;IAC/E,MAAM,KAAK,GAAG,GAAG,CAAC,KAEjB,CAAA;IACD,IAAI,QAAQ,GAAG,KAAK,CAAA;IACpB,IAAI,UAAU,GAAG,CAAC,CAAA;IAClB,MAAM,IAAI,GAAG,CAAC,KAAmC,EAAe,EAAE;QAChE,SAAS,CAAC,GAAG,EAAE;YACb,MAAM,OAAO,GAAG,EAAE,UAAU,CAAA;YAC5B,OAAO,GAAG,EAAE;gBACV,kEAAkE;gBAClE,cAAc,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,QAAQ,IAAI,UAAU,KAAK,OAAO;oBAAE,QAAQ,EAAE,CAAA,CAAC,CAAC,CAAC,CAAA;YAC/E,CAAC,CAAA;QACH,CAAC,EAAE,EAAE,CAAC,CAAA;QACN,OAAO,MAAM,CAAC,KAAK,CAAC,CAAA;IACtB,CAAC,CAAA;IACD,MAAM,MAAM,GAAG,KAAK,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,CAAA;IAC9D,MAAM,OAAO,GAAG,GAAS,EAAE,GAAG,IAAI,QAAQ;QAAE,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC,MAAM,EAAE,CAAA,CAAC,CAAC,CAAA;IAC/E,IAAI,CAAC;QAAC,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAA;IAAC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAAC,OAAO,EAAE,CAAC;QAAC,MAAM,KAAK,CAAA;IAAC,CAAC;IACvE,yEAAyE;IACzE,0EAA0E;IAC1E,OAAO,OAAO,CAAA;AAChB,CAAC"}
@@ -0,0 +1,19 @@
1
+ export declare const MAX_MARKDOWN_EDIT_BYTES = 262144;
2
+ export interface MarkdownSaveRequest {
3
+ path: string;
4
+ text: string;
5
+ expectedHash: string;
6
+ }
7
+ export declare const markdownHash: (value: string | Uint8Array) => string;
8
+ export declare function markdownError(status: number, message: string): Error;
9
+ export declare function parseMarkdownSave(body: Record<string, unknown>): MarkdownSaveRequest;
10
+ /** Serializes our writers. External changes are checked again just before replacement. */
11
+ export declare function saveMarkdownWithAdapter(key: string, request: MarkdownSaveRequest, adapter: {
12
+ read(): Promise<Buffer>;
13
+ stage(text: string): Promise<void>;
14
+ commit(): Promise<void>;
15
+ cleanup(): Promise<void>;
16
+ }): Promise<{
17
+ contentHash: string;
18
+ }>;
19
+ //# sourceMappingURL=markdown-file.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdown-file.d.ts","sourceRoot":"","sources":["../src/markdown-file.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,uBAAuB,SAAS,CAAA;AAC7C,MAAM,WAAW,mBAAmB;IAAG,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE;AACzF,eAAO,MAAM,YAAY,GAAI,OAAO,MAAM,GAAG,UAAU,KAAG,MAA0D,CAAA;AACpH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,KAAK,CAAyD;AAC9H,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,mBAAmB,CAKpF;AAGD,0FAA0F;AAC1F,wBAAsB,uBAAuB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,mBAAmB,EAAE,OAAO,EAAE;IAChG,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAAC,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAAC,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAAC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CAC/G,GAAG,OAAO,CAAC;IAAE,WAAW,EAAE,MAAM,CAAA;CAAE,CAAC,CAmBnC"}
@@ -0,0 +1,52 @@
1
+ import { createHash } from 'node:crypto';
2
+ export const MAX_MARKDOWN_EDIT_BYTES = 262144;
3
+ export const markdownHash = (value) => createHash('sha256').update(value).digest('hex');
4
+ export function markdownError(status, message) { return Object.assign(new Error(message), { status }); }
5
+ export function parseMarkdownSave(body) {
6
+ if (typeof body.path !== 'string' || !body.path || body.path.length > 4096 || !/\.md$/i.test(body.path) || body.path.includes('\0'))
7
+ throw markdownError(400, '仅支持编辑 .md 文件');
8
+ if (typeof body.text !== 'string' || Buffer.byteLength(body.text) > MAX_MARKDOWN_EDIT_BYTES)
9
+ throw markdownError(413, 'Markdown 编辑上限为 256 KB');
10
+ if (typeof body.expectedHash !== 'string' || !/^[a-f0-9]{64}$/.test(body.expectedHash))
11
+ throw markdownError(400, '缺少有效的文件版本,请重新打开文件');
12
+ return { path: body.path, text: body.text, expectedHash: body.expectedHash };
13
+ }
14
+ const saving = new Set();
15
+ /** Serializes our writers. External changes are checked again just before replacement. */
16
+ export async function saveMarkdownWithAdapter(key, request, adapter) {
17
+ parseMarkdownSave(request);
18
+ if (saving.has(key))
19
+ throw markdownError(409, '文件正在保存,请稍后重试');
20
+ saving.add(key);
21
+ try {
22
+ const before = await adapter.read();
23
+ if (before.length > MAX_MARKDOWN_EDIT_BYTES)
24
+ throw markdownError(413, '文件超过 256 KB,不能直接编辑');
25
+ try {
26
+ new TextDecoder('utf-8', { fatal: true }).decode(before);
27
+ }
28
+ catch {
29
+ throw markdownError(400, '仅支持 UTF-8 Markdown 文件');
30
+ }
31
+ const contentHash = markdownHash(request.text);
32
+ const previousHash = markdownHash(before);
33
+ if (previousHash === contentHash)
34
+ return { contentHash };
35
+ if (previousHash !== request.expectedHash)
36
+ throw markdownError(409, '文件已被其他地方修改,未覆盖远端;请保留草稿并重新打开核对');
37
+ await adapter.stage(request.text);
38
+ if (markdownHash(await adapter.read()) !== previousHash)
39
+ throw markdownError(409, '保存期间文件发生变化,已停止写入');
40
+ await adapter.commit();
41
+ return { contentHash };
42
+ }
43
+ finally {
44
+ try {
45
+ await adapter.cleanup();
46
+ }
47
+ finally {
48
+ saving.delete(key);
49
+ }
50
+ }
51
+ }
52
+ //# sourceMappingURL=markdown-file.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdown-file.js","sourceRoot":"","sources":["../src/markdown-file.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ export declare function supportsMarkdownEditing(text: string): boolean;
2
+ export declare function MarkdownPreviewEditor({ text, editable, onChange, onSave }: {
3
+ text: string;
4
+ editable: boolean;
5
+ onChange(text: string): void;
6
+ onSave(): void;
7
+ }): JSX.Element;
8
+ //# sourceMappingURL=markdown-preview-editor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdown-preview-editor.d.ts","sourceRoot":"","sources":["../src/markdown-preview-editor.tsx"],"names":[],"mappings":"AAUA,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAI7D;AAED,wBAAgB,qBAAqB,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE;IAC1E,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,MAAM,IAAI,IAAI,CAAA;CAC9E,GAAG,GAAG,CAAC,OAAO,CAkCd"}
@@ -0,0 +1,56 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useEffect, useRef } from 'react';
3
+ import { Editor } from '@tiptap/core';
4
+ import StarterKit from '@tiptap/starter-kit';
5
+ import { Markdown } from '@tiptap/markdown';
6
+ import { TableKit } from '@tiptap/extension-table';
7
+ import Image from '@tiptap/extension-image';
8
+ import TaskList from '@tiptap/extension-task-list';
9
+ import TaskItem from '@tiptap/extension-task-item';
10
+ // Do not silently round-trip embedded HTML or frontmatter through a rich editor.
11
+ export function supportsMarkdownEditing(text) {
12
+ const withoutCode = text.replace(/```[^]*?```|~~~[^]*?~~~|`[^`]*`/g, '');
13
+ return !/^\uFEFF?(?:---|\+\+\+)\r?\n/.test(text) && !/<\/?[a-z!][^>]*>/i.test(withoutCode)
14
+ && !/^\s*\[[^\]]+\]:/m.test(text) && !text.includes('\uFFFD');
15
+ }
16
+ export function MarkdownPreviewEditor({ text, editable, onChange, onSave }) {
17
+ const host = useRef(null);
18
+ const instance = useRef();
19
+ const callbacks = useRef({ onChange, onSave });
20
+ callbacks.current = { onChange, onSave };
21
+ useEffect(() => {
22
+ const editor = new Editor({
23
+ element: host.current,
24
+ extensions: [StarterKit.configure({ link: { openOnClick: false } }), Markdown, TableKit, Image, TaskList, TaskItem.configure({ nested: true })],
25
+ content: text, contentType: 'markdown', editable,
26
+ editorProps: {
27
+ attributes: { class: 'dsh-ssh-markdown-preview dsh-ssh-markdown-editor', role: 'textbox', 'aria-label': 'Markdown 正文', 'aria-multiline': 'true', spellcheck: 'false' },
28
+ handleKeyDown: (_view, event) => {
29
+ if ((event.ctrlKey || event.metaKey) && event.key.toLowerCase() === 's') {
30
+ event.preventDefault();
31
+ callbacks.current.onSave();
32
+ return true;
33
+ }
34
+ return false;
35
+ },
36
+ },
37
+ onUpdate: ({ editor }) => callbacks.current.onChange(editor.getMarkdown()),
38
+ });
39
+ instance.current = editor;
40
+ return () => { instance.current = undefined; editor.destroy(); };
41
+ }, []);
42
+ useEffect(() => { instance.current?.setEditable(editable, false); }, [editable]);
43
+ useEffect(() => {
44
+ const editor = instance.current;
45
+ const comparable = (value) => value.replace(/^\uFEFF/, '').replace(/\r\n/g, '\n').replace(/\n+$/, '');
46
+ if (editor && comparable(editor.getMarkdown()) !== comparable(text)) {
47
+ const parent = host.current?.parentElement;
48
+ const top = parent?.scrollTop ?? 0;
49
+ editor.commands.setContent(text, { contentType: 'markdown', emitUpdate: false });
50
+ if (parent)
51
+ parent.scrollTop = top;
52
+ }
53
+ }, [text]);
54
+ return _jsx("div", { ref: host, className: "dsh-ssh-markdown-editor-host" });
55
+ }
56
+ //# sourceMappingURL=markdown-preview-editor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdown-preview-editor.js","sourceRoot":"","sources":["../src/markdown-preview-editor.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ export declare function PreviewRefreshControl({ busy, blocked, automatic, available, onRefresh, onToggle }: {
2
+ busy: boolean;
3
+ blocked?: boolean;
4
+ automatic: boolean;
5
+ available: boolean;
6
+ onRefresh(): void;
7
+ onToggle(): void;
8
+ }): JSX.Element;
9
+ //# sourceMappingURL=preview-refresh-control.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preview-refresh-control.d.ts","sourceRoot":"","sources":["../src/preview-refresh-control.tsx"],"names":[],"mappings":"AAEA,wBAAgB,qBAAqB,CAAC,EAAE,IAAI,EAAE,OAAe,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,EAAE;IAC1G,IAAI,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,SAAS,EAAE,OAAO,CAAC;IAAC,SAAS,EAAE,OAAO,CAAC;IAAC,SAAS,IAAI,IAAI,CAAC;IAAC,QAAQ,IAAI,IAAI,CAAA;CAC9G,GAAG,GAAG,CAAC,OAAO,CAKd"}