@keith9681/dsh-sidebar 0.15.2

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 (220) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +0 -0
  3. package/README_EN.md +0 -0
  4. package/cordis.patch.yml +49 -0
  5. package/lib/client-editor.js +34651 -0
  6. package/lib/client-mermaid.js +200629 -0
  7. package/lib/client-registry.js +13388 -0
  8. package/lib/client-terminal.js +8904 -0
  9. package/lib/client.js +13388 -0
  10. package/lib/index.js +3959 -0
  11. package/lib/invariant.js +22 -0
  12. package/lib/types/agent-pty.d.ts +226 -0
  13. package/lib/types/browser-probe.d.ts +15 -0
  14. package/lib/types/bundle-route.d.ts +12 -0
  15. package/lib/types/client/BrowserView.d.ts +22 -0
  16. package/lib/types/client/DiffTab.d.ts +6 -0
  17. package/lib/types/client/DiffView.d.ts +51 -0
  18. package/lib/types/client/EditorHost.d.ts +12 -0
  19. package/lib/types/client/FileTree.d.ts +36 -0
  20. package/lib/types/client/GitView.d.ts +8 -0
  21. package/lib/types/client/OrphanedTab.d.ts +11 -0
  22. package/lib/types/client/PdfView.d.ts +6 -0
  23. package/lib/types/client/RenderBoundary.d.ts +32 -0
  24. package/lib/types/client/SandboxStatusBar.d.ts +10 -0
  25. package/lib/types/client/SideCardSection.d.ts +74 -0
  26. package/lib/types/client/SideChatView.d.ts +16 -0
  27. package/lib/types/client/Sidebar.d.ts +6 -0
  28. package/lib/types/client/SubagentView.d.ts +16 -0
  29. package/lib/types/client/TabBar.d.ts +43 -0
  30. package/lib/types/client/TerminalView.d.ts +24 -0
  31. package/lib/types/client/TextEditor.d.ts +10 -0
  32. package/lib/types/client/TreePanel.d.ts +23 -0
  33. package/lib/types/client/UploadOverlay.d.ts +20 -0
  34. package/lib/types/client/add-plugin-modal.d.ts +15 -0
  35. package/lib/types/client/api.d.ts +268 -0
  36. package/lib/types/client/binary-download.d.ts +12 -0
  37. package/lib/types/client/breakpoints.d.ts +12 -0
  38. package/lib/types/client/browser.d.ts +50 -0
  39. package/lib/types/client/builtins/index.d.ts +18 -0
  40. package/lib/types/client/builtins/tabs.d.ts +11 -0
  41. package/lib/types/client/builtins/viewers.d.ts +3 -0
  42. package/lib/types/client/chunk-loader.d.ts +124 -0
  43. package/lib/types/client/chunks/editor.d.ts +9 -0
  44. package/lib/types/client/chunks/mermaid.d.ts +10 -0
  45. package/lib/types/client/chunks/terminal.d.ts +9 -0
  46. package/lib/types/client/cm-themes.d.ts +24 -0
  47. package/lib/types/client/conversation-draft.d.ts +14 -0
  48. package/lib/types/client/desktop-env.d.ts +35 -0
  49. package/lib/types/client/editable-state.d.ts +27 -0
  50. package/lib/types/client/editor-load.d.ts +66 -0
  51. package/lib/types/client/frame-batcher.d.ts +24 -0
  52. package/lib/types/client/icons.d.ts +57 -0
  53. package/lib/types/client/image-types.d.ts +3 -0
  54. package/lib/types/client/ime-guard.d.ts +36 -0
  55. package/lib/types/client/index.d.ts +19 -0
  56. package/lib/types/client/intercept.d.ts +33 -0
  57. package/lib/types/client/lang.d.ts +12 -0
  58. package/lib/types/client/lazy-chunk.d.ts +25 -0
  59. package/lib/types/client/link-intercept.d.ts +42 -0
  60. package/lib/types/client/locales.d.ts +366 -0
  61. package/lib/types/client/mermaid-blocks.d.ts +41 -0
  62. package/lib/types/client/mermaid-sanitize.d.ts +2 -0
  63. package/lib/types/client/mermaid.d.ts +12 -0
  64. package/lib/types/client/open-when-sized.d.ts +20 -0
  65. package/lib/types/client/open-with-settings.d.ts +4 -0
  66. package/lib/types/client/open-with.d.ts +87 -0
  67. package/lib/types/client/openpath-intercept.d.ts +41 -0
  68. package/lib/types/client/paths.d.ts +35 -0
  69. package/lib/types/client/pdf-types.d.ts +2 -0
  70. package/lib/types/client/plugin-settings.d.ts +8 -0
  71. package/lib/types/client/plugins-shared.d.ts +27 -0
  72. package/lib/types/client/plugins-tabs.d.ts +3 -0
  73. package/lib/types/client/plugins-viewers.d.ts +3 -0
  74. package/lib/types/client/prefs.d.ts +41 -0
  75. package/lib/types/client/produced-files.d.ts +23 -0
  76. package/lib/types/client/selection-payload.d.ts +27 -0
  77. package/lib/types/client/service.d.ts +440 -0
  78. package/lib/types/client/settings-nav-icon.d.ts +19 -0
  79. package/lib/types/client/shell-presets.d.ts +48 -0
  80. package/lib/types/client/sidechat-transcript.d.ts +103 -0
  81. package/lib/types/client/split-pane.d.ts +30 -0
  82. package/lib/types/client/state.d.ts +359 -0
  83. package/lib/types/client/subagent-detect.d.ts +54 -0
  84. package/lib/types/client/subagent-jobs.d.ts +63 -0
  85. package/lib/types/client/tab-content-memo.d.ts +33 -0
  86. package/lib/types/client/terminal-font.d.ts +20 -0
  87. package/lib/types/client/theme.d.ts +45 -0
  88. package/lib/types/client/titlebar-strip.d.ts +23 -0
  89. package/lib/types/client/upload.d.ts +69 -0
  90. package/lib/types/client/wco.d.ts +47 -0
  91. package/lib/types/config.d.ts +64 -0
  92. package/lib/types/context-types.d.ts +603 -0
  93. package/lib/types/fs-operations.d.ts +28 -0
  94. package/lib/types/fs-search.d.ts +24 -0
  95. package/lib/types/fs-tree.d.ts +51 -0
  96. package/lib/types/git.d.ts +82 -0
  97. package/lib/types/html-route.d.ts +59 -0
  98. package/lib/types/index.d.ts +47 -0
  99. package/lib/types/invariant.d.ts +15 -0
  100. package/lib/types/jobs-routes.d.ts +45 -0
  101. package/lib/types/open-external.d.ts +24 -0
  102. package/lib/types/prefs-shared.d.ts +225 -0
  103. package/lib/types/pty-deps.d.ts +78 -0
  104. package/lib/types/pty-manager.d.ts +168 -0
  105. package/lib/types/sidechat-core.d.ts +172 -0
  106. package/lib/types/sidechat-routes.d.ts +30 -0
  107. package/lib/types/subagent-activity.d.ts +44 -0
  108. package/lib/types/subagent-live-route.d.ts +44 -0
  109. package/lib/types/tools.d.ts +31 -0
  110. package/lib/types/trust-fence.d.ts +24 -0
  111. package/lib/types/wire.d.ts +38 -0
  112. package/package.json +173 -0
  113. package/scripts/install.ps1 +289 -0
  114. package/scripts/install.sh +287 -0
  115. package/src/agent-pty.ts +527 -0
  116. package/src/browser-probe.ts +26 -0
  117. package/src/bundle-route.ts +129 -0
  118. package/src/client/BrowserView.tsx +253 -0
  119. package/src/client/DiffTab.tsx +110 -0
  120. package/src/client/DiffView.tsx +305 -0
  121. package/src/client/EditorHost.tsx +525 -0
  122. package/src/client/FileTree.tsx +653 -0
  123. package/src/client/GitView.tsx +558 -0
  124. package/src/client/OrphanedTab.tsx +27 -0
  125. package/src/client/PdfView.tsx +110 -0
  126. package/src/client/RenderBoundary.tsx +49 -0
  127. package/src/client/SandboxStatusBar.tsx +60 -0
  128. package/src/client/SideCardSection.module.css +960 -0
  129. package/src/client/SideCardSection.tsx +1152 -0
  130. package/src/client/SideChatView.module.css +437 -0
  131. package/src/client/SideChatView.tsx +644 -0
  132. package/src/client/Sidebar.tsx +1148 -0
  133. package/src/client/SubagentView.module.css +547 -0
  134. package/src/client/SubagentView.tsx +883 -0
  135. package/src/client/TabBar.tsx +305 -0
  136. package/src/client/TerminalView.tsx +383 -0
  137. package/src/client/TextEditor.tsx +500 -0
  138. package/src/client/TreePanel.tsx +273 -0
  139. package/src/client/UploadOverlay.tsx +62 -0
  140. package/src/client/add-plugin-modal.tsx +199 -0
  141. package/src/client/api.ts +335 -0
  142. package/src/client/binary-download.tsx +23 -0
  143. package/src/client/breakpoints.ts +51 -0
  144. package/src/client/browser.ts +119 -0
  145. package/src/client/builtins/index.ts +37 -0
  146. package/src/client/builtins/tabs.tsx +331 -0
  147. package/src/client/builtins/viewers.tsx +125 -0
  148. package/src/client/chunk-loader.ts +351 -0
  149. package/src/client/chunks/editor.tsx +9 -0
  150. package/src/client/chunks/mermaid.tsx +10 -0
  151. package/src/client/chunks/terminal.tsx +9 -0
  152. package/src/client/cm-themes.ts +129 -0
  153. package/src/client/conversation-draft.ts +29 -0
  154. package/src/client/css-modules.d.ts +5 -0
  155. package/src/client/desktop-env.ts +72 -0
  156. package/src/client/editable-state.ts +70 -0
  157. package/src/client/editor-load.ts +92 -0
  158. package/src/client/frame-batcher.ts +56 -0
  159. package/src/client/icons.tsx +161 -0
  160. package/src/client/image-types.ts +8 -0
  161. package/src/client/ime-guard.ts +47 -0
  162. package/src/client/index.tsx +369 -0
  163. package/src/client/intercept.tsx +110 -0
  164. package/src/client/lang.ts +103 -0
  165. package/src/client/layout.css +94 -0
  166. package/src/client/lazy-chunk.tsx +89 -0
  167. package/src/client/link-intercept.ts +73 -0
  168. package/src/client/locales.ts +734 -0
  169. package/src/client/mermaid-blocks.ts +110 -0
  170. package/src/client/mermaid-sanitize.ts +93 -0
  171. package/src/client/mermaid.tsx +401 -0
  172. package/src/client/open-when-sized.ts +43 -0
  173. package/src/client/open-with-settings.tsx +135 -0
  174. package/src/client/open-with.ts +221 -0
  175. package/src/client/openpath-intercept.ts +62 -0
  176. package/src/client/paths.ts +47 -0
  177. package/src/client/pdf-types.ts +4 -0
  178. package/src/client/plugin-settings.ts +43 -0
  179. package/src/client/plugins-shared.ts +29 -0
  180. package/src/client/plugins-tabs.ts +87 -0
  181. package/src/client/plugins-viewers.ts +30 -0
  182. package/src/client/prefs.ts +207 -0
  183. package/src/client/produced-files.ts +91 -0
  184. package/src/client/selection-payload.ts +86 -0
  185. package/src/client/service.ts +838 -0
  186. package/src/client/settings-nav-icon.ts +45 -0
  187. package/src/client/shell-presets.ts +83 -0
  188. package/src/client/sidebar.module.css +2577 -0
  189. package/src/client/sidechat-transcript.ts +321 -0
  190. package/src/client/split-pane.tsx +322 -0
  191. package/src/client/state.ts +1175 -0
  192. package/src/client/subagent-detect.ts +137 -0
  193. package/src/client/subagent-jobs.ts +161 -0
  194. package/src/client/tab-content-memo.ts +46 -0
  195. package/src/client/terminal-font.ts +28 -0
  196. package/src/client/theme.ts +110 -0
  197. package/src/client/titlebar-strip.ts +37 -0
  198. package/src/client/upload.ts +187 -0
  199. package/src/client/wco.ts +120 -0
  200. package/src/config.ts +155 -0
  201. package/src/context-types.ts +610 -0
  202. package/src/fs-operations.ts +99 -0
  203. package/src/fs-search.ts +86 -0
  204. package/src/fs-tree.ts +158 -0
  205. package/src/git.ts +244 -0
  206. package/src/html-route.ts +106 -0
  207. package/src/index.ts +1132 -0
  208. package/src/invariant.ts +32 -0
  209. package/src/jobs-routes.ts +257 -0
  210. package/src/open-external.ts +90 -0
  211. package/src/prefs-shared.ts +268 -0
  212. package/src/pty-deps.ts +240 -0
  213. package/src/pty-manager.ts +376 -0
  214. package/src/sidechat-core.ts +468 -0
  215. package/src/sidechat-routes.ts +344 -0
  216. package/src/subagent-activity.ts +91 -0
  217. package/src/subagent-live-route.ts +93 -0
  218. package/src/tools.ts +479 -0
  219. package/src/trust-fence.ts +77 -0
  220. package/src/wire.ts +100 -0
@@ -0,0 +1,24 @@
1
+ /**
2
+ * CodeMirror 6 theme pieces for the sidebar editor. The editor surface
3
+ * (background, caret, gutter) rides the DSH theme tokens so it blends with
4
+ * the panel in both schemes; only the syntax token colors need concrete
5
+ * values, and those come from the same designed palettes the app's code
6
+ * surfaces use — the one-dark family for dark, the one-light family for
7
+ * light. The scheme flip reconfigures these via a compartment (see
8
+ * TextEditor), so the document, undo history and scroll survive re-theming.
9
+ */
10
+ import { Compartment } from '@codemirror/state';
11
+ /** Token-driven surface shared by both schemes (pure CSS values). */
12
+ export declare const cmSurfaceTheme: import("@codemirror/state").Extension;
13
+ /**
14
+ * A Compartment holding the two scheme-dependent extensions. Created once
15
+ * per editor view; a scheme flip dispatches `reconfigure(dark)` on it, so
16
+ * the document, undo history, scroll and keymaps survive re-theming.
17
+ */
18
+ export declare class CmThemeCompartment {
19
+ private readonly compartment;
20
+ /** `of(...)` payload for EditorState.create. */
21
+ of(dark: boolean): ReturnType<Compartment['of']>;
22
+ /** Reconfigure for a new scheme. */
23
+ reconfigure(dark: boolean): ReturnType<Compartment['reconfigure']>;
24
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Append text to the current session's composer draft through the
3
+ * conversation service — the shared path behind the explorer's @-reference
4
+ * button and the viewer selection popup. The service is resolved lazily
5
+ * through `ctx.get` (the inject-free read the app's own plugins use); a
6
+ * missing service or scope degrades to a logged no-op, never a crash.
7
+ */
8
+ import type { Context } from '../context-types.ts';
9
+ /**
10
+ * Append `text` to the session's composer draft (space-separated, like the
11
+ * @-mentions). Returns false — and logs — when the conversation service or
12
+ * the session scope is unavailable.
13
+ */
14
+ export declare function appendToDraft(ctx: Context, sessionId: string, text: string): boolean;
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Desktop-shell detection for the sidebar. Shells may stamp the render URL
3
+ * with `dsh-desktop-mode` / `dsh-desktop-platform` (the official Electron
4
+ * shell does) and expose `window.__DSH_DESKTOP_FILE_PATH__` through a
5
+ * preload. Parsed once per page and memoized (the URL never changes
6
+ * mid-session); `resetDesktopEnvForTests` clears the memo for unit tests.
7
+ *
8
+ * GEOMETRY POLICY: this module only REPORTS shell facts — it never decides
9
+ * how to adapt. The strip height comes from standard signals first (the
10
+ * Window Controls Overlay API, see wco.ts), then the documented contract
11
+ * parameter `dsh-desktop-titlebar-inset` (a shell may stamp the real pixels
12
+ * it reserves at the top), then the user's chosen scheme (preset / custom).
13
+ * The legacy win32-advanced 32px constant is gone from the core: it lives
14
+ * in the opt-in shell preset (shell-presets.ts) as a fallback for shells
15
+ * without the WCO API.
16
+ */
17
+ export interface DesktopEnv {
18
+ /** Running inside a desktop shell (any URL stamp or preload marker). */
19
+ readonly desktop: boolean;
20
+ /** `advanced` = frameless/custom-titlebar shell; `compatibility` = native frame. */
21
+ readonly mode: 'compatibility' | 'advanced' | null;
22
+ /** Shell platform stamp ('darwin' | 'win32' | …), lowercased, or null. */
23
+ readonly platform: string | null;
24
+ /**
25
+ * Contract parameter `dsh-desktop-titlebar-inset`: pixels the shell
26
+ * reserves at the top of the web content for its own chrome (0–120,
27
+ * clamped; 0 when absent). Standard WCO geometry takes precedence over
28
+ * this whenever the API is available.
29
+ */
30
+ readonly titlebarInset: number;
31
+ }
32
+ /** Read the shell's desktop stamps (memoized per page; SSR-safe). */
33
+ export declare function parseDesktopEnv(): DesktopEnv;
34
+ /** Test hook: drop the memo so the next parse re-reads the URL/globals. */
35
+ export declare function resetDesktopEnvForTests(): void;
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Per-session write-permission state shared between the main client bundle
3
+ * and the lazy editor chunk.
4
+ *
5
+ * The sidebar is READ-ONLY by default: the host refuses every fs.write and
6
+ * git mutation unless the session has been explicitly switched to
7
+ * "editable" from the editor toolbar toggle (see TextEditor.tsx). The
8
+ * AUTHORITATIVE flag lives on the host (config.get / config.set-editable);
9
+ * this module is only the client mirror that keeps the main bundle and the
10
+ * editor chunk in lockstep — chunks bypass the module loader (see
11
+ * chunk-loader.ts), so they cannot import state from the main bundle and
12
+ * must rendezvous on a shared global instead, exactly like
13
+ * `globalThis.__dshChunks__`.
14
+ */
15
+ /**
16
+ * Whether the session may write files. Defaults to false — every session
17
+ * starts read-only and only becomes writable through the toolbar toggle.
18
+ */
19
+ export declare function isSessionEditable(sessionId: string): boolean;
20
+ /**
21
+ * Update the local editable flag and notify subscribers. The caller issues
22
+ * the host call (config.set-editable) separately; a host failure should
23
+ * flip the flag back through this same setter.
24
+ */
25
+ export declare function setSessionEditable(sessionId: string, editable: boolean): void;
26
+ /** Subscribe to editable changes of one session; returns an unsubscribe fn. */
27
+ export declare function subscribeSessionEditable(sessionId: string, callback: (editable: boolean) => void): () => void;
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Pure editor-load planning: the decision logic the editor host needs to
3
+ * turn a matched file viewer + a host fs.read result into a render action.
4
+ * Kept dependency-free (no React, no fetch) so the strategy dispatch is
5
+ * unit-testable and the wire contract (head bytes, binary flag) is pinned.
6
+ *
7
+ * The host flow this module drives:
8
+ * 1. `matchFileViewer(path)` picks a viewer by extension/priority.
9
+ * 2. `planFirstMatch` dispatches its fetchStrategy.
10
+ * 3. An fsRead viewer fetches through the host; `planFsReadOutcome`
11
+ * decides what to do with the result — including the head-based
12
+ * re-match that lets a `detect` viewer claim a binary the extension
13
+ * match could not see (the builtin NUL probe on `binary-download`).
14
+ */
15
+ import type { FileViewerDescriptor } from './service.ts';
16
+ /** One host fs.read result (mirror of the wire; `head` present when binary). */
17
+ export interface FsReadOutcome {
18
+ binary: boolean;
19
+ content: string;
20
+ truncated: boolean;
21
+ /** base64 of the first bytes (present on binary reads; sniffing material). */
22
+ head?: string;
23
+ }
24
+ /** What the editor host should do next. */
25
+ export type EditorLoadAction =
26
+ /** No renderer: show the download UI. */
27
+ {
28
+ kind: 'binary';
29
+ }
30
+ /** Render `viewer`'s component with the carried payload. */
31
+ | {
32
+ kind: 'render';
33
+ viewer: FileViewerDescriptor;
34
+ content?: string;
35
+ truncated?: boolean;
36
+ mediaUrl?: string;
37
+ customData?: unknown;
38
+ }
39
+ /** Fetch the file through the host (fsRead strategy). */
40
+ | {
41
+ kind: 'fetchFsRead';
42
+ viewer: FileViewerDescriptor;
43
+ }
44
+ /** Call the viewer's load() and render with its return value. */
45
+ | {
46
+ kind: 'customLoad';
47
+ viewer: FileViewerDescriptor;
48
+ };
49
+ /** Decode the host's base64 head bytes into the sniffing buffer. */
50
+ export declare function decodeHead(headBase64: string): Uint8Array;
51
+ /**
52
+ * Dispatch one matched viewer's fetchStrategy. A missing viewer or a
53
+ * `binary-download` strategy both mean "no client-side renderer" → the
54
+ * download UI. `mediaUrlOf` builds the media URL for `mediaUrl`/`none`
55
+ * strategies (pure, but scope-bound — injected by the host).
56
+ */
57
+ export declare function planFirstMatch(viewer: FileViewerDescriptor | undefined, mediaUrlOf: () => string): EditorLoadAction;
58
+ /**
59
+ * Decide what an fsRead result means for the editor.
60
+ * - Text: the first match stands (content is valid for any fsRead viewer).
61
+ * - Binary: the host head bytes enable a re-match — a `detect` viewer (e.g.
62
+ * a plugin sniffing a binary format) may claim the file. `custom` viewers
63
+ * load their own bytes; `mediaUrl`/`none` viewers render the media route;
64
+ * an fsRead viewer or nothing cannot render binary → download UI.
65
+ */
66
+ export declare function planFsReadOutcome(viewer: FileViewerDescriptor, result: FsReadOutcome, rematch: (head: Uint8Array) => FileViewerDescriptor | undefined, mediaUrlOf: () => string): EditorLoadAction;
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Per-frame task coalescing for pointer-driven interactions.
3
+ *
4
+ * Pointer streams fire several times faster than the display refresh, and
5
+ * applying every event (a React setState, a store reduce) re-renders whole
6
+ * trees at event cadence — the visible drag lag on slower CPUs (#315). This
7
+ * batcher keeps the LATEST scheduled task, runs it at most once per
8
+ * animation frame, and lets the caller flush synchronously on release (so
9
+ * the final pointer position is never lost to a cancelled frame).
10
+ *
11
+ * Callers compose the pending value in a ref before scheduling; the
12
+ * scheduled task reads that ref, so replacing the task on every event is
13
+ * cheap (one ref write + one rAF check).
14
+ */
15
+ export interface FrameBatcher {
16
+ /** Schedule (or replace) the per-frame task. Safe to call on every event. */
17
+ schedule(task: () => void): void;
18
+ /** Cancel any pending frame and run the scheduled task synchronously
19
+ * (no-op when nothing is scheduled). */
20
+ flushNow(): void;
21
+ /** Cancel any pending frame and drop the task without running it. */
22
+ dispose(): void;
23
+ }
24
+ export declare function createFrameBatcher(): FrameBatcher;
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Icons the sidebar needs beyond the primitives set: a terminal glyph (the
3
+ * icon library has none), a diff glyph, and the two panel-toggle glyphs for
4
+ * the top-right cluster. Per-tab icons live on the tab descriptors
5
+ * (`descriptor.icon`), not in a type-keyed switch — the icon mapping was
6
+ * registry-ized with the tab types.
7
+ */
8
+ import type { IconProps } from '@deepseek-ai/dsh-client-ui-primitives';
9
+ /**
10
+ * Right-panel toggle glyph (the "侧拉" button): a frame with a filled strip
11
+ * along its RIGHT edge, in the app's outline style (1.5px stroke,
12
+ * currentColor).
13
+ */
14
+ export declare const IconPanelRightOutline16: ({ size, className }: IconProps) => import("react").JSX.Element;
15
+ /**
16
+ * Terminal glyph in the app's outline style (1.5px stroke, currentColor):
17
+ * a rounded frame with a prompt chevron and underscore cursor.
18
+ */
19
+ export declare const IconTerminalOutline16: ({ size, className }: IconProps) => import("react").JSX.Element;
20
+ /** Diff glyph in the app's outline style: a file frame with a plus and a minus row. */
21
+ export declare const IconDiffOutline16: ({ size, className }: IconProps) => import("react").JSX.Element;
22
+ /**
23
+ * Stop glyph for the background-job kill button: a filled square in the
24
+ * app's outline scale (16), the universal "halt this work" mark.
25
+ */
26
+ export declare const IconStopOutline16: ({ size, className }: IconProps) => import("react").JSX.Element;
27
+ /** Upload glyph in the app's outline style: an arrow rising into a tray
28
+ * (the file-manager "upload into the workspace" action). */
29
+ export declare const IconUploadOutline16: ({ size, className }: IconProps) => import("react").JSX.Element;
30
+ /** Image viewer glyph: a picture frame with a sun and a mountain. */
31
+ export declare const IconImageOutline16: ({ size, className }: IconProps) => import("react").JSX.Element;
32
+ /** PDF viewer glyph: a document frame with the "PDF" label. */
33
+ export declare const IconPdfOutline16: ({ size, className }: IconProps) => import("react").JSX.Element;
34
+ /** Markdown viewer glyph: the classic "M with a down arrow" badge. */
35
+ export declare const IconMarkdownOutline16: ({ size, className }: IconProps) => import("react").JSX.Element;
36
+ /** HTML viewer glyph: a document frame with a "‹/›" tag pair. */
37
+ export declare const IconHtmlOutline16: ({ size, className }: IconProps) => import("react").JSX.Element;
38
+ /** Browser tab glyph: a globe with meridians. */
39
+ export declare const IconGlobeOutline16: ({ size, className }: IconProps) => import("react").JSX.Element;
40
+ /** History glyph (thread switcher): a clock with a counterclockwise arrow,
41
+ * in the app's outline style — the "past conversations" mark. */
42
+ export declare const IconHistoryOutline16: ({ size, className }: IconProps) => import("react").JSX.Element;
43
+ /** Save glyph (save-as-new-session): the classic floppy disk, in the app's
44
+ * outline style. */
45
+ export declare const IconSaveOutline16: ({ size, className }: IconProps) => import("react").JSX.Element;
46
+ /**
47
+ * Visual Studio Code brand mark for the file-tree "open with" menu. The
48
+ * path is the Simple Icons `visualstudiocode` glyph (CC0 1.0,
49
+ * simple-icons@11.0.0 — later releases dropped it over Microsoft's brand
50
+ * policy, so it is inlined here rather than pulled from react-icons),
51
+ * rendered monochrome via currentColor to follow the active skin.
52
+ */
53
+ export declare const IconVscode16: ({ size, className }: IconProps) => import("react").JSX.Element;
54
+ /** Closed padlock: the session is READ-ONLY — click to enable editing. */
55
+ export declare const IconLockClosedOutline16: ({ size, className }: IconProps) => import("react").JSX.Element;
56
+ /** Open padlock: the session is EDITABLE — click to go back to read-only. */
57
+ export declare const IconLockOpenOutline16: ({ size, className }: IconProps) => import("react").JSX.Element;
@@ -0,0 +1,3 @@
1
+ /** Image extension dispatch, separate from React for unit testing. */
2
+ export declare const IMAGE_EXTENSIONS: readonly string[];
3
+ export declare function isImageExt(ext: string): boolean;
@@ -0,0 +1,36 @@
1
+ /**
2
+ * IME-composition key guard.
3
+ *
4
+ * While a Chinese/Japanese/Korean input method is composing (the user is
5
+ * picking a candidate from the IME window), every pressed key BELONGS to the
6
+ * input method: arrows move the candidate highlight, Enter/Space confirm the
7
+ * composition, Escape cancels it. Page code must not process those keys —
8
+ * a component that does (a number stepper calling preventDefault() on
9
+ * ArrowUp/ArrowDown, a submit handler reacting to Enter, ...) silently
10
+ * breaks the IME: candidates stop responding, the composition gets torn
11
+ * apart, and only bare letters come out.
12
+ *
13
+ * This guard enforces that rule at the document boundary: a capture-phase
14
+ * keydown/keyup listener that stops the event from propagating further
15
+ * whenever a composition is in progress. Because it runs in the capture
16
+ * phase on `document` — the outermost node — it fires BEFORE React's
17
+ * delegated handlers (attached at the root container) and before any native
18
+ * target/bubble listener, so an inlined third-party component (e.g. the
19
+ * Univer office UI bundled into this plugin) can never intercept
20
+ * composition keys. The browser's native IME processing is untouched:
21
+ * stopPropagation only silences page JS, not the default action.
22
+ *
23
+ * The composition signal follows the DSH core convention (InputBar's IME
24
+ * guard, issue #535): `isComposing` for modern engines, keyCode 229 as the
25
+ * legacy signal engines emit without isComposing.
26
+ */
27
+ /** The pure decision: is this keyboard event part of an IME composition? */
28
+ export declare function isImeComposition(event: {
29
+ isComposing: boolean;
30
+ keyCode: number;
31
+ }): boolean;
32
+ /**
33
+ * Register the document-level capture guard. Returns the disposer
34
+ * (HMR-safe; call through `ctx.effect`).
35
+ */
36
+ export declare function registerImeGuard(): () => void;
@@ -0,0 +1,19 @@
1
+ import type { Context } from '../context-types.ts';
2
+ import './layout.css';
3
+ /** Services required before mounting (provided by the client runtime; the
4
+ * locale service backs the sidebar's copy — see locales.ts). `modules`
5
+ * (rc.8+) is the client module system the chunk loader resolves its
6
+ * externals through — Cordis guards service access without inject. */
7
+ export declare const inject: string[];
8
+ /**
9
+ * Error boundary over the sidebar tree (root scope): a render error in the
10
+ * sidebar SHELL itself must never blank the page silently — the shared
11
+ * RenderBoundary shows a dismissible error strip and logs the stack. The
12
+ * per-tab scope (Sidebar.tsx) catches viewer/editor crashes first; this root
13
+ * boundary stays as the last resort for Workbench/shell errors.
14
+ */
15
+ /**
16
+ * Client plugin body.
17
+ * @param ctx - the client cordis context (slots, sessions).
18
+ */
19
+ export declare function apply(ctx: Context): void;
@@ -0,0 +1,33 @@
1
+ import type { Context } from '../context-types.ts';
2
+ import type { SidebarStore } from './state.ts';
3
+ /** Open a file in the sidebar's editor (used by the intercepted row and the explorer). */
4
+ export declare function openSidebarFile(ctx: Context, store: SidebarStore, sessionId: string, path: string): void;
5
+ /** The intercepted produced-files row (visual twin of the deliverables chips). */
6
+ export declare function SidebarProducedFiles(props: {
7
+ matched: readonly string[];
8
+ openInSidebar: (path: string) => void;
9
+ }): import("react").JSX.Element;
10
+ /**
11
+ * Register the turn-tail interception (returns the disposer).
12
+ *
13
+ * The slot is a CHILD slot the host's ui-conversation declares in its
14
+ * `conversation.chat.node` children table (kind: chain, scope: session).
15
+ * Registering it directly races the declaration — the ui-slots core's
16
+ * load-time validation throws "not declared (a parent entry's children
17
+ * table must declare it)" when the parent entry is not on the ledger yet.
18
+ * slots.inject waits for the declaration: the callback runs synchronously
19
+ * when the slot is already declared, otherwise it runs inside the declaring
20
+ * register() call once the declaration commits; declaration collapse
21
+ * disposes the entry and a later declaration re-registers it. This mirrors
22
+ * @deepseek-ai/dsh-client-ui-deliverables' registration of the same slot.
23
+ */
24
+ export declare function registerTurnTailInterception(ctx: Context, store: SidebarStore): () => void;
25
+ /**
26
+ * Register the chat file-open interception: wraps `ctx.workspaces.openPath`
27
+ * — the single funnel every chat-side file open goes through (tool-row path
28
+ * links, the produced-files row, prose mentions) — so opens land in the
29
+ * sidebar editor instead of the Host OS. Gated by BOTH the `interceptOpenPath`
30
+ * pref and the editor tab's enable switch; declined opens fall through to
31
+ * the original method. Returns the disposer restoring the original (HMR-safe).
32
+ */
33
+ export declare function registerOpenPathInterception(ctx: Context, store: SidebarStore): () => void;
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Syntax highlighting for the file editor: extension → CodeMirror language
3
+ * mapping. The key derivation is pure and unit-tested; the factories pull in
4
+ * the CodeMirror language packages (bundled into the client).
5
+ */
6
+ import { Language, LanguageSupport } from '@codemirror/language';
7
+ /** The lowercased file extension of a path ('' when none). */
8
+ export declare function extOf(path: string): string;
9
+ /** Language key for an extension, or null for plain text. Pure (tested). */
10
+ export declare function languageKeyForExt(ext: string): string | null;
11
+ /** The CodeMirror language support for a path, or null for plain text. */
12
+ export declare function languageForPath(path: string): Language | LanguageSupport | null;
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Lazy chunk view wrapper: mounts a component that lives in a lazy chunk,
3
+ * showing a loading placeholder while the chunk script loads and an error +
4
+ * retry affordance on failure. Used by the built-in tab/viewer descriptors.
5
+ *
6
+ * Contract note: {@link lazyChunkComponent} returns a plain render-prop
7
+ * function — the descriptor contract is `component: (props) => ReactNode`,
8
+ * and the repo renders descriptors BOTH ways: Sidebar calls
9
+ * `descriptor.component(props)` directly, EditorHost renders it via
10
+ * `createElement`. The wrapper function body therefore contains no hooks;
11
+ * all state lives in the inner {@link LazyChunkView} component.
12
+ */
13
+ import { type ComponentType, type ReactNode } from 'react';
14
+ import { type ChunkExports, type ChunkName } from './chunk-loader.ts';
15
+ /**
16
+ * Build a descriptor-compatible lazy wrapper for a chunk-resident component.
17
+ * The returned function is the descriptor `component` itself: it returns an
18
+ * element and never calls hooks, so both invocation styles (plain function
19
+ * call and createElement/JSX render) work. `pick` must be a module-level
20
+ * function (stable identity) — an inline lambda would re-trigger the load
21
+ * effect on every render.
22
+ * @param chunk - the chunk name (see chunk-loader.ts).
23
+ * @param pick - select the component from the chunk's exports.
24
+ */
25
+ export declare function lazyChunkComponent<P extends object>(chunk: ChunkName, pick: (mod: ChunkExports) => ComponentType<P> | undefined): (props: P) => ReactNode;
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Chat/GUI external-link interception: clicking an http(s) link that points
3
+ * OUTSIDE the GUI (chat messages, tool rows, prose mentions) opens the
4
+ * sidebar instead of a new browser tab. Gated by the caller through
5
+ * `takeoverEnabled(url)` — the `browserInterceptLinks` master, the URL's
6
+ * protocol flag (`browserInterceptHttp` / `browserInterceptHttps`) and the
7
+ * target tab's enable switch — and a Ctrl/Cmd/Shift/Alt-modified click
8
+ * always bypasses the takeover so the user can still force a real browser
9
+ * tab.
10
+ *
11
+ * Only the GUI's OWN document is watched — links inside the browser tab's
12
+ * sandboxed iframe live in another document and never bubble here (and
13
+ * their clicks must keep working inside the sidebar).
14
+ */
15
+ /** The pure decision: the URL to open in the sidebar, or null to let the
16
+ * click fall through. Extracted so the policy is unit-testable without a
17
+ * DOM. `anchorHref` must be the ABSOLUTE href (`<a>.href` already is).
18
+ * The protocol/same-origin policy lives HERE; the prefs gates (master +
19
+ * protocol flags + target enablement) live in the caller's
20
+ * `takeoverEnabled(url)` callback. */
21
+ export declare function shouldInterceptLink(anchorHref: string, selfOrigin: string): string | null;
22
+ /** Whether a left-click may be taken over (unmodified left click only). */
23
+ export declare function isPlainLeftClick(event: {
24
+ button: number;
25
+ metaKey: boolean;
26
+ ctrlKey: boolean;
27
+ shiftKey: boolean;
28
+ altKey: boolean;
29
+ }): boolean;
30
+ /**
31
+ * Register the document-level click capture that funnels external links
32
+ * into the sidebar. Returns the disposer (HMR-safe).
33
+ */
34
+ export declare function registerLinkInterception(opts: {
35
+ /** Whether the takeover may happen for THIS url (the caller's prefs
36
+ * gates: master switch, protocol flag, target enablement). */
37
+ takeoverEnabled: (url: URL) => boolean;
38
+ /** Open the sidebar tab at `url` (the caller resolves the target type). */
39
+ openInSidebar: (url: string) => void;
40
+ /** The GUI's own origin (window.location.origin at registration). */
41
+ selfOrigin: string;
42
+ }): () => void;