@benz-ai-x/dsh-md-preview 0.7.2 → 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/README.md +5 -3
- package/README.zh.md +6 -3
- package/lib/client.js +910 -525
- package/lib/index.js +102 -3
- package/lib/typert/remote-client.js +47 -0
- package/lib/types/client/DocumentIcon.d.ts +7 -0
- package/lib/types/client/PanelToggle.d.ts +10 -0
- package/lib/types/client/PreviewOverlay.d.ts +21 -4
- package/lib/types/client/WorkspaceBrowser.d.ts +30 -17
- package/lib/types/client/WorkspaceDocsAction.d.ts +27 -15
- package/lib/types/client/document-path.d.ts +6 -0
- package/lib/types/client/leave-intent.d.ts +31 -0
- package/lib/types/client/locale.d.ts +26 -2
- package/lib/types/client/outline.d.ts +2 -0
- package/lib/types/client/panel-dock.d.ts +32 -0
- package/lib/types/client/preferences.d.ts +63 -0
- package/lib/types/client/preview-session.d.ts +5 -7
- package/lib/types/client/reading.d.ts +97 -0
- package/lib/types/client/turn-files.d.ts +48 -0
- package/lib/types/client/use-panel-dock.d.ts +8 -0
- package/lib/types/client/use-preview-session.d.ts +0 -2
- package/lib/types/config.d.ts +6 -0
- package/lib/types/constants.d.ts +8 -0
- package/lib/types/index.d.ts +2 -2
- package/lib/types/protocol.d.ts +27 -0
- package/lib/types/remote.d.ts +18 -1
- package/lib/types/typert/remote-client.d.ts +3 -1
- package/package.json +1 -1
- package/lib/types/client/FileManagerAction.d.ts +0 -31
- package/lib/types/client/SideBrowser.d.ts +0 -43
- package/lib/types/client/WorkspaceDocsDock.d.ts +0 -40
- package/lib/types/client/WorkspaceDocsView.d.ts +0 -29
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
* lifecycle — content read, edit session, guarded save, prompts. The React
|
|
4
4
|
* adapter lives beside the panel (use-preview-session.ts); effects and RPC
|
|
5
5
|
* never enter here. `READ_STARTED` is the single reset point: a new read
|
|
6
|
-
* begins only when the previous document's whole session is over.
|
|
6
|
+
* begins only when the previous document's whole session is over. Leaving
|
|
7
|
+
* with a dirty draft is asked about at the leave-intent seat (leave-intent.ts)
|
|
8
|
+
* before anything reaches this machine, so no unsaved prompt lives here.
|
|
7
9
|
*/
|
|
8
10
|
import type { MdPreviewFile, MdPreviewWriteResult } from '../protocol.ts';
|
|
9
11
|
/** Content lifecycle of one preview target. */
|
|
@@ -34,10 +36,10 @@ export interface PreviewSessionState {
|
|
|
34
36
|
readonly code: string;
|
|
35
37
|
readonly message: string;
|
|
36
38
|
} | null;
|
|
37
|
-
/** The unsaved guard is asking before a close. */
|
|
38
|
-
readonly unsavedPrompt: boolean;
|
|
39
39
|
/** The saved toast is showing. */
|
|
40
40
|
readonly toast: boolean;
|
|
41
|
+
/** The write succeeded and the confirming re-read has not settled yet (#23). */
|
|
42
|
+
readonly savedPendingRead: boolean;
|
|
41
43
|
/** The session asked the shell to close the panel; the adapter acts once. */
|
|
42
44
|
readonly closeRequested: boolean;
|
|
43
45
|
}
|
|
@@ -73,10 +75,6 @@ export type PreviewSessionAction = {
|
|
|
73
75
|
readonly type: 'CANCEL_EDIT';
|
|
74
76
|
} | {
|
|
75
77
|
readonly type: 'REQUEST_CLOSE';
|
|
76
|
-
} | {
|
|
77
|
-
readonly type: 'DISCARD';
|
|
78
|
-
} | {
|
|
79
|
-
readonly type: 'KEEP_EDITING';
|
|
80
78
|
} | {
|
|
81
79
|
readonly type: 'TOAST_EXPIRED';
|
|
82
80
|
};
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The reading record (#25): what lets a reopened document land back near
|
|
3
|
+
* where reading stopped. UI-local viewing state only — keyed by (session,
|
|
4
|
+
* path), holding nothing but position facts (section identity, offsets,
|
|
5
|
+
* fractions, timestamps); never a document body, draft, or fingerprint.
|
|
6
|
+
* The envelope is versioned, every loaded record is validated, and the
|
|
7
|
+
* collection is bounded. Storage damage or absence degrades to an empty
|
|
8
|
+
* (then in-memory) store — reading itself never depends on it.
|
|
9
|
+
*/
|
|
10
|
+
import type { OutlineEntry } from './outline.ts';
|
|
11
|
+
/** Records kept at most; the oldest `at` evict first. */
|
|
12
|
+
export declare const MAX_READING_RECORDS = 50;
|
|
13
|
+
/** Envelope format version; an unknown version means an unreadable store. */
|
|
14
|
+
export declare const READING_RECORD_VERSION = 1;
|
|
15
|
+
/** The minimal persistence face the store needs (a subset of DOM Storage). */
|
|
16
|
+
export interface StorageLike {
|
|
17
|
+
getItem(key: string): string | null;
|
|
18
|
+
setItem(key: string, value: string): void;
|
|
19
|
+
}
|
|
20
|
+
/** Section identity: the heading text plus its occurrence ordinal among same-text headings. */
|
|
21
|
+
export interface ReadingAnchor {
|
|
22
|
+
readonly text: string;
|
|
23
|
+
readonly ordinal: number;
|
|
24
|
+
}
|
|
25
|
+
/** One document's reading position, as captured from the view face. */
|
|
26
|
+
export interface ReadingPosition {
|
|
27
|
+
/** Capture time (ms epoch); recency order and eviction key. */
|
|
28
|
+
readonly at: number;
|
|
29
|
+
/** The section owning the reading line; null above the first heading. */
|
|
30
|
+
readonly anchor: ReadingAnchor | null;
|
|
31
|
+
/** The anchor's outline index at capture time (in-range fallback). */
|
|
32
|
+
readonly index: number;
|
|
33
|
+
/** Scroll offset below the anchor heading's top, in px. */
|
|
34
|
+
readonly offsetIntoSection: number;
|
|
35
|
+
/** Scroll fraction 0..1 — the fallback that survives any outline change. */
|
|
36
|
+
readonly fraction: number;
|
|
37
|
+
}
|
|
38
|
+
/** The panel-facing reading record store. */
|
|
39
|
+
export interface ReadingStore {
|
|
40
|
+
/** The stored position of one document, or null without a usable record. */
|
|
41
|
+
get(sessionId: string, path: string): ReadingPosition | null;
|
|
42
|
+
/** Record (or overwrite) one document's position. */
|
|
43
|
+
record(sessionId: string, path: string, position: ReadingPosition): void;
|
|
44
|
+
/** The most recently read document of one session — the continue-reading target. */
|
|
45
|
+
latest(sessionId: string): {
|
|
46
|
+
readonly path: string;
|
|
47
|
+
readonly at: number;
|
|
48
|
+
} | null;
|
|
49
|
+
/** The session's documents by recency, most recent first (#31). */
|
|
50
|
+
recent(sessionId: string, limit: number): ReadonlyArray<{
|
|
51
|
+
readonly path: string;
|
|
52
|
+
readonly at: number;
|
|
53
|
+
}>;
|
|
54
|
+
}
|
|
55
|
+
/** An in-memory StorageLike for tests and for browsers without storage. */
|
|
56
|
+
export declare function createMemoryStorage(): StorageLike;
|
|
57
|
+
/** The browser's localStorage when reachable, else null (memory fallback). */
|
|
58
|
+
export declare function browserStorage(): StorageLike | null;
|
|
59
|
+
/**
|
|
60
|
+
* Create the reading record store over one storage backend.
|
|
61
|
+
* @param storage - the persistence face; every failing call degrades the
|
|
62
|
+
* store to its in-memory copy for the rest of the session.
|
|
63
|
+
*/
|
|
64
|
+
export declare function createReadingStore(storage: StorageLike): ReadingStore;
|
|
65
|
+
/** Where a stored position wants to land in the current document. */
|
|
66
|
+
export type RestoreTarget = {
|
|
67
|
+
readonly kind: 'section';
|
|
68
|
+
readonly index: number;
|
|
69
|
+
readonly offsetIntoSection: number;
|
|
70
|
+
} | {
|
|
71
|
+
readonly kind: 'fraction';
|
|
72
|
+
readonly fraction: number;
|
|
73
|
+
} | {
|
|
74
|
+
readonly kind: 'top';
|
|
75
|
+
};
|
|
76
|
+
/**
|
|
77
|
+
* Resolve the restore plan for a stored position against the fresh outline.
|
|
78
|
+
* The chain: the stored section by text and ordinal → the stored outline
|
|
79
|
+
* index while it stays inside the valid range → the scroll fraction → the
|
|
80
|
+
* top. Resolution never fails; the caller always gets a place to be.
|
|
81
|
+
*/
|
|
82
|
+
export declare function resolveRestoreTarget(position: ReadingPosition, outline: readonly OutlineEntry[]): RestoreTarget;
|
|
83
|
+
/**
|
|
84
|
+
* Capture the view face's current reading position from the rendered DOM.
|
|
85
|
+
* Mirrors the outline tracker's geometry: the reading line sits `inset`
|
|
86
|
+
* below the container top, and heading offsets are document coordinates.
|
|
87
|
+
* @returns the position, or null when the container carries no layout.
|
|
88
|
+
*/
|
|
89
|
+
export declare function captureViewPosition(container: HTMLElement, outline: readonly OutlineEntry[], at: number): ReadingPosition | null;
|
|
90
|
+
/**
|
|
91
|
+
* Apply one stored position to the rendered document: scroll once to the
|
|
92
|
+
* resolved target, degrading exactly as the resolution prescribes. The
|
|
93
|
+
* assignment is the whole effect — no smooth scrolling, no re-application.
|
|
94
|
+
* @returns whether a scroll was applied.
|
|
95
|
+
*/
|
|
96
|
+
export declare function applyReadingPosition(container: HTMLElement, outline: readonly OutlineEntry[], position: ReadingPosition): boolean;
|
|
97
|
+
//# sourceMappingURL=reading.d.ts.map
|
|
@@ -6,8 +6,55 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import type { TurnTailOwnerProps } from '@deepseek-ai/dsh-client-ui-chat/client';
|
|
8
8
|
import type { TurnLocation } from '@deepseek-ai/dsh-client-ui-conversation/client';
|
|
9
|
+
/** Structural slice of the deliverables Turn data the readers consume. */
|
|
10
|
+
interface DeliverablesData {
|
|
11
|
+
readonly produced: ReadonlyArray<{
|
|
12
|
+
readonly seq: number;
|
|
13
|
+
readonly path: string;
|
|
14
|
+
}>;
|
|
15
|
+
}
|
|
16
|
+
/** Structural slice of the ui-chat turn-tail Turn data (closing facts). */
|
|
17
|
+
interface TurnTailData {
|
|
18
|
+
readonly seq: number;
|
|
19
|
+
readonly closing?: {
|
|
20
|
+
readonly finalNode: {
|
|
21
|
+
readonly seq: number;
|
|
22
|
+
};
|
|
23
|
+
} | null;
|
|
24
|
+
}
|
|
25
|
+
/** Any turn-shaped holder whose data store answers the two keys we read. */
|
|
26
|
+
interface TurnDataHolder {
|
|
27
|
+
readonly data: {
|
|
28
|
+
get(key: 'deliverables'): DeliverablesData | undefined;
|
|
29
|
+
} & {
|
|
30
|
+
get(key: 'turn-tail'): TurnTailData | undefined;
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
/** Structural slice of a Chat snapshot: the timeline is all we read. */
|
|
34
|
+
export interface TurnOutputsSnapshot {
|
|
35
|
+
readonly timeline: {
|
|
36
|
+
readonly turnOrder: readonly number[];
|
|
37
|
+
readonly turns: ReadonlyMap<number, TurnDataHolder & {
|
|
38
|
+
readonly status: string;
|
|
39
|
+
}>;
|
|
40
|
+
};
|
|
41
|
+
}
|
|
9
42
|
/** Produced paths of one closing Turn, first-seen order, seq-cutoff applied. */
|
|
10
43
|
export declare function producedPaths(turn: TurnLocation, seq: number): readonly string[];
|
|
44
|
+
/**
|
|
45
|
+
* The previewable documents the session's newest turn produced — the quick
|
|
46
|
+
* entry's source (#31). Only the newest turn in the timeline counts: an
|
|
47
|
+
* earlier turn's outputs are never passed off as current. A closed turn
|
|
48
|
+
* fences at its closing seq (the same boundary the chip row applies — the
|
|
49
|
+
* turn-tail data's closing final node seq, falling back to the turn-end
|
|
50
|
+
* seq); an open turn keeps its produced-so-far as live facts. Nothing is
|
|
51
|
+
* parsed out of conversation prose, and no turn facts are copied — this
|
|
52
|
+
* derives a view over the owning service's data on each call.
|
|
53
|
+
* @param snapshot - the chat snapshot (timeline slice suffices).
|
|
54
|
+
* @returns previewable produced paths, first-seen order; empty when the
|
|
55
|
+
* newest turn produced nothing previewable (or no turns exist).
|
|
56
|
+
*/
|
|
57
|
+
export declare function latestTurnPreviewable(snapshot: TurnOutputsSnapshot): readonly string[];
|
|
11
58
|
/** Matched value for the turn-tail chain entry. */
|
|
12
59
|
export interface MdTurnFiles {
|
|
13
60
|
/** Markdown documents this turn produced (open the preview panel). */
|
|
@@ -23,4 +70,5 @@ export interface MdTurnFiles {
|
|
|
23
70
|
* @returns the split paths when the turn produced markdown, otherwise null.
|
|
24
71
|
*/
|
|
25
72
|
export declare function selectMdTurnFiles(owner: TurnTailOwnerProps): MdTurnFiles | null;
|
|
73
|
+
export {};
|
|
26
74
|
//# sourceMappingURL=turn-files.d.ts.map
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type PanelDockBounds } from './panel-dock.ts';
|
|
2
|
+
/** Bind the frame adapter to the shell contribution's lifetime and local viewing state. */
|
|
3
|
+
export declare function usePanelDock(open: boolean, width: number, maximized: boolean): {
|
|
4
|
+
anchor: import("react").RefObject<HTMLSpanElement>;
|
|
5
|
+
bounds: PanelDockBounds | null;
|
|
6
|
+
container: HTMLElement | null;
|
|
7
|
+
};
|
|
8
|
+
//# sourceMappingURL=use-panel-dock.d.ts.map
|
package/lib/types/config.d.ts
CHANGED
|
@@ -9,6 +9,12 @@ export interface Config {
|
|
|
9
9
|
/** Extensions (lowercased, dot-prefixed) eligible for preview (a superset
|
|
10
10
|
* of the editable set — plain-text members render but never edit). */
|
|
11
11
|
previewExtensions: string[];
|
|
12
|
+
/** Workspace search: most matches one answer returns (result bound). */
|
|
13
|
+
searchMaxResults: number;
|
|
14
|
+
/** Workspace search: most directories one answer walks (traversal bound). */
|
|
15
|
+
searchMaxDirectories: number;
|
|
16
|
+
/** Workspace search: parallel directory listings per traversal step. */
|
|
17
|
+
searchConcurrency: number;
|
|
12
18
|
}
|
|
13
19
|
/** Standard Schema twin of {@link Config}; defaults live here, not in code. */
|
|
14
20
|
export declare const Config: z<Config>;
|
package/lib/types/constants.d.ts
CHANGED
|
@@ -5,4 +5,12 @@ export declare const DEFAULT_MAX_BYTES = 1048576;
|
|
|
5
5
|
export declare const DEFAULT_ALLOWED_EXTENSIONS: readonly [".md", ".markdown"];
|
|
6
6
|
/** The preview union: readable (and rendered) even though only markdown edits. */
|
|
7
7
|
export declare const DEFAULT_PREVIEW_EXTENSIONS: readonly [".md", ".markdown", ".txt"];
|
|
8
|
+
/** Default search result cap: far above real agent-workspace document counts
|
|
9
|
+
* (tens to low hundreds observed in DSH sessions) while bounding one answer. */
|
|
10
|
+
export declare const DEFAULT_SEARCH_MAX_RESULTS = 200;
|
|
11
|
+
/** Default search traversal cap in directories: bounded for any deployment
|
|
12
|
+
* workspace; a pathological tree reports `traversal-limit`, never hangs. */
|
|
13
|
+
export declare const DEFAULT_SEARCH_MAX_DIRECTORIES = 2000;
|
|
14
|
+
/** Default parallel `listDir` width for one search. */
|
|
15
|
+
export declare const DEFAULT_SEARCH_CONCURRENCY = 8;
|
|
8
16
|
//# sourceMappingURL=constants.d.ts.map
|
package/lib/types/index.d.ts
CHANGED
|
@@ -7,9 +7,9 @@ import type { Context } from '@deepseek-ai/cordis';
|
|
|
7
7
|
import { type Config as ConfigType } from './config.ts';
|
|
8
8
|
export { Config } from './config.ts';
|
|
9
9
|
export type { Config as ConfigInterface } from './config.ts';
|
|
10
|
-
export { DEFAULT_ALLOWED_EXTENSIONS, DEFAULT_MAX_BYTES, DEFAULT_PREVIEW_EXTENSIONS } from './constants.ts';
|
|
10
|
+
export { DEFAULT_ALLOWED_EXTENSIONS, DEFAULT_MAX_BYTES, DEFAULT_PREVIEW_EXTENSIONS, DEFAULT_SEARCH_CONCURRENCY, DEFAULT_SEARCH_MAX_DIRECTORIES, DEFAULT_SEARCH_MAX_RESULTS, } from './constants.ts';
|
|
11
11
|
export { isAllowedExtension, MdPreviewService } from './remote.ts';
|
|
12
|
-
export type { MdPreviewFile, MdPreviewFailureCode, MdPreviewReadRequest } from './protocol.ts';
|
|
12
|
+
export type { MdPreviewFile, MdPreviewFailureCode, MdPreviewReadRequest, MdPreviewSearchLimit, MdPreviewSearchMatch, MdPreviewSearchResult, } from './protocol.ts';
|
|
13
13
|
export { MD_PREVIEW_FAILURE_CODES } from './protocol.ts';
|
|
14
14
|
export declare const name = "md-preview";
|
|
15
15
|
/** Host services the read authority depends on. */
|
package/lib/types/protocol.d.ts
CHANGED
|
@@ -32,6 +32,33 @@ export interface MdPreviewListResult {
|
|
|
32
32
|
/** Directory entries, folders first then alphabetical. */
|
|
33
33
|
readonly entries: readonly MdPreviewEntry[];
|
|
34
34
|
}
|
|
35
|
+
/** One workspace document search match: a previewable document's name and
|
|
36
|
+
* where it lives, nothing about its content. */
|
|
37
|
+
export interface MdPreviewSearchMatch {
|
|
38
|
+
/** Entry basename as the fs layer reports it (what the query matched). */
|
|
39
|
+
readonly name: string;
|
|
40
|
+
/** Workspace-relative path of the document (the open handoff identity). */
|
|
41
|
+
readonly path: string;
|
|
42
|
+
}
|
|
43
|
+
/** Why a search stopped short of a complete answer. */
|
|
44
|
+
export type MdPreviewSearchLimit =
|
|
45
|
+
/** One or more directories could not be listed (permissions, io). */
|
|
46
|
+
'directory-failure'
|
|
47
|
+
/** The traversal cap stopped the walk before the workspace was covered. */
|
|
48
|
+
| 'traversal-limit'
|
|
49
|
+
/** The result cap truncated the match list. */
|
|
50
|
+
| 'result-limit';
|
|
51
|
+
/** One workspace document search answer. */
|
|
52
|
+
export interface MdPreviewSearchResult {
|
|
53
|
+
/** The query exactly as the caller sent it. */
|
|
54
|
+
readonly query: string;
|
|
55
|
+
/** Previewable documents whose names matched, sorted by path. */
|
|
56
|
+
readonly matches: readonly MdPreviewSearchMatch[];
|
|
57
|
+
/** Whether the whole workspace was walked without any bound or failure. */
|
|
58
|
+
readonly complete: boolean;
|
|
59
|
+
/** Why the answer stopped short; empty exactly when complete. */
|
|
60
|
+
readonly limits: readonly MdPreviewSearchLimit[];
|
|
61
|
+
}
|
|
35
62
|
/** Stable failure codes carried by `RemoteError` across the wire. */
|
|
36
63
|
export declare const MD_PREVIEW_FAILURE_CODES: readonly ["md-preview/bad-request", "md-preview/unknown-session", "md-preview/no-workspace", "md-preview/unsupported-extension", "md-preview/forbidden", "md-preview/not-found", "md-preview/too-large", "md-preview/conflict", "md-preview/unavailable"];
|
|
37
64
|
/** One stable MdPreview failure code. */
|
package/lib/types/remote.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ import type { Context } from '@deepseek-ai/cordis';
|
|
|
8
8
|
import { TypertRemoteService } from '@deepseek-ai/dsh-typert-protocol';
|
|
9
9
|
import type { SessionId } from '@deepseek-ai/dsh-session/types';
|
|
10
10
|
import type { Config } from './config.ts';
|
|
11
|
-
import type { MdPreviewFile, MdPreviewListResult, MdPreviewWriteResult } from './protocol.ts';
|
|
11
|
+
import type { MdPreviewFile, MdPreviewListResult, MdPreviewSearchResult, MdPreviewWriteResult } from './protocol.ts';
|
|
12
12
|
/** Whether a candidate extension passes the configured allowlist. */
|
|
13
13
|
export declare function isAllowedExtension(path: string, allowedExtensions: readonly string[]): boolean;
|
|
14
14
|
/**
|
|
@@ -60,6 +60,23 @@ export declare class MdPreviewService extends TypertRemoteService {
|
|
|
60
60
|
* @throws RemoteError with a stable MdPreview failure code.
|
|
61
61
|
*/
|
|
62
62
|
list(sessionId: SessionId, path: string, signal: AbortSignal): Promise<MdPreviewListResult>;
|
|
63
|
+
/**
|
|
64
|
+
* Search previewable documents by name across the whole session workspace,
|
|
65
|
+
* including directories the browser face never expanded. First-version
|
|
66
|
+
* semantics: case-insensitive substring match on the entry name. The walk
|
|
67
|
+
* stays inside the session authority (root resolve + containment, visited
|
|
68
|
+
* dedupe so links cannot loop it), never reads file bodies, and reports
|
|
69
|
+
* honestly whether the answer is complete — a permission failure, a
|
|
70
|
+
* traversal bound, or the result cap each mark it incomplete with the
|
|
71
|
+
* matching limit.
|
|
72
|
+
* @param sessionId - owning session; its header cwd roots the walk.
|
|
73
|
+
* @param query - raw search text; matched case-insensitively against names.
|
|
74
|
+
* @param signal - caller cancellation carried through every fs call.
|
|
75
|
+
* @returns the query, its matches with workspace-relative paths, and
|
|
76
|
+
* whether the walk finished whole.
|
|
77
|
+
* @throws RemoteError with a stable MdPreview failure code.
|
|
78
|
+
*/
|
|
79
|
+
search(sessionId: SessionId, query: string, signal: AbortSignal): Promise<MdPreviewSearchResult>;
|
|
63
80
|
/**
|
|
64
81
|
* The shared authority preamble of the remote methods: resolve a path to a
|
|
65
82
|
* live, contained, regular workspace file, or reject it with the stable
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { RemoteResult, TypertRemoteContribution } from '@deepseek-ai/dsh-typert-protocol';
|
|
2
2
|
import type { SessionId } from '@deepseek-ai/dsh-session/types';
|
|
3
|
-
import type { MdPreviewFile, MdPreviewListResult, MdPreviewWriteResult } from '../protocol.ts';
|
|
3
|
+
import type { MdPreviewFile, MdPreviewListResult, MdPreviewSearchResult, MdPreviewWriteResult } from '../protocol.ts';
|
|
4
4
|
/** Browser face of the mounted `mdPreview` Remote namespace. */
|
|
5
5
|
export interface MdPreviewRemote {
|
|
6
6
|
/** Read one previewable document of a session's workspace. */
|
|
@@ -13,6 +13,8 @@ export interface MdPreviewRemote {
|
|
|
13
13
|
write(sessionId: SessionId, path: string, content: string, fingerprint?: string, force?: boolean, signal?: AbortSignal): Promise<RemoteResult<MdPreviewWriteResult>>;
|
|
14
14
|
/** List one workspace directory for the browser face (blank path = root). */
|
|
15
15
|
list(sessionId: SessionId, path: string, signal?: AbortSignal): Promise<RemoteResult<MdPreviewListResult>>;
|
|
16
|
+
/** Search previewable document names over the whole session workspace. */
|
|
17
|
+
search(sessionId: SessionId, query: string, signal?: AbortSignal): Promise<RemoteResult<MdPreviewSearchResult>>;
|
|
16
18
|
}
|
|
17
19
|
declare module '@deepseek-ai/dsh-typert-protocol' {
|
|
18
20
|
interface TypertRemoteNamespaceMap {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@benz-ai-x/dsh-md-preview",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"description": "DSH markdown preview: clicking a markdown document in the conversation opens a rendered preview panel docked to the right of the chat.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The header file-manager action: a collapse/expand button in the
|
|
3
|
-
* conversation header that opens a workspace file-tree popover. Opening a
|
|
4
|
-
* file hands it to the right preview panel; the popover stays open for
|
|
5
|
-
* further picks. jsdom coverage asserts content and behavior, not layout
|
|
6
|
-
* (no layout engine there).
|
|
7
|
-
*/
|
|
8
|
-
import { type ReactElement } from 'react';
|
|
9
|
-
import type { InjectFace, PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots';
|
|
10
|
-
import type { SnapshotStore } from '@deepseek-ai/dsh-client-store';
|
|
11
|
-
import type { SessionId } from '@deepseek-ai/dsh-session/types';
|
|
12
|
-
import type { MdPreviewListResult } from '../protocol.ts';
|
|
13
|
-
import type { MdPreviewState } from './preview-state.ts';
|
|
14
|
-
/** The composed props of the header action: slot kit + inject face + locale. */
|
|
15
|
-
export type FileManagerActionProps = PropsRuntime<'conversation.session.header.actions'> & InjectFace<{
|
|
16
|
-
hooks: {
|
|
17
|
-
previewTarget: SnapshotStore<MdPreviewState>;
|
|
18
|
-
};
|
|
19
|
-
list(sessionId: SessionId, path: string, signal: AbortSignal): Promise<import('@deepseek-ai/dsh-typert-protocol').RemoteResult<MdPreviewListResult>>;
|
|
20
|
-
setTarget(target: {
|
|
21
|
-
sessionId: SessionId;
|
|
22
|
-
path: string;
|
|
23
|
-
} | null): void;
|
|
24
|
-
}> & PropsLocale<'md-preview'>;
|
|
25
|
-
/**
|
|
26
|
-
* Render the header file-manager button and its popover for one session.
|
|
27
|
-
* @param props - the composed action props.
|
|
28
|
-
* @returns the trigger button (popover renders beside it in the panel tree).
|
|
29
|
-
*/
|
|
30
|
-
export declare function FileManagerAction(props: FileManagerActionProps): ReactElement;
|
|
31
|
-
//# sourceMappingURL=FileManagerAction.d.ts.map
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The left-edge document browser: a collapse-style strip hugging the
|
|
3
|
-
* conversation's left boundary (the app sidebar's right edge) that expands
|
|
4
|
-
* into the session workspace tree. Opening a file hands it to the right
|
|
5
|
-
* preview panel — left browser picks, right panel reads. The strip is
|
|
6
|
-
* driven by a session probe: a null-rendering composer-dock entry that
|
|
7
|
-
* publishes which conversation is showing.
|
|
8
|
-
*/
|
|
9
|
-
import { type ReactElement } from 'react';
|
|
10
|
-
import type { SessionId } from '@deepseek-ai/dsh-session/types';
|
|
11
|
-
import type { MdPreviewListResult } from '../protocol.ts';
|
|
12
|
-
/**
|
|
13
|
-
* Publishes one conversation's session while that conversation shows.
|
|
14
|
-
* Renders nothing; the activate/deactivate pair comes from the slot's
|
|
15
|
-
* session-scoped inject closure.
|
|
16
|
-
*/
|
|
17
|
-
export declare function SessionProbe(props: {
|
|
18
|
-
activate(): void;
|
|
19
|
-
deactivate(): void;
|
|
20
|
-
}): null;
|
|
21
|
-
/** The composed props of the side browser entry: stores + RPC + locale. */
|
|
22
|
-
export interface SideBrowserProps {
|
|
23
|
-
/** Selector hook over the conversation probe's session (null without one). */
|
|
24
|
-
useCurrentSession(selector: (state: unknown) => unknown): unknown;
|
|
25
|
-
/** Selector hook over the preview target (for the current-file mark). */
|
|
26
|
-
usePreviewTarget(selector: (state: unknown) => unknown): unknown;
|
|
27
|
-
/** One directory listing; the transport carries the AbortSignal. */
|
|
28
|
-
list(sessionId: SessionId, path: string, signal: AbortSignal): Promise<import('@deepseek-ai/dsh-typert-protocol').RemoteResult<MdPreviewListResult>>;
|
|
29
|
-
/** Open one file in the right preview panel. */
|
|
30
|
-
setTarget(target: {
|
|
31
|
-
sessionId: SessionId;
|
|
32
|
-
path: string;
|
|
33
|
-
} | null): void;
|
|
34
|
-
/** Locale seat. */
|
|
35
|
-
t(key: string): string;
|
|
36
|
-
}
|
|
37
|
-
/**
|
|
38
|
-
* Render the left-edge strip and, expanded, the workspace tree.
|
|
39
|
-
* @param props - stores, listing RPC, panel handoff, locale seat.
|
|
40
|
-
* @returns the side browser, or null while no conversation shows.
|
|
41
|
-
*/
|
|
42
|
-
export declare function SideBrowser({ useCurrentSession, usePreviewTarget, list, setTarget, t }: SideBrowserProps): ReactElement | null;
|
|
43
|
-
//# sourceMappingURL=SideBrowser.d.ts.map
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The composer-dock entry: opens the preview panel on the session's
|
|
3
|
-
* workspace without waiting for a turn that produced markdown — the dock
|
|
4
|
-
* button lists the root, picks its first previewable file, and sets the
|
|
5
|
-
* preview target; an empty root shows a transient hint instead.
|
|
6
|
-
*/
|
|
7
|
-
import { type ReactElement } from 'react';
|
|
8
|
-
import type { InjectFace, PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots';
|
|
9
|
-
import type { MdPreviewEntry } from '../protocol.ts';
|
|
10
|
-
/**
|
|
11
|
-
* The first previewable file of a root listing.
|
|
12
|
-
* @param entries - one directory level, in listing order.
|
|
13
|
-
* @returns its workspace-relative path, or null when nothing previews.
|
|
14
|
-
*/
|
|
15
|
-
export declare function firstPreviewablePath(entries: readonly MdPreviewEntry[]): string | null;
|
|
16
|
-
/** Props: the mount-bound open action plus the dock's locale seat. */
|
|
17
|
-
export interface WorkspaceDocsDockProps {
|
|
18
|
-
/** Lists the workspace root and opens the first previewable file.
|
|
19
|
-
* Resolves 'none' when the root has nothing previewable. */
|
|
20
|
-
openWorkspace: () => Promise<'opened' | 'none'>;
|
|
21
|
-
/** Locale seat. */
|
|
22
|
-
t(key: string): string;
|
|
23
|
-
}
|
|
24
|
-
/** The registered header action: session slot kit + injected face + locale. */
|
|
25
|
-
export type WorkspaceDocsDockActionProps = PropsRuntime<'conversation.session.header.actions'> & InjectFace<{
|
|
26
|
-
openWorkspace: () => Promise<'opened' | 'none'>;
|
|
27
|
-
}> & PropsLocale<'md-preview'>;
|
|
28
|
-
/**
|
|
29
|
-
* Bind the slot's injected face into the presentational entry.
|
|
30
|
-
* @param props - the header action's composed props.
|
|
31
|
-
* @returns the header entry element.
|
|
32
|
-
*/
|
|
33
|
-
export declare function WorkspaceDocsDockAction(props: WorkspaceDocsDockActionProps): ReactElement;
|
|
34
|
-
/**
|
|
35
|
-
* Render the dock entry for one session's workspace.
|
|
36
|
-
* @param props - the bound open action and locale seat.
|
|
37
|
-
* @returns the entry button (or its transient empty hint).
|
|
38
|
-
*/
|
|
39
|
-
export declare function WorkspaceDocsDock({ openWorkspace, t }: WorkspaceDocsDockProps): import("react").JSX.Element;
|
|
40
|
-
//# sourceMappingURL=WorkspaceDocsDock.d.ts.map
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The 文档 conversation view: the session workspace tree rendered inside
|
|
3
|
-
* the conversation area as a view tab (beside 对话/轨迹). Opening a file
|
|
4
|
-
* sets the preview target — the docked panel takes it from there.
|
|
5
|
-
*/
|
|
6
|
-
import type { ReactElement } from 'react';
|
|
7
|
-
import type { ConvViewProps } from '@deepseek-ai/dsh-client-ui-conversation/client';
|
|
8
|
-
import type { InjectFace, PropsLocale } from '@deepseek-ai/dsh-client-ui-slots';
|
|
9
|
-
import type { SnapshotStore } from '@deepseek-ai/dsh-client-store';
|
|
10
|
-
import type { MdPreviewState } from './preview-state.ts';
|
|
11
|
-
import type { MdPreviewListResult } from '../protocol.ts';
|
|
12
|
-
/** The composed props of the docs view tab: session kit + inject face + locale. */
|
|
13
|
-
export type WorkspaceDocsViewProps = ConvViewProps & InjectFace<{
|
|
14
|
-
hooks: {
|
|
15
|
-
previewTarget: SnapshotStore<MdPreviewState>;
|
|
16
|
-
};
|
|
17
|
-
list(sessionId: string, path: string, signal: AbortSignal): Promise<import('@deepseek-ai/dsh-typert-protocol').RemoteResult<MdPreviewListResult>>;
|
|
18
|
-
setTarget(target: {
|
|
19
|
-
sessionId: string;
|
|
20
|
-
path: string;
|
|
21
|
-
} | null): void;
|
|
22
|
-
}> & PropsLocale<'md-preview'>;
|
|
23
|
-
/**
|
|
24
|
-
* Render the docs view tab body for one session.
|
|
25
|
-
* @param props - the view's composed props.
|
|
26
|
-
* @returns the workspace tree element.
|
|
27
|
-
*/
|
|
28
|
-
export declare function WorkspaceDocsView({ sessionId, usePreviewTarget, list, setTarget, t }: WorkspaceDocsViewProps): ReactElement;
|
|
29
|
-
//# sourceMappingURL=WorkspaceDocsView.d.ts.map
|