@dsh-xhl/dsh-file-explorer 0.1.2 → 0.1.3
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 +2 -0
- package/cordis.patch.yml +8 -8
- package/lib/client.js +166 -21
- package/lib/types/context-types.d.ts +29 -0
- package/package.json +113 -113
package/README.md
CHANGED
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
## 功能
|
|
6
6
|
|
|
7
7
|
- **标题栏 ButtonGroup**(`conversation.session.header.utilities`):左侧按钮 + 右侧下拉(编辑器 / 文件夹 / VSCode)
|
|
8
|
+
- **Hero / 新建会话同样显示**:同一 ButtonGroup 通过框架通用浮层 `shell.overlay` 由插件自身定位到会话列右上角(hero 阶段显示,有记录后由标题栏图标接管,无重复);纯插件实现,不改动框架代码(详见 `docs/hero-filex-button.md`)
|
|
9
|
+
- **对话内点击文件 → 编辑器预览**:聊天里的文件路径链接(工具行、产物行、正文提及)默认用系统程序打开;插件拦截 `remote.session.openWorkspacePath` 与 `workspaces.openPath` 两条通道,改为在编辑器弹窗中预览(目录或 cwd 外的路径仍落回系统打开)
|
|
8
10
|
- **编辑器**(默认):点击打开全屏文件预览 / 编辑弹窗(Ctrl+P 亦可)
|
|
9
11
|
- **文件夹**:点击直接打开会话工作区所在的**系统文件夹**(Windows `explorer` / macOS `open` / Linux `xdg-open`)
|
|
10
12
|
- **VSCode**:点击用 `code` 命令行在 **VS Code** 中打开会话工作区(自动探测安装位置 / PATH)
|
package/cordis.patch.yml
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
# dsh-file-explorer bundle patch
|
|
2
|
-
#
|
|
3
|
-
# 通过 bundle 通道挂载:
|
|
4
|
-
# dsh plugin --profile <name> add @dsh-xhl/dsh-file-explorer@<version>
|
|
5
|
-
# 或手动把 '@dsh-xhl/dsh-file-explorer' 加进 profile 的 dsh.profile.bundles 并 link 依赖。
|
|
6
|
-
- insert:
|
|
7
|
-
- id: dsh-file-explorer
|
|
8
|
-
name: '@dsh-xhl/dsh-file-explorer'
|
|
1
|
+
# dsh-file-explorer bundle patch
|
|
2
|
+
#
|
|
3
|
+
# 通过 bundle 通道挂载:
|
|
4
|
+
# dsh plugin --profile <name> add @dsh-xhl/dsh-file-explorer@<version>
|
|
5
|
+
# 或手动把 '@dsh-xhl/dsh-file-explorer' 加进 profile 的 dsh.profile.bundles 并 link 依赖。
|
|
6
|
+
- insert:
|
|
7
|
+
- id: dsh-file-explorer
|
|
8
|
+
name: '@dsh-xhl/dsh-file-explorer'
|
package/lib/client.js
CHANGED
|
@@ -37018,6 +37018,14 @@ window.__ModuleLoader__.load({
|
|
|
37018
37018
|
.filex-group .filex-group-main{border-radius:8px 0 0 8px;padding:0 9px}
|
|
37019
37019
|
.filex-group .filex-group-trigger{margin-left:-1px;border-radius:0 8px 8px 0;border-left:0;padding:0 7px}
|
|
37020
37020
|
|
|
37021
|
+
/* ── hero floating utility (shell.overlay entry) ─────────────────────── */
|
|
37022
|
+
/* The same ButtonGroup, pinned by the plugin to the conversation column's
|
|
37023
|
+
top-right while the column is in its hero phase. The shell.overlay layer
|
|
37024
|
+
is click-through by design, so the entry opts back into pointer events;
|
|
37025
|
+
no explicit z-index keeps it below sibling overlay entries (modal,
|
|
37026
|
+
notices) and any body-portaled popup. */
|
|
37027
|
+
.filex-hero-fab{position:fixed;pointer-events:auto}
|
|
37028
|
+
|
|
37021
37029
|
/* ── transient notice strip ──────────────────────────────────────────── */
|
|
37022
37030
|
.filex-notice{position:fixed;left:50%;bottom:24px;transform:translateX(-50%);z-index:2147483003;display:flex;align-items:center;gap:10px;max-width:70vw;padding:9px 14px;font:12px/1.5 ui-monospace,SFMono-Regular,Menlo,monospace;color:var(--dsw-alias-state-warn-primary,#f59e0b);background:var(--dsw-alias-bg-layer-2,#1b1b22);border:1px solid rgba(245,158,11,.5);border-radius:10px;box-shadow:0 8px 28px rgba(0,0,0,.45);pointer-events:auto}
|
|
37023
37031
|
.filex-notice-btn{border:0;background:transparent;color:inherit;cursor:pointer;font-size:14px;line-height:1;padding:2px 4px;opacity:.7;flex-shrink:0}
|
|
@@ -37946,16 +37954,70 @@ window.__ModuleLoader__.load({
|
|
|
37946
37954
|
* @returns the disposer restoring the original method (HMR-safe).
|
|
37947
37955
|
*/
|
|
37948
37956
|
function wrapOpenPath(workspaces, deps) {
|
|
37957
|
+
const descriptor = Object.getOwnPropertyDescriptor(workspaces, "openPath");
|
|
37949
37958
|
const original = workspaces.openPath;
|
|
37950
|
-
|
|
37959
|
+
const wrapped = async (path) => {
|
|
37951
37960
|
const sessionId = deps.currentSessionId();
|
|
37952
37961
|
if (sessionId !== void 0) {
|
|
37953
37962
|
if (await deps.openInEditor(path, sessionId)) return;
|
|
37954
37963
|
}
|
|
37955
37964
|
return original.call(workspaces, path);
|
|
37956
37965
|
};
|
|
37966
|
+
Object.defineProperty(workspaces, "openPath", {
|
|
37967
|
+
configurable: true,
|
|
37968
|
+
enumerable: descriptor?.enumerable ?? true,
|
|
37969
|
+
writable: false,
|
|
37970
|
+
value: wrapped
|
|
37971
|
+
});
|
|
37957
37972
|
return () => {
|
|
37958
|
-
workspaces
|
|
37973
|
+
if (descriptor !== void 0) Object.defineProperty(workspaces, "openPath", descriptor);
|
|
37974
|
+
else {
|
|
37975
|
+
delete workspaces.openPath;
|
|
37976
|
+
workspaces.openPath = original;
|
|
37977
|
+
}
|
|
37978
|
+
};
|
|
37979
|
+
}
|
|
37980
|
+
/**
|
|
37981
|
+
* Wrap `remote.session.openWorkspacePath` — the chat file-open funnel in
|
|
37982
|
+
* current runtimes (ui-chat's `ChatView` calls it for tool-row path links,
|
|
37983
|
+
* the produced-files row, and prose file mentions alike). Intercepted opens
|
|
37984
|
+
* go to the explorer modal and resolve as a successful open (the caller only
|
|
37985
|
+
* checks `ok`); anything that declines falls through to the original RPC,
|
|
37986
|
+
* which opens the path with the Host OS default application.
|
|
37987
|
+
*
|
|
37988
|
+
* The generated remote face exposes `openWorkspacePath` as an own accessor
|
|
37989
|
+
* (getter without setter), so a plain assignment silently fails — the
|
|
37990
|
+
* property is redefined instead, and the original descriptor is restored on
|
|
37991
|
+
* disposal (HMR-safe).
|
|
37992
|
+
* @param service - the `remote.session` face to wrap.
|
|
37993
|
+
* @param deps - per-call takeover decisions (same as {@link wrapOpenPath}).
|
|
37994
|
+
* @returns the disposer restoring the original method (HMR-safe).
|
|
37995
|
+
*/
|
|
37996
|
+
function wrapOpenWorkspacePath(service, deps) {
|
|
37997
|
+
const descriptor = Object.getOwnPropertyDescriptor(service, "openWorkspacePath");
|
|
37998
|
+
const original = service.openWorkspacePath;
|
|
37999
|
+
const wrapped = async (input) => {
|
|
38000
|
+
const sessionId = deps.currentSessionId();
|
|
38001
|
+
if (sessionId !== void 0) {
|
|
38002
|
+
if (await deps.openInEditor(input.path, sessionId)) return {
|
|
38003
|
+
ok: true,
|
|
38004
|
+
value: { opened: true }
|
|
38005
|
+
};
|
|
38006
|
+
}
|
|
38007
|
+
return original.call(service, input);
|
|
38008
|
+
};
|
|
38009
|
+
Object.defineProperty(service, "openWorkspacePath", {
|
|
38010
|
+
configurable: true,
|
|
38011
|
+
enumerable: descriptor?.enumerable ?? true,
|
|
38012
|
+
writable: false,
|
|
38013
|
+
value: wrapped
|
|
38014
|
+
});
|
|
38015
|
+
return () => {
|
|
38016
|
+
if (descriptor !== void 0) Object.defineProperty(service, "openWorkspacePath", descriptor);
|
|
38017
|
+
else {
|
|
38018
|
+
delete service.openWorkspacePath;
|
|
38019
|
+
service.openWorkspacePath = original;
|
|
38020
|
+
}
|
|
37959
38021
|
};
|
|
37960
38022
|
}
|
|
37961
38023
|
//#endregion
|
|
@@ -37973,6 +38035,15 @@ window.__ModuleLoader__.load({
|
|
|
37973
38035
|
* new default mode and immediately runs that mode's open action. The choice
|
|
37974
38036
|
* is persisted in localStorage so it survives reloads.
|
|
37975
38037
|
*
|
|
38038
|
+
* The same ButtonGroup is also shown on the new-session screen through the
|
|
38039
|
+
* generic `shell.overlay` floating layer (no shell change involved): a
|
|
38040
|
+
* plugin-owned entry pins it to the conversation column's top-right while
|
|
38041
|
+
* the column is in its hero phase — the no-session hero and the
|
|
38042
|
+
* blank-session (new chat) hero, where the session header and its utilities
|
|
38043
|
+
* seat are absent or deliberately hidden. The floating entry resolves its
|
|
38044
|
+
* session itself: the actions fall back to the live selection
|
|
38045
|
+
* (`useSessions` → `state.current`) and show a notice when none exists.
|
|
38046
|
+
*
|
|
37976
38047
|
* Session binding: every /filex request is conversation-scoped, so the modal
|
|
37977
38048
|
* must know WHICH session it belongs to — the host resolves the workspace
|
|
37978
38049
|
* from `session.header.cwd`, never from a global setting. The slot supplies
|
|
@@ -37983,7 +38054,9 @@ window.__ModuleLoader__.load({
|
|
|
37983
38054
|
const inject = [
|
|
37984
38055
|
"slots",
|
|
37985
38056
|
"sessions",
|
|
37986
|
-
"workspaces"
|
|
38057
|
+
"workspaces",
|
|
38058
|
+
"remote",
|
|
38059
|
+
"remote.session"
|
|
37987
38060
|
];
|
|
37988
38061
|
const MODE_STORAGE_KEY = "dsh-file-explorer.header-mode";
|
|
37989
38062
|
/** Read the persisted mode; anything unknown defaults to the editor. */
|
|
@@ -38079,7 +38152,7 @@ window.__ModuleLoader__.load({
|
|
|
38079
38152
|
function openExplorer(sessionId, path) {
|
|
38080
38153
|
const resolved = sessionId !== void 0 && sessionId !== "" ? sessionId : activeSessionId;
|
|
38081
38154
|
if (resolved === void 0) {
|
|
38082
|
-
showNotice("
|
|
38155
|
+
showNotice("没有可用的会话:无法确定文件工作区。请先新建/选择一个会话。");
|
|
38083
38156
|
return;
|
|
38084
38157
|
}
|
|
38085
38158
|
store = {
|
|
@@ -38246,6 +38319,58 @@ window.__ModuleLoader__.load({
|
|
|
38246
38319
|
})
|
|
38247
38320
|
});
|
|
38248
38321
|
}
|
|
38322
|
+
/**
|
|
38323
|
+
* Hero / new-session floating utility: the same HeaderGroup, rendered by the
|
|
38324
|
+
* plugin itself through the generic `shell.overlay` floating layer (no shell
|
|
38325
|
+
* change needed) and pinned to the conversation column's top-right corner —
|
|
38326
|
+
* the spot where the session-header utilities sit once a conversation has
|
|
38327
|
+
* records. Shown only while the conversation column is in its `hero` phase
|
|
38328
|
+
* (no session at all, or a blank session whose header is deliberately
|
|
38329
|
+
* hidden); the position is measured from the rendered column root
|
|
38330
|
+
* (`[data-phase]`), so sidebar collapse and details-panel toggles are
|
|
38331
|
+
* tracked automatically. Clicking behaves exactly like the header icon: in a
|
|
38332
|
+
* blank-session hero the actions bind to that session, and with no session
|
|
38333
|
+
* at all they surface the no-session notice.
|
|
38334
|
+
*/
|
|
38335
|
+
function HeroFilexButton(props) {
|
|
38336
|
+
const [pos, setPos] = (0, react.useState)(null);
|
|
38337
|
+
(0, react.useEffect)(() => {
|
|
38338
|
+
const update = () => {
|
|
38339
|
+
const column = document.querySelector("[data-phase]");
|
|
38340
|
+
if (column === null || column.getAttribute("data-phase") !== "hero") {
|
|
38341
|
+
setPos(null);
|
|
38342
|
+
return;
|
|
38343
|
+
}
|
|
38344
|
+
const rect = column.getBoundingClientRect();
|
|
38345
|
+
if (rect.width === 0 || rect.height === 0) {
|
|
38346
|
+
setPos(null);
|
|
38347
|
+
return;
|
|
38348
|
+
}
|
|
38349
|
+
const top = rect.top + 14;
|
|
38350
|
+
const right = window.innerWidth - rect.right + 28;
|
|
38351
|
+
setPos((current) => current !== null && current.top === top && current.right === right ? current : {
|
|
38352
|
+
top,
|
|
38353
|
+
right
|
|
38354
|
+
});
|
|
38355
|
+
};
|
|
38356
|
+
const timer = window.setInterval(update, 400);
|
|
38357
|
+
window.addEventListener("resize", update);
|
|
38358
|
+
update();
|
|
38359
|
+
return () => {
|
|
38360
|
+
window.clearInterval(timer);
|
|
38361
|
+
window.removeEventListener("resize", update);
|
|
38362
|
+
};
|
|
38363
|
+
}, []);
|
|
38364
|
+
if (pos === null) return null;
|
|
38365
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
38366
|
+
className: "filex-hero-fab",
|
|
38367
|
+
style: {
|
|
38368
|
+
top: pos.top,
|
|
38369
|
+
right: pos.right
|
|
38370
|
+
},
|
|
38371
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(HeaderGroup, { useSessions: props.useSessions })
|
|
38372
|
+
});
|
|
38373
|
+
}
|
|
38249
38374
|
/** The overlay entry: keyboard shortcut + modal + transient notice. */
|
|
38250
38375
|
function ExplorerOverlay(props) {
|
|
38251
38376
|
const state = (0, react.useSyncExternalStore)(subscribe, getSnapshot);
|
|
@@ -38321,25 +38446,45 @@ window.__ModuleLoader__.load({
|
|
|
38321
38446
|
order: 10,
|
|
38322
38447
|
label: "文件预览 / 编辑"
|
|
38323
38448
|
}, HeaderGroup));
|
|
38324
|
-
ctx.slots.inject("shell.overlay", () =>
|
|
38325
|
-
|
|
38326
|
-
|
|
38327
|
-
|
|
38328
|
-
|
|
38329
|
-
|
|
38449
|
+
ctx.slots.inject("shell.overlay", () => {
|
|
38450
|
+
const overlay = ctx.slots.register({
|
|
38451
|
+
name: "shell.overlay",
|
|
38452
|
+
id: "file-explorer-overlay",
|
|
38453
|
+
order: 100,
|
|
38454
|
+
label: "文件预览"
|
|
38455
|
+
}, ExplorerOverlay);
|
|
38456
|
+
const heroFab = ctx.slots.register({
|
|
38457
|
+
name: "shell.overlay",
|
|
38458
|
+
id: "file-explorer-hero-fab",
|
|
38459
|
+
order: 90,
|
|
38460
|
+
label: "文件预览 / 编辑(hero)"
|
|
38461
|
+
}, HeroFilexButton);
|
|
38462
|
+
return () => {
|
|
38463
|
+
overlay();
|
|
38464
|
+
heroFab();
|
|
38465
|
+
};
|
|
38466
|
+
});
|
|
38330
38467
|
probeVscode();
|
|
38331
|
-
ctx.effect(() =>
|
|
38332
|
-
|
|
38333
|
-
|
|
38334
|
-
|
|
38335
|
-
|
|
38336
|
-
|
|
38337
|
-
|
|
38468
|
+
ctx.effect(() => {
|
|
38469
|
+
const deps = {
|
|
38470
|
+
currentSessionId: () => activeSessionId,
|
|
38471
|
+
openInEditor: async (path, sessionId) => {
|
|
38472
|
+
try {
|
|
38473
|
+
await api.fsRead({ sessionId }, path);
|
|
38474
|
+
} catch {
|
|
38475
|
+
return false;
|
|
38476
|
+
}
|
|
38477
|
+
openExplorer(sessionId, path);
|
|
38478
|
+
return true;
|
|
38338
38479
|
}
|
|
38339
|
-
|
|
38340
|
-
|
|
38341
|
-
}
|
|
38342
|
-
|
|
38480
|
+
};
|
|
38481
|
+
const restoreOpenPath = wrapOpenPath(ctx.workspaces, deps);
|
|
38482
|
+
const restoreWorkspacePath = ctx.remote?.session?.openWorkspacePath !== void 0 ? wrapOpenWorkspacePath(ctx.remote.session, deps) : () => {};
|
|
38483
|
+
return () => {
|
|
38484
|
+
restoreOpenPath();
|
|
38485
|
+
restoreWorkspacePath();
|
|
38486
|
+
};
|
|
38487
|
+
}, "dsh-file-explorer: file-open interception");
|
|
38343
38488
|
} catch (error) {
|
|
38344
38489
|
fail("load", error);
|
|
38345
38490
|
}
|
|
@@ -64,6 +64,31 @@ export interface FilexWorkspacesService {
|
|
|
64
64
|
/** Open a filesystem path through the Host (OS default application). */
|
|
65
65
|
openPath(path: string): Promise<void>;
|
|
66
66
|
}
|
|
67
|
+
/** Result of the chat's workspace-path open RPC (dsh-api-remotes face). */
|
|
68
|
+
export interface FilexWorkspaceOpenResult {
|
|
69
|
+
ok: boolean;
|
|
70
|
+
value?: {
|
|
71
|
+
opened: boolean;
|
|
72
|
+
};
|
|
73
|
+
error?: {
|
|
74
|
+
message: string;
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* The `ctx.remote.session` face (dsh-api-remotes): the remote API the
|
|
79
|
+
* conversation view uses for chat-side file opens in current runtimes —
|
|
80
|
+
* `session/openWorkspacePath` opens with the Host OS default application
|
|
81
|
+
* unless a plugin takes it over.
|
|
82
|
+
*/
|
|
83
|
+
export interface FilexRemoteSession {
|
|
84
|
+
openWorkspacePath(input: {
|
|
85
|
+
path: string;
|
|
86
|
+
}): Promise<FilexWorkspaceOpenResult>;
|
|
87
|
+
}
|
|
88
|
+
/** The `ctx.remote` service face (structural subset used by this plugin). */
|
|
89
|
+
export interface FilexRemoteService {
|
|
90
|
+
session: FilexRemoteSession;
|
|
91
|
+
}
|
|
67
92
|
/** The composer input face (client conversation service). */
|
|
68
93
|
export interface FilexConversationInput {
|
|
69
94
|
state: {
|
|
@@ -98,6 +123,10 @@ declare module 'cordis' {
|
|
|
98
123
|
slots: FilexSlotsService;
|
|
99
124
|
/** Client-only: the chat's file-open funnel the explorer intercepts. */
|
|
100
125
|
workspaces: FilexWorkspacesService;
|
|
126
|
+
/** Client-only: the remote API face (dsh-api-remotes); chat-side file
|
|
127
|
+
* opens route through `remote.session.openWorkspacePath` in current
|
|
128
|
+
* runtimes, which the explorer also intercepts. */
|
|
129
|
+
remote?: FilexRemoteService;
|
|
101
130
|
/** Subscribe to session events (cordis event API). */
|
|
102
131
|
on(event: string, listener: (session: unknown, event: unknown) => void): () => void;
|
|
103
132
|
/** DSH-vendored cordis lifecycle helper. */
|
package/package.json
CHANGED
|
@@ -1,113 +1,113 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@dsh-xhl/dsh-file-explorer",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "DSH 外部编译型插件:工作区文件预览 / 编辑(CodeMirror 6 编辑器 + 文件树 + 全文搜索 + Markdown/HTML/图片/PDF 预览)。移植自同目录下的动态 Cordis 插件版本。",
|
|
5
|
-
"type": "module",
|
|
6
|
-
"main": "lib/index.js",
|
|
7
|
-
"types": "lib/types/index.d.ts",
|
|
8
|
-
"exports": {
|
|
9
|
-
".": {
|
|
10
|
-
"types": "./lib/types/index.d.ts",
|
|
11
|
-
"default": "./lib/index.js"
|
|
12
|
-
},
|
|
13
|
-
"./client": "./lib/client.js",
|
|
14
|
-
"./package.json": "./package.json"
|
|
15
|
-
},
|
|
16
|
-
"engines": {
|
|
17
|
-
"node": ">=20"
|
|
18
|
-
},
|
|
19
|
-
"publishConfig": {
|
|
20
|
-
"access": "public",
|
|
21
|
-
"registry": "https://registry.npmjs.org"
|
|
22
|
-
},
|
|
23
|
-
"dsh": {
|
|
24
|
-
"bundle": {
|
|
25
|
-
"patch": "./cordis.patch.yml"
|
|
26
|
-
},
|
|
27
|
-
"client": {
|
|
28
|
-
"inject": [
|
|
29
|
-
"@deepseek-ai/dsh-client-runtime",
|
|
30
|
-
"@deepseek-ai/dsh-client-ui-slots",
|
|
31
|
-
"@deepseek-ai/dsh-client-web-react"
|
|
32
|
-
],
|
|
33
|
-
"platform": "web"
|
|
34
|
-
}
|
|
35
|
-
},
|
|
36
|
-
"files": [
|
|
37
|
-
"lib/index.js",
|
|
38
|
-
"lib/client.js",
|
|
39
|
-
"lib/types/**/*.d.ts",
|
|
40
|
-
"cordis.patch.yml",
|
|
41
|
-
"README.md"
|
|
42
|
-
],
|
|
43
|
-
"scripts": {
|
|
44
|
-
"build": "node -e \"fs.rmSync('lib',{recursive:true,force:true})\" && tsc -p tsconfig.build.json && tsdown",
|
|
45
|
-
"typecheck": "tsc --noEmit",
|
|
46
|
-
"bundle": "tsdown",
|
|
47
|
-
"prepare": "tsdown"
|
|
48
|
-
},
|
|
49
|
-
"license": "MIT",
|
|
50
|
-
"peerDependencies": {
|
|
51
|
-
"@deepseek-ai/cordis": "^4.0.1",
|
|
52
|
-
"@deepseek-ai/dsh-client-runtime": "^0.1.0-rc.6",
|
|
53
|
-
"@deepseek-ai/dsh-client-ui-primitives": "^0.1.0-rc.6",
|
|
54
|
-
"@deepseek-ai/dsh-client-ui-slots": "^0.1.0-rc.6",
|
|
55
|
-
"@deepseek-ai/dsh-client-web-react": "^0.1.0-rc.6",
|
|
56
|
-
"@deepseek-ai/dsh-host-webserver": "^0.1.0-rc.6",
|
|
57
|
-
"@deepseek-ai/dsh-session": "^0.1.0-rc.6",
|
|
58
|
-
"cordis": "^4.0.0-rc.7",
|
|
59
|
-
"react": "^18.2.0",
|
|
60
|
-
"react-dom": "^18.2.0"
|
|
61
|
-
},
|
|
62
|
-
"peerDependenciesMeta": {
|
|
63
|
-
"cordis": {
|
|
64
|
-
"optional": true
|
|
65
|
-
}
|
|
66
|
-
},
|
|
67
|
-
"dependencies": {
|
|
68
|
-
"@codemirror/commands": "^6.10.4",
|
|
69
|
-
"@codemirror/lang-cpp": "^6.0.3",
|
|
70
|
-
"@codemirror/lang-css": "^6.3.1",
|
|
71
|
-
"@codemirror/lang-go": "^6.0.1",
|
|
72
|
-
"@codemirror/lang-html": "^6.4.12",
|
|
73
|
-
"@codemirror/lang-java": "^6.0.2",
|
|
74
|
-
"@codemirror/lang-javascript": "^6.2.5",
|
|
75
|
-
"@codemirror/lang-json": "^6.0.2",
|
|
76
|
-
"@codemirror/lang-markdown": "^6.5.2",
|
|
77
|
-
"@codemirror/lang-php": "^6.0.2",
|
|
78
|
-
"@codemirror/lang-python": "^6.2.1",
|
|
79
|
-
"@codemirror/lang-rust": "^6.0.2",
|
|
80
|
-
"@codemirror/lang-sql": "^6.10.0",
|
|
81
|
-
"@codemirror/lang-vue": "^0.1.3",
|
|
82
|
-
"@codemirror/lang-xml": "^6.1.0",
|
|
83
|
-
"@codemirror/lang-yaml": "^6.1.3",
|
|
84
|
-
"@codemirror/language": "^6.12.4",
|
|
85
|
-
"@codemirror/legacy-modes": "^6.5.3",
|
|
86
|
-
"@codemirror/search": "6.7.1",
|
|
87
|
-
"@codemirror/state": "^6.7.1",
|
|
88
|
-
"@codemirror/view": "^6.43.8",
|
|
89
|
-
"@lezer/highlight": "^1.2.3",
|
|
90
|
-
"vscode-icons-js": "^11.6.1"
|
|
91
|
-
},
|
|
92
|
-
"devDependencies": {
|
|
93
|
-
"@deepseek-ai/cordis": "^4.0.1",
|
|
94
|
-
"@deepseek-ai/dsh-agent": "^0.1.0-rc.6",
|
|
95
|
-
"@deepseek-ai/dsh-client-locale": "^0.1.0-rc.6",
|
|
96
|
-
"@deepseek-ai/dsh-client-runtime": "^0.1.0-rc.6",
|
|
97
|
-
"@deepseek-ai/dsh-client-ui-conversation": "^0.1.0-rc.6",
|
|
98
|
-
"@deepseek-ai/dsh-client-ui-primitives": "^0.1.0-rc.6",
|
|
99
|
-
"@deepseek-ai/dsh-client-ui-slots": "^0.1.0-rc.6",
|
|
100
|
-
"@deepseek-ai/dsh-client-web-react": "^0.1.0-rc.6",
|
|
101
|
-
"@deepseek-ai/dsh-host-webserver": "^0.1.0-rc.6",
|
|
102
|
-
"@deepseek-ai/dsh-session": "^0.1.0-rc.6",
|
|
103
|
-
"@deepseek-ai/dsh-tools": "^0.1.0-rc.6",
|
|
104
|
-
"@types/node": "^22.0.0",
|
|
105
|
-
"@types/react": "~18.3.1",
|
|
106
|
-
"@types/react-dom": "~18.3.1",
|
|
107
|
-
"cordis": "^4.0.0-rc.7",
|
|
108
|
-
"react": "^18.2.0",
|
|
109
|
-
"react-dom": "^18.2.0",
|
|
110
|
-
"tsdown": "^0.22.2",
|
|
111
|
-
"typescript": "^5.6.0"
|
|
112
|
-
}
|
|
113
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@dsh-xhl/dsh-file-explorer",
|
|
3
|
+
"version": "0.1.3",
|
|
4
|
+
"description": "DSH 外部编译型插件:工作区文件预览 / 编辑(CodeMirror 6 编辑器 + 文件树 + 全文搜索 + Markdown/HTML/图片/PDF 预览)。移植自同目录下的动态 Cordis 插件版本。",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "lib/index.js",
|
|
7
|
+
"types": "lib/types/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./lib/types/index.d.ts",
|
|
11
|
+
"default": "./lib/index.js"
|
|
12
|
+
},
|
|
13
|
+
"./client": "./lib/client.js",
|
|
14
|
+
"./package.json": "./package.json"
|
|
15
|
+
},
|
|
16
|
+
"engines": {
|
|
17
|
+
"node": ">=20"
|
|
18
|
+
},
|
|
19
|
+
"publishConfig": {
|
|
20
|
+
"access": "public",
|
|
21
|
+
"registry": "https://registry.npmjs.org"
|
|
22
|
+
},
|
|
23
|
+
"dsh": {
|
|
24
|
+
"bundle": {
|
|
25
|
+
"patch": "./cordis.patch.yml"
|
|
26
|
+
},
|
|
27
|
+
"client": {
|
|
28
|
+
"inject": [
|
|
29
|
+
"@deepseek-ai/dsh-client-runtime",
|
|
30
|
+
"@deepseek-ai/dsh-client-ui-slots",
|
|
31
|
+
"@deepseek-ai/dsh-client-web-react"
|
|
32
|
+
],
|
|
33
|
+
"platform": "web"
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
"files": [
|
|
37
|
+
"lib/index.js",
|
|
38
|
+
"lib/client.js",
|
|
39
|
+
"lib/types/**/*.d.ts",
|
|
40
|
+
"cordis.patch.yml",
|
|
41
|
+
"README.md"
|
|
42
|
+
],
|
|
43
|
+
"scripts": {
|
|
44
|
+
"build": "node -e \"fs.rmSync('lib',{recursive:true,force:true})\" && tsc -p tsconfig.build.json && tsdown",
|
|
45
|
+
"typecheck": "tsc --noEmit",
|
|
46
|
+
"bundle": "tsdown",
|
|
47
|
+
"prepare": "tsdown"
|
|
48
|
+
},
|
|
49
|
+
"license": "MIT",
|
|
50
|
+
"peerDependencies": {
|
|
51
|
+
"@deepseek-ai/cordis": "^4.0.1",
|
|
52
|
+
"@deepseek-ai/dsh-client-runtime": "^0.1.0-rc.6",
|
|
53
|
+
"@deepseek-ai/dsh-client-ui-primitives": "^0.1.0-rc.6",
|
|
54
|
+
"@deepseek-ai/dsh-client-ui-slots": "^0.1.0-rc.6",
|
|
55
|
+
"@deepseek-ai/dsh-client-web-react": "^0.1.0-rc.6",
|
|
56
|
+
"@deepseek-ai/dsh-host-webserver": "^0.1.0-rc.6",
|
|
57
|
+
"@deepseek-ai/dsh-session": "^0.1.0-rc.6",
|
|
58
|
+
"cordis": "^4.0.0-rc.7",
|
|
59
|
+
"react": "^18.2.0",
|
|
60
|
+
"react-dom": "^18.2.0"
|
|
61
|
+
},
|
|
62
|
+
"peerDependenciesMeta": {
|
|
63
|
+
"cordis": {
|
|
64
|
+
"optional": true
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
"dependencies": {
|
|
68
|
+
"@codemirror/commands": "^6.10.4",
|
|
69
|
+
"@codemirror/lang-cpp": "^6.0.3",
|
|
70
|
+
"@codemirror/lang-css": "^6.3.1",
|
|
71
|
+
"@codemirror/lang-go": "^6.0.1",
|
|
72
|
+
"@codemirror/lang-html": "^6.4.12",
|
|
73
|
+
"@codemirror/lang-java": "^6.0.2",
|
|
74
|
+
"@codemirror/lang-javascript": "^6.2.5",
|
|
75
|
+
"@codemirror/lang-json": "^6.0.2",
|
|
76
|
+
"@codemirror/lang-markdown": "^6.5.2",
|
|
77
|
+
"@codemirror/lang-php": "^6.0.2",
|
|
78
|
+
"@codemirror/lang-python": "^6.2.1",
|
|
79
|
+
"@codemirror/lang-rust": "^6.0.2",
|
|
80
|
+
"@codemirror/lang-sql": "^6.10.0",
|
|
81
|
+
"@codemirror/lang-vue": "^0.1.3",
|
|
82
|
+
"@codemirror/lang-xml": "^6.1.0",
|
|
83
|
+
"@codemirror/lang-yaml": "^6.1.3",
|
|
84
|
+
"@codemirror/language": "^6.12.4",
|
|
85
|
+
"@codemirror/legacy-modes": "^6.5.3",
|
|
86
|
+
"@codemirror/search": "6.7.1",
|
|
87
|
+
"@codemirror/state": "^6.7.1",
|
|
88
|
+
"@codemirror/view": "^6.43.8",
|
|
89
|
+
"@lezer/highlight": "^1.2.3",
|
|
90
|
+
"vscode-icons-js": "^11.6.1"
|
|
91
|
+
},
|
|
92
|
+
"devDependencies": {
|
|
93
|
+
"@deepseek-ai/cordis": "^4.0.1",
|
|
94
|
+
"@deepseek-ai/dsh-agent": "^0.1.0-rc.6",
|
|
95
|
+
"@deepseek-ai/dsh-client-locale": "^0.1.0-rc.6",
|
|
96
|
+
"@deepseek-ai/dsh-client-runtime": "^0.1.0-rc.6",
|
|
97
|
+
"@deepseek-ai/dsh-client-ui-conversation": "^0.1.0-rc.6",
|
|
98
|
+
"@deepseek-ai/dsh-client-ui-primitives": "^0.1.0-rc.6",
|
|
99
|
+
"@deepseek-ai/dsh-client-ui-slots": "^0.1.0-rc.6",
|
|
100
|
+
"@deepseek-ai/dsh-client-web-react": "^0.1.0-rc.6",
|
|
101
|
+
"@deepseek-ai/dsh-host-webserver": "^0.1.0-rc.6",
|
|
102
|
+
"@deepseek-ai/dsh-session": "^0.1.0-rc.6",
|
|
103
|
+
"@deepseek-ai/dsh-tools": "^0.1.0-rc.6",
|
|
104
|
+
"@types/node": "^22.0.0",
|
|
105
|
+
"@types/react": "~18.3.1",
|
|
106
|
+
"@types/react-dom": "~18.3.1",
|
|
107
|
+
"cordis": "^4.0.0-rc.7",
|
|
108
|
+
"react": "^18.2.0",
|
|
109
|
+
"react-dom": "^18.2.0",
|
|
110
|
+
"tsdown": "^0.22.2",
|
|
111
|
+
"typescript": "^5.6.0"
|
|
112
|
+
}
|
|
113
|
+
}
|