@khorsheed/dsh-file-preview 0.3.2 → 0.4.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/CHANGELOG.md +6 -0
- package/README.en.md +38 -20
- package/README.i18n.yaml +2 -2
- package/README.md +39 -21
- package/cordis.patch.yml +10 -2
- package/lib/client.js +8427 -0
- package/lib/typert.host.js +6 -2
- package/lib/types/client/DiffHistory.d.ts +20 -0
- package/lib/types/client/DiffHistory.js +56 -0
- package/lib/types/client/FilePreviewTab.d.ts +34 -0
- package/lib/types/client/FilePreviewTab.js +193 -0
- package/lib/types/client/TurnFileRow.d.ts +30 -0
- package/lib/types/client/TurnFileRow.js +72 -0
- package/lib/types/client/contract.d.ts +39 -0
- package/lib/types/client/contract.js +2 -0
- package/lib/types/client/definition.d.ts +55 -0
- package/lib/types/client/definition.js +93 -0
- package/lib/types/client/file-preview-store.d.ts +42 -0
- package/lib/types/client/file-preview-store.js +58 -0
- package/lib/types/client/icons.d.ts +21 -0
- package/lib/types/client/icons.js +5 -0
- package/lib/types/client/index.d.ts +80 -0
- package/lib/types/client/index.js +238 -0
- package/lib/types/client/locales.d.ts +16 -0
- package/lib/types/client/locales.js +177 -0
- package/lib/types/client/mentions-wrap.d.ts +60 -0
- package/lib/types/client/mentions-wrap.js +42 -0
- package/lib/types/client/open-in-app.d.ts +85 -0
- package/lib/types/client/open-in-app.js +146 -0
- package/lib/types/client/path-utils.d.ts +53 -0
- package/lib/types/client/path-utils.js +110 -0
- package/lib/types/client/preview.d.ts +27 -0
- package/lib/types/client/preview.js +72 -0
- package/lib/types/client/turn-files-cache.d.ts +24 -0
- package/lib/types/client/turn-files-cache.js +39 -0
- package/lib/types/client/turn-files.d.ts +26 -0
- package/lib/types/client/turn-files.js +14 -0
- package/locale/en.json +2 -2
- package/locale/zh.json +2 -2
- package/package.json +55 -4
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/** Pure path display helpers for the file-preview tab. */
|
|
2
|
+
import { isAbsoluteWorkspacePath } from '@deepseek-ai/dsh-util-workspace-path';
|
|
3
|
+
/** The last path segment; the path itself when it has no separator. */
|
|
4
|
+
export function basename(path) {
|
|
5
|
+
const slash = Math.max(path.lastIndexOf('/'), path.lastIndexOf('\\'));
|
|
6
|
+
return slash < 0 ? path : path.slice(slash + 1);
|
|
7
|
+
}
|
|
8
|
+
/** Everything before the last path separator ('' when the path has none). */
|
|
9
|
+
export function parentPath(path) {
|
|
10
|
+
const slash = Math.max(path.lastIndexOf('/'), path.lastIndexOf('\\'));
|
|
11
|
+
return slash <= 0 ? '' : path.slice(0, slash);
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Sort touched files by their last recorded activity, newest first. The fold
|
|
15
|
+
* keeps first-seen order; the view presents latest-first so the agent's most
|
|
16
|
+
* recent work is at the top.
|
|
17
|
+
* @param entries - the fold's first-seen entries.
|
|
18
|
+
* @returns a new array sorted by descending last-occurrence seq.
|
|
19
|
+
*/
|
|
20
|
+
export function sortByLatest(entries) {
|
|
21
|
+
return [...entries].sort((a, b) => b.seq - a.seq);
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Case-insensitive substring match of a search query against a file's display
|
|
25
|
+
* path (the whole path, so a directory name matches too). Empty and
|
|
26
|
+
* whitespace-only queries match nothing deliberately — the view treats them as
|
|
27
|
+
* "no search" and shows the unfiltered list.
|
|
28
|
+
* @param path - the entry's display path.
|
|
29
|
+
* @param query - the trimmed search term.
|
|
30
|
+
* @returns whether the path contains the query, ignoring case.
|
|
31
|
+
*/
|
|
32
|
+
export function matchesQuery(path, query) {
|
|
33
|
+
if (query.length === 0)
|
|
34
|
+
return false;
|
|
35
|
+
return path.toLowerCase().includes(query.toLowerCase());
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Split a file name into [before, match, after] for the first case-insensitive
|
|
39
|
+
* occurrence of `query`, so the view can highlight the matched substring.
|
|
40
|
+
* @param name - the display name to search.
|
|
41
|
+
* @param query - the trimmed search term.
|
|
42
|
+
* @returns the three parts, or null when the name does not contain the query.
|
|
43
|
+
*/
|
|
44
|
+
export function highlightMatch(name, query) {
|
|
45
|
+
if (query.length === 0)
|
|
46
|
+
return null;
|
|
47
|
+
const at = name.toLowerCase().indexOf(query.toLowerCase());
|
|
48
|
+
if (at < 0)
|
|
49
|
+
return null;
|
|
50
|
+
return [name.slice(0, at), name.slice(at, at + query.length), name.slice(at + query.length)];
|
|
51
|
+
}
|
|
52
|
+
/** Strip a workspace root prefix for compact display; the path stands when unrelated. */
|
|
53
|
+
export function relativeToCwd(path, cwd) {
|
|
54
|
+
if (cwd === undefined || cwd.length === 0)
|
|
55
|
+
return path;
|
|
56
|
+
if (path === cwd)
|
|
57
|
+
return basename(path);
|
|
58
|
+
const rooted = cwd.endsWith('/') ? cwd : `${cwd}/`;
|
|
59
|
+
return path.startsWith(rooted) ? path.slice(rooted.length) : path;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Whether the official document tab can render this path: the `file` resource
|
|
63
|
+
* is workspace-scoped (the host answers outside-workspace stats with
|
|
64
|
+
* `workspace-file/outside-workspace`), so only workspace-rooted paths get a
|
|
65
|
+
* `dsh-resource://file/...` open. Relative paths qualify (the host resolves
|
|
66
|
+
* them against the session root); an absolute path qualifies when the session
|
|
67
|
+
* cwd is known and contains it, or when the cwd is unknown — the host's own
|
|
68
|
+
* failure line is the honest answer there.
|
|
69
|
+
* @param cwd - the session's workspace root, when known.
|
|
70
|
+
* @param path - the recorded display path (absolute or workspace-relative).
|
|
71
|
+
* @returns whether `openResource` stands a chance of rendering the file.
|
|
72
|
+
*/
|
|
73
|
+
export function isWithinWorkspace(cwd, path) {
|
|
74
|
+
if (!isAbsoluteWorkspacePath(path))
|
|
75
|
+
return true;
|
|
76
|
+
if (cwd === undefined || cwd.length === 0)
|
|
77
|
+
return true;
|
|
78
|
+
const root = cwd.replace(/\\/g, '/').replace(/\/+$/, '');
|
|
79
|
+
const target = path.replace(/\\/g, '/');
|
|
80
|
+
return target === root || target.startsWith(`${root}/`);
|
|
81
|
+
}
|
|
82
|
+
/** Whether a path names an HTML document (`.html`/`.htm`), offered a
|
|
83
|
+
* sandboxed render view alongside the source view. */
|
|
84
|
+
export function isHtmlPath(path) {
|
|
85
|
+
const dot = path.lastIndexOf('.');
|
|
86
|
+
if (dot < 0)
|
|
87
|
+
return false;
|
|
88
|
+
const ext = path.slice(dot).toLowerCase();
|
|
89
|
+
return ext === '.html' || ext === '.htm';
|
|
90
|
+
}
|
|
91
|
+
/** Map a file extension to a prism language name for CodeBlock, or undefined to auto-detect. */
|
|
92
|
+
const LANGUAGE_BY_EXTENSION = {
|
|
93
|
+
'.ts': 'typescript', '.tsx': 'typescript', '.mts': 'typescript', '.cts': 'typescript',
|
|
94
|
+
'.js': 'javascript', '.jsx': 'javascript', '.mjs': 'javascript', '.cjs': 'javascript',
|
|
95
|
+
'.json': 'json', '.jsonc': 'json', '.md': 'markdown', '.mdx': 'markdown',
|
|
96
|
+
'.yml': 'yaml', '.yaml': 'yaml', '.html': 'html', '.htm': 'html',
|
|
97
|
+
'.css': 'css', '.scss': 'scss', '.less': 'less', '.sh': 'bash', '.bash': 'bash',
|
|
98
|
+
'.py': 'python', '.sql': 'sql', '.xml': 'xml', '.toml': 'toml', '.ini': 'ini',
|
|
99
|
+
'.go': 'go', '.rs': 'rust', '.java': 'java', '.c': 'c', '.h': 'c',
|
|
100
|
+
'.cpp': 'cpp', '.hpp': 'cpp', '.rb': 'ruby', '.php': 'php', '.swift': 'swift',
|
|
101
|
+
'.kotlin': 'kotlin', '.vue': 'vue', '.svelte': 'svelte', '.dockerfile': 'docker',
|
|
102
|
+
'.graphql': 'graphql', '.proto': 'protobuf', '.diff': 'diff', '.patch': 'diff',
|
|
103
|
+
};
|
|
104
|
+
/** The prism language name for a path's extension, or undefined for auto-detection. */
|
|
105
|
+
export function languageFor(path) {
|
|
106
|
+
const dot = path.lastIndexOf('.');
|
|
107
|
+
if (dot < 0)
|
|
108
|
+
return undefined;
|
|
109
|
+
return LANGUAGE_BY_EXTENSION[path.slice(dot).toLowerCase()];
|
|
110
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { TranslateNS } from '@deepseek-ai/dsh-client-ui-slots';
|
|
2
|
+
import type { PreviewRead, PreviewTranslator, StructuredLabels } from '@khorsheed/dsh-client-ui-content-preview/src/client/index.ts';
|
|
3
|
+
import type { FilePreviewRead } from '../types.ts';
|
|
4
|
+
/**
|
|
5
|
+
* Map one file-preview read onto the kernel's contract.
|
|
6
|
+
*
|
|
7
|
+
* The wire type carries `path` plus optional per-kind fields (like the
|
|
8
|
+
* local-files one), so the arms are spelled out rather than cast: an image read
|
|
9
|
+
* with no URL becomes `missing`/`unreadable` instead of an `<img>` with no
|
|
10
|
+
* source.
|
|
11
|
+
* @param read - the host's read result.
|
|
12
|
+
* @returns the kernel's normalized read.
|
|
13
|
+
*/
|
|
14
|
+
export declare function toPreviewRead(read: FilePreviewRead): PreviewRead;
|
|
15
|
+
/**
|
|
16
|
+
* The pane's translator over this plugin's `filePreview` dictionary.
|
|
17
|
+
* @param t - the locale-bound translator for this plugin's namespace.
|
|
18
|
+
* @returns the kernel's translator.
|
|
19
|
+
*/
|
|
20
|
+
export declare function previewTranslator(t: TranslateNS<'filePreview'>): PreviewTranslator;
|
|
21
|
+
/**
|
|
22
|
+
* The structured-render chrome for the kernel's JSON tree / CSV table / markdown.
|
|
23
|
+
* @param t - the locale-bound translator for this plugin's namespace.
|
|
24
|
+
* @returns the kernel's label object.
|
|
25
|
+
*/
|
|
26
|
+
export declare function structuredLabels(t: TranslateNS<'filePreview'>): StructuredLabels;
|
|
27
|
+
//# sourceMappingURL=preview.d.ts.map
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Map one file-preview read onto the kernel's contract.
|
|
3
|
+
*
|
|
4
|
+
* The wire type carries `path` plus optional per-kind fields (like the
|
|
5
|
+
* local-files one), so the arms are spelled out rather than cast: an image read
|
|
6
|
+
* with no URL becomes `missing`/`unreadable` instead of an `<img>` with no
|
|
7
|
+
* source.
|
|
8
|
+
* @param read - the host's read result.
|
|
9
|
+
* @returns the kernel's normalized read.
|
|
10
|
+
*/
|
|
11
|
+
export function toPreviewRead(read) {
|
|
12
|
+
switch (read.kind) {
|
|
13
|
+
case 'text':
|
|
14
|
+
return {
|
|
15
|
+
kind: 'text',
|
|
16
|
+
path: read.path,
|
|
17
|
+
content: read.content ?? '',
|
|
18
|
+
...(read.truncated === true ? { truncated: true } : {}),
|
|
19
|
+
...(read.htmlScripted === true ? { htmlScripted: true } : {}),
|
|
20
|
+
};
|
|
21
|
+
case 'image':
|
|
22
|
+
return read.url === undefined
|
|
23
|
+
? { kind: 'missing', path: read.path, reason: 'unreadable' }
|
|
24
|
+
: { kind: 'image', path: read.path, url: read.url, ...(read.size === undefined ? {} : { size: read.size }) };
|
|
25
|
+
case 'binary':
|
|
26
|
+
return { kind: 'binary', path: read.path, ...(read.size === undefined ? {} : { size: read.size }) };
|
|
27
|
+
case 'too-large':
|
|
28
|
+
return { kind: 'too-large', path: read.path, ...(read.size === undefined ? {} : { size: read.size }) };
|
|
29
|
+
case 'missing':
|
|
30
|
+
return { kind: 'missing', path: read.path };
|
|
31
|
+
case 'error':
|
|
32
|
+
return { kind: 'error', path: read.path, ...(read.message === undefined ? {} : { message: read.message }) };
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* The pane's translator over this plugin's `filePreview` dictionary.
|
|
37
|
+
* @param t - the locale-bound translator for this plugin's namespace.
|
|
38
|
+
* @returns the kernel's translator.
|
|
39
|
+
*/
|
|
40
|
+
export function previewTranslator(t) {
|
|
41
|
+
return (key, params) => t(key, params);
|
|
42
|
+
}
|
|
43
|
+
/** JsonTree chrome over this plugin's dictionary. */
|
|
44
|
+
function jsonTreeLabels(t) {
|
|
45
|
+
return {
|
|
46
|
+
copyValue: t('json.copyValue'),
|
|
47
|
+
copyJson: t('json.copyJson'),
|
|
48
|
+
copyPath: t('json.copyPath'),
|
|
49
|
+
copyPrettyJson: t('json.copyPrettyJson'),
|
|
50
|
+
copyCompactJson: t('json.copyCompactJson'),
|
|
51
|
+
copied: t('json.copied'),
|
|
52
|
+
copyFailed: t('json.copyFailed'),
|
|
53
|
+
collapseNode: t('json.collapseNode'),
|
|
54
|
+
expandNode: t('json.expandNode'),
|
|
55
|
+
copyButtonTitle: action => t('json.copyButtonTitle', { action }),
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
/** MarkdownText chrome over this plugin's dictionary. */
|
|
59
|
+
function markdownLabels(t) {
|
|
60
|
+
return {
|
|
61
|
+
code: { copyLabel: t('action.copy'), copiedLabel: t('action.copied') },
|
|
62
|
+
footnotes: t('markdown.footnotes'),
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* The structured-render chrome for the kernel's JSON tree / CSV table / markdown.
|
|
67
|
+
* @param t - the locale-bound translator for this plugin's namespace.
|
|
68
|
+
* @returns the kernel's label object.
|
|
69
|
+
*/
|
|
70
|
+
export function structuredLabels(t) {
|
|
71
|
+
return { json: jsonTreeLabels(t), markdown: markdownLabels(t) };
|
|
72
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session-level cache in front of the `filePreview.turnFiles` RPC. One fetch
|
|
3
|
+
* warms every turn the response carries (the host returns the whole per-turn
|
|
4
|
+
* map up to its watermark, and the host itself caches the fold by that
|
|
5
|
+
* watermark), and every requested turn — including one the response reports
|
|
6
|
+
* empty — is pinned so a re-mount of the same card never refetches. A card for
|
|
7
|
+
* a newer, not-yet-seen turn triggers one refetch, which the host answers
|
|
8
|
+
* without refolding. Errors resolve to an empty list — the card just shows
|
|
9
|
+
* nothing.
|
|
10
|
+
* @module @khorsheed/dsh-file-preview
|
|
11
|
+
*/
|
|
12
|
+
import type { FilePreviewTurnFile } from '../types.ts';
|
|
13
|
+
import type { SessionId } from '@deepseek-ai/dsh-api-remotes/client';
|
|
14
|
+
import type { FilePreviewRemote } from './contract.ts';
|
|
15
|
+
/**
|
|
16
|
+
* Build a turn-files loader bound to one mounted Remote (created per apply, so
|
|
17
|
+
* the cache never pins module-level identity across plugin reloads).
|
|
18
|
+
* @param remote - the mounted filePreview Remote handle.
|
|
19
|
+
* @returns a loader resolving one session's files for one turn.
|
|
20
|
+
*/
|
|
21
|
+
export declare function createTurnFilesLoader(remote: FilePreviewRemote): (sessionId: SessionId, turn: number) => Promise<readonly FilePreviewTurnFile[]>;
|
|
22
|
+
/** The loader's function shape, shared with the inject face. */
|
|
23
|
+
export type TurnFilesLoader = ReturnType<typeof createTurnFilesLoader>;
|
|
24
|
+
//# sourceMappingURL=turn-files-cache.d.ts.map
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session-level cache in front of the `filePreview.turnFiles` RPC. One fetch
|
|
3
|
+
* warms every turn the response carries (the host returns the whole per-turn
|
|
4
|
+
* map up to its watermark, and the host itself caches the fold by that
|
|
5
|
+
* watermark), and every requested turn — including one the response reports
|
|
6
|
+
* empty — is pinned so a re-mount of the same card never refetches. A card for
|
|
7
|
+
* a newer, not-yet-seen turn triggers one refetch, which the host answers
|
|
8
|
+
* without refolding. Errors resolve to an empty list — the card just shows
|
|
9
|
+
* nothing.
|
|
10
|
+
* @module @khorsheed/dsh-file-preview
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Build a turn-files loader bound to one mounted Remote (created per apply, so
|
|
14
|
+
* the cache never pins module-level identity across plugin reloads).
|
|
15
|
+
* @param remote - the mounted filePreview Remote handle.
|
|
16
|
+
* @returns a loader resolving one session's files for one turn.
|
|
17
|
+
*/
|
|
18
|
+
export function createTurnFilesLoader(remote) {
|
|
19
|
+
const cache = new Map();
|
|
20
|
+
return (sessionId, turn) => {
|
|
21
|
+
const sessionCache = cache.get(sessionId);
|
|
22
|
+
if (sessionCache !== undefined && sessionCache.has(turn)) {
|
|
23
|
+
return Promise.resolve(sessionCache.get(turn) ?? []);
|
|
24
|
+
}
|
|
25
|
+
return remote.turnFiles(sessionId).then((result) => {
|
|
26
|
+
const merged = cache.get(sessionId) ?? new Map();
|
|
27
|
+
if (result.ok) {
|
|
28
|
+
for (const group of result.value.turns)
|
|
29
|
+
merged.set(group.turn, group.files);
|
|
30
|
+
}
|
|
31
|
+
// Pin the requested turn's resolution (possibly empty) so the same card
|
|
32
|
+
// never refetches; newer turns still trigger one refetch each.
|
|
33
|
+
if (!merged.has(turn))
|
|
34
|
+
merged.set(turn, []);
|
|
35
|
+
cache.set(sessionId, merged);
|
|
36
|
+
return merged.get(turn) ?? [];
|
|
37
|
+
});
|
|
38
|
+
};
|
|
39
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Turn-tail chain claim for the file-preview turn card — the 0.1.5 fallback
|
|
3
|
+
* path only. 0.1.6-alpha.2 re-kinded `conversation.chat.turnTail` from chain
|
|
4
|
+
* (election) to list (every entry renders; no selector exists), where the
|
|
5
|
+
* card coexists with the official cards and self-hides without data; this
|
|
6
|
+
* claim survives for the chain branch of the dual-host registration in
|
|
7
|
+
* index.ts. The card is an async thin shell: the host `filePreview.turnFiles`
|
|
8
|
+
* RPC is the SINGLE source of truth for every turn's mutations — write/edit
|
|
9
|
+
* calls, Code Mode dispatches, render-intent paths from result diff meta, and
|
|
10
|
+
* bash captures — so the card and the file-preview tab read the same host
|
|
11
|
+
* data. The claim is unconditional so the card claims every turn (priority
|
|
12
|
+
* -1, ahead of the official deliverables entry's default 0 — the chain elects
|
|
13
|
+
* ascending) and renders nothing until its fetch settles or the turn has no
|
|
14
|
+
* files.
|
|
15
|
+
*/
|
|
16
|
+
import type { TurnTailOwnerProps } from '@deepseek-ai/dsh-client-ui-chat/client';
|
|
17
|
+
/**
|
|
18
|
+
* Claim every turn of the chain (the row decides visibility from its fetch).
|
|
19
|
+
* @param _owner - chain owner currency; unused — the claim never declines.
|
|
20
|
+
* @returns a non-null marker so this entry wins the election whenever the
|
|
21
|
+
* earlier official entries declined the turn.
|
|
22
|
+
*/
|
|
23
|
+
export declare function selectTurnFiles(_owner: TurnTailOwnerProps): readonly [];
|
|
24
|
+
/** Re-export for the row component's basename display. */
|
|
25
|
+
export declare function basename(path: string): string;
|
|
26
|
+
//# sourceMappingURL=turn-files.d.ts.map
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Claim every turn of the chain (the row decides visibility from its fetch).
|
|
3
|
+
* @param _owner - chain owner currency; unused — the claim never declines.
|
|
4
|
+
* @returns a non-null marker so this entry wins the election whenever the
|
|
5
|
+
* earlier official entries declined the turn.
|
|
6
|
+
*/
|
|
7
|
+
export function selectTurnFiles(_owner) {
|
|
8
|
+
return [];
|
|
9
|
+
}
|
|
10
|
+
/** Re-export for the row component's basename display. */
|
|
11
|
+
export function basename(path) {
|
|
12
|
+
const at = Math.max(path.lastIndexOf('/'), path.lastIndexOf('\\'));
|
|
13
|
+
return at === -1 ? path : path.slice(at + 1);
|
|
14
|
+
}
|
package/locale/en.json
CHANGED
package/locale/zh.json
CHANGED
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@khorsheed/dsh-file-preview",
|
|
3
|
-
"description": "
|
|
3
|
+
"description": "Session products preview, host+client in one: the read-only file-preview Remote service (the files a session wrote or edited, current content, per-change diffs) plus the right-sidebar 会话产物 tab, per-turn change cards, and the file detail view",
|
|
4
4
|
"keywords": [
|
|
5
5
|
"dsh",
|
|
6
6
|
"dsh-plugin",
|
|
7
7
|
"cordis",
|
|
8
8
|
"file-preview"
|
|
9
9
|
],
|
|
10
|
-
"version": "0.
|
|
10
|
+
"version": "0.4.0",
|
|
11
11
|
"type": "module",
|
|
12
12
|
"main": "lib/index.js",
|
|
13
13
|
"types": "lib/types/index.d.ts",
|
|
@@ -24,6 +24,10 @@
|
|
|
24
24
|
"types": "./lib/types/types.d.ts",
|
|
25
25
|
"default": "./lib/types/types.js"
|
|
26
26
|
},
|
|
27
|
+
"./client": {
|
|
28
|
+
"types": "./lib/types/client/index.d.ts",
|
|
29
|
+
"default": "./lib/client.js"
|
|
30
|
+
},
|
|
27
31
|
"./typert": {
|
|
28
32
|
"types": "./lib/typert.host.d.ts",
|
|
29
33
|
"default": "./lib/typert.host.js"
|
|
@@ -49,14 +53,48 @@
|
|
|
49
53
|
],
|
|
50
54
|
"license": "MIT",
|
|
51
55
|
"peerDependencies": {
|
|
56
|
+
"@deepseek-ai/cordis": "^4.0.1",
|
|
52
57
|
"@deepseek-ai/dsh-agent": "^0.1.0-rc.6",
|
|
58
|
+
"@deepseek-ai/dsh-api-remotes": "^0.1.0-rc.6",
|
|
59
|
+
"@deepseek-ai/dsh-client-locale": "^0.1.0-rc.6",
|
|
60
|
+
"@deepseek-ai/dsh-client-ui-chat": "^0.1.0-rc.6",
|
|
61
|
+
"@deepseek-ai/dsh-client-ui-primitives": "^0.1.0-rc.6",
|
|
62
|
+
"@deepseek-ai/dsh-client-ui-sidebar-right": "^0.1.7-rc.1",
|
|
63
|
+
"@deepseek-ai/dsh-client-ui-slots": "^0.1.0-rc.6",
|
|
53
64
|
"@deepseek-ai/dsh-fs": "^0.1.0-rc.6",
|
|
54
65
|
"@deepseek-ai/dsh-invariants": "^0.1.0-rc.6",
|
|
55
66
|
"@deepseek-ai/dsh-native-command": "^0.1.0-rc.6",
|
|
56
67
|
"@deepseek-ai/dsh-session": "^0.1.0-rc.6",
|
|
57
68
|
"@deepseek-ai/dsh-tools": "^0.1.0-rc.6",
|
|
58
69
|
"@deepseek-ai/dsh-typert-protocol": "^0.1.0-rc.6",
|
|
59
|
-
"
|
|
70
|
+
"react": "^18.2.0",
|
|
71
|
+
"react-dom": "^18.2.0"
|
|
72
|
+
},
|
|
73
|
+
"peerDependenciesMeta": {
|
|
74
|
+
"@deepseek-ai/dsh-api-remotes": {
|
|
75
|
+
"optional": true
|
|
76
|
+
},
|
|
77
|
+
"@deepseek-ai/dsh-client-locale": {
|
|
78
|
+
"optional": true
|
|
79
|
+
},
|
|
80
|
+
"@deepseek-ai/dsh-client-ui-chat": {
|
|
81
|
+
"optional": true
|
|
82
|
+
},
|
|
83
|
+
"@deepseek-ai/dsh-client-ui-primitives": {
|
|
84
|
+
"optional": true
|
|
85
|
+
},
|
|
86
|
+
"@deepseek-ai/dsh-client-ui-sidebar-right": {
|
|
87
|
+
"optional": true
|
|
88
|
+
},
|
|
89
|
+
"@deepseek-ai/dsh-client-ui-slots": {
|
|
90
|
+
"optional": true
|
|
91
|
+
},
|
|
92
|
+
"react": {
|
|
93
|
+
"optional": true
|
|
94
|
+
},
|
|
95
|
+
"react-dom": {
|
|
96
|
+
"optional": true
|
|
97
|
+
}
|
|
60
98
|
},
|
|
61
99
|
"dependencies": {
|
|
62
100
|
"zod": "^4.4.3"
|
|
@@ -65,9 +103,22 @@
|
|
|
65
103
|
"bundle": {
|
|
66
104
|
"patch": "./cordis.patch.yml"
|
|
67
105
|
},
|
|
106
|
+
"client": {
|
|
107
|
+
"inject": [
|
|
108
|
+
"@deepseek-ai/dsh-api-remotes",
|
|
109
|
+
"@deepseek-ai/dsh-api-session-controller",
|
|
110
|
+
"@deepseek-ai/dsh-client-locale",
|
|
111
|
+
"@deepseek-ai/dsh-client-ui-conversation",
|
|
112
|
+
"@deepseek-ai/dsh-client-ui-deliverables",
|
|
113
|
+
"@deepseek-ai/dsh-client-ui-session",
|
|
114
|
+
"@deepseek-ai/dsh-client-ui-sidebar-right"
|
|
115
|
+
],
|
|
116
|
+
"platform": "web"
|
|
117
|
+
},
|
|
68
118
|
"compat": {
|
|
69
119
|
"minHost": "0.1.5-rc.1",
|
|
70
|
-
"verifiedHost": "0.1.5-rc.1"
|
|
120
|
+
"verifiedHost": "0.1.5-rc.1",
|
|
121
|
+
"notes": "单一形态双线一致:自建「会话产物」page 型右栏 tab(向导页进入 + extension 档认领 dsh-resource://file/** 可渲染后缀,压过官方 document tab 的 fallback 档——rc.1 的 tab-registry 保留 band 机制),文件树/mention/回合卡/产物行点击全部落自绘详情页(共享内容面板全 chrome + 内容/改动记录切换 + 复制路径/在文件夹/IDE 打开);pdf/压缩包/二进制等 decline 后缀落回官方 document tab。方案 B(内容面注册进官方 documentPreviews 面做默认渲染器)与二期 headless 嵌入已于 2026-09-24 同日被仓主否决回退——接缝成本(renderer loading 协议/extension 档语义/headless 布局耦合)与 UX 妥协(改动记录塞进渲染器下拉、复制钮浮动压搜索行)不成立;改动记录维度(TurnFileRow + 详情页 DiffHistory)官方仍无对应物(workspace-changes 内存态、git-only、重启即失),维持自留并跟踪上游。turnTail 回合卡照常:0.1.6-alpha.2 起 list 槽臂同时注册官方 deliverables 条目的一等遮蔽(同 cell id、priority -1 空体胜出,官方条目在册故其子槽不塌),0.1.5 chain 槽臂保持 select + priority -1 抢占回退——均不涉及 rc.1 专有 API,minHost 不动。0.4.0 起宿主 Remote 与浏览器半同包(ui-file-preview 并入),headless 组合只装宿主半照常工作(client 面在 web 组合里经 dsh.client 发现)。"
|
|
71
122
|
}
|
|
72
123
|
}
|
|
73
124
|
}
|