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,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure derivations for the Subagent page's background-job section. Kept
|
|
3
|
+
* framework-free so the node test environment can unit-test them: the job
|
|
4
|
+
* rows arrive through the harness `session/jobs` push mirror
|
|
5
|
+
* (`jobsBySession` in the sessions list feed) — nothing here issues
|
|
6
|
+
* requests, and the row ordering / status mapping mirror the official
|
|
7
|
+
* ui-jobs header list.
|
|
8
|
+
*/
|
|
9
|
+
import type { SidebarSessionList, SidebarJobStatus, SidebarJobView } from '../context-types.ts';
|
|
10
|
+
import type { CopyKey } from './locales.ts';
|
|
11
|
+
/** One row of the jobs section: the job plus its owning session's title. */
|
|
12
|
+
export interface TreeJob {
|
|
13
|
+
ownerSessionId: string;
|
|
14
|
+
ownerTitle: string;
|
|
15
|
+
job: SidebarJobView;
|
|
16
|
+
}
|
|
17
|
+
/** Whether the registry still holds the job open (its duration ticks). */
|
|
18
|
+
export declare function isJobLive(job: SidebarJobView): boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Every session id of the topology tree rooted at `rootId` (the root plus
|
|
21
|
+
* each session whose uninterrupted subagent-origin chain reaches it — same
|
|
22
|
+
* lineage semantics as {@link countSubagentDescendants}; cycles fail soft).
|
|
23
|
+
* Sessions outside the tree (orphans, other trees) are excluded, so the
|
|
24
|
+
* jobs section never shows foreign work.
|
|
25
|
+
*/
|
|
26
|
+
export declare function treeSessionIds(byId: SidebarSessionList['byId'], rootId: string | undefined): Set<string>;
|
|
27
|
+
/**
|
|
28
|
+
* Whether a NEW background job appeared for one session between two
|
|
29
|
+
* consecutive list snapshots (a job id the previous snapshot lacked).
|
|
30
|
+
* Unlike the subagent auto-open (0 → N only), ANY new job id triggers: the
|
|
31
|
+
* agent may start several jobs over a session, and each new one should
|
|
32
|
+
* surface the Jobs page (a fresh page load never triggers — its baseline
|
|
33
|
+
* starts at the current snapshot).
|
|
34
|
+
*/
|
|
35
|
+
export declare function detectNewJob(prev: SidebarSessionList, next: SidebarSessionList, sessionId: string): boolean;
|
|
36
|
+
/**
|
|
37
|
+
* Collect the background jobs of the whole current tree, owner-labeled.
|
|
38
|
+
* Sessions without a mirror entry contribute nothing; an absent mirror
|
|
39
|
+
* (runtime older than the jobs feed) yields an empty list.
|
|
40
|
+
*/
|
|
41
|
+
export declare function collectTreeJobs(byId: SidebarSessionList['byId'], jobsBySession: Readonly<Record<string, readonly SidebarJobView[]>> | undefined, rootId: string | undefined): TreeJob[];
|
|
42
|
+
/**
|
|
43
|
+
* Live rows first in start order, then settled rows newest-first (mirror of
|
|
44
|
+
* the official ui-jobs ordering); a tie falls back to start order so the
|
|
45
|
+
* sort never depends on the host's map iteration.
|
|
46
|
+
*/
|
|
47
|
+
export declare function orderJobs(rows: readonly TreeJob[]): TreeJob[];
|
|
48
|
+
/** The sidebar's StateDot states for the five wire statuses. */
|
|
49
|
+
export type JobDotState = 'ongoing' | 'warning' | 'done' | 'error';
|
|
50
|
+
/**
|
|
51
|
+
* Status marker semantics. `stopping` and `killed` share the attention
|
|
52
|
+
* color: both mean the work ended (or is ending) on request rather than on
|
|
53
|
+
* its own.
|
|
54
|
+
*/
|
|
55
|
+
export declare function jobDotState(status: SidebarJobStatus): JobDotState;
|
|
56
|
+
/** Human status word of one wire status (localized through the passed translator). */
|
|
57
|
+
export declare function jobStatusLabel(status: SidebarJobStatus, t: (key: CopyKey, params?: Record<string, string | number>) => string): string;
|
|
58
|
+
/**
|
|
59
|
+
* Elapsed time in at most two adjacent units (mirror of the official
|
|
60
|
+
* ui-jobs duration wording). A background job that outlives an hour is
|
|
61
|
+
* already exceptional, so hours is the widest unit.
|
|
62
|
+
*/
|
|
63
|
+
export declare function formatJobDuration(elapsedMs: number, t: (key: CopyKey, params?: Record<string, string | number>) => string): string;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Live theme access for surfaces that cannot consume the token colors
|
|
3
|
+
* directly — xterm's palette and CodeMirror's theme extensions need concrete
|
|
4
|
+
* values, but the app's scheme flips at runtime (ui-layout's ThemePresenter
|
|
5
|
+
* projects prefers-color-scheme and the user's choice onto
|
|
6
|
+
* body[data-ds-dark-theme] and html { color-scheme }). This module reads the
|
|
7
|
+
* resolved scheme and token values, and notifies subscribers on flips, so
|
|
8
|
+
* the terminal and the editor re-theme in place instead of freezing in the
|
|
9
|
+
* scheme they happened to be created under.
|
|
10
|
+
*/
|
|
11
|
+
/** Whether the app shell resolved to the dark scheme.
|
|
12
|
+
*
|
|
13
|
+
* The presenter sets `html { color-scheme }` together with the body palette
|
|
14
|
+
* attribute, so a set color-scheme means the decision is authoritative (an
|
|
15
|
+
* absent attribute is then LIGHT even when the OS prefers dark — the user
|
|
16
|
+
* chose light). Before the presenter has run, fall back to the OS media
|
|
17
|
+
* query as the best guess.
|
|
18
|
+
*/
|
|
19
|
+
export declare function isDarkScheme(): boolean;
|
|
20
|
+
/** One token's computed value on <body> ('' while the theme has not applied). */
|
|
21
|
+
export declare function tokenValue(name: string): string;
|
|
22
|
+
/**
|
|
23
|
+
* Subscribe to color-scheme flips (the presenter toggles the body
|
|
24
|
+
* attribute). The callback fires after the attribute changed; re-read the
|
|
25
|
+
* scheme inside it.
|
|
26
|
+
* @returns the disposer.
|
|
27
|
+
*/
|
|
28
|
+
export declare function subscribeColorScheme(callback: () => void): () => void;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Convert a SheetJS (xlsx) workbook into Univer's {@link IWorkbookData} so
|
|
3
|
+
* {@link XlsxView} can render it through the Univer sheets preset.
|
|
4
|
+
*
|
|
5
|
+
* v1 scope (matches docs/plans/2026-08-10-office-preview-design.md §3.6):
|
|
6
|
+
* - Sheet names + order
|
|
7
|
+
* - Cell values, typed (string / number / boolean / error → force-string)
|
|
8
|
+
* - Cell formulas (text form; Univer's formula engine computes them)
|
|
9
|
+
* - Merged cells (!merges → mergeData)
|
|
10
|
+
* - Column widths (!cols → columnData) and row heights (!rows → rowData)
|
|
11
|
+
*
|
|
12
|
+
* Out of scope for v1 (SheetJS community edition does not parse them and the
|
|
13
|
+
* Pro edition is commercial): cell styles (font/fill/border/alignment),
|
|
14
|
+
* conditional formatting, charts. Users who need style fidelity get the
|
|
15
|
+
* download button on the binary placeholder.
|
|
16
|
+
*
|
|
17
|
+
* The function is pure (no DOM, no Univer imports) so it is unit-testable
|
|
18
|
+
* without jsdom or canvas.
|
|
19
|
+
*/
|
|
20
|
+
import type * as XLSX from 'xlsx';
|
|
21
|
+
import { type LocaleType, type IWorkbookData } from '@univerjs/presets';
|
|
22
|
+
/** SheetJS workbook (the slice of the module we use). */
|
|
23
|
+
type XLSXWorkbook = XLSX.WorkBook;
|
|
24
|
+
/**
|
|
25
|
+
* Build a Univer workbook snapshot from a SheetJS workbook.
|
|
26
|
+
*
|
|
27
|
+
* @param wb - the parsed workbook from `XLSX.read(buf, { type: 'array' })`
|
|
28
|
+
* @param appVersion - the Univer package version, written into `appVersion`
|
|
29
|
+
* (Univer requires the field but does not gate on it).
|
|
30
|
+
* @param locale - the locale Univer should render in.
|
|
31
|
+
*/
|
|
32
|
+
export declare function xlsxWorkbookToUniver(wb: XLSXWorkbook, appVersion: string, locale: LocaleType): IWorkbookData;
|
|
33
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type OfficeViewProps } from './office-shared.tsx';
|
|
2
|
+
import '@univerjs/preset-sheets-core/lib/index.css';
|
|
3
|
+
/**
|
|
4
|
+
* Render a .xlsx file via Univer. The sheets preset creates a canvas-based
|
|
5
|
+
* spreadsheet (formula bar, sheet tabs, formula engine) sized to its
|
|
6
|
+
* container, so the host fills the pane. Unmounting calls `univer.dispose()`
|
|
7
|
+
* — without it the canvas, workers, and DOM listeners leak (mirrors the
|
|
8
|
+
* xterm dispose discipline in TerminalView).
|
|
9
|
+
*/
|
|
10
|
+
export declare function XlsxView(props: OfficeViewProps): JSX.Element;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Serializable configuration and defaults for the sidebar host half. Loader
|
|
3
|
+
* schema validation normally fills defaults; {@link resolveSidebarConfig}
|
|
4
|
+
* applies the same defaults for direct callers that bypass the Loader.
|
|
5
|
+
* @module dsh-better-sidebar/config
|
|
6
|
+
*/
|
|
7
|
+
import z from 'schemastery';
|
|
8
|
+
import { type SidebarPrefs } from './prefs-shared.ts';
|
|
9
|
+
export { SIDEBAR_PREFS_DEFAULTS, SIDEBAR_PREFS_NS, WIDTH_PERCENT_DEFAULT, WIDTH_PERCENT_MAX, WIDTH_PERCENT_MIN, type SidebarPrefs, } from './prefs-shared.ts';
|
|
10
|
+
/** Tunable sidebar host limits (every field optional; defaults fill in). */
|
|
11
|
+
export interface SidebarConfig {
|
|
12
|
+
/** Read cap of one text file (bytes); larger files return truncated. */
|
|
13
|
+
readLimit?: number;
|
|
14
|
+
/** Media route cap (bytes); larger binaries are refused. */
|
|
15
|
+
mediaLimit?: number;
|
|
16
|
+
/** Explorer row bound of one level. */
|
|
17
|
+
listLimit?: number;
|
|
18
|
+
/** Terminals per session. */
|
|
19
|
+
terminalsPerSession?: number;
|
|
20
|
+
/** How long a disconnected terminal process survives awaiting a reconnect. */
|
|
21
|
+
reconnectGraceMs?: number;
|
|
22
|
+
}
|
|
23
|
+
/** Schemastery schema for the plugin configuration. */
|
|
24
|
+
export declare const Config: z<SidebarConfig>;
|
|
25
|
+
/** Fully defaulted sidebar host settings. */
|
|
26
|
+
export interface ResolvedSidebarConfig {
|
|
27
|
+
readLimit: number;
|
|
28
|
+
mediaLimit: number;
|
|
29
|
+
listLimit: number;
|
|
30
|
+
terminalsPerSession: number;
|
|
31
|
+
reconnectGraceMs: number;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Apply direct-call defaults after Loader schema validation has normally run.
|
|
35
|
+
*
|
|
36
|
+
* @param config - Deployment-provided sidebar host settings.
|
|
37
|
+
* @returns Complete settings consumed by the host half.
|
|
38
|
+
*/
|
|
39
|
+
export declare function resolveSidebarConfig(config: SidebarConfig | undefined): ResolvedSidebarConfig;
|
|
40
|
+
/** Schemastery schema for the user-facing preferences (validated by the settings service). */
|
|
41
|
+
export declare const PrefsSchema: z<SidebarPrefs>;
|
|
@@ -0,0 +1,431 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Structural types for the cordis services this plugin consumes, plus the
|
|
3
|
+
* Context augmentation both halves share. A third-party plugin resolves
|
|
4
|
+
* outside the DSH monorepo's single cordis instance, so the upstream
|
|
5
|
+
* `declare module 'cordis'` augmentations do not reach this Context — and
|
|
6
|
+
* the npm cordis package does not declare the DSH-vendored runtime members
|
|
7
|
+
* (`ctx.effect`, service properties). The members below mirror the actual
|
|
8
|
+
* runtime shapes this plugin touches:
|
|
9
|
+
* - webServer: @deepseek-ai/dsh-host-webserver (the WebServer)
|
|
10
|
+
* - sessions: host side @deepseek-ai/dsh-session (SessionStore), client
|
|
11
|
+
* side the runtime ISessions list feed
|
|
12
|
+
* - conversation: client side ui-conversation's IConversation (composer
|
|
13
|
+
* draft), read lazily through `ctx.get` — cross-plugin service reads need
|
|
14
|
+
* an inject declaration, so the direct property is never typed here
|
|
15
|
+
* - loader: @cordisjs/plugin-loader (entry options)
|
|
16
|
+
* - slots: the client runtime SlotRegistry
|
|
17
|
+
* - effect: the DSH-vendored cordis lifecycle helper
|
|
18
|
+
* Drift from upstream is contained to this file.
|
|
19
|
+
*/
|
|
20
|
+
import type { IncomingMessage, ServerResponse } from 'node:http';
|
|
21
|
+
import type { Duplex } from 'node:stream';
|
|
22
|
+
import type { Context } from 'cordis';
|
|
23
|
+
import type { BetterSidebarService } from './client/service.ts';
|
|
24
|
+
/** One named webserver route (mirror of the host-webserver WebRoute). */
|
|
25
|
+
export interface SidebarWebRoute {
|
|
26
|
+
kind: 'exact' | 'prefix';
|
|
27
|
+
path: string;
|
|
28
|
+
handler: (req: IncomingMessage, res: ServerResponse) => void | Promise<void>;
|
|
29
|
+
}
|
|
30
|
+
/** One exact-path HTTP upgrade registration (mirror of WebUpgradeRoute). */
|
|
31
|
+
export interface SidebarWebUpgradeRoute {
|
|
32
|
+
path: string;
|
|
33
|
+
handler: (req: IncomingMessage, socket: Duplex, head: Buffer) => void | Promise<void>;
|
|
34
|
+
}
|
|
35
|
+
/** The webServer service face this plugin uses. */
|
|
36
|
+
export interface SidebarWebServer {
|
|
37
|
+
register(route: SidebarWebRoute): () => void;
|
|
38
|
+
registerUpgrade(route: SidebarWebUpgradeRoute): () => void;
|
|
39
|
+
}
|
|
40
|
+
/** A published session's header slice the sidebar reads (authoritative cwd). */
|
|
41
|
+
export interface SidebarSessionHeader {
|
|
42
|
+
cwd?: string;
|
|
43
|
+
}
|
|
44
|
+
/** The host session store face (`ctx.sessions.get(id)` returns the live session). */
|
|
45
|
+
export interface SidebarSessionStore {
|
|
46
|
+
get(id: string): {
|
|
47
|
+
header: SidebarSessionHeader;
|
|
48
|
+
/**
|
|
49
|
+
* The live session's append-only event log (immutable snapshot; absent
|
|
50
|
+
* on sessions the runtime has not hydrated). Read-only access — the
|
|
51
|
+
* jobs.output route replays `job_output` tool/result rows from it.
|
|
52
|
+
*/
|
|
53
|
+
events?: readonly SidebarSessionEvent[];
|
|
54
|
+
} | undefined;
|
|
55
|
+
}
|
|
56
|
+
/** One loader entry's options slice (the connection row's resolved config). */
|
|
57
|
+
export interface SidebarLoaderEntry {
|
|
58
|
+
options: {
|
|
59
|
+
name: string;
|
|
60
|
+
config?: unknown;
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
/** The loader face used to read the connection row's trustedHosts config. */
|
|
64
|
+
export interface SidebarLoader {
|
|
65
|
+
entries(): Iterable<SidebarLoaderEntry>;
|
|
66
|
+
}
|
|
67
|
+
/** Registration options the sidebar passes to `ctx.slots.register` (subset of the real options). */
|
|
68
|
+
export interface SidebarSlotRegisterOptions {
|
|
69
|
+
name: string;
|
|
70
|
+
key?: string;
|
|
71
|
+
id?: string;
|
|
72
|
+
order?: number;
|
|
73
|
+
label?: string | (() => string);
|
|
74
|
+
/** Chain routing selector (returns the matched value, or null to pass on). */
|
|
75
|
+
select?: (owner: unknown) => unknown;
|
|
76
|
+
priority?: number;
|
|
77
|
+
locale?: string;
|
|
78
|
+
registrant?: string;
|
|
79
|
+
/** Business-face factory; args depend on the slot scope. */
|
|
80
|
+
inject?: (...args: any[]) => Record<string, unknown>;
|
|
81
|
+
children?: Record<string, unknown>;
|
|
82
|
+
}
|
|
83
|
+
/** The client slots service face (register returns the disposer). */
|
|
84
|
+
export interface SidebarSlotsService {
|
|
85
|
+
register(options: SidebarSlotRegisterOptions, component: unknown): () => void;
|
|
86
|
+
/**
|
|
87
|
+
* Run a callback for each declaration lifetime of a slot (the runtime
|
|
88
|
+
* SlotRegistry.inject): a no-op while the slot is undeclared, so the
|
|
89
|
+
* settings section registration waits for the settings shell.
|
|
90
|
+
*/
|
|
91
|
+
inject(key: string, callback: () => () => void): () => void;
|
|
92
|
+
}
|
|
93
|
+
/** The client session list row the sidebar reads (cwd for the explorer). */
|
|
94
|
+
export interface SidebarSessionSummary {
|
|
95
|
+
id: string;
|
|
96
|
+
cwd?: string;
|
|
97
|
+
displayTitle: string;
|
|
98
|
+
/** Coarse durable origin for navigation filtering (subagent children). */
|
|
99
|
+
origin?: 'subagent';
|
|
100
|
+
/** Durable direct parent session id (present on subagent children). */
|
|
101
|
+
parentId?: string;
|
|
102
|
+
/** Whether the session's agent is currently running. */
|
|
103
|
+
running?: boolean;
|
|
104
|
+
}
|
|
105
|
+
/** One healthy subagent catalog child row (structural mirror of the runtime). */
|
|
106
|
+
export interface SidebarSubagentChildEntry {
|
|
107
|
+
kind: 'child';
|
|
108
|
+
id: string;
|
|
109
|
+
/** Whether the child Agent driver is running at the Host sampling boundary. */
|
|
110
|
+
activity: 'running' | 'inactive';
|
|
111
|
+
/** Whether a direct descendant has durable `origin: 'subagent'`. */
|
|
112
|
+
hasChildren: boolean;
|
|
113
|
+
mode: 'one-shot' | 'continuable';
|
|
114
|
+
label?: string;
|
|
115
|
+
}
|
|
116
|
+
/** One unreadable catalog row (corrupt / unsupported / unavailable). */
|
|
117
|
+
export interface SidebarSubagentDiagnosticEntry {
|
|
118
|
+
kind: 'diagnostic';
|
|
119
|
+
id: string;
|
|
120
|
+
reason: 'corrupt' | 'unsupported' | 'unavailable';
|
|
121
|
+
}
|
|
122
|
+
/** The per-parent lazy catalog delivered through the sessions list feed. */
|
|
123
|
+
export interface SidebarSubagentCatalog {
|
|
124
|
+
entries: Array<SidebarSubagentChildEntry | SidebarSubagentDiagnosticEntry>;
|
|
125
|
+
parentAvailable: boolean;
|
|
126
|
+
state: 'loading' | 'ready' | 'error';
|
|
127
|
+
error: {
|
|
128
|
+
code?: string;
|
|
129
|
+
message?: string;
|
|
130
|
+
} | null;
|
|
131
|
+
}
|
|
132
|
+
/** Durable parent/child address that selects subagent transport in the client. */
|
|
133
|
+
export interface SidebarSubagentAddress {
|
|
134
|
+
parentSessionId: string;
|
|
135
|
+
childSessionId: string;
|
|
136
|
+
mode: 'one-shot' | 'continuable';
|
|
137
|
+
}
|
|
138
|
+
/** Minimal structural mirror of one session event (the subagent history tail). */
|
|
139
|
+
export interface SidebarSessionEvent {
|
|
140
|
+
type: string;
|
|
141
|
+
seq: number;
|
|
142
|
+
time: number;
|
|
143
|
+
data: Record<string, unknown>;
|
|
144
|
+
}
|
|
145
|
+
/** One history row: the durable event plus an optional tool presentation view. */
|
|
146
|
+
export interface SidebarHistoryEntry {
|
|
147
|
+
event: SidebarSessionEvent;
|
|
148
|
+
view?: unknown;
|
|
149
|
+
}
|
|
150
|
+
/** Lifecycle status set of one background job (closed wire union). */
|
|
151
|
+
export type SidebarJobStatus = 'running' | 'stopping' | 'completed' | 'killed' | 'failed';
|
|
152
|
+
/**
|
|
153
|
+
* One background job as the client mirror sees it (wire `JobView` shape:
|
|
154
|
+
* id/kind/label/status/detail?/startedAt/finishedAt?).
|
|
155
|
+
*/
|
|
156
|
+
export interface SidebarJobView {
|
|
157
|
+
/** Registry-issued `<kind>-N` identity, stable for the job's whole life. */
|
|
158
|
+
id: string;
|
|
159
|
+
/** Producer kind (`bash`, `pwsh`, `subagent`, …; open string by design). */
|
|
160
|
+
kind: string;
|
|
161
|
+
/** Producer-supplied one-line label: the command, or the delegation description. */
|
|
162
|
+
label: string;
|
|
163
|
+
/** Current lifecycle state. */
|
|
164
|
+
status: SidebarJobStatus;
|
|
165
|
+
/** Kind-specific status detail ('exit code: 3'), present once supplied. */
|
|
166
|
+
detail?: string;
|
|
167
|
+
/** Epoch ms when the job was registered. */
|
|
168
|
+
startedAt: number;
|
|
169
|
+
/** Epoch ms when the job settled; absent while live. */
|
|
170
|
+
finishedAt?: number;
|
|
171
|
+
}
|
|
172
|
+
/** The host jobs registry face the sidebar routes touch (structural mirror of `JobRegistry`). */
|
|
173
|
+
export interface SidebarJobsService {
|
|
174
|
+
/** Request cancellation; throws for an unknown or foreign job. */
|
|
175
|
+
kill(id: string, caller?: SidebarAgent, reason?: string): 'requested' | 'already-finished';
|
|
176
|
+
}
|
|
177
|
+
/** The host agent registry face (structural mirror of the runtime `ctx.agents`). */
|
|
178
|
+
export interface SidebarAgentsService {
|
|
179
|
+
/** The live agent registered under a session id, or undefined when not live. */
|
|
180
|
+
get(id: string): SidebarAgent | undefined;
|
|
181
|
+
}
|
|
182
|
+
/** RPC result slot mirror (`RpcResult<T>` on the wire). */
|
|
183
|
+
export type SidebarRpcResult<T> = {
|
|
184
|
+
ok: true;
|
|
185
|
+
value: T;
|
|
186
|
+
} | {
|
|
187
|
+
ok: false;
|
|
188
|
+
error: {
|
|
189
|
+
code: string;
|
|
190
|
+
message: string;
|
|
191
|
+
};
|
|
192
|
+
};
|
|
193
|
+
/** Unary response mirror (`RpcResponse<T>` on the wire). */
|
|
194
|
+
export interface SidebarRpcResponse<T> {
|
|
195
|
+
rpcId: unknown;
|
|
196
|
+
result: SidebarRpcResult<T>;
|
|
197
|
+
}
|
|
198
|
+
/** The wire face the Subagent activity summary needs (subset of `ctx.connection`). */
|
|
199
|
+
export interface SidebarConnectionHandle {
|
|
200
|
+
api: {
|
|
201
|
+
subagents: {
|
|
202
|
+
history(payload: SidebarSubagentAddress & {
|
|
203
|
+
beforeSeq?: number;
|
|
204
|
+
maxMessages?: number;
|
|
205
|
+
}, signal?: AbortSignal): Promise<SidebarRpcResponse<{
|
|
206
|
+
events: SidebarHistoryEntry[];
|
|
207
|
+
hasMore: boolean;
|
|
208
|
+
}>>;
|
|
209
|
+
};
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
/** The client session list snapshot the sidebar subscribes to. */
|
|
213
|
+
export interface SidebarSessionList {
|
|
214
|
+
current: string | undefined;
|
|
215
|
+
byId: Record<string, SidebarSessionSummary>;
|
|
216
|
+
/** Direct durable catalogs keyed by their selected parent address. */
|
|
217
|
+
subagentsByParent?: Readonly<Record<string, SidebarSubagentCatalog>>;
|
|
218
|
+
/**
|
|
219
|
+
* Background jobs per session, last-wins from the harness's `session/jobs`
|
|
220
|
+
* push (a missing key is an empty set). Absent on runtime snapshots older
|
|
221
|
+
* than the jobs mirror — the sidebar simply shows no job rows.
|
|
222
|
+
*/
|
|
223
|
+
jobsBySession?: Readonly<Record<string, readonly SidebarJobView[]>>;
|
|
224
|
+
}
|
|
225
|
+
/** The client sessions service face (only the list feed is needed). */
|
|
226
|
+
export interface SidebarSessionsService {
|
|
227
|
+
list: {
|
|
228
|
+
getSnapshot(): SidebarSessionList;
|
|
229
|
+
subscribe(fn: () => void): () => void;
|
|
230
|
+
};
|
|
231
|
+
/**
|
|
232
|
+
* Select a listed session as current (mirror of the runtime ISessions.open)
|
|
233
|
+
* — used to jump back to the main agent from the topology root node.
|
|
234
|
+
*/
|
|
235
|
+
open?(id: string): void;
|
|
236
|
+
/**
|
|
237
|
+
* Resolve an Agent-scoped context view for one session (mirror of the
|
|
238
|
+
* runtime ISessions.scope) — the ticket `ctx.conversation.input.for`
|
|
239
|
+
* requires to reach that session's composer.
|
|
240
|
+
*/
|
|
241
|
+
scope(id: string): Context | undefined;
|
|
242
|
+
/**
|
|
243
|
+
* Open a healthy catalog child through its exact direct-parent address
|
|
244
|
+
* (mirror of the runtime ISessions.openSubagent).
|
|
245
|
+
*/
|
|
246
|
+
openSubagent?(address: SidebarSubagentAddress): void;
|
|
247
|
+
/**
|
|
248
|
+
* Resolve an already discovered direct-parent address without opening it.
|
|
249
|
+
*/
|
|
250
|
+
subagentAddress?(id: string): SidebarSubagentAddress | undefined;
|
|
251
|
+
/**
|
|
252
|
+
* Mark whether a catalog surface is consuming live membership updates.
|
|
253
|
+
*/
|
|
254
|
+
setSubagentCatalogOpen?(parentSessionId: string, open: boolean): void;
|
|
255
|
+
/**
|
|
256
|
+
* Refresh one direct-child catalog.
|
|
257
|
+
*/
|
|
258
|
+
refreshSubagents?(parentSessionId: string): Promise<void>;
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* The client locale service face (mirror of @deepseek-ai/dsh-client-locale's
|
|
262
|
+
* LocaleRuntime — only the slices the sidebar touches). The sidebar follows
|
|
263
|
+
* the DSH i18n system: the active locale is the Host-backed preference
|
|
264
|
+
* (`locale.preference` in settings.yaml) rather than the raw browser
|
|
265
|
+
* language, and the sidebar's zh/en dictionaries register into the service's
|
|
266
|
+
* namespace registry under `betterSidebar`.
|
|
267
|
+
*/
|
|
268
|
+
export interface SidebarLocaleService {
|
|
269
|
+
/** Current immutable locale snapshot (uSES-safe; `active` is 'zh' | 'en' today). */
|
|
270
|
+
getSnapshot(): {
|
|
271
|
+
active: string;
|
|
272
|
+
};
|
|
273
|
+
/** Subscribe to snapshot changes (locale switch or dictionary registration). */
|
|
274
|
+
subscribe(fn: () => void): () => void;
|
|
275
|
+
/** Register one locale's dictionary for a namespace; returns the disposer. */
|
|
276
|
+
register(ns: string, locale: string, dict: Record<string, string>): () => void;
|
|
277
|
+
}
|
|
278
|
+
/** The composer draft face the sidebar reaches through `ctx.conversation.input`. */
|
|
279
|
+
export interface SidebarSessionInput {
|
|
280
|
+
/** The live input store (draft read for append). */
|
|
281
|
+
state: {
|
|
282
|
+
getSnapshot(): {
|
|
283
|
+
draft: string;
|
|
284
|
+
};
|
|
285
|
+
};
|
|
286
|
+
/** Replace the draft text (the input machine's single public write path). */
|
|
287
|
+
setDraft(text: string): void;
|
|
288
|
+
}
|
|
289
|
+
/** The composer draft face the sidebar reaches through `ctx.get('conversation')`. */
|
|
290
|
+
export interface SidebarConversation {
|
|
291
|
+
input: {
|
|
292
|
+
for(actx: Context): SidebarSessionInput;
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* The client workspaces service face (mirror of the runtime IWorkspaces). Only
|
|
297
|
+
* the chat's file-open funnel is touched: `openPath` hands an absolute path
|
|
298
|
+
* to the Host OS's default application, and every chat-side file open
|
|
299
|
+
* (tool rows, produced-files, prose mentions) funnels through it.
|
|
300
|
+
*/
|
|
301
|
+
export interface SidebarWorkspacesService {
|
|
302
|
+
/** Open a filesystem path with the Host operating system's default application. */
|
|
303
|
+
openPath(path: string): Promise<void>;
|
|
304
|
+
}
|
|
305
|
+
/**
|
|
306
|
+
* The invariant service face (mirror of @deepseek-ai/dsh-invariants'
|
|
307
|
+
* InvariantRegistry). The upstream augmentation does not reach this Context
|
|
308
|
+
* (dual-cordis-instance resolution), so the register signature is restated
|
|
309
|
+
* structurally, exactly like the other service faces above.
|
|
310
|
+
*/
|
|
311
|
+
export interface SidebarInvariantsService {
|
|
312
|
+
/** Reserve one package's checks and install them in the service's child fiber. */
|
|
313
|
+
register(packageName: string, installer: (ctx: Context, fail: (message: string) => never) => void | Promise<void>): () => void;
|
|
314
|
+
}
|
|
315
|
+
/** The settings service face (mirror of @deepseek-ai/dsh-settings' SettingsProvider). */
|
|
316
|
+
export interface SidebarSettingsService {
|
|
317
|
+
/**
|
|
318
|
+
* Register one namespace schema (the resolved value layers schema defaults,
|
|
319
|
+
* then the composition base, then the user document).
|
|
320
|
+
*/
|
|
321
|
+
register<T>(ns: string, schema: unknown, options?: {
|
|
322
|
+
base?: Partial<T>;
|
|
323
|
+
applies?: 'live' | 'restart';
|
|
324
|
+
}): {
|
|
325
|
+
get(): T;
|
|
326
|
+
watch(callback: (next: T, prev: T) => void | Promise<void>): () => void;
|
|
327
|
+
update(patch: object): Promise<void>;
|
|
328
|
+
replace(section: object): Promise<void>;
|
|
329
|
+
};
|
|
330
|
+
/** Redacted descriptors of every registered namespace (secrets stripped). */
|
|
331
|
+
describe(options?: {
|
|
332
|
+
redactSecrets?: boolean;
|
|
333
|
+
}): Array<{
|
|
334
|
+
ns: string;
|
|
335
|
+
value?: unknown;
|
|
336
|
+
base?: unknown;
|
|
337
|
+
user?: unknown;
|
|
338
|
+
applies: 'live' | 'restart';
|
|
339
|
+
revision: number;
|
|
340
|
+
}>;
|
|
341
|
+
/** Service-level merge write with the revision guard (a stale writer is refused). */
|
|
342
|
+
update(ns: string, patch: object, expectedRevision?: number): Promise<void>;
|
|
343
|
+
}
|
|
344
|
+
/**
|
|
345
|
+
* The tools service face (mirror of @deepseek-ai/dsh-tools' ToolRuntime).
|
|
346
|
+
* The host half registers model-facing tools here; the registry attaches the
|
|
347
|
+
* returned disposer to the contributing fiber so unloading unregisters them.
|
|
348
|
+
*/
|
|
349
|
+
export interface SidebarToolsService {
|
|
350
|
+
/** Register one tool definition (raw JSON-Schema or defineTool-sugar form). */
|
|
351
|
+
register(tool: unknown): () => void;
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* The agent face a tool sees on `exec.agent` (mirror of @deepseek-ai/dsh-agent's
|
|
355
|
+
* Agent). Only the slices the terminal tools touch are restated: the live
|
|
356
|
+
* session identity and its header cwd, both readonly.
|
|
357
|
+
*/
|
|
358
|
+
export interface SidebarAgent {
|
|
359
|
+
/** The live session identity shared with the session log. */
|
|
360
|
+
readonly id: string;
|
|
361
|
+
/** The live session this agent drives. */
|
|
362
|
+
readonly session: {
|
|
363
|
+
/** The session's header (validated cwd, lineage metadata). */
|
|
364
|
+
readonly header: {
|
|
365
|
+
readonly cwd?: string;
|
|
366
|
+
};
|
|
367
|
+
};
|
|
368
|
+
}
|
|
369
|
+
declare module 'cordis' {
|
|
370
|
+
interface Context {
|
|
371
|
+
webServer: SidebarWebServer;
|
|
372
|
+
sessions: SidebarSessionStore & SidebarSessionsService;
|
|
373
|
+
connection: SidebarConnectionHandle;
|
|
374
|
+
loader: SidebarLoader;
|
|
375
|
+
slots: SidebarSlotsService;
|
|
376
|
+
workspaces: SidebarWorkspacesService;
|
|
377
|
+
settings: SidebarSettingsService;
|
|
378
|
+
invariants: SidebarInvariantsService;
|
|
379
|
+
tools: SidebarToolsService;
|
|
380
|
+
/**
|
|
381
|
+
* The client locale service (`@deepseek-ai/dsh-client-locale`): the
|
|
382
|
+
* sidebar's copy follows its active locale and registers its
|
|
383
|
+
* dictionaries under the `betterSidebar` namespace. Client side only.
|
|
384
|
+
*/
|
|
385
|
+
locale: SidebarLocaleService;
|
|
386
|
+
/**
|
|
387
|
+
* The host background-job registry (`ctx.get('jobs')`; optional — the
|
|
388
|
+
* sidebar routes degrade to a 503 when the deployment lacks it).
|
|
389
|
+
*/
|
|
390
|
+
jobs: SidebarJobsService;
|
|
391
|
+
/**
|
|
392
|
+
* The host live-agent registry (`ctx.get('agents')`; optional — used to
|
|
393
|
+
* resolve the caller the jobs fence compares against).
|
|
394
|
+
*/
|
|
395
|
+
agents: SidebarAgentsService;
|
|
396
|
+
/**
|
|
397
|
+
* The client-side sidebar registry: external plugins register tab types
|
|
398
|
+
* and file previewers here. Provided by the client half (see
|
|
399
|
+
* {@link ./client/index.tsx}); undefined on the host side.
|
|
400
|
+
*/
|
|
401
|
+
betterSidebar: BetterSidebarService;
|
|
402
|
+
/**
|
|
403
|
+
* Subscribe to the session append feed (mirror of the cordis event API):
|
|
404
|
+
* the listener receives every appended session event with the LIVE
|
|
405
|
+
* Session instance that appended it. The api-proxy pushes the same feed
|
|
406
|
+
* to browsers; the sidebar uses it to mirror job_output events the
|
|
407
|
+
* session store's own log can lag behind (restart divergence). Returns
|
|
408
|
+
* the disposer.
|
|
409
|
+
*/
|
|
410
|
+
on(event: string, listener: (session: unknown, event: SidebarSessionEvent) => void): () => void;
|
|
411
|
+
/**
|
|
412
|
+
* Register a lifecycle callback (DSH-vendored cordis): runs at plugin
|
|
413
|
+
* activation; its returned cleanup runs at disposal.
|
|
414
|
+
*/
|
|
415
|
+
effect(fn: () => void | (() => void), label?: string): void;
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
/**
|
|
419
|
+
* Dual cordis-scope augmentation: DSH's runtime (and the public packages)
|
|
420
|
+
* resolve against the vendored `@deepseek-ai/cordis` scope, which DSH's own
|
|
421
|
+
* packages already augment with `effect`/`on`/service members. This side only
|
|
422
|
+
* adds the sidebar service member so consumers importing `Context` from
|
|
423
|
+
* `@deepseek-ai/cordis` (instead of the public `cordis` above) still see
|
|
424
|
+
* `ctx.betterSidebar`.
|
|
425
|
+
*/
|
|
426
|
+
declare module '@deepseek-ai/cordis' {
|
|
427
|
+
interface Context {
|
|
428
|
+
betterSidebar: BetterSidebarService;
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
export type { Context };
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/** One explorer row. */
|
|
2
|
+
export interface SidebarFsEntry {
|
|
3
|
+
name: string;
|
|
4
|
+
path: string;
|
|
5
|
+
isDir: boolean;
|
|
6
|
+
hidden: boolean;
|
|
7
|
+
}
|
|
8
|
+
/** One listed level. */
|
|
9
|
+
export interface SidebarFsListing {
|
|
10
|
+
path: string;
|
|
11
|
+
entries: SidebarFsEntry[];
|
|
12
|
+
truncated: boolean;
|
|
13
|
+
}
|
|
14
|
+
/** Directory-first, case-insensitive name ordering (VSCode explorer order). */
|
|
15
|
+
export declare function compareEntries(a: SidebarFsEntry, b: SidebarFsEntry): number;
|
|
16
|
+
/**
|
|
17
|
+
* List one directory level.
|
|
18
|
+
* @param path - absolute directory path.
|
|
19
|
+
* @param maxEntries - row bound of one level (extra rows flag `truncated`).
|
|
20
|
+
* @returns the sorted listing.
|
|
21
|
+
* @throws {SidebarError} fs-error when the level is unreadable or not a directory.
|
|
22
|
+
*/
|
|
23
|
+
export declare function listDirectory(path: string, maxEntries?: number): Promise<SidebarFsListing>;
|
|
24
|
+
/** The root row label of a listing: the last path segment (or the full path at the filesystem root). */
|
|
25
|
+
export declare function rootLabel(path: string): string;
|
|
26
|
+
/** Parent of a path, or undefined at the filesystem root (the explorer's "up" target). */
|
|
27
|
+
export declare function parentOf(path: string): string | undefined;
|
|
28
|
+
/** Normalize a caller-supplied path to an absolute, resolved path or throw fs-error. */
|
|
29
|
+
export declare function requireAbsolute(path: string): string;
|
|
30
|
+
/**
|
|
31
|
+
* Whether `target` lies under `base` (or equals it), tolerant of separator
|
|
32
|
+
* style and — on Windows, where the filesystem is case-insensitive — of
|
|
33
|
+
* letter case. The media route uses this instead of a raw `startsWith` so a
|
|
34
|
+
* case-mismatched or mixed-separator path can never be misclassified
|
|
35
|
+
* (e.g. `C:\Users\Me` vs `c:/users/me/file.png`).
|
|
36
|
+
* @param platform - filesystem semantics; injectable so both branches are
|
|
37
|
+
* unit-testable on any host.
|
|
38
|
+
*/
|
|
39
|
+
export declare function isWithin(base: string, target: string, platform?: NodeJS.Platform): boolean;
|
|
40
|
+
/** Message text of an unknown thrown value. */
|
|
41
|
+
export declare function messageOf(error: unknown): string;
|