dsh-better-sidebar 0.10.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.
- package/LICENSE +21 -0
- package/README.md +139 -0
- package/README_EN.md +139 -0
- package/lib/client-docx.js +7649 -0
- package/lib/client-editor.js +32677 -0
- package/lib/client-pptx.js +63438 -0
- package/lib/client-registry.js +8021 -0
- package/lib/client-terminal.js +8060 -0
- package/lib/client-xlsx.js +359755 -0
- package/lib/client.js +8021 -0
- package/lib/index.js +2604 -0
- package/lib/invariant.js +22 -0
- package/lib/types/agent-pty.d.ts +220 -0
- package/lib/types/browser-probe.d.ts +15 -0
- package/lib/types/bundle-route.d.ts +13 -0
- package/lib/types/client/BrowserView.d.ts +22 -0
- package/lib/types/client/DiffTab.d.ts +6 -0
- package/lib/types/client/DiffView.d.ts +51 -0
- package/lib/types/client/EditorHost.d.ts +10 -0
- package/lib/types/client/ExplorerView.d.ts +9 -0
- package/lib/types/client/GitView.d.ts +8 -0
- package/lib/types/client/OrphanedTab.d.ts +11 -0
- package/lib/types/client/PdfView.d.ts +6 -0
- package/lib/types/client/PptxView.d.ts +6 -0
- package/lib/types/client/SandboxStatusBar.d.ts +10 -0
- package/lib/types/client/SideCardSection.d.ts +27 -0
- package/lib/types/client/Sidebar.d.ts +6 -0
- package/lib/types/client/SubagentView.d.ts +16 -0
- package/lib/types/client/TabBar.d.ts +38 -0
- package/lib/types/client/TerminalView.d.ts +8 -0
- package/lib/types/client/TextEditor.d.ts +10 -0
- package/lib/types/client/api.d.ts +170 -0
- package/lib/types/client/binary-download.d.ts +12 -0
- package/lib/types/client/breakpoints.d.ts +12 -0
- package/lib/types/client/browser.d.ts +50 -0
- package/lib/types/client/builtins/index.d.ts +17 -0
- package/lib/types/client/builtins/tabs.d.ts +6 -0
- package/lib/types/client/builtins/viewers.d.ts +3 -0
- package/lib/types/client/chunk-loader.d.ts +74 -0
- package/lib/types/client/chunks/docx.d.ts +8 -0
- package/lib/types/client/chunks/editor.d.ts +9 -0
- package/lib/types/client/chunks/pptx.d.ts +8 -0
- package/lib/types/client/chunks/terminal.d.ts +9 -0
- package/lib/types/client/chunks/xlsx.d.ts +9 -0
- package/lib/types/client/cm-themes.d.ts +24 -0
- package/lib/types/client/conversation-draft.d.ts +14 -0
- package/lib/types/client/docx-view.d.ts +8 -0
- package/lib/types/client/editor-load.d.ts +66 -0
- package/lib/types/client/icons.d.ts +47 -0
- package/lib/types/client/image-types.d.ts +3 -0
- package/lib/types/client/ime-guard.d.ts +36 -0
- package/lib/types/client/index.d.ts +10 -0
- package/lib/types/client/intercept.d.ts +20 -0
- package/lib/types/client/lang.d.ts +12 -0
- package/lib/types/client/lazy-chunk.d.ts +25 -0
- package/lib/types/client/link-intercept.d.ts +35 -0
- package/lib/types/client/locales.d.ts +237 -0
- package/lib/types/client/office-shared.d.ts +33 -0
- package/lib/types/client/office-types.d.ts +36 -0
- package/lib/types/client/office-view.d.ts +12 -0
- package/lib/types/client/openpath-intercept.d.ts +41 -0
- package/lib/types/client/paths.d.ts +19 -0
- package/lib/types/client/pdf-types.d.ts +2 -0
- package/lib/types/client/prefs.d.ts +30 -0
- package/lib/types/client/produced-files.d.ts +27 -0
- package/lib/types/client/selection-payload.d.ts +27 -0
- package/lib/types/client/service.d.ts +214 -0
- package/lib/types/client/split-pane.d.ts +29 -0
- package/lib/types/client/state.d.ts +322 -0
- package/lib/types/client/subagent-activity.d.ts +35 -0
- package/lib/types/client/subagent-detect.d.ts +47 -0
- package/lib/types/client/subagent-jobs.d.ts +63 -0
- package/lib/types/client/theme.d.ts +28 -0
- package/lib/types/client/xlsx-to-univer.d.ts +33 -0
- package/lib/types/client/xlsx-view.d.ts +10 -0
- package/lib/types/config.d.ts +41 -0
- package/lib/types/context-types.d.ts +431 -0
- package/lib/types/fs-tree.d.ts +41 -0
- package/lib/types/git.d.ts +75 -0
- package/lib/types/html-route.d.ts +48 -0
- package/lib/types/index.d.ts +39 -0
- package/lib/types/invariant.d.ts +15 -0
- package/lib/types/jobs-routes.d.ts +45 -0
- package/lib/types/prefs-shared.d.ts +106 -0
- package/lib/types/pty-manager.d.ts +76 -0
- package/lib/types/tools.d.ts +28 -0
- package/lib/types/trust-fence.d.ts +24 -0
- package/lib/types/wire.d.ts +38 -0
- package/package.json +168 -0
- package/src/agent-pty.ts +519 -0
- package/src/browser-probe.ts +26 -0
- package/src/bundle-route.ts +130 -0
- package/src/client/BrowserView.tsx +253 -0
- package/src/client/DiffTab.tsx +110 -0
- package/src/client/DiffView.tsx +266 -0
- package/src/client/EditorHost.tsx +101 -0
- package/src/client/ExplorerView.tsx +283 -0
- package/src/client/GitView.tsx +540 -0
- package/src/client/OrphanedTab.tsx +27 -0
- package/src/client/PdfView.tsx +110 -0
- package/src/client/PptxView.tsx +131 -0
- package/src/client/SandboxStatusBar.tsx +60 -0
- package/src/client/SideCardSection.module.css +271 -0
- package/src/client/SideCardSection.tsx +426 -0
- package/src/client/Sidebar.tsx +861 -0
- package/src/client/SubagentView.module.css +547 -0
- package/src/client/SubagentView.tsx +866 -0
- package/src/client/TabBar.tsx +188 -0
- package/src/client/TerminalView.tsx +233 -0
- package/src/client/TextEditor.tsx +382 -0
- package/src/client/api.ts +215 -0
- package/src/client/binary-download.tsx +23 -0
- package/src/client/breakpoints.ts +51 -0
- package/src/client/browser.ts +119 -0
- package/src/client/builtins/index.ts +33 -0
- package/src/client/builtins/tabs.tsx +211 -0
- package/src/client/builtins/viewers.tsx +151 -0
- package/src/client/chunk-loader.ts +196 -0
- package/src/client/chunks/docx.tsx +8 -0
- package/src/client/chunks/editor.tsx +9 -0
- package/src/client/chunks/pptx.tsx +8 -0
- package/src/client/chunks/terminal.tsx +9 -0
- package/src/client/chunks/xlsx.tsx +9 -0
- package/src/client/cm-themes.ts +129 -0
- package/src/client/conversation-draft.ts +29 -0
- package/src/client/css-modules.d.ts +5 -0
- package/src/client/docx-view.tsx +113 -0
- package/src/client/editor-load.ts +92 -0
- package/src/client/icons.tsx +137 -0
- package/src/client/image-types.ts +8 -0
- package/src/client/ime-guard.ts +47 -0
- package/src/client/index.tsx +238 -0
- package/src/client/intercept.tsx +94 -0
- package/src/client/lang.ts +95 -0
- package/src/client/layout.css +54 -0
- package/src/client/lazy-chunk.tsx +89 -0
- package/src/client/link-intercept.ts +66 -0
- package/src/client/locales.ts +476 -0
- package/src/client/office-shared.tsx +40 -0
- package/src/client/office-types.ts +48 -0
- package/src/client/office-view.tsx +12 -0
- package/src/client/openpath-intercept.ts +62 -0
- package/src/client/paths.ts +28 -0
- package/src/client/pdf-types.ts +4 -0
- package/src/client/prefs.ts +100 -0
- package/src/client/produced-files.ts +87 -0
- package/src/client/selection-payload.ts +86 -0
- package/src/client/service.ts +434 -0
- package/src/client/sidebar.module.css +1917 -0
- package/src/client/split-pane.tsx +292 -0
- package/src/client/state.ts +1048 -0
- package/src/client/subagent-activity.ts +67 -0
- package/src/client/subagent-detect.ts +125 -0
- package/src/client/subagent-jobs.ts +161 -0
- package/src/client/theme.ts +44 -0
- package/src/client/xlsx-to-univer.ts +260 -0
- package/src/client/xlsx-view.tsx +116 -0
- package/src/config.ts +95 -0
- package/src/context-types.ts +445 -0
- package/src/fs-tree.ts +115 -0
- package/src/git.ts +236 -0
- package/src/html-route.ts +70 -0
- package/src/index.ts +897 -0
- package/src/invariant.ts +32 -0
- package/src/jobs-routes.ts +257 -0
- package/src/prefs-shared.ts +127 -0
- package/src/pty-manager.ts +199 -0
- package/src/tools.ts +477 -0
- package/src/trust-fence.ts +77 -0
- package/src/wire.ts +94 -0
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import type { BrowserProbeResult } from './browser.ts';
|
|
2
|
+
/** One wire failure. */
|
|
3
|
+
export declare class SidebarApiError extends Error {
|
|
4
|
+
readonly code: string;
|
|
5
|
+
constructor(code: string, message: string);
|
|
6
|
+
}
|
|
7
|
+
/** Explorer row (host fs-tree shape). */
|
|
8
|
+
export interface FsEntry {
|
|
9
|
+
name: string;
|
|
10
|
+
path: string;
|
|
11
|
+
isDir: boolean;
|
|
12
|
+
hidden: boolean;
|
|
13
|
+
}
|
|
14
|
+
/** Git status entry (host git shape). */
|
|
15
|
+
export interface GitStatusEntry {
|
|
16
|
+
path: string;
|
|
17
|
+
xy: string;
|
|
18
|
+
}
|
|
19
|
+
/** Git status snapshot. */
|
|
20
|
+
export interface GitStatusResult {
|
|
21
|
+
isRepo: boolean;
|
|
22
|
+
branch?: string;
|
|
23
|
+
entries: GitStatusEntry[];
|
|
24
|
+
}
|
|
25
|
+
/** One git log row. */
|
|
26
|
+
export interface GitLogEntry {
|
|
27
|
+
/** Short hash (7+ chars, display). */
|
|
28
|
+
hash: string;
|
|
29
|
+
/** Full 40-char hash (advanced operations). */
|
|
30
|
+
hashFull: string;
|
|
31
|
+
subject: string;
|
|
32
|
+
author: string;
|
|
33
|
+
/** ISO 8601 author date (`%ai`). */
|
|
34
|
+
date: string;
|
|
35
|
+
/** Ref decorations (--decorate=short), e.g. `HEAD -> main, origin/main`; '' when none. */
|
|
36
|
+
refs: string;
|
|
37
|
+
}
|
|
38
|
+
/** Text read result. */
|
|
39
|
+
export interface FsTextResult {
|
|
40
|
+
kind: 'text';
|
|
41
|
+
content: string;
|
|
42
|
+
truncated: boolean;
|
|
43
|
+
}
|
|
44
|
+
/** Binary read result (no content; images load through the media route).
|
|
45
|
+
* `head` carries the first bytes (base64) for viewer detect sniffing. */
|
|
46
|
+
export interface FsBinaryResult {
|
|
47
|
+
kind: 'binary';
|
|
48
|
+
size: number;
|
|
49
|
+
truncated: boolean;
|
|
50
|
+
head: string;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* One jobs.output response: the output the MODEL has read so far for the
|
|
54
|
+
* job (replayed from the owner session's event log — the model's
|
|
55
|
+
* job_output cursor is never touched, so the pane can never steal the
|
|
56
|
+
* agent's bytes). `read` is false until the model actually called
|
|
57
|
+
* job_output for the job.
|
|
58
|
+
*/
|
|
59
|
+
export interface JobOutputResult {
|
|
60
|
+
text: string;
|
|
61
|
+
/** True when the host capped the text at its output limit. */
|
|
62
|
+
truncated: boolean;
|
|
63
|
+
/** Whether the model has read the job at least once. */
|
|
64
|
+
read: boolean;
|
|
65
|
+
}
|
|
66
|
+
/** One request's session scope: the conversation id plus its cwd when known. */
|
|
67
|
+
export interface SessionScope {
|
|
68
|
+
sessionId: string;
|
|
69
|
+
/** The session's working directory from the client list summary (optional). */
|
|
70
|
+
cwd?: string;
|
|
71
|
+
}
|
|
72
|
+
/** The sidebar API surface (session scope threaded through every call). */
|
|
73
|
+
export declare const api: {
|
|
74
|
+
sessionCwd: (scope: SessionScope, signal?: AbortSignal) => Promise<{
|
|
75
|
+
sessionId: string;
|
|
76
|
+
cwd: string;
|
|
77
|
+
root: string;
|
|
78
|
+
parent: string | null;
|
|
79
|
+
}>;
|
|
80
|
+
fsTree: (scope: SessionScope, path: string, signal?: AbortSignal) => Promise<{
|
|
81
|
+
path: string;
|
|
82
|
+
entries: FsEntry[];
|
|
83
|
+
truncated: boolean;
|
|
84
|
+
}>;
|
|
85
|
+
fsRead: (scope: SessionScope, path: string, signal?: AbortSignal) => Promise<FsTextResult | FsBinaryResult>;
|
|
86
|
+
fsWrite: (scope: SessionScope, path: string, content: string) => Promise<{
|
|
87
|
+
ok: true;
|
|
88
|
+
}>;
|
|
89
|
+
gitStatus: (scope: SessionScope, signal?: AbortSignal) => Promise<GitStatusResult>;
|
|
90
|
+
gitDiff: (scope: SessionScope, path: string | undefined, staged: boolean, signal?: AbortSignal) => Promise<{
|
|
91
|
+
diff: string;
|
|
92
|
+
}>;
|
|
93
|
+
gitStage: (scope: SessionScope, path?: string) => Promise<{
|
|
94
|
+
ok: true;
|
|
95
|
+
}>;
|
|
96
|
+
gitUnstage: (scope: SessionScope, path?: string) => Promise<{
|
|
97
|
+
ok: true;
|
|
98
|
+
}>;
|
|
99
|
+
gitCommit: (scope: SessionScope, message: string) => Promise<{
|
|
100
|
+
ok: true;
|
|
101
|
+
}>;
|
|
102
|
+
gitBranch: (scope: SessionScope, signal?: AbortSignal) => Promise<{
|
|
103
|
+
current: string;
|
|
104
|
+
names: string[];
|
|
105
|
+
}>;
|
|
106
|
+
gitCheckout: (scope: SessionScope, branch: string) => Promise<{
|
|
107
|
+
ok: true;
|
|
108
|
+
}>;
|
|
109
|
+
/** Recent commit history, lazily pageable (skip/count; defaults 0/30). */
|
|
110
|
+
gitLog: (scope: SessionScope, count?: number, skip?: number, signal?: AbortSignal) => Promise<GitLogEntry[]>;
|
|
111
|
+
/** Full patch text of one commit (diff display for the history rows). */
|
|
112
|
+
gitCommitDiff: (scope: SessionScope, hash: string, signal?: AbortSignal) => Promise<{
|
|
113
|
+
diff: string;
|
|
114
|
+
}>;
|
|
115
|
+
/** Discard the worktree changes of one file (the index is untouched). */
|
|
116
|
+
gitDiscard: (scope: SessionScope, path: string) => Promise<{
|
|
117
|
+
ok: true;
|
|
118
|
+
}>;
|
|
119
|
+
/** Revert one commit onto the current branch. */
|
|
120
|
+
gitRevert: (scope: SessionScope, hash: string) => Promise<{
|
|
121
|
+
ok: true;
|
|
122
|
+
}>;
|
|
123
|
+
/** Cherry-pick one commit onto the current branch. */
|
|
124
|
+
gitCherryPick: (scope: SessionScope, hash: string) => Promise<{
|
|
125
|
+
ok: true;
|
|
126
|
+
}>;
|
|
127
|
+
/** Release a terminal's process immediately (tab closed; the WS close frame
|
|
128
|
+
* may be unreachable while the socket is down, so the host also accepts
|
|
129
|
+
* this explicit route). */
|
|
130
|
+
ptyClose: (scope: SessionScope, tab: string) => Promise<{
|
|
131
|
+
ok: true;
|
|
132
|
+
}>;
|
|
133
|
+
/** Release an agent terminal by uuid (tab closed while WS was down). */
|
|
134
|
+
agentPtyClose: (uuid: string) => Promise<{
|
|
135
|
+
ok: true;
|
|
136
|
+
}>;
|
|
137
|
+
/**
|
|
138
|
+
* The output the model has read so far for one background job (replayed
|
|
139
|
+
* from the owner session's event log — never the model's job_output
|
|
140
|
+
* cursor). The scope MUST be the job's OWNER session.
|
|
141
|
+
*/
|
|
142
|
+
jobOutput: (scope: SessionScope, id: string, signal?: AbortSignal) => Promise<JobOutputResult>;
|
|
143
|
+
/** Request cancellation of one background job (live jobs flip to stopping). */
|
|
144
|
+
jobKill: (scope: SessionScope, id: string, reason?: string) => Promise<{
|
|
145
|
+
ok: true;
|
|
146
|
+
outcome: "requested" | "already-finished";
|
|
147
|
+
}>;
|
|
148
|
+
/** Read the side card preferences (plugin-global, no session scope). */
|
|
149
|
+
settingsGet: () => Promise<{
|
|
150
|
+
value?: unknown;
|
|
151
|
+
revision?: number;
|
|
152
|
+
}>;
|
|
153
|
+
/** Merge a patch into the side card preferences (revision-guarded). */
|
|
154
|
+
settingsUpdate: (patch: Record<string, unknown>, expectedRevision?: number) => Promise<{
|
|
155
|
+
value?: unknown;
|
|
156
|
+
revision?: number;
|
|
157
|
+
}>;
|
|
158
|
+
/** Probe a URL's response headers (the sidebar browser's embeddability
|
|
159
|
+
* check; see the host's browser.probe route). */
|
|
160
|
+
browserProbe: (url: string, signal?: AbortSignal) => Promise<BrowserProbeResult>;
|
|
161
|
+
};
|
|
162
|
+
/** Absolute URL of the media route for one path (images only). */
|
|
163
|
+
export declare function mediaUrl(scope: SessionScope, path: string): string;
|
|
164
|
+
/** Absolute URL of the download route: serves raw bytes (binary-safe) with
|
|
165
|
+
* `Content-Disposition: attachment`, so the browser saves the file. */
|
|
166
|
+
export declare function downloadUrl(scope: SessionScope, path: string): string;
|
|
167
|
+
/** Absolute URL of the HTML preview route (see html-route.ts): the path is
|
|
168
|
+
* fully encoded so the previewed page's relative assets resolve back into
|
|
169
|
+
* the same route with the session scope intact. */
|
|
170
|
+
export declare function htmlUrl(scope: SessionScope, path: string): string;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The "no preview — download instead" pane: shown by the editor host when no
|
|
3
|
+
* viewer can render a file (binary without a registered renderer, or the
|
|
4
|
+
* `binary-download` strategy) and registered as the `binary-download` viewer
|
|
5
|
+
* component so the declarative route and the host fallback share one UI.
|
|
6
|
+
*/
|
|
7
|
+
import type { ReactNode } from 'react';
|
|
8
|
+
import type { SessionScope } from './api.ts';
|
|
9
|
+
export declare function BinaryDownload(props: {
|
|
10
|
+
scope: SessionScope;
|
|
11
|
+
path: string;
|
|
12
|
+
}): ReactNode;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/** Viewport widths strictly below this are "mobile" (paired CSS: max-width: 767px). */
|
|
2
|
+
export declare const NARROW_MAX_WIDTH = 768;
|
|
3
|
+
/** Whether a viewport width is narrow (mobile). */
|
|
4
|
+
export declare function isNarrowWidth(width: number): boolean;
|
|
5
|
+
/**
|
|
6
|
+
* Live narrow-viewport flag for components. Reads `window.innerWidth` and
|
|
7
|
+
* re-measures on resize (rAF-throttled, the repo's existing drag pattern).
|
|
8
|
+
* Deliberately avoids `matchMedia` (jsdom does not implement it) — the
|
|
9
|
+
* resize listener is equally exact for a breakpoint that never changes
|
|
10
|
+
* while the page is open.
|
|
11
|
+
*/
|
|
12
|
+
export declare function useNarrowViewport(): boolean;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure URL policy for the built-in browser tab: normalize user input into
|
|
3
|
+
* an http(s) URL, and refuse destinations that would be dangerous to embed
|
|
4
|
+
* in the sidebar iframe. Kept dependency-free so it is unit-testable.
|
|
5
|
+
*
|
|
6
|
+
* The iframe sandbox (opaque origin, no allow-same-origin / top-navigation)
|
|
7
|
+
* is the primary security boundary; this module is the address-bar gate on
|
|
8
|
+
* top of it: only http/https may be navigated, and loopback addresses are
|
|
9
|
+
* refused so a browsed page cannot probe local services by user action.
|
|
10
|
+
* The GUI's OWN origin is explicitly ALLOWED — the user may open the GUI
|
|
11
|
+
* itself in the sidebar (debugging, mirroring); the sandbox still renders
|
|
12
|
+
* it in an opaque origin with no same-origin privileges, exactly like any
|
|
13
|
+
* other site.
|
|
14
|
+
*/
|
|
15
|
+
/** Why a navigation attempt was refused. */
|
|
16
|
+
export type BrowserBlockReason = 'scheme' | 'loopback';
|
|
17
|
+
/** Result of normalizing one address-bar input. */
|
|
18
|
+
export type BrowserNavigateResult = {
|
|
19
|
+
kind: 'ok';
|
|
20
|
+
url: string;
|
|
21
|
+
} | {
|
|
22
|
+
kind: 'blocked';
|
|
23
|
+
reason: BrowserBlockReason;
|
|
24
|
+
} | {
|
|
25
|
+
kind: 'invalid';
|
|
26
|
+
};
|
|
27
|
+
/** One browser.probe wire result (host fetch of the target's headers). */
|
|
28
|
+
export interface BrowserProbeResult {
|
|
29
|
+
reachable: boolean;
|
|
30
|
+
/** The final (post-redirect) URL; present when reachable. */
|
|
31
|
+
url?: string;
|
|
32
|
+
status?: number;
|
|
33
|
+
xFrameOptions?: string;
|
|
34
|
+
/** The CSP frame-ancestors source list; present when the directive exists. */
|
|
35
|
+
frameAncestors?: string[];
|
|
36
|
+
}
|
|
37
|
+
/** Embeddability verdict of one probe. */
|
|
38
|
+
export type Embeddability = 'embeddable' | 'blocked' | 'unknown';
|
|
39
|
+
/**
|
|
40
|
+
* Decide whether a site can render inside the sidebar iframe. The signals
|
|
41
|
+
* are exactly the ones the BROWSER enforces when it refuses an iframe load:
|
|
42
|
+
* X-Frame-Options DENY/SAMEORIGIN, or a frame-ancestors directive that does
|
|
43
|
+
* not allow `*` ('self' here means the SITE's own origin — never ours, so
|
|
44
|
+
* it also blocks the sidebar). A site we could not reach yields 'unknown'
|
|
45
|
+
* and the plain iframe stays.
|
|
46
|
+
*/
|
|
47
|
+
export declare function embeddabilityOf(probe: BrowserProbeResult): Embeddability;
|
|
48
|
+
/** A loopback hostname (localhost, IPv6 ::1, 127.0.0.0/8, 0.0.0.0). */
|
|
49
|
+
export declare function isLoopbackHostname(hostname: string): boolean;
|
|
50
|
+
export declare function normalizeBrowserUrl(input: string, selfOrigin: string): BrowserNavigateResult;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Built-in registration: the plugin registers its own tab pages and file
|
|
3
|
+
* previewers through the same {@link BetterSidebarService} external plugins
|
|
4
|
+
* use — eating its own dogfood. The descriptors live next to their feature
|
|
5
|
+
* modules (tabs.tsx / viewers.tsx); this module only aggregates them and
|
|
6
|
+
* owns the disposer lifecycle (cordis auto-invokes it on fiber disposal,
|
|
7
|
+
* HMR-safe).
|
|
8
|
+
*/
|
|
9
|
+
import type { Context } from '../../context-types.ts';
|
|
10
|
+
import type { BetterSidebarService } from '../service.ts';
|
|
11
|
+
/**
|
|
12
|
+
* Register all built-in tabs and viewers with the service. Returns a
|
|
13
|
+
* disposer that unregisters everything (cordis auto-invokes it on fiber
|
|
14
|
+
* disposal). The `ctx` is threaded into tab descriptors that need it
|
|
15
|
+
* (EditorHost reads `ctx.betterSidebar` for file-viewer matching).
|
|
16
|
+
*/
|
|
17
|
+
export declare function registerBuiltins(ctx: Context, service: BetterSidebarService): () => void;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { Context } from '../../context-types.ts';
|
|
2
|
+
import type { TabDescriptor } from '../service.ts';
|
|
3
|
+
/** How many UI-owned terminals may be open at once (agent-owned ones are uncapped). */
|
|
4
|
+
export declare const TERMINAL_LIMIT = 3;
|
|
5
|
+
/** The 7 built-in tab descriptors. */
|
|
6
|
+
export declare function builtinTabs(ctx: Context): readonly TabDescriptor[];
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lazy chunk loader for the client bundle. The heavy preview/terminal
|
|
3
|
+
* libraries (Univer, docx-preview, pptx-renderer, CodeMirror, xterm — the
|
|
4
|
+
* office/terminal/editor stacks, tens of MB) live in separate build-time
|
|
5
|
+
* bundles (`lib/client-<name>.js`) fetched only on first use of the feature
|
|
6
|
+
* that needs them, so startup downloads/parses only the ~1MB core bundle.
|
|
7
|
+
*
|
|
8
|
+
* How a chunk script works (see tsdown.config.ts chunkBundle):
|
|
9
|
+
*
|
|
10
|
+
* globalThis.__dshChunks__ = globalThis.__dshChunks__ || {};
|
|
11
|
+
* globalThis.__dshChunks__["terminal"] = (require) => { ...exports };
|
|
12
|
+
*
|
|
13
|
+
* The script registers its factory on a plugin-owned global registry (NOT
|
|
14
|
+
* through window.__ModuleLoader__.load — the module loader's import() only
|
|
15
|
+
* resolves seed words, shell-own modules, registered factories, and boot
|
|
16
|
+
* graph rows; a chunk id is none of those, so resolution would be version-
|
|
17
|
+
* dependent). Materialization is plugin-owned:
|
|
18
|
+
*
|
|
19
|
+
* 1. inject <script src="/sidebar/bundle/<name>.js"> (classic same-origin
|
|
20
|
+
* script; the official /plugins/<id>/client.js route cannot serve
|
|
21
|
+
* arbitrary file names, so the plugin's own host route serves the chunks),
|
|
22
|
+
* 2. read the factory from the global registry,
|
|
23
|
+
* 3. call it with a require that resolves the platform externals through
|
|
24
|
+
* `__DSH_MODULES__.import(spec)` — the seed-word branch, the one part of
|
|
25
|
+
* the module system that is stable across versions.
|
|
26
|
+
*
|
|
27
|
+
* Caching contract (three layers, each with a failure path):
|
|
28
|
+
* - In-memory: one in-flight promise per chunk, memoized until
|
|
29
|
+
* {@link resetChunks}; a failed load removes its entry so the next call
|
|
30
|
+
* retries from scratch.
|
|
31
|
+
* - Script execution: each re-execution overwrites the global registry slot
|
|
32
|
+
* (assignment, never registration) — no "duplicate factory registration"
|
|
33
|
+
* class of errors; a failed materialization clears the cache so the retry
|
|
34
|
+
* re-injects and re-executes.
|
|
35
|
+
* - HTTP: the bundle route revalidates every request (`cache-control:
|
|
36
|
+
* no-cache` + ETag, 304 when unchanged), so page refreshes and HMR
|
|
37
|
+
* re-activations never re-download a multi-MB chunk that did not change.
|
|
38
|
+
*
|
|
39
|
+
* HMR: each plugin activation calls {@link resetChunks}, which drops the
|
|
40
|
+
* in-memory cache (and any test registry), so a hot-reloaded core bundle
|
|
41
|
+
* re-fetches and re-executes the current chunk scripts on the next lazy
|
|
42
|
+
* open. Chunk-only source edits still need a manual page refresh (the HMR
|
|
43
|
+
* poll watches only client.js).
|
|
44
|
+
*/
|
|
45
|
+
export type ChunkName = 'docx' | 'xlsx' | 'pptx' | 'terminal' | 'editor';
|
|
46
|
+
/** The module exports a chunk factory provides (namespace-ish record). */
|
|
47
|
+
export type ChunkExports = Record<string, unknown>;
|
|
48
|
+
/**
|
|
49
|
+
* The platform externals a chunk bundle may require (mirror of
|
|
50
|
+
* CLIENT_EXTERNALS in tsdown.config.ts — the chunk builds keep these
|
|
51
|
+
* external and the loader resolves them here). A superset is safe: the
|
|
52
|
+
* require only answers what the chunk actually asks for.
|
|
53
|
+
*/
|
|
54
|
+
export declare const CHUNK_EXTERNALS: readonly string[];
|
|
55
|
+
/** Script-load hook; tests replace it with a stub (the default needs a real DOM + network). */
|
|
56
|
+
export type ChunkScriptLoader = (src: string) => Promise<void>;
|
|
57
|
+
/** Test hook: replace the chunk-script loader (pass null to restore the default). */
|
|
58
|
+
export declare function setChunkScriptLoaderForTests(loader: ChunkScriptLoader | null): void;
|
|
59
|
+
export declare function registerChunkForTests(name: ChunkName, loader: () => Promise<ChunkExports>): void;
|
|
60
|
+
/**
|
|
61
|
+
* Load (once) and materialize a lazy chunk, returning its module exports.
|
|
62
|
+
* Concurrent callers share one in-flight load; a failure clears the cache
|
|
63
|
+
* entry so the next call retries (the script re-executes and overwrites its
|
|
64
|
+
* global registry slot — assignments are idempotent).
|
|
65
|
+
* @param name - the chunk to load.
|
|
66
|
+
*/
|
|
67
|
+
export declare function loadChunk(name: ChunkName): Promise<ChunkExports>;
|
|
68
|
+
/**
|
|
69
|
+
* Drop all chunk state for a fresh plugin activation (HMR-safe): clear the
|
|
70
|
+
* in-memory cache and any test-registry entries, so the next lazy open
|
|
71
|
+
* re-fetches and re-executes the current chunk scripts (the registry slots
|
|
72
|
+
* are overwritten by the re-execution — no cleanup needed).
|
|
73
|
+
*/
|
|
74
|
+
export declare function resetChunks(): void;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lazy chunk entry: the .docx preview (docx-preview + jszip). Built as
|
|
3
|
+
* `lib/client-docx.js` and registered under `dsh-better-sidebar/docx` —
|
|
4
|
+
* fetched only when a .docx is first opened (see chunk-loader.ts and
|
|
5
|
+
* docs/plans/2026-08-12-lazy-chunks-design.md). Never import this module
|
|
6
|
+
* from the core bundle: it pulls the office library into the startup path.
|
|
7
|
+
*/
|
|
8
|
+
export { DocxView } from '../docx-view.tsx';
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lazy chunk entry: the code/markdown/html text editor (CodeMirror 6 + the
|
|
3
|
+
* language packages). Built as `lib/client-editor.js` and registered under
|
|
4
|
+
* `dsh-better-sidebar/editor` — fetched only when a text file is first
|
|
5
|
+
* opened (see chunk-loader.ts and docs/plans/2026-08-12-lazy-chunks-design.md).
|
|
6
|
+
* Never import this module from the core bundle: it pulls CodeMirror into
|
|
7
|
+
* the startup path.
|
|
8
|
+
*/
|
|
9
|
+
export { TextEditor } from '../TextEditor.tsx';
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lazy chunk entry: the .pptx preview (pptx-renderer). Built as
|
|
3
|
+
* `lib/client-pptx.js` and registered under `dsh-better-sidebar/pptx` —
|
|
4
|
+
* fetched only when a .pptx is first opened (see chunk-loader.ts and
|
|
5
|
+
* docs/plans/2026-08-12-lazy-chunks-design.md). Never import this module
|
|
6
|
+
* from the core bundle: it pulls the renderer into the startup path.
|
|
7
|
+
*/
|
|
8
|
+
export { PptxView } from '../PptxView.tsx';
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lazy chunk entry: the interactive terminal (xterm + fit addon). Built as
|
|
3
|
+
* `lib/client-terminal.js` and registered under
|
|
4
|
+
* `dsh-better-sidebar/terminal` — fetched only when a terminal tab is first
|
|
5
|
+
* opened (see chunk-loader.ts and docs/plans/2026-08-12-lazy-chunks-design.md).
|
|
6
|
+
* Never import this module from the core bundle: it pulls xterm (and its
|
|
7
|
+
* stylesheet) into the startup path.
|
|
8
|
+
*/
|
|
9
|
+
export { TerminalView } from '../TerminalView.tsx';
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lazy chunk entry: the .xlsx preview (Univer family + SheetJS, several MB).
|
|
3
|
+
* Built as `lib/client-xlsx.js` and registered under
|
|
4
|
+
* `dsh-better-sidebar/xlsx` — fetched only when a .xlsx is first opened
|
|
5
|
+
* (see chunk-loader.ts and docs/plans/2026-08-12-lazy-chunks-design.md).
|
|
6
|
+
* Never import this module from the core bundle: it pulls Univer into the
|
|
7
|
+
* startup path.
|
|
8
|
+
*/
|
|
9
|
+
export { XlsxView } from '../xlsx-view.tsx';
|
|
@@ -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,8 @@
|
|
|
1
|
+
import { type OfficeViewProps } from './office-shared.tsx';
|
|
2
|
+
/**
|
|
3
|
+
* Render a .docx file via docx-preview. The library renders into a container
|
|
4
|
+
* div (no canvas); images and styles are inlined. Unmounting clears the
|
|
5
|
+
* container's innerHTML — docx-preview has no dispose API, but tearing down
|
|
6
|
+
* the DOM is enough.
|
|
7
|
+
*/
|
|
8
|
+
export declare function DocxView(props: OfficeViewProps): JSX.Element;
|
|
@@ -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,47 @@
|
|
|
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
|
+
* Bottom-panel toggle glyph (the "底栏" button): a frame with a filled strip
|
|
17
|
+
* along its BOTTOM edge, in the app's outline style.
|
|
18
|
+
*/
|
|
19
|
+
export declare const IconPanelBottomOutline16: ({ size, className }: IconProps) => import("react").JSX.Element;
|
|
20
|
+
/**
|
|
21
|
+
* Terminal glyph in the app's outline style (1.5px stroke, currentColor):
|
|
22
|
+
* a rounded frame with a prompt chevron and underscore cursor.
|
|
23
|
+
*/
|
|
24
|
+
export declare const IconTerminalOutline16: ({ size, className }: IconProps) => import("react").JSX.Element;
|
|
25
|
+
/** Diff glyph in the app's outline style: a file frame with a plus and a minus row. */
|
|
26
|
+
export declare const IconDiffOutline16: ({ size, className }: IconProps) => import("react").JSX.Element;
|
|
27
|
+
/**
|
|
28
|
+
* Stop glyph for the background-job kill button: a filled square in the
|
|
29
|
+
* app's outline scale (16), the universal "halt this work" mark.
|
|
30
|
+
*/
|
|
31
|
+
export declare const IconStopOutline16: ({ size, className }: IconProps) => import("react").JSX.Element;
|
|
32
|
+
/** Image viewer glyph: a picture frame with a sun and a mountain. */
|
|
33
|
+
export declare const IconImageOutline16: ({ size, className }: IconProps) => import("react").JSX.Element;
|
|
34
|
+
/** PDF viewer glyph: a document frame with the "PDF" label. */
|
|
35
|
+
export declare const IconPdfOutline16: ({ size, className }: IconProps) => import("react").JSX.Element;
|
|
36
|
+
/** Word viewer glyph: a document frame with a "W". */
|
|
37
|
+
export declare const IconDocxOutline16: ({ size, className }: IconProps) => import("react").JSX.Element;
|
|
38
|
+
/** Excel viewer glyph: a spreadsheet grid. */
|
|
39
|
+
export declare const IconXlsxOutline16: ({ size, className }: IconProps) => import("react").JSX.Element;
|
|
40
|
+
/** PowerPoint viewer glyph: a chart with rising bars. */
|
|
41
|
+
export declare const IconPptxOutline16: ({ size, className }: IconProps) => import("react").JSX.Element;
|
|
42
|
+
/** Markdown viewer glyph: the classic "M with a down arrow" badge. */
|
|
43
|
+
export declare const IconMarkdownOutline16: ({ size, className }: IconProps) => import("react").JSX.Element;
|
|
44
|
+
/** HTML viewer glyph: a document frame with a "‹/›" tag pair. */
|
|
45
|
+
export declare const IconHtmlOutline16: ({ size, className }: IconProps) => import("react").JSX.Element;
|
|
46
|
+
/** Browser tab glyph: a globe with meridians. */
|
|
47
|
+
export declare const IconGlobeOutline16: ({ size, className }: IconProps) => import("react").JSX.Element;
|
|
@@ -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,10 @@
|
|
|
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). */
|
|
5
|
+
export declare const inject: string[];
|
|
6
|
+
/**
|
|
7
|
+
* Client plugin body.
|
|
8
|
+
* @param ctx - the client cordis context (slots, sessions).
|
|
9
|
+
*/
|
|
10
|
+
export declare function apply(ctx: Context): void;
|
|
@@ -0,0 +1,20 @@
|
|
|
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
|
+
/** Register the turn-tail interception (returns the disposer). */
|
|
11
|
+
export declare function registerTurnTailInterception(ctx: Context, store: SidebarStore): () => void;
|
|
12
|
+
/**
|
|
13
|
+
* Register the chat file-open interception: wraps `ctx.workspaces.openPath`
|
|
14
|
+
* — the single funnel every chat-side file open goes through (tool-row path
|
|
15
|
+
* links, the produced-files row, prose mentions) — so opens land in the
|
|
16
|
+
* sidebar editor instead of the Host OS. Gated by BOTH the `interceptOpenPath`
|
|
17
|
+
* pref and the editor tab's enable switch; declined opens fall through to
|
|
18
|
+
* the original method. Returns the disposer restoring the original (HMR-safe).
|
|
19
|
+
*/
|
|
20
|
+
export declare function registerOpenPathInterception(ctx: Context, store: SidebarStore): () => void;
|